diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..14c3c0a80 --- /dev/null +++ b/.gitignore @@ -0,0 +1,43 @@ +*.qm +moc_* +gen_* +*.o +*.gcno +Makefile +*.so +*.so.* + +# vim swap files +.*.swp +BUILD_ID +Makefile +doc/html +lib/* +.moc +.obj +.*.swp +*.o +testdui +*~ +*.tmp +*moc_* +*.log +*.log.xml +YES +*-stamp +*.gcov +*.log.xml +*.deb +*.gcno +*.old +*.foo +*.gcda +*.pro.user +*.app +.DS_Store +.dummy +cscope.files +cscope.out +.gen +build-i386 +build-armel diff --git a/LICENSE.LGPL b/LICENSE.LGPL new file mode 100644 index 000000000..5be4c8f20 --- /dev/null +++ b/LICENSE.LGPL @@ -0,0 +1,514 @@ + GNU LESSER GENERAL PUBLIC LICENSE + + The DirectUI Framework is Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). + Contact: Nokia Corporation (directui@nokia.com) + + You may use, distribute and copy the DirectUI Framework under the terms of + GNU Lesser General Public License version 2.1, which is displayed below. + +------------------------------------------------------------------------- + + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/README b/README new file mode 100644 index 000000000..56356efb8 --- /dev/null +++ b/README @@ -0,0 +1,47 @@ +This source tree contains the DirectUI library + +Building +======== +./configure +make +sudo make install + +The library will be installed by default with a prefix of /usr/local, +see ./configure -help for options. + +The reference documentation can be built with "make doc", +if doxygen is available. + +Running +======= +The library ships with a demo application called "widgetsgallery" + +The duitheme package must be installed before running any DirectUI +applications. + +duitheme is available separately from http://qt.gitorious.org and can +be installed with the following commands: + cd duitheme + qmake + sudo make install + + +Build dependencies +================== +- Development headers: + - Qt 4.6 + - X11 + - Mesa or vendor specific OpenGL libraries +- pkg-config + +Optional dependencies +===================== + +If found, the following libraries will enable additional +features in the DirectUI library: + +- ICU: I18N and L10N extensions +- GConf2: C++ abstraction layer for gconf settings system +- ContextKit context subscriber: Automatic rotation on supported hardware +- GStreamer 0.10: Media widgets +- DBus: Out of process applet support, out of process theme server support diff --git a/README.win32 b/README.win32 new file mode 100644 index 000000000..b7368e382 --- /dev/null +++ b/README.win32 @@ -0,0 +1,205 @@ +this README describes how to set up libdui on a windows +computer. + +right now we support the MinGW GCC compiler and the +Microsoft Visual Studio cl C++ compiler. this document +describes how to compile libdui for both compilers. + +general prerequisites: + +- install git, i installed it from http://code.google.com/p/msysgit/ + +- install perl, strawberry perl works for me. + +- install coreutils from gnuwin32.sf.net. this is needed, because + in the qmake build files there are some calls for the unix touch + command. and this package installs touch for windows. + +- install debugview. i got it from + http://technet.microsoft.com/en-us/sysinternals/bb896647.aspx + it shows the qDebug statements that libdui will print when + something goes wrong. + + +prerequisities for visual studio: + +- install visual studio, express version worked for me. + +- install a qt version with dbus support. either do it + on your own, or use the version that is distributed by + kde. go to http://winkde.org/pub/kde/ports/win32/installer/ + and download the latest installer. then install kde. + you can install everything, but for this purpose it is important + to install the qt package and also the qt development package + (the header files etc.). kde for windows comes in two "versions", + one is compiles with visual studio express, and the other is + compiles with mingw. make sure you select to install the + msvc version. + + +prerequisities for mingw: + +- install MinGW. the version that can be installed at the + installation routine of qt for windows is ok. + +- install a qt version with dbus support. either do it + on your own, or use the version that is distributed by + kde. go to http://winkde.org/pub/kde/ports/win32/installer/ + and download the latest installer. then install kde. + you can install everything, but for this purpose it is important + to install the qt package and also the qt development package + (the header files etc.). kde for windows comes in two "versions", + one is compiles with visual studio express, and the other is + compiles with mingw. make sure you select to install the + mingw version. + + +now you should have all the tools you need to build and execute libdui +and its programs. + +# now you should check that youe environment is setup in a way +# that the needed tools can be found. for the following commands, +# execute them in a cmd.exe window and check if they are found. +# (when you know konsole on linux as a shell window, try out +# console2, you might like it: http://sourceforge.net/projects/console/ ) +touch +perl +git +qmake + +# for mingw +gcc +g++ +make + +# for msvc +cl +nmake + +# if all the commands are found, you are fine. if not, you have to add +# the pathes to these commands to your PATH environment variable, +# like this: +# set PATH=%PATH%;c:\KDE\bin + +now go to some directory, e.g. c:\dui. in the following i will +list the commands needed to get a working widgets gallery. + +# go to this empty directory... +c: +cd \dui + +# now do a git checkout of duitheme +git co git+ssh://git@dvcs.projects.maemo.org:af/duitheme + +# now install the theme files +cd duitheme +qmake + +# for msvc +nmake +nmake install + +# or for mingw +make +make install + +#for all +cd .. + +# in this dir do a git checkout of libdui. +# right now we still need the holger-msvc branch, but it +# will be merged to master in short time. +git co git+ssh://git@dvcs.projects.maemo.org:af/libdui + +# now switch to holger-msvc branch +cd libdui +git co -b holger-msvc origin/holger-msvc +cd .. + +# sources are now in libdui. + +# now create build directory +mkdir libduibuild + +cd libduibuild + +# run qmake +qmake ..\libdui\projects.pro + +# for msvc: + +# run nmake to build it. +nmake +# currently this will fail with an error about a missing +# duigen executable + +# actually right now under windows i was not able to build +# the duigen executable in the same location no matter if +# we build a debug or release build. for that the following +# steps in between are needed. we build and "install" duigen +# before we build the rest of libdui. +cd duigen +nmake +nmake install +cd .. + +# and now we continue with the normal libdui build +nmake + +# now install libdui +nmake install + + + +# for mingw +# run make to build it. +make +# currently this will fail with an error about a missing +# duigen executable + +# actually right now under windows i was not able to build +# the duigen executable in the same location no matter if +# we build a debug or release build. for that the following +# steps in between are needed. we build and "install" duigen +# before we build the rest of libdui. +cd duigen +make +make install +cd .. + +# and now we continue with the normal libdui build +make + +# now install libdui +make install + + + +# for all + +# now we built libdui and installed it, but the theme files +# are not yet in the right places. let's see if widgetsgallery +# tries to start anyway. it is expected that when you start +# widgetsgallery, it only prints some output in the stderr channel +# and exits again. first start the debugview program to catch +# messages on stderr. +debugview + +# now we set the PATH environment variable to contain the path to +# the installed qt with dbus support. in this case we use the +# KDE-on-windows version. +set PATH=c:\d\kde\bin;%PATH% + +# now we add the directories which contain dui.dll and the executables. +# qmake by default installs to /usr prefix. this is c:\usr\ under windows. +set PATH=c:\usr\bin;c:\usr\lib;%PATH% + +# now everything that is needed should be in place. +# start widgets gallery: +widgetsgallery + +# now you should see the same widgets gallery window as you see +# on linux. +# if you do: Congratulations :-) +# if you don't: contact me and i will try to help you: +# holger.schroeder.ext@basyskom.de diff --git a/benchmarks/.gitignore b/benchmarks/.gitignore new file mode 100644 index 000000000..f96f45d01 --- /dev/null +++ b/benchmarks/.gitignore @@ -0,0 +1,14 @@ +mt_duibutton +mt_duibuttongroup +mt_duiimage +mt_duilabel +mt_duilist +mt_duimenu +mt_duitoolbar +pt_duibutton +pt_duiimage +pt_duilist +pt_duimenu +pt_duiprogressindicator +pt_duislider +pt_duitoolbar \ No newline at end of file diff --git a/benchmarks/README.txt b/benchmarks/README.txt new file mode 100644 index 000000000..a2499cfbf --- /dev/null +++ b/benchmarks/README.txt @@ -0,0 +1,9 @@ +Some short instructions and notes on how to write performance benchmarks. + +1) Use pt_duibutton as a template - TODO:make a base class for common parts. +2) Change file and class names as appropriate +3) In the createView() method, change the cases of the switch statement to set the 'currentView' to a new instance of each view's class +4) In the fetchNewRow() method, the header file, and the paintPerformance_data() method, change the columns/variables to what you want to use as variables to measure performance +5) In the createController() method, create the controller and assign the properties appropriately +6) In the createPaintDevice() method, you generally want to set the width and height of the target pixmap to the width being rendered, but sometimes not since things may be rendered outside this area (eg labels) +7) In the paintPerformance() method, you generally only need a single call to paint() but some view's paint methods have different parameters, in which case you'll need a switch (eg in the duislider). diff --git a/benchmarks/benchmarks.pro b/benchmarks/benchmarks.pro new file mode 100644 index 000000000..9c6cc17a1 --- /dev/null +++ b/benchmarks/benchmarks.pro @@ -0,0 +1,25 @@ +TEMPLATE = subdirs + +SUBDIRS = \ + mt_duibutton \ + mt_duibuttongroup \ + mt_duiimagewidget \ + mt_duilist \ + mt_duimenu \ + mt_duitoolbar \ + mt_duilabel \ + \ + pt_duiapplication \ + pt_duibutton \ + pt_duicomponentdata \ + pt_duiimagewidget \ + pt_duimenu \ + pt_minimalduiapplication \ + pt_minimalqtapplication \ + pt_duiprogressindicator \ + pt_qapplication \ + pt_duislider \ + pt_duitheme \ + pt_duitoolbar \ + pt_widgetsgallery \ + diff --git a/benchmarks/common_top.pri b/benchmarks/common_top.pri new file mode 100644 index 000000000..339402fc4 --- /dev/null +++ b/benchmarks/common_top.pri @@ -0,0 +1,30 @@ +DUISRCDIR = ../../src/ +STUBSDIR = ../stubs +INCLUDEPATH += . $$DUISRCDIR $$STUBSDIR $$DUISRCDIR/include $$DUISRCDIR/core $$DUISRCDIR/widgets $$DUISRCDIR/workspace $$DUISRCDIR/style ../memorybenchmark/ + +DEPENDPATH = $$INCLUDEPATH +QMAKE_LIBDIR += ../../lib +CONFIG += debug +QT += testlib dbus svg +TEMPLATE = app +# DEFINES += QT_NO_DEBUG_OUTPUT +DEFINES += UNIT_TEST +target.path = $$[QT_INSTALL_LIBS]/libdui-benchmarks +INSTALLS += target + +win32|macx { + macx { + QMAKE_LFLAGS += -F../../lib + LIBS += -framework dui + } + win32:LIBS += -L../../lib -ldui0 +} else { + LIBS += ../../lib/libdui.so +} + +QMAKE_CXXFLAGS += -Werror +support_files.files = +support_files.path = $$[QT_INSTALL_LIBS]/libdui-benchmarks +INSTALLS += support_files + +CONFIG-=app_bundle diff --git a/benchmarks/memorybenchmark/memorybenchmark.h b/benchmarks/memorybenchmark/memorybenchmark.h new file mode 100644 index 000000000..be2be6fd6 --- /dev/null +++ b/benchmarks/memorybenchmark/memorybenchmark.h @@ -0,0 +1,67 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef MEMORYBENCHMARK_H +#define MEMORYBENCHMARK_H + +#include + +// Do not use these three methods, they produce +// inaccurate results that are nonsense. +void resetMemorySizeSnapshot(); +long int usedMemorySizeSnapshot(); +void printUsedMemorySizeSnapshot(); + +/*! + \brief Begins memory benchmark, clears all counters + */ +void beginMemoryBenchmark(); + +/*! + \brief Reports currently reserved memory after last beginMemoryBenchmark call + */ +size_t allocatedMemorySize(); + +/*! + \brief Outputs the size of allocated memory + */ +void outputAllocatedMemorySize(); + +/*! + \brief Finishes memory benchmark, clears counters and returns the amount of unfreed memory. + \param outputUnfreedMemory if true, outputs the amount of unfreed memory (in bytes) + */ +size_t endMemoryBenchmark(bool outputUnfreedMemory = false); + +/*! + \brief Starts to collect backtrace information from allocations, NOTE! this is a SLOW process. + */ +void beginBacktracing(); + +/*! + \brief Stops collecting backtrace. + */ +void endBacktracing(); + +/*! + \brief Prints out all allocated memory with backtrace information. + */ +void outputAllocatedMemoryBacktrace(); +#endif + diff --git a/benchmarks/memorybenchmark/memorybenchmark.inl b/benchmarks/memorybenchmark/memorybenchmark.inl new file mode 100644 index 000000000..e08fc06b8 --- /dev/null +++ b/benchmarks/memorybenchmark/memorybenchmark.inl @@ -0,0 +1,222 @@ +#ifdef __APPLE__ +#include +#else +#include +#endif + +#include + +long int usedMemorySize = 0; + +void resetMemorySizeSnapshot() +{ +#ifdef __APPLE__ + usedMemorySize = mstats().bytes_used; +#else + usedMemorySize = mallinfo().uordblks; +#endif +} + +long int usedMemorySizeSnapshot() +{ +#ifdef __APPLE__ + return mstats().bytes_used - usedMemorySize; +#else + return mallinfo().uordblks - usedMemorySize; +#endif +} + +void printUsedMemorySizeSnapshot() +{ + qDebug() << "Memory used: " << usedMemorySizeSnapshot() << " bytes"; +} + +#include "memorybenchmark.h" +typedef struct Allocation_t +{ + void* address; + size_t size; + void* backtrace; + Allocation_t* prev; +}Allocation; + +static size_t allocatedSize = 0; +static Allocation* allocations = 0; +static bool store_backtrace = false; + +pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + +//For backtrace +#include +#include +#include + +void demangleBacktrace(void* trace) +{ + if(trace == 0) { + printf("no backtrace"); + return; + } + + char** all_symbols = backtrace_symbols (&trace, 1); + char* symbol = all_symbols[0]; + + char* begin = 0, *end = 0; + int length = strlen(symbol); + + for(int i=0; isize)); + demangleBacktrace(allocation->backtrace); + printf("\n"); + allocation = allocation->prev; + } + pthread_mutex_unlock( &mutex ); +} + +void* operator new (size_t size) +{ + pthread_mutex_lock( &mutex ); + void *p=malloc(size); + + if (p==0) { + pthread_mutex_unlock( &mutex ); + throw std::bad_alloc(); // ANSI/ISO compliant behavior + } + + allocatedSize += size; + + Allocation* allocation = (Allocation*) malloc(sizeof(Allocation)); + allocation->address = p; + allocation->size = size; + allocation->prev = 0; + + if(allocations) { + allocation->prev = allocations; + } + + allocations = allocation; + pthread_mutex_unlock( &mutex ); + + if(store_backtrace) { + void* trace[2]; + backtrace(trace, 2); + allocation->backtrace = trace[1]; + } else { + allocation->backtrace = 0; + } + + return p; +} + +#include +void operator delete (void *p) +{ + pthread_mutex_lock( &mutex ); + + Allocation* lastProcessed = 0; + Allocation* allocation = allocations; + + while(allocation) { + // check if this is the one we want + if(allocation->address == p) { + + // reduce allocated size + allocatedSize -= allocation->size; + + // keep the chain valid + if(lastProcessed) { + lastProcessed->prev = allocation->prev; + } + + // chain pointer changing + if(allocation == allocations) { + allocations = allocation->prev; + } + + free(allocation); + break; + } else { + // store this as last processed + lastProcessed = allocation; + // get next in list (we'll be traversing from back to start) + allocation = allocation->prev; + } + } + free(p); + pthread_mutex_unlock( &mutex ); + +} + +void beginMemoryBenchmark() +{ + pthread_mutex_lock( &mutex ); + while(allocations) { + Allocation* newhead = allocations->prev; + free(allocations); + allocations = newhead; + } + + allocations = 0; + allocatedSize = 0; + pthread_mutex_unlock( &mutex ); +} + +size_t allocatedMemorySize() +{ + return allocatedSize; +} + +void outputAllocatedMemorySize() +{ + qDebug() << "Used memory:" << allocatedMemorySize() << "bytes."; +} + +size_t endMemoryBenchmark(bool outputUnfreedMemory) +{ + if(outputUnfreedMemory) { + qDebug() << "Unfreed memory: " << int(allocatedSize) << " bytes"; + } + return allocatedSize; +} diff --git a/benchmarks/mt_duidialog/mt_duidialog.cpp b/benchmarks/mt_duidialog/mt_duidialog.cpp new file mode 100644 index 000000000..142a5e55d --- /dev/null +++ b/benchmarks/mt_duidialog/mt_duidialog.cpp @@ -0,0 +1,180 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "memorybenchmark.h" +#include "memorybenchmark.inl" +#include "mt_duidialog.h" +#include +#include +#include +#include +#include +#include +#include + +DuiApplication *app; + +void Mt_DuiDialog::initTestCase() +{ + int argc = 1; + const char *argv[argc]; + char appName[] = "./widgetsgallery"; + argv[0] = appName; + app = new DuiApplication(argc, (char **)argv); + DuiTheme::instance()->changeTheme("common"); + + // We need to ensure that QTs subsystems are up and running + // and do not affect to our benchmark + QPixmap pixmap(100, 30); + QPainter painter(&pixmap); + DuiDialog *dialog = new DuiDialog(); + dialog->appearNow(); + dialog->paint(&painter, NULL); + delete dialog; +} + +void Mt_DuiDialog::cleanupTestCase() +{ + delete app; +} + +void Mt_DuiDialog::testPlainDialog_data() +{ +} + +void Mt_DuiDialog::testPlainDialog() +{ + /* + We want to measure how much memory will be used by dialog + when it's painted on a screen (buffer). We don't take into + account pixmap and painter. Also since graphics resource + loading is asynchronous we need to make sure that DuiTheme + daemon loaded all pictures. + */ + QPixmap pixmap(DuiDeviceProfile::instance()->resolution()); + QPainter painter(&pixmap); + + beginMemoryBenchmark(); + + DuiDialog *dialog = new DuiDialog; + dialog->appearNow(); + + dialog->paint(&painter, NULL); + + // Print used memory, it will be recorded in a log + outputAllocatedMemorySize(); + + // Release + delete dialog; + + QCoreApplication::processEvents(); + + endMemoryBenchmark(); +} + +void Mt_DuiDialog::testQueryDialog_data() +{ + QTest::addColumn("buttonCount"); + + QTest::newRow("1 buttons") << 1; + QTest::newRow("2 button") << 2; + QTest::newRow("5 buttons") << 5; + QTest::newRow("10 buttons") << 10; + QTest::newRow("20 buttons") << 20; + QTest::newRow("50 buttons") << 50; + QTest::newRow("100 buttons") << 100; + +} +void Mt_DuiDialog::testQueryDialog() +{ + QFETCH(int, buttonCount); + + QPixmap pixmap(DuiDeviceProfile::instance()->resolution()); + QPainter painter(&pixmap); + + DuiButton **buttons = new DuiButton*[buttonCount]; + + beginMemoryBenchmark(); + + DuiQueryDialog *dialog = new DuiQueryDialog("Test"); + + for (int i = 0; i < buttonCount; ++i) { + buttons[i] = dialog->addButton(QString("Button ") + QString::number(i)); + } + dialog->appearNow(); + + dialog->paint(&painter, NULL); + + // Print used memory, it will be recorded in a log + outputAllocatedMemorySize(); + + // Release + delete dialog; + + QCoreApplication::processEvents(); + + endMemoryBenchmark(); + + delete[] buttons; +} + + +void Mt_DuiDialog::testMessagebox_data() +{ + QTest::addColumn("buttons"); + + QTest::newRow("no buttons") << (int)(DuiMessageBoxModel::NoButton); + QTest::newRow("ok") << (int)(DuiMessageBoxModel::Ok); + QTest::newRow("ok & cancel") << (int)(DuiMessageBoxModel::Ok | DuiMessageBoxModel::Cancel); + QTest::newRow("ok & cancel & save") << (int)(DuiMessageBoxModel::Ok | DuiMessageBoxModel::Cancel | DuiMessageBoxModel::Save); + QTest::newRow("ok & cancel & save & discard") << (int)(DuiMessageBoxModel::Ok | DuiMessageBoxModel::Cancel | DuiMessageBoxModel::Save | DuiMessageBoxModel::Discard); +} + +void Mt_DuiDialog::testMessagebox() +{ + QFETCH(int, buttons); + /* + We want to measure how much memory will be used by dialog + when it's painted on a screen (buffer). We don't take into + account pixmap and painter. Also since graphics resource + loading is asynchronous we need to make sure that DuiTheme + daemon loaded all pictures. + */ + QPixmap pixmap(DuiDeviceProfile::instance()->resolution()); + QPainter painter(&pixmap); + + beginMemoryBenchmark(); + + DuiMessageBox *mb = new DuiMessageBox("Test messageBox", (DuiMessageBoxModel::Button) buttons); + mb->appearNow(); + + mb->paint(&painter, NULL); + + // Print used memory, it will be recorded in a log + outputAllocatedMemorySize(); + + // Release + delete mb; + + QCoreApplication::processEvents(); + + endMemoryBenchmark(); +} + +QTEST_APPLESS_MAIN(Mt_DuiDialog) diff --git a/benchmarks/mt_duidialog/mt_duidialog.h b/benchmarks/mt_duidialog/mt_duidialog.h new file mode 100644 index 000000000..2bd726dd7 --- /dev/null +++ b/benchmarks/mt_duidialog/mt_duidialog.h @@ -0,0 +1,42 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef MT_DUIDIALOG_H +#define MT_DUIDIALOG_H + +#include +#include + +class Mt_DuiDialog : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase(); + void cleanupTestCase(); + void testPlainDialog(); + void testPlainDialog_data(); + void testQueryDialog(); + void testQueryDialog_data(); + void testMessagebox(); + void testMessagebox_data(); +}; + +#endif + diff --git a/benchmarks/mt_duidialog/mt_duidialog.pro b/benchmarks/mt_duidialog/mt_duidialog.pro new file mode 100644 index 000000000..ed53e1b60 --- /dev/null +++ b/benchmarks/mt_duidialog/mt_duidialog.pro @@ -0,0 +1,8 @@ +include(../common_top.pri) +INCLUDEPATH += ../../src/include +DEPENDPATH += ../../src/include +TARGET = mt_duidialog + +SOURCES += mt_duidialog.cpp + +HEADERS += mt_duidialog.h diff --git a/benchmarks/mt_duiimagewidget/.gitignore b/benchmarks/mt_duiimagewidget/.gitignore new file mode 100644 index 000000000..6312969a1 --- /dev/null +++ b/benchmarks/mt_duiimagewidget/.gitignore @@ -0,0 +1 @@ +mt_duiimagewidget diff --git a/benchmarks/mt_duiimagewidget/mt_duiimagewidget.cpp b/benchmarks/mt_duiimagewidget/mt_duiimagewidget.cpp new file mode 100644 index 000000000..a550e5687 --- /dev/null +++ b/benchmarks/mt_duiimagewidget/mt_duiimagewidget.cpp @@ -0,0 +1,78 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "mt_duiimagewidget.h" + +#include "memorybenchmark.h" +#include "memorybenchmark.inl" + +#include +#include +#include +#include +#include + +DuiApplication *app; + +void Mt_DuiImageWidget::initTestCase() +{ + int argc = 1; + char *app_name = (char *) "./mt_duiimage"; + app = new DuiApplication(argc, &app_name); + DuiTheme::addPixmapDirectory(QCoreApplication::applicationDirPath()); +} + +void Mt_DuiImageWidget::cleanupTestCase() +{ + delete app; +} + +void Mt_DuiImageWidget::memory300over300png() +{ + int width = 300, height = 300; + QString imagename("test"); + + // create pixmap paintdevice + QPixmap pixmap(width, height); + pixmap.fill(QColor(0, 0, 0, 0)); + QPainter painter(&pixmap); + + beginMemoryBenchmark(); + + DuiImageWidget *image = new DuiImageWidget(); + + image->setImage(imagename); + image->setGeometry(QRectF(0, 0, width, height)); + + while (DuiTheme::hasPendingRequests()) { + usleep(10000); + QCoreApplication::processEvents(); + } + + image->paint(&painter, NULL); + + // Print used memory, it will be recorded in a log + outputAllocatedMemorySize(); + + delete image; + endMemoryBenchmark(); +} + +QTEST_APPLESS_MAIN(Mt_DuiImageWidget) + diff --git a/benchmarks/mt_duiimagewidget/mt_duiimagewidget.h b/benchmarks/mt_duiimagewidget/mt_duiimagewidget.h new file mode 100644 index 000000000..33a9404d2 --- /dev/null +++ b/benchmarks/mt_duiimagewidget/mt_duiimagewidget.h @@ -0,0 +1,37 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef MT_DUIIMAGEWIDGET_H +#define MT_DUIIMAGEWIDGET_H + +#include +#include + +class Mt_DuiImageWidget : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase(); + void cleanupTestCase(); + void memory300over300png(); +}; + +#endif + diff --git a/benchmarks/mt_duiimagewidget/mt_duiimagewidget.pro b/benchmarks/mt_duiimagewidget/mt_duiimagewidget.pro new file mode 100644 index 000000000..cf611d546 --- /dev/null +++ b/benchmarks/mt_duiimagewidget/mt_duiimagewidget.pro @@ -0,0 +1,8 @@ + +include(../common_top.pri) +INCLUDEPATH += ../../src/include +DEPENDPATH += ../../src/include +TARGET = mt_duiimagewidget + +SOURCES += mt_duiimagewidget.cpp +HEADERS += mt_duiimagewidget.h diff --git a/benchmarks/mt_duiimagewidget/test.png b/benchmarks/mt_duiimagewidget/test.png new file mode 100755 index 000000000..23c523367 Binary files /dev/null and b/benchmarks/mt_duiimagewidget/test.png differ diff --git a/benchmarks/mt_duiprogressindicator/mt_duiprogressindicator.cpp b/benchmarks/mt_duiprogressindicator/mt_duiprogressindicator.cpp new file mode 100644 index 000000000..7e918b19c --- /dev/null +++ b/benchmarks/mt_duiprogressindicator/mt_duiprogressindicator.cpp @@ -0,0 +1,145 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "memorybenchmark.h" +#include "memorybenchmark.inl" +#include "mt_duiprogressindicator.h" +#include +#include +#include +#include +#include +#include +#include + +DuiApplication *app; + +void Mt_DuiProgressIndicator::initTestCase() +{ + int argc = 1; + const char *argv[argc]; + char appName[] = "./widgetsgallery"; + argv[0] = appName; + app = new DuiApplication(argc, (char **)argv); + DuiTheme::instance()->changeTheme("common"); + + // We need to warmup QTs painters and probably + // some other subsystems + QPixmap pixmap(100, 30); + QPainter painter(&pixmap); + DuiProgressIndicator *progressindicator = new DuiProgressIndicator(); + progressindicator->setGeometry(QRectF(0, 0, 100, 100)); + while (DuiTheme::hasPendingRequests()) { + usleep(10000); + QCoreApplication::processEvents(); + } + progressindicator->paint(&painter, NULL); + delete progressindicator; +} + +void Mt_DuiProgressIndicator::cleanupTestCase() +{ + delete app; +} + +void Mt_DuiProgressIndicator::memoryBenchmark() +{ + QFETCH(qint32, width); + QFETCH(qint32, height); + QFETCH(qint32, viewIndex); + QFETCH(int, count); + + ViewName currentViewName = (ViewName)viewIndex; + DuiWidgetView *currentView; + + /* + We want to measure how much memory will be used by progressindicator + when it's painted on a screen (buffer). We don't take into + account pixmap and painter. Also since graphics resource + loading is asynchronous we need to make sure that DuTheme + deamon loaded all pictures. + */ + QPixmap pixmap(width, height); + QPainter painter(&pixmap); + + QList progressindicators; + + beginMemoryBenchmark(); + + // Create as many progressindicators as needed + for (int i = 0; i < count; ++i) { + DuiProgressIndicator *progressindicator = new DuiProgressIndicator(); + progressindicator->setMinimumSize(width, height); + progressindicator->setMaximumSize(width, height); + progressindicator->setRange(0, 100); + progressindicator->setValue(50); + switch (currentViewName) { + case Default: + currentView = new DuiProgressIndicatorCircularView(progressindicator); + break; + case Bar: + currentView = new DuiProgressIndicatorBarView(progressindicator); + break; + default: + break; + } + if (currentView) { + progressindicator->setView(currentView); // transfers ownership to controller + } + progressindicators.append(progressindicator); + } + + while (DuiTheme::hasPendingRequests()) { + usleep(10000); + QCoreApplication::processEvents(); + } + + // Paint all progressindicators + foreach(DuiProgressIndicator * progressindicator, progressindicators) { + progressindicator->paint(&painter, NULL); + } + + // Print used memory, it will be recorded in a log + outputAllocatedMemorySize(); + + // Release all progressindicators + qDeleteAll(progressindicators); + + endMemoryBenchmark(); + + +} + +void Mt_DuiProgressIndicator::memoryBenchmark_data() +{ + QTest::addColumn("width"); + QTest::addColumn("height"); + QTest::addColumn("viewIndex"); + QTest::addColumn("count"); + + for (qint32 viewIndex = FirstView; viewIndex < NoViews; viewIndex++) { + for (int i = 1; i < 5; ++i) { + QTest::newRow("864x64") << 864 / 2 << 64 << viewIndex << i; + QTest::newRow("864x128") << 864 / 2 << 128 << viewIndex << i; + } + } +} + +QTEST_APPLESS_MAIN(Mt_DuiProgressIndicator) + diff --git a/benchmarks/mt_duiprogressindicator/mt_duiprogressindicator.h b/benchmarks/mt_duiprogressindicator/mt_duiprogressindicator.h new file mode 100644 index 000000000..179d3683c --- /dev/null +++ b/benchmarks/mt_duiprogressindicator/mt_duiprogressindicator.h @@ -0,0 +1,47 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef MT_DUIPROGRESSINDICATOR_H +#define MT_DUIPROGRESSINDICATOR_H + +#include +#include + +class Mt_DuiProgressIndicator : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase(); + void cleanupTestCase(); + void memoryBenchmark(); + void memoryBenchmark_data(); + +private: + enum ViewName { + FirstView = 0, + Default = 0, + Bar, + NoViews + }; + +}; + +#endif + diff --git a/benchmarks/mt_duiprogressindicator/mt_duiprogressindicator.pro b/benchmarks/mt_duiprogressindicator/mt_duiprogressindicator.pro new file mode 100644 index 000000000..309855508 --- /dev/null +++ b/benchmarks/mt_duiprogressindicator/mt_duiprogressindicator.pro @@ -0,0 +1,7 @@ +include(../common_top.pri) +INCLUDEPATH += ../../src/include +DEPENDPATH += ../../src/include +TARGET = mt_duiprogressindicator + +SOURCES += mt_duiprogressindicator.cpp +HEADERS += mt_duiprogressindicator.h diff --git a/benchmarks/performancebenchmark/emptymainloophelper.cpp b/benchmarks/performancebenchmark/emptymainloophelper.cpp new file mode 100644 index 000000000..7d3061fa7 --- /dev/null +++ b/benchmarks/performancebenchmark/emptymainloophelper.cpp @@ -0,0 +1,59 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "emptymainloophelper.h" + +#include +#include + +#include + + +EmptyMainLoopHelper::EmptyMainLoopHelper() +{ +} + +void EmptyMainLoopHelper::triggerTermination(TerminationType type) +{ + terminationType = type; + QTimer::singleShot(0, this, SLOT(terminateOnEmptyMainLoop())); +} + +void EmptyMainLoopHelper::terminateOnEmptyMainLoop() +{ + if (qApp->hasPendingEvents()) { + QTimer::singleShot(0, this, SLOT(terminateOnEmptyMainLoop())); + } else { + QTimer::singleShot(20, this, SLOT(terminateOnEmptyMainLoop2())); + } +} + +void EmptyMainLoopHelper::terminateOnEmptyMainLoop2() +{ + if (qApp->hasPendingEvents()) { + QTimer::singleShot(0, this, SLOT(terminateOnEmptyMainLoop())); + } else { + if (terminationType == ExitOnEmpty) { + exit(0); + } else { + qApp->quit(); + } + } +} + diff --git a/benchmarks/performancebenchmark/emptymainloophelper.h b/benchmarks/performancebenchmark/emptymainloophelper.h new file mode 100644 index 000000000..bb48fa29b --- /dev/null +++ b/benchmarks/performancebenchmark/emptymainloophelper.h @@ -0,0 +1,58 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef EMPTYMAINLOOPHELPER_H +#define EMPTYMAINLOOPHELPER_H + +#include + +/** + * \class EmptyMainLoopHelper + * \brief Allows to terminate the application when the main loop is empty. + */ +class EmptyMainLoopHelper : public QObject +{ + Q_OBJECT +public: + enum TerminationType { ExitOnEmpty, QuitOnEmpty }; + + EmptyMainLoopHelper(); + + /** + * Once this method is called the application is terminated as soon as the main loop is empty. + * /param Defines how the application will be terminated. + */ + void triggerTermination(TerminationType type); + +public slots: + /** + * Exit the application if main loop is empty in combination with terminateOnEmptyMainLoop2(). + */ + void terminateOnEmptyMainLoop(); + + /** + * Called by terminateOnEmptyMainLoop() to terminate app if main loop is really empty. + */ + void terminateOnEmptyMainLoop2(); + +private: + TerminationType terminationType; +}; + +#endif // EMPTYMAINLOOPHELPER_H diff --git a/benchmarks/pt_duiapplication/.gitignore b/benchmarks/pt_duiapplication/.gitignore new file mode 100644 index 000000000..c33f4e95a --- /dev/null +++ b/benchmarks/pt_duiapplication/.gitignore @@ -0,0 +1 @@ +pt_duiapplication diff --git a/benchmarks/pt_duiapplication/pt_duiapplication.cpp b/benchmarks/pt_duiapplication/pt_duiapplication.cpp new file mode 100644 index 000000000..757f3f972 --- /dev/null +++ b/benchmarks/pt_duiapplication/pt_duiapplication.cpp @@ -0,0 +1,95 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include + +#include + +#include "pt_duiapplication.h" + +/* + Test how long it takes to launch an application which is quitting immediately. +*/ +void Pt_DuiApplication::processCreation() +{ + executeSelf(QLatin1String("--exit-immediately")); +} + +void Pt_DuiApplication::processCreationAndCtor() +{ + executeSelf(QLatin1String("--exit-after-qapp")); +} + +void Pt_DuiApplication::ctor() +{ + DuiApplication *a; + QBENCHMARK { + int fakeArgc = 1; + char *fakeArgv[fakeArgc]; + char appName[] = "./pt_duiapplication"; + fakeArgv[0] = appName; + a = new DuiApplication(fakeArgc, fakeArgv); + } + delete a; +} + +void Pt_DuiApplication::ctor2() +{ + DuiApplication *a; + QBENCHMARK { + int fakeArgc = 1; + char *fakeArgv[fakeArgc]; + char appName[] = "./pt_duiapplication2"; + fakeArgv[0] = appName; + a = new DuiApplication(fakeArgc, fakeArgv); + } + delete a; +} + +void Pt_DuiApplication::executeSelf(const QLatin1String ¶meter) +{ + QProcess proc; + const QString program = "./pt_duiapplication"; + const QStringList arguments = QStringList() << QLatin1String(parameter); + + QBENCHMARK { + proc.start(program, arguments); + QVERIFY(proc.waitForStarted()); + QVERIFY(proc.waitForFinished()); + QCOMPARE(proc.exitStatus(), QProcess::NormalExit); + QCOMPARE(proc.exitCode(), 0); + } +} + +int main(int argc, char **argv) +{ + if (argc == 2 && QLatin1String("--exit-immediately") == QLatin1String(argv[1])) { + return 0; + } + + if (argc == 2 && QLatin1String("--exit-after-qapp") == QLatin1String(argv[1])) { + DuiApplication app(argc, argv); + return 0; + } + + Pt_DuiApplication test; + return QTest::qExec(&test, argc, argv); +} + diff --git a/benchmarks/pt_duiapplication/pt_duiapplication.h b/benchmarks/pt_duiapplication/pt_duiapplication.h new file mode 100644 index 000000000..a24b868cf --- /dev/null +++ b/benchmarks/pt_duiapplication/pt_duiapplication.h @@ -0,0 +1,63 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef PT_QAPPLICATION_H +#define PT_QAPPLICATION_H + +#include + +/** + * Test performance oif the DuiApplication constructor. + * The constructor is created in process and as part of a newly created process. + */ +class Pt_DuiApplication : public QObject +{ + Q_OBJECT +private slots: + /** + * Test how long it takes to launch an application which is quitting immediately. + */ + void processCreation(); + + /** + * Test the performance of the duiapplication constructor. + * + * This test creates a new process and thus includes process creation overhead. + * Callgrind results are meaningless since the child process is not traced. + */ + void processCreationAndCtor(); + + /** + * Test the performance of the duiapplication constructor. + */ + void ctor(); + + /** + * Execute the constructor a second time to evaluate caching possibilities. + */ + void ctor2(); + +private: + /** + * Executes the current programm with a given parameter. + */ + void executeSelf(const QLatin1String ¶meter); +}; + +#endif // PT_QAPPLICATION_H diff --git a/benchmarks/pt_duiapplication/pt_duiapplication.pro b/benchmarks/pt_duiapplication/pt_duiapplication.pro new file mode 100644 index 000000000..c94f71a8f --- /dev/null +++ b/benchmarks/pt_duiapplication/pt_duiapplication.pro @@ -0,0 +1,4 @@ +include(../common_top.pri) +TARGET = pt_duiapplication +SOURCES = pt_duiapplication.cpp +HEADERS += pt_duiapplication.h diff --git a/benchmarks/pt_duicomponentdata/.gitignore b/benchmarks/pt_duicomponentdata/.gitignore new file mode 100644 index 000000000..af554a4c5 --- /dev/null +++ b/benchmarks/pt_duicomponentdata/.gitignore @@ -0,0 +1 @@ +pt_duicomponentdata diff --git a/benchmarks/pt_duicomponentdata/pt_duicomponentdata.cpp b/benchmarks/pt_duicomponentdata/pt_duicomponentdata.cpp new file mode 100644 index 000000000..c95629538 --- /dev/null +++ b/benchmarks/pt_duicomponentdata/pt_duicomponentdata.cpp @@ -0,0 +1,39 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "pt_duicomponentdata.h" + +#include +#include + +void Pt_DuiComponentData::constructor() +{ + int argc = 1; + char *argv[argc]; + char appName[] = "./widgetsgallery"; + argv[0] = appName; + + DuiComponentData *componentData; + QBENCHMARK_ONCE { + componentData = new DuiComponentData(argc, argv, appName); + } + delete componentData; +} + +QTEST_MAIN(Pt_DuiComponentData) diff --git a/benchmarks/pt_duicomponentdata/pt_duicomponentdata.h b/benchmarks/pt_duicomponentdata/pt_duicomponentdata.h new file mode 100644 index 000000000..dd7a3908f --- /dev/null +++ b/benchmarks/pt_duicomponentdata/pt_duicomponentdata.h @@ -0,0 +1,42 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef PT_DuiComponentData_H +#define PT_DuiComponentData_H + +#include +#include + +class DuiComponentData; +class DuiWidgetView; + +/** + * DuiApplication constructor spends most of its runtime creating a + * DuiComponentData object. This test benchmarks the DuiComponentData + * creation. + */ +class Pt_DuiComponentData : public QObject +{ + Q_OBJECT + +private slots: + void constructor(); +}; + +#endif diff --git a/benchmarks/pt_duicomponentdata/pt_duicomponentdata.pro b/benchmarks/pt_duicomponentdata/pt_duicomponentdata.pro new file mode 100644 index 000000000..c90bf4025 --- /dev/null +++ b/benchmarks/pt_duicomponentdata/pt_duicomponentdata.pro @@ -0,0 +1,7 @@ +include(../common_top.pri) +INCLUDEPATH += ../../src/include +DEPENDPATH += $$INCLUDEPATH +TARGET = pt_duicomponentdata + +SOURCES += pt_duicomponentdata.cpp +HEADERS += pt_duicomponentdata.h diff --git a/benchmarks/pt_duiicontestcase/pt_duiicontestcase.cpp b/benchmarks/pt_duiicontestcase/pt_duiicontestcase.cpp new file mode 100644 index 000000000..6cc58372e --- /dev/null +++ b/benchmarks/pt_duiicontestcase/pt_duiicontestcase.cpp @@ -0,0 +1,146 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pt_duiicontestcase.h" + +DuiApplication *app; + +void Pt_DuiButton::initTestCase() +{ + int argc = 1; + const char *argv[argc]; + char appName[] = "./eternia"; + argv[0] = appName; + app = new DuiApplication(argc, (char **)argv); + DuiTheme::instance()->changeTheme("common"); + DuiTheme::addPixmapDirectory("images/", true); + + currentViewIndex = 0; +} + +void Pt_DuiButton::cleanupTestCase() +{ + delete app; +} + +void Pt_DuiButton::init() +{ + // get size dimensions for test + QFETCH(qint32, viewIndex); + QFETCH(qint32, width); + QFETCH(qint32, height); + + this->currentViewIndex = viewIndex; + this->width = width; + this->height = height; + + // create widget, set size + m_subject = new DuiButton(); + + m_subject->setObjectName("MyButton2"); + m_subject->setText("SILENCE!"); + m_subject->setMinimumSize(width, height); + m_subject->setMaximumSize(width, height); + + // create wanted view + views[ this->currentViewIndex ] = new DuiButtonView(m_subject); + + m_subject->setView(views[ this->currentViewIndex ]); // transfers ownership to controller + m_subject->setIconID("Icon-mute"); + + views[ this->currentViewIndex ]->updateStyle(); + views[ this->currentViewIndex ]->styleUpdated(); + + // if this is paced above 'updateStyle()', then get a core dump; if above setView(), then no icon + //m_subject->setIconID("Icon-mute"); + qDebug() << "ICONID" << m_subject->iconID(); + + sleep(1); + QCoreApplication::processEvents(); + + // create pixmap paintdevice + pixmap = new QPixmap(width, height); + pixmap->fill(Qt::black); + painter = new QPainter(pixmap); +} + +void Pt_DuiButton::cleanup() +{ + // save a shot (for debugging) +#define SCREENSHOT +#ifdef SCREENSHOT + QString kuva; + QTextStream(&kuva) + << "view_" + << this->currentViewIndex + << "_" + << m_subject->size().width() + << "x" + << m_subject->size().height() + << ".png"; + if (!written.contains(kuva)) { + pixmap->save(kuva, "png", -1); + written.append(kuva); + } +#endif + + // delete m_subject; + // m_subject = 0; + // if you call 'setView()' on this, then the controller owns the object + //delete view; + //view = 0; + delete painter; + painter = 0; + delete pixmap; + pixmap = 0; + +} + +void Pt_DuiButton::paintPerformance() +{ + // actual benchmark + //QBENCHMARK + { + views[ currentViewIndex ]->paint(painter, NULL); + } +} + +void Pt_DuiButton::paintPerformance_data() +{ + QTest::addColumn("width"); + QTest::addColumn("height"); + QTest::addColumn("viewIndex"); + + QTest::newRow("864x480") << 864 << 480 << 0; +} + +QTEST_APPLESS_MAIN(Pt_DuiButton) diff --git a/benchmarks/pt_duiicontestcase/pt_duiicontestcase.h b/benchmarks/pt_duiicontestcase/pt_duiicontestcase.h new file mode 100644 index 000000000..1090b6a6d --- /dev/null +++ b/benchmarks/pt_duiicontestcase/pt_duiicontestcase.h @@ -0,0 +1,71 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef PT_DUIICONTESTCASE_H +#define PT_DUIICONTESTCASE_H + +#include +#include + +class DuiButton; +class DuiButtonView; +class DuiButtonIconView; +class DuiButtonObjectMenuItemView; +class DuiButtonSpinView; +class DuiButtonViewMenuItemView; +class DuiButtonViewMenuView; +class DuiWidgetView; + +class Pt_DuiButton : public QObject +{ + Q_OBJECT + +private slots: + void init(); + void cleanup(); + void initTestCase(); + void cleanupTestCase(); + + // paint handler performance + + void paintPerformance(); + void paintPerformance_data(); + +private: + DuiButton *m_subject; + enum ViewName { + View = 0, + IconView, + ObjectMenuItemView, + SpinView, + ViewMenuItemView, + ViewMenuView, + NoViews + }; + DuiWidgetView *views[ NoViews ]; + + qint32 currentViewIndex; + QPixmap *pixmap; + QPainter *painter; + qint32 width; + qint32 height; + QList written; +}; + +#endif diff --git a/benchmarks/pt_duiicontestcase/pt_duiicontestcase.pro b/benchmarks/pt_duiicontestcase/pt_duiicontestcase.pro new file mode 100644 index 000000000..e2010ce1b --- /dev/null +++ b/benchmarks/pt_duiicontestcase/pt_duiicontestcase.pro @@ -0,0 +1,7 @@ +include(../common_top.pri) +INCLUDEPATH += ../../src/include +DEPENDPATH += ../../src/include +TARGET = pt_duiicontestcase + +SOURCES += pt_duiicontestcase.cpp +HEADERS += pt_duiicontestcase.h diff --git a/benchmarks/pt_duiimagewidget/.gitignore b/benchmarks/pt_duiimagewidget/.gitignore new file mode 100644 index 000000000..df395f070 --- /dev/null +++ b/benchmarks/pt_duiimagewidget/.gitignore @@ -0,0 +1 @@ +pt_duiimagewidget diff --git a/benchmarks/pt_duiimagewidget/pt_duiimagewidget.cpp b/benchmarks/pt_duiimagewidget/pt_duiimagewidget.cpp new file mode 100644 index 000000000..e0ee29ee3 --- /dev/null +++ b/benchmarks/pt_duiimagewidget/pt_duiimagewidget.cpp @@ -0,0 +1,104 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "pt_duiimagewidget.h" + +#include +#include +#include +#include +#include + + +DuiApplication *app; + +void Pt_DuiImageWidget::initTestCase() +{ + int argc = 1; + char *app_name = (char *) "./pt_duiimage"; + app = new DuiApplication(argc, &app_name); + DuiTheme::addPixmapDirectory(QCoreApplication::applicationDirPath()); + + m_subject = new DuiImageWidget(); +} + +void Pt_DuiImageWidget::cleanupTestCase() +{ + delete m_subject; + delete app; +} + +void Pt_DuiImageWidget::paintPerformance_data() +{ + //wait for the resource loading to finish + while (DuiTheme::instance()->hasPendingRequests()) { + usleep(100); + QCoreApplication::processEvents(); + } + + QTest::addColumn("width"); + QTest::addColumn("height"); + QTest::addColumn("imagename"); + + QTest::newRow("300x300 PNG") << 300 << 300 << "testpng"; + QTest::newRow("300x300 SVG") << 300 << 300 << "Layer_1"; + + // fullscreen + QTest::newRow("864x480 PNG") << 864 << 480 << "testpng"; + QTest::newRow("864x480 SVG") << 864 << 480 << "Layer_1"; +} + +void Pt_DuiImageWidget::paintPerformance() +{ + QFETCH(qint32, width); + QFETCH(qint32, height); + QFETCH(QString, imagename); + + m_subject->setImage(imagename); + m_subject->setGeometry(QRectF(0, 0, width, height)); + + // create pixmap paintdevice + QPixmap *pixmap = new QPixmap(width, height); + pixmap->fill(QColor(0, 0, 0, 0)); + QPainter *painter = new QPainter(pixmap); + + // actual benchmark + QBENCHMARK { + m_subject->paint(painter, NULL); + } + + // save a shot (for debugging) +#ifdef SCREENSHOT + + QStringList list; + list.append(imagename); + list.append(QString::number(this->m_subject->size().width())); + list.append(QString::number(this->m_subject->size().height())); + + QString kuva = list.join("_") + ".png"; + pixmap->save(kuva, "png", -1); + +#endif + + delete painter; + delete pixmap; +} + + +QTEST_APPLESS_MAIN(Pt_DuiImageWidget) diff --git a/benchmarks/pt_duiimagewidget/pt_duiimagewidget.h b/benchmarks/pt_duiimagewidget/pt_duiimagewidget.h new file mode 100644 index 000000000..20cd75f8e --- /dev/null +++ b/benchmarks/pt_duiimagewidget/pt_duiimagewidget.h @@ -0,0 +1,46 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef PT_DUIIMAGEWIDGET_H +#define PT_DUIIMAGEWIDGET_H + +#include +#include + +class DuiImageWidget; +class DuiImageWidgetView; + +class Pt_DuiImageWidget : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase(); + void cleanupTestCase(); + + // paint handler performance + void paintPerformance(); + void paintPerformance_data(); + +private: + DuiImageWidget *m_subject; + +}; + +#endif diff --git a/benchmarks/pt_duiimagewidget/pt_duiimagewidget.pro b/benchmarks/pt_duiimagewidget/pt_duiimagewidget.pro new file mode 100644 index 000000000..08d62511c --- /dev/null +++ b/benchmarks/pt_duiimagewidget/pt_duiimagewidget.pro @@ -0,0 +1,7 @@ +include(../common_top.pri) +INCLUDEPATH += ../../src/include ../../src/theme +DEPENDPATH += $$INCLUDEPATH +TARGET = pt_duiimagewidget + +SOURCES += pt_duiimagewidget.cpp +HEADERS += pt_duiimagewidget.h diff --git a/benchmarks/pt_duiimagewidget/testpng.png b/benchmarks/pt_duiimagewidget/testpng.png new file mode 100755 index 000000000..23c523367 Binary files /dev/null and b/benchmarks/pt_duiimagewidget/testpng.png differ diff --git a/benchmarks/pt_duiimagewidget/testsvg.svg b/benchmarks/pt_duiimagewidget/testsvg.svg new file mode 100644 index 000000000..cfbb3f1bc --- /dev/null +++ b/benchmarks/pt_duiimagewidget/testsvg.svg @@ -0,0 +1,15954 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SB_P + + r + + essed + + SB_P + + r + + essed + + + + + + SB_Released + + SB_Released + + + + + + SB_On + + SB_On + + + + + + SB_Disabled + + SB_Disabled + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + B + u + t + t + on + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + B + u + t + t + on + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + B + u + t + t + on + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + B + u + t + t + on + + + + + + + + + + + + + + + + + + + + + Mu + + t + + e + + Mu + + t + + e + + + + + + SB_Normal + + SB_Normal + + + + + + Slider_mu + + t + + e + + Slider_mu + + t + + e + + + + + + (smooth one bullet blink animation) + + (smooth one bullet blink animation) + + + + + + Slider_selec + + t + + ed_finger_up + + Slider_selec + + t + + ed_finger_up + + + + + + I + + c + + on-home-normal + + I + + c + + on-home-normal + + + + + + I + + c + + on-home-p + + r + + ess + + I + + c + + on-home-p + + r + + ess + + + + + + I + + c + + on-home- + + r + + elease + + I + + c + + on-home- + + r + + elease + + + + + + I + + c + + on-close-normal + + I + + c + + on-close-normal + + + + + + I + + c + + on-close-p + + r + + ess + + I + + c + + on-close-p + + r + + ess + + + + + + I + + c + + on-close- + + r + + elease + + I + + c + + on-close- + + r + + elease + + + + + + Slider_finger_p + + r + + ess/d + + r + + ag + + Slider_finger_p + + r + + ess/d + + r + + ag + + + + + + Without label + + Without label + + + + + + With label + + With label + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Sending + + Sending + + + + + + SB_P + + r + + og + + r + + ess_1 + + SB_P + + r + + og + + r + + ess_1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Sending + + Sending + + + + + + SB_P + + r + + og + + r + + ess_3 + + SB_P + + r + + og + + r + + ess_3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Sending + + Sending + + + + + + SB_P + + r + + og + + r + + ess_4 + + SB_P + + r + + og + + r + + ess_4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Sending + + Sending + + + + + + SB_P + + r + + og + + r + + ess_5 + + SB_P + + r + + og + + r + + ess_5 + + + + + + SB_g + + r + + aph_normal_bg + + SB_g + + r + + aph_normal_bg + + + + + + SB_g + + r + + aph_p + + r + + essed_bg + + SB_g + + r + + aph_p + + r + + essed_bg + + + + + + SB_g + + r + + aph_on_bg + + SB_g + + r + + aph_on_bg + + + + + + SB_g + + r + + aph_ + + r + + eleased_bg + + SB_g + + r + + aph_ + + r + + eleased_bg + + + + + + SB_g + + r + + aph_disabled_bg + + SB_g + + r + + aph_disabled_bg + + + + + + SB_g + + r + + aph_bo + + r + + der + + SB_g + + r + + aph_bo + + r + + der + + + + + + SB_P + + r + + og + + r + + ess_g + + r + + aph + + SB_P + + r + + og + + r + + ess_g + + r + + aph + + + + + + SB_P + + r + + og + + r + + ess_mas + + k + + ed + + SB_P + + r + + og + + r + + ess_mas + + k + + ed + + + + + + SB_g + + r + + aph_disabled_btn + + SB_g + + r + + aph_disabled_btn + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Sending + + Sending + + + + + + SB_P + + r + + og + + r + + ess_2 + + SB_P + + r + + og + + r + + ess_2 + + + + DUI + c + om + p + one + n + t + s + DUI + c + om + p + one + n + t + s + + + SB_g + + r + + aph_normal_btn + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Simple but + t + on (SB) + I + c + ons + P + r + o + g + r + ess but + t + on + SB_pie + c + es + Slider + + + + + Slider_pie + c + es + + V + iew_menu + + T + oolbar + + + + + + + + + + + + + + + + + + + + + Mu + s + ic & + R + a + d + io + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/benchmarks/pt_duilabel/pt_duilabel.cpp b/benchmarks/pt_duilabel/pt_duilabel.cpp new file mode 100644 index 000000000..c6d25c492 --- /dev/null +++ b/benchmarks/pt_duilabel/pt_duilabel.cpp @@ -0,0 +1,134 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include +#include +#include + +#include "pt_duilabel.h" + +DuiApplication *app; + +void Pt_DuiLabel::initTestCase() +{ + int argc = 1; + const char *argv[argc]; + char appName[] = "./eternia"; + argv[0] = appName; + app = new DuiApplication(argc, (char **)argv); + DuiTheme::instance()->changeTheme("common"); + + currentViewIndex = 0; +} + +void Pt_DuiLabel::cleanupTestCase() +{ + delete app; +} + +void Pt_DuiLabel::init() +{ + // get size dimensions for test + QFETCH(QString, text); + QFETCH(qint32, viewIndex); + + this->currentViewIndex = viewIndex; + + // create widget, set size + m_subject = new DuiLabel(text); + + m_subject->setMaximumWidth(864); + + switch (this->currentViewIndex) { + case View: + this->currentView = new DuiLabelView(m_subject); + break; + } + + this->currentView->updateStyle(); + //this->currentView->styleUpdated(); + + // There is no DuiLabel::setView() so this is the one from + // DuiWidgetController, which is private, so need to be friends + m_subject->setView(this->currentView); // transfers ownership to controller + + // wait for the image loading + usleep(1000000); + QCoreApplication::processEvents(); + + // create pixmap paintdevice + pixmap = new QPixmap(846, 480); + pixmap->fill(QColor(0, 0, 0, 0)); + painter = new QPainter(pixmap); +} + +void Pt_DuiLabel::cleanup() +{ + // save a shot (for debugging) +#define SCREENSHOT +#ifdef SCREENSHOT + QString kuva; + QTextStream(&kuva) + << "view_" + << this->currentViewIndex + << "_" + << m_subject->size().width() + << "x" + << m_subject->size().height() + << ".png"; + if (!written.contains(kuva)) { + pixmap->save(kuva, "png", -1); + written.append(kuva); + } +#endif + + delete m_subject; + m_subject = 0; + + delete painter; + painter = 0; + delete pixmap; + pixmap = 0; + +} + +void Pt_DuiLabel::paintPerformance() +{ + // actual benchmark + QBENCHMARK { + this->currentView->paint(painter, NULL); + } +} + +void Pt_DuiLabel::paintPerformance_data() +{ + QTest::addColumn("text"); + QTest::addColumn("viewIndex"); + + for (qint32 viewIndex = 0; viewIndex < NoViews; viewIndex++) { + // typical icon sizes + QTest::newRow("plaintext") << "Silence!" << viewIndex; + QTest::newRow("richtext") << "Silence! I kill you!" << viewIndex; + QTest::newRow("veryrich") << "
Very rich text, multi line label

The phrase \"to be, or not to be\" comes from William Shakespeare's Hamlet (written about 1600), act three, scene one. It is one of the most famous quotations in world literature and the best-known of this particular play...

And tables...
Cell 1Cell 2

" << viewIndex; + } +} + +QTEST_APPLESS_MAIN(Pt_DuiLabel) diff --git a/benchmarks/pt_duilabel/pt_duilabel.h b/benchmarks/pt_duilabel/pt_duilabel.h new file mode 100644 index 000000000..d2392b061 --- /dev/null +++ b/benchmarks/pt_duilabel/pt_duilabel.h @@ -0,0 +1,60 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef PT_DUILABEL_H +#define PT_DUILABEL_H + +#include +#include + +class DuiLabel; +class DuiWidgetView; + +class Pt_DuiLabel : public QObject +{ + Q_OBJECT + +private slots: + void init(); + void cleanup(); + void initTestCase(); + void cleanupTestCase(); + + // paint handler performance + + void paintPerformance(); + void paintPerformance_data(); + +private: + DuiLabel *m_subject; + enum ViewName { + View = 0, + NoViews + }; + DuiWidgetView *currentView; + + qint32 currentViewIndex; + QPixmap *pixmap; + QPainter *painter; + qint32 width; + qint32 height; + QList written; +}; + +#endif diff --git a/benchmarks/pt_duilabel/pt_duilabel.pro b/benchmarks/pt_duilabel/pt_duilabel.pro new file mode 100644 index 000000000..3d3e6a0f2 --- /dev/null +++ b/benchmarks/pt_duilabel/pt_duilabel.pro @@ -0,0 +1,7 @@ +include(../common_top.pri) +INCLUDEPATH += ../../src/include +DEPENDPATH += ../../src/include +TARGET = pt_duilabel + +SOURCES += pt_duilabel.cpp +HEADERS += pt_duilabel.h diff --git a/benchmarks/pt_duiscalableimage/pt_duiscalableimage.cpp b/benchmarks/pt_duiscalableimage/pt_duiscalableimage.cpp new file mode 100644 index 000000000..a30ef4eb3 --- /dev/null +++ b/benchmarks/pt_duiscalableimage/pt_duiscalableimage.cpp @@ -0,0 +1,206 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include +#include +#include +#include "duiglrenderer.h" + +#include "pt_duiscalableimage.h" + +#ifdef DUI_USE_OPENGL +#include +#endif + +DuiApplication *app; +#ifdef DUI_USE_OPENGL +QGLWidget *glw = NULL; +#endif +void Pt_DuiScalableImage::initTestCase() +{ + int argc = 1; + char *app_name = (char *) "./pt_duiscalableimage"; + app = new DuiApplication(argc, &app_name); +#ifdef DUI_USE_OPENGL + glw = new QGLWidget(); + DuiGLRenderer::instance()->initGL(glw); +#endif +} + +void Pt_DuiScalableImage::cleanupTestCase() +{ +#ifdef DUI_USE_OPENGL + delete glw; +#endif + delete app; +} + +void Pt_DuiScalableImage::init() +{ + //wait for the resource loading to finish + while (DuiTheme::instance()->hasPendingRequests()) { + usleep(100); + QCoreApplication::processEvents(); + } +} + +void Pt_DuiScalableImage::paintScalablePerformance_data() +{ + QTest::addColumn("width"); + QTest::addColumn("height"); + QTest::addColumn("HW"); + QTest::addColumn("useGLRenderer"); + + QTest::newRow("300x300 SW") << 300 << 300 << false << false; + QTest::newRow("300x300 HW !DuiGLRenderer") << 300 << 300 << true << false; + QTest::newRow("300x300 HW DuiGLRenderer") << 300 << 300 << true << true; +} + +void Pt_DuiScalableImage::paintScalablePerformance() +{ + QFETCH(qint32, width); + QFETCH(qint32, height); + QFETCH(bool, HW); + QFETCH(bool, useGLRenderer); + + DuiScalableImage *image = const_cast(DuiTheme::scalableImage("stretchbutton", 11, 11, 11, 11)); + image->enableOptimizedRendering(useGLRenderer); + + QPainter painter; + QPixmap *pixmap = NULL; + if (!HW) { + pixmap = new QPixmap(width, height); + pixmap->fill(QColor(255, 255, 255, 255)); + painter.begin(pixmap); + } else { +#ifdef DUI_USE_OPENGL + glw->resize(width, height); + DuiGLRenderer::instance()->initGL(glw); + painter.begin(glw); + painter.fillRect(0, 0, width, height, QColor(255, 255, 255, 255)); +#else + qWarning("Cannot run HW test."); +#endif + } + + // actual benchmark + if (painter.isActive()) { + QBENCHMARK { + image->draw(0, 0, width, height, &painter); + } + painter.end(); + } + // save a shot (for debugging) +#define SCREENSHOT +#ifdef SCREENSHOT + QString kuva; + kuva.sprintf("scalable_%d_%d_%d_%d.png", width, height, HW, useGLRenderer); + if (pixmap) + pixmap->save(kuva, "png", -1); + else { +#ifdef DUI_USE_OPENGL + glw->grabFrameBuffer().save(kuva, "png", -1); +#endif + } +#endif + delete pixmap; + DuiTheme::releaseScalableImage(image); +} + +void Pt_DuiScalableImage::paintPixmapPerformance_data() +{ + QTest::addColumn("width"); + QTest::addColumn("height"); + QTest::addColumn("HW"); + QTest::addColumn("useGLRenderer"); + + QTest::newRow("300x300 SW") << 300 << 300 << false << false; + QTest::newRow("300x300 HW !DuiGLRenderer") << 300 << 300 << true << false; + QTest::newRow("300x300 HW DuiGLRenderer") << 300 << 300 << true << true; +} + + +void Pt_DuiScalableImage::paintPixmapPerformance() +{ + QFETCH(qint32, width); + QFETCH(qint32, height); + QFETCH(bool, HW); + QFETCH(bool, useGLRenderer); + + const QPixmap *image = DuiTheme::pixmap("stretchbutton", QSize(width, height)); + //glw->bindTexture(*image); + //((MyScalable*)image)->setUseDuiGLRenderer(useGLRenderer); + //wait for the resource loading to finish + while (DuiTheme::instance()->hasPendingRequests()) { + usleep(100); + QCoreApplication::processEvents(); + } + QPainter painter; + QPixmap *pixmap = NULL; + if (!HW) { + pixmap = new QPixmap(width, height); + pixmap->fill(QColor(255, 255, 255, 255)); + painter.begin(pixmap); + } else { +#ifdef DUI_USE_OPENGL + glw->resize(width, height); + painter.begin(glw); + painter.fillRect(0, 0, width, height, QColor(255, 255, 255, 255)); +#else + qWarning("Cannot run HW test."); +#endif + } + + //warmup + //painter.drawPixmap(0, 0, *image); + + // actual benchmark + if (painter.isActive()) { + if (useGLRenderer) { +#ifdef DUI_USE_OPENGL + QBENCHMARK { + DuiGLRenderer::instance()->drawPixmap(painter.combinedTransform(), *image, 1.0); + } +#endif + } else { + QBENCHMARK { + painter.drawPixmap(0, 0, *image); + } + } + painter.end(); + } + // save a shot (for debugging) +#define SCREENSHOT +#ifdef SCREENSHOT + QString kuva; + kuva.sprintf("pixmap_%d_%d_%d_%d.png", width, height, HW, useGLRenderer); + if (pixmap) + pixmap->save(kuva, "png", -1); + else { +#ifdef DUI_USE_OPENGL + glw->grabFrameBuffer().save(kuva, "png", -1); +#endif + } +#endif + delete pixmap; + DuiTheme::releasePixmap(image); +} +QTEST_APPLESS_MAIN(Pt_DuiScalableImage) diff --git a/benchmarks/pt_duiscalableimage/pt_duiscalableimage.h b/benchmarks/pt_duiscalableimage/pt_duiscalableimage.h new file mode 100644 index 000000000..690755fe6 --- /dev/null +++ b/benchmarks/pt_duiscalableimage/pt_duiscalableimage.h @@ -0,0 +1,43 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef PT_DUISCALABLEIMAGE_H +#define PT_DUISCALABLEIMAGE_H + +#include +#include + +class Pt_DuiScalableImage : public QObject +{ + Q_OBJECT + +private slots: + void init(); + void initTestCase(); + void cleanupTestCase(); + + void paintScalablePerformance(); + void paintScalablePerformance_data(); + + void paintPixmapPerformance(); + void paintPixmapPerformance_data(); + +}; + +#endif diff --git a/benchmarks/pt_duiscalableimage/pt_duiscalableimage.pro b/benchmarks/pt_duiscalableimage/pt_duiscalableimage.pro new file mode 100644 index 000000000..b68ac9c46 --- /dev/null +++ b/benchmarks/pt_duiscalableimage/pt_duiscalableimage.pro @@ -0,0 +1,12 @@ +include(../common_top.pri) +INCLUDEPATH += ../../src/include ../../src/theme ../../src/painting +DEPENDPATH += $$INCLUDEPATH +TARGET = pt_duiscalableimage + +SOURCES += pt_duiscalableimage.cpp +HEADERS += pt_duiscalableimage.h + +exists($$[QT_INSTALL_LIBS]/libQtOpenGL.so) { + QT += opengl +} + diff --git a/benchmarks/pt_duitheme/.gitignore b/benchmarks/pt_duitheme/.gitignore new file mode 100644 index 000000000..af554a4c5 --- /dev/null +++ b/benchmarks/pt_duitheme/.gitignore @@ -0,0 +1 @@ +pt_duicomponentdata diff --git a/benchmarks/pt_duitheme/pt_duitheme.cpp b/benchmarks/pt_duitheme/pt_duitheme.cpp new file mode 100644 index 000000000..f018b09ed --- /dev/null +++ b/benchmarks/pt_duitheme/pt_duitheme.cpp @@ -0,0 +1,36 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "pt_duitheme.h" + +#include +#include + +#include + +void Pt_DuiTheme::constructor() +{ + DuiTheme *theme; + QBENCHMARK_ONCE { + theme = new DuiTheme("widgetsgallery"); + } + delete theme; +} + +QTEST_MAIN(Pt_DuiTheme) diff --git a/benchmarks/pt_duitheme/pt_duitheme.h b/benchmarks/pt_duitheme/pt_duitheme.h new file mode 100644 index 000000000..0857aaca2 --- /dev/null +++ b/benchmarks/pt_duitheme/pt_duitheme.h @@ -0,0 +1,39 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef PT_DUITHEME_H +#define PT_DUITHEME_H + +#include + +class DuiComponentData; +class DuiWidgetView; + +/** + * This test benchmarks the DuiTheme creation. + */ +class Pt_DuiTheme : public QObject +{ + Q_OBJECT + +private slots: + void constructor(); +}; + +#endif diff --git a/benchmarks/pt_duitheme/pt_duitheme.pro b/benchmarks/pt_duitheme/pt_duitheme.pro new file mode 100644 index 000000000..9466e7c2f --- /dev/null +++ b/benchmarks/pt_duitheme/pt_duitheme.pro @@ -0,0 +1,7 @@ +include(../common_top.pri) +INCLUDEPATH += ../../src/include +DEPENDPATH += $$INCLUDEPATH +TARGET = pt_duitheme + +SOURCES += pt_duitheme.cpp +HEADERS += pt_duitheme.h diff --git a/benchmarks/pt_minimalduiapplication/.gitignore b/benchmarks/pt_minimalduiapplication/.gitignore new file mode 100644 index 000000000..7ec3f4621 --- /dev/null +++ b/benchmarks/pt_minimalduiapplication/.gitignore @@ -0,0 +1 @@ +pt_minimalduiapplication diff --git a/benchmarks/pt_minimalduiapplication/pt_minimalduiapplication.cpp b/benchmarks/pt_minimalduiapplication/pt_minimalduiapplication.cpp new file mode 100644 index 000000000..e40727300 --- /dev/null +++ b/benchmarks/pt_minimalduiapplication/pt_minimalduiapplication.cpp @@ -0,0 +1,151 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "pt_minimalduiapplication.h" +#include "../performancebenchmark/emptymainloophelper.h" + +#include +#include +#include +#include + +#include +#include +#include + +#define MY_QBENCHMARK_ONCE(CODE) \ + if (!noBenchmark) \ + QBENCHMARK_ONCE { \ + CODE \ + } else { \ + CODE \ + } + +Pt_minimalduiapplication::Pt_minimalduiapplication() + : appearType("appear"), noBenchmark(false) +{ +} + +int Pt_minimalduiapplication::executeAll() +{ + noBenchmark = true; + + createDuiLocale(); + createDuiApplicationWindow(); + windowShow(); + createDuiApplicationPage(); + pageAppear(); + + // terminate as soon as startup is complete and the main loop is empty + EmptyMainLoopHelper mainLoopHelper; + mainLoopHelper.triggerTermination(EmptyMainLoopHelper::ExitOnEmpty); + + return qApp->exec(); +} + +void Pt_minimalduiapplication::createDuiLocale() +{ + MY_QBENCHMARK_ONCE( + locale = new DuiLocale(); + ) +} + +void Pt_minimalduiapplication::createDuiApplicationWindow() +{ + MY_QBENCHMARK_ONCE( + window = new DuiApplicationWindow(); + ) +} + +void Pt_minimalduiapplication::windowShow() +{ + MY_QBENCHMARK_ONCE( + window->show(); + ) +} + +void Pt_minimalduiapplication::createDuiApplicationPage() +{ + MY_QBENCHMARK_ONCE( + page = new DuiApplicationPage(); + ) +} + +void Pt_minimalduiapplication::pageAppear() +{ + if (appearType == "appear") { + MY_QBENCHMARK_ONCE(page->appear();) + } else { + MY_QBENCHMARK_ONCE(page->appearNow();) + } +} + +void Pt_minimalduiapplication::overallRuntime() +{ + executeSelf("appear"); +} + +void Pt_minimalduiapplication::overallRuntimeAppearNow() +{ + executeSelf("appearNow"); +} + +void Pt_minimalduiapplication::executeSelf(const QString ¶m) +{ + QProcess proc; + const QString program = QCoreApplication::applicationFilePath(); + const QStringList arguments = QStringList() << QLatin1String("--exit-immediately") << param; + + QBENCHMARK { + // execute ourselve and check for success + proc.start(program, arguments); + QVERIFY(proc.waitForStarted()); + QVERIFY(proc.waitForFinished()); + QCOMPARE(proc.exitStatus(), QProcess::NormalExit); + QCOMPARE(proc.exitCode(), 0); + } +} + +int main(int argc, char **argv) +{ + // fake arc and argv to use the remote theme daemon + int fakeArgc = 2; + char *fakeArgv[fakeArgc]; + char remoteTheme[] = "-remote-theme"; + fakeArgv[1] = remoteTheme; + char appName[] = "./pt_minimalduiapplication"; + fakeArgv[0] = appName; + + if (argc >= 3 && strcmp("--exit-immediately", argv[1]) == 0 + && (strcmp("appear", argv[2]) == 0 || strcmp("appearNow", argv[2]) == 0)) { + // a DuiApplication can just run once. create the second one with a different name + char appName[] = "./pt_minimalduiapplication2"; + fakeArgv[0] = appName; + DuiApplication a(fakeArgc, fakeArgv); + + Pt_minimalduiapplication test; + test.appearType = argv[2]; + return test.executeAll(); + } + + DuiApplication a(fakeArgc, fakeArgv); + Pt_minimalduiapplication test; + + return QTest::qExec(&test, argc, argv); +} diff --git a/benchmarks/pt_minimalduiapplication/pt_minimalduiapplication.h b/benchmarks/pt_minimalduiapplication/pt_minimalduiapplication.h new file mode 100644 index 000000000..df99d5819 --- /dev/null +++ b/benchmarks/pt_minimalduiapplication/pt_minimalduiapplication.h @@ -0,0 +1,63 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef PT_MINIMALDUIAPPLICATION_H +#define PT_MINIMALDUIAPPLICATION_H + +#include + +class DuiLocale; +class DuiApplicationWindow; +class DuiApplicationPage; + +/** + Benchmark runtime of a simple DUI application. + All elements are benchmarked individually and the whole application is benchmarked at once. + */ +class Pt_minimalduiapplication : public QObject +{ + Q_OBJECT +public: + Pt_minimalduiapplication(); + + /** + * Execute a whole simple DUI application by calling the slots from below. + */ + int executeAll(); + + QString appearType; +private slots: + void overallRuntime(); + void overallRuntimeAppearNow(); + void createDuiLocale(); + void createDuiApplicationWindow(); + void windowShow(); + void createDuiApplicationPage(); + void pageAppear(); + +private: + void executeSelf(const QString ¶m); + bool noBenchmark; + + DuiLocale *locale; + DuiApplicationWindow *window; + DuiApplicationPage *page; +}; + +#endif // PT_MINIMALDUIAPPLICATION_H diff --git a/benchmarks/pt_minimalduiapplication/pt_minimalduiapplication.pro b/benchmarks/pt_minimalduiapplication/pt_minimalduiapplication.pro new file mode 100644 index 000000000..9372a9655 --- /dev/null +++ b/benchmarks/pt_minimalduiapplication/pt_minimalduiapplication.pro @@ -0,0 +1,6 @@ +include(../common_top.pri) +TARGET = pt_minimalduiapplication +SOURCES = pt_minimalduiapplication.cpp \ + ../performancebenchmark/emptymainloophelper.cpp +HEADERS += pt_minimalduiapplication.h \ + ../performancebenchmark/emptymainloophelper.h diff --git a/benchmarks/pt_minimalqtapplication/pt_minimalqtapplication.cpp b/benchmarks/pt_minimalqtapplication/pt_minimalqtapplication.cpp new file mode 100644 index 000000000..f8dfad6ca --- /dev/null +++ b/benchmarks/pt_minimalqtapplication/pt_minimalqtapplication.cpp @@ -0,0 +1,143 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "pt_minimalqtapplication.h" + +#define MY_QBENCHMARK_ONCE(CODE) \ + if (!noBenchmark) \ + QBENCHMARK_ONCE { \ + CODE \ + } else { \ + CODE \ + } + +Pt_minimalqtapplication::Pt_minimalqtapplication() + : noBenchmark(false) +{ +} + +int Pt_minimalqtapplication::executeAll() +{ + noBenchmark = true; + + createAndShowMainWindowAndGraphicsView(); + createGraphicsScene(); + createGLWidget(); + setupGraphicsView(); + drawSomething(); + + QTimer::singleShot(0, qApp, SLOT(quit())); + return qApp->exec(); +} + +void Pt_minimalqtapplication::createAndShowMainWindowAndGraphicsView() +{ + MY_QBENCHMARK_ONCE( + window = new QMainWindow(); + window->show(); + + graphicsView = new QGraphicsView(window); + window->setCentralWidget(graphicsView); + + ) +} + +void Pt_minimalqtapplication::createGraphicsScene() +{ + MY_QBENCHMARK_ONCE( + graphicsScene = new QGraphicsScene(graphicsView); + graphicsView->setScene(graphicsScene); + ) +} + +void Pt_minimalqtapplication::createGLWidget() +{ + MY_QBENCHMARK_ONCE( + QGLFormat fmt; + // disable multisampling, is enabled by default in Qt + fmt.setSampleBuffers(false); + fmt.setSamples(0); + + glWidget = new QGLWidget(fmt); + ) +} + +void Pt_minimalqtapplication::setupGraphicsView() +{ + MY_QBENCHMARK_ONCE( + QSize screenSize(864, 480); + + graphicsView->setOptimizationFlag(QGraphicsView::DontSavePainterState); + graphicsView->resize(screenSize); + graphicsView->setFrameStyle(0); + graphicsView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + graphicsView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + graphicsView->setSceneRect(QRectF(QPointF(), screenSize)); + graphicsView->centerOn(graphicsView->sceneRect().center()); + graphicsView->setBackgroundBrush(Qt::black); + ) +} + +void Pt_minimalqtapplication::drawSomething() +{ + MY_QBENCHMARK_ONCE( + QPen pen(Qt::green); + graphicsScene->addRect(QRect(50, 50, 100, 100), pen); + graphicsScene->addRect(QRect(150, 150, 100, 100), pen); + ) +} + +void Pt_minimalqtapplication::overallRuntime() +{ + QProcess proc; + const QString program = QCoreApplication::applicationFilePath(); + const QStringList arguments = QStringList() << QLatin1String("--exit-immediately"); + + QBENCHMARK_ONCE { + // execute ourselve and check for success + proc.start(program, arguments); + QVERIFY(proc.waitForStarted()); + QVERIFY(proc.waitForFinished()); + QCOMPARE(proc.exitStatus(), QProcess::NormalExit); + QCOMPARE(proc.exitCode(), 0); + } +} + +int main(int argc, char **argv) +{ + + QApplication a(argc, argv); + Pt_minimalqtapplication test; + + if (argc >= 2 && strcmp("--exit-immediately", argv[1]) == 0) { + return test.executeAll(); + } + + return QTest::qExec(&test, argc, argv); +} diff --git a/benchmarks/pt_minimalqtapplication/pt_minimalqtapplication.h b/benchmarks/pt_minimalqtapplication/pt_minimalqtapplication.h new file mode 100644 index 000000000..85b0779e0 --- /dev/null +++ b/benchmarks/pt_minimalqtapplication/pt_minimalqtapplication.h @@ -0,0 +1,63 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef PT_MINIMALQTAPPLICATION_H +#define PT_MINIMALQTAPPLICATION_H + +#include + +class QMainWindow; +class QGraphicsScene; +class QGraphicsView; +class QGLWidget; + +/** + * Benchmark runtime of a simple Qt application. It mimics a minimal DUI application and therefor + * creates QGraphicsView/QGraphicsscene and initializes them. + * All elements are benchmarked individually and the whole application is benchmarked at once. + */ +class Pt_minimalqtapplication : public QObject +{ + Q_OBJECT +public: + Pt_minimalqtapplication(); + + /** + * Execute a whole simple Qt application by calling the slots from below. + */ + int executeAll(); + +private slots: + void overallRuntime(); + void createAndShowMainWindowAndGraphicsView(); + void createGraphicsScene(); + void createGLWidget(); + void setupGraphicsView(); + void drawSomething(); + +private: + bool noBenchmark; + + QMainWindow *window; + QGraphicsScene *graphicsScene; + QGraphicsView *graphicsView; + QGLWidget *glWidget; +}; + +#endif // PT_MINIMALQTAPPLICATION_H diff --git a/benchmarks/pt_minimalqtapplication/pt_minimalqtapplication.pro b/benchmarks/pt_minimalqtapplication/pt_minimalqtapplication.pro new file mode 100644 index 000000000..e6f7cf64b --- /dev/null +++ b/benchmarks/pt_minimalqtapplication/pt_minimalqtapplication.pro @@ -0,0 +1,7 @@ +include(../common_top.pri) + +QT += opengl + +TARGET = pt_minimalqtapplication +SOURCES = pt_minimalqtapplication.cpp +HEADERS += pt_minimalqtapplication.h diff --git a/benchmarks/pt_qapplication/.gitignore b/benchmarks/pt_qapplication/.gitignore new file mode 100644 index 000000000..142dd6bd0 --- /dev/null +++ b/benchmarks/pt_qapplication/.gitignore @@ -0,0 +1 @@ +pt_qapplication diff --git a/benchmarks/pt_qapplication/pt_qapplication.cpp b/benchmarks/pt_qapplication/pt_qapplication.cpp new file mode 100644 index 000000000..9fa210314 --- /dev/null +++ b/benchmarks/pt_qapplication/pt_qapplication.cpp @@ -0,0 +1,92 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "pt_qapplication.h" + +#include +#include + +#include + +void Pt_QApplication::processCreation() +{ + executeSelf(QLatin1String("--exit-immediately")); +} + +void Pt_QApplication::processCreationAndCtor() +{ + executeSelf(QLatin1String("--exit-after-qapp")); +} + +void Pt_QApplication::ctor() +{ + QApplication *a; + QBENCHMARK { + int fakeArgc = 1; + char *fakeArgv[fakeArgc]; + char appName[] = "./pt_qapplication"; + fakeArgv[0] = appName; + a = new QApplication(fakeArgc, fakeArgv); + } + delete a; +} + +void Pt_QApplication::ctor2() +{ + QApplication *a; + QBENCHMARK { + int fakeArgc = 1; + char *fakeArgv[fakeArgc]; + char appName[] = "./pt_qapplication2"; + fakeArgv[0] = appName; + a = new QApplication(fakeArgc, fakeArgv); + } + delete a; +} + +void Pt_QApplication::executeSelf(const QLatin1String ¶meter) +{ + QProcess proc; + const QString program = "./pt_qapplication"; + const QStringList arguments = QStringList() << QLatin1String(parameter); + + QBENCHMARK { + proc.start(program, arguments); + QVERIFY(proc.waitForStarted()); + QVERIFY(proc.waitForFinished()); + QCOMPARE(proc.exitStatus(), QProcess::NormalExit); + QCOMPARE(proc.exitCode(), 0); + } +} + +int main(int argc, char **argv) +{ + if (argc == 2 && QLatin1String("--exit-immediately") == QLatin1String(argv[1])) { + return 0; + } + + if (argc == 2 && QLatin1String("--exit-after-qapp") == QLatin1String(argv[1])) { + QApplication app(argc, argv); + return 0; + } + + Pt_QApplication test; + return QTest::qExec(&test, argc, argv); +} + diff --git a/benchmarks/pt_qapplication/pt_qapplication.h b/benchmarks/pt_qapplication/pt_qapplication.h new file mode 100644 index 000000000..be7e7f105 --- /dev/null +++ b/benchmarks/pt_qapplication/pt_qapplication.h @@ -0,0 +1,63 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef PT_QAPPLICATION_H +#define PT_QAPPLICATION_H + +#include + +/** + * Test performance oif the QApplication constructor. + * The constructor is created in process and as part of a newly created process. + */ +class Pt_QApplication : public QObject +{ + Q_OBJECT +private slots: + /** + * Test how long it takes to launch an application which is quitting immediately. + */ + void processCreation(); + + /** + * Test the performance of the qapplication constructor. + * + * This test creates a new process and thus includes process creation overhead. + * Callgrind results are meaningless since the child process is not traced. + */ + void processCreationAndCtor(); + + /** + * Test the performance of the qapplication constructor. + */ + void ctor(); + + /** + * Execute the constructor a second time to evaluate caching possibilities. + */ + void ctor2(); + +private: + /** + * Executes the current programm with a given parameter. + */ + void executeSelf(const QLatin1String ¶meter); +}; + +#endif // PT_QAPPLICATION_H diff --git a/benchmarks/pt_qapplication/pt_qapplication.pro b/benchmarks/pt_qapplication/pt_qapplication.pro new file mode 100644 index 000000000..adf11cb9e --- /dev/null +++ b/benchmarks/pt_qapplication/pt_qapplication.pro @@ -0,0 +1,4 @@ +include(../common_top.pri) +TARGET = pt_qapplication +SOURCES = pt_qapplication.cpp +HEADERS += pt_qapplication.h diff --git a/benchmarks/pt_widgetsgallery/.gitignore b/benchmarks/pt_widgetsgallery/.gitignore new file mode 100644 index 000000000..d17071368 --- /dev/null +++ b/benchmarks/pt_widgetsgallery/.gitignore @@ -0,0 +1 @@ +pt_widgetsgallery diff --git a/benchmarks/pt_widgetsgallery/pt_widgetsgallery.cpp b/benchmarks/pt_widgetsgallery/pt_widgetsgallery.cpp new file mode 100644 index 000000000..0911a5d92 --- /dev/null +++ b/benchmarks/pt_widgetsgallery/pt_widgetsgallery.cpp @@ -0,0 +1,41 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "pt_widgetsgallery.h" + +#include + +#include + +void Pt_WidgetsGallery::startupTime() +{ + QProcess proc; + const QString program = "widgetsgallery"; + const QStringList arguments = QStringList() << "-quitimmediately" << "-remote-theme"; + + QBENCHMARK { + proc.start(program, arguments); + QVERIFY(proc.waitForStarted()); + QVERIFY(proc.waitForFinished()); + QCOMPARE(proc.exitStatus(), QProcess::NormalExit); + QCOMPARE(proc.exitCode(), 0); + } +} + +QTEST_APPLESS_MAIN(Pt_WidgetsGallery) diff --git a/benchmarks/pt_widgetsgallery/pt_widgetsgallery.h b/benchmarks/pt_widgetsgallery/pt_widgetsgallery.h new file mode 100644 index 000000000..d82a5a0ed --- /dev/null +++ b/benchmarks/pt_widgetsgallery/pt_widgetsgallery.h @@ -0,0 +1,36 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef PT_WIDGETSGALLERY_H +#define PT_WIDGETSGALLERY_H + +#include + +class Pt_WidgetsGallery : public QObject +{ + Q_OBJECT +private slots: + + /** + * Benchmark startup time of widgetsgallery + */ + void startupTime(); +}; + +#endif // PT_WIDGETSGALLERY_H diff --git a/benchmarks/pt_widgetsgallery/pt_widgetsgallery.pro b/benchmarks/pt_widgetsgallery/pt_widgetsgallery.pro new file mode 100644 index 000000000..71f4f9757 --- /dev/null +++ b/benchmarks/pt_widgetsgallery/pt_widgetsgallery.pro @@ -0,0 +1,4 @@ +include(../common_top.pri) +TARGET = pt_widgetsgallery +SOURCES = pt_widgetsgallery.cpp +HEADERS = pt_widgetsgallery.h diff --git a/configure b/configure new file mode 100755 index 000000000..97254f68a --- /dev/null +++ b/configure @@ -0,0 +1,481 @@ +#!/bin/sh +# +# Configures the libdui build +# +# Copyright (C) 2010 Nokia Corporation. +# +# This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +# WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +#------------------------------------------------------------------------------- +# script initialization +#------------------------------------------------------------------------------- + +# the name of this script +relconf=`basename $0` +# the directory of this script is the "source tree" +relpath=`dirname $0` +relpath=`(cd "$relpath"; /bin/pwd)` +# the current directory is the "build tree" or "object tree" +outpath=`/bin/pwd` + +#------------------------------------------------------------------------------- +# operating system detection +#------------------------------------------------------------------------------- + +# need that throughout the script +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +#----------------------------------------------------------------------------- +# Dui version detection +#----------------------------------------------------------------------------- +DUI_MAJOR_VERSION=`grep -m1 DUI_MAJOR_VERSION src/dui_defines.prf |cut -f2 -d'='|sed 's/ //g'` +DUI_MINOR_VERSION=`grep -m1 DUI_MINOR_VERSION src/dui_defines.prf |cut -f2 -d'='|sed 's/ //g'` +DUI_PATCH_VERSION=`grep -m1 DUI_PATCH_VERSION src/dui_defines.prf |cut -f2 -d'='|sed 's/ //g'` +DUI_VERSION=$DUI_MAJOR_VERSION.$DUI_MINOR_VERSION.$DUI_PATCH_VERSION + +if [ -z "$DUI_MAJOR_VERSION" ]; then + echo "Cannot process version from src/dui_defines.prf: $DUI_VERSION" + echo "Cannot proceed." + exit 1 +fi + +#------------------------------------------------------------------------------- +# initalize variables +#------------------------------------------------------------------------------- + +# initalize internal variables +CFG_DEBUG=yes +CFG_RELEASE=no +CFG_OPENGL=yes +CFG_TESTABLE=no +CFG_COVERAGE=no +CFG_TIMESTAMPS=no +CFG_DEV=no + +DUI_DEFAULT_BUILD_PARTS="libs demos" +CFG_BUILD_PARTS="" +CFG_NOBUILD_PARTS="" + +HAVE_ICU=no +HAVE_CONTEXTSUBSCRIBER=no +HAVE_GCONF=no +HAVE_GSTREAMER=no +HAVE_DBUS=no + +# initalize variables used for installation +DUI_INSTALL_PREFIX=/usr/local + +#------------------------------------------------------------------------------- +# parse command line arguments +#------------------------------------------------------------------------------- + +# parse the arguments, setting things to "yes" or "no" +while [ "$#" -gt 0 ]; do + CURRENT_OPT="$1" + UNKNOWN_ARG=no + case "$1" in + #Autoconf style options + --enable-*) + VAR=`echo $1 | sed "s,^--enable-\(.*\),\1,"` + VAL=yes + ;; + --disable-*) + VAR=`echo $1 | sed "s,^--disable-\(.*\),\1,"` + VAL=no + ;; + --*=*) + VAR=`echo $1 | sed "s,^--\(.*\)=.*,\1,"` + VAL=`echo $1 | sed "s,^--.*=\(.*\),\1,"` + ;; + --no-*) + VAR=`echo $1 | sed "s,^--no-\(.*\),\1,"` + VAL=no + ;; + --*) + VAR=`echo $1 | sed "s,^--\(.*\),\1,"` + VAL=yes + ;; + #Qt style no options + -no-*) + VAR=`echo $1 | sed "s,^-no-\(.*\),\1,"` + VAL=no + ;; + #Qt style yes options + -h|-help|-v|-verbose|-debug|-release|-testable|-coverage|-timestamps|-dev) + VAR=`echo $1 | sed "s,^-\(.*\),\1,"` + VAL=yes + ;; + #Qt style options that pass an argument + -prefix|-make|-nomake) + VAR=`echo $1 | sed "s,^-\(.*\),\1,"` + shift + VAL="$1" + ;; + #Qt style complex options in one command + -enable-*|-disable-*) + VAR=`echo $1 | sed "s,^-\([^-]*\)-.*,\1,"` + VAL=`echo $1 | sed "s,^-[^-]*-\(.*\),\1,"` + ;; + #Qt Builtin/System style options + -no-*) + VAR=`echo $1 | sed "s,^-[^-]*-\(.*\),\1,"` + VAL=`echo $1 | sed "s,^-\([^-]*\)-.*,\1,"` + ;; + #Options that cannot be generalized + -opengl) + VAR=opengl + # this option may or may not be followed by an argument + if [ -z "$2" ] || echo "$2" | grep '^-' >/dev/null 2>&1; then + VAL=yes + else + shift; + VAL=$1 + fi + ;; + -*) + VAR=`echo $1 | sed "s,^-\(.*\),\1,"` + VAL="unknown" + ;; + *) + UNKNOWN_ARG=yes + ;; + esac + if [ "$UNKNOWN_ARG" = "yes" ]; then + echo "$1: unknown argument" + OPT_HELP=yes + ERROR=yes + shift + continue + fi + shift + + UNKNOWN_OPT=no + case "$VAR" in + prefix) + DUI_INSTALL_PREFIX="$VAL" + ;; + nomake) + CFG_NOBUILD_PARTS="$CFG_NOBUILD_PARTS $VAL" + ;; + make) + CFG_BUILD_PARTS="$CFG_BUILD_PARTS $VAL" + ;; + opengl) + if [ "$VAL" = "auto" ] || [ "$VAL" = "desktop" ] || + [ "$VAL" = "yes" ] || [ "$VAL" = "no" ] || + [ "$VAL" = "es1cl" ] || [ "$VAL" = "es1" ] || [ "$VAL" = "es2" ]; then + CFG_OPENGL="$VAL" + else + UNKNOWN_OPT=yes + fi + ;; + release) + CFG_RELEASE="$VAL" + ;; + debug) + CFG_DEBUG="$VAL" + ;; + testable) + CFG_TESTABLE="$VAL" + ;; + coverage) + CFG_COVERAGE="$VAL" + ;; + timestamps) + CFG_TIMESTAMPS="$VAL" + ;; + dev) + CFG_DEV="yes" + ;; + h|help) + if [ "$VAL" = "yes" ]; then + OPT_HELP="$VAL" + else + UNKNOWN_OPT=yes + fi + ;; + v|verbose) + if [ "$VAL" = "yes" ]; then + if [ "$OPT_VERBOSE" = "$VAL" ]; then # takes two verboses to turn on qmake debugs + QMAKE_SWITCHES="$QMAKE_SWITCHES -d" + else + OPT_VERBOSE=yes + fi + elif [ "$VAL" = "no" ]; then + if [ "$OPT_VERBOSE" = "$VAL" ] && echo "$QMAKE_SWITCHES" | grep ' -d' >/dev/null 2>&1; then + QMAKE_SWITCHES=`echo $QMAKE_SWITCHES | sed "s, -d,,"` + else + OPT_VERBOSE=no + fi + else + UNKNOWN_OPT=yes + fi + ;; + silent) + CFG_SILENT="$VAL" + ;; + esac + if [ "$UNKNOWN_OPT" = "yes" ]; then + echo "${CURRENT_OPT}: invalid command-line switch" + OPT_HELP=yes + ERROR=yes + fi +done + +if [ "$CFG_SILENT" = "yes" ]; then + QMAKE_CONFIG="$QMAKE_CONFIG silent" +fi + +#------------------------------------------------------------------------------- +# tests +#------------------------------------------------------------------------------- + +#setup the build parts +CFG_BUILD_PARTS="$CFG_BUILD_PARTS $DUI_DEFAULT_BUILD_PARTS" + +for nobuild in $CFG_NOBUILD_PARTS; do + CFG_BUILD_PARTS=`echo "$CFG_BUILD_PARTS" | sed "s, $nobuild,,g"` +done + +if echo $CFG_BUILD_PARTS | grep -v libs >/dev/null 2>&1; then + echo + echo "WARNING: libs is a required part of the build." + echo + CFG_BUILD_PARTS="$CFG_BUILD_PARTS libs" +fi + +if [ "$CFG_DEV" = "yes" ]; then + CFG_BUILD_PARTS="$CFG_BUILD_PARTS tests benchmarks plainqt" +fi + +# Test for ICU +which icu-config > /dev/null +if [ $? -eq 0 ]; then + icu-config --exists + if [ $? -eq 0 ]; then + HAVE_ICU=yes + fi +fi + +# Test for pkg-config enabled dependencies +which pkg-config > /dev/null +if [ $? -eq 0 ]; then + + pkg-config --exists contextsubscriber-1.0 + if [ $? -eq 0 ]; then + HAVE_CONTEXTSUBSCRIBER=yes + fi + + pkg-config --exists gconf-2.0 + if [ $? -eq 0 ]; then + HAVE_GCONF=yes + fi + + pkg-config --exists gstreamer-0.10 + if [ $? -eq 0 ]; then + HAVE_GSTREAMER=yes + fi + + pkg-config --exists QtDBus + if [ $? -eq 0 ]; then + HAVE_DBUS=yes + fi + +fi + + + +#------------------------------------------------------------------------------- +# help - interactive parts of the script _after_ this section please +#------------------------------------------------------------------------------- + +# next, emit a usage message if something failed. +if [ "$OPT_HELP" = "yes" ]; then + [ "x$ERROR" = "xyes" ] && echo + cat <] [-release] [-debug] [-make ] + [-no-make ] + +Installation options: + + -prefix ...... This will install everything relative to + (default $DUI_INSTALL_PREFIX) + +Configure options: + + The defaults (*) are usually acceptable. A plus (+) denotes a default value + that needs to be evaluated. If the evaluation succeeds, the feature is + included. Here is a short explanation of each option: + + -release ........... Compile and link libdui in release mode + * -debug ............. Compile and link libdui with debugging turned on + + -testable .......... Enable the testability plugin interface in libdui + -timestamps ........ Enable time debug measurements in the code + -coverage .......... Enable code coverage calculation + +Additional options: + + -make ....... Add part to the list of parts to be built at make time + (*libs *demos plainqt tests benchmarks) + -nomake ..... Exclude part from the list of parts to be built + + -dev ............... Compile and link with default developer options +EOF + +exit 0 + +fi + +#------------------------------------------------------------------------------- +# save configuration into duiconfig.pri +#------------------------------------------------------------------------------- + +DUICONFIG="$outpath/mkspecs/duiconfig.pri" +[ -f "$DUICONFIG.tmp" ] && rm -f "$DUICONFIG.tmp" + +if [ "$CFG_DEBUG" = "yes" ]; then + DUICONFIG_CONFIG="$DUICONFIG_CONFIG debug" +fi + +if [ "$CFG_RELEASE" = "yes" ]; then + DUICONFIG_CONFIG="$DUICONFIG_CONFIG release" +fi + + +if [ "$CFG_TESTABLE" = "yes" ]; then + DUICONFIG_FEATURES="$DUICONFIG_FEATURES testable" +fi + +if [ "$CFG_TIMESTAMPS" = "yes" ]; then + DUICONFIG_FEATURES="$DUICONFIG_FEATURES timestamps" +fi + +if [ "$CFG_COVERAGE" = "yes" ]; then + DUICONFIG_FEATURES="$DUICONFIG_FEATURES coverage" +fi + + +if [ "$HAVE_ICU" = "yes" ]; then + DUICONFIG_DEPS="$DUICONFIG_DEPS HAVE_ICU" +fi + +if [ "$HAVE_CONTEXTSUBSCRIBER" = "yes" ]; then + DUICONFIG_DEPS="$DUICONFIG_DEPS HAVE_CONTEXTSUBSCRIBER" +fi + +if [ "$HAVE_GCONF" = "yes" ]; then + DUICONFIG_DEPS="$DUICONFIG_DEPS HAVE_GCONF" +fi + +if [ "$HAVE_GSTREAMER" = "yes" ]; then + DUICONFIG_DEPS="$DUICONFIG_DEPS HAVE_GSTREAMER" +fi + +if [ "$HAVE_DBUS" = "yes" ]; then + DUICONFIG_DEPS="$DUICONFIG_DEPS HAVE_DBUS" +fi + + +cat >>"$DUICONFIG.tmp" < /dev/null + if [ $? -eq 0 ]; then + QMAKE_BIN=`which qmake` + else + echo "qmake was not found in your path\n" + fi +elif [ -f "$QTDIR/bin/qmake" ]; then + QMAKE_BIN="$QTDIR/bin/qmake" +else + echo "QTDIR variable was set but could not find $QTDIR/bin/qmake\n" +fi + +if [ -z "$QMAKE_BIN" ]; then + echo "If your Qt is in a nonstandard location, try:" + echo "QTDIR= ./$relconf" + exit 1 +fi + +#Run qmake +$QMAKE_BIN $QMAKE_CONFIG $QMAKE_SWITCHES + +#------------------------------------------------------------------------------- +# give feedback on configuration +#------------------------------------------------------------------------------- + +echo "\n\nOptional build dependencies found:" + +echo "ICU ...................... $HAVE_ICU" +echo "Context Subscriber 1.0 ... $HAVE_CONTEXTSUBSCRIBER" +echo "GConf 2.0 ................ $HAVE_GCONF" +echo "GStreamer 0.10 ........... $HAVE_GSTREAMER" +echo "DBus (incl. QtDBus) ...... $HAVE_DBUS" + + +if [ "$CFG_DEV" = "yes" ]; then + echo "\n\nEnabling DirectUI developer's build\n" +else + echo "\n" +fi + +echo "DirectUI framework build configuration:" +echo "Version ............. $DUI_VERSION" +echo "Build ...............$CFG_BUILD_PARTS" +echo "Extra features ......$DUICONFIG_FEATURES" +echo "Release ............. $CFG_RELEASE" +echo "Debug ............... $CFG_DEBUG" + +echo +echo libdui is now configured for building. Just run \'make\'. +if [ "$relpath" = "$DUI_INSTALL_PREFIX" ]; then + echo Once everything is built, libdui is installed. + echo You should not run \'make install\'. +else + echo Once everything is built, you can run \'make install\'. + echo libdui will be installed into $DUI_INSTALL_PREFIX +fi + +echo "\n" diff --git a/debian/.gitignore b/debian/.gitignore new file mode 100644 index 000000000..faf916fd7 --- /dev/null +++ b/debian/.gitignore @@ -0,0 +1,38 @@ +libdui-dev +libdui-tests +*.debhelper +*.substvars +libdui0 +libdui-doc +libdui0-dbg +libdui-l10n-ar +libdui-l10n-de +libdui-l10n-en +libdui-l10n-engineering-english +libdui-l10n-fi +libdui-l10n-ur +libdui-l10n-zh-cn +libdui-benchmarks +tmp +files +dui-demos +dui-demos-eternia +dui-demos-imageviewer +dui-demos-widgetsgallery +dui-demos-widgetsgallery-dbg +dui-demos-widgetsgallery-tests +dui-demos-widgetsgallery-l10n-ar +dui-demos-widgetsgallery-l10n-de +dui-demos-widgetsgallery-l10n-en +dui-demos-widgetsgallery-l10n-engineering-english +dui-demos-widgetsgallery-l10n-fi +dui-demos-widgetsgallery-l10n-hu +dui-demos-widgetsgallery-l10n-ur +dui-demos-widgetsgallery-l10n-zh-cn +dui-demos-appletinstallationsource +dui-demos-appletinstallationsource-dbg +dui-dev-tools +dui-demos-plainqt-dbg +dui-demos-plainqt +dui-im-context + diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 000000000..df57b3bee --- /dev/null +++ b/debian/changelog @@ -0,0 +1,182 @@ +libdui (0.19.0-1) unstable; urgency=low + + * New version + * License changed + + -- Tomas Junnonen Mon, 15 Feb 2010 13:49:00 +0200 + +libdui (0.18.9-2) unstable; urgency=low + + * New version + * Unit test fixes + * Implemented: SWP#DUI-2901 + + -- Tomas Junnonen Fri, 12 Feb 2010 14:30:00 +0200 + +libdui (0.18.8-1) unstable; urgency=low + + * Fixes: NB#155940 - DuiDialog crashes at times if created with DuiSceneWindow::KeepWhenDone + * Fixes: NB#156148 - There is no way to change theme on non linux OS + * Fixes: NB#153770 - Closing a window when app has multiple windows causes exit with error code 1 + * Fixes: NB#154831 - Widgetsgallery crash on first run + * Fixes: NB#155361 - Removed warnings and added -Werror + * Fixes: NB#155726 - Asynchronously handled dialog returns wrong result + * Fixes: NB#154422 - Inserting rows to first group in DuiList does not update the list + * Fixes: NB#156073 - Widgetsgallery : Broken Query dialog, yes and no Button double caption + * Fixes: NB#155116 - Pannable viewport doesn't come back to the very same position + * Fixes: NB#152282 - DuiNavigationBar animates incorrectly when the screen is rotated + * Fixes: NB#154831 - Widgetsgallery -timedemo causes consistent segfault in CITA; occasionally on device + * Fixes: NB#154535 - Not possible to keep current window orientation angle with keepCurrentOrientation() + * Fixes: NB#156155 - Widgets are invisible after layout policy switch + * Fixes: NB#154584 - -remote-theme switch doesn't work + * Fixes: NB#154446 - duistylesheet.cpp + * Fixes: NB#154129 - DuiPopupList::scrollTo makes some items disappear + * Fixes: NB#154888 - performing click() on DuiComboBox is not working as expected + * Fixes: NB#154891 - setting the icon & icon visibility for DuiComboBox is not working properly + * Fixes: NB#153911 - DuiStylableWidget shouldn't require the DUI_REGISTER_WIDGET macro, or default constructor + * Fixes: NB#155682 - ta_duilistmod: complete List deletion causes segfault + * Fixes: NB#155734 - Items under the last group of DuiList are duplicated + * Fixes: NB#153100 - DuiList doesn't update when items are removed from a model with group headers + * Fixes: NB#151937 - Incorrect include files libdui-dev package + * Fixes: NB#155837 - DuiComboBox does not change current item text when item model is changed + * Fixes: NB#152740 - trid function is not marked as deprecated + * Fixes: NB#152994 - Width of the view menu items differ from each other + * Fixes: NB#155856 - Launching applications in Portrait is broken again + * Fixes: NB#154449 - sorting does not work correctly neither in no_NO nor nb_NO locales + * Fixes: NB#156115 - typo in doxygen documentation + * Fixes: NB#154958 - libicudata is invalid shared library -> LD_AUDIT doesn't work for anything linking it (i.e. DUI) + * Implemented: SWP#DUI-2143, SWP#DUI-2147, SWP#DUI-2201, SWP#DUI-2207 + * Implemented: SWP#DUI-2145, SWP#DUI-2148, SWP#DUI-2140, SWP#DUI-2228 + * Implemented: SWP#DUI-2135, SWP#DUI-2134, SWP#DUI-2139, SWP#DUI-2114 + * Implemented: SWP#DUI-2051, SWP#DUI-2052, SWP#DUI-2191, SWP#DUI-2185 + * Implemented: SWP#DUI-2186, SWP#DUI-2189, SWP#DUI-2190, SWP#DUI-2188 + * Implemented: SWP#DUI-2187, SWP#DUI-1885, SWP#DUI-2053, SWP#DUI-2115 + * Implemented: SWP#DUI-2132, SWP#DUI-2121, SWP#DUI-2120, SWP#DUI-2119 + * Implemented: SWP#DUI-2117, SWP#DUI-2116, SWP#DUI-2166, SWP#DUI-2164 + * Implemented: SWP#DUI-2162, SWP#DUI-2161, SWP#DUI-1546, SWP#DUI-2083 + * Implemented: SWP#DUI-2169, SWP#DUI-2168 + + -- Tomas Junnonen Thu, 11 Feb 2010 15:26:00 +0200 + +libdui (0.18.7-1) unstable; urgency=low + + * Fixes: NB#154408 - displayExited doesn't get emitted when the DuiWindow gets closed + * Fixes: NB#154886 - setItemIconID() for DuiComboBox items is not working properly + * Fixes: NB#144088 - DuiList can't scroll to index + * Fixes: NB#153902 - DuiContainer crashes when ProgressIndicator is set visible and headerVisible property is toggled + * Fixes: NB#154433 - DuiButton's shape() is not within the button's bounding rectangle. + * Fixes: NB#155031 - Transaction support in DuiModel not functioning + * Fixes: NB#153437 - DuiTheme::pixmap() not working + * Fixes: NB#154878 - DuiList component does not react to some item model signals + * Fixes: NB#154961 - DuiList doesnt update cells correctly when deleting a row from the underlying model + * Fixes: NB#113828 - Documentation for DUI Theme system is out of date and/or lacking + * Fixes: NB#152740 - trid function is not marked as deprecated + * Fixes: NB#154240 - List has visual artefacts when run with Pineapple profile + * Fixes: NB#154907 - The background of tapped DuiContentItem in Single mode looks foggy + * Fixes: NB#152990 - DuiList's setColumns() doesn't work + * Fixes: NB#148937 - Multiple slection is not possible in the duilist in libdui15 + * Fixes: NB#137510 - DuiGrid performance is bad + * Implemented: SWP#DUI-2036, SWP#DUI-2035, SWP#DUI-2034, SWP#DUI-2033 + * Implemented: SWP#DUI-2032, SWP#DUI-2031, SWP#DUI-2086, SWP#DUI-2084 + * Implemented: SWP#DUI-2049, SWP#DUI-2097, SWP#DUI-2046, SWP#DUI-2045 + * Implemented: SWP#DUI-1915, SWP#DUI-1903, SWP#DUI-1904, SWP#DUI-2081 + * Implemented: SWP#DUI-2082, SWP#DUI-2047, SWP#DUI-2096, SWP#DUI-2080 + * Implemented: SWP#DUI-2075, SWP#DUI-2095, SWP#DUI-2074, SWP#DUI-1882 + * Implemented: SWP#DUI-514, SWP#DUI-2054, SWP#DUI-2050, SWP#DUI-1776 + * Implemented: SWP#DUI-1778, SWP#DUI-1880, SWP#DUI-2076, SWP#DUI-2048 + * Implemented: SWP#DUI-1847, SWP#DUI-1503, SWP#DUI-2089, SWP#DUI-1798 + * Implemented: SWP#DUI-2090 + + -- Tomas Junnonen Tue, 02 Feb 2010 10:21:00 +0200 + +libdui (0.18.6-1) unstable; urgency=low + + * Fixes: NB#149818 - Theming changes always causes segfaults + * Fixes: NB#154885 - DuiApplicationPage::setAutoMarginsForComponentsEnabled() does not work when page is open + * Fixes: NB#154860 - Theme switching doesn't work + * Fixes: NB#150496 - DuiDialog destructor crashes with a QGridLayoutEngine::setItemAt() + * Fixes: NB#153447 - Newly created widgets ignore calling hide() + * Fixes: NB#154005 - Page of the DuiImage in documentation tells about DuiPopupList and not DuiImage + * Fixes: NB#154417 - DuiList visible item update is broken when group headers are used + * Fixes: NB#154517 - DuiList component crahes when non-empty item model is given + * Unit test fixes + + -- Tomas Junnonen Fri, 29 Jan 2010 17:55:00 +0200 + +libdui (0.18.5-1) unstable; urgency=low + + * Fixes: NB#153100 - DuiList doesn't update when items are removed from a model with group headers + * Fixes: NB#154445 - Multi column list does not refresh content (for non first columns) + * Fixes: NB#154304 - Crash when inserting (prepending) items into an empty DuiList + * Fixes: NB#154241 - WidgetsGallery does now show title area in Portrait for Pineapple target + * Unit test fixes + + -- Tomas Junnonen Tue, 26 Jan 2010 16:50:00 +0200 + +libdui (0.18.4-1) unstable; urgency=low + + * Fixes: NB#153413 - Event cancellation does not work for DuiSlider (DuiSlider value is not reset when panning occurs) + * Fixes: NB#152102 - DuiLinearLayoutPolicy - make the documentation clearer about indexes + * Fixes: NB#153983 - DuiApplication(argc, argv) does not allow to open 2 app processes with the same name + * Fixes: NB#153978 - Broken applets can not be removed by clicking Remove in the broken applet dialog + * Unit test fixes + + -- Tomas Junnonen Mon, 25 Jan 2010 11:54:00 +0200 + +libdui (0.18.3-1) unstable; urgency=low + + * Fixes: NB#151691 - Prestarted applications still visible in the switcher after lazy shutdown + * Fixes: NB#153483 - The background image can not be loaded for DuiInformBanner sometimes + * Fixes: NB#153952 - DuiApplicationPage::disappear() causes segmentation fault with DuiSceneWindow::DestroyWhenDone policy + * Fixes: NB#153800 - Setting application to full screen does not automatically remove toolbar offset from application page + * Unit test fixes + + -- Tomas Junnonen Thu, 21 Jan 2010 16:58:00 +0200 + +libdui (0.18.2-1) unstable; urgency=low + + * Fixes: NB#153412 - Switch button interaction reverted in Portrait + * Fixes: NB#152770 - Styling system does not support QChar attributes + * Fixes: NB#153415 - Animations fail with recent Qt + * Fixes: NB#152804 - DuiList::itemClicked(QModelIndex) signal is never emitted for non DuiContentItem cells + * Unit test fixes + + -- Tomas Junnonen Wed, 20 Jan 2010 17:01:00 +0200 + +libdui (0.18.1-1) unstable; urgency=low + + * New version + * Unit test fixes + + -- Tomas Junnonen Tue, 19 Jan 2010 09:50:00 +0200 + +libdui (0.18.0-1) unstable; urgency=low + + * Fixes: NB#150389 - Window modal dialogs do not work + * Fixes: NB#143497 - Can't add views from plugins + * Fixes: NB#153164 - Closing windows when multiple windows in application causes segfault + * Fixes: NB#151200 - DuiAction::setVisible( bool ) is not handled correctly in application menu + * Fixes: NB#153158 - Segmentation fault when using fast list without specified cell creators + * Fixes: NB#150040 - dui application using filtered duigrid crashes when clicking the items before repaint of grid finished + * Fixes: NB#150567 - Outdated list items appear out of list when DuiList model is updated + * Fixes: NB#151550 - Widgets inheriting DuiStylableWidget have no obvious size to paint to + * Fixes: NB#153314 - When Screen.IsCovered property is set to TRUE, dui apps crash on startup. + * Fixes: NB#147429 - DuiWidgetView::xxxChanged() methods break fundamental Qt API conventions + * Fixes: NB#147904 - Closing DuiApplicationWindow causes huge CPU usage + * Fixes: NB#149294 - Problem with tool dui-servicefwgen in dui 0.16 + * Fixes: NB#144564 - Delayed model initialization in DuiWidgetController + * Fixes: NB#152624 - Page title doesn't change after DuiApplicationPage::disappear - appear sequence + * Fixes: NB#149214 - Clicked signal is not working with DuiGrid and DuiList + * Fixes: NB#152737 - [blocker proposal] Mapcanvas fails to compile with latest dui v0.17 + * Fixes: NB#140299 - device is flickering while virtual key board is launching(Qt 4.6.0~git20090911-0maemo1+0m6) + * Fixes: NB#151978 - DuiLinearLayoutPolicy ignores addStretch() + * Implemented: SWP#DUI-1898, SWP#DUI-1897, SWP#DUI-1899, SWP#DUI-1936 + * Implemented: SWP#DUI-1905, SWP#DUI-1900, SWP#DUI-1819, SWP#DUI-1901, SWP#DUI-1992 + * Implemented: SWP#DUI-1909, SWP#DUI-1935, SWP#DUI-2013, SWP#DUI-1910, SWP#DUI-1912 + * Implemented: SWP#DUI-1913, SWP#DUI-1920, SWP#DUI-1881, SWP#DUI-1919, SWP#DUI-1879 + * Implemented: SWP#DUI-1877, SWP#DUI-1971, SWP#DUI-1872, SWP#DUI-1882, SWP#DUI-1932 + * Implemented: SWP#DUI-1931, SWP#DUI-1916, SWP#DUI-1702, SWP#DUI-1793, SWP#DUI-1918 + * Implemented: SWP#DUI-1572, SWP#DUI-1794, SWP#DUI-1798, SWP#DUI-1996, SWP#DUI-1995 + * Implemented: SWP#DUI-1964, SWP#DUI-1963, SWP#DUI-1962, SWP#DUI-1961, SWP#DUI-1960 + + -- Tomas Junnonen Sun, 17 Jan 2010 18:02:00 +0200 diff --git a/debian/compat b/debian/compat new file mode 100644 index 000000000..b8626c4cf --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +4 diff --git a/debian/control b/debian/control new file mode 100644 index 000000000..243334df5 --- /dev/null +++ b/debian/control @@ -0,0 +1,219 @@ +Source: libdui +Section: libs +Priority: extra +Maintainer: Tomas Junnonen +Build-Depends: debhelper (>= 5), libqt4-dev (>= 4.6.0), libicu-dev, libx11-dev, doxygen (>=1.5.9), libgconf2-dev, libcontextsubscriber-dev, libgstreamer0.10-dev, libgstreamer-plugins-base0.10-dev, libgles2-sgx-img-dev [arm armel], opengles-sgx-img-common-dev [arm armel], libgl-dev [i386], libgl1 [i386], libqt4-opengl-dev, pkg-config (>= 0.22), libxdamage-dev +Standards-Version: 3.7.2 + +Package: libdui0 +Architecture: any +Depends: libdui-l10n-engineering-english (= ${Source-Version}), libqtcore4 (>= 4.6.0), libqtgui4 (>= 4.6.0), libqt4-dbus (>= 4.6.0), dbus-x11, ${misc:Depends}, ${launcher:Depends}, ${shlibs:Depends}, duitheme (>= 0.5.0), libxdamage1 +Provides: libdui +Conflicts: libdui +Suggests: libdui-l10n-ar, libdui-l10n-de, libdui-l10n-en, libdui-l10n-fi, libdui-l10n-ur, libdui-l10n-zh-cn +Description: DirectUI library + libdui framework libraries + +Package: libdui-dev +Section: devel +Architecture: any +Depends: libdui0 (= ${Source-Version}), dui-dev-tools (=${Source-Version}), libqt4-dev (>= 4.6.0), libx11-dev, libgstreamer0.10-dev, libgstreamer-plugins-base0.10-dev, libgconf2-dev, libcontextsubscriber-dev, libxdamage-dev +Description: libdui development files + Development files for DirectUI + +Package: dui-dev-tools +Section: devel +Architecture: any +Depends: ${shlibs:Depends} +Suggests: perl (>= 5.10.0) +Description: libdui specific development and testing tools + Collection of tools for testing and developing on top of libdui. Includes + stuff like applettester and code/mock generation. + +Package: dui-demos +Section: devel +Architecture: any +Depends: dui-demos-widgetsgallery, dui-demos-plainqt +Description: Demo applications for DirectUI + Collection of demo applications for DirectUI + +Package: dui-demos-widgetsgallery +Section: devel +Architecture: any +Depends: libdui0 (= ${Source-Version}), dui-demos-widgetsgallery-l10n-engineering-english (= ${Source-Version}) +Suggests: dui-demos-widgetsgallery-l10n-ar, dui-demos-widgetsgallery-l10n-de, dui-demos-widgetsgallery-l10n-en, dui-demos-widgetsgallery-l10n-fi, dui-demos-widgetsgallery-l10n-ur, dui-demos-widgetsgallery-l10n-zh-cn +Description: Demo application for DirectUI + +Package: dui-demos-widgetsgallery-tests +Section: devel +Architecture: any +Depends: libdui0 (= ${Source-Version}), duitestrunner, dui-demos-widgetsgallery (= ${Source-Version}) +Description: Demo application for DirectUI + +Package: dui-demos-widgetsgallery-dbg +Section: devel +Architecture: any +Depends: dui-demos-widgetsgallery (= ${Source-Version}) +Description: Demo application for DirectUI. + . + This package contains the debug symbols. + +Package: dui-demos-widgetsgallery-l10n-engineering-english +Section: devel +Architecture: any +Enhances: dui-demos-widgetsgallery +Replaces: dui-demos-widgetsgallery (<< 0.17.0-0) +Description: Engineering English translations for widgetsgallery + +Package: dui-demos-widgetsgallery-l10n-ar +Section: devel +Architecture: any +Enhances: dui-demos-widgetsgallery +Replaces: dui-demos-widgetsgallery (<< 0.17.0-0) +Description: Arabic translations for widgetsgallery + +Package: dui-demos-widgetsgallery-l10n-de +Section: devel +Architecture: any +Enhances: dui-demos-widgetsgallery +Replaces: dui-demos-widgetsgallery (<< 0.17.0-0) +Description: German translations for widgetsgallery + +Package: dui-demos-widgetsgallery-l10n-en +Section: devel +Architecture: any +Enhances: dui-demos-widgetsgallery +Replaces: dui-demos-widgetsgallery (<< 0.17.0-0) +Description: English translations for widgetsgallery + +Package: dui-demos-widgetsgallery-l10n-fi +Section: devel +Architecture: any +Enhances: dui-demos-widgetsgallery +Replaces: dui-demos-widgetsgallery (<< 0.17.0-0) +Description: Finnish translations for widgetsgallery + +Package: dui-demos-widgetsgallery-l10n-hu +Section: devel +Architecture: any +Enhances: dui-demos-widgetsgallery +Replaces: dui-demos-widgetsgallery (<< 0.17.0-0) +Description: Hungarian translations for widgetsgallery + +Package: dui-demos-widgetsgallery-l10n-ur +Section: devel +Architecture: any +Enhances: dui-demos-widgetsgallery +Replaces: dui-demos-widgetsgallery (<< 0.17.0-0) +Description: Urdu translations for widgetsgallery + +Package: dui-demos-widgetsgallery-l10n-zh-cn +Section: devel +Architecture: any +Enhances: dui-demos-widgetsgallery +Replaces: dui-demos-widgetsgallery (<< 0.17.0-0) +Description: Simplified Chinese translations for widgetsgallery + +Package: dui-demos-plainqt +Section: devel +Architecture: any +Depends: libdui0 (= ${Source-Version}) +Replaces: dui-demos-plainqt (<< 0.16.0-1) +Description: Demo applications showing the capabilities of the plain qt style. + +Package: dui-demos-plainqt-dbg +Section: devel +Architecture: any +Depends: dui-demos-plainqt (= ${Source-Version}) +Replaces: dui-demos-plainqt-dbg (<< 0.16.0-1) +Description: debug symbols of the plain qt examples + +Package: dui-demos-appletinstallationsource +Section: devel +Architecture: any +Depends: libdui0 (= ${Source-Version}) +Description: Demo applet installation source for the applet library. + +Package: dui-demos-appletinstallationsource-dbg +Section: devel +Architecture: any +Depends: dui-demos-appletinstallationsource (= ${Source-Version}) +Description: Debug symbols of the demo applet installation source. + +Package: libdui-tests +Section: extra +Architecture: any +Depends: libdui0 (= ${Source-Version}), libqtgui4, testrunner, locales, ${shlibs:Depends} +Description: libdui unit tests + Unit testing binaries and shellscripts for testing libdui library + +Package: libdui-benchmarks +Section: extra +Architecture: any +Depends: libdui0 (= ${Source-Version}), ${shlibs:Depends} +Description: libdui benchmarks + Benchmarking binaries for testing libdui library + +Package: libdui0-dbg +Architecture: any +Section: devel +Depends: libdui0 (= ${Source-Version}) +Description: libdui debug package + libdui debug symbols. + +Package: libdui-doc +Section: doc +Architecture: all +Description: API documentation for libdui + +Package: libdui-l10n-engineering-english +Section: devel +Architecture: any +Enhances: libdui0 +Replaces: dui-demos-widgetsgallery (<< 0.17.0-0) +Description: Engineering English translations for libdui + +Package: libdui-l10n-ar +Section: devel +Architecture: any +Enhances: libdui0 +Replaces: dui-demos-widgetsgallery (<< 0.17.0-0) +Description: Arabic translations for libdui + +Package: libdui-l10n-de +Section: devel +Architecture: any +Enhances: libdui0 +Replaces: dui-demos-widgetsgallery (<< 0.17.0-0) +Description: German translations for libdui + +Package: libdui-l10n-en +Section: devel +Architecture: any +Enhances: libdui0 +Replaces: dui-demos-widgetsgallery (<< 0.17.0-0) +Description: English translations for libdui + +Package: libdui-l10n-fi +Section: devel +Architecture: any +Enhances: libdui0 +Replaces: dui-demos-widgetsgallery (<< 0.17.0-0) +Description: Finnish translations for libdui + +Package: libdui-l10n-ur +Section: devel +Architecture: any +Enhances: libdui0 +Replaces: dui-demos-widgetsgallery (<< 0.17.0-0) +Description: Urdu translations for libdui + +Package: libdui-l10n-zh-cn +Section: devel +Architecture: any +Enhances: libdui0 +Replaces: dui-demos-widgetsgallery (<< 0.17.0-0) +Description: Simplified Chinese translations for libdui + + + diff --git a/debian/dui-demos-appletinstallationsource.install b/debian/dui-demos-appletinstallationsource.install new file mode 100644 index 000000000..3e2001e9b --- /dev/null +++ b/debian/dui-demos-appletinstallationsource.install @@ -0,0 +1 @@ +usr/lib/dui/appletinstallationsources/libfakeinstallationsource.so diff --git a/debian/dui-demos-plainqt.install b/debian/dui-demos-plainqt.install new file mode 100644 index 000000000..67ad5117a --- /dev/null +++ b/debian/dui-demos-plainqt.install @@ -0,0 +1,9 @@ +usr/bin/qtstyledialogs +usr/bin/qtstyleexample +usr/share/applications/qtstyledialogs.desktop +usr/share/applications/qtstyledialogs-windows-style.desktop +usr/share/applications/qtstyleexample.desktop +usr/share/applications/qtstyleexample-windows-style.desktop +usr/share/dbus-1/services/com.nokia.qtstyledialogs.service +usr/share/dbus-1/services/com.nokia.qtstyleexample.service +usr/share/qtstyleexample/themes/style/qtstyleexample.css diff --git a/debian/dui-demos-widgetsgallery-l10n-ar.install b/debian/dui-demos-widgetsgallery-l10n-ar.install new file mode 100644 index 000000000..502e4c60c --- /dev/null +++ b/debian/dui-demos-widgetsgallery-l10n-ar.install @@ -0,0 +1 @@ +usr/share/l10n/dui/widgetsgallery_ar.qm diff --git a/debian/dui-demos-widgetsgallery-l10n-de.install b/debian/dui-demos-widgetsgallery-l10n-de.install new file mode 100644 index 000000000..d6cfbfb5b --- /dev/null +++ b/debian/dui-demos-widgetsgallery-l10n-de.install @@ -0,0 +1 @@ +usr/share/l10n/dui/widgetsgallery_de.qm diff --git a/debian/dui-demos-widgetsgallery-l10n-en.install b/debian/dui-demos-widgetsgallery-l10n-en.install new file mode 100644 index 000000000..f6778c500 --- /dev/null +++ b/debian/dui-demos-widgetsgallery-l10n-en.install @@ -0,0 +1 @@ +usr/share/l10n/dui/widgetsgallery_en.qm diff --git a/debian/dui-demos-widgetsgallery-l10n-engineering-english.install b/debian/dui-demos-widgetsgallery-l10n-engineering-english.install new file mode 100644 index 000000000..8d9bcc973 --- /dev/null +++ b/debian/dui-demos-widgetsgallery-l10n-engineering-english.install @@ -0,0 +1,2 @@ +usr/share/l10n/dui/widgetsgallery.qm +usr/share/doc/dui-demos-widgetsgallery-l10n-engineering-english/widgetsgallery.ts diff --git a/debian/dui-demos-widgetsgallery-l10n-fi.install b/debian/dui-demos-widgetsgallery-l10n-fi.install new file mode 100644 index 000000000..3a0a4aba1 --- /dev/null +++ b/debian/dui-demos-widgetsgallery-l10n-fi.install @@ -0,0 +1 @@ +usr/share/l10n/dui/widgetsgallery_fi.qm diff --git a/debian/dui-demos-widgetsgallery-l10n-hu.install b/debian/dui-demos-widgetsgallery-l10n-hu.install new file mode 100644 index 000000000..85f9f9181 --- /dev/null +++ b/debian/dui-demos-widgetsgallery-l10n-hu.install @@ -0,0 +1 @@ +usr/share/l10n/dui/widgetsgallery_hu.qm diff --git a/debian/dui-demos-widgetsgallery-l10n-ur.install b/debian/dui-demos-widgetsgallery-l10n-ur.install new file mode 100644 index 000000000..c16f98485 --- /dev/null +++ b/debian/dui-demos-widgetsgallery-l10n-ur.install @@ -0,0 +1 @@ +usr/share/l10n/dui/widgetsgallery_ur.qm diff --git a/debian/dui-demos-widgetsgallery-l10n-zh-cn.install b/debian/dui-demos-widgetsgallery-l10n-zh-cn.install new file mode 100644 index 000000000..385dd4430 --- /dev/null +++ b/debian/dui-demos-widgetsgallery-l10n-zh-cn.install @@ -0,0 +1 @@ +usr/share/l10n/dui/widgetsgallery_zh_CN.qm diff --git a/debian/dui-demos-widgetsgallery-tests.install b/debian/dui-demos-widgetsgallery-tests.install new file mode 100644 index 000000000..0fa29f509 --- /dev/null +++ b/debian/dui-demos-widgetsgallery-tests.install @@ -0,0 +1 @@ +usr/share/dui-demos-widgetsgallery-tests/tests.xml diff --git a/debian/dui-demos-widgetsgallery.dirs b/debian/dui-demos-widgetsgallery.dirs new file mode 100644 index 000000000..0346ff3ac --- /dev/null +++ b/debian/dui-demos-widgetsgallery.dirs @@ -0,0 +1,9 @@ +usr/bin +usr/lib +usr/share/widgetsgallery/themes +usr/share/widgetsgallery/themes/style +usr/share/widgetsgallery/themes/images +usr/share/widgetsgallery/themes/images/contacts +usr/share/widgetsgallery/themes/svg +usr/share/themes/base/dui/widgetsgallery/feedbacks +usr/share/applications diff --git a/debian/dui-demos-widgetsgallery.install b/debian/dui-demos-widgetsgallery.install new file mode 100644 index 000000000..c4f586ac2 --- /dev/null +++ b/debian/dui-demos-widgetsgallery.install @@ -0,0 +1,4 @@ +usr/bin/widgetsgallery +usr/share/themes/* +usr/share/applications/widgetsgallery.desktop +usr/share/dbus-1/services/com.nokia.widgetsgallery.service diff --git a/debian/dui-dev-tools.install b/debian/dui-dev-tools.install new file mode 100644 index 000000000..342b29664 --- /dev/null +++ b/debian/dui-dev-tools.install @@ -0,0 +1,7 @@ +usr/bin/duimoc +usr/bin/duigen +usr/bin/dui-servicefwgen +usr/bin/duiapplettester +usr/bin/duiapplicationextensiontester +usr/bin/duinotificationtool +usr/bin/duinotificationstresstest diff --git a/debian/dui-widgetsgallery-tests.dirs b/debian/dui-widgetsgallery-tests.dirs new file mode 100644 index 000000000..089de51dc --- /dev/null +++ b/debian/dui-widgetsgallery-tests.dirs @@ -0,0 +1 @@ +usr/share/dui-demos-widgetsgallery-tests diff --git a/debian/dui-widgetsgallery-tests.install b/debian/dui-widgetsgallery-tests.install new file mode 100644 index 000000000..0fa29f509 --- /dev/null +++ b/debian/dui-widgetsgallery-tests.install @@ -0,0 +1 @@ +usr/share/dui-demos-widgetsgallery-tests/tests.xml diff --git a/debian/libdui-benchmarks.install b/debian/libdui-benchmarks.install new file mode 100644 index 000000000..793241862 --- /dev/null +++ b/debian/libdui-benchmarks.install @@ -0,0 +1 @@ +usr/lib/libdui-benchmarks/* diff --git a/debian/libdui-dev.dirs b/debian/libdui-dev.dirs new file mode 100644 index 000000000..ba745b4bf --- /dev/null +++ b/debian/libdui-dev.dirs @@ -0,0 +1,2 @@ +usr/include/dui +usr/lib/pkgconfig diff --git a/debian/libdui-dev.install b/debian/libdui-dev.install new file mode 100644 index 000000000..32b42ba8d --- /dev/null +++ b/debian/libdui-dev.install @@ -0,0 +1,5 @@ +usr/include/* +usr/lib/pkgconfig/* +usr/share/qt4/mkspecs/features/dui.prf +usr/share/qt4/mkspecs/features/dui_defines.prf +usr/share/qt4/mkspecs/features/translations.prf diff --git a/debian/libdui-doc.install b/debian/libdui-doc.install new file mode 100644 index 000000000..a2fd1d700 --- /dev/null +++ b/debian/libdui-doc.install @@ -0,0 +1 @@ +usr/share/doc/libdui/* diff --git a/debian/libdui-l10n-ar.install b/debian/libdui-l10n-ar.install new file mode 100644 index 000000000..4a4ff59fe --- /dev/null +++ b/debian/libdui-l10n-ar.install @@ -0,0 +1 @@ +usr/share/l10n/dui/libdui_ar.qm diff --git a/debian/libdui-l10n-de.install b/debian/libdui-l10n-de.install new file mode 100644 index 000000000..dac113539 --- /dev/null +++ b/debian/libdui-l10n-de.install @@ -0,0 +1 @@ +usr/share/l10n/dui/libdui_de.qm diff --git a/debian/libdui-l10n-en.install b/debian/libdui-l10n-en.install new file mode 100644 index 000000000..ec58899d5 --- /dev/null +++ b/debian/libdui-l10n-en.install @@ -0,0 +1 @@ +usr/share/l10n/dui/libdui_en.qm diff --git a/debian/libdui-l10n-engineering-english.install b/debian/libdui-l10n-engineering-english.install new file mode 100644 index 000000000..d0d7fdac8 --- /dev/null +++ b/debian/libdui-l10n-engineering-english.install @@ -0,0 +1,2 @@ +usr/share/l10n/dui/libdui.qm +usr/share/doc/libdui-l10n-engineering-english/libdui.ts diff --git a/debian/libdui-l10n-fi.install b/debian/libdui-l10n-fi.install new file mode 100644 index 000000000..fc5ae3558 --- /dev/null +++ b/debian/libdui-l10n-fi.install @@ -0,0 +1 @@ +usr/share/l10n/dui/libdui_fi.qm diff --git a/debian/libdui-l10n-ur.install b/debian/libdui-l10n-ur.install new file mode 100644 index 000000000..d74bd8170 --- /dev/null +++ b/debian/libdui-l10n-ur.install @@ -0,0 +1 @@ +usr/share/l10n/dui/libdui_ur.qm diff --git a/debian/libdui-l10n-zh-cn.install b/debian/libdui-l10n-zh-cn.install new file mode 100644 index 000000000..a45737ce1 --- /dev/null +++ b/debian/libdui-l10n-zh-cn.install @@ -0,0 +1 @@ +usr/share/l10n/dui/libdui_zh_CN.qm diff --git a/debian/libdui-tests.dirs b/debian/libdui-tests.dirs new file mode 100644 index 000000000..714f060ed --- /dev/null +++ b/debian/libdui-tests.dirs @@ -0,0 +1,2 @@ +usr/lib/libdui-tests +usr/share/libdui-tests diff --git a/debian/libdui-tests.install b/debian/libdui-tests.install new file mode 100644 index 000000000..c222af502 --- /dev/null +++ b/debian/libdui-tests.install @@ -0,0 +1,2 @@ +usr/share/libdui-tests/* +usr/lib/libdui-tests/* diff --git a/debian/libdui-tests.postinst b/debian/libdui-tests.postinst new file mode 100644 index 000000000..0c6e28d3e --- /dev/null +++ b/debian/libdui-tests.postinst @@ -0,0 +1,9 @@ +#!/bin/sh + +# add en_US.UTF-8 locale if not already there: +# (this locale is needed for the test ft_duigconfitem) + +if ! egrep -q -E "^[[:space:]]*en_US.UTF-8[[:space:]]+UTF-8" /etc/locale.gen ; then + echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen + /usr/sbin/locale-gen +fi diff --git a/debian/libdui0.dirs b/debian/libdui0.dirs new file mode 100644 index 000000000..a9e6bb343 --- /dev/null +++ b/debian/libdui0.dirs @@ -0,0 +1,2 @@ +usr/lib/ +usr/lib/dui/applets diff --git a/debian/libdui0.install b/debian/libdui0.install new file mode 100644 index 000000000..7d48efcf9 --- /dev/null +++ b/debian/libdui0.install @@ -0,0 +1,7 @@ +usr/lib/libdui*.so* +usr/lib/qt4/plugins/styles/libduiqtstyleplugin.so +usr/bin/duithemedaemon +usr/bin/duiservicemapper +usr/share/dbus-1/services/com.nokia.servicefw.service +usr/share/dui/shaders/* +usr/lib/dui/applets/duiappletrunner diff --git a/debian/rules b/debian/rules new file mode 100755 index 000000000..d74694b64 --- /dev/null +++ b/debian/rules @@ -0,0 +1,147 @@ +#!/usr/bin/make -f +# -*- makefile -*- +# Uncomment this to turn on verbose mode. +export DH_VERBOSE=1 + +DEBDIR = .. + +comma :=, +empty := +space := $(empty) $(empty) + +ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS))) + INSTALL_PROGRAM += -s +endif + +TMP_BUILD_OPTS = $(subst $(comma),$(space),$(DEB_BUILD_OPTIONS)) + +ifneq (,$(filter parallel=%,$(TMP_BUILD_OPTS))) + NUMJOBS = $(patsubst parallel=%,%,$(filter parallel=%,$(TMP_BUILD_OPTS))) + PARALLEL_MAKEFLAGS += -j$(NUMJOBS) +endif + + +# Enable instrumentation by setting DEB_BUILD_OPTION=coverage,... +ifneq (,$(filter coverage,$(TMP_BUILD_OPTS))) + OPTIONS += -coverage +endif + +# Enable instrumentation by setting DEB_BUILD_OPTION=timestamps,... +ifneq (,$(filter timestamps,$(TMP_BUILD_OPTS))) + OPTIONS += -timestamps +endif + +# Disable building of tests by setting DEB_BUILD_OPTION=notests,... +ifneq (,$(filter nocheck,$(TMP_BUILD_OPTS))) + OPTIONS += -nomake tests +endif + +# Disable building of benchmarks by setting DEB_BUILD_OPTION=nobenchmarks,... +ifneq (,$(filter nobenchmarks,$(TMP_BUILD_OPTS))) + OPTIONS += -nomake benchmarks +endif + +# Disable building of demos by setting DEB_BUILD_OPTION=nodemos,... +ifneq (,$(filter nodemos,$(TMP_BUILD_OPTS))) + OPTIONS += -nomake demos +endif + +# When doing official releases, set TESTABILITY to off. Defaults to on now +# because integration cannot pass DEB_BUILD_OPTIONS. +ifeq (,$(findstring notestability,$(DEB_BUILD_OPTIONS))) + OPTIONS += -testable +endif + +QMAKE_OPTIONS += -r + +BUILD_DIR=build-$(shell dpkg-architecture -qDEB_BUILD_ARCH) + +configure: configure-stamp +configure-stamp: + dh_testdir + + mkdir -p $(BUILD_DIR) + ./configure --prefix=/usr -release -make "tests plainqt benchmarks" $(OPTIONS) + cd $(BUILD_DIR) && qmake $(QMAKE_OPTIONS) ../projects.pro + + touch configure-stamp + +build: build-stamp +build-stamp: configure-stamp + dh_testdir + + cd $(BUILD_DIR) && make $(PARALLEL_MAKEFLAGS) + + touch build-stamp + +clean: + dh_testdir + dh_testroot + + rm -f build-stamp configure-stamp + + rm -rf $(BUILD_DIR) + + dh_clean + +install: build + dh_testdir + dh_testroot + dh_prep + dh_installdirs + + # Add here commands to install the package into debian/tmp + + #libdui-doc package +ifeq (,$(findstring nodocs,$(DEB_BUILD_OPTIONS))) + cd $(BUILD_DIR) && make $(PARALLEL_MAKEFLAGS) doc +endif + + #libdui0 package + cd $(BUILD_DIR) && INSTALL_ROOT=$(CURDIR)/debian/tmp make $(PARALLEL_MAKEFLAGS) install + + install -m 644 -D -p $(BUILD_DIR)/demos/widgetsgallery/translations/widgetsgallery.ts $(CURDIR)/debian/tmp/usr/share/doc/dui-demos-widgetsgallery-l10n-engineering-english/widgetsgallery.ts + + install -m 644 -D -p $(BUILD_DIR)/src/translations/libdui.ts $(CURDIR)/debian/tmp/usr/share/doc/libdui-l10n-engineering-english/libdui.ts + +# Build architecture-independent files here. +binary-indep: build install +# We have nothing to do by default. + +# Build architecture-dependent files here. +binary-arch: build install + dh_testdir + dh_testroot + dh_installchangelogs + dh_installdocs + dh_install --sourcedir=debian/tmp -v +# dh_installexamples +# dh_install +# dh_installmenu +# dh_installdebconf +# dh_installlogrotate +# dh_installemacsen +# dh_installpam +# dh_installmime +# dh_installinit +# dh_installcron +# dh_installinfo +# dh_installman + dh_link + dh_strip -p libdui0 --dbg-package=libdui0 + dh_strip -p dui-demos-widgetsgallery --dbg-package=dui-demos-widgetsgallery + dh_strip -p dui-demos-plainqt --dbg-package=dui-demos-plainqt + dh_strip -p libdui-tests + dh_compress + dh_fixperms +# dh_perl +# dh_python + dh_makeshlibs + dh_installdeb + dh_shlibdeps + dh_gencontrol + dh_md5sums + dh_builddeb --destdir=$(DEBDIR) + +binary: binary-indep binary-arch +.PHONY: build clean binary-indep binary-arch binary install configure diff --git a/demos/animatedlayout/.gitignore b/demos/animatedlayout/.gitignore new file mode 100644 index 000000000..6f27c8f9f --- /dev/null +++ b/demos/animatedlayout/.gitignore @@ -0,0 +1,3 @@ +animatedlayout +qrc_animatedlayout.cpp + diff --git a/demos/animatedlayout/animatedlayout.cpp b/demos/animatedlayout/animatedlayout.cpp new file mode 100644 index 000000000..6679dbedc --- /dev/null +++ b/demos/animatedlayout/animatedlayout.cpp @@ -0,0 +1,547 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +/**************************************************************************** +** +** This file was initially based on a part of a Qt Solutions component. +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Solutions Commercial License Agreement provided +** with the Software or, alternatively, in accordance with the terms +** contained in a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** Please note Third Party Software included with Qt Solutions may impose +** additional restrictions and it is the user's responsibility to ensure +** that they have met the licensing requirements of the GPL, LGPL, or Qt +** Solutions Commercial license and the relevant license of the Third +** Party Software they are using. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +****************************************************************************/ + +#include +#include "../../src/core/duiexport.h" +#include +#include +#include +#include +#include +#include +#include +#include +//#include +#include +#include +#include +#include +#include +#include + +#define USE_INNER_FORM + +class AddItemButton; + +DuiScene *s_scene; +QList s_policies; +DuiFlowLayoutPolicy *s_flowLayoutPolicy; +DuiLinearLayoutPolicy *s_innerPolicy; +AddItemButton *s_addItemButton; + +/*! + * \class AnimatedlayoutRetranslator + * \brief AnimatedlayoutRetranslator is a test class to test translation on the fly + * + * This is just a simple test which will be changed soon. + * + */ +class AnimatedlayoutRetranslator : public QObject +{ + Q_OBJECT + +public slots: + void animatedlayoutRetranslate() { + qDebug() << __PRETTY_FUNCTION__; + DuiGConfItem languageItem("/Dui/i18n/Language"); + QString language = languageItem.value().toString(); + DuiLocale locale(language); + QString catalog = "animatedlayout"; + locale.installTrCatalog(catalog); + DuiLocale::setDefault(locale); + + // tell the scene and its items about the language change + QList items = s_scene->items(); + + foreach(QGraphicsItem * item, items) { + // call setLayoutDirection_helper() for all top-level items + if (!item->parentItem()) + this->setLayoutDirection_helper(static_cast(item)); + + if (item->isWidget()) { + QGraphicsWidget *widget = static_cast(item); + + QEvent ev(QEvent::LanguageChange); + qApp->sendEvent(widget, &ev); + QEvent evlayout(QEvent::LanguageChange); + qApp->sendEvent(widget, &evlayout); + } + } + } + +private: + void setLayoutDirection_helper(QGraphicsItem *item) { + if (item->isWidget()) { + QGraphicsWidget *widget = static_cast(item); + Qt::LayoutDirection direction = qApp->layoutDirection(); + // if the direction has not changed or has been specified + // directly, do not update. + if (((direction == Qt::RightToLeft) == widget->testAttribute(Qt::WA_RightToLeft)) + || widget->testAttribute(Qt::WA_SetLayoutDirection)) + return; + widget->setAttribute(Qt::WA_RightToLeft, (direction == Qt::RightToLeft)); + } + // Propagate this change to all children. + const int childItemsSize = item->childItems().size(); + for (int i = 0; i < childItemsSize; ++i) { + QGraphicsItem *childItem = item->childItems().at(i); + setLayoutDirection_helper(childItem); + } + if (item->isWidget()) { + // Send the notification event to this widget item. + QEvent e(QEvent::LayoutDirectionChange); + QApplication::sendEvent(static_cast(item), &e); + } + } +}; + +class ContainerWidget : public QGraphicsWidget +{ +public: + ContainerWidget(QGraphicsItem *parent = 0) + : QGraphicsWidget(parent) + {} + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) { + Q_UNUSED(option); + Q_UNUSED(widget); + QLinearGradient linearGrad(QPointF(0, 0), QPointF(size().width() / 5, size().height() / 5)); + linearGrad.setColorAt(0, QColor(0, 0, 0, 255)); + linearGrad.setColorAt(1, QColor(0, 0, 0, 0)); + painter->setPen(Qt::NoPen); + painter->setBrush(linearGrad); + painter->drawRoundedRect(0, 0, size().width() / 2, size().height() / 2, 5, 5); + + QLinearGradient linearGrad2(QPointF(size().width(), 0), QPointF(size().width() * 4 / 5, size().height() / 5)); + linearGrad2.setColorAt(0, QColor(0, 0, 0, 255)); + linearGrad2.setColorAt(1, QColor(0, 0, 0, 0)); + painter->setBrush(linearGrad2); + painter->drawRoundedRect(size().width() / 2, 0, size().width() / 2, size().height() / 2, 5, 5); + } +}; +class Button : public QGraphicsWidget +{ + Q_OBJECT +public: + Button(const QPixmap &pixmap, QGraphicsItem *parent = 0) + : QGraphicsWidget(parent), _pix(pixmap) { + setAcceptHoverEvents(true); + setCacheMode(DeviceCoordinateCache); + } + + QRectF boundingRect() const { + return QRectF(-65, -65, 130, 130); + } + + QPainterPath shape() const { + QPainterPath path; + path.addEllipse(boundingRect()); + return path; + } + + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *) { + bool down = option->state & QStyle::State_Sunken; + QRectF r = boundingRect(); + QLinearGradient grad(r.topLeft(), r.bottomRight()); + grad.setColorAt(down ? 1 : 0, option->state & QStyle::State_MouseOver ? Qt::white : Qt::lightGray); + grad.setColorAt(down ? 0 : 1, Qt::darkGray); + painter->setPen(Qt::darkGray); + painter->setBrush(grad); + painter->drawEllipse(r); + QLinearGradient grad2(r.topLeft(), r.bottomRight()); + grad.setColorAt(down ? 1 : 0, Qt::darkGray); + grad.setColorAt(down ? 0 : 1, Qt::lightGray); + painter->setPen(Qt::NoPen); + painter->setBrush(grad); + if (down) + painter->translate(2, 2); + painter->drawEllipse(r.adjusted(5, 5, -5, -5)); + painter->drawPixmap(-_pix.width() / 2, -_pix.height() / 2, _pix); + } + +signals: + void pressed(); + +protected: + void mousePressEvent(QGraphicsSceneMouseEvent *) { + emit pressed(); + update(); + } + + void mouseReleaseEvent(QGraphicsSceneMouseEvent *) { + update(); + } + +private: + QPixmap _pix; +}; + +class AnimatedlayoutLabel : public DuiLabel +{ + Q_OBJECT +public: + AnimatedlayoutLabel(const QString &messageId, DuiWidget *parent = 0) + : DuiLabel(parent), _messageId(messageId) { + this->setText(qtTrId(_messageId.toUtf8().constData())); + } +protected: + virtual void retranslateUi() { + this->setText(qtTrId(_messageId.toUtf8().constData())); + } +private: + QString _messageId; +}; + +class ChangePolicyObjectNameButton : public DuiButton +{ + Q_OBJECT +public: + ChangePolicyObjectNameButton(const QString &messageId, const QString &objectName, DuiWidget *parent = 0) + : DuiButton(parent), _objectName(objectName), _messageId(messageId) { + retranslateUi(); + } +protected: + virtual void retranslateUi() { + this->setText(qtTrId(_messageId.toUtf8().constData())); + } + + void mousePressEvent(QGraphicsSceneMouseEvent *event) { + foreach(DuiAbstractLayoutPolicy * policy, s_policies) { + policy->setObjectName(_objectName); + } + DuiButton::mousePressEvent(event); + } +private: + QString _objectName; + QString _messageId; +}; + + +class Image : public DuiImageWidget +{ +public: + explicit Image(const QString &imageName, DuiWidget *parent = 0) + : DuiImageWidget(imageName, parent) { + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum); + } + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event) { + DuiLayout *layout = dynamic_cast(parentLayoutItem()); + if (layout) { + if (event && event->button() == Qt::RightButton) { + layout->removeItem(this); + deleteLater(); + } else + layout->animatedDeleteItem(this); + } + } + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { + //Paint a white background so that we completely paint the bounding box + painter->setPen(Qt::NoPen); + painter->setBrush(Qt::white); + painter->drawRect(QRectF(0, 0, size().width(), size().height())); + DuiImageWidget::paint(painter, option, widget); + } +}; + +class AddItemButton : public DuiButton +{ +public: + AddItemButton(DuiWidget *parent = 0) + : DuiButton("+", parent) + {} +protected: + void mousePressEvent(QGraphicsSceneMouseEvent *event) { + Image *item = new Image("dui-logo-red"); + item->setObjectName("new"); + item->setVisible(false); + + s_flowLayoutPolicy->insertItem(10, item); + DuiButton::mousePressEvent(event); + } +}; + + +class ChangePolicyButton : public Button +{ +public: + ChangePolicyButton(const QPixmap &pixmap, DuiAbstractLayoutPolicy *policy, QGraphicsItem *parent = 0) + : Button(pixmap, parent), _policy(policy) + {} +protected: + void mousePressEvent(QGraphicsSceneMouseEvent *event) { + _policy->activate(); + Button::mousePressEvent(event); + DuiLinearLayoutPolicy *linearPolicy = dynamic_cast(_policy); + if (linearPolicy && + linearPolicy->orientation() == Qt::Vertical) + s_innerPolicy->setOrientation(Qt::Horizontal); + else + s_innerPolicy->setOrientation(Qt::Vertical); + s_addItemButton->setVisible(_policy == s_flowLayoutPolicy); + } +private: + DuiAbstractLayoutPolicy *_policy; +}; + +class View : public QGraphicsView +{ +public: + View(QGraphicsScene *scene) : QGraphicsView(scene) { } + +protected: + void resizeEvent(QResizeEvent *event) { + QGraphicsView::resizeEvent(event); + fitInView(sceneRect(), Qt::KeepAspectRatio); + } +}; + + +int main(int argc, char **argv) +{ + DuiApplication app(argc, argv); + + AnimatedlayoutRetranslator animatedlayoutRetranslator; + QObject::connect(&app, SIGNAL(localeSettingsChanged()), &animatedlayoutRetranslator, SLOT(animatedlayoutRetranslate())); + + QPixmap *bgPix = new QPixmap("images/background.png"); + + s_scene = new DuiScene; + int offset = 0; //sets where the background image starts tiling from + s_scene->setSceneRect(offset, offset, 864, 480); + + //We scale the background pixmap to be a bit bigger than the actual scene because + //when its resized, the aspect ratio might not be exactly 1:1. It's an ugly hack + QGraphicsPixmapItem *background = new QGraphicsPixmapItem(bgPix->scaled(864 + 10, 480 + 10)); + s_scene->addItem(background); + background->setZValue(-1); + background->setPos(-5, -5); + + DuiLayout *layout = new DuiLayout; + QGraphicsWidget *form = new ContainerWidget; + form->setLayout(layout); + s_scene->addItem(form); + form->setGeometry(offset, offset, 864, 480); + form->setPreferredWidth(864); + form->setPreferredHeight(480); + form->setMaximumWidth(864); + form->setMaximumHeight(480); + form->setMinimumWidth(864); + form->setMinimumHeight(480); + + DuiGridLayoutPolicy *gridPolicy = new DuiGridLayoutPolicy(layout); + DuiLinearLayoutPolicy *linearHorizontalPolicy = new DuiLinearLayoutPolicy(layout, Qt::Horizontal); + DuiLinearLayoutPolicy *linearVerticalPolicy = new DuiLinearLayoutPolicy(layout, Qt::Vertical); + s_flowLayoutPolicy = new DuiFlowLayoutPolicy(layout); + DuiAbstractLayoutPolicy *emptyPolicy = new DuiLinearLayoutPolicy(layout, Qt::Horizontal); + s_policies << linearHorizontalPolicy; + s_policies << linearVerticalPolicy; + s_policies << gridPolicy; + s_policies << s_flowLayoutPolicy; + s_policies << emptyPolicy; +// DuiFreestyleLayoutPolicy *freestylePolicy = new DuiFreestyleLayoutPolicy(layout); + + DuiLayout *innerLayout = new DuiLayout; +#ifdef USE_INNER_FORM + QGraphicsWidget *innerForm = new QGraphicsWidget; + innerForm->setLayout(innerLayout); + innerForm->setContentsMargins(0, 0, 0, 0); + innerForm->setMaximumWidth(50); + innerForm->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); +#endif + s_innerPolicy = new DuiLinearLayoutPolicy(innerLayout, Qt::Vertical); + innerLayout->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + + for (int i = 0; i < 4; ++i) { + Image *item = new Image("dui-logo-blue"); + item->setObjectName("blue"); + item->setVisible(false); + //add to active policy first + s_innerPolicy->addItem(item); + } + + int i = 0; + for (int y = 0; y < 10; ++y) { + for (int x = 0; x < 4; ++x, ++i) { + Image *item = new Image("dui-logo"); + item->setZValue(i); + item->setVisible(false); + //add to active policy first + if (y < 4) { + gridPolicy->addItem(item, y, x); + Q_ASSERT(item->scene()); + linearHorizontalPolicy->addItem(item); + linearVerticalPolicy->addItem(item); +// freestylePolicy->addItemAtGeometry(item, QRectF(100*x,100*y,130,130)); + } + s_flowLayoutPolicy->addItem(item); + } + gridPolicy->setColumnMaximumWidth(y, 50); + } + + //% "Hello" + AnimatedlayoutLabel *textlabel = new AnimatedlayoutLabel(QT_TRID_NOOP("xx_hello")); + textlabel->setObjectName("myLabelMultiLength"); + textlabel->setTextElide(true); + gridPolicy->addItem(textlabel, 4, 0); + linearHorizontalPolicy->addItem(textlabel); + linearVerticalPolicy->addItem(textlabel); +#ifdef USE_INNER_FORM + s_flowLayoutPolicy->addItem(textlabel); + gridPolicy->addItem(innerForm, 4, 1, 1, 1); + linearHorizontalPolicy->addItem(innerForm); + linearVerticalPolicy->addItem(innerForm); + s_flowLayoutPolicy->addItem(innerForm); +#else + s_flowLayoutPolicy->addItem(textlabel); + gridPolicy->addItem(innerLayout, 4, 1, 1, 1); + linearHorizontalPolicy->addItem(innerLayout); + linearVerticalPolicy->addItem(innerLayout); + s_flowLayoutPolicy->addItem(innerLayout); +#endif + + Q_ASSERT(dynamic_cast(s_innerPolicy->itemAt(0))->scene()); + + // Buttons + QGraphicsWidget *buttonParent = new QGraphicsWidget; + QList + + + diff --git a/examples/imtoolbar/toolbar2.xml b/examples/imtoolbar/toolbar2.xml new file mode 100644 index 000000000..286a4669b --- /dev/null +++ b/examples/imtoolbar/toolbar2.xml @@ -0,0 +1,25 @@ + + + + + + + + diff --git a/examples/layout/duiflowlayoutpolicy/.gitignore b/examples/layout/duiflowlayoutpolicy/.gitignore new file mode 100644 index 000000000..ee40536b2 --- /dev/null +++ b/examples/layout/duiflowlayoutpolicy/.gitignore @@ -0,0 +1 @@ +duiflowlayoutpolicy diff --git a/examples/layout/duiflowlayoutpolicy/duiflowlayoutpolicy.cpp b/examples/layout/duiflowlayoutpolicy/duiflowlayoutpolicy.cpp new file mode 100644 index 000000000..8be2e3065 --- /dev/null +++ b/examples/layout/duiflowlayoutpolicy/duiflowlayoutpolicy.cpp @@ -0,0 +1,59 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +/* + * A simple example of the DuiFlowLayoutPolicy class. + */ + +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char **argv) +{ + DuiApplication app(argc, argv); + DuiTheme::loadCSS("duiflowlayoutpolicy.css"); + DuiApplicationWindow window; + DuiApplicationPage page; + + /* Create a DuiLayout that we set the policy for */ + DuiLayout *layout = new DuiLayout; + + DuiFlowLayoutPolicy *policy = new DuiFlowLayoutPolicy(layout); + policy->setObjectName("example"); + policy->setRowLimit(2); //Only show 2 rows of items + + /* Add 20 items to the policy */ + for (int i = 1; i <= 20; ++i) { + DuiLabel *label = new DuiLabel(QString("Item %1").arg(i)); + policy->addItem(label); + label->setObjectName("item"); //Set CSS name, for styling + label->setAlignment(Qt::AlignCenter); + } + + /* Attach the layout to the page */ + page.centralWidget()->setLayout(layout); + window.show(); + page.appearNow(); + return app.exec(); +} diff --git a/examples/layout/duiflowlayoutpolicy/duiflowlayoutpolicy.css b/examples/layout/duiflowlayoutpolicy/duiflowlayoutpolicy.css new file mode 100644 index 000000000..d09e0b793 --- /dev/null +++ b/examples/layout/duiflowlayoutpolicy/duiflowlayoutpolicy.css @@ -0,0 +1,16 @@ +#item { + font: "Nokia Sans Wide" 21px; + background-color: #eeeeee; + preferred-size: 100 100; +} + +DuiAbstractLayoutPolicyStyle#example { + horizontal-spacing: 10; + vertical-spacing: 10; +} +DuiAbstractLayoutPolicyStyle#example.Portrait { + vertical-spacing: 0; + horizontal-spacing: 0; +} + + diff --git a/examples/layout/duiflowlayoutpolicy/duiflowlayoutpolicy.dox b/examples/layout/duiflowlayoutpolicy/duiflowlayoutpolicy.dox new file mode 100644 index 000000000..16d4aa94b --- /dev/null +++ b/examples/layout/duiflowlayoutpolicy/duiflowlayoutpolicy.dox @@ -0,0 +1,16 @@ +/** +\page layout-duiflowlayoutpolicy DuiFlowLayoutPolicy example + +Source code for a simple example of DuiFlowLayoutPolicy. + +\image html duiflowlayoutpolicy.png + +\include examples/layout/duiflowlayoutpolicy/duiflowlayoutpolicy.cpp + +Styled with the following duiflowlayoutpolicy.css file: +\include examples/layout/duiflowlayoutpolicy/duiflowlayoutpolicy.css + +And compiled with the following duiflowlayoutpolicy.pro file: +\include examples/layout/duiflowlayoutpolicy/duiflowlayoutpolicy.pro + +*/ diff --git a/examples/layout/duiflowlayoutpolicy/duiflowlayoutpolicy.pro b/examples/layout/duiflowlayoutpolicy/duiflowlayoutpolicy.pro new file mode 100644 index 000000000..dd3ac94a7 --- /dev/null +++ b/examples/layout/duiflowlayoutpolicy/duiflowlayoutpolicy.pro @@ -0,0 +1,10 @@ +TEMPLATE = app +CONFIG += dui + +# Input +SOURCES += *.cpp + +INCLUDEPATH += ../../src/include +QMAKE_LIBDIR += ../../lib/ + + diff --git a/examples/layout/duifreestylelayoutpolicy/.gitignore b/examples/layout/duifreestylelayoutpolicy/.gitignore new file mode 100644 index 000000000..d587b126e --- /dev/null +++ b/examples/layout/duifreestylelayoutpolicy/.gitignore @@ -0,0 +1 @@ +duifreestylelayoutpolicy diff --git a/examples/layout/duifreestylelayoutpolicy/duifreestylelayoutpolicy.cpp b/examples/layout/duifreestylelayoutpolicy/duifreestylelayoutpolicy.cpp new file mode 100644 index 000000000..bf4c22618 --- /dev/null +++ b/examples/layout/duifreestylelayoutpolicy/duifreestylelayoutpolicy.cpp @@ -0,0 +1,61 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +/* + * A simple example of the DuiFreestyleLayoutPolicy class. + */ + +#include +#include +#include +#include +#include +#include +#include +#include //For sin and cos +int main(int argc, char **argv) +{ + DuiApplication app(argc, argv); + DuiTheme::loadCSS("duifreestylelayoutpolicy.css"); + + /* Create a DuiLayout that we set the policy for */ + DuiLayout *layout = new DuiLayout; + DuiFreestyleLayoutPolicy *policy = new DuiFreestyleLayoutPolicy(layout); + policy->setSpacing(10); + + DuiApplicationWindow window; + DuiApplicationPage page; + /* Attach the layout to the page */ + page.centralWidget()->setLayout(layout); + window.show(); + page.appearNow(); + + int n = 20; + for (int i = 0; i < n; ++i) { + DuiLabel *label = new DuiLabel(QString("Item %1").arg(i + 1)); + label->setObjectName("item"); + //Place the items in an ellipse with the width and height of the page + int center_x = label->preferredWidth() / 2 + (page.geometry().width() - label->preferredWidth()) / 2 * (1 - cos(2 * 3.13 * i / n)); + int center_y = 25 + (page.geometry().height() - 50) / 3 * (1 - sin(2 * 3.13 * i / n)); + policy->addItemAtGeometry(label, QRect(center_x - label->preferredWidth() / 2, center_y - label->preferredHeight() / 2, label->preferredWidth(), label->preferredHeight())); + label->setAlignment(Qt::AlignCenter); + } + + return app.exec(); +} diff --git a/examples/layout/duifreestylelayoutpolicy/duifreestylelayoutpolicy.css b/examples/layout/duifreestylelayoutpolicy/duifreestylelayoutpolicy.css new file mode 100644 index 000000000..8d1cedb92 --- /dev/null +++ b/examples/layout/duifreestylelayoutpolicy/duifreestylelayoutpolicy.css @@ -0,0 +1,4 @@ +#item { + font: "Nokia Sans Wide" 21px; + background-color: #eeeeee; +} diff --git a/examples/layout/duifreestylelayoutpolicy/duifreestylelayoutpolicy.dox b/examples/layout/duifreestylelayoutpolicy/duifreestylelayoutpolicy.dox new file mode 100644 index 000000000..72c545bdf --- /dev/null +++ b/examples/layout/duifreestylelayoutpolicy/duifreestylelayoutpolicy.dox @@ -0,0 +1,16 @@ +/** +\page layout-duifreestylelayoutpolicy DuiFreestyleLayoutPolicy example + +Source code for a simple example of DuiFreestyleLayoutPolicy. + +\image html duifreestylelayoutpolicy.png + +\include examples/layout/duifreestylelayoutpolicy/duifreestylelayoutpolicy.cpp + +Styled with the following duifreestylelayoutpolicy.css file: +\include examples/layout/duifreestylelayoutpolicy/duifreestylelayoutpolicy.css + +And compiled with the following duifreestylelayoutpolicy.pro file: +\include examples/layout/duifreestylelayoutpolicy/duifreestylelayoutpolicy.pro + +*/ diff --git a/examples/layout/duifreestylelayoutpolicy/duifreestylelayoutpolicy.pro b/examples/layout/duifreestylelayoutpolicy/duifreestylelayoutpolicy.pro new file mode 100644 index 000000000..dd3ac94a7 --- /dev/null +++ b/examples/layout/duifreestylelayoutpolicy/duifreestylelayoutpolicy.pro @@ -0,0 +1,10 @@ +TEMPLATE = app +CONFIG += dui + +# Input +SOURCES += *.cpp + +INCLUDEPATH += ../../src/include +QMAKE_LIBDIR += ../../lib/ + + diff --git a/examples/layout/duigridlayoutpolicy/.gitignore b/examples/layout/duigridlayoutpolicy/.gitignore new file mode 100644 index 000000000..99b9dcacc --- /dev/null +++ b/examples/layout/duigridlayoutpolicy/.gitignore @@ -0,0 +1 @@ +duigridlayoutpolicy diff --git a/examples/layout/duigridlayoutpolicy/duigridlayoutpolicy.cpp b/examples/layout/duigridlayoutpolicy/duigridlayoutpolicy.cpp new file mode 100644 index 000000000..e2fbdcaac --- /dev/null +++ b/examples/layout/duigridlayoutpolicy/duigridlayoutpolicy.cpp @@ -0,0 +1,56 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +/* + * A simple example of the DuiGridLayoutPolicy class. + */ + +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char **argv) +{ + DuiApplication app(argc, argv); + DuiTheme::loadCSS("duigridlayoutpolicy.css"); + DuiApplicationWindow window; + DuiApplicationPage page; + /* Create a DuiLayout that we set the policy for */ + DuiLayout *layout = new DuiLayout; + DuiGridLayoutPolicy *policy = new DuiGridLayoutPolicy(layout); + policy->setSpacing(10); + + /* Add 7 items to the policy, arranging them into a grid with 3 columns */ + for (int i = 0; i < 7; ++i) { + DuiLabel *label = new DuiLabel(QString("Item %1").arg(i + 1)); + policy->addItem(label, i / 3, i % 3); + label->setObjectName("item"); + label->setAlignment(Qt::AlignCenter); + } + + /* Attach the layout to the page */ + page.centralWidget()->setLayout(layout); + window.show(); + page.appearNow(); + return app.exec(); +} diff --git a/examples/layout/duigridlayoutpolicy/duigridlayoutpolicy.css b/examples/layout/duigridlayoutpolicy/duigridlayoutpolicy.css new file mode 100644 index 000000000..0ac8ce7f0 --- /dev/null +++ b/examples/layout/duigridlayoutpolicy/duigridlayoutpolicy.css @@ -0,0 +1,5 @@ +#item { + font: "Nokia Sans Wide" 21px; + background-color: #eeeeee; + preferred-size: 85 85; +} diff --git a/examples/layout/duigridlayoutpolicy/duigridlayoutpolicy.dox b/examples/layout/duigridlayoutpolicy/duigridlayoutpolicy.dox new file mode 100644 index 000000000..67e00e7cc --- /dev/null +++ b/examples/layout/duigridlayoutpolicy/duigridlayoutpolicy.dox @@ -0,0 +1,16 @@ +/** +\page layout-duigridlayoutpolicy DuiGridLayoutPolicy example + +Source code for a simple example of DuiGridLayoutPolicy. + +\image html duigridlayoutpolicy.png + +\include examples/layout/duigridlayoutpolicy/duigridlayoutpolicy.cpp + +Styled with the following duigridlayoutpolicy.css file: +\include examples/layout/duigridlayoutpolicy/duigridlayoutpolicy.css + +And compiled with the following duigridlayoutpolicy.pro file: +\include examples/layout/duigridlayoutpolicy/duigridlayoutpolicy.pro + +*/ diff --git a/examples/layout/duigridlayoutpolicy/duigridlayoutpolicy.pro b/examples/layout/duigridlayoutpolicy/duigridlayoutpolicy.pro new file mode 100644 index 000000000..dd3ac94a7 --- /dev/null +++ b/examples/layout/duigridlayoutpolicy/duigridlayoutpolicy.pro @@ -0,0 +1,10 @@ +TEMPLATE = app +CONFIG += dui + +# Input +SOURCES += *.cpp + +INCLUDEPATH += ../../src/include +QMAKE_LIBDIR += ../../lib/ + + diff --git a/examples/layout/duilinearlayoutpolicy/.gitignore b/examples/layout/duilinearlayoutpolicy/.gitignore new file mode 100644 index 000000000..8c8060ef0 --- /dev/null +++ b/examples/layout/duilinearlayoutpolicy/.gitignore @@ -0,0 +1 @@ +duilinearlayoutpolicy diff --git a/examples/layout/duilinearlayoutpolicy/duilinearlayoutpolicy.cpp b/examples/layout/duilinearlayoutpolicy/duilinearlayoutpolicy.cpp new file mode 100644 index 000000000..6a31dde97 --- /dev/null +++ b/examples/layout/duilinearlayoutpolicy/duilinearlayoutpolicy.cpp @@ -0,0 +1,56 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +/* + * A simple example of the DuiLinearLayoutPolicy class. + */ + +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char **argv) +{ + DuiApplication app(argc, argv); + DuiTheme::loadCSS("duilinearlayoutpolicy.css"); + DuiApplicationWindow window; + DuiApplicationPage page; + /* Create a DuiLayout that we set the policy for */ + DuiLayout *layout = new DuiLayout; + DuiLinearLayoutPolicy *policy = new DuiLinearLayoutPolicy(layout, Qt::Vertical); + policy->setSpacing(10); + + /* Add 3 items to the policy, arranging them vertically stacked on top of each other */ + for (int i = 0; i < 3; ++i) { + DuiLabel *label = new DuiLabel(QString("Item %1").arg(i + 1)); + policy->addItem(label); + label->setObjectName("item"); + label->setAlignment(Qt::AlignCenter); + } + + /* Attach the layout to the page */ + page.centralWidget()->setLayout(layout); + window.show(); + page.appearNow(); + return app.exec(); +} diff --git a/examples/layout/duilinearlayoutpolicy/duilinearlayoutpolicy.css b/examples/layout/duilinearlayoutpolicy/duilinearlayoutpolicy.css new file mode 100644 index 000000000..6cbb97c48 --- /dev/null +++ b/examples/layout/duilinearlayoutpolicy/duilinearlayoutpolicy.css @@ -0,0 +1,5 @@ +#item { + font: "Nokia Sans Wide" 21px; + background-color: #eeeeee; + preferred-size: 100 85; +} diff --git a/examples/layout/duilinearlayoutpolicy/duilinearlayoutpolicy.dox b/examples/layout/duilinearlayoutpolicy/duilinearlayoutpolicy.dox new file mode 100644 index 000000000..80ad90531 --- /dev/null +++ b/examples/layout/duilinearlayoutpolicy/duilinearlayoutpolicy.dox @@ -0,0 +1,16 @@ +/** +\page layout-duilinearlayoutpolicy DuiLinearLayoutPolicy example + +Source code for a simple example of DuiLinearLayoutPolicy. + +\image html duilinearlayoutpolicy.png + +\include examples/layout/duilinearlayoutpolicy/duilinearlayoutpolicy.cpp + +Styled with the following duilinearlayoutpolicy.css file: +\include examples/layout/duilinearlayoutpolicy/duilinearlayoutpolicy.css + +And compiled with the following duilinearlayoutpolicy.pro file: +\include examples/layout/duilinearlayoutpolicy/duilinearlayoutpolicy.pro + +*/ diff --git a/examples/layout/duilinearlayoutpolicy/duilinearlayoutpolicy.pro b/examples/layout/duilinearlayoutpolicy/duilinearlayoutpolicy.pro new file mode 100644 index 000000000..dd3ac94a7 --- /dev/null +++ b/examples/layout/duilinearlayoutpolicy/duilinearlayoutpolicy.pro @@ -0,0 +1,10 @@ +TEMPLATE = app +CONFIG += dui + +# Input +SOURCES += *.cpp + +INCLUDEPATH += ../../src/include +QMAKE_LIBDIR += ../../lib/ + + diff --git a/examples/layout/hidden_widgets/.gitignore b/examples/layout/hidden_widgets/.gitignore new file mode 100644 index 000000000..8cf60d58f --- /dev/null +++ b/examples/layout/hidden_widgets/.gitignore @@ -0,0 +1 @@ +hidden_widgets diff --git a/examples/layout/hidden_widgets/hidden_widgets.cpp b/examples/layout/hidden_widgets/hidden_widgets.cpp new file mode 100644 index 000000000..4fa025ee8 --- /dev/null +++ b/examples/layout/hidden_widgets/hidden_widgets.cpp @@ -0,0 +1,59 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +/* + * A simple example of hiding a widget + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char **argv) +{ + DuiApplication app(argc, argv); + DuiTheme::loadCSS("hidden_widgets.css"); + DuiApplicationWindow window; + DuiApplicationPage page; + /* Create a DuiLayout that we set the policy for */ + DuiLayout *layout = new DuiLayout; + DuiLinearLayoutPolicy *policy = new DuiLinearLayoutPolicy(layout, Qt::Vertical); + policy->setSpacing(10); + + /* Add 3 items to the policy, arranging them vertically stacked on top of each other */ + for (int i = 0; i < 3; ++i) { + DuiLabel *label = new DuiLabel(QString("Item %1").arg(i + 1)); + policy->addItem(label); + label->setObjectName("item"); + label->setAlignment(Qt::AlignCenter); + } + /* Hide the middle item manually. Note that we must call the DuiWidget::hide() function. */ + qgraphicsitem_cast(policy->itemAt(1)->graphicsItem())->hide(); + + /* Attach the layout to the page */ + page.centralWidget()->setLayout(layout); + window.show(); + page.appearNow(); + return app.exec(); +} diff --git a/examples/layout/hidden_widgets/hidden_widgets.css b/examples/layout/hidden_widgets/hidden_widgets.css new file mode 100644 index 000000000..6cbb97c48 --- /dev/null +++ b/examples/layout/hidden_widgets/hidden_widgets.css @@ -0,0 +1,5 @@ +#item { + font: "Nokia Sans Wide" 21px; + background-color: #eeeeee; + preferred-size: 100 85; +} diff --git a/examples/layout/hidden_widgets/hidden_widgets.dox b/examples/layout/hidden_widgets/hidden_widgets.dox new file mode 100644 index 000000000..2a058be7e --- /dev/null +++ b/examples/layout/hidden_widgets/hidden_widgets.dox @@ -0,0 +1,16 @@ +/** +\page layout-hidden_widgets A layout with a hidden widget example + +Source code for a simple example of hiding a widget in a layout. + +\image html hidden_widgets.png + +\include examples/layout/hidden_widgets/hidden_widgets.cpp + +Styled with the following hidden_widgets.css file: +\include examples/layout/hidden_widgets/hidden_widgets.css + +And compiled with the following hidden_widgets.pro file: +\include examples/layout/hidden_widgets/hidden_widgets.pro + +*/ diff --git a/examples/layout/hidden_widgets/hidden_widgets.pro b/examples/layout/hidden_widgets/hidden_widgets.pro new file mode 100644 index 000000000..cde87187a --- /dev/null +++ b/examples/layout/hidden_widgets/hidden_widgets.pro @@ -0,0 +1,6 @@ +TEMPLATE = app +CONFIG += dui + +# Input +SOURCES += *.cpp + diff --git a/examples/layout/layout_inside_layout/.gitignore b/examples/layout/layout_inside_layout/.gitignore new file mode 100644 index 000000000..d8768ee2a --- /dev/null +++ b/examples/layout/layout_inside_layout/.gitignore @@ -0,0 +1 @@ +layout_inside_layout diff --git a/examples/layout/layout_inside_layout/layout_inside_layout.cpp b/examples/layout/layout_inside_layout/layout_inside_layout.cpp new file mode 100644 index 000000000..23b4c972a --- /dev/null +++ b/examples/layout/layout_inside_layout/layout_inside_layout.cpp @@ -0,0 +1,74 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +/* + * A simple example of a layout within a layout where the inner layout can be hidden. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char **argv) +{ + DuiApplication app(argc, argv); + DuiTheme::loadCSS("layout_inside_layout.css"); + DuiApplicationWindow window; + DuiApplicationPage page; + + /* Create a DuiLayout that we set the policies for */ + DuiLayout *layout = new DuiLayout; + DuiLinearLayoutPolicy *portraitPolicy = new DuiLinearLayoutPolicy(layout, Qt::Horizontal); + DuiLinearLayoutPolicy *landscapePolicy = new DuiLinearLayoutPolicy(layout, Qt::Horizontal); + for (int i = 0; i < 3; ++i) { + DuiLabel *label = new DuiLabel(QString("Item %1").arg(i + 1)); + label->setAlignment(Qt::AlignCenter); + label->setObjectName("item"); //Set CSS name for styling + portraitPolicy->addItem(label); + landscapePolicy->addItem(label); + } + /* Create a widget to hold the inner layout and to put inside the policy */ + QGraphicsWidget *widget = new QGraphicsWidget; + /* Create an inner layout. A QGraphicsGridLayout is used since we don't require + * multiple policies here, but using a DuiLayout would also work. */ + QGraphicsGridLayout *innerLayout = new QGraphicsGridLayout(widget); + for (int i = 0; i < 4; ++i) { + DuiLabel *label = new DuiLabel(QString("Inner Item %1").arg(i + 1)); + label->setAlignment(Qt::AlignCenter); + label->setObjectName("inneritem"); //Set CSS name for styling + innerLayout->addItem(label, i / 2, i % 2); + } + /* Now add the widget to the landscape policy only, so that the innerLayout is hidden when device is rotated */ + landscapePolicy->addItem(widget); + layout->setLandscapePolicy(landscapePolicy); + layout->setPortraitPolicy(portraitPolicy); + + /* Attach the layout to the page */ + page.centralWidget()->setLayout(layout); + window.show(); + page.appearNow(); + return app.exec(); +} diff --git a/examples/layout/layout_inside_layout/layout_inside_layout.css b/examples/layout/layout_inside_layout/layout_inside_layout.css new file mode 100644 index 000000000..5954af199 --- /dev/null +++ b/examples/layout/layout_inside_layout/layout_inside_layout.css @@ -0,0 +1,9 @@ +#item { + font: "Nokia Sans Wide" 21px; + background-color: #eeeeee; + preferred-size: 85 85; +} +#inneritem { + font: "Nokia Sans Wide" 16px; + background-color: #303030; +} diff --git a/examples/layout/layout_inside_layout/layout_inside_layout.dox b/examples/layout/layout_inside_layout/layout_inside_layout.dox new file mode 100644 index 000000000..578cd4dc7 --- /dev/null +++ b/examples/layout/layout_inside_layout/layout_inside_layout.dox @@ -0,0 +1,28 @@ +/** +\page layout-inside-layout Hiding a QGraphicsLayout or DuiLayout + +Source code for a simple example showing how do hide a DuiLayout or QGraphicsLayout. + +A DuiLayout or QGraphicsLayout should always be attached to QGraphicsWidget (or DuiWidget) or inside another layout. +If you place a layout inside of another layout, the inner layout cannot be hidden, because a layout by +itself cannot be hidden (There is no hide() function in QGraphicsLayout). Likewise if you remove the inner layout, +it will remain visible because it needs to be attached to something. + +If you want to be able to hide a layout that is inside another layout, you can place the inner layout inside of +a QGraphicsWidget, then place that QGraphicsWidget inside of the outer layout. This example demonstrates this. + +\image html layout_inside_layout_landscape.png + + +\image html layout_inside_layout_portrait.png + +Source code of layout_inside_layout.cpp: +\include examples/layout_inside_layout/layout_inside_layout.cpp + +Styled with the following layout_inside_layout.css file: +\include examples/layout_inside_layout/layout_inside_layout.css + +And compiled with the following layout_inside_layout.pro file: +\include examples/layout_inside_layout/layout_inside_layout.pro + +*/ diff --git a/examples/layout/layout_inside_layout/layout_inside_layout.pro b/examples/layout/layout_inside_layout/layout_inside_layout.pro new file mode 100644 index 000000000..dd3ac94a7 --- /dev/null +++ b/examples/layout/layout_inside_layout/layout_inside_layout.pro @@ -0,0 +1,10 @@ +TEMPLATE = app +CONFIG += dui + +# Input +SOURCES += *.cpp + +INCLUDEPATH += ../../src/include +QMAKE_LIBDIR += ../../lib/ + + diff --git a/examples/layout/multiplepolicies/.gitignore b/examples/layout/multiplepolicies/.gitignore new file mode 100644 index 000000000..10451756a --- /dev/null +++ b/examples/layout/multiplepolicies/.gitignore @@ -0,0 +1 @@ +multiplepolicies diff --git a/examples/layout/multiplepolicies/multiplepolicies.cpp b/examples/layout/multiplepolicies/multiplepolicies.cpp new file mode 100644 index 000000000..3f6bdb56c --- /dev/null +++ b/examples/layout/multiplepolicies/multiplepolicies.cpp @@ -0,0 +1,64 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +/* + * A simple example of a layout with both a DuiLinearLayoutPolicy and a DuiFlowLayoutPolicy. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char **argv) +{ + DuiApplication app(argc, argv); + DuiTheme::loadCSS("multiplepolicies.css"); + DuiApplicationWindow window; + DuiApplicationPage page; + + /* Create a DuiLayout that we set the policies for */ + DuiLayout *layout = new DuiLayout(page.centralWidget()); + DuiLinearLayoutPolicy *linearPolicy = new DuiLinearLayoutPolicy(layout, Qt::Vertical); + DuiFlowLayoutPolicy *flowPolicy = new DuiFlowLayoutPolicy(layout); + for (int i = 0; i < 10; ++i) { + DuiLabel *label = new DuiLabel(QString("Item %1").arg(i + 1)); + label->setAlignment(Qt::AlignCenter); + label->setObjectName("item"); //Set CSS name for styling + + flowPolicy->addItem(label); // Add all of the items to the flow policy + if (i < 3) // But only add the first 3 items to the linear policy + linearPolicy->addItem(label); + else + label->setObjectName("flowonly"); //Set CSS name, for styling flow layout items differently + } + /* Switch from a linear policy in landscape mode to a flow policy in portrait mode */ + layout->setLandscapePolicy(linearPolicy); + layout->setPortraitPolicy(flowPolicy); + + window.show(); + page.appearNow(); + return app.exec(); +} diff --git a/examples/layout/multiplepolicies/multiplepolicies.css b/examples/layout/multiplepolicies/multiplepolicies.css new file mode 100644 index 000000000..01955911e --- /dev/null +++ b/examples/layout/multiplepolicies/multiplepolicies.css @@ -0,0 +1,10 @@ +#item { + font: "Nokia Sans Wide" 21px; + background-color: #eeeeee; + preferred-size: 85 85; +} +#flowonly { + font: "Nokia Sans Wide" 21px; + background-color: #303030; + preferred-size: 85 85; +} diff --git a/examples/layout/multiplepolicies/multiplepolicies.dox b/examples/layout/multiplepolicies/multiplepolicies.dox new file mode 100644 index 000000000..eee932b6e --- /dev/null +++ b/examples/layout/multiplepolicies/multiplepolicies.dox @@ -0,0 +1,19 @@ +/** +\page layout-multiplepolicies DuiLayout With Multiple Policies Example + +Source code for a simple example of a DuiLayout with both a flow and a linear layout. +A vertical linear layout is used when the device is in landscape mode, and a flow layout +when the device in portrait mode. Some of the items are added to only one layout, and some +are added to both. Note that the layout hides and shows the items as required. + +\image html multiplepolicies.gif "Animation of device changing from landscape to portrait mode" + +\include examples/layout/multiplepolicies/multiplepolicies.cpp + +Styled with the following multiplepolicies.css file: +\include examples/layout/multiplepolicies/multiplepolicies.css + +And compiled with the following multiplepolicies.pro file: +\include examples/layout/multiplepolicies/multiplepolicies.pro + +*/ diff --git a/examples/layout/multiplepolicies/multiplepolicies.pro b/examples/layout/multiplepolicies/multiplepolicies.pro new file mode 100644 index 000000000..dd3ac94a7 --- /dev/null +++ b/examples/layout/multiplepolicies/multiplepolicies.pro @@ -0,0 +1,10 @@ +TEMPLATE = app +CONFIG += dui + +# Input +SOURCES += *.cpp + +INCLUDEPATH += ../../src/include +QMAKE_LIBDIR += ../../lib/ + + diff --git a/examples/layout/qgraphicsgridlayout/.gitignore b/examples/layout/qgraphicsgridlayout/.gitignore new file mode 100644 index 000000000..cf835107a --- /dev/null +++ b/examples/layout/qgraphicsgridlayout/.gitignore @@ -0,0 +1 @@ +qgraphicsgridlayout diff --git a/examples/layout/qgraphicsgridlayout/qgraphicsgridlayout.cpp b/examples/layout/qgraphicsgridlayout/qgraphicsgridlayout.cpp new file mode 100644 index 000000000..c3688efb3 --- /dev/null +++ b/examples/layout/qgraphicsgridlayout/qgraphicsgridlayout.cpp @@ -0,0 +1,54 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +/* + * A simple example of the QGraphicsGridLayout class. + */ + +#include +#include +#include +#include +#include +#include + +int main(int argc, char **argv) +{ + DuiApplication app(argc, argv); + DuiTheme::loadCSS("qgraphicsgridlayout.css"); + DuiApplicationWindow window; + DuiApplicationPage page; + /* Create a grid layout */ + QGraphicsGridLayout *layout = new QGraphicsGridLayout; + layout->setSpacing(10); + + /* Add 7 items to the layout, arranging them into a grid with 3 columns */ + for (int i = 0; i < 7; ++i) { + DuiLabel *label = new DuiLabel(QString("Item %1").arg(i + 1)); + layout->addItem(label, i / 3, i % 3); + label->setObjectName("item"); + label->setAlignment(Qt::AlignCenter); + } + + /* Attach the layout to the page */ + page.centralWidget()->setLayout(layout); + window.show(); + page.appearNow(); + return app.exec(); +} diff --git a/examples/layout/qgraphicsgridlayout/qgraphicsgridlayout.css b/examples/layout/qgraphicsgridlayout/qgraphicsgridlayout.css new file mode 100644 index 000000000..0ac8ce7f0 --- /dev/null +++ b/examples/layout/qgraphicsgridlayout/qgraphicsgridlayout.css @@ -0,0 +1,5 @@ +#item { + font: "Nokia Sans Wide" 21px; + background-color: #eeeeee; + preferred-size: 85 85; +} diff --git a/examples/layout/qgraphicsgridlayout/qgraphicsgridlayout.dox b/examples/layout/qgraphicsgridlayout/qgraphicsgridlayout.dox new file mode 100644 index 000000000..1f8148ed8 --- /dev/null +++ b/examples/layout/qgraphicsgridlayout/qgraphicsgridlayout.dox @@ -0,0 +1,17 @@ +/** +\page layout-qgraphicsgridlayout QGraphicsGridLayout example + +Source code for a simple example of QGraphicsGridLayout. + +\image html duigridlayoutpolicy.png + +Source code of qgraphicsgridlayout.cpp: +\include examples/layout/qgraphicsgridlayout/qgraphicsgridlayout.cpp + +Styled with the following qgraphicsgridlayout.css file: +\include examples/layout/qgraphicsgridlayout/qgraphicsgridlayout.css + +And compiled with the following qgraphicsgridlayout.pro file: +\include examples/layout/qgraphicsgridlayout/qgraphicsgridlayout.pro + +*/ diff --git a/examples/layout/qgraphicsgridlayout/qgraphicsgridlayout.pro b/examples/layout/qgraphicsgridlayout/qgraphicsgridlayout.pro new file mode 100644 index 000000000..dd3ac94a7 --- /dev/null +++ b/examples/layout/qgraphicsgridlayout/qgraphicsgridlayout.pro @@ -0,0 +1,10 @@ +TEMPLATE = app +CONFIG += dui + +# Input +SOURCES += *.cpp + +INCLUDEPATH += ../../src/include +QMAKE_LIBDIR += ../../lib/ + + diff --git a/examples/layout/qgraphicslayout/.gitignore b/examples/layout/qgraphicslayout/.gitignore new file mode 100644 index 000000000..9173e82c7 --- /dev/null +++ b/examples/layout/qgraphicslayout/.gitignore @@ -0,0 +1 @@ +qgraphicslayout diff --git a/examples/layout/qgraphicslayout/qgraphicslayout.cpp b/examples/layout/qgraphicslayout/qgraphicslayout.cpp new file mode 100644 index 000000000..6c0887af7 --- /dev/null +++ b/examples/layout/qgraphicslayout/qgraphicslayout.cpp @@ -0,0 +1,55 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +/* + * A simple example of a layout within a layout, using the Qt layout classes. + */ + +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char **argv) +{ + DuiApplication app(argc, argv); + DuiTheme::loadCSS("qgraphicslayout.css"); + DuiApplicationWindow window; + DuiApplicationPage page; + + QGraphicsLinearLayout *outerLayout = new QGraphicsLinearLayout(Qt::Vertical, page.centralWidget()); + QGraphicsLinearLayout *firstRow = new QGraphicsLinearLayout(Qt::Horizontal); + QGraphicsLinearLayout *secondRow = new QGraphicsLinearLayout(Qt::Horizontal); + outerLayout->addItem(firstRow); + outerLayout->addItem(secondRow); + firstRow->addItem(new DuiLabel("Label on first row")); + firstRow->addItem(new DuiButton("Button")); + firstRow->addStretch(); + secondRow->addItem(new DuiLabel("Label on second row")); + secondRow->addItem(new DuiButton("Button 1")); + secondRow->addItem(new DuiButton("Button 2")); + secondRow->addStretch(); + + window.show(); + page.appearNow(); + return app.exec(); +} diff --git a/examples/layout/qgraphicslayout/qgraphicslayout.css b/examples/layout/qgraphicslayout/qgraphicslayout.css new file mode 100644 index 000000000..6e8c0ced3 --- /dev/null +++ b/examples/layout/qgraphicslayout/qgraphicslayout.css @@ -0,0 +1,8 @@ +DuiLabelStyle { + font: "Nokia Sans Wide" 21px; +} +DuiButtonStyle { + font: "Nokia Sans Wide" 16px; + normal-background-image: scalable(Toggle-btn-normal,0,0,0,0); + pressed-background-image: scalable(Toggle-btn-selected,0,0,0,0); +} diff --git a/examples/layout/qgraphicslayout/qgraphicslayout.dox b/examples/layout/qgraphicslayout/qgraphicslayout.dox new file mode 100644 index 000000000..79668fc84 --- /dev/null +++ b/examples/layout/qgraphicslayout/qgraphicslayout.dox @@ -0,0 +1,19 @@ +/** +\page layout-qgraphicslayout QGraphicsLayout Example + +Source code for a simple example showing how do place a QGraphicsLayout inside of another QGraphicsLayout. + +QGraphicsLayout (or DuiLayout) should always be attached to QGraphicsWidget (or DuiWidget) or inside another QGraphicsLayout. + +\image html qgraphicslayout.png + +Source code of qgraphicslayout.cpp: +\include examples/layout/qgraphicslayout/qgraphicslayout.cpp + +Styled with the following qgraphicslayout.css file: +\include examples/layout/qgraphicslayout/qgraphicslayout.css + +And compiled with the following qgraphicslayout.pro file: +\include examples/layout/qgraphicslayout/qgraphicslayout.pro + +*/ diff --git a/examples/layout/qgraphicslayout/qgraphicslayout.pro b/examples/layout/qgraphicslayout/qgraphicslayout.pro new file mode 100644 index 000000000..dd3ac94a7 --- /dev/null +++ b/examples/layout/qgraphicslayout/qgraphicslayout.pro @@ -0,0 +1,10 @@ +TEMPLATE = app +CONFIG += dui + +# Input +SOURCES += *.cpp + +INCLUDEPATH += ../../src/include +QMAKE_LIBDIR += ../../lib/ + + diff --git a/examples/layout/qgraphicslinearlayout/.gitignore b/examples/layout/qgraphicslinearlayout/.gitignore new file mode 100644 index 000000000..a38e1be63 --- /dev/null +++ b/examples/layout/qgraphicslinearlayout/.gitignore @@ -0,0 +1 @@ +qgraphicslinearlayout diff --git a/examples/layout/qgraphicslinearlayout/qgraphicslinearlayout.cpp b/examples/layout/qgraphicslinearlayout/qgraphicslinearlayout.cpp new file mode 100644 index 000000000..f8d85ffad --- /dev/null +++ b/examples/layout/qgraphicslinearlayout/qgraphicslinearlayout.cpp @@ -0,0 +1,54 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +/* + * A simple example of the QGraphicsLinearLayout class. + */ + +#include +#include +#include +#include +#include +#include + +int main(int argc, char **argv) +{ + DuiApplication app(argc, argv); + DuiTheme::loadCSS("qgraphicslinearlayout.css"); + DuiApplicationWindow window; + DuiApplicationPage page; + /* Create a linear layout */ + QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(Qt::Vertical); + layout->setSpacing(10); + + /* Add 3 items to the layout, arranging them vertically stacked on top of each other */ + for (int i = 0; i < 3; ++i) { + DuiLabel *label = new DuiLabel(QString("Item %1").arg(i + 1)); + layout->addItem(label); + label->setObjectName("item"); + label->setAlignment(Qt::AlignCenter); + } + + /* Attach the layout to the page */ + page.centralWidget()->setLayout(layout); + window.show(); + page.appearNow(); + return app.exec(); +} diff --git a/examples/layout/qgraphicslinearlayout/qgraphicslinearlayout.css b/examples/layout/qgraphicslinearlayout/qgraphicslinearlayout.css new file mode 100644 index 000000000..6cbb97c48 --- /dev/null +++ b/examples/layout/qgraphicslinearlayout/qgraphicslinearlayout.css @@ -0,0 +1,5 @@ +#item { + font: "Nokia Sans Wide" 21px; + background-color: #eeeeee; + preferred-size: 100 85; +} diff --git a/examples/layout/qgraphicslinearlayout/qgraphicslinearlayout.dox b/examples/layout/qgraphicslinearlayout/qgraphicslinearlayout.dox new file mode 100644 index 000000000..687da33a1 --- /dev/null +++ b/examples/layout/qgraphicslinearlayout/qgraphicslinearlayout.dox @@ -0,0 +1,17 @@ +/** +\page layout-qgraphicslinearlayout QGraphicsLinearLayout example + +Source code for a simple example of QGraphicsLinearLayout. + +\image html duilinearlayoutpolicy.png + +Source code of qgraphicslinearlayout.cpp: +\include examples/layout/qgraphicslinearlayout/qgraphicslinearlayout.cpp + +Styled with the following qgraphicslinearlayout.css file: +\include examples/layout/qgraphicslinearlayout/qgraphicslinearlayout.css + +And compiled with the following qgraphicslinearlayout.pro file: +\include examples/layout/qgraphicslinearlayout/qgraphicslinearlayout.pro + +*/ diff --git a/examples/layout/qgraphicslinearlayout/qgraphicslinearlayout.pro b/examples/layout/qgraphicslinearlayout/qgraphicslinearlayout.pro new file mode 100644 index 000000000..dd3ac94a7 --- /dev/null +++ b/examples/layout/qgraphicslinearlayout/qgraphicslinearlayout.pro @@ -0,0 +1,10 @@ +TEMPLATE = app +CONFIG += dui + +# Input +SOURCES += *.cpp + +INCLUDEPATH += ../../src/include +QMAKE_LIBDIR += ../../lib/ + + diff --git a/examples/layout/two_columns/.gitignore b/examples/layout/two_columns/.gitignore new file mode 100644 index 000000000..56dbe80fc --- /dev/null +++ b/examples/layout/two_columns/.gitignore @@ -0,0 +1 @@ +two_columns diff --git a/examples/layout/two_columns/two_columns.pro b/examples/layout/two_columns/two_columns.pro new file mode 100644 index 000000000..dd3ac94a7 --- /dev/null +++ b/examples/layout/two_columns/two_columns.pro @@ -0,0 +1,10 @@ +TEMPLATE = app +CONFIG += dui + +# Input +SOURCES += *.cpp + +INCLUDEPATH += ../../src/include +QMAKE_LIBDIR += ../../lib/ + + diff --git a/examples/layout/two_columns/twocolumns.cpp b/examples/layout/two_columns/twocolumns.cpp new file mode 100644 index 000000000..e5a0cb21d --- /dev/null +++ b/examples/layout/two_columns/twocolumns.cpp @@ -0,0 +1,76 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +/* + * A simple example of having a two-column layout + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char **argv) +{ + DuiApplication app(argc, argv); + DuiApplicationWindow window; + DuiApplicationPage page; + DuiTheme::loadCSS("twocolumns.css"); + /* Create a DuiLayout that we set the policy for */ + DuiLayout *layout = new DuiLayout(page.centralWidget()); + DuiLinearLayoutPolicy *policy = new DuiLinearLayoutPolicy(layout, Qt::Horizontal); + + /* Setup first layout with a label and text edit */ + DuiLayout *nameLayout = new DuiLayout; + DuiLinearLayoutPolicy *namePolicy = new DuiLinearLayoutPolicy(nameLayout, Qt::Horizontal); + DuiLabel *textEditLabel = new DuiLabel("Name:"); + DuiTextEdit *textEdit = new DuiTextEdit(DuiTextEditModel::MultiLine); + namePolicy->addItem(textEditLabel); //Add the label and textedit + namePolicy->addItem(textEdit); + textEdit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + + /* Setup second layout with a large label */ + DuiLayout *labelLayout = new DuiLayout; + DuiLinearLayoutPolicy *labelPolicy = new DuiLinearLayoutPolicy(labelLayout, Qt::Horizontal); + DuiLabel *label = new DuiLabel("Enter the name of the person who likes to listen to music while sorting their socks!"); + label->setObjectName("nameLabel"); + labelPolicy->addItem(label); + label->setWordWrap(true); + + /* Add the two layouts to the layout */ + policy->addItem(nameLayout); + policy->addItem(labelLayout); + + /* Make the two layouts have an equal preferred size, so that they get an equal amount of space */ + nameLayout->setPreferredWidth(1); + labelLayout->setPreferredWidth(1); + + /* Attach the layout to the page */ + window.show(); + page.appearNow(); + + return app.exec(); +} diff --git a/examples/layout/two_columns/twocolumns.css b/examples/layout/two_columns/twocolumns.css new file mode 100644 index 000000000..bfed17b2a --- /dev/null +++ b/examples/layout/two_columns/twocolumns.css @@ -0,0 +1,3 @@ +#nameLabel { + color: #333333; +} diff --git a/examples/layout/two_columns/twocolumns.dox b/examples/layout/two_columns/twocolumns.dox new file mode 100644 index 000000000..3da74dfa7 --- /dev/null +++ b/examples/layout/two_columns/twocolumns.dox @@ -0,0 +1,17 @@ +/** +\page layout-twocolumns Layout example with equal column sizes + +Source code for a simple example to demonstrate how to get equal column sizes with DuiLinearLayoutPolicy +or DuiGridLayoutPolicy. The key part is that we set the preferred size of items to be equal. + +\image html twocolumns.png + +\include examples/layout/two_columns/twocolumns.cpp + +Styled with the following twocolumns.css file: +\include examples/layout/two_columns/twocolumns.css + +And compiled with the following twocolumns.pro file: +\include examples/layout/two_columns/twocolumns.pro + +*/ diff --git a/examples/lifecycle/.gitignore b/examples/lifecycle/.gitignore new file mode 100644 index 000000000..0792bb5a5 --- /dev/null +++ b/examples/lifecycle/.gitignore @@ -0,0 +1 @@ +lifecycle diff --git a/examples/lifecycle/anotherpage.cpp b/examples/lifecycle/anotherpage.cpp new file mode 100644 index 000000000..83d8dfe72 --- /dev/null +++ b/examples/lifecycle/anotherpage.cpp @@ -0,0 +1,187 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "anotherpage.h" + +AnotherPage::AnotherPage() +{ + setTitle("Visibility Page"); + setObjectName("visibilitypage"); + + labelBgColors << "" << "" + << "" << ""; + + labelBgColorIndex = 0; + hiddenCount = 0; + + logLabelRows << "" << "" << "" << ""; +} + +AnotherPage::~AnotherPage() +{ +} + +void AnotherPage::createContent() +{ + DuiLayout *layout = new DuiLayout(); + centralWidget()->setLayout(layout); + + l_policy = new DuiGridLayoutPolicy(layout); + l_policy->setContentsMargins(32, 32, 32, 32); + l_policy->setRowSpacing(1, 32.0f); + l_policy->setSpacing(36); + + DuiLabel *label1 = new DuiLabel("This Label's Visibility Log:", this); + label1->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum)); + label1->setObjectName("Label"); + + windowHiddenLabel = new DuiLabel(("Window hidden: 00:00:00"), this); + windowVisibleLabel = new DuiLabel(("Window visible: 00:00:00"), this); + + panLabel = new DuiLabel((labelBgColors.at(labelBgColorIndex++) + "
Pan me out
"), this); + panLabel->setObjectName("panLabel"); + + logLabel = new DuiLabel("", this); + fillLogLabel("" + QTime::currentTime().toString("hh:mm:ss") + " Visible"); + + DuiButton *button = new DuiButton("Clear Logs"); + connect(button, SIGNAL(clicked()), this, SLOT(clearLog())); + + connect(panLabel, SIGNAL(displayEntered()), this, SLOT(itemVisible())); + connect(panLabel, SIGNAL(displayExited()), this, SLOT(itemHidden())); + connect(label1, SIGNAL(displayEntered()), this, SLOT(itemVisible())); + connect(label1, SIGNAL(displayExited()), this, SLOT(itemHidden())); + DuiApplicationWindow *window = DuiApplication::activeApplicationWindow(); + connect(window, SIGNAL(displayExited()), this, SLOT(windowHidden())); + connect(window, SIGNAL(displayEntered()), this, SLOT(windowVisible())); + + for (int i = 0; i < LABEL_COUNT; i++) { + labelList[i] = new DuiLabel(("
" + QString(i + 'A') + "
"), this); + labelList[i]->setObjectName("labelList" + QString(i + 'A')); + connect(labelList[i], SIGNAL(displayEntered()), this, SLOT(itemVisible())); + connect(labelList[i], SIGNAL(displayExited()), this, SLOT(itemHidden())); + l_policy->addItem(labelList[i], 6 + i, 0, 1, 3); + } + + l_policy->addItem(label1, 0, 0, 1, 2); + l_policy->addItem(logLabel, 1, 0, 3, 2); + l_policy->addItem(button, 4, 2, 1, 1); + l_policy->addItem(panLabel, 3, 2, 1, 1); + l_policy->addItem(windowHiddenLabel, 0, 2); + l_policy->addItem(windowVisibleLabel, 1, 2); + // Return to initial state in case of LazyShutdown + connect(DuiApplication::instance(), SIGNAL(prestartRestored()), this, SLOT(clearLog())); +} + +void AnotherPage::clearLog() +{ + for (int i = 0; i < 4; i++) { + fillLogLabel(""); + } + labelBgColorIndex = 0; + hiddenCount = 0; + panLabel->setText(labelBgColors.at(labelBgColorIndex++ % 4) + "
Pan me out
"); + windowHiddenLabel->setText("Window hidden: 00:00:00"); + windowVisibleLabel->setText("Window visible: 00:00:00"); +} + +void AnotherPage::fillLogLabel(QString text) +{ + logLabelRows.replace(3, logLabelRows.at(2)); + logLabelRows.replace(2, logLabelRows.at(1)); + logLabelRows.replace(1, logLabelRows.at(0)); + logLabelRows.replace(0, text); + + logLabel->setText("


" + logLabelRows.join("
")); +} + +void AnotherPage::itemHidden() +{ + duiDebug("") << sender()->objectName() << "HIDDEN"; + if (sender()->objectName() == "Label") { + fillLogLabel("" + QTime::currentTime().toString("hh:mm:ss") + " Hidden"); + } else if (sender()->objectName() == "panLabel") { + hiddenCount++; + panLabel->setText(labelBgColors.at(labelBgColorIndex++ % 4) + "
Pan me out
(Hidden " + QString().setNum(hiddenCount) + "X)
"); + } else if (sender()->objectName().leftRef(9) == "labelList") { + QString header = "Visible: "; + + for (int i = 0; i < LABEL_COUNT; i++) { + if (labelList[i]->isOnDisplay()) { + header = header + QString(i + 'A'); + } + } + setTitle(header); + } +} + +void AnotherPage::itemVisible() +{ + duiDebug("") << sender()->objectName() << "Visible"; + if (sender()->objectName() == "Label") { + fillLogLabel("" + QTime::currentTime().toString("hh:mm:ss") + " Visible<"); + } else if (sender()->objectName().leftRef(9) == "labelList") { + QString header = "Visible: "; + + for (int i = 0; i < LABEL_COUNT; i++) { + if (labelList[i]->isOnDisplay()) { + header = header + QString(i + 'A'); + } + } + + setTitle(header); + } +} + +void AnotherPage::windowHidden() +{ + duiDebug("") << "lifecycle: Window hidden"; + windowHiddenLabel->setText("Window hidden: " + QTime::currentTime().toString("hh:mm:ss")); +} + +void AnotherPage::windowVisible() +{ + duiDebug("") << "lifecycle: Window visible"; + windowVisibleLabel->setText("Window visible: " + QTime::currentTime().toString("hh:mm:ss")); +} + +void AnotherPage::exitDisplayEvent() +{ + duiDebug("") << "lifecycle: AnotherPage hidden"; +} + +void AnotherPage::enterDisplayEvent() +{ + duiDebug("") << "lifecycle: AnotherPage visible"; +} + + diff --git a/examples/lifecycle/anotherpage.h b/examples/lifecycle/anotherpage.h new file mode 100644 index 000000000..1a27ffffa --- /dev/null +++ b/examples/lifecycle/anotherpage.h @@ -0,0 +1,72 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef ANOTHERPAGE_H +#define ANOTHERPAGE_H + +#include +#include +#include +#include + +const int LABEL_COUNT = 10; + +class DuiGridLayoutPolicy; +class DuiProgressIndicator; +class DuiButton; + +class AnotherPage : public DuiApplicationPage +{ + Q_OBJECT; + +public: + AnotherPage(); + virtual ~AnotherPage(); + + virtual void createContent(); + +private slots: + void clearLog(); + void itemVisible(); + void itemHidden(); + void windowVisible(); + void windowHidden(); + +protected: + DuiGridLayoutPolicy *l_policy; + DuiGridLayoutPolicy *p_policy; + + //! Visibility re-imps + virtual void enterDisplayEvent(); + virtual void exitDisplayEvent(); + +private: + void fillLogLabel(QString text); + DuiLabel *logLabel; + DuiLabel *panLabel; + DuiLabel *windowVisibleLabel; + DuiLabel *windowHiddenLabel; + DuiLabel *labelList[LABEL_COUNT]; + QStringList labelBgColors; + QStringList logLabelRows; + int labelBgColorIndex; + int hiddenCount; +}; + +#endif // ANOTHERPAGE_H diff --git a/examples/lifecycle/com.nokia.lifecycle.service b/examples/lifecycle/com.nokia.lifecycle.service new file mode 100644 index 000000000..7c310fe23 --- /dev/null +++ b/examples/lifecycle/com.nokia.lifecycle.service @@ -0,0 +1,3 @@ +[D-BUS Service] +Name=com.nokia.lifecycle +Exec=/usr/bin/lifecycle diff --git a/examples/lifecycle/containerpage.cpp b/examples/lifecycle/containerpage.cpp new file mode 100644 index 000000000..da6cbacea --- /dev/null +++ b/examples/lifecycle/containerpage.cpp @@ -0,0 +1,61 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "containerpage.h" +#include +#include +#include +#include +#include +#include +#include + +ContainerPage::ContainerPage() +{ + setTitle("DuiMashupCanvas"); +} + +ContainerPage::~ContainerPage() +{ +} + +void ContainerPage::createContent() +{ + DuiApplicationPage::createContent(); + + DuiWidget *panel = centralWidget(); + + QGraphicsLinearLayout *vbox = new QGraphicsLinearLayout(Qt::Vertical); + panel->setLayout(vbox); + + DuiMashupCanvas *canvas = new DuiMashupCanvas("ContainerPage"); + canvas->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum)); + + vbox->addItem(canvas); +} + +void ContainerPage::exitDisplayEvent() +{ + duiDebug("") << "lifecycle: ContainerPage hidden"; +} + +void ContainerPage::enterDisplayEvent() +{ + duiDebug("") << "lifecycle: ContainerPage visible"; +} diff --git a/examples/lifecycle/containerpage.h b/examples/lifecycle/containerpage.h new file mode 100644 index 000000000..3674f63a2 --- /dev/null +++ b/examples/lifecycle/containerpage.h @@ -0,0 +1,40 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef CONTAINERPAGE_H +#define CONTAINERPAGE_H + +#include + +class ContainerPage : public DuiApplicationPage +{ +public: + ContainerPage(); + virtual ~ContainerPage(); + + virtual void createContent(); + +protected: + + //! Visibility re-imps + virtual void enterDisplayEvent(); + virtual void exitDisplayEvent(); +}; + +#endif // CONTAINERPAGE_H diff --git a/examples/lifecycle/duihome_session_env.sh b/examples/lifecycle/duihome_session_env.sh new file mode 100755 index 000000000..2bea41f5e --- /dev/null +++ b/examples/lifecycle/duihome_session_env.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +# This script sets up the D-Bus environment variables to the same +# value as used by duihomescreen +# +# source ./duihome_session_env.sh + +eval $(cat /proc/$(pgrep duihome)/environ | sed 's/\x00/\nexport /g' | grep DBUS_SESSION_BUS) diff --git a/examples/lifecycle/lifecycle.desktop b/examples/lifecycle/lifecycle.desktop new file mode 100644 index 000000000..6f6a21d93 --- /dev/null +++ b/examples/lifecycle/lifecycle.desktop @@ -0,0 +1,8 @@ +[Desktop Entry] +Type=Application +Name=Lifecycle Demo +Icon=icon-l-video +Exec=lifecycle +X-Maemo-Service=com.nokia.lifecycle +Categories=DUI;Demos; +OnlyShowIn=DUI; diff --git a/examples/lifecycle/lifecycle.pro b/examples/lifecycle/lifecycle.pro new file mode 100644 index 000000000..c9c782876 --- /dev/null +++ b/examples/lifecycle/lifecycle.pro @@ -0,0 +1,70 @@ +DUIROOT = ../.. +include($$DUIROOT/mkspecs/common.pri) + +DUILIB = $$DUIROOT/lib +DUISRC = $$DUIROOT/src +DUISRCINCLUDE = $$DUISRC/include +DUISFWINCLUDE = $$DUIROOT/servicefw/include +INCLUDEPATH += . \ + $$DUISRCINCLUDE \ + $$DUISRC +QMAKE_LIBDIR += $$DUILIB +win32|macx { + macx { + QMAKE_LFLAGS += -F../../lib + LIBS += -framework \ + dui + } + win32:LIBS += -L../../lib \ + -ldui0 +} +else:LIBS += ../../lib/libdui.so +TEMPLATE = app +TARGET = lifecycle +target.path = /usr/bin +OBJECTS_DIR = ./.obj +MOC_DIR = ./.moc +DEPENDPATH += $$INCLUDEPATH +CONFIG += qt \ + qdbus +CONFIG -= app_bundle +QT += svg \ + dbus +SOURCES += main.cpp \ + mainpage.cpp \ + anotherpage.cpp \ + containerpage.cpp \ + lifecycleapplication.cpp +HEADERS += mainpage.h \ + anotherpage.h \ + containerpage.h \ + lifecycleapplication.h + +# to update the .pm files automatically when running "make" +# include(../../updateqm.pri) +# LifeCycle Demo UI style definition +view_configuration.path = $$DUI_THEME_DIR/../lifecycle/themes +view_configuration.files = style/lifecycle.conf +style_images.path = $$DUI_THEME_DIR/../lifecycle/themes/images +style_images.files = images/*.png \ + images/*.jpg +style_svg.path = $$DUI_THEME_DIR/../lifecycle/themes/svg +style_svg.files = images/*.svg +contacts.path = $$DUI_THEME_DIR/../lifecycle/themes/images/contacts +contacts.files = images/contacts/* +desktop_entry.path = /usr/share/applications +desktop_entry.files = lifecycle.desktop +services.target = .dummy +services.commands = touch \ + $$services.target +services.path = /usr/share/dbus-1/services +services.files = com.nokia.lifecycle.service +DEFINES += CONTACTS_DIR=\"\\\"$$contacts.path/\\\"\" + +# Install instructions +INSTALLS += target \ + style_images \ + style_svg \ + view_configuration \ + desktop_entry \ + services diff --git a/examples/lifecycle/lifecycleapplication.cpp b/examples/lifecycle/lifecycleapplication.cpp new file mode 100644 index 000000000..bea4727d4 --- /dev/null +++ b/examples/lifecycle/lifecycleapplication.cpp @@ -0,0 +1,56 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "lifecycleapplication.h" +#include +#include + +LifeCycleApplication::LifeCycleApplication(int &argc, char **argv, const QString &appIdentifier, DuiApplicationService *service) + : DuiApplication(argc, argv, appIdentifier, service), m_bHandleSignal(true) +{ + connect(this, SIGNAL(memoryLow()), SLOT(releaseMemoryHandler())); +} + +LifeCycleApplication::~LifeCycleApplication() +{} + +void LifeCycleApplication::releaseMemory() +{ + if (!m_bHandleSignal) { + showReleaseMemory(QString("System memory low, virtual method handler")); + } +} + +void LifeCycleApplication::showReleaseMemory(QString message) +{ + DuiInfoBanner *infoBanner = new DuiInfoBanner(DuiInfoBanner::Information); + infoBanner->setBodyText(message); + infoBanner->setIconID("Icon-close"); + infoBanner->appear(DuiSceneWindow::DestroyWhenDone); + QTimer::singleShot(5000, infoBanner, SLOT(disappear())); +} + + +void LifeCycleApplication::releaseMemoryHandler() +{ + if (m_bHandleSignal) { + showReleaseMemory(QString("System memory low, signal handler ")); + m_bHandleSignal = false; + } +} diff --git a/examples/lifecycle/lifecycleapplication.h b/examples/lifecycle/lifecycleapplication.h new file mode 100644 index 000000000..132a0530d --- /dev/null +++ b/examples/lifecycle/lifecycleapplication.h @@ -0,0 +1,47 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef LIFECYCLEAPPLICATION_H +#define LIFECYCLEAPPLICATION_H + +#include +#include + +class LifeCycleApplication : public DuiApplication +{ + Q_OBJECT + +public: + + bool m_bHandleSignal; + + LifeCycleApplication(int &argc, char **argv, const QString &appIdentifier, DuiApplicationService *service); + + virtual ~LifeCycleApplication(); + virtual void releaseMemory(); + +private: + + void showReleaseMemory(QString message); + +private slots: + void releaseMemoryHandler(); + +}; +#endif // LIFECYCLEAPPLICATION_H diff --git a/examples/lifecycle/main.cpp b/examples/lifecycle/main.cpp new file mode 100644 index 000000000..4c8880dad --- /dev/null +++ b/examples/lifecycle/main.cpp @@ -0,0 +1,91 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mainpage.h" +#include "lifecycleapplication.h" + +void emitMemorySignal(int sig); + +DuiApplication *App; +int requestCounter = 0; + +class MyApplicationService: public DuiApplicationService +{ +public: + MyApplicationService(QObject *parent = 0) : + DuiApplicationService("com.nokia.lifecycle", parent) + {} + + void handleServiceRegistrationFailure() { + qDebug() << "MyApplicationService::handleServiceRegistrationFailure()"; + + incrementAndRegister(); + } +}; + + +int main(int argc, char **argv) +{ + LifeCycleApplication app(argc, argv, "lifecycle", new MyApplicationService()); + LifeCycleApplication::setPrestartMode(Dui::LazyShutdown); + + DuiApplicationWindow window; + window.show(); + + MainPage mainPage; + mainPage.appearNow(); + + (void) signal(SIGINT, emitMemorySignal); + App = &app; + + // Run activateWidgets() here to setup things if app is NOT prestarted, otherwise + // connect it to prestartReleased() -signal from DuiApplication so that it's run + // at the time when the window is really being shown to the user. + + if (!app.isPrestarted()) { + mainPage.activateWidgets(); + } else { + app.connect(&app, SIGNAL(prestartReleased()), &mainPage, SLOT(activateWidgets())); + app.connect(&app, SIGNAL(prestartRestored()), &mainPage, SLOT(deactivateWidgets())); + } + + return app.exec(); +} + +void emitMemorySignal(int) +{ + // memory signal cannot be emitted in the current setting. + requestCounter++; + + if (requestCounter >= 2) { + (void) signal(SIGINT, SIG_DFL); + } +} diff --git a/examples/lifecycle/mainpage.cpp b/examples/lifecycle/mainpage.cpp new file mode 100644 index 000000000..405222bf3 --- /dev/null +++ b/examples/lifecycle/mainpage.cpp @@ -0,0 +1,165 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mainpage.h" +#include "anotherpage.h" + +MainPage::MainPage() : + bar0(NULL), + bar1(NULL), + anotherPage(new AnotherPage()), + canvasPage(new ContainerPage()), + m_shownPage(NULL), + m_pTimer(new QTimer(this)) +{ + setTitle("MainPage"); + + m_pbarValue = 1; + + m_pTimer->setInterval(100); + connect(m_pTimer, SIGNAL(timeout()), this, SLOT(updateProgressBars())); +} + +MainPage::~MainPage() +{ + delete anotherPage; + delete canvasPage; +} + +void MainPage::createContent() +{ + DuiLayout *layout = new DuiLayout(centralWidget()); + DuiGridLayoutPolicy *policy = new DuiGridLayoutPolicy(layout); + policy->setSpacing(20.0); + + bar0 = new DuiProgressIndicator(this, "spinner"); + bar0->setRange(0, 12); + bar0->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum)); + bar0->setUnknownDuration(false); + bar0->setObjectName("bar0"); + policy->addItem(bar0, 0, 0, 1, 3); + + DuiLabel *label1 = new DuiLabel("Application Lifecycle Demo"); + label1->setAlignment(Qt::AlignCenter); + policy->addItem(label1, 1, 1); + + bar1 = new DuiProgressIndicator(this, "spinner"); + bar1->setRange(0, 120); + bar1->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum)); + bar1->setUnknownDuration(false); + bar1->setObjectName("bar1"); + policy->addItem(bar1, 4, 0, 1, 3); + + connect(bar0, SIGNAL(displayEntered()), this, SLOT(activateWidgets())); + connect(bar1, SIGNAL(displayEntered()), this, SLOT(activateWidgets())); + connect(bar0, SIGNAL(displayExited()), this, SLOT(pauseWidgets())); + connect(bar1, SIGNAL(displayExited()), this, SLOT(pauseWidgets())); + + DuiButton *button = new DuiButton("Visibility Information"); + connect(button, SIGNAL(clicked()), this, SLOT(buttonPress())); + policy->addItem(button, 5, 1); + + DuiButton *button2 = new DuiButton("Applet Stuff"); + connect(button2, SIGNAL(clicked()), this, SLOT(button2Press())); + policy->addItem(button2, 6, 1); + + layout->setLandscapePolicy(policy); +} + +void MainPage::indicatorVisible() +{ + qDebug() << qobject_cast(sender())->objectName() << " visible"; + +} + +void MainPage::indicatorHidden() +{ + qDebug() << qobject_cast(sender())->objectName() << " hidden"; +} + +void MainPage::buttonPress() +{ + anotherPage->setEscapeButtonMode(DuiEscapeButtonPanelModel::BackMode); + connect(anotherPage, SIGNAL(backButtonClicked()), this, SLOT(handleBackItemClick())); + m_shownPage = anotherPage; + anotherPage->appear(); +} + +void MainPage::button2Press() +{ + canvasPage->setEscapeButtonMode(DuiEscapeButtonPanelModel::BackMode); + connect(canvasPage, SIGNAL(backButtonClicked()), this, SLOT(handleBackItemClick())); + m_shownPage = canvasPage; + canvasPage->appear(); +} + +void MainPage::handleBackItemClick() +{ + m_shownPage->disconnect(this, SLOT(handleBackItemClick())); + appear(); +} + +void MainPage::updateProgressBars() +{ + bar0->setValue(m_pbarValue % (bar0->maximum() + 1)); + bar1->setValue(m_pbarValue % (bar1->maximum() + 1)); + m_pbarValue++; +} + +void MainPage::deactivateWidgets() +{ + qDebug() << "lifecycle: prestart restored"; + m_pTimer->stop(); + bar0->reset(); + bar1->reset(); + m_pbarValue = 0; +} + +void MainPage::pauseWidgets() +{ + qDebug() << "pauseWidgets"; + m_pTimer->stop(); +} + +void MainPage::activateWidgets() +{ + qDebug() << "activateWidgets"; + m_pTimer->start(); +} + +void MainPage::exitDisplayEvent() +{ + qDebug() << "lifecycle: MainPage hidden"; +} + +void MainPage::enterDisplayEvent() +{ + qDebug() << "lifecycle: MainPage visible"; +} + diff --git a/examples/lifecycle/mainpage.h b/examples/lifecycle/mainpage.h new file mode 100644 index 000000000..5a9872ec0 --- /dev/null +++ b/examples/lifecycle/mainpage.h @@ -0,0 +1,67 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef MAINPAGE_H +#define MAINPAGE_H + +#include +#include +#include +#include "anotherpage.h" +#include "containerpage.h" + +class MainPage : public DuiApplicationPage +{ + Q_OBJECT + +public: + MainPage(); + virtual ~MainPage(); + virtual void createContent(); + +public slots: + void buttonPress(); + void button2Press(); + void deactivateWidgets(); + void activateWidgets(); + void pauseWidgets(); + + +private slots: + void updateProgressBars(); + void handleBackItemClick(); + void indicatorVisible(); + void indicatorHidden(); + +protected: + //! Visibility re-imps + virtual void exitDisplayEvent(); + virtual void enterDisplayEvent(); + +private: + DuiProgressIndicator *bar0; + DuiProgressIndicator *bar1; + AnotherPage *anotherPage; + ContainerPage *canvasPage; + DuiApplicationPage *m_shownPage; + QTimer *m_pTimer; + int m_pbarValue; +}; + +#endif // MAINPAGE_H diff --git a/examples/lifecycle/page1.cpp b/examples/lifecycle/page1.cpp new file mode 100644 index 000000000..d4fec6cbf --- /dev/null +++ b/examples/lifecycle/page1.cpp @@ -0,0 +1,199 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "progressindicatorpage.h" + +ProgressIndicatorPage::ProgressIndicatorPage() : DuiApplicationPage() +{ + //% "Progress Indicator" + setTitle(qtTrId("xx_progressindicator_page_title")); + setObjectName("lifecycleypage"); +} + +ProgressIndicatorPage::~ProgressIndicatorPage() +{ +} + +void ProgressIndicatorPage::createContent() +{ + DuiLayout *layout = new DuiLayout(); + centralWidget()->setLayout(layout); + + l_policy = new DuiGridLayoutPolicy(layout); + l_policy->setContentsMargins(32, 32, 32, 32); + l_policy->setRowSpacing(1, 32.0f); + l_policy->setSpacing(36); + + p_policy = new DuiGridLayoutPolicy(layout); + p_policy->setContentsMargins(32, 32, 32, 32); + p_policy->setRowSpacing(1, 32.0f); + p_policy->setRowSpacing(3, 32.0f); + + //% "unknown duration - bar" + DuiLabel *label1 = new DuiLabel(qtTrId("xx_progressindicator_unknown_duration_bar"), this); + label1->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum)); + label1->setMaximumWidth(382); + label1->setMinimumWidth(382); + + bar1 = new DuiProgressIndicator(this, "bar"); + bar1->setRange(0, 99); + bar1->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum)); + bar1->setRunUnknown(TRUE); + bar1->setObjectName("bar"); + + //% "known duration - bar" + DuiLabel *label2 = new DuiLabel(qtTrId("xx_progressindicator_known_duration_bar"), this); + label2->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum)); + + bar2 = new DuiProgressIndicator(this, "bar"); + bar2->setRange(0, 99); + bar2->setValue(0); + bar2->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum)); + bar2->setObjectName("bar"); + + //% "unknown duration - circular" + DuiLabel *label3 = new DuiLabel(qtTrId("xx_progressindicator_unknown_duration_circular"), this); + label3->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum)); + + circ1 = new DuiProgressIndicator(this); + circ1->setRange(0, 99); + circ1->setMaximumHeight(64); + circ1->setMinimumHeight(64); + circ1->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum)); + circ1->setRunUnknown(true); + circ1->setObjectName("circle"); + + //% "known duration - circular" + DuiLabel *label4 = new DuiLabel(qtTrId("xx_progressindicator_known_duration_circular"), this); + label4->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum)); + + circ2 = new DuiProgressIndicator(this); + circ2->setRange(0, 99); + circ2->setValue(0); + circ2->setMaximumHeight(64); + circ2->setMinimumHeight(64); + circ2->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum)); + circ2->setObjectName("circle"); + + //% "Stop" + buttonLeft = new DuiButton(qtTrId("xx_progressindicator_button_stop"), this); + //% "Increase" + DuiButton *buttonRight = new DuiButton(qtTrId("xx_progressindicator_button_increase"), this); + + buttonLeft->setMinimumHeight(72); + buttonRight->setMinimumHeight(72); + + l_policy->addItem(label1, 0, 0); + l_policy->addItem(bar1, 1, 0); + l_policy->addItem(label2, 0, 1); + l_policy->addItem(bar2, 1, 1, 1, 1, Qt::AlignVCenter); + l_policy->addItem(label3, 2, 0); + l_policy->addItem(circ1, 3, 0); + l_policy->addItem(label4, 2, 1); + l_policy->addItem(circ2, 3, 1, 1, 1, Qt::AlignVCenter); + l_policy->addItem(buttonLeft, 4, 0); + l_policy->addItem(buttonRight, 4, 1, 1, 1, Qt::AlignVCenter); + + p_policy->addItem(label1, 0, 0, 1, 2); + p_policy->addItem(bar1, 1, 0, 1, 2); + p_policy->addItem(label2, 2, 0, 1, 2); + p_policy->addItem(bar2, 3, 0, 1, 2); + p_policy->addItem(label3, 4, 0, 1, 2); + p_policy->addItem(circ1, 5, 0, 1, 2); + p_policy->addItem(label4, 6, 0, 1, 2); + p_policy->addItem(circ2, 7, 0, 1, 2); + + connect(buttonLeft, SIGNAL(pressed()), this, SLOT(buttonLeftSlot())); + connect(buttonRight, SIGNAL(pressed()), this, SLOT(buttonRightSlot())); + + connect(DuiSceneManager::instance(), + SIGNAL(orientationChanged(Dui::Orientation)), + this, + SLOT(pageRotated(Dui::Orientation))); +} + +void ProgressIndicatorPage::pageRotated(const Dui::Orientation &orientation) +{ + QSize s = DuiSceneManager::instance()->visibleSceneSize(); + + centralWidget()->setMinimumSize(s); + centralWidget()->setMaximumSize(s); + centralWidget()->setPreferredSize(s); + + if (orientation == Dui::Portrait) { + p_policy->activate(); + } else { + l_policy->activate(); + } +} + +void ProgressIndicatorPage::buttonLeftSlot() +{ + bar1->setRunUnknown(!bar1->runUnknown()); + circ1->setRunUnknown(!circ1->runUnknown()); + if (bar1->runUnknown()) + //% "Stop" + buttonLeft->setText(qtTrId("xx_progressindicator_button_stop")); + else + //% "Run" + buttonLeft->setText(qtTrId("xx_progressindicator_button_run")); +} + +void ProgressIndicatorPage::buttonRightSlot() +{ + bar2->setValue((bar2->value() + 10) % bar2->maximum()); + circ2->setValue((circ2->value() + 10) % circ2->maximum()); +} + +void ProgressIndicatorPage::rotatel() +{ + rotate(-1); +} + +void ProgressIndicatorPage::rotater() +{ + rotate(1); +} + +void ProgressIndicatorPage::rotate(int d) +{ + static const Dui::OrientationAngle angles[] = { + Dui::Angle0, + Dui::Angle90, + Dui::Angle180, + Dui::Angle270 + }; + + static int a = 0; + + a = (a + d) & 3; + + DuiSceneManager::instance()->setOrientationAngle(angles[a]); +} diff --git a/examples/lifecycle/page1.h b/examples/lifecycle/page1.h new file mode 100644 index 000000000..9dc3911d6 --- /dev/null +++ b/examples/lifecycle/page1.h @@ -0,0 +1,61 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef PROGRESSINDICATORPAGE_H +#define PROGRESSINDICATORPAGE_H + +#include + +class DuiGridLayoutPolicy; +class DuiProgressIndicator; +class DuiButton; + +class ProgressIndicatorPage : public DuiApplicationPage +{ + Q_OBJECT; + +public: + ProgressIndicatorPage(); + virtual ~ProgressIndicatorPage(); + + virtual void createContent(); + +public slots: + void rotate(int d); + void rotatel(); + void rotater(); + + void buttonLeftSlot(); + void buttonRightSlot(); + + void pageRotated(const Dui::Orientation &orientation); + +protected: + DuiGridLayoutPolicy *l_policy; + DuiGridLayoutPolicy *p_policy; + + DuiProgressIndicator *bar1; + DuiProgressIndicator *bar2; + DuiProgressIndicator *circ1; + DuiProgressIndicator *circ2; + + DuiButton *buttonLeft; +}; + +#endif // PROGRESSINDICATORPAGE_H diff --git a/examples/lifecycle/style/lifecycle.conf b/examples/lifecycle/style/lifecycle.conf new file mode 100644 index 000000000..e69de29bb diff --git a/examples/multipleinstances/.gitignore b/examples/multipleinstances/.gitignore new file mode 100644 index 000000000..d55a4116e --- /dev/null +++ b/examples/multipleinstances/.gitignore @@ -0,0 +1 @@ +multipleinstances diff --git a/examples/multipleinstances/main.cpp b/examples/multipleinstances/main.cpp new file mode 100644 index 000000000..51641378e --- /dev/null +++ b/examples/multipleinstances/main.cpp @@ -0,0 +1,77 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +/* + * An example of a minimalistic DirectUI application + */ + +#include +#include +#include +#include +#include +#include + +class MyApplicationService: public DuiApplicationService +{ +public: + MyApplicationService(QObject *parent = 0) : + DuiApplicationService("com.nokia.multipleinstances", parent) { + } + + void launch() { + launchAnotherWithQProcess(); + } + + void handleServiceRegistrationFailure() { + qDebug() << "MyApplicationService::handleServiceRegistrationFailure()"; + + incrementAndRegister(); + } +}; + +int main(int argc, char **argv) +{ + /* The base class of all DirectUI applications */ + DuiApplication app(argc, argv, "multipleinstances", new MyApplicationService()); + + /* The application window is a top-level window that contains + the Home and Back/Close framework controls, Navigation bar, + View menu and Toolbar components */ + DuiApplicationWindow w; + w.show(); + + /* Pages represent one "view" of an application, into which you + can add your application's contents. An application can have + any number of pages with transitions between them */ + DuiApplicationPage p; + p.appearNow(); /* appearNow causes the page to be visible without + a transition animation, which is recommended + for the initial application page */ + + /* Let's add a simple push button to our page */ + DuiButton b(p.centralWidget()); /* The (optional) constructor parameter + causes our button to be a child of the + central widget of the page. This + pattern can be used with all DuiWidgets + */ + b.setText("Hello World!"); + + return app.exec(); +} diff --git a/examples/multipleinstances/multipleinstances.pro b/examples/multipleinstances/multipleinstances.pro new file mode 100644 index 000000000..be631dd53 --- /dev/null +++ b/examples/multipleinstances/multipleinstances.pro @@ -0,0 +1,13 @@ +TEMPLATE = app +TARGET = multipleInstances +CONFIG += dui # Requires libdui to be installed + +# Input +SOURCES += main.cpp + +# The following lines are only to allow building the +# example inside the source tree without installing +# libdui first: +INCLUDEPATH += ../../src/include +QMAKE_LIBDIR += ../../lib/ +LIBS += -ldui diff --git a/examples/separatorTest/.gitignore b/examples/separatorTest/.gitignore new file mode 100644 index 000000000..53944fc1f --- /dev/null +++ b/examples/separatorTest/.gitignore @@ -0,0 +1 @@ +SeparatorTest diff --git a/examples/separatorTest/SeparatorTestPage.cpp b/examples/separatorTest/SeparatorTestPage.cpp new file mode 100644 index 000000000..8c8f7862d --- /dev/null +++ b/examples/separatorTest/SeparatorTestPage.cpp @@ -0,0 +1,85 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "SeparatorTestPage.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +SeparatorTestPage::SeparatorTestPage() +{ + //% "Separator" + setTitle(qtTrId("xx_separator_test_page_title")); + setObjectName("separatortestpage"); +} + +SeparatorTestPage::~SeparatorTestPage() +{ +} + +void SeparatorTestPage::createContent() +{ + DuiApplicationPage::createContent(); + DuiWidget *panel = centralWidget(); + + DuiLayout *layout = new DuiLayout(panel); + panel->setLayout(layout); + DuiGridLayoutPolicy *grid = new DuiGridLayoutPolicy(layout); + + // 1 | 3 + // – 5 – + // 7 | 9 + // + grid->addItem(createButton("1"), 0, 0); + grid->addItem(createSeparator(Qt::Vertical), 0, 1); + grid->addItem(createButton("3"), 0, 2); + grid->addItem(createSeparator(Qt::Horizontal), 1, 0); + grid->addItem(createButton("5"), 1, 1); + grid->addItem(createSeparator(Qt::Horizontal), 1, 2); + grid->addItem(createButton("7"), 2, 0); + grid->addItem(createSeparator(Qt::Vertical), 2, 1); + grid->addItem(new DuiContainer("9", panel), 2, 2); +} + +DuiButton *SeparatorTestPage::createButton(const QString &text) +{ + DuiButton *button = NULL; + button = new DuiButton(text); + QSizeF size(130.0, 130.0); + button->setMinimumSize(size); + button->setMaximumSize(size); + button->setPreferredSize(size); + return button; +} + +DuiSeparator *SeparatorTestPage::createSeparator(Qt::Orientation orientation) +{ + DuiSeparator *separator = NULL; + separator = new DuiSeparator(centralWidget(), orientation); + return separator; +} diff --git a/examples/separatorTest/SeparatorTestPage.h b/examples/separatorTest/SeparatorTestPage.h new file mode 100644 index 000000000..be09cc301 --- /dev/null +++ b/examples/separatorTest/SeparatorTestPage.h @@ -0,0 +1,40 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef SEPARATORTESTPAGE_H +#define SEPARATORTESTPAGE_H + +#include + +class DuiButton; +class DuiSeparator; + +class SeparatorTestPage : public DuiApplicationPage +{ +public: + SeparatorTestPage(); + virtual ~SeparatorTestPage(); + virtual void createContent(); + +private: + DuiButton *createButton(const QString &text); + DuiSeparator *createSeparator(Qt::Orientation orientation); +}; + +#endif // SEPARATORTESTPAGE_H diff --git a/examples/separatorTest/main.cpp b/examples/separatorTest/main.cpp new file mode 100644 index 000000000..26d04aa52 --- /dev/null +++ b/examples/separatorTest/main.cpp @@ -0,0 +1,50 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +/* + * An example of a minimalistic DirectUI application + */ + +#include +#include +#include + +#include "SeparatorTestPage.h" + +int main(int argc, char **argv) +{ + /* The base class of all DirectUI applications */ + DuiApplication app(argc, argv); + + /* The application window is a top-level window that contains + the Home and Back/Close framework controls, Navigation bar, + View menu and Toolbar components */ + DuiApplicationWindow w; + w.show(); + + /* Pages represent one "view" of an application, into which you + can add your application's contents. An application can have + any number of pages with transitions between them */ + SeparatorTestPage p; + p.appearNow(); /* appearNow causes the page to be visible without + a transition animation, which is recommended + for the initial application page */ + + return app.exec(); +} diff --git a/examples/separatorTest/separatorTest.pro b/examples/separatorTest/separatorTest.pro new file mode 100644 index 000000000..20d34d0bb --- /dev/null +++ b/examples/separatorTest/separatorTest.pro @@ -0,0 +1,32 @@ +TEMPLATE = app +TARGET = SeparatorTest +CONFIG += dui # Requires libdui to be installed + +# Input +SOURCES += main.cpp SeparatorTestPage.cpp + +DUIROOT = ../.. + +include($$DUIROOT/mkspecs/common.pri) + +DUILIB = $$DUIROOT/lib +DUISRC = $$DUIROOT/src +DUISRCINCLUDE = $$DUISRC/include +DUISFWINCLUDE = $$DUIROOT/servicefw/include + +INCLUDEPATH += . \ + $$DUISRCINCLUDE \ + $$DUISRC \ + +QMAKE_LIBDIR += \ + $$DUILIB \ + +INCLUDEPATH += ../../src/include +QMAKE_LIBDIR += ../../lib/ + +style_sheet.path = $$DUI_THEME_DIR/SeparatorTest +style_sheet.files = style/SeparatorTest.css +view_configuration.path = $$DUI_THEME_DIR/SeparatorTest + +INSTALLS += \ + style_sheet \ diff --git a/examples/separatorTest/style/SeparatorTest.css b/examples/separatorTest/style/SeparatorTest.css new file mode 100644 index 000000000..6a5ddedd4 --- /dev/null +++ b/examples/separatorTest/style/SeparatorTest.css @@ -0,0 +1,3 @@ +#separatortestpage { + background: "bg2"; +} diff --git a/examples/testwidget/.gitignore b/examples/testwidget/.gitignore new file mode 100644 index 000000000..ae942d1a1 --- /dev/null +++ b/examples/testwidget/.gitignore @@ -0,0 +1 @@ +testwidget diff --git a/examples/testwidget/main.cpp b/examples/testwidget/main.cpp new file mode 100644 index 000000000..fc8af0615 --- /dev/null +++ b/examples/testwidget/main.cpp @@ -0,0 +1,74 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +/* + * testwidgetview.h + * + * Created on: May 19, 2009 + * Author: Janne Koivuranta + */ + + + +#include +#include +#include + +#include "testwidget.h" +#include "testwidgetview.h" + +int main(int argc, char **argv) +{ + // Create main dui application. + DuiApplication application(argc, argv); + + // Create application window and make it visible. + DuiApplicationWindow window; + window.show(); + + // Create application page and make it visible. + DuiApplicationPage page; + page.appear(); + + // Load widget style from CSS file. + DuiTheme::loadCSS("testwidgetstyle.css"); + + // Create widget controller and view. + TestWidget widget; + TestWidgetView view(&widget); + widget.setView(&view); + + // Set geometry (active area) of widget. + widget.setGeometry(QRectF(100, 100, 200, 200)); + + // Attach widget to parent widget so it will be drawn and run dui application. + widget.setParentItem(page.centralWidget()); + return application.exec(); +} + + + + + + + + + + + diff --git a/examples/testwidget/testwidget.cpp b/examples/testwidget/testwidget.cpp new file mode 100644 index 000000000..4cc0bb710 --- /dev/null +++ b/examples/testwidget/testwidget.cpp @@ -0,0 +1,40 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +/* + * testwidget.cpp + * + * Created on: May 19, 2009 + * Author: Janne Koivuranta + */ + + +#include "testwidget.h" + +TestWidget::TestWidget(DuiWidget *parent) : + DuiWidgetController(NULL, new TestWidgetModel) +{ + +} + +TestWidget::~TestWidget() +{ +} + + diff --git a/examples/testwidget/testwidget.h b/examples/testwidget/testwidget.h new file mode 100644 index 000000000..08f7b6be5 --- /dev/null +++ b/examples/testwidget/testwidget.h @@ -0,0 +1,45 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +/* + * testwidget.h + * + * Created on: May 19, 2009 + * Author: Janne Koivuranta + */ + + +#ifndef TESTWIDGET_H +#define TESTWIDGET_H + + +#include +#include "testwidgetmodel.h" + +class TestWidget : public DuiWidgetController +{ + Q_OBJECT + DUI_CONTROLLER(TestWidget) + +public: + TestWidget(DuiWidget *parent = NULL); + virtual ~TestWidget(); +}; + +#endif diff --git a/examples/testwidget/testwidget.pro b/examples/testwidget/testwidget.pro new file mode 100644 index 000000000..212d1520d --- /dev/null +++ b/examples/testwidget/testwidget.pro @@ -0,0 +1,15 @@ +TEMPLATE = app +TARGET = testwidget +CONFIG += dui # Requires libdui to be installed + +# Input +SOURCES += testwidgetmodel.cpp \ + main.cpp \ + testwidget.cpp \ + testwidgetview.cpp +HEADERS += testwidget.h \ + testwidgetmodel.h \ + testwidgetstyle.h \ + testwidgetview.h +MODEL_HEADERS += testwidgetmodel.h +STYLE_HEADERS += testwidgetstyle.h diff --git a/examples/testwidget/testwidgetmodel.cpp b/examples/testwidget/testwidgetmodel.cpp new file mode 100644 index 000000000..ee4aeedd1 --- /dev/null +++ b/examples/testwidget/testwidgetmodel.cpp @@ -0,0 +1,42 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +/* + * testwidgetmodel.cpp + * + * Created on: May 20, 2009 + * Author: Janne Koivuranta + */ + +#include "testwidgetmodel.h" + +const int &TestWidgetModel::styleIndex() const +{ + // Call private method to access style index variable. + return _styleIndex(); +} + +void TestWidgetModel::setStyleIndex(const int &styleIndex) +{ + // Notice that hand-written setters and getters can perform validity checks, which is not + // the case for automatically generated handlers. + _styleIndex() = styleIndex; + if (_styleIndex() > 5) + _styleIndex() = 5; +} diff --git a/examples/testwidget/testwidgetmodel.h b/examples/testwidget/testwidgetmodel.h new file mode 100644 index 000000000..4a2629cba --- /dev/null +++ b/examples/testwidget/testwidgetmodel.h @@ -0,0 +1,55 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +/* + * testwidgetmodel.h + * + * Created on: May 19, 2009 + * Author: Janne Koivuranta + */ + + +#ifndef testwidgetmodel_h +#define testwidgetmodel_h + +#include +#include +#include + +class DUI_EXPORT TestWidgetModel : public DuiWidgetModel +{ + Q_OBJECT + DUI_MODEL(TestWidgetModel) + +public: + enum ButtonState { + Pressed, + Released + }; + + +private: + // Index of current style. Fourth parameter is false so public handler methods are not automatically generated. + // They are implemented in source file. + DUI_MODEL_PROPERTY(int, styleIndex, StyleIndex, false, 0) +}; + + +#endif + diff --git a/examples/testwidget/testwidgetstyle.css b/examples/testwidget/testwidgetstyle.css new file mode 100644 index 000000000..40401f6f5 --- /dev/null +++ b/examples/testwidget/testwidgetstyle.css @@ -0,0 +1,25 @@ +/* TestWidgetStyle : DuiWidgetStyle */ +TestWidgetStyle { + color: #ff0000; +} + +TestWidgetStyle:green { + color : #00ff00; +} + +TestWidgetStyle:blue { + color : #0000ff; +} + +TestWidgetStyle:yellow { + color : #ffff00; +} + +TestWidgetStyle:cyan { + color : #00ffff; +} + +TestWidgetStyle:purple { + color : #ff00ff; +} + diff --git a/examples/testwidget/testwidgetstyle.h b/examples/testwidget/testwidgetstyle.h new file mode 100644 index 000000000..ab8059683 --- /dev/null +++ b/examples/testwidget/testwidgetstyle.h @@ -0,0 +1,52 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +/* + * testwidgetstyle.h + * + * Created on: May 19, 2009 + * Author: Janne Koivuranta + */ + + +#ifndef TESTWIDGETSTYLE_H +#define TESTWIDGETSTYLE_H + +#include +#include + +class TestWidgetStyle : public DuiWidgetStyle +{ + Q_OBJECT + DUI_STYLE(TestWidgetStyle) + DUI_STYLE_ATTRIBUTE(QColor, color, Color) +}; + +class TestWidgetStyleContainer : public DuiWidgetStyleContainer +{ + DUI_STYLE_CONTAINER(TestWidgetStyle) + DUI_STYLE_MODE(Green) + DUI_STYLE_MODE(Blue) + DUI_STYLE_MODE(Yellow) + DUI_STYLE_MODE(Cyan) + DUI_STYLE_MODE(Purple) +}; + + +#endif diff --git a/examples/testwidget/testwidgetview.cpp b/examples/testwidget/testwidgetview.cpp new file mode 100644 index 000000000..322f175f9 --- /dev/null +++ b/examples/testwidget/testwidgetview.cpp @@ -0,0 +1,116 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +/* + * testwidgetview.cpp + * + * Created on: May 19, 2009 + * Author: jak + */ + + +#include "testwidgetview.h" + +#include +#include +#include + +#include "testwidget.h" +#include "duitheme.h" +#include "duiviewcreator.h" + + +TestWidgetView::TestWidgetView(TestWidget *controller) : + DuiWidgetView(controller) +{ +} + +TestWidgetView::~TestWidgetView() +{ +} + +void TestWidgetView::resizeEvent(QGraphicsSceneResizeEvent *event) +{ + DuiWidgetView::resizeEvent(event); +} + + +void TestWidgetView::drawContents(QPainter *painter, const QStyleOptionGraphicsItem *option) const +{ + Q_UNUSED(option); + + // Create string that contains color from current style as rgb values. + QString text("color: "); + + QString num; + num.setNum(style()->color().red(), 10); + text.append(num); + text.append(QString(" ")); + + num.setNum(style()->color().green(), 10); + text.append(num); + text.append(QString(" ")); + + num.setNum(style()->color().blue(), 10); + text.append(num); + + // Draw rectangle with size from geometry and text that display color. + QRectF box(QPointF(0, 0), size()); + painter->fillRect(box, style()->color()); + painter->drawText(box, text); +} + + + +void TestWidgetView::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + Q_UNUSED(event); + + // Get style index from model, increase it by one and check boundaries, then reset model style index. + int styleIndex = model()->styleIndex(); + styleIndex ++; + if (styleIndex > 5) + styleIndex = 0; + model()->setStyleIndex(styleIndex); + + // Set style mode by style index. + switch (styleIndex) { + case 1: + style().setModeGreen(); + break; + case 2: + style().setModeBlue(); + break; + case 3: + style().setModeYellow(); + break; + case 4: + style().setModeCyan(); + break; + case 5: + style().setModePurple(); + break; + default: + style().setModeDefault(); + break; + } + update(); +} + +DUI_REGISTER_VIEW(TestWidgetView, TestWidget) diff --git a/examples/testwidget/testwidgetview.h b/examples/testwidget/testwidgetview.h new file mode 100644 index 000000000..a02afb2f2 --- /dev/null +++ b/examples/testwidget/testwidgetview.h @@ -0,0 +1,53 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +/* + * testwidgetview.h + * + * Created on: May 19, 2009 + * Author: Janne Koivuranta + */ + +#ifndef TESTWIDGETVIEW_H_ +#define TESTWIDGETVIEW_H_ + +#include +#include +#include + +class TestWidget; +class QGraphicsSceneResizeEvent; + +class TestWidgetView : public DuiWidgetView +{ + Q_OBJECT + DUI_VIEW(TestWidgetModel, TestWidgetStyle) + +public: + TestWidgetView(TestWidget *controller); + + virtual ~TestWidgetView(); + virtual void resizeEvent(QGraphicsSceneResizeEvent *event); + +protected: + virtual void drawContents(QPainter *painter, const QStyleOptionGraphicsItem *option) const; + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); +}; + +#endif /* TESTWIDGETVIEW_H_ */ diff --git a/examples/trackergrid/.gitignore b/examples/trackergrid/.gitignore new file mode 100644 index 000000000..9a874b9ea --- /dev/null +++ b/examples/trackergrid/.gitignore @@ -0,0 +1 @@ +trackergrid diff --git a/examples/trackergrid/README b/examples/trackergrid/README new file mode 100644 index 000000000..9be46b264 --- /dev/null +++ b/examples/trackergrid/README @@ -0,0 +1,75 @@ +This source example demonstrates using tracker to populate dui grid widget. + +Preconditions +============= +This example is dependant on tracker and libqttracker. Make sure that both +are properly set up by running the following Sparql-query: + +tracker-sparql -q ' +SELECT ?GridItem_Mime ?GridItem_Path ?GridItem_Name +WHERE +{ + { + _:_1 . + _:_1 ?GridItem_Mime . + _:_1 ?GridItem_Path . + _:_1 ?GridItem_Name . + } +} +LIMIT 20 +' + +The output should be similar to this: + + image/png, file:///home/mw/Desktop/misc, Screenshot.png + image/png, file:///home/mw/Desktop/misc, git-cheat-sheet-medium.png + image/png, file:///home/mw/Desktop/misc, logo.png + ... + + +Limitations +=========== +The current version of trackergrid doesn't support "live" data: changes on +tracker doesn't update grid contents without doing a new query. + + +Building +======== +qmake +make + + +Running +======= +./trackergrid + + +Build dependencies +================== +- libraptor1-dev_1.4.18-1 +- libraptor1_1.4.18-1 +- vala-0.7.0 +- tracker +- libqttracker-0.3.3 + +Installing dependencies +======================= +sudo apt-get install libgmime2-dev libdbus-glib-1-dev uuid-dev libhal-dev libhal-storage-dev libsqlite3-dev libpango1.0-dev flex bison intltool libxml2-dev libgtk2.0-dev libexif-dev libjpeg62-dev libtiff4-dev + +wget http://download.librdf.org/binaries/debian/unstable/libraptor1-dev_1.4.18-1_i386.deb http://download.librdf.org/binaries/debian/unstable/libraptor1_1.4.18-1_i386.deb +sudo dpkg -i libraptor1-dev_1.4.18-1_i386.deb libraptor1_1.4.18-1_i386.deb + +wget http://download.gnome.org/sources/vala/0.7/vala-0.7.0.tar.bz2 +tar jxf vala-0.7.0.tar.bz2 +cd vala-0.7.0 +./configure ; make ; sudo make install + +git clone git://git.gnome.org/tracker +cd tracker +./autogen.sh ; ./configure ; make ; sudo make install + +svn checkout https://projects.maemo.org/svn/af/projects/libqttracker/tags/0.3.3/ libqttracker +cd libqttracker +nano -w shared.pri # edit so that install_prefix = /usr +qmake ; make ; sudo make install + diff --git a/examples/trackergrid/main.cpp b/examples/trackergrid/main.cpp new file mode 100644 index 000000000..807c1cfc8 --- /dev/null +++ b/examples/trackergrid/main.cpp @@ -0,0 +1,50 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +/* + * An example of a minimalistic DirectUI application + */ + +#include +#include +#include + +#include "trackergridpage.h" + +int main(int argc, char **argv) +{ + /* The base class of all DirectUI applications */ + DuiApplication app(argc, argv); + + /* The application window is a top-level window that contains + the Home and Back/Close framework controls, Navigation bar, + View menu and Toolbar components */ + DuiApplicationWindow w; + w.show(); + + /* Pages represent one "view" of an application, into which you + can add your application's contents. An application can have + any number of pages with transitions between them */ + TrackerGridPage p; + p.appearNow(); /* appearNow causes the page to be visible without + a transition animation, which is recommended + for the initial application page */ + + return app.exec(); +} diff --git a/examples/trackergrid/trackergrid.pro b/examples/trackergrid/trackergrid.pro new file mode 100644 index 000000000..9ec0a6e5e --- /dev/null +++ b/examples/trackergrid/trackergrid.pro @@ -0,0 +1,35 @@ +TEMPLATE = app +TARGET = trackergrid +CONFIG += dui # Requires libdui to be installed +LIBS += -lqttracker # Requires libqttracker + tracker + +# Input +SOURCES += main.cpp trackergridpage.cpp +HEADERS += trackergridpage.h + +# DUIROOT = ../.. +# +# include($$DUIROOT/mkspecs/common.pri) +# +# DUILIB = $$DUIROOT/lib +# DUISRC = $$DUIROOT/src +# DUISRCINCLUDE = $$DUISRC/include +# DUISFWINCLUDE = $$DUIROOT/servicefw/include +# +# INCLUDEPATH += . \ +# $$DUISRCINCLUDE \ +# $$DUISRC \ +# +# QMAKE_LIBDIR += \ +# $$DUILIB \ +# +# INCLUDEPATH += ../../src/include +# QMAKE_LIBDIR += ../../lib/ +# +# style_sheet.path = $$DUI_THEME_DIR/trackergrid +# style_sheet.files = style/trackergrid.css +# view_configuration.path = $$DUI_THEME_DIR/trackergrid +# +# INSTALLS += \ +# style_sheet \ + diff --git a/examples/trackergrid/trackergridpage.cpp b/examples/trackergrid/trackergridpage.cpp new file mode 100644 index 000000000..8d2071bd6 --- /dev/null +++ b/examples/trackergrid/trackergridpage.cpp @@ -0,0 +1,161 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include +#include +#include + +#include "trackergridpage.h" + +// Implementation for custom grid widget factory plugin +DuiWidget *GridWidgetFactoryPlugin::onBuild(QMap* data) +{ + qDebug() << "GridWidgetFactoryPlugin::onBuild()"; + + // Check that Mime type is image + if (data->value("?GridItem_Mime").toString().contains("image/")) { + // Make full path to image file + QString fullpath = data->value("?GridItem_Path").toString() + + QString("/") + + data->value("?GridItem_Name").toString(); + + // nfo::Image ontology presents paths like this: "file:///home/user" + // so strip the prefix + if (fullpath.startsWith(QString("file:/"))) + fullpath = fullpath.right(fullpath.length() - 6); + + // Construct DuiImage with the full path to image + qDebug() << "...creating DuiImage from " << fullpath; + DuiImage *widget = new DuiImage(fullpath); + + // Set widget size + QSize size(128, 128); + widget->setMinimumSize(size); + widget->setMaximumSize(size); + widget->setPreferredSize(size); + + return (DuiWidget *)widget; + } + return 0; +} + +QStringList GridWidgetFactoryPlugin::dataFields() +{ + qDebug() << "GridWidgetFactoryPlugin::dataFields()"; + + static QStringList list; + + if (list.empty()) { + list << "?GridItem_Name"; + list << "?GridItem_Path"; + list << "?GridItem_Mime"; + } + + return list; +} + + + +// Implementation for tracker grid page +TrackerGridPage::TrackerGridPage() +{ + qDebug() << "TrackerGridPage::TrackerGridPage()"; + + //% "TrackerGridPage" + setTitle(qtTrId("xx_tracker_grid_page_title")); + setObjectName("trackergridpage"); +} + +TrackerGridPage::~TrackerGridPage() +{ +} + +void TrackerGridPage::createContent() +{ + qDebug() << "TrackerGridPage::createContent()"; + + DuiApplicationPage::createContent(); + + // Grid for presenting tracker items + grid = new DuiGrid(); + grid->resize(800, 450); + grid->setSpacing(10); + grid->setLayoutMode(DuiGridModel::SinglePass); + grid->setBatchSize(100); + setCentralWidget(grid); + + // Attach a custom grid plugin to widget factory: + // default plugins cannot handle tracker data format + DuiWidgetFactory *pFactory = DuiWidgetFactory::instance(); + pFactory->attachPlugin(new GridWidgetFactoryPlugin()); + + // Query 20 images from tracker + SopranoLive::RDFSelect query; + makeQueryForImages(query, 20); + imageNodes = tracker()->modelQuery(query); + + // Connect signals to get live data updates + connectUpdateSignals(imageNodes); + + // Pass the abstract item model to grid + grid->setItemModel(imageNodes.model()); +} + +// SELECT ?__GridItem_MimeObjOfnie_mimeType ?__GridItem_PathObjOfnfo_belongsToContainer ?__GridItem_NameObjOfnfo_fileName +// WHERE { +// { +// ?__1 . +// ?__1 ?__GridItem_MimeObjOfnie_mimeType . +// ?__1 ?__GridItem_PathObjOfnfo_belongsToContainer . +// ?__1 ?__GridItem_NameObjOfnfo_fileName . +// } +// } +// LIMIT 20 +void TrackerGridPage::makeQueryForImages(SopranoLive::RDFSelect &query, int limit) +{ + qDebug() << "TrackerGridPage::makeQueryForImages()"; + + SopranoLive::RDFVariable image = SopranoLive::RDFVariable::fromType(); + query.limit(limit); + query.addColumn("GridItem_Mime", image.property()); + query.addColumn("GridItem_Path", image.property()); + query.addColumn("GridItem_Name", image.property()); + qDebug() << query.getQuery(); +} + +void TrackerGridPage::connectUpdateSignals(const SopranoLive::LiveNodes &nodes) +{ + qDebug() << "TrackerGridPage::connectUpdateSignals()"; + + QObject::connect(nodes.model(), SIGNAL(rowsInserted(QModelIndex, int, int)) + , this, SLOT(updateGrid())); + QObject::connect(nodes.model(), SIGNAL(rowsRemoved(QModelIndex, int, int)) + , this, SLOT(updateGrid())); + QObject::connect(nodes.model(), SIGNAL(dataChanged(QModelIndex, QModelIndex)) + , this, SLOT(updateGrid())); +} + +void TrackerGridPage::updateGrid() +{ + qDebug() << "TrackerGridPage::updateGrid()"; +} + +// End of file diff --git a/examples/trackergrid/trackergridpage.h b/examples/trackergrid/trackergridpage.h new file mode 100644 index 000000000..5c6223e92 --- /dev/null +++ b/examples/trackergrid/trackergridpage.h @@ -0,0 +1,69 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef TRACKERGRIDPAGE_H +#define TRACKERGRIDPAGE_H + +#include +#include +#include + +#include +#include + +// Forward class declarations +class DuiGrid; + + + +// Class declaration for custom grid widget factory plugin +class GridWidgetFactoryPlugin: public DuiWidgetFactoryPluginInterface +{ + Q_OBJECT + +public: + DuiWidget *onBuild(QMap* data); + QStringList dataFields(); +}; + + + +// Class declaration for tracker grid page +class TrackerGridPage : public DuiApplicationPage +{ + Q_OBJECT + +public: + TrackerGridPage(); + virtual ~TrackerGridPage(); + virtual void createContent(); + +public slots: + void updateGrid(); + +private: + void makeQueryForImages(SopranoLive::RDFSelect &query, int limit); + void connectUpdateSignals(const SopranoLive::LiveNodes &nodes); + +private: + SopranoLive::LiveNodes imageNodes; + DuiGrid *grid; +}; + +#endif // TRACKERGRIDPAGE_H diff --git a/lib/.gitignore b/lib/.gitignore new file mode 100644 index 000000000..e69de29bb diff --git a/mkspecs/.gitignore b/mkspecs/.gitignore new file mode 100644 index 000000000..1278887bd --- /dev/null +++ b/mkspecs/.gitignore @@ -0,0 +1 @@ +duiconfig.pri diff --git a/mkspecs/common.pri b/mkspecs/common.pri new file mode 100644 index 000000000..a029b5fa8 --- /dev/null +++ b/mkspecs/common.pri @@ -0,0 +1,80 @@ +# Build configuration + +QMAKE_TARGET_COMPANY = Nokia +QMAKE_TARGET_PRODUCT = DirectUI +QMAKE_TARGET_DESCRIPTION = DirectUI Framework +QMAKE_TARGET_COPYRIGHT = Copyright (C) 2010 Nokia + +# Features +# Parts to build. Options: libs tests benchmarks demos doc debian +#DUI_BUILD_PARTS = libs tests benchmarks demos doc debian + + +contains(TEMPLATE, app) { + DEFINES += DUI_APPLICATION_NAME=\\\"${QMAKE_TARGET}\\\" +} else { + contains(TEMPLATE, lib) { + DEFINES += DUI_LIBRARY_NAME=\\\"lib${QMAKE_TARGET}\\\" + } else { + # error(Unknown template) + } +} + +mac { + DUI_BUILD_FEATURES = debug + INCLUDEPATH += include +} + +# Load configure script results +!win32:!macx { + include(duiconfig.pri) +} + +# Load global definitions +include(../src/dui_defines.prf) + +# Defines for directories, for use in source code. +{ + # THEMEDIR determines the location of the theme + DEFINES += THEMEDIR=\\\"\"$$DUI_THEME_DIR\"\\\" + + # APPLET_LIBS determines the location where all applet binaries are + DEFINES += APPLET_LIBS=\\\"\"$$DUI_APPLET_DIR\"\\\" + + # APPLET_INSTALLATION_SOURCES determines the location where applet installation source binaries are + DEFINES += APPLET_INSTALLATION_SOURCES=\\\"\"$$DUI_APPLET_INSTALLATION_SOURCES_DIR\"\\\" + + # APPLET_DATA determines where the .desktop files are located + DEFINES += APPLET_DATA=\\\"\"$$DUI_APPLET_DATA_DIR\"\\\" + + # APPLET_SETTINGS_DIR determines where the applet global and instance settings files are located + DEFINES += APPLET_SETTINGS_DIR=\\\"\"$$DUI_APPLET_SETTINGS_DIR\"\\\" + + # TRANSLATION_DIR determines the default translation path + DEFINES += TRANSLATION_DIR=\\\"\"$$DUI_TRANSLATION_DIR\"\\\" + + # DUI_THEME_PRELOAD_DIR and DUI_THEME_POST_PRELOAD_DIR defines from where + # to get lists of images to be preloaded + DEFINES += DUI_THEME_PRELOAD_DIR=\\\"\"$$DUI_THEME_PRELOAD_DIR\"\\\" + DEFINES += DUI_THEME_POST_PRELOAD_DIR=\\\"\"$$DUI_THEME_POST_PRELOAD_DIR\"\\\" + DEFINES += DUI_DBUS_SERVICES_DIR=\\\"\"$$DUI_DBUS_SERVICES_DIR\"\\\" + DEFINES += DUI_XDG_DIR=\\\"\"$$DUI_XDG_DIR\"\\\" + + # DUI_BINARY_SHADERS_DIR defines the location of precompiled shader programs + DEFINES += DUI_SHADER_SOURCE_DIR=\\\"\"$$DUI_SHADER_SOURCE_DIR\"\\\" + DEFINES += DUI_SHADER_BINARY_DIR=\\\"\"$$DUI_SHADER_BINARY_DIR\"\\\" +} + +# Compiler configuration for all subprojects in libdui + +!win32-msvc*:QMAKE_CXXFLAGS += -g + +# To use compiler cache, "export USE_CCACHE=true" +USE_CCACHE=$$(USE_CCACHE) +contains(USE_CCACHE, "true") { + message("Using compiler cache") + QMAKE_CC = ccache gcc + QMAKE_CXX = ccache g++ +} + +include(shared.pri) diff --git a/mkspecs/shared.pri b/mkspecs/shared.pri new file mode 100644 index 000000000..f5ea435a7 --- /dev/null +++ b/mkspecs/shared.pri @@ -0,0 +1,25 @@ +defineReplace(findFile) { + FILE=$$1 + + # LIST=$$(PATH) + # for a reason beyond my knowledge, if i get path list from $$(PATH) and replace all :'s with space, + # i cant iterate the entries with qmake's for loop. + # SO, here's a list of predefined places where to look for executable files.. + # Also, i cant rely to find doxygen via system() call since doxygen returns error every time its called + # if it cant find Doxyfile =( + + LIST = /bin/ /usr/bin /usr/local/bin /usr/X11R6/bin ~/bin . + LIST += /scratchbox/devkits/cputransp/bin /scratchbox/devkits/maemo3-tools/bin + LIST += /scratchbox/devkits/debian-etch/bin /scratchbox/devkits/doctools/bin + LIST += /scratchbox/devkits/perl/bin /scratchbox/tools/bin /targets/links/arch_tools/bin + LIST += /host_usr/bin /scratchbox/compilers/bin + + LOCATED= + for(path,LIST) { + exists($${path}/$${FILE}): { + isEmpty(LOCATED):LOCATED=$${path}/$${FILE} + } + } + + return($${LOCATED}) +} diff --git a/plainqt/icons/Icon-back.png b/plainqt/icons/Icon-back.png new file mode 100644 index 000000000..61930d1e4 Binary files /dev/null and b/plainqt/icons/Icon-back.png differ diff --git a/plainqt/icons/Icon-close.png b/plainqt/icons/Icon-close.png new file mode 100644 index 000000000..d80badae8 Binary files /dev/null and b/plainqt/icons/Icon-close.png differ diff --git a/plainqt/icons/Icon-home.png b/plainqt/icons/Icon-home.png new file mode 100644 index 000000000..66b647d74 Binary files /dev/null and b/plainqt/icons/Icon-home.png differ diff --git a/plainqt/plainqt.pro b/plainqt/plainqt.pro new file mode 100644 index 000000000..9d312b7b7 --- /dev/null +++ b/plainqt/plainqt.pro @@ -0,0 +1,8 @@ +TEMPLATE = subdirs +SUBDIRS = style + +QMAKE_EXTRA_TARGETS += check +check.commands = $$system(true) + +QMAKE_EXTRA_TARGETS += check-xml +check-xml.commands = $$system(true) diff --git a/plainqt/style/.gitignore b/plainqt/style/.gitignore new file mode 100644 index 000000000..c4f6bed6a --- /dev/null +++ b/plainqt/style/.gitignore @@ -0,0 +1 @@ +qrc_style.cpp diff --git a/plainqt/style/bg2.png b/plainqt/style/bg2.png new file mode 100644 index 000000000..c4d6b9dd8 Binary files /dev/null and b/plainqt/style/bg2.png differ diff --git a/plainqt/style/qtmaemo6clicklabel.h b/plainqt/style/qtmaemo6clicklabel.h new file mode 100644 index 000000000..bcf16cdb6 --- /dev/null +++ b/plainqt/style/qtmaemo6clicklabel.h @@ -0,0 +1,45 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef QTMAEMO6CLICKLABEL_H +#define QTMAEMO6CLICKLABEL_H + +#include + + +/*! + * this class extends QLabel to behave more like a button + */ +class QtMaemo6ClickLabel : public QLabel +{ + Q_OBJECT +public: + explicit QtMaemo6ClickLabel(QWidget *parent): QLabel(parent) {} + +protected: + void mousePressEvent(QMouseEvent *ev) { + Q_UNUSED(ev); + emit clicked(); + } + +Q_SIGNALS: + void clicked(); +}; + +#endif // QTMAEMO6CLICKLABEL_H diff --git a/plainqt/style/qtmaemo6dialogproxy.cpp b/plainqt/style/qtmaemo6dialogproxy.cpp new file mode 100644 index 000000000..e10475095 --- /dev/null +++ b/plainqt/style/qtmaemo6dialogproxy.cpp @@ -0,0 +1,70 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "qtmaemo6dialogproxy.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "qtmaemo6dialogtitle.h" +#include "qtmaemo6style_p.h" + +QtMaemo6DialogProxy::QtMaemo6DialogProxy(QDialog *mw, QWidget *parent) + : QtMaemo6Window(mw, parent) +{ + setAttribute(Qt::WA_TranslucentBackground); + + QPalette palette; + palette.setBrush(QPalette::Window, QBrush(QColor(0, 0, 0, 192))); + setPalette(palette); + + m_dialogTitle = new QtMaemo6DialogTitle(NULL); + QtMaemo6StylePrivate::drawWindowBackground(m_dialogTitle); + + QSpacerItem *leftSideSpacer = new QSpacerItem(9, 0); + QSpacerItem *rightSideSpacer = new QSpacerItem(9, 0); + QSpacerItem *topSpacer = new QSpacerItem(10, 10, QSizePolicy::Minimum, QSizePolicy::Expanding); + + m_windowLayout->addItem(topSpacer, 0, 0, 1, 3); + m_windowLayout->addItem(leftSideSpacer, 1, 0, 2, 1); + m_windowLayout->addWidget(m_dialogTitle, 1, 1, 1, 1); + m_windowLayout->addWidget(m_scrollArea, 2, 1, 1, 1); + m_windowLayout->addItem(rightSideSpacer, 1, 2, 2, 1); + + connect(m_dialogTitle, SIGNAL(closeRequest()), mw, SLOT(reject())); +} + +QtMaemo6DialogProxy::~QtMaemo6DialogProxy() +{ +} + +void QtMaemo6DialogProxy::setTitle(const QString &text) +{ + m_dialogTitle->setTitle(text); +} + +void QtMaemo6DialogProxy::setPixmap(const QPixmap &icon) +{ + m_dialogTitle->setPixmap(icon); +} diff --git a/plainqt/style/qtmaemo6dialogproxy.h b/plainqt/style/qtmaemo6dialogproxy.h new file mode 100644 index 000000000..61300b226 --- /dev/null +++ b/plainqt/style/qtmaemo6dialogproxy.h @@ -0,0 +1,65 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef QTMAEMO6DIALOGPROXY_H +#define QTMAEMO6DIALOGPROXY_H + +#include +#include +#include +#include +#include "qtmaemo6window.h" + +class QtMaemo6DialogTitle; +class QDialog; + +/*! + * This class emulates the windowdecoration, for dialogs. It draws the the + * titlebar and cares for the composition modes. + */ +class QtMaemo6DialogProxy : public QtMaemo6Window +{ + Q_OBJECT +public: + explicit QtMaemo6DialogProxy(QDialog *mw, QWidget *parent); + ~QtMaemo6DialogProxy(); + + /*! + * sets the title of the dialog + */ + void setTitle(const QString &text); + + /*! + * sets the icon shown in the dialog's titlebar + */ + void setPixmap(const QPixmap &icon); + +protected: + QtMaemo6DialogProxy() {}; + + /*! \reimp */ + //bool eventFilter(QObject* watched, QEvent* ev); + //void closeEvent(QCloseEvent* event); + /*! \reimp_end */ + +private: + QtMaemo6DialogTitle *m_dialogTitle; +}; + +#endif diff --git a/plainqt/style/qtmaemo6dialogtitle.cpp b/plainqt/style/qtmaemo6dialogtitle.cpp new file mode 100644 index 000000000..8b24266bb --- /dev/null +++ b/plainqt/style/qtmaemo6dialogtitle.cpp @@ -0,0 +1,80 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "qtmaemo6dialogtitle.h" + +#include +#include +#include +#include +#include +#include + + +QtMaemo6DialogTitle::QtMaemo6DialogTitle(QWidget *parent) : QWidget(parent) +{ + setObjectName(QString("Qt_Maemo6_DialogTitle")); + + m_titleLabel = new QLabel(this); + + m_closeButton = new QtMaemo6ClickLabel(this); + m_closeButton->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred); + m_closeButton->setMargin(8); + connect(m_closeButton, SIGNAL(clicked()), this, SIGNAL(closeRequest())); + + m_titleBarLayout = new QHBoxLayout(this); + m_titleBarLayout->setMargin(0); + m_titleBarLayout->setSpacing(0); + m_titleBarLayout->addWidget(m_titleLabel); + m_titleBarLayout->addWidget(m_closeButton); + +} + +QtMaemo6DialogTitle::~QtMaemo6DialogTitle() +{ + +} + +void QtMaemo6DialogTitle::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event); + + QPainter painter(this); + + QStyleOption option; + option.initFrom(this); + + style()->drawPrimitive(QStyle::PE_Widget, &option, &painter, this); +} + +void QtMaemo6DialogTitle::setTitle(const QString &title) +{ + m_titleLabel->setText(title); + m_titleLabel->setAlignment(Qt::AlignHCenter); +} + +QString QtMaemo6DialogTitle::title() const +{ + return m_titleLabel->text(); +} + +void QtMaemo6DialogTitle::setPixmap(const QPixmap &icon) +{ + m_closeButton->setPixmap(icon); +} diff --git a/plainqt/style/qtmaemo6dialogtitle.h b/plainqt/style/qtmaemo6dialogtitle.h new file mode 100644 index 000000000..88a15f846 --- /dev/null +++ b/plainqt/style/qtmaemo6dialogtitle.h @@ -0,0 +1,70 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef QTMAEMO6DIALOGTITLE_H +#define QTMAEMO6DIALOGTITLE_H + +#include "qtmaemo6clicklabel.h" +#include + + +/*! + * This class emulates the title bar of a dialog + */ +class QtMaemo6DialogTitle : public QWidget +{ + Q_OBJECT + Q_PROPERTY(QString title READ title WRITE setTitle) +public: + explicit QtMaemo6DialogTitle(QWidget *parent); + virtual ~QtMaemo6DialogTitle(); + + /*! + * returns the dialog's title + */ + QString title() const; + +public Q_SLOTS: + /*! + * sets the title of the dialog + */ + void setTitle(const QString &title); + + /*! + * sets the icon shown in the title bar + */ + void setPixmap(const QPixmap &icon); + +Q_SIGNALS: + /*! + * this signal is emitted, if the title bar's close button was clicked + */ + void closeRequest(); + +protected: + /*! \reimp */ + void paintEvent(QPaintEvent *event); + /*! \reimp_end */ +private: + QtMaemo6ClickLabel *m_closeButton; + QLabel *m_titleLabel; + QHBoxLayout *m_titleBarLayout; +}; + +#endif diff --git a/plainqt/style/qtmaemo6menu.cpp b/plainqt/style/qtmaemo6menu.cpp new file mode 100644 index 000000000..8f24be5d9 --- /dev/null +++ b/plainqt/style/qtmaemo6menu.cpp @@ -0,0 +1,89 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "qtmaemo6menu.h" +#include "qtmaemo6submenu.h" +#include "qtmaemo6windowdecoration.h" +#include "qtmaemo6style_p.h" + +#include +#include +#include +#include +#include + +QtMaemo6Menu::QtMaemo6Menu(QMenuBar *mb, QWidget *parent) : QWidget(parent) +{ + QGridLayout *gridLayout = new QGridLayout(this); + + for (int i = 0; i < mb->actions().count(); ++i) { + QAction *action = mb->actions().at(i); + QToolButton *button = new QToolButton(); + button->setDefaultAction(action); + if (action->menu()) + connect(button, SIGNAL(clicked()), this, SLOT(showSubMenu())); + else + connect(button, SIGNAL(clicked()), this, SLOT(executeAction())); + button->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + gridLayout->addWidget(button, i / 2, i % 2); + } +} + +QtMaemo6Menu::~QtMaemo6Menu() +{ + +} + +void QtMaemo6Menu::showSubMenu() +{ + if (QToolButton *button = qobject_cast(sender())) { + if (QMenu *menu = button->defaultAction()->menu()) { + //show menu + QtMaemo6SubMenu *subMenu = new QtMaemo6SubMenu(menu, NULL); + QtMaemo6WindowDecoration *decoration = new QtMaemo6WindowDecoration(subMenu, NULL); + decoration->showFastMaximized(); + //these both must be done after the show, because the status- and + // menubar is added on show event + decoration->setStatusBar(NULL); + decoration->setMenuBar(NULL); + QtMaemo6StylePrivate::drawWindowBackground(decoration); + close(); + } + } +} + +void QtMaemo6Menu::executeAction() +{ + if (QToolButton *button = qobject_cast(sender())) { + button->defaultAction()->activate(QAction::Trigger); + close(); + } +} + +void QtMaemo6Menu::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event); + + QPainter painter(this); + + QStyleOption option; + option.initFrom(this); + + style()->drawPrimitive(QStyle::PE_Widget, &option, &painter, this); +} diff --git a/plainqt/style/qtmaemo6menu.h b/plainqt/style/qtmaemo6menu.h new file mode 100644 index 000000000..4803643a4 --- /dev/null +++ b/plainqt/style/qtmaemo6menu.h @@ -0,0 +1,44 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef QTMAEMO6MENU_H +#define QTMAEMO6MENU_H + +#include +#include + +/*! + * This class emulates the title bar of a dialog + */ +class QtMaemo6Menu : public QWidget +{ + Q_OBJECT +public: + explicit QtMaemo6Menu(QMenuBar *mb, QWidget *parent); + virtual ~QtMaemo6Menu(); +protected Q_SLOTS: + void showSubMenu(); + void executeAction(); +protected: + /*! \reimp */ + void paintEvent(QPaintEvent *event); + /*! \reimp_end */ +}; + +#endif diff --git a/plainqt/style/qtmaemo6menuproxy.cpp b/plainqt/style/qtmaemo6menuproxy.cpp new file mode 100644 index 000000000..f2ddf36e3 --- /dev/null +++ b/plainqt/style/qtmaemo6menuproxy.cpp @@ -0,0 +1,74 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "qtmaemo6menuproxy.h" +#include "qtmaemo6menu.h" +#include "qtmaemo6style_p.h" + +#include +#include +#include +#include +#include +#include + +#include + +QtMaemo6MenuProxy::QtMaemo6MenuProxy(QMenuBar *mb, QWidget *parent) + : QtMaemo6Window(NULL, parent), + m_menuBar(mb) +{ + setAttribute(Qt::WA_TranslucentBackground); + + QPalette palette; + palette.setBrush(QPalette::Window, QBrush(QColor(0, 0, 0, 192))); + setPalette(palette); + + m_menu = new QtMaemo6Menu(mb, NULL); + setCentralWidget(m_menu); + + QStyleOption option; + option.initFrom(mb); + + const DuiApplicationMenuStyle *style = + static_cast( + QtMaemo6StylePrivate::duiStyle(option.state, "DuiApplicationMenuStyle")); + + QSpacerItem *topSpacer = new QSpacerItem(1, style->paddingTop()); + QSpacerItem *rightSpacer = new QSpacerItem(style->paddingRight(), 1); + QSpacerItem *bottomSpacer = new QSpacerItem(1, style->paddingBottom()); + QSpacerItem *leftSpacer = new QSpacerItem(style->paddingLeft(), 1); + + m_windowLayout->addItem(topSpacer, 0, 0, 1, 3); + m_windowLayout->addItem(leftSpacer, 1, 0, 1, 1); + m_windowLayout->addItem(rightSpacer, 1, 2, 1, 1); + m_windowLayout->addItem(bottomSpacer, 2, 0, 1, 3); +} + +QtMaemo6MenuProxy::~QtMaemo6MenuProxy() +{ + //delete manually, because it is removed from the scroll area bevore deleting + delete m_menu; +} + +void QtMaemo6MenuProxy::mousePressEvent(QMouseEvent *event) +{ + Q_UNUSED(event); + close(); +} diff --git a/plainqt/style/qtmaemo6menuproxy.h b/plainqt/style/qtmaemo6menuproxy.h new file mode 100644 index 000000000..cc1b950eb --- /dev/null +++ b/plainqt/style/qtmaemo6menuproxy.h @@ -0,0 +1,52 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef QTMAEMO6MENUPROXY_H +#define QTMAEMO6MENUPROXY_H + +#include + +#include "qtmaemo6window.h" + +class QtMaemo6Menu; +class QDialog; +class QMenuBar; + +/*! + * This class emulates the windowdecoration, for dialogs. It draws the the + * titlebar and cares for the composition modes. + */ +class QtMaemo6MenuProxy : public QtMaemo6Window +{ + Q_OBJECT +public: + explicit QtMaemo6MenuProxy(QMenuBar *menu, QWidget *parent); + ~QtMaemo6MenuProxy(); + +protected: + QtMaemo6MenuProxy() {}; + + virtual void mousePressEvent(QMouseEvent *event); + +protected: + QMenuBar *m_menuBar; + QtMaemo6Menu *m_menu; +}; + +#endif diff --git a/plainqt/style/qtmaemo6pangesture.cpp b/plainqt/style/qtmaemo6pangesture.cpp new file mode 100644 index 000000000..a0a8f32c5 --- /dev/null +++ b/plainqt/style/qtmaemo6pangesture.cpp @@ -0,0 +1,121 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "qtmaemo6pangesture.h" + +#include +#include +#include +#include +#include +#include + +void QtMaemo6PanGesture::enableOn(QWidget *w) +{ + if (w) { + w->installEventFilter(this); + ScrollState *state = new ScrollState; + state->widget = w; + state->panState = ScrollState::None; + m_activeWidgets.insert(w, state); + } +} + +bool QtMaemo6PanGesture::eventFilter(QObject *object, QEvent *event) +{ + if (!qobject_cast(object)) + return false; + + QEvent::Type type = event->type(); + if (type != QEvent::MouseButtonPress && + type != QEvent::MouseButtonRelease && + type != QEvent::MouseMove) + return false; + + QMouseEvent *mouseEvent = dynamic_cast(event); + if (!mouseEvent || (mouseEvent->modifiers() != Qt::NoModifier)) + return false; + + QAbstractScrollArea *scrollArea = qobject_cast(object); + ScrollState *scrollState = m_activeWidgets.value(scrollArea); + if (scrollArea && scrollState) { + //return if the event is on the ignore list + if (scrollState->ignoreEvents.removeAll(event)) + return false; + + switch (scrollState->panState) { + case ScrollState::None: + if (mouseEvent->type() == QEvent::MouseButtonPress + && mouseEvent->buttons() == Qt::LeftButton) { + qDebug() << "Gesture State None Press Event"; + scrollState->pressPos = mouseEvent->pos(); + scrollState->panState = ScrollState::Pressed; + scrollState->scrollOffset = QPoint(scrollArea->horizontalScrollBar()->value(), + scrollArea->verticalScrollBar()->value()); + } + break; + case ScrollState::Pressed: + if (mouseEvent->type() == QEvent::MouseButtonRelease) { + qDebug() << "Gesture State Pressed Release Event"; + //generate new press and release event and + scrollState->panState = ScrollState::None; + + QMouseEvent *pressEvent = new QMouseEvent(QEvent::MouseButtonPress, + scrollState->pressPos, Qt::LeftButton, + Qt::LeftButton, Qt::NoModifier); + QMouseEvent *releaseEvent = new QMouseEvent(*mouseEvent); + + //these generated events must not be handled by this filter again! + scrollState->ignoreEvents << pressEvent << releaseEvent; + + QApplication::postEvent(object, pressEvent); + QApplication::postEvent(object, releaseEvent); + } + if (mouseEvent->type() == QEvent::MouseMove) { + qDebug() << "Gesture State Pressed Move Event"; + scrollState->panState = ScrollState::Scroll; + QPoint delta = mouseEvent->pos() - scrollState->pressPos; + + scrollArea->horizontalScrollBar()->setValue(scrollState->scrollOffset.x() - delta.x()); + scrollArea->verticalScrollBar()->setValue(scrollState->scrollOffset.y() - delta.y()); + } + break; + case ScrollState::Scroll: + if (mouseEvent->type() == QEvent::MouseMove) { + qDebug() << "Gesture State Scroll Move Event"; + QPoint delta = mouseEvent->pos() - scrollState->pressPos; + + scrollArea->horizontalScrollBar()->setValue(scrollState->scrollOffset.x() - delta.x()); + scrollArea->verticalScrollBar()->setValue(scrollState->scrollOffset.y() - delta.y()); + + qDebug() << "Gesture delta" << delta; + qDebug() << "ScrollBars Value" << scrollArea->horizontalScrollBar()->value() << scrollArea->verticalScrollBar()->value(); + } + if (mouseEvent->type() == QEvent::MouseButtonRelease) { + qDebug() << "Gesture State Scroll Release Event"; + scrollState->panState = ScrollState::None; + } + break; + default: + return false; + } + return true; + } else + return false; +} diff --git a/plainqt/style/qtmaemo6pangesture.h b/plainqt/style/qtmaemo6pangesture.h new file mode 100644 index 000000000..64538f5fb --- /dev/null +++ b/plainqt/style/qtmaemo6pangesture.h @@ -0,0 +1,67 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef QTMAEMO6PANGESTURE_H +#define QTMAEMO6PANGESTURE_H + +#include +#include +#include +#include + +class QWidget; + +/*! + * this class implements a pan gesture recognition which can be enabled on + * plain scrollareas. + * this class may be deprecated in future, because dui gestures may be used + */ +class QtMaemo6PanGesture : public QObject +{ + Q_OBJECT +public: + QtMaemo6PanGesture(QObject *parent) : QObject(parent) {}; + + /*! + * enables the pan gesture recognition onto the given widget + */ + void enableOn(QWidget *w); + + /*! \reimp */ + /* ! + * the recognition is handled here + */ + bool eventFilter(QObject *object, QEvent *event); + /*! \reimp_end */ +private: + /*! + * this struct holdes the different states when panning is active + */ + struct ScrollState { + enum PanState { None, Pressed, Scroll, PostScroll, Stop }; + PanState panState; + QPoint pressPos; + QPoint scrollOffset; + QWidget *widget; + QList ignoreEvents; + }; + QMap m_activeWidgets; +}; + +#endif diff --git a/plainqt/style/qtmaemo6scrollbareventfilter.cpp b/plainqt/style/qtmaemo6scrollbareventfilter.cpp new file mode 100644 index 000000000..77506c489 --- /dev/null +++ b/plainqt/style/qtmaemo6scrollbareventfilter.cpp @@ -0,0 +1,386 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "qtmaemo6scrollbareventfilter.h" +#include "qtmaemo6style_p.h" +#include "qtmaemo6windowdecoration.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +AbstractScrollAreaThumbView::AbstractScrollAreaThumbView(QWidget *parent /*= NULL*/) + : QLabel(parent) +{ + setVisible(false); +} + +void AbstractScrollAreaThumbView::paintEvent(QPaintEvent *event) +{ + if (pixmap()) { + + QPixmap pix = *pixmap(); + + QPainter pixPainter(&pix); + + QPainterPath grayedOutRegion; + grayedOutRegion.setFillRule(Qt::OddEvenFill); + grayedOutRegion.addRect(QRect(QPoint(0, 0), pixmap()->size())); + grayedOutRegion.addRect(m_visibleRect); + + pixPainter.setPen(Qt::NoPen); + pixPainter.setBrush(QBrush(QColor(255, 255, 255, 128))); + pixPainter.drawPath(grayedOutRegion); + + pixPainter.setPen(QPen(Qt::black, 1.0)); + pixPainter.setBrush(Qt::NoBrush); + pixPainter.drawRect(m_visibleRect); + pixPainter.end(); + + pix = setPixmapOpacity(pix, m_opacity); + + QPainter painter(this); + painter.drawPixmap(event->rect(), pix); + } +} + + +QtMaemo6ScrollBarEventFilter::QtMaemo6ScrollBarEventFilter(QObject *parent) : + QObject(parent), + m_scrollBarsAlwaysVisible(false), + m_scrollAreaThumbnailMaxSize(200), + m_scrollAreaThumbnailOffset(20), + m_scrollAreaThumbnailBorder(3), + m_showScrollAreaThumbnailFactor(0.2) +{} + +QtMaemo6ScrollBarEventFilter::~QtMaemo6ScrollBarEventFilter() +{ +} + +void QtMaemo6ScrollBarEventFilter::enableOn(QObject *o) +{ + o->installEventFilter(this); + + if (QAbstractScrollArea *abstractScrollArea = qobject_cast(o)) { +#ifdef SHOW_SCROLLING_THUMBNAIL + if (qobject_cast(abstractScrollArea->parent())) { + AbstractScrollAreaThumbView *scrollAreaThumbView = new AbstractScrollAreaThumbView(abstractScrollArea); + scrollAreaThumbView->setObjectName(SCROLLAREATHUMBVIEW); + scrollAreaThumbView->setOpacity(0); + } +#endif + //FIXME: find a more proper solution without manipulating the widget's properties + // turn the scrollbars off for ScrollArea, they are handled manually by the style + abstractScrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + abstractScrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + } + if (QScrollBar *scrollBar = qobject_cast(o)) { + //FIXME: using the signals from scrollbar is not the best solution, because + // they maybe disconnected by the user + connect(scrollBar, SIGNAL(valueChanged(int)), this, SLOT(scrollBarValueChanged())); + } +} + +bool QtMaemo6ScrollBarEventFilter::eventFilter(QObject *obj, QEvent *event) +{ + switch (event->type()) { + /* this is the implementation for showing the scrollbars without using the signals + from the scrollbars + this piece of code is kept intentionally, because it may be useful when not using + the signals from the scrollbar to recognize that scrolling is in progress + case QEvent::Move: { + if(!scrollBarsAlwaysVisible()) { + QMoveEvent* moveEvent = static_cast(event); + if(QWidget* widget = qobject_cast(obj)) { + QWidget* viewport = widget->parentWidget(); + QAbstractScrollArea* scrollArea = qobject_cast(viewport->parent()); + if(scrollArea) { + generateScrollAreaThumb(scrollArea); + fadeInOutAnimation(scrollArea->findChild(SCROLLAREATHUMBVIEW), "opacity"); + if(scrollArea->horizontalScrollBar() && moveEvent->oldPos().x() != moveEvent->pos().x()) { + fadeInOutAnimation(scrollArea->horizontalScrollBar(), WIDGET_OPACITY); + } + if(scrollArea->verticalScrollBar() && moveEvent->oldPos().y() != moveEvent->pos().y()) { + fadeInOutAnimation(scrollArea->verticalScrollBar(), WIDGET_OPACITY); + } + } + } + } + } + break; + */ + case QEvent::Resize: { + if (QAbstractScrollArea *scrollArea = qobject_cast(obj)) { + if (QScrollBar *scrollBar = scrollArea->horizontalScrollBar()) { + //Moved the scrollBar init stuff into resizeEvent because + // in QStyle::polish are no sizes set, so there can't be made + // a decision about the need to show a scrollbar + scrollBar->setAttribute(Qt::WA_OpaquePaintEvent, false); + scrollBar->setParent(scrollArea); + setScrollBarVisibility(scrollBar); + + scrollBar->setGeometry(QRect(scrollArea->contentsRect().left(), + scrollArea->contentsRect().bottom() - scrollBar->sizeHint().height(), + scrollArea->contentsRect().width(), + scrollBar->sizeHint().height())); + } + if (QScrollBar *scrollBar = scrollArea->verticalScrollBar()) { + //Moved the scrollBar init stuff into resizeEvent beacause + // in QStyle::polish are no sizes set, so there can't be made + // a decision about the need to show a scrollbar + scrollBar->setAttribute(Qt::WA_OpaquePaintEvent, false); + scrollBar->setParent(scrollArea); + setScrollBarVisibility(scrollBar); + + if (qApp->isRightToLeft()) { + scrollBar->setGeometry(QRect(scrollArea->contentsRect().left(), + scrollArea->contentsRect().top(), + scrollBar->sizeHint().width(), + scrollArea->contentsRect().height())); + } else { + scrollBar->setGeometry(QRect(scrollArea->contentsRect().right() - scrollBar->sizeHint().width(), + scrollArea->contentsRect().top(), + scrollBar->sizeHint().width(), + scrollArea->contentsRect().height())); + } + } +#ifdef SHOW_SCROLLING_THUMBNAIL + if (QLabel *scrollAreaThumbView = scrollArea->findChild(SCROLLAREATHUMBVIEW)) { + setScrollAreaThumbGeometry(scrollAreaThumbView); + } +#endif + } + } + break; + default: + break; + } + return QObject::eventFilter(obj, event); +} + +void QtMaemo6ScrollBarEventFilter::setScrollBarVisibility(QScrollBar *scrollBar) +{ + if (!scrollBarsAlwaysVisible()) { + scrollBar->setProperty(WIDGET_OPACITY, 0.0); + } else { + //set the scrollBar only visible if there is something to scroll + bool isValidScrollRange = scrollBar->minimum() < scrollBar->maximum(); + scrollBar->setVisible(isValidScrollRange); + } +} + + +void QtMaemo6ScrollBarEventFilter::generateScrollAreaThumb(QAbstractScrollArea *scrollArea, + bool forceUpdate /*= false*/) +{ + //surpress unused warning while this is inactive + Q_UNUSED(scrollArea); + Q_UNUSED(forceUpdate); + +#ifdef SHOW_SCROLLING_THUMBNAIL + if (AbstractScrollAreaThumbView *scrollAreaThumbView = + scrollArea->findChild(SCROLLAREATHUMBVIEW)) { + if (scrollAreaThumbView) { + QWidget *vp = scrollArea->viewport(); + + double scaleFactor; + double longSide = qMax(vp->childrenRect().width(), vp->childrenRect().height()); + + if (0.0 != longSide) { + scaleFactor = m_scrollAreaThumbnailMaxSize / longSide; + + if (!scrollAreaThumbView->pixmap() || forceUpdate) { + qDebug() << "generating Pixmap"; + + QPixmap pixmap(vp->childrenRect().size() * scaleFactor + QSize(m_scrollAreaThumbnailBorder * 2, m_scrollAreaThumbnailBorder * 2)); + pixmap.fill(Qt::white); + QPainter p(&pixmap); + + const DuiApplicationPageStyle *style = + static_cast( + QtMaemo6StylePrivate::duiStyle(QStyle::State_Active, "DuiApplicationPageStyle", "")); + + p.drawPixmap(pixmap.rect(), *style->backgroundImage()->pixmap()); + + //Drawing the border + p.setPen(QPen(Qt::black, 1.0)); + p.drawRect(QRect(QPoint(0, 0), pixmap.size() - QSize(1, 1))); + + p.translate(3, 3); + p.scale(scaleFactor, scaleFactor); + vp->render(&p, QPoint(), vp->childrenRect()); + + scrollAreaThumbView->setPixmap(pixmap); + } + + QRect visibleRect = QRect(-vp->childrenRect().topLeft(), vp->rect().size()); + + //scale visibleRect manually to fit the thumbnailview + scrollAreaThumbView->setVisibleRect( + QRect(visibleRect.topLeft() * scaleFactor, visibleRect.size() * scaleFactor - QSize(1, 1)).translated(3, 3)); + + setScrollAreaThumbGeometry(scrollAreaThumbView); + } + } + } +#endif +} + +void QtMaemo6ScrollBarEventFilter::cleanUpTimerMap() +{ + if (QAbstractAnimation *animation = qobject_cast(sender())) { + //the event comes from the fadeOut-animation, so we need to get the group + if ((animation = qobject_cast(animation->parent()))) { + foreach(QWidget * w, m_pendingAnimations.keys()) { + if (m_pendingAnimations.value(w) == animation) { + delete m_pendingAnimations.take(w); + } + } + } + } +} + +void QtMaemo6ScrollBarEventFilter::setScrollAreaThumbGeometry(QLabel *label) +{ + if (label->pixmap()) { + if (qApp->isRightToLeft()) { + label->setGeometry(m_scrollAreaThumbnailOffset, m_scrollAreaThumbnailOffset, + label->pixmap()->width(), label->pixmap()->height()); + } else { + label->setGeometry(label->parentWidget()->width() - (label->pixmap()->width() + m_scrollAreaThumbnailOffset), + m_scrollAreaThumbnailOffset, label->pixmap()->width(), label->pixmap()->height()); + } + } +} + +void QtMaemo6ScrollBarEventFilter::scrollBarValueChanged() +{ + if (QScrollBar *scrollBar = qobject_cast(sender())) { + if (QAbstractScrollArea *scrollArea = qobject_cast(scrollBar->parent())) { + int scrollBarRange = scrollBar->maximum() - scrollBar->minimum(); + + double factor = 0; + if (scrollBar->orientation() == Qt::Horizontal) + factor = scrollBarRange / (double)scrollArea->viewport()->childrenRect().size().width(); + else + factor = scrollBarRange / (double)scrollArea->viewport()->childrenRect().size().height(); + + //only show the scrollArea thumbnail if the contents have enough amount of scrolling + if (factor > m_showScrollAreaThumbnailFactor) { + //if a new animation is started force generating a new thumbnail + bool forceThumbnailUpdate = !m_pendingAnimations.contains(scrollBar); + generateScrollAreaThumb(scrollArea, forceThumbnailUpdate); + + fadeInOutAnimation(scrollArea->findChild(SCROLLAREATHUMBVIEW), "opacity"); + } + + //only show the scrollBar if it has a valid range + if (scrollBarRange) + fadeInOutAnimation(scrollBar, WIDGET_OPACITY); + } + } +} + +void QtMaemo6ScrollBarEventFilter::fadeInOutAnimation(QWidget *w, const char *property) +{ + if (!w || !property) + return; + + if (m_pendingAnimations.contains(w)) { + //if the animation is already running + QSequentialAnimationGroup *sag = m_pendingAnimations.value(w); + if (sag->animationAt(FadeIn)->state() == QAbstractAnimation::Running || + sag->animationAt(Show)->state() == QAbstractAnimation::Running || + sag->animationAt(FadeOut)->state() == QAbstractAnimation::Running) { + //if the scrollbar is fully visible, restart the show animation. + if (sag->animationAt(Show)->state() == QAbstractAnimation::Running) { + sag->animationAt(Show)->stop(); + sag->animationAt(Show)->start(); + } + } + } else { + const DuiPositionIndicatorStyle *style = + static_cast(QtMaemo6StylePrivate::duiStyle(QStyle::State_Active, + "DuiPositionIndicatorStyle")); + + const DuiWidgetFadeInAnimationStyle *fadeInStyle = + static_cast(QtMaemo6StylePrivate::duiStyle(QStyle::State_Active, + "DuiWidgetFadeInAnimationStyle")); + + const DuiWidgetFadeOutAnimationStyle *fadeOutStyle = + static_cast(QtMaemo6StylePrivate::duiStyle(QStyle::State_Active, + "DuiWidgetFadeOutAnimationStyle")); + + QSequentialAnimationGroup *animationGroup = new QSequentialAnimationGroup(); + QPropertyAnimation *fadeIn = new QPropertyAnimation(animationGroup); + fadeIn->setTargetObject(w); + fadeIn->setPropertyName(property); + fadeIn->setDuration(fadeInStyle->duration()); + fadeIn->setEasingCurve(fadeInStyle->easingCurve()); + fadeIn->setStartValue(0.0); + fadeIn->setEndValue(1.0); + + QPropertyAnimation *fadeOut = new QPropertyAnimation(animationGroup); + fadeOut->setTargetObject(w); + fadeOut->setPropertyName(property); + fadeOut->setDuration(fadeOutStyle->duration()); + fadeOut->setEasingCurve(fadeOutStyle->easingCurve()); + fadeOut->setStartValue(1.0); + fadeOut->setEndValue(0.0); + + animationGroup->insertAnimation(FadeIn, fadeIn); + animationGroup->insertPause(Show, style->hideTimeout()); + animationGroup->insertAnimation(FadeOut, fadeOut); + + connect(animationGroup->animationAt(FadeIn), SIGNAL(finished()), animationGroup->animationAt(Show), SLOT(start())); + connect(animationGroup->animationAt(Show), SIGNAL(finished()), animationGroup->animationAt(FadeOut), SLOT(start())); + + //hide must be called before cleanup, because otherwise the widget is deleted before hiding + connect(animationGroup->animationAt(FadeOut), SIGNAL(finished()), w, SLOT(hide())); + connect(animationGroup->animationAt(FadeOut), SIGNAL(finished()), this, SLOT(cleanUpTimerMap())); + + connect(fadeIn, SIGNAL(valueChanged(QVariant)), w, SLOT(repaint())); + connect(fadeOut, SIGNAL(valueChanged(QVariant)), w, SLOT(repaint())); + + w->show(); + m_pendingAnimations.insert(w, animationGroup); + + //do NOT use the animationGroup's start method. + // if the animation reached the pause animation (show state), + // the pause animation is restarted every time a scrolling activity + // occurs. So the pause animation only reaches it's end, if there is + // no scrolling activity. + // resetting the animation within the running animation group didn't + // work! + fadeIn->start(); + } +} diff --git a/plainqt/style/qtmaemo6scrollbareventfilter.h b/plainqt/style/qtmaemo6scrollbareventfilter.h new file mode 100644 index 000000000..4627495ec --- /dev/null +++ b/plainqt/style/qtmaemo6scrollbareventfilter.h @@ -0,0 +1,176 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef QTMAEMO6SCROLLBAREVENTFILTER_H +#define QTMAEMO6SCROLLBAREVENTFILTER_H + +#include +#include +#include + +class QWidget; +class QScrollBar; +class QAbstractScrollArea; +class QSequentialAnimationGroup; + +#define SCROLLAREATHUMBVIEW "scrollAreaThumbView" +#define WIDGET_OPACITY "widgetOpacity" + + +/*! + * this class shows a thumbnail of any other widget placed within an + * scrollarea. It marks the currently visible part in the scrollarea's + * viewport on the thumbnail + */ +class AbstractScrollAreaThumbView : public QLabel +{ + Q_OBJECT +public: + Q_PROPERTY(double opacity READ opacity WRITE setOpacity); + Q_PROPERTY(QRect visibleRect READ visibleRect WRITE setVisibleRect); + + AbstractScrollAreaThumbView(QWidget *parent = NULL); + + /*! + * returns the opacity for the widget + */ + double opacity() const { + return m_opacity; + }; + /*! + * sets the opacity of the widget + * this is used for fade in and fade out effects + */ + void setOpacity(double o) { + m_opacity = o; + }; + + /*! + * returns the rect that describes the visible part of the widget + */ + QRect visibleRect() const { + return m_visibleRect; + }; + + /*! + * sets the current visible rect of the widget + */ + void setVisibleRect(QRect rect) { + m_visibleRect = rect; + }; +protected: + /*! \reimp */ + virtual void paintEvent(QPaintEvent *event); + /*! \reimp_end */ +protected: + QRect m_visibleRect; + double m_opacity; +}; + + +/*! + * this class handles visibility of scrollbars. + * it also cares for the fade effects + */ +class QtMaemo6ScrollBarEventFilter : public QObject +{ + Q_OBJECT +public: + explicit QtMaemo6ScrollBarEventFilter(QObject *parent); + ~QtMaemo6ScrollBarEventFilter(); + + /*! + * enables the effects on the given scrollbars + */ + void enableOn(QObject *o); + + bool scrollBarsAlwaysVisible() const { + return m_scrollBarsAlwaysVisible; + }; + void setScrollBarsAlwaysVisible(bool b) { + m_scrollBarsAlwaysVisible = b; + }; +protected: + + /*! + * This filter filters some events that are needed for correct scrollbar handling + * case QEvent:Move: + * This event is filtered from the widget contained in scrollareas viewport. + * It is used for showing and hiding the scrollbars when scrolling is active. + * case QEvent::Resize: + * This event is filtered from the scrollArea. It's used to manually adjust the + * scrollbars. + */ + bool eventFilter(QObject *obj, QEvent *event); + + /*! + * this updates the visibility of the scrollbar, depending of global settings + * and the scrollrange of the scrollbar + */ + void setScrollBarVisibility(QScrollBar *scrollBar); + + /*! + * Generates the fade in and fade out animation, for QWidget w + * and starts it + * \param w the widget which sould be animated + * \param property the property used to animate the widgets opacity + */ + void fadeInOutAnimation(QWidget *w, const char *property); +protected Q_SLOTS: + /*! + * removes scrollbars from the animations list if the animation is completed + */ + void cleanUpTimerMap(); + + /*! + * places the scrolling preview thumb + */ + void setScrollAreaThumbGeometry(QLabel *label); + + /*! + * this slot is called, if a scrollbars value changed + */ + void scrollBarValueChanged(); + + /*! + * Generates a thumbnail pixmap of the whole scrollarea contents + * and sets the pixmap to the thumbnail label of the scrollarea + * and starts it + * \param scrollArea the scrollArea the thumbnail should be generated for + * \param forceUpdate forces to redraw the cached pixmap + */ + void generateScrollAreaThumb(QAbstractScrollArea *scrollArea, bool forceUpdate = false); + +protected: + enum AnimationState { + FadeIn = 0, + Show = 1, + FadeOut = 2 + }; + + QMap m_pendingAnimations; + bool m_scrollBarsAlwaysVisible; + const int m_scrollAreaThumbnailMaxSize; + const int m_scrollAreaThumbnailOffset; + const int m_scrollAreaThumbnailBorder; + const double m_showScrollAreaThumbnailFactor; +}; + + +#endif //QTMAEMO6SCROLLBAREVENTFILTER_H diff --git a/plainqt/style/qtmaemo6style.cpp b/plainqt/style/qtmaemo6style.cpp new file mode 100644 index 000000000..da4b4c997 --- /dev/null +++ b/plainqt/style/qtmaemo6style.cpp @@ -0,0 +1,2042 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "qtmaemo6style.h" +#include "qtmaemo6style_p.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "qtmaemo6pangesture.h" +#include "qtmaemo6titlebar.h" +#include "qtmaemo6dialogtitle.h" +#include "qtmaemo6windowdecoration.h" +#include "qtmaemo6dialogproxy.h" +#include "qtmaemo6menu.h" + +//#include "duicontainerheader_p.h" + +#define WIDGET_OPACITY "widgetOpacity" +#define SCROLLAREATHUMBVIEW "scrollAreaThumbView" + +//#define MOVE_ACTIONS_FROM_TOOLBAR_TO_TITLEBAR + +QPixmap setPixmapOpacity(const QPixmap &pixmap, double opacity) +{ + //opacity == 1 makes no transparency, so let the pixmap unchanged + if (opacity >= 1.0) + return pixmap; + + QPixmap transparentPixmap(pixmap.size()); + transparentPixmap.fill(Qt::transparent); + + //if the opacity is 0, just return a fully transparent pixmap + if (opacity >= 0.0) { + QPainter painter(&transparentPixmap); + painter.setCompositionMode(QPainter::CompositionMode_Source); + painter.drawPixmap(0, 0, pixmap); + + painter.setCompositionMode(QPainter::CompositionMode_DestinationIn); + painter.fillRect(transparentPixmap.rect(), QColor(0, 0, 0, 255 * opacity)); + painter.end(); + } + return transparentPixmap; +} + +QtMaemo6StylePrivate::QtMaemo6StylePrivate() + : m_actionsInTitleBarCount(5), + m_componentData(0), + m_isDuiInitialized(false), + m_isDuiApplication(false), + m_scrollBarEventFilter(0), + m_panGestureScrolling(0), + m_menuBar(0) +{ +} + +QtMaemo6StylePrivate::~QtMaemo6StylePrivate() +{ + if (!m_isDuiApplication) { + delete m_componentData; + } +} + +void QtMaemo6StylePrivate::initDui() +{ + Q_Q(QtMaemo6Style); + + m_isDuiInitialized = true; + + QStringList args = qApp->arguments(); + + int argc = 1; + char *argv[ 1 ]; + argv[ 0 ] = 0; + + if (! args.isEmpty()) { + //FIXME: using QString would be nicer + argv[ 0 ] = strndup(args[ 0 ].toLocal8Bit().constData(), 42); + + qDebug("appName: %s", argv[ 0 ]); + } + + if (DuiComponentData::instance() != 0) { + m_isDuiApplication = true; + } else { + m_componentData = new DuiComponentData(argc, argv); + } + + m_windowEventFilter = new QtMaemo6StyleEventFilter(q); + m_panGestureScrolling = new QtMaemo6PanGesture(q); + m_scrollBarEventFilter = new QtMaemo6ScrollBarEventFilter(q); + m_scrollBarEventFilter->setScrollBarsAlwaysVisible(false); + m_panGestureScrolling = new QtMaemo6PanGesture(q); + + const DuiLabelStyle *style = + static_cast(duiStyle(QStyle::State_Active, + "DuiLabelStyle")); + qApp->setFont(style->font()); + qApp->setGlobalStrut(QSize(0, 0)); + qApp->setInputContext(QInputContextFactory::create("DuiInputContext", qApp)); +} + +const DuiStyle *QtMaemo6StylePrivate::duiStyle(QStyle::State state, + const QString &styleClass, + const QString &styleObject, + const QString &type, + const DuiWidgetController *parent + ) +{ + // Set mode + QString mode = modeFromState(state); + + return DuiTheme::style(styleClass.toLocal8Bit().constData(), + styleObject.toLocal8Bit().constData(), + mode, type, Dui::Landscape, parent); +} + +QString QtMaemo6StylePrivate::modeFromState(QStyle::State state) +{ + QString mode; + if (state & QStyle::State_Enabled) { + if (state & QStyle::State_Active) + mode = "active"; + if (state & QStyle::State_Sunken || state & QStyle::State_On + || state & QStyle::State_Selected) + mode = "selected"; + } else { + mode = "disabled"; + } + return mode; +} + +void QtMaemo6StylePrivate::drawWindowBackground(QWidget *widget) +{ + if (NULL != widget) { + QStyleOption widgetOption; + widgetOption.initFrom(widget); + + QPixmap backgroundPixmap(widget->size()); + backgroundPixmap.fill(Qt::transparent); + QPainter painter; + painter.begin(&backgroundPixmap); + + if (qobject_cast(widget)) { + const DuiPannableWidgetStyle *style = + static_cast( + QtMaemo6StylePrivate::duiStyle(widgetOption.state, "DuiPannableWidgetStyle", "DuiDialogContentsViewport")); + QtMaemo6StylePrivate::drawWidgetBackground(&painter, &widgetOption, backgroundPixmap.rect(), style); + } else { + const DuiApplicationPageStyle *style = + static_cast( + QtMaemo6StylePrivate::duiStyle(widgetOption.state, "DuiApplicationPageStyle", "")); + QtMaemo6StylePrivate::drawWidgetBackground(&painter, &widgetOption, backgroundPixmap.rect(), style); + } + + painter.end(); + + QPalette palette; + palette.setBrush(widget->backgroundRole(), QBrush(backgroundPixmap)); + widget->setPalette(palette); + } +} + +void QtMaemo6StylePrivate::drawWidgetBackground(QPainter *p, + const QStyleOption *option, + const QRect &rect, + const DuiWidgetStyle *style) +{ + if (style && style->backgroundImage()) { + drawScalableImage(p, option, rect, style->backgroundImage(), style, "bg"); + } +} + +void QtMaemo6StylePrivate::drawScalableImage(QPainter *p, + const QStyleOption *option, + const QRect &rect, + const DuiScalableImage *scalableImage, + const DuiWidgetStyle *style, + const QString &purpose, + bool enableCache) +{ + if (style) { + // draw Background + qreal effectiveOpacity = p->opacity(); + p->setOpacity(style->backgroundOpacity() * effectiveOpacity); + + // This is a cheap hack to enfore synchronous loading + // FIXME: Implement dynamic updating for asynchronous loading + // to get rid of this. + while (DuiTheme::hasPendingRequests()) { + usleep(10000); + QCoreApplication::processEvents(); + } + + if (scalableImage) { + + // Per Widget background image cache implementation + QPixmap backgroundPixmap(rect.size()); + + QPaintDevice *device = p->device(); + QWidget *cachedWidget = dynamic_cast(device); + + QString mode; + if (cachedWidget) { + mode = QtMaemo6StylePrivate::modeFromState(option->state); + } + + quintptr pWidget = reinterpret_cast(device); + quintptr pImage = reinterpret_cast(scalableImage); + + QString cacheKey = QString("%1_2%_%3_%4_%5x%6").arg(pWidget) + .arg(pImage) + .arg(mode) + .arg(purpose) + .arg(rect.width()) + .arg(rect.height()); + + if (!enableCache || !QPixmapCache::find(cacheKey, backgroundPixmap)) { + backgroundPixmap.fill(Qt::transparent); + QPainter pixmapPainter; + pixmapPainter.begin(&backgroundPixmap); + scalableImage->draw(0, 0, rect.width(), rect.height(), &pixmapPainter); + pixmapPainter.end(); + QPixmapCache::insert(cacheKey, backgroundPixmap); + } + + p->drawPixmap(rect, backgroundPixmap); + } else if (style->backgroundColor().isValid()) { + p->fillRect(rect, QBrush(style->backgroundColor())); + } + p->setOpacity(effectiveOpacity); + } +} + +void QtMaemo6StylePrivate::drawSliderBaseBackground(QPainter *p, + const QStyleOption *option, + const QRect &rect, + const DuiSliderStyle *style, + int maxSliderLength) +{ + Q_UNUSED(maxSliderLength); + + p->save(); + if (style) { + if (const QStyleOptionSlider *slider = qstyleoption_cast(option)) { + // draw Background + qreal effectiveOpacity = p->opacity(); + p->setOpacity(style->backgroundOpacity() * effectiveOpacity); + + bool isHorizontal = slider->orientation == Qt::Horizontal; + + //unsued + //int span = ( isHorizontal ) + // ? slider->rect.width() - maxSliderLength + // : slider->rect.height() - maxSliderLength; + + //unused + //int handlePos = sliderPositionFromValue(slider->minimum, + // slider->maximum, + // slider->sliderPosition, + // span, + // slider->upsideDown); + + const DuiScalableImage *baseImage = (isHorizontal) + ? style->backgroundBaseImage() + : style->backgroundVerticalBaseImage(); + + if (baseImage) { + // Per Widget background image cache implementation + QPixmap backgroundPixmap(rect.size()); + + QPaintDevice *device = p->device(); + QWidget *cachedWidget = dynamic_cast(device); + + QString mode; + if (cachedWidget) { + mode = QtMaemo6StylePrivate::modeFromState(option->state); + } + + quintptr pWidget = reinterpret_cast(device); + + QString cacheKey = QString("%1_%2_%3x%4_base").arg(pWidget) + .arg(mode) + .arg(rect.width()) + .arg(rect.height()); + + if (!QPixmapCache::find(cacheKey, backgroundPixmap)) { + backgroundPixmap.fill(Qt::transparent); + QPainter pixmapPainter; + pixmapPainter.begin(&backgroundPixmap); + baseImage->draw(0, 0, rect.width(), rect.height(), &pixmapPainter); + pixmapPainter.end(); + QPixmapCache::insert(cacheKey, backgroundPixmap); + } + p->drawPixmap(rect, backgroundPixmap); + } else if (style->backgroundColor().isValid()) { + p->fillRect(rect, QBrush(style->backgroundColor())); + } + + p->setOpacity(effectiveOpacity); + } + } + p->restore(); +} + +void QtMaemo6StylePrivate::drawBasicButton(QPainter *painter, + const QString &text, + const QIcon &icon, + const QRect &rect, + const QStyleOption *option, + const DuiButtonStyle *style) const +{ + drawBasicButton(painter, text, icon, rect, option, style, style->font(), style->iconSize()); +} + +void QtMaemo6StylePrivate::drawBasicButton(QPainter *p, + const QString &text, + const QIcon &icon, + const QRect &rect, + const QStyleOption *option, + const QString &styleClass, + const QString &styleObject /*= QString()*/) const +{ + const DuiButtonStyle *style = + static_cast(QtMaemo6StylePrivate::duiStyle(option->state, + styleClass.toLocal8Bit().constData(), + styleObject)); + drawBasicButton(p, text, icon, rect, option, style, style->font(), style->iconSize()); + +} + +void QtMaemo6StylePrivate::drawToggleButton(QPainter *p, + const QString &text, + const QIcon &icon, + const QRect &rect, + const QStyleOption *option, + const QString &styleClass, + const QString &styleObject /*= QString()*/) const +{ + const DuiButtonStyle *style = + static_cast(QtMaemo6StylePrivate::duiStyle(option->state, + styleClass.toLocal8Bit().constData(), + styleObject, + "toggle")); + drawBasicButton(p, text, icon, rect, option, style, style->font(), style->iconSize()); +} + +void QtMaemo6StylePrivate::drawCheckBox(QPainter *p, + const QString &text, + const QIcon &icon, + const QRect &rect, + const QStyleOption *option, + const QString &styleClass, + const QString &styleObject /*= QString()*/) const +{ + const DuiCheckboxStyle *style = + static_cast(QtMaemo6StylePrivate::duiStyle(option->state, + styleClass.toLocal8Bit().constData(), + styleObject, + "checkbox")); + // TODO: Fix regression due to introduction of DuiCheckBoxStyle + drawBasicButton(p, text, icon, rect, option, style, style->font(), style->iconSize()); +} + +void QtMaemo6StylePrivate::drawBasicButton(QPainter *p, + const QString &text, + const QIcon &icon, + const QRect &rect, + const QStyleOption *option, + const DuiButtonStyle *style, + const QFont &font, + const QSize &iconSize) const +{ + if (style) { + // draw Background + QtMaemo6StylePrivate::drawWidgetBackground(p, option, rect, style); + + QSize usedIconSize = iconSize.isValid() ? iconSize : style->iconSize(); + + QRect textAndIconRect = getTextAndIconRect(style, text, icon, font, usedIconSize); + + //there is only an icon + if (!icon.isNull() && text.isEmpty()) { + //If the iconsize exceeds the widget's size (maybe fixed- or maximumSize set) + // scale the icon to the widget size. This is only a fallback solution + int paddingLeft, paddingTop, paddingRight, paddingBottom; + paddingFromStyle(style, &paddingLeft, &paddingTop, &paddingRight, &paddingBottom); + + if (usedIconSize.width() > option->rect.width() + || usedIconSize.height() > option->rect.height()) { + QSize maxIconSize = option->rect.size() - + QSize(paddingLeft + paddingRight, + paddingTop + paddingBottom); + usedIconSize.scale(maxIconSize, Qt::KeepAspectRatio); + } + textAndIconRect = option->rect; + } else { + //TODO: is always centered + textAndIconRect.moveTo( + option->rect.left() + (rect.width() - textAndIconRect.width()) / 2, + option->rect.top() + (rect.height() - textAndIconRect.height()) / 2); + } + + if (!icon.isNull()) { + drawButtonIcon(style, p, textAndIconRect, icon, usedIconSize); + + //merge the alignment of icon and text + // if the button is aligned horizontaly to the text, text must be drawn with inverted + // icon's horizontal align and horizontal align of the text + if (hasVerticalAlignment(style->iconAlign())) { + drawButtonText(style, p, textAndIconRect, text, + invertAlignment(verticalAlignment(style->iconAlign())) | style->horizontalTextAlign(), font); + } else if (hasHorizontalAlignment(style->iconAlign())) { + drawButtonText(style, p, textAndIconRect, text, + invertAlignment(horizontalAlignment(style->iconAlign())) | style->verticalTextAlign(), font); + } else { + qDebug("QtMaemo6Style: Button has no text align"); + } + } else { //Text only + drawButtonText(style, p, textAndIconRect, text, style->horizontalTextAlign() | style->verticalTextAlign(), font); + } + } +} + +void QtMaemo6StylePrivate::drawButtonText(const DuiButtonStyle *style, + QPainter *painter, + const QRectF &textRect, + const QString &text, + Qt::Alignment align, + const QFont &font) const +{ + if (text.isEmpty()) + return; + + // update text area by margin + int marginLeft = style->textMarginLeft(); + int marginRight = style->textMarginRight(); + int marginTop = style->textMarginTop(); + int marginBottom = style->textMarginBottom(); + + QRectF rect; + rect.setX(textRect.x() + marginLeft); + rect.setY(textRect.y() + marginTop); + rect.setWidth(textRect.width() - marginLeft - marginRight); + rect.setHeight(textRect.height() - marginTop - marginBottom); + + int alignment = align | Qt::TextHideMnemonic; + + painter->setFont(font); + painter->setPen(style->textColor()); + painter->drawText(rect, alignment, text); +} + +void QtMaemo6StylePrivate::drawButtonText(const DuiButtonStyle *style, + QPainter *painter, + const QRectF &textRect, + const QString &text, + Qt::Alignment align) const +{ + drawButtonText(style, painter, textRect, text, align, style->font()); +} + +void QtMaemo6StylePrivate::drawButtonIcon(const DuiButtonStyle *style, + QPainter *painter, + const QRect &contentsRect, + const QIcon &icon, + const QSize &iconSize /*= QSize()*/) const +{ + Q_Q(const QtMaemo6Style); + QSize usedIconSize = iconSize.isValid() ? iconSize : style->iconSize(); + + //If alignment is only horizontal oder vertical, center in the other direction + Qt::Alignment usedAlign = style->iconAlign(); + if (!hasHorizontalAlignment(usedAlign)) + usedAlign |= Qt::AlignHCenter; + if (!hasVerticalAlignment(usedAlign)) + usedAlign |= Qt::AlignVCenter; + + int paddingLeft, paddingTop, paddingRight, paddingBottom; + paddingFromStyle(style, &paddingLeft, &paddingTop, &paddingRight, &paddingBottom); + + QRect ctRect = contentsRect.translated(paddingLeft, paddingTop); + ctRect.setWidth(ctRect.width() - (paddingLeft + paddingRight)); + ctRect.setHeight(ctRect.height() - (paddingTop + paddingBottom)); + q->drawItemPixmap(painter, ctRect, usedAlign, icon.pixmap(usedIconSize)); +} + +QRect QtMaemo6StylePrivate::getTextAndIconRect(const DuiButtonStyle *style, + const QString &text, + const QIcon &icon /*= QIcon()*/, + const QFont &font /*= QFont()*/, + const QSize &iconSize /*= QSize()*/) const +{ + QRect textAndIconRect; + QRect textRect = textBoundingRect(text, font); + if (!text.isEmpty()) { + textRect.setWidth(textRect.width() + style->textMarginLeft() + style->textMarginRight()); + textRect.setHeight(textRect.height() + style->textMarginTop() + style->textMarginBottom()); + } + QSize usedIconSize = iconSize.isValid() ? iconSize : style->iconSize(); + + if (hasHorizontalAlignment(style->iconAlign())) { + if (!icon.isNull()) { + QRect iconRect = QRect(QPoint(0, 0), usedIconSize); + //TODO: currently the textMarginLeft is used as space between icon and text + textAndIconRect = iconRect | textRect.translated(iconRect.width(), 0); + //if the alignment is left -> calc with textMarginLeft + //if the alignment is right -> calc with textMarginRight + } else { + textAndIconRect = textRect; + } + } else { + if (!icon.isNull()) { + QRect iconRect = QRect(QPoint(0, 0), usedIconSize); + //TODO: currently the textMarginLeft is used as space between icon and text + textAndIconRect = iconRect | textRect.translated(0, iconRect.height()); + //if the alignment is top -> calc with textMarginTop + //if the alignment is bottom -> calc with textMarginBottom + } else { + textAndIconRect = textRect; + } + } + + int paddingLeft, paddingTop, paddingRight, paddingBottom; + paddingFromStyle(style, &paddingLeft, &paddingTop, &paddingRight, &paddingBottom); + + //add margins to the final rect + textAndIconRect = QRect(textAndIconRect.x(), textAndIconRect.y(), + textAndIconRect.width() + paddingLeft + paddingRight, + textAndIconRect.height() + paddingTop + paddingBottom); + + return textAndIconRect; +} + +QRect QtMaemo6StylePrivate::textBoundingRect(const QString &text, const QFont &font) const +{ + QRect rect = QFontMetrics(font).boundingRect(text); + return QRect(QPoint(0, 0), QSize(rect.x() + rect.width(), rect.height())); +} + +void QtMaemo6StylePrivate::paddingFromStyle(const DuiWidgetStyle *style, + int *left, + int *top, + int *right, + int *bottom) const +{ + style->backgroundImage()->borders(left, right, top, bottom); + if (left && style->paddingLeft() > *left) + *left = style->paddingLeft(); + if (top && style->paddingTop() > *top) + *top = style->paddingTop(); + if (right && style->paddingRight() > *right) + *right = style->paddingRight(); + if (bottom && style->paddingBottom() > *bottom) + *bottom = style->paddingBottom(); +} + +QRect QtMaemo6StylePrivate::scrollBarSliderRect(const QStyleOptionComplex *option, + const QWidget *widget /*= 0*/) const +{ + Q_Q(const QtMaemo6Style); + if (const QStyleOptionSlider *scrollBar = qstyleoption_cast(option)) { + int sliderMaxLength = (scrollBar->orientation == Qt::Horizontal) ? + scrollBar->rect.width() : scrollBar->rect.height(); + int sliderMinLength = q->proxy()->pixelMetric(QStyle::PM_ScrollBarSliderMin, scrollBar, widget); + int sliderLength; + + // calculate slider length + if (scrollBar->maximum != scrollBar->minimum) { + uint valueRange = scrollBar->maximum - scrollBar->minimum; + sliderLength = (scrollBar->pageStep * sliderMaxLength) / (valueRange + scrollBar->pageStep); + + if (sliderLength < sliderMinLength || valueRange > INT_MAX / 2) + sliderLength = sliderMinLength; + if (sliderLength > sliderMaxLength) + sliderLength = sliderMaxLength; + } else { + sliderLength = sliderMaxLength; + } + + int sliderStart = q->sliderPositionFromValue(scrollBar->minimum, + scrollBar->maximum, + scrollBar->sliderPosition, + sliderMaxLength - sliderLength, + scrollBar->upsideDown); + + QRect scrollBarRect = scrollBar->rect; + QRect rect; + if (scrollBar->orientation == Qt::Horizontal) { + rect.setRect(sliderStart, 0, sliderLength, scrollBarRect.height()); + } else { + rect.setRect(0, sliderStart, scrollBarRect.width(), sliderLength); + } + + return q->visualRect(scrollBar->direction, scrollBarRect, rect); + } + return QRect(); +} + +Qt::Alignment QtMaemo6StylePrivate::invertAlignment(Qt::Alignment align) const +{ + Qt::Alignment retAlign; + //invert horizontal alignment + if (align.testFlag(Qt::AlignLeft)) + retAlign = Qt::AlignRight; + else if (align.testFlag(Qt::AlignRight)) + retAlign = Qt::AlignLeft; + else if (align.testFlag(Qt::AlignHCenter)) + retAlign = Qt::AlignHCenter; + + //invert vertical alignment + if (align.testFlag(Qt::AlignTop)) + retAlign |= Qt::AlignBottom; + else if (align.testFlag(Qt::AlignBottom)) + retAlign = Qt::AlignTop; + else if (align.testFlag(Qt::AlignVCenter)) + retAlign = Qt::AlignVCenter; + + return retAlign; +} + + +QtMaemo6Style::QtMaemo6Style() + : QtMaemo6TestStyle(*new QtMaemo6StylePrivate) +{ + init(); +} + +QtMaemo6Style::~QtMaemo6Style() +{ + +} + +void QtMaemo6Style::init() +{ +// QPixmapCache::setCacheLimit( 1000 ); +} + + + + +void QtMaemo6Style::polish(QApplication *app) +{ + QtMaemo6TestStyle::polish(app); +} + +void QtMaemo6Style::polish(QWidget *widget) +{ + Q_D(QtMaemo6Style); + // Lazy initialization of the DuiFramework. + // This is needed to guarantee that actual DuiApplications will work as well. + if (!d->m_isDuiInitialized) { + d->initDui(); + } + + //Ensure that the widget draws its background transparent + if (!qobject_cast(widget) + && !qobject_cast(widget) + && !qobject_cast(widget)) { + //FIXME: public API usage + QPalette pal = widget->palette(); + pal.setBrush(QPalette::Window, Qt::transparent); + widget->setPalette(pal); + } + + widget->installEventFilter(d->m_windowEventFilter); + +#ifdef MOVE_ACTIONS_FROM_TOOLBAR_TO_TITLEBAR + if (QtMaemo6TitleBar *titleBar = qobject_cast(widget)) { + foreach(QAction * action, d->m_toolBarActions) { + titleBar->addAction(action); + } + } + + QToolBar *toolBar = qobject_cast(widget); + if (toolBar && qobject_cast(widget->parent())) { + foreach(QAction * action, toolBar->actions()) { + if (d->m_toolBarActions.count() < d->m_actionsInTitleBarCount) { + d->m_toolBarActions.append(action); + toolBar->removeAction(action); + } else + break; + } + if (toolBar->actions().isEmpty()) { + QMainWindow *mw = qobject_cast(widget->parent()); + mw->removeToolBar(toolBar); + } + } +#endif + + if (qobject_cast(widget)) { + //FIXME: public API usage + widget->setAttribute(Qt::WA_OpaquePaintEvent, false); + d->m_scrollBarEventFilter->enableOn(widget); + } + + if (QAbstractScrollArea *abstractScrollArea = qobject_cast(widget)) { + d->m_panGestureScrolling->enableOn(abstractScrollArea); + d->m_scrollBarEventFilter->enableOn(abstractScrollArea); + //FIXME: public API usage + //widget->setAutoFillBackground(false); + + //must use inherits() because it's an private Qt class + if (!abstractScrollArea->inherits("QComboBoxListView")) { + //don't do this for QComboBoxListView, because it uses the QItemDelegate + //which not uses the style + QPalette pal = abstractScrollArea->viewport()->palette(); + pal.setBrush(QPalette::Base, Qt::transparent); + abstractScrollArea->viewport()->setPalette(pal); + } else { + //this must be set for ComboBox DropDowns, don't know why! + QPalette pal = abstractScrollArea->viewport()->palette(); + pal.setBrush(QPalette::Base, Qt::white); + abstractScrollArea->viewport()->setPalette(pal); + } + } + + if (QStatusBar *statusBar = qobject_cast(widget)) { + //only use statusbars directly from MainWindow + if (qobject_cast(statusBar->parent())) { + //FIXME: add handling here for not showing empty statusbars + d->m_statusBar = statusBar; + } + //FIXME: Public API usage + statusBar->setSizeGripEnabled(false); + } + + if (QMenuBar *menuBar = qobject_cast(widget)) { + //Only take the menubar from the main window + //TODO: this doesn't work for applications that use shared menuBars, like eg. some + // mac applications do. + if (menuBar->parent()) { + if (qobject_cast(menuBar->parent())) { + d->m_menuBar = menuBar; + //do not remove the menuBar from the mainWindow, it may be changed + //by the user + } + } + } + + if (QtMaemo6WindowDecoration *decoration = qobject_cast(widget)) { + if (d->m_statusBar) + decoration->setStatusBar(d->m_statusBar); + if (d->m_menuBar) + decoration->setMenuBar(d->m_menuBar); + } +} + +void QtMaemo6Style::drawPrimitive(PrimitiveElement element, + const QStyleOption *option, + QPainter *painter, + const QWidget *widget) const +{ + Q_D(const QtMaemo6Style); + + switch (element) { + case PE_Widget: { + if (qobject_cast(widget)) { + const DuiNavigationBarStyle *style = + static_cast(QtMaemo6StylePrivate::duiStyle(option->state, + "DuiNavigationBarStyle")); + // draw widget background + d->drawWidgetBackground(painter, option, widget->rect(), style); + + } + if (qobject_cast(widget)) { + const DuiWidgetStyle *style = + static_cast( + QtMaemo6StylePrivate::duiStyle(option->state, "DuiWidgetStyle", "DuiDialogTitleBar")); + // draw widget background + d->drawWidgetBackground(painter, option, widget->rect(), style); + + } + if (qobject_cast(widget)) { + const DuiApplicationMenuStyle *style = + static_cast( + QtMaemo6StylePrivate::duiStyle(option->state, "DuiApplicationMenuStyle")); + // draw widget background + d->drawScalableImage(painter, option, widget->rect(), style->canvasImage(), style, "canvas-image"); + //d->drawWidgetBackground( painter, option, widget->rect(), style ); + } + } + break; + + case PE_PanelLineEdit: { + if (const QStyleOptionFrame *panel = qstyleoption_cast(option)) { + + const DuiTextEditStyle *style = + static_cast(QtMaemo6StylePrivate::duiStyle(panel->state, + "DuiTextEditStyle")); + QtMaemo6StylePrivate::drawWidgetBackground(painter, option, panel->rect, style); + } + } + break; + case PE_PanelItemViewItem: { //draw the background of ItemViewItems + if (const QStyleOptionViewItemV4 *item = qstyleoption_cast(option)) { + const DuiContentItemStyle *style = + static_cast(QtMaemo6StylePrivate::duiStyle(item->state, + "DuiContentItemStyle")); + const QAbstractItemModel *model = item->index.model(); + + //it's a simple Listview + if (model->columnCount() == 1) { + if (model->rowCount() == 1) { + d->drawScalableImage(painter, option, item->rect, style->backgroundImageSingle(), style); + } else if (item->index.row() == 0) { + d->drawScalableImage(painter, option, item->rect, style->backgroundImageSinglecolumnTop(), style); + } else if (item->index.row() == model->rowCount() - 1) { + d->drawScalableImage(painter, option, item->rect, style->backgroundImageSinglecolumnBottom(), style); + } else { + d->drawScalableImage(painter, option, item->rect, style->backgroundImageSinglecolumnCenter(), style); + } + } else { + //TODO: Add implementation for tableviews here + QtMaemo6TestStyle::drawPrimitive(element, option, painter, widget); + if (model->rowCount() == 1) { + if (item->index.column() == 0) { + d->drawScalableImage(painter, option, item->rect, style->backgroundImageSinglerowLeft(), style); + } else if (item->index.column() == model->columnCount() - 1) { + d->drawScalableImage(painter, option, item->rect, style->backgroundImageSinglerowRight(), style); + } else { + d->drawScalableImage(painter, option, item->rect, style->backgroundImageSinglerowCenter(), style); + } + } else if (item->index.row() == 0) { + if (item->index.column() == 0) { + d->drawScalableImage(painter, option, item->rect, style->backgroundImageTopLeft(), style); + } else if (item->index.column() == model->columnCount() - 1) { + d->drawScalableImage(painter, option, item->rect, style->backgroundImageTopRight(), style); + } else { + d->drawScalableImage(painter, option, item->rect, style->backgroundImageTop(), style); + } + } else if (item->index.row() == model->rowCount() - 1) { + if (item->index.column() == 0) { + d->drawScalableImage(painter, option, item->rect, style->backgroundImageBottomLeft(), style); + } else if (item->index.column() == model->columnCount() - 1) { + d->drawScalableImage(painter, option, item->rect, style->backgroundImageBottomRight(), style); + } else { + d->drawScalableImage(painter, option, item->rect, style->backgroundImageBottom(), style); + } + } else { + if (item->index.column() == 0) { + d->drawScalableImage(painter, option, item->rect, style->backgroundImageLeft(), style); + } else if (item->index.column() == model->columnCount() - 1) { + d->drawScalableImage(painter, option, item->rect, style->backgroundImageRight(), style); + } else { + d->drawScalableImage(painter, option, item->rect, style->backgroundImageCenter(), style); + } + } + } + + } + } + break; + case PE_IndicatorBranch: { + QtMaemo6TestStyle::drawPrimitive(element, option, painter, widget); + if (option->state.testFlag(QStyle::State_Children)) { + QToolButton button; + QStyleOptionToolButton buttonOption; + buttonOption.initFrom(&button); + buttonOption.rect = option->rect; + if (option->state.testFlag(QStyle::State_Open)) { + buttonOption.text = '-'; + } else { + buttonOption.text = '+'; + } + + QSize size = sizeFromContents(QStyle::CT_ToolButton, &buttonOption, QSize(), &button); + + QRect buttonRect = QRect(option->rect.left() + (option->rect.width() - size.width()) / 2, + option->rect.top() + (option->rect.height() - size.height()) / 2, + size.width(), size.height()); + buttonOption.rect = buttonRect; + + drawComplexControl(QStyle::CC_ToolButton, &buttonOption, painter, &button); + } + } + break; + case PE_Frame: { + //don't draw the frame for item views, this is done by the items themselfs + if (qobject_cast(widget)) { + } else + QtMaemo6TestStyle::drawPrimitive(element, option, painter, widget); + } + break; + case PE_FrameFocusRect: { + //The focus rect of selected items in AbstractItemViews + //don't draw anything here + } + default: { + QtMaemo6TestStyle::drawPrimitive(element, option, painter, widget); + } + break; + } + +} + + +void QtMaemo6Style::drawControl(ControlElement element, + const QStyleOption *opt, + QPainter *p, + const QWidget *widget) const +{ + Q_D(const QtMaemo6Style); + + switch (element) { + case CE_ComboBoxLabel: { + if (const QStyleOptionComboBox *cmb = qstyleoption_cast(opt)) { + + QStyleOptionComboBox subopt = *cmb; + subopt.palette = QPalette(Qt::black); + + //const DuiComboBoxStyle * style = + // static_cast( QtMaemo6StylePrivate::duiStyle( cmb->state, + // "DuiComboBoxStyle", "DuiComboBoxTitle" ) ); +// Not implemented yet on the DUI side + /* + p->setFont( style->font() ); + p->setPen( QPen( style->color() ) ); + */ + QtMaemo6TestStyle::drawControl(element, cmb, p, widget); + } + } + break; + case CE_PushButton: { + if (const QStyleOptionButton *btn = qstyleoption_cast(opt)) { + + QStyleOptionButton subopt = *btn; + subopt.rect = subElementRect(SE_PushButtonContents, btn, widget); + + const QAbstractButton *buttonWidget = qobject_cast(widget); + if (buttonWidget->isCheckable()) + d->drawToggleButton(p, subopt.text, subopt.icon, subopt.rect, opt, "DuiButtonIconStyle"); + else + d->drawBasicButton(p, subopt.text, subopt.icon, subopt.rect, opt, "DuiButtonIconStyle"); + } + } + break; + + case CE_ProgressBar: { + if (const QStyleOptionProgressBar * pb + = qstyleoption_cast(opt)) { + QStyleOptionProgressBarV2 subopt = *pb; + subopt.rect = subElementRect(SE_ProgressBarGroove, pb, widget); + proxy()->drawControl(CE_ProgressBarGroove, &subopt, p, widget); + subopt.rect = subElementRect(SE_ProgressBarContents, pb, widget); + proxy()->drawControl(CE_ProgressBarContents, &subopt, p, widget); + } + } + break; + + case CE_RadioButton: + case CE_CheckBox: { + if (const QStyleOptionButton *btn = qstyleoption_cast(opt)) { + + bool isCheckBox = (element == CE_CheckBox); + + QStyleOptionButton subopt = *btn; + subopt.rect = subElementRect(isCheckBox ? SE_CheckBoxIndicator + : SE_RadioButtonIndicator, + btn, widget); + + d->drawCheckBox(p, QString(), subopt.icon, subopt.rect, opt, "DuiButtonStyle"); + + subopt.rect = subElementRect(isCheckBox ? SE_CheckBoxContents + : SE_RadioButtonContents, + btn, widget); + + proxy()->drawControl(isCheckBox ? CE_CheckBoxLabel + : CE_RadioButtonLabel, + &subopt, p, widget); + } + break; + } + case CE_TabBarTabShape: { + if (const QStyleOptionTab *tab = qstyleoption_cast(opt)) { + + QStyleOptionButton btn; + btn.initFrom(widget); + btn.rect = tab->rect; + btn.state = tab->state; + + const DuiButtonStyle *style = + static_cast(QtMaemo6StylePrivate::duiStyle(opt->state, + "DuiButtonIconStyle")); + // Don't show the edge of the button that is closest to the + // TabBarBase. + // FIXME: Solve for other tab bar orientations + if (style) { + int left, right, top, bottom; + style->backgroundImage()->borders(&left, &right, &top, &bottom); + + qreal cutOff = 0; + qreal origSize = 0; + + const QPixmap *pixmap = style->backgroundImage()->pixmap(); + if (pixmap) { + int buttonHeight = btn.rect.height(); + int buttonWidth = btn.rect.width(); + + switch (tab->shape) { + case QTabBar::RoundedNorth: + case QTabBar::TriangularNorth: + cutOff = bottom; + origSize = pixmap->height(); + btn.rect.setHeight(buttonHeight * origSize / (origSize - cutOff)); + break; + + case QTabBar::RoundedSouth: + case QTabBar::TriangularSouth: + cutOff = top; + origSize = pixmap->height(); + btn.rect.setTop(-buttonHeight * cutOff / origSize); + btn.rect.setHeight(buttonHeight * origSize / (origSize - cutOff)); + break; + + case QTabBar::RoundedWest: + case QTabBar::TriangularWest: + cutOff = right; + origSize = pixmap->width(); + btn.rect.setWidth(buttonWidth * origSize / (origSize - cutOff)); + break; + + case QTabBar::RoundedEast: + case QTabBar::TriangularEast: + cutOff = left; + origSize = pixmap->width(); + btn.rect.setLeft(-buttonWidth * cutOff / origSize); + btn.rect.setWidth(buttonWidth * origSize / (origSize - cutOff)); + break; + + default: + break; + } + } + } + + d->drawBasicButton(p, + QString() /*tab->text*/, + QIcon() /*tab->icon*/, + btn.rect, &btn, "DuiButtonIconStyle"); + } + break; + } + case CE_ToolBar: { + //const QToolBar* toolBar = qobject_cast(widget); + if (widget->actions().count() > 0) + QtMaemo6TestStyle::drawControl(element, opt, p, widget); + break; + } + case CE_ProgressBarGroove: { + if (const QStyleOptionProgressBar *bar = qstyleoption_cast(opt)) { + const DuiProgressIndicatorStyle *style = + static_cast(QtMaemo6StylePrivate::duiStyle(bar->state, + "DuiProgressIndicatorStyle", QString(), "bar")); + if (style && style->inactiveImage()) + d->drawScalableImage(p, opt, bar->rect, style->inactiveImage(), style, "groove"); + } + break; + } + case CE_ProgressBarContents: { + + if (const QStyleOptionProgressBar *bar = qstyleoption_cast(opt)) { + const DuiProgressIndicatorStyle *style = + static_cast(QtMaemo6StylePrivate::duiStyle(bar->state, + "DuiProgressIndicatorStyle", QString(), "bar")); + if (style && style->activeImage()) { + + bool reverse = qApp->isRightToLeft(); + + QRect r(bar->rect); + + int left, right; + style->activeImage()->borders(&left, &right, NULL, NULL); + + qreal position = (qreal)(bar->progress - bar->minimum) / (qreal)(bar->maximum - bar->minimum); + qreal distance = position * (qreal) r.width(); + + // need to draw in 1 or 2 parts, depending if the indicator element goes across the ends + // one draw call + if (!reverse) { + r.setLeft(0); + r.setRight(distance); + } else { + r.setRight(r.width()); + r.setLeft(r.width() - distance); + } + d->drawScalableImage(p, opt, r, style->activeImage(), style, "contents", false); + } + } + break; + } + case CE_ScrollBarAddLine: + case CE_ScrollBarSubLine: + case CE_ScrollBarAddPage: + case CE_ScrollBarSubPage: + case CE_ScrollBarFirst: + case CE_ScrollBarLast: + //QtMaemo6TestStyle::drawControl(element, opt, p, widget); + //these cases do not occur + break; + case CE_ScrollBarSlider: { + if (const QStyleOptionSlider *slider = qstyleoption_cast(opt)) { + const DuiPositionIndicatorStyle *style = + static_cast(QtMaemo6StylePrivate::duiStyle(slider->state, + "DuiPositionIndicatorStyle")); + + d->drawWidgetBackground(p, opt, slider->rect, style); + + const QPixmap *railDotPixmap = style->offPixmap(); + const QPixmap *railDotPlayedPixmap = style->onPixmap(); + QSize maxRailDotSize = + (railDotPixmap->size()).expandedTo(railDotPlayedPixmap->size()); + + int sliderLength = slider->orientation == Qt::Horizontal ? slider->rect.width() : slider->rect.height(); + int railDotSize = slider->orientation == Qt::Horizontal ? maxRailDotSize.width() : maxRailDotSize.height(); + + int dotCount = sliderLength / (railDotSize + style->pixmapDistance()); + int offset = (sliderLength - (dotCount * (railDotSize + style->pixmapDistance()) - style->pixmapDistance())) / 2; + + //calculating the slider size, and position within the groove + //QRect scSliderRect = subControlRect(CC_ScrollBar, slider, SC_ScrollBarSlider, widget); + QRect scSliderRect = subControlRect(CC_ScrollBar, slider, SC_ScrollBarSlider, widget); + + int sliderStart, sliderEnd; + if (slider->orientation == Qt::Horizontal) { + sliderStart = scSliderRect.x(); + sliderEnd = scSliderRect.x() + scSliderRect.width(); + } else { + sliderStart = scSliderRect.y(); + sliderEnd = scSliderRect.y() + scSliderRect.height(); + } + int grooveLength = sliderEnd - sliderStart; + + int grooveDotCount = qRound((qreal)grooveLength * (qreal)dotCount / (qreal)sliderLength); + int sliderDotsSubPage = qRound((qreal)sliderStart * (qreal)dotCount / (qreal)sliderLength); + //int sliderDotsAddPage = dotCount - (grooveDotCount + sliderDotsSubPage); + + //make copies of the pixmaps to avoid doing the transparency within the loop + QPixmap railDotPixmapAlpha(*railDotPixmap); + QPixmap railDotPlayedPixmapAlpha(*railDotPlayedPixmap); + if (widget->dynamicPropertyNames().contains(WIDGET_OPACITY)) { + double opacity = widget->property(WIDGET_OPACITY).toDouble(); + + railDotPixmapAlpha = setPixmapOpacity(railDotPixmapAlpha, opacity); + railDotPlayedPixmapAlpha = setPixmapOpacity(railDotPlayedPixmapAlpha, opacity); + } + + for (int i = 0; i < dotCount; ++i) { + QPixmap *pm = i < sliderDotsSubPage || i >= sliderDotsSubPage + grooveDotCount + ? &railDotPixmapAlpha : &railDotPlayedPixmapAlpha; + + if (slider->orientation == Qt::Horizontal) + p->drawPixmap(QPoint(offset, 0), *pm); + else + p->drawPixmap(QPoint(0, offset), *pm); + offset += railDotSize + style->pixmapDistance(); + } + } + } + break; + case CE_ItemViewItem: { + if (const QStyleOptionViewItemV4 *item = qstyleoption_cast(opt)) { + proxy()->drawPrimitive(PE_PanelItemViewItem, opt, p, widget); + const DuiContentItemStyle *style = + static_cast(QtMaemo6StylePrivate::duiStyle(item->state, + "DuiContentItemStyle")); + const DuiLabelStyle *labelTitle = + static_cast(QtMaemo6StylePrivate::duiStyle(item->state, + "DuiLabelStyle", style->titleObjectName())); + //subtitles for list view items are currently not supported by qt. + //const DuiLabelStyle* labelSubTitle = + // static_cast( QtMaemo6StylePrivate::duiStyle( item->state, + // "DuiLabelStyle", style->subtitleObjectName() ) ); + const DuiImageWidgetStyle *labelIcon = + static_cast(QtMaemo6StylePrivate::duiStyle(item->state, + "DuiImageWidgetStyle", style->imageObjectName())); + + QString itemText = qvariant_cast(item->index.data(Qt::DisplayRole)); + QIcon itemIcon = qvariant_cast(item->index.data(Qt::DecorationRole)); + + QRect rect = item->rect; + + if (!itemIcon.isNull()) { + rect.setTop(rect.top() + labelIcon->marginTop()); + rect.setLeft(rect.left() + labelIcon->marginLeft()); + p->drawPixmap(rect.topLeft(), itemIcon.pixmap(labelIcon->preferredSize())); + rect.setLeft(rect.left() + labelIcon->preferredSize().width() + labelIcon->marginRight()); + } + + rect.setLeft(rect.left() + labelTitle->marginLeft()); + QFont labelFont = labelTitle->font(); + + p->setFont(labelFont); + p->setPen(labelTitle->color()); + + p->drawText(rect, itemText, QTextOption(Qt::AlignLeft | Qt::AlignTop)); + } + } + break; + default: { + QtMaemo6TestStyle::drawControl(element, opt, p, widget); + } + break; + } +} + +void QtMaemo6Style::drawComplexControl(ComplexControl control, + const QStyleOptionComplex *opt, + QPainter *p, + const QWidget *widget /*= 0*/) const +{ + Q_D(const QtMaemo6Style); + switch (control) { + case CC_ComboBox: { + if (const QStyleOptionComboBox *cmb = qstyleoption_cast(opt)) { + + const DuiComboBoxStyle *style = + static_cast(QtMaemo6StylePrivate::duiStyle(cmb->state, + "DuiComboBoxStyle")); + d->drawWidgetBackground(p, opt, cmb->rect, style); + } + } + break; + + case CC_ToolButton: { + QWidget *parentOfControl = widget->parentWidget(); + + if (const QStyleOptionToolButton *btn = qstyleoption_cast(opt)) { + QStyleOptionToolButton subopt = *btn; + subopt.rect = subControlRect(control, opt, SC_ToolButton, widget); + + //a ToolButton on a ToolBar + if (qobject_cast(parentOfControl)) { + QtMaemo6TestStyle::drawComplexControl(control, opt, p, widget); + //a ToolButton on the DuiTitleBar + } else if (qobject_cast(parentOfControl)) { + QtMaemo6TestStyle::drawComplexControl(control, opt, p, widget); + //a ToolButton anywhere else on the Screen should be drawn like a PushButton + } else { + const DuiButtonStyle *style = + static_cast(QtMaemo6StylePrivate::duiStyle(subopt.state, "DuiButtonIconStyle", "")); + const DuiButtonStyle *styleFont = + static_cast(QtMaemo6StylePrivate::duiStyle(subopt.state, "DuiButtonIconStyle", + "NavigationBarToolBarButton")); + + qDebug("Button \"%s\" font-size: %d, icon-size: %d", subopt.text.toLocal8Bit().constData(), + styleFont->font().pixelSize(), styleFont->iconSize().width()); + + d->drawBasicButton(p, subopt.text, subopt.icon, subopt.rect, opt, style, styleFont->font(), styleFont->iconSize()); + } + } + } + break; + + case CC_Slider: { + p->save(); + if (const QStyleOptionSlider *slider = qstyleoption_cast(opt)) { + const DuiSliderStyle *style = + static_cast(QtMaemo6StylePrivate::duiStyle(slider->state, + "DuiSliderStyle")); + + // draw widget background + d->drawWidgetBackground(p, opt, widget->rect(), style); + + // draw groove + bool isHorizontal = slider->orientation == Qt::Horizontal; + + QRect grooveArea = proxy()->subControlRect(CC_Slider, opt, + SC_SliderGroove, + widget); + + int maxSliderLength = proxy()->pixelMetric(PM_SliderLength, + slider, widget); + int grooveThickness = style->grooveThickness(); + + QRect grooveRect; + if (isHorizontal) { + grooveRect = grooveArea.adjusted(maxSliderLength / 2, + (grooveArea.height() - grooveThickness) / 2, + - maxSliderLength / 2, + - (grooveArea.height() - grooveThickness) / 2); + } else { + grooveRect = grooveArea.adjusted((grooveArea.width() - grooveThickness) / 2, + maxSliderLength / 2, + - (grooveArea.width() - grooveThickness) / 2, + - maxSliderLength / 2); + } + + QtMaemo6StylePrivate::drawSliderBaseBackground(p, opt, grooveRect, style, maxSliderLength); + + // Handle + QPixmap handlePixmap; + + if (isHorizontal) { + const QPixmap *handleSourcePixmap = + (slider->state & State_Sunken) + ? style->handlePressedPixmap() + : style->handlePixmap(); + handlePixmap = *handleSourcePixmap; + } else { + const QPixmap *handleSourcePixmap = + (slider->state & State_Sunken) + ? style->handleVerticalPressedPixmap() + : style->handleVerticalPixmap(); + handlePixmap = *handleSourcePixmap; + } + + QRect handleRect = proxy()->subControlRect(CC_Slider, opt, + SC_SliderHandle, + widget); + p->drawPixmap(handleRect, handlePixmap); + } + p->restore(); + } + break; + case CC_ScrollBar: { + drawControl(CE_ScrollBarSlider, opt, p, widget); + } + break; + case CC_GroupBox: { + if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast(opt)) { + const DuiContainerStyle *groupBoxStyle = + static_cast(QtMaemo6StylePrivate::duiStyle(groupBox->state, + "DuiContainerStyle")); + //causes problems because requires to include a private header file + //DuiContainerHeader containerHeaderLabel; + //const DuiLabelStyle * headerLabelStyle = + // static_cast( QtMaemo6StylePrivate::duiStyle( groupBox->state, + // "DuiLabelStyle", "", "", &containerHeaderLabel ) ); + + const DuiLabelStyle *headerStyle = + static_cast(QtMaemo6StylePrivate::duiStyle(groupBox->state, + "DuiContainerHeaderStyle")); + + const DuiSeparatorStyle *separatorStyle = + static_cast(QtMaemo6StylePrivate::duiStyle(groupBox->state, + "DuiSeparatorStyle")); + + QRect headerTextRect = proxy()->subControlRect(CC_GroupBox, opt, SC_GroupBoxLabel, widget); + QRect checkBoxRect = proxy()->subControlRect(CC_GroupBox, opt, SC_GroupBoxCheckBox, widget); + + int headMarginLeft = headerStyle->paddingLeft() + + headerStyle->marginLeft(); + int headMarginRight = headerStyle->paddingRight() + + headerStyle->marginRight(); + int headMarginBottom = headerStyle->paddingBottom() + + headerStyle->marginBottom() + + 4; // Make it look good fix (while the header text padding in duicontainer is broken) + + QRect unitedRect = headerTextRect.united(checkBoxRect); + int headerBottom = unitedRect.bottom() + headMarginBottom; + + int sepMarginLeft = separatorStyle->marginLeft() + separatorStyle->paddingLeft(); + int sepMarginRight = separatorStyle->marginRight() + separatorStyle->paddingRight(); + int sepMarginTop = separatorStyle->marginTop() + separatorStyle->paddingTop(); + + QRect separatorRect(groupBox->rect.left() + sepMarginLeft, + headerBottom + sepMarginTop, + groupBox->rect.width() + - headMarginLeft - headMarginRight + - sepMarginLeft - sepMarginRight, + separatorStyle->span()); + + // Draw frame + // Draw widget background + QRect headerRect = widget->rect(); + headerRect.setBottom(headerBottom); + QRect containerRect = widget->rect(); + containerRect.adjust(0, headerRect.height(), 0, 0); + + d->drawWidgetBackground(p, groupBox, headerRect, headerStyle); + d->drawWidgetBackground(p, groupBox, containerRect, groupBoxStyle); +// drawWidgetBackground( p, groupBox, separatorRect, separatorStyle ); + + // Draw title + if ((groupBox->subControls & QStyle::SC_GroupBoxLabel) && !groupBox->text.isEmpty()) { + + QColor headerColor = Qt::black; //FIXME: = headerLabelStyle->color(); + if (headerColor.isValid()) { + p->setPen(headerColor); + } + + int alignment = int(groupBox->textAlignment); + if (!proxy()->styleHint(QStyle::SH_UnderlineShortcut, opt, widget)) + alignment |= Qt::TextHideMnemonic; + + p->drawText(headerTextRect, Qt::TextShowMnemonic | Qt::AlignHCenter | alignment, + groupBox->text); + } + + // Draw checkbox + if (groupBox->subControls & SC_GroupBoxCheckBox) { + d->drawCheckBox(p, QString(), QIcon(), checkBoxRect, + groupBox, "DuiButtonIconStyle"); + } + + } + } + break; + default: { + QtMaemo6TestStyle::drawComplexControl(control, opt, p, widget); + } + break; + } +} + +QRect QtMaemo6Style::subControlRect(ComplexControl control, + const QStyleOptionComplex *option, + SubControl subControl, + const QWidget *widget /*= 0*/) const +{ + Q_D(const QtMaemo6Style); + + if (!d->m_isDuiInitialized) { + return QRect(); + } + + switch (control) { + case CC_ToolButton: { + } + break; + + case CC_Slider: { + if (const QStyleOptionSlider *slider = qstyleoption_cast(option)) { + int maxSliderThickness = proxy()->pixelMetric(PM_SliderControlThickness, slider, widget); + int maxSliderLength = proxy()->pixelMetric(PM_SliderLength, slider, widget); + bool isHorizontal = (slider->orientation == Qt::Horizontal); + + switch (subControl) { + case SC_SliderHandle: { + int span = (isHorizontal) + ? slider->rect.width() - maxSliderLength + : slider->rect.height() - maxSliderLength; + + int handlePos = sliderPositionFromValue(slider->minimum, + slider->maximum, + slider->sliderPosition, + span, + slider->upsideDown); + if (isHorizontal) + return QRect(slider->rect.x() + handlePos, + slider->rect.y(), + maxSliderLength, + maxSliderThickness); + else + return QRect(slider->rect.x(), + slider->rect.y() + handlePos, + maxSliderThickness, + maxSliderLength); + } + break; + case SC_SliderGroove: { + if (isHorizontal) + return QRect(slider->rect.x(), + slider->rect.y(), + slider->rect.width(), + maxSliderThickness); + else + return QRect(slider->rect.x(), + slider->rect.y(), + maxSliderThickness, + slider->rect.height()); + } + break; + default: + break; + } + } + } + break; + + case CC_ScrollBar: { + if (subControl == SC_ScrollBarSlider) + return d->scrollBarSliderRect(option, widget); + break; + } + case CC_GroupBox: { + if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast(option)) { + switch (subControl) { + case SC_GroupBoxFrame: + // Fall Through + case SC_GroupBoxContents: { + QRect contentsRect; + + const DuiLabelStyle *headerStyle = + static_cast(QtMaemo6StylePrivate::duiStyle(groupBox->state, + "DuiLabelStyle", + "DuiContainerTitle")); + + QFont headerFont = headerStyle->font(); + QFontMetrics fontMetrics(headerFont); + int height = fontMetrics.height(); + + const DuiContainerStyle *groupBoxStyle = + static_cast(QtMaemo6StylePrivate::duiStyle(groupBox->state, + "DuiContainerStyle")); + const DuiSeparatorStyle *separatorStyle = + static_cast(QtMaemo6StylePrivate::duiStyle(groupBox->state, + "DuiSeparatorStyle")); + + int sepMarginTop = separatorStyle->marginTop() + separatorStyle->paddingTop(); + int sepMarginBottom = separatorStyle->marginBottom() + separatorStyle->paddingBottom(); + + int leftMargin = groupBoxStyle->paddingLeft() + + groupBoxStyle->marginLeft(); + + int rightMargin = groupBoxStyle->paddingRight() + + groupBoxStyle->marginRight(); + + int topMargin = groupBoxStyle->paddingTop() + + groupBoxStyle->marginTop() + + headerStyle->paddingTop() + + headerStyle->marginTop() + + sepMarginTop + + separatorStyle->span() + + sepMarginBottom; + + int checkMarkHeight = 0; + + bool hasCheckBox = groupBox->subControls & QStyle::SC_GroupBoxCheckBox; + + if (hasCheckBox) { + QStyleOptionButton checkBox; + checkBox.QStyleOption::operator=(*option); + checkMarkHeight = proxy()->pixelMetric(PM_IndicatorHeight, &checkBox, widget); + } + + topMargin += qMax(height, checkMarkHeight); + + contentsRect = groupBox->rect.adjusted(leftMargin, + topMargin, + -rightMargin, + 0); + + return contentsRect; + break; + } + case SC_GroupBoxCheckBox: + // Fall Through + case SC_GroupBoxLabel: { + QRect labelRect; + + const DuiLabelStyle *headerStyle = + static_cast(QtMaemo6StylePrivate::duiStyle(groupBox->state, + "DuiLabelStyle", + "DuiContainerTitle")); + QFont headerFont = headerStyle->font(); + QFontMetrics fontMetrics(headerFont); + int height = fontMetrics.height(); + int textWidth = fontMetrics.size(Qt::TextShowMnemonic, groupBox->text).width() + 1; + + const DuiContainerStyle *groupBoxStyle = + static_cast(QtMaemo6StylePrivate::duiStyle(groupBox->state, + "DuiContainerStyle")); + + int leftMargin = groupBoxStyle->paddingLeft() + + groupBoxStyle->marginLeft() + + headerStyle->paddingLeft() + + headerStyle->marginLeft(); + + int rightMargin = groupBoxStyle->paddingRight() + + groupBoxStyle->marginRight() + + headerStyle->paddingRight() + + headerStyle->marginRight(); + + int topMargin = groupBoxStyle->paddingTop() + + groupBoxStyle->marginTop() + + headerStyle->paddingTop() + + headerStyle->marginTop(); + + //unused + //int bottomMargin = groupBoxStyle->paddingBottom() + // + groupBoxStyle->marginBottom() + // + headerStyle->paddingBottom() + // + headerStyle->marginBottom(); + + labelRect = groupBox->rect.adjusted(leftMargin, + topMargin, + -rightMargin, + 0); + + labelRect.setHeight(height); + + // We need a QStyleOptionButton based style option in order + // to get correct geometries. + QStyleOptionButton checkBox; + checkBox.QStyleOption::operator=(*option); + bool hasCheckBox = groupBox->subControls & QStyle::SC_GroupBoxCheckBox; + int checkMarkWidth = 0; + if (hasCheckBox) { + checkMarkWidth = proxy()->pixelMetric(PM_IndicatorWidth, &checkBox, widget); + + proxy()->pixelMetric(PM_CheckBoxLabelSpacing, &checkBox, widget); + } + QRect totalRect = alignedRect(groupBox->direction, + groupBox->textAlignment, + QSize(textWidth + checkMarkWidth, height), + labelRect); + + // Adjust totalRect if checkbox is set + if (hasCheckBox) { + int checkMarkHeight = proxy()->pixelMetric(PM_IndicatorHeight, &checkBox, widget); + + bool leftToRight = (groupBox->direction == Qt::LeftToRight); + int left = 0; + // Adjust for check box + if (subControl == SC_GroupBoxCheckBox) { + left = leftToRight ? totalRect.left() : (totalRect.right() - checkMarkWidth); + int top = totalRect.top(); + totalRect.setRect(left, top, checkMarkWidth, checkMarkHeight); + // Adjust for label + } else { + left = leftToRight ? (totalRect.left() + checkMarkWidth) : totalRect.left(); + int top = totalRect.top() + (checkMarkHeight - fontMetrics.height()) / 2; + totalRect.setRect(left, top, + totalRect.width() - checkMarkWidth, totalRect.height()); + } + } + return totalRect; + + break; + } + default: + break; + } + } + break; + } + default: + break; + } + return QtMaemo6TestStyle::subControlRect(control, option, subControl, widget); +} + +QSize QtMaemo6Style::sizeFromContents(ContentsType type, + const QStyleOption *option, + const QSize &contentsSize, + const QWidget *widget) const +{ + Q_D(const QtMaemo6Style); + + QSize retSize = QtMaemo6TestStyle::sizeFromContents(type, option, contentsSize, widget); + + switch (type) { + case CT_ScrollBar: + if (const QStyleOptionSlider *scrollBar = qstyleoption_cast(option)) { + + int scrollBarExtent = proxy()->pixelMetric(PM_ScrollBarExtent, option, widget); + int scrollBarSliderMinimum = proxy()->pixelMetric(PM_ScrollBarSliderMin, option, widget); + if (scrollBar->orientation == Qt::Horizontal) { + retSize = QSize(scrollBarSliderMinimum, scrollBarExtent); + } else { + retSize = QSize(scrollBarExtent, scrollBarSliderMinimum); + } + } + break; + case CT_Slider: { + if (const QStyleOptionSlider *slider = qstyleoption_cast(option)) { + int sliderThickness = proxy()->pixelMetric(PM_SliderThickness, slider, widget); + + bool isHorizontal = (slider->orientation == Qt::Horizontal); + if (isHorizontal) + retSize.setHeight(sliderThickness); + else + retSize.setWidth(sliderThickness); + return retSize; + } + } + break; + case CT_ToolButton: + if (widget) { + QWidget *parentOfControl = widget->parentWidget(); + + if (const QStyleOptionToolButton *btn = qstyleoption_cast(option)) { + //a ToolButton on a ToolBar + if (dynamic_cast(parentOfControl)) { + //intentionally no code here at the moment + //a ToolButton on the DuiTitleBar + } else if (dynamic_cast(parentOfControl)) { + //intentionally no code here at the moment + //a ToolButton anywhere else on the Screen should be drawn like a PushButton + } else { + QStyleOptionToolButton subopt = *btn; + const DuiButtonStyle *style = + static_cast(QtMaemo6StylePrivate::duiStyle(subopt.state, "DuiButtonIconStyle", "")); + const DuiButtonStyle *styleFont = + static_cast(QtMaemo6StylePrivate::duiStyle(subopt.state, "DuiButtonIconStyle", + "NavigationBarToolBarButton")); + + int borderTop, borderRight, borderBottom, borderLeft; + d->paddingFromStyle(style, &borderLeft, &borderTop, &borderRight, &borderBottom); + + QRect textAndIconRect = d->getTextAndIconRect(style, subopt.text, subopt.icon, styleFont->font(), styleFont->iconSize()); + textAndIconRect.setWidth(textAndIconRect.width() + borderLeft + borderRight); + textAndIconRect.setHeight(textAndIconRect.height() + borderTop + borderBottom); + retSize = textAndIconRect.size(); + } + } + } + break; + case CT_PushButton: { + if (const QStyleOptionButton *btn = qstyleoption_cast(option)) { + QStyleOptionButton subopt = *btn; + const DuiButtonStyle *style = + static_cast(QtMaemo6StylePrivate::duiStyle(subopt.state, "DuiButtonIconStyle", "")); + + int borderTop, borderRight, borderBottom, borderLeft; + d->paddingFromStyle(style, &borderLeft, &borderTop, &borderRight, &borderBottom); + + QRect textAndIconRect = d->getTextAndIconRect(style, subopt.text, subopt.icon); + textAndIconRect.setWidth(textAndIconRect.width() + borderLeft + borderRight); + textAndIconRect.setHeight(textAndIconRect.height() + borderTop + borderBottom); + retSize = textAndIconRect.size(); + } + } + break; + case CT_ItemViewItem: + if (const QStyleOptionViewItemV4 *item = qstyleoption_cast(option)) { + const DuiContentItemStyle *style = + static_cast(QtMaemo6StylePrivate::duiStyle(option->state, + "DuiContentItemStyle")); + const DuiLabelStyle *labelTitle = + static_cast(QtMaemo6StylePrivate::duiStyle(option->state, + "DuiLabelStyle", style->titleObjectName())); + // subtitles for ListViewItems are currently not provided by qt. + //const DuiLabelStyle* labelSubTitle = + // static_cast( QtMaemo6StylePrivate::duiStyle( option->state, + // "DuiLabelStyle", style->subtitleObjectName() ) ); + const DuiImageWidgetStyle *labelIcon = + static_cast(QtMaemo6StylePrivate::duiStyle(option->state, + "DuiImageWidgetStyle", style->imageObjectName())); + + QString itemText = qvariant_cast(item->index.data(Qt::DisplayRole)); //.toString(); + QIcon itemIcon = qvariant_cast(item->index.data(Qt::DecorationRole)); + + //always calculate icon size, even if the index has no item, + // to get equal row heights + QSize iconSize = labelIcon->preferredSize() + + QSize(labelIcon->marginLeft() + labelIcon->marginRight(), + labelIcon->marginTop() + labelIcon->marginBottom()); + + QFontMetrics fontMetrics(labelTitle->font()); + QRect textRect = fontMetrics.boundingRect(itemText); + textRect.setWidth(textRect.width() + + labelTitle->marginLeft() + labelTitle->marginRight()); + + retSize.setWidth(textRect.width() + iconSize.width()); + if (iconSize.height() < textRect.height()) + retSize.setHeight(textRect.height()); + else + retSize.setHeight(iconSize.height()); + + } + break; + case CT_MenuBar: { + //return 0 size because the menubar should not be drawn + // this is done by the windowdecoration + if (widget == d->m_menuBar) + retSize = QSize(0, 0); + } + break; + default: + break; + } + return retSize; +} + +int QtMaemo6Style::pixelMetric(PixelMetric metric, + const QStyleOption *option, + const QWidget *widget) const +{ + switch (metric) { + case PM_ScrollBarExtent: + case PM_ScrollBarSliderMin: { + if (const QStyleOptionSlider *slider = qstyleoption_cast(option)) { + const DuiPositionIndicatorStyle *style = + static_cast(QtMaemo6StylePrivate::duiStyle(slider->state, + "DuiPositionIndicatorStyle")); + + QSize pixmapSize = style->onPixmap()->size().expandedTo(style->offPixmap()->size()); + + int minSize; + if (slider->orientation == Qt::Horizontal) + minSize = pixmapSize.width(); + else + minSize = pixmapSize.height(); + return minSize; + + } + } + break; + case PM_SliderThickness: + case PM_SliderControlThickness: { + int sliderThickness = 0; + + if (const QStyleOptionSlider *slider = qstyleoption_cast(option)) { + const DuiSliderStyle *style = + static_cast(QtMaemo6StylePrivate::duiStyle(slider->state, + "DuiSliderStyle")); + if (style) { + bool isHorizontal = slider->orientation == Qt::Horizontal; + const QPixmap *handleSourcePixmap = (isHorizontal) + ? style->handlePixmap() + : style->handleVerticalPixmap(); + const QPixmap *handlePressedSourcePixmap = (isHorizontal) + ? style->handlePressedPixmap() + : style->handleVerticalPressedPixmap(); + + QSize sliderHandleSize = handleSourcePixmap->size(); + QSize sliderHandlePressedSize = handlePressedSourcePixmap->size(); + QSize maxHandleSize = sliderHandleSize.expandedTo(sliderHandlePressedSize); + sliderThickness = maxHandleSize.height(); + } + } + return sliderThickness; + } + break; + case PM_SliderLength: { + int sliderLength = 0; + + if (const QStyleOptionSlider *slider = qstyleoption_cast(option)) { + const DuiSliderStyle *style = + static_cast(QtMaemo6StylePrivate::duiStyle(slider->state, + "DuiSliderStyle")); + if (style) { + bool isHorizontal = slider->orientation == Qt::Horizontal; + const QPixmap *handleSourcePixmap = (isHorizontal) + ? style->handlePixmap() + : style->handleVerticalPixmap(); + const QPixmap *handlePressedSourcePixmap = (isHorizontal) + ? style->handlePressedPixmap() + : style->handleVerticalPressedPixmap(); + + QSize sliderHandleSize = handleSourcePixmap->size(); + QSize sliderHandlePressedSize = handlePressedSourcePixmap->size(); + QSize maxHandleSize = sliderHandleSize.expandedTo(sliderHandlePressedSize); + sliderLength = maxHandleSize.width(); + } + } + return sliderLength; + } + break; + case PM_ExclusiveIndicatorWidth: + case PM_IndicatorWidth: { + + int left = 0; + int right = 0; + int top = 0; + int bottom = 0; + int fontSize = 10; + + if (const QStyleOptionButton *btn = qstyleoption_cast(option)) { + const DuiButtonStyle *style = + static_cast(QtMaemo6StylePrivate::duiStyle(btn->state, + "DuiButtonIconStyle", + QString(), + "checkbox")); + + if (style) { + // Check the recommended border size ... + if (style->backgroundImage()) { + style->backgroundImage()->borders(&left, &right, &top, &bottom); + } + // Use the font size for determining the ideal checkmark height + fontSize = style->font().pixelSize(); + } + } + return left + 0.8 * fontSize + right; + } + break; + case PM_ExclusiveIndicatorHeight: + case PM_IndicatorHeight: { + + int left = 0; + int right = 0; + int top = 0; + int bottom = 0; + int fontSize = 10; + + if (const QStyleOptionButton *btn = qstyleoption_cast(option)) { + const DuiButtonStyle *style = + static_cast(QtMaemo6StylePrivate::duiStyle(btn->state, + "DuiButtonIconStyle", + QString(), + "checkbox")); + + if (style) { + // Check the recommended border size ... + if (style->backgroundImage()) { + style->backgroundImage()->borders(&left, &right, &top, &bottom); + } + // Use the font size for determining the ideal checkmark height + fontSize = style->font().pixelSize(); + } + } + return top + 0.8 * fontSize + bottom; + } + break; + case PM_TabBarScrollButtonWidth: + return widget->height(); + default: + break; + } + + return QtMaemo6TestStyle::pixelMetric(metric, option, widget); +} + +QIcon QtMaemo6Style::standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *option, + const QWidget *widget) const +{ + QIcon icon; + QPixmap pixmap; + + switch (standardIcon) { + case QStyle::SP_MessageBoxInformation: // 09 + return QIcon(); + case QStyle::SP_MessageBoxWarning: // 10 + return QIcon(); + case QStyle::SP_MessageBoxCritical: // 11 + return QIcon(); + case QStyle::SP_MessageBoxQuestion: // 12 + return QIcon(); + case QStyle::SP_DialogOkButton: // 38 + return QIcon(); + case QStyle::SP_DialogCancelButton: // 39 + return QIcon(); + case QStyle::SP_DialogHelpButton: // 40 + return QIcon(); + case QStyle::SP_DialogOpenButton: // 41 + return QIcon(); + case QStyle::SP_DialogSaveButton: // 42 + return QIcon(); + case QStyle::SP_DialogCloseButton: // 43 + return QIcon(); + case QStyle::SP_DialogApplyButton: // 44 + return QIcon(); + case QStyle::SP_DialogResetButton: // 45 + return QIcon(); + case QStyle::SP_DialogDiscardButton: // 46 + return QIcon(); + case QStyle::SP_DialogYesButton: // 47 + return QIcon(); + case QStyle::SP_DialogNoButton: // 48 + return QIcon(); + default: + break; + } + + if (icon.isNull()) + icon = QCommonStyle::standardIconImplementation(standardIcon, option, widget); + return icon; +} + +int QtMaemo6Style::styleHint(StyleHint hint, const QStyleOption *option, + const QWidget *widget, QStyleHintReturn *returnData) const +{ + if (hint == QStyle::SH_ToolBar_Movable) { + return false; + } else if (hint == QStyle::SH_RequestSoftwareInputPanel) { + return QStyle::RSIP_OnMouseClick; + } + + return QtMaemo6TestStyle::styleHint(hint, option, widget, returnData); +} +/* + Private implementation specific methods: + */ + + + + + + + + diff --git a/plainqt/style/qtmaemo6style.h b/plainqt/style/qtmaemo6style.h new file mode 100644 index 000000000..a01c3d9b1 --- /dev/null +++ b/plainqt/style/qtmaemo6style.h @@ -0,0 +1,110 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef QTMAEMO6STYLE_H +#define QTMAEMO6STYLE_H + +#include +#include +#include +#include "qtmaemo6teststyle.h" + +#include + +class DuiComponentData; +class DuiStyle; +class DuiButtonStyle; +class DuiWidgetStyle; +class DuiScalableImage; +class DuiSliderStyle; +class QScrollBar; +class QTimer; +class QSequentialAnimationGroup; +class QAbstractScrollArea; + +class QtMaemo6StylePrivate; + +/*! + * This global function adds opacity to a pixmap + */ +QPixmap setPixmapOpacity(const QPixmap &pixmap, double opacity); + +/*! + * This class emulates the DUI windowdecoration, it provides a emulation + * of the DUI titlebar, adds scrolling functionallity and places a statusbar + * on the bottom of the screen, if the application has one. + * This class inherits indirectly from QPlastiqueStyle and reimplements + * necessarry methods for doing the correct dui-like styling. + * Currently it inherits from QtMaemo6TestStyle (inherits QPlastiqueStyle), + * which is currently only for testing purposes and may be deprecated in future. + */ +class DUI_EXPORT QtMaemo6Style : public QtMaemo6TestStyle +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QtMaemo6Style) + friend class QtMaemo6StyleEventFilter; +public: + QtMaemo6Style(); + virtual ~QtMaemo6Style(); + + /*! \reimp */ + virtual void init(); + + virtual void polish(QApplication *app); + virtual void polish(QWidget *w); + + virtual void drawPrimitive(PrimitiveElement element, + const QStyleOption *option, + QPainter *painter, + const QWidget *widget = 0) const; + + virtual void drawControl(ControlElement element, + const QStyleOption *option, + QPainter *painter, + const QWidget *widget = 0) const; + + virtual void drawComplexControl(ComplexControl control, + const QStyleOptionComplex *option, + QPainter *painter, + const QWidget *widget = 0) const; + + QSize sizeFromContents(ContentsType type, + const QStyleOption *option, + const QSize &contentsSize, + const QWidget *widget = 0) const; + + int pixelMetric(PixelMetric metric, + const QStyleOption *option = 0, + const QWidget *widget = 0) const; + + virtual QRect subControlRect(ComplexControl control, + const QStyleOptionComplex *option, + SubControl subControl, + const QWidget *widget = 0) const; + +protected Q_SLOTS: + QIcon standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *option, + const QWidget *widget = 0) const; + + virtual int styleHint(StyleHint hint, const QStyleOption *option = 0, + const QWidget *widget = 0, QStyleHintReturn *returnData = 0) const; + /*! \reimp_end */ +}; + +#endif diff --git a/plainqt/style/qtmaemo6style_p.h b/plainqt/style/qtmaemo6style_p.h new file mode 100644 index 000000000..0a50ef128 --- /dev/null +++ b/plainqt/style/qtmaemo6style_p.h @@ -0,0 +1,313 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef QTMAEMO6STYLE_P_H +#define QTMAEMO6STYLE_P_H + +#include "qtmaemo6style.h" +#include "qtmaemo6teststyle_p.h" +#include "qtmaemo6styleeventfilter.h" +#include "qtmaemo6scrollbareventfilter.h" + +class QtMaemo6PanGesture; + +class DuiComponentData; +class DuiWidgetController; +class QToolButton; +class QAction; +class QStatusBar; +class QMenuBar; + +class QtMaemo6StylePrivate : public QtMaemo6TestStylePrivate +{ +public: + Q_DECLARE_PUBLIC(QtMaemo6Style) + + QtMaemo6StylePrivate(); + virtual ~QtMaemo6StylePrivate(); + + /*! + * Initialization of the DUI framework. + * init() gets called by the style constructor. + * At that point we don't know yet whether the application object is a DUI + * application or not. As we only need to fully initialize the DUI framework + * for non-DUI application we need to defer the initialization of the DUI + * framework to a later point of the application life cycle. + */ + void initDui(); + + /*! + * returns a DuiStyle corresponding the given parameters + */ + static const DuiStyle *duiStyle(QStyle::State state, + const QString &styleClass, + const QString &styleObject = QString(), + const QString &type = QString(), + const DuiWidgetController *parent = NULL); + + /*! + * returns a string generated from the QStyle::state, dui can use + */ + static QString modeFromState(QStyle::State state) ; + + /*! + * draws the background of the widget + */ + static void drawWindowBackground(QWidget *); + static void drawWidgetBackground(QPainter *p, + const QStyleOption *option, + const QRect &rect, + const DuiWidgetStyle *style); + + /*! + * draws a scalable image + */ + static void drawScalableImage(QPainter *p, + const QStyleOption *option, + const QRect &rect, + const DuiScalableImage *scalableImage, + const DuiWidgetStyle *style, + const QString &purpose = "bg", + bool enableCache = true); + + /*! + * draws the background of a slider + */ + static void drawSliderBaseBackground(QPainter *p, + const QStyleOption *option, + const QRect &rect, + const DuiSliderStyle *style, + int maxSliderLength); + + /*! + * Draws the text on the button. + * \param style the dui style which is used to draw the button + * \param painter + * \param textRect the rect within the button in which the text (and icon) is drawn + * \param text the text + * \param align the alignment the text uses within the textRect!! + * \param font font used instead of font from the style + */ + void drawButtonText(const DuiButtonStyle *style, + QPainter *painter, + const QRectF &textRect, + const QString &text, + Qt::Alignment align, + const QFont &font) const; + /*! + * Draws the text on the button. + * overload: uses the font from style to draw the text + * \param style the dui style which is used to draw the button + * \param painter + * \param textRect the rect within the button in which the text (and icon) is drawn + * \param text the text + * \param align the alignment the text uses within the textRect!! + */ + void drawButtonText(const DuiButtonStyle *style, + QPainter *painter, + const QRectF &textRect, + const QString &text, + Qt::Alignment align) const; + + /*! + * Draws the icon on the button. + * \param style the dui style which is used to draw the button + * \param painter + * \param contentsRect the rect within the button in which the text (and icon) is drawn + * \param icon the icon + * \param iconSize optional overrides the icon size from style + */ + void drawButtonIcon(const DuiButtonStyle *style, + QPainter *painter, + const QRect &contentsRect, + const QIcon &icon, + const QSize &iconSize = QSize()) const; + + /*! + * Draws the button. + * \param painter + * \param text the text on the button + * \param icon the icon on the button + * \param rect the rect in which the button is drawn + * \param option the QStyleOption used to draw the button + * \param style the dui style used to draw the button + */ + void drawBasicButton(QPainter *painter, + const QString &text, + const QIcon &icon, + const QRect &rect, + const QStyleOption *option, + const DuiButtonStyle *style) const; + + /*! + * Draws the button (overloaded) + * \param painter + * \param text the text on the button + * \param icon the icon on the button + * \param rect the rect in which the button is drawn + * \param option the QStyleOption used for the button + * \param styleClass style class that should be used + * \param styleObject style object that should be used + */ + void drawBasicButton(QPainter *painter, + const QString &text, + const QIcon &icon, + const QRect &rect, + const QStyleOption *option, + const QString &styleClass, + const QString &styleObject = QString()) const; + + /*! + * Draws the button. + * \param painter + * \param text the text on the button + * \param icon the icon on the button + * \param rect the rect in which the button is drawn + * \param option the QStyleOption used to draw the button + * \param style the dui style used to draw the button + * \param font use this font instead of the font from the style + * \param font use this icon size instead of icon size from the style + */ + void drawBasicButton(QPainter *painter, + const QString &text, + const QIcon &icon, + const QRect &rect, + const QStyleOption *option, + const DuiButtonStyle *style, + const QFont &font, + const QSize &iconSize) const; + + /*! + * Draws the toggle button + * \param painter + * \param text the text on the button + * \param rect the rect in which the button is drawn + * \param icon the icon on the button + * \param option the QStyleOption used to draw the button + * \param styleClass style class that should be used + * \param styleObject style object that should be used + */ + void drawToggleButton(QPainter *painter, + const QString &text, + const QIcon &icon, + const QRect &rect, + const QStyleOption *option, + const QString &styleClass, + const QString &styleObject = QString()) const; + + /*! + * Draws the checkbox + * \param painter + * \param text the text besides the checkBox + * \param rect the rect in which the checkBox is drawn + * \param icon the icon on the button + * \param option the QStyleOption used to draw the checkBox + * \param styleClass style class that should be used + * \param styleObject style object that should be used + */ + void drawCheckBox(QPainter *painter, + const QString &text, + const QIcon &icon, + const QRect &rect, + const QStyleOption *option, + const QString &styleClass, + const QString &styleObject = QString()) const; + + /*! + * calculates a rect the text and icon earn + * returns a rect within the button's rect used by the text and icon + * the rect already includes the margins + * \param style the dui style used to draw the button + * \param text the text on the button + * \param icon optional the icon on the button + * \param font optional used instead of the font from the style + * \param iconSize optional used instead of iconSize from the style if valid + */ + QRect getTextAndIconRect(const DuiButtonStyle *style, + const QString &text, + const QIcon &icon = QIcon(), + const QFont &font = QFont(), + const QSize &iconSize = QSize()) const; + /*! + * returns the rect of the text with font font + * includes no margins + * \param text the text + * \param font font used to calculate the text size + */ + QRect textBoundingRect(const QString &text, const QFont &font) const; + + /*! + * returns the effective padding used for the style + * uses the borders of the DuiScalableImage, but if the padding specified in the style is + * greater than the border of the DuiScalableImage, the borders from style are used + * \param style the used style + * \param left border in the left side + * \param top border in the top side + * \param right border in the right side + * \param bottom border in the bottom side + */ + void paddingFromStyle(const DuiWidgetStyle *style, + int *left, + int *top, + int *right, + int *bottom) const; + + /*! + * returns the rect a slider uses + */ + QRect scrollBarSliderRect(const QStyleOptionComplex *option, const QWidget *widget = 0) const; + + /*! + * returns an inverted Alignment, so align right will become align left, top + * will become bottom and so on + */ + Qt::Alignment invertAlignment(Qt::Alignment align) const; + + bool hasVerticalAlignment(Qt::Alignment align) const { + return (align & 0xF0) > 0; + }; + bool hasHorizontalAlignment(Qt::Alignment align) const { + return (align & 0xF) > 0; + }; + Qt::Alignment verticalAlignment(Qt::Alignment align) const { + return align & 0xF0; + }; + Qt::Alignment horizontalAlignment(Qt::Alignment align) const { + return align & 0xF; + }; + +public: + QList m_toolButtonsInTitleBar; + QList m_toolBarActions; + QStatusBar *m_statusBar; + + const int m_actionsInTitleBarCount; + + DuiComponentData *m_componentData; + bool m_isDuiInitialized; + bool m_isDuiApplication; + QtMaemo6ScrollBarEventFilter *m_scrollBarEventFilter; + QtMaemo6PanGesture *m_panGestureScrolling; + QtMaemo6StyleEventFilter *m_windowEventFilter; + + QMenuBar *m_menuBar; + +}; + +#endif diff --git a/plainqt/style/qtmaemo6styleeventfilter.cpp b/plainqt/style/qtmaemo6styleeventfilter.cpp new file mode 100644 index 000000000..d0b2d4509 --- /dev/null +++ b/plainqt/style/qtmaemo6styleeventfilter.cpp @@ -0,0 +1,162 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "qtmaemo6styleeventfilter.h" +#include "qtmaemo6style_p.h" +#include "qtmaemo6windowdecoration.h" +#include "qtmaemo6dialogproxy.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +QtMaemo6StyleEventFilter::QtMaemo6StyleEventFilter(QtMaemo6TestStyle *parent) + : QtMaemo6TestStyleEventFilter(parent) +{ +} + +bool QtMaemo6StyleEventFilter::eventFilter(QObject *obj, QEvent *event) +{ + QWidget *widget = qobject_cast(obj); + + //unused + //QWidget * parent = widget->parentWidget(); + + switch (event->type()) { + case QEvent::Show: { + if (NULL != widget) { + if (widget->windowFlags() & Qt::Window + && (qobject_cast(widget) || qobject_cast(widget))) { + if (qobject_cast(widget)) { + qDebug() << "Generating and Showing DuiWindowDecoration"; + m_style->m_windowDecoration = new QtMaemo6WindowDecoration(widget); + m_style->m_windowDecoration->showFastMaximized(); + QtMaemo6StylePrivate::drawWindowBackground(m_style->m_windowDecoration); + + //ensure that the mainwindow takes at least the width of the screen + widget->setMinimumWidth(m_style->m_windowDecoration->maxViewportSize().width()); + return true; + } + if (QDialog *dialog = qobject_cast(widget)) { + qCritical() << "Generating and Showing DuiDialog"; + QtMaemo6DialogProxy *dialogProxy = new QtMaemo6DialogProxy(dialog, m_style->m_windowDecoration); + + dialogProxy->setTitle(widget->windowTitle()); + + const QPixmap *closePixmap = DuiTheme::pixmap("Icon-close", QSize(28, 28)); + dialogProxy->setPixmap(*closePixmap); + + //connect( dialogProxy, SIGNAL( closeClicked() ), + // dialog, SLOT( reject() ) ); + dialogProxy->showFastMaximized(); + QtMaemo6StylePrivate::drawWindowBackground(widget); + + //ensure that the mainwindow takes at least the width of the screen + widget->setMinimumWidth(dialogProxy->maxViewportSize().width()); + return true; + } + } + // Unfortunately this can't be safely done in polish: + if (QDialogButtonBox *box = qobject_cast(widget)) { + QPushButton *okButton = box->button(QDialogButtonBox::Ok); + //~ uispec-document DirectUI_Common_Strings_UI_Specification_0.7.doc + //: Command for confirmation + //% "Done" + if (okButton) okButton->setText(qtTrId("qtn_comm_command_done")); + QPushButton *cancelButton = box->button(QDialogButtonBox::Cancel); + if (cancelButton) cancelButton->hide(); + } + if (QPushButton *button = qobject_cast(widget)) { + QString okString = tr("OK"); + //~ uispec-document DirectUI_Common_Strings_UI_Specification_0.7.doc + //: Command for confirmation + //% "Done" + QString doneString = qtTrId("qtn_comm_command_done"); + if (button->text() == okString) button->setText(doneString); + QString cancelString = tr("Cancel"); + if (button->text() == cancelString) { + button->hide(); + } + } + if (QTreeView *treeWidget = qobject_cast(widget)) { + //unfortunately this must be done in showEvent, because it's + // a property of QTreeWidget, that can't be influenzed by the + // style + + //FIXME: really bad to do all that in showEvent + QToolButton button; + QStyleOptionToolButton option; + option.initFrom(&button); + option.text = '+'; + QSize size = m_style->sizeFromContents(QStyle::CT_ToolButton, &option, QSize(), &button); + + //only set the indentation if the required buttonsize is bigger + // than original indentation + if (size.width() > treeWidget->indentation()) { + treeWidget->setIndentation(size.width()); + } + } + } + + } + break; + case QEvent::MouseButtonPress: { + //qDebug( "eventFilter got mousePress" ); + + // now send press feedback + DuiFeedbackPlayer *feedbackPlayer = DuiComponentData::feedbackPlayer(); + + if (feedbackPlayer) { + feedbackPlayer->play(DuiFeedbackPlayer::Press); + } + } + break; + + case QEvent::MouseButtonRelease: { + //qDebug( "eventFilter got mouseRelease" ); + + // now send release feedback + DuiFeedbackPlayer *feedbackPlayer = DuiComponentData::feedbackPlayer(); + + if (feedbackPlayer) { + feedbackPlayer->play(DuiFeedbackPlayer::Release); + } + } + + break; + default: + break; + } + // standard event processing + return QObject::eventFilter(obj, event); +} + diff --git a/plainqt/style/qtmaemo6styleeventfilter.h b/plainqt/style/qtmaemo6styleeventfilter.h new file mode 100644 index 000000000..323af1af6 --- /dev/null +++ b/plainqt/style/qtmaemo6styleeventfilter.h @@ -0,0 +1,43 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef QTMAEMO6STYLEEVENTFILTER_H +#define QTMAEMO6STYLEEVENTFILTER_H + +#include "qtmaemo6teststyle.h" + +/*! + * the eventfilter for the basic style. Currently this is only used for + * testing purposes and may be deprecated + */ +class QtMaemo6StyleEventFilter : public QtMaemo6TestStyleEventFilter +{ + Q_OBJECT +public: + explicit QtMaemo6StyleEventFilter(QtMaemo6TestStyle *parent); + virtual ~QtMaemo6StyleEventFilter() {}; +protected: + /*! \reimp */ + bool eventFilter(QObject *obj, QEvent *event); + /*! \reimp_end */ + +}; + + +#endif //QTMAEMO6STYLEEVENTFILTER_H diff --git a/plainqt/style/qtmaemo6styleplugin.cpp b/plainqt/style/qtmaemo6styleplugin.cpp new file mode 100644 index 000000000..91377f7a1 --- /dev/null +++ b/plainqt/style/qtmaemo6styleplugin.cpp @@ -0,0 +1,47 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "qtmaemo6styleplugin.h" + +#include "qtmaemo6style.h" + +QStringList QtMaemo6StylePlugin::keys() const +{ + return QStringList() + << "maemo6" + << "DuiBasicQtStyle" + << "DuiIntegratedQtStyle" //deprecated + << "bqs" + << "iqs"; //deprecated +} + +QStyle *QtMaemo6StylePlugin::create(const QString &key) +{ + QString lkey = key.toLower(); + + if ((lkey == "duibasicqtstyle") || (lkey == "bqs")) + return new QtMaemo6TestStyle; + + if ((lkey == "maemo6") || (lkey == "duiintegratedqtstyle") || (lkey == "iqs")) + return new QtMaemo6Style; + + return 0; +} + +Q_EXPORT_PLUGIN2(pnp_qtmaemo6styleplugin, QtMaemo6StylePlugin) diff --git a/plainqt/style/qtmaemo6styleplugin.h b/plainqt/style/qtmaemo6styleplugin.h new file mode 100644 index 000000000..df8a912ca --- /dev/null +++ b/plainqt/style/qtmaemo6styleplugin.h @@ -0,0 +1,37 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef QTMAEMO6STYLEPLUGIN_H +#define QTMAEMO6STYLEPLUGIN_H + +#include + +/*! + * this class provides the QtMaemo6Style as a plugin + */ +class QtMaemo6StylePlugin : public QStylePlugin +{ +public: + /*! \reimp */ + QStringList keys() const; + QStyle *create(const QString &key); + /*! \reimp_end */ +}; + +#endif diff --git a/plainqt/style/qtmaemo6submenu.cpp b/plainqt/style/qtmaemo6submenu.cpp new file mode 100644 index 000000000..04a4c094d --- /dev/null +++ b/plainqt/style/qtmaemo6submenu.cpp @@ -0,0 +1,71 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "qtmaemo6submenu.h" +#include "qtmaemo6windowdecoration.h" +#include "qtmaemo6style_p.h" + +#include +#include + +QtMaemo6SubMenu::QtMaemo6SubMenu(QMenu *m, QWidget *parent) : QListWidget(parent) +{ + fillListWidget(m); + + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + + connect(this, SIGNAL(itemClicked(QListWidgetItem *)), this, SLOT(listItemClicked(QListWidgetItem *))); +} + +QtMaemo6SubMenu::~QtMaemo6SubMenu() +{ + +} + +void QtMaemo6SubMenu::fillListWidget(QMenu *m) +{ + m_actionItemList.clear(); + foreach(QAction * action, m->actions()) { + if (!action->isSeparator() && action->isEnabled()) { + QListWidgetItem *item = new QListWidgetItem(action->icon(), action->text(), this); + m_actionItemList.insert(item, action); + } + } +} + +void QtMaemo6SubMenu::listItemClicked(QListWidgetItem *item) +{ + QAction *action = m_actionItemList.value(item); + if (action) { + if (action->menu()) { + QtMaemo6SubMenu *subMenu = new QtMaemo6SubMenu(action->menu(), NULL); + QtMaemo6WindowDecoration *decoration = new QtMaemo6WindowDecoration(subMenu, NULL); + decoration->showFastMaximized(); + //these both must be done after the show, because the status- and + // menubar is added on show event + decoration->setStatusBar(NULL); + decoration->setMenuBar(NULL); + QtMaemo6StylePrivate::drawWindowBackground(decoration); + close(); + } else { + action->activate(QAction::Trigger); + } + } + close(); +} diff --git a/plainqt/style/qtmaemo6submenu.h b/plainqt/style/qtmaemo6submenu.h new file mode 100644 index 000000000..d5e31ccf8 --- /dev/null +++ b/plainqt/style/qtmaemo6submenu.h @@ -0,0 +1,47 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef QTMAEMO6SUBMENU_H +#define QTMAEMO6SUBMENU_H + +#include "qtmaemo6window.h" + +#include + +class QMenu; +class QListWidgetItem; + +/*! + * This class shows a submenu out of the menubar + */ +class QtMaemo6SubMenu : public QListWidget +{ + Q_OBJECT +public: + explicit QtMaemo6SubMenu(QMenu *m, QWidget *parent); + virtual ~QtMaemo6SubMenu(); +protected Q_SLOTS: + void listItemClicked(QListWidgetItem *); +protected: + void fillListWidget(QMenu *m); +private: + QMap m_actionItemList; +}; + +#endif diff --git a/plainqt/style/qtmaemo6teststyle.cpp b/plainqt/style/qtmaemo6teststyle.cpp new file mode 100644 index 000000000..b50a334d2 --- /dev/null +++ b/plainqt/style/qtmaemo6teststyle.cpp @@ -0,0 +1,135 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "qtmaemo6teststyle.h" +#include "qtmaemo6teststyle_p.h" +#include "qtmaemo6windowdecoration.h" + +#include +#include +#include +#include +#include + +QtMaemo6TestStyleEventFilter::QtMaemo6TestStyleEventFilter(QtMaemo6TestStyle *parent) + : QObject(parent) +{ + m_style = parent; +} + +bool QtMaemo6TestStyleEventFilter::eventFilter(QObject *obj, QEvent *event) +{ + QWidget *widget = qobject_cast(obj); + QWidget *parent = qobject_cast(widget->parent()); + + switch (event->type()) { + case QEvent::Show: { + if (NULL != widget && (qobject_cast(widget) || qobject_cast(widget))) { + //QMainWindow* main_window(qobject_cast(widget)); + //if (NULL != main_window) { + if (widget->windowFlags() & Qt::Window) { + if (!parent || !qobject_cast(parent)) { + parent = m_style->m_windowDecoration = new QtMaemo6WindowDecoration(widget); + } + parent->showMaximized(); + } + } + } + break; + default: + break; + } + // standard event processing + return QObject::eventFilter(obj, event); +} + +QtMaemo6TestStyle::QtMaemo6TestStyle(QtMaemo6TestStylePrivate &dd) + : d_ptr(& dd), // this is a special case, since we start our shared d-pointer hierarchy within dui right here + m_windowDecoration(NULL) +{ + Q_D(QtMaemo6TestStyle); + if (d) + d->q_ptr = this; +} + +QtMaemo6TestStyle::QtMaemo6TestStyle() + : QPlastiqueStyle(), + d_ptr(new QtMaemo6TestStylePrivate()), + m_windowEventFilter(0) +{ + Q_D(QtMaemo6TestStyle); + d->q_ptr = this; +} + + +QtMaemo6TestStyle::~QtMaemo6TestStyle() +{ + delete d_ptr; +} + +void QtMaemo6TestStyle::init() +{ + m_windowEventFilter = new QtMaemo6TestStyleEventFilter(this); +} + +void QtMaemo6TestStyle::polish(QApplication *app) +{ + //FIXME: remove magic numbers! + app->setGlobalStrut(QSize(48, 48)); + QFont font("Nokia Sans"); + font.setPointSize(25); + app->setFont(font); +} + +void QtMaemo6TestStyle::polish(QPalette &palette) +{ + Q_UNUSED(palette); + /* + QPixmap backgroundPixmap( ":/bg2.png" ); + + //setTexture( palette, QPalette::Button, backgroundPixmap ); + palette.setBrush( QPalette::Background, Qt::black ); + setTexture( palette, QPalette::Mid, backgroundPixmap ); + setTexture( palette, QPalette::Window, backgroundPixmap ); + + + palette.setBrush( QPalette::Text, Qt::white ); + palette.setBrush( QPalette::ButtonText, Qt::white ); + palette.setBrush( QPalette::WindowText, Qt::white ); + + QBrush half_transparent(QColor(0,0,0,128)); + + palette.setBrush( QPalette::Button, half_transparent ); + palette.setBrush( QPalette::Base, half_transparent ); + */ +} + +void QtMaemo6TestStyle::polish(QWidget *widget) +{ + widget->installEventFilter(m_windowEventFilter); +} + +void QtMaemo6TestStyle::setTexture(QPalette &palette, QPalette::ColorRole role, + const QPixmap &pixmap) +{ + for (int i = 0; i < QPalette::NColorGroups; ++i) { + QColor color = palette.brush(QPalette::ColorGroup(i), role).color(); + palette.setBrush(QPalette::ColorGroup(i), role, QBrush(color, pixmap)); + } +} diff --git a/plainqt/style/qtmaemo6teststyle.h b/plainqt/style/qtmaemo6teststyle.h new file mode 100644 index 000000000..bb92a3c42 --- /dev/null +++ b/plainqt/style/qtmaemo6teststyle.h @@ -0,0 +1,83 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef QTMAEMO6TESTSTYLE_H +#define QTMAEMO6TESTSTYLE_H + +#include + +class QtMaemo6WindowDecoration; +class QtMaemo6TestStyle; +class QtMaemo6TestStylePrivate; + +class QtMaemo6TestStyleEventFilter : public QObject +{ + Q_OBJECT +public: + explicit QtMaemo6TestStyleEventFilter(QtMaemo6TestStyle *parent); + virtual ~QtMaemo6TestStyleEventFilter() {}; +protected: + bool eventFilter(QObject *obj, QEvent *event); +protected: + QtMaemo6TestStyle *m_style; +}; + +/*! + * this class is a basic QStyle. It is currently only used for testing purposes + * and may be deprecated in future + */ +class QtMaemo6TestStyle : public QPlastiqueStyle +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QtMaemo6TestStyle) + Q_DISABLE_COPY(QtMaemo6TestStyle) + + friend class QtMaemo6TestStyleEventFilter; + //FIXME: bad dependency + friend class QtMaemo6StyleEventFilter; +public: + QtMaemo6TestStyle(); + virtual ~QtMaemo6TestStyle(); + + /*! \reimp */ + virtual void polish(QApplication *app); + virtual void polish(QPalette &palette); + virtual void polish(QWidget *widget); + /*! \reimp_end */ + + /*! + * initializes the style + */ + virtual void init(); +protected: + QtMaemo6TestStylePrivate *const d_ptr; + QtMaemo6TestStyle(QtMaemo6TestStylePrivate &dd); + +protected: + + QtMaemo6TestStyleEventFilter *m_windowEventFilter; + QtMaemo6WindowDecoration *m_windowDecoration; + +private: + void setTexture(QPalette &palette, + QPalette::ColorRole role, + const QPixmap &pixmap); +}; + +#endif diff --git a/plainqt/style/qtmaemo6teststyle_p.h b/plainqt/style/qtmaemo6teststyle_p.h new file mode 100644 index 000000000..958a8b01c --- /dev/null +++ b/plainqt/style/qtmaemo6teststyle_p.h @@ -0,0 +1,39 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef QTMAEMO6TESTSTYLEPRIVATE_H +#define QTMAEMO6TESTSTYLEPRIVATE_H + +#include "qtmaemo6teststyle.h" + +/*! + * private part of the teststyle. This does nothing specific, it's just + * used as base class for the final style's private class + */ +class QtMaemo6TestStylePrivate +{ + Q_DECLARE_PUBLIC(QtMaemo6TestStyle) +public: + QtMaemo6TestStylePrivate() {}; + virtual ~QtMaemo6TestStylePrivate() {}; +protected: + QtMaemo6TestStyle *q_ptr; +}; + +#endif diff --git a/plainqt/style/qtmaemo6titlebar.cpp b/plainqt/style/qtmaemo6titlebar.cpp new file mode 100644 index 000000000..59a5eb2a3 --- /dev/null +++ b/plainqt/style/qtmaemo6titlebar.cpp @@ -0,0 +1,147 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "qtmaemo6titlebar.h" +#include "qtmaemo6clicklabel.h" +#include "qtmaemo6style_p.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +QtMaemo6TitleBar::QtMaemo6TitleBar(QWidget *parent) : QWidget(parent) +{ + setObjectName(QString("Qt_Maemo6_TitleBar")); + + QToolButton *minimize_button(new QToolButton(this)); + minimize_button->setText("MinimizeButton"); + minimize_button->setIcon(QPixmap(":/Icon-home.png")); + minimize_button->setAutoRaise(true); + minimize_button->setIconSize(QSize(48, 48)); + + connect(minimize_button, SIGNAL(clicked()), this, SIGNAL(minimizeButtonClicked())); + + m_titleLabel = new QtMaemo6ClickLabel(this); + connect(m_titleLabel, SIGNAL(clicked()), this, SIGNAL(menuLabelClicked())); + + m_titleLabelMenuButton = new QtMaemo6ClickLabel(this); + + QStyleOption option; + option.initFrom(this); + + const DuiApplicationMenuButtonStyle *iconStyle = + static_cast(QtMaemo6StylePrivate::duiStyle(option.state, + "DuiApplicationMenuButtonStyle", "NavigationBarMenuButton")); + if (iconStyle) { + m_titleLabelMenuButton->setPixmap(*DuiTheme::pixmap(iconStyle->arrowIcon(), iconStyle->arrowIconSize())); + } + connect(m_titleLabelMenuButton, SIGNAL(clicked()), this, SIGNAL(menuLabelClicked())); + + + QSpacerItem *spacer = new QSpacerItem(0, 0); + const DuiWidgetStyle *spacerStyle = + static_cast(QtMaemo6StylePrivate::duiStyle(option.state, + "DuiWidgetStyle", "NavigationBarMenuButtonArrowImage")); + if (spacerStyle) { + spacer->changeSize(spacerStyle->marginLeft(), 0); + } + + QToolButton *close_button(new QToolButton(this)); + close_button->setText("CloseButton"); + close_button->setIcon(QPixmap(":/Icon-close.png")); + //FIXME: remove magic numbers! + close_button->setIconSize(QSize(48, 48)); + close_button->setAutoRaise(true); + + connect(close_button, SIGNAL(clicked()), this, SIGNAL(closeButtonClicked())); + + m_buttonsLayout = new QHBoxLayout; + m_buttonsLayout->setMargin(0); + m_buttonsLayout->setSpacing(0); + m_buttonsLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum)); + + m_titleBarLayout = new QHBoxLayout(this); + m_titleBarLayout->setMargin(0); + m_titleBarLayout->setSpacing(0); + m_titleBarLayout->addWidget(minimize_button); + m_titleBarLayout->addWidget(m_titleLabel); + m_titleBarLayout->addItem(spacer); + m_titleBarLayout->addWidget(m_titleLabelMenuButton); + m_titleBarLayout->addLayout(m_buttonsLayout); + m_titleBarLayout->addWidget(close_button); + +} + +QtMaemo6TitleBar::~QtMaemo6TitleBar() +{ + +} + +void QtMaemo6TitleBar::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event); + + QPainter painter(this); + + QStyleOption option; + option.initFrom(this); + + style()->drawPrimitive(QStyle::PE_Widget, &option, &painter, this); +} + +void QtMaemo6TitleBar::setTitle(const QString &title) +{ + m_titleLabel->setText(title); +} + +QString QtMaemo6TitleBar::title() const +{ + return m_titleLabel->text(); +} + +void QtMaemo6TitleBar::setMenuButtonVisible(bool visible) +{ + m_titleLabelMenuButton->setVisible(visible); +} + +void QtMaemo6TitleBar::addAction(QAction *action) +{ + QToolButton *tbtn = new QToolButton(this); + tbtn->setDefaultAction(action); + tbtn->setIconSize(QSize(48, 48)); + tbtn->setAutoRaise(true); + + addButton(tbtn); +} + +void QtMaemo6TitleBar::addButton(QToolButton *button) +{ + m_buttonsLayout->addWidget(button); + m_buttonsLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum)); + + qDebug("Added ToolButton %s to TitleBar", button->text().toLocal8Bit().constData()); +} diff --git a/plainqt/style/qtmaemo6titlebar.h b/plainqt/style/qtmaemo6titlebar.h new file mode 100644 index 000000000..c7b122184 --- /dev/null +++ b/plainqt/style/qtmaemo6titlebar.h @@ -0,0 +1,94 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef QTMAEMO6TITLEBAR_H +#define QTMAEMO6TITLEBAR_H + +#include +#include +#include + +class QtMaemo6ClickLabel; + +/*! + * this class emulates a dui titlebar + */ +class QtMaemo6TitleBar : public QWidget +{ + Q_OBJECT + Q_PROPERTY(QString title READ title WRITE setTitle) +public: + explicit QtMaemo6TitleBar(QWidget *parent); + virtual ~QtMaemo6TitleBar(); + + /*! + * returns the title of titlebar + */ + QString title() const; + + /*! + * hides or shows the Menu Button + */ + void setMenuButtonVisible(bool visible); +public Q_SLOTS: + /*! + * sets the title of the titlebar + */ + void setTitle(const QString &title); + + /*! + * adds a QAction to the titlebar + * /see addButton() + */ + void addAction(QAction *action); + + /*! + * adds a button to the titlebar + */ + void addButton(QToolButton *button); + +Q_SIGNALS: + /*! + * this signal is emitted if the home button was pressed + */ + void closeButtonClicked(); + + /*! + * this signal is emitted if the close button was pressed + */ + void minimizeButtonClicked(); + + /*! + * this signal is emitted if the title label was pressed + */ + void menuLabelClicked(); + +protected: + /*! \reimp */ + void paintEvent(QPaintEvent *event); + /*! \reimp_end */ + +private: + QtMaemo6ClickLabel *m_titleLabel; + QtMaemo6ClickLabel *m_titleLabelMenuButton; + QHBoxLayout *m_buttonsLayout; + QHBoxLayout *m_titleBarLayout; +}; + +#endif diff --git a/plainqt/style/qtmaemo6window.cpp b/plainqt/style/qtmaemo6window.cpp new file mode 100644 index 000000000..8e255101e --- /dev/null +++ b/plainqt/style/qtmaemo6window.cpp @@ -0,0 +1,143 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "qtmaemo6window.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "qtmaemo6dialogtitle.h" +#include "qtmaemo6style_p.h" + +QtMaemo6Window::QtMaemo6Window(QWidget *originalWidget, QWidget *parent /*= NULL*/) + : QWidget(parent) + , m_centralWidget(0) + , m_scrollArea(0) + , m_window(originalWidget) + , m_closeFromChild(false) +{ + setWindowFlags(Qt::Window + | Qt::CustomizeWindowHint + | Qt::FramelessWindowHint); + setAttribute(Qt::WA_DeleteOnClose); + + //FIXME: this sort of layouting is not nice + // spacers and widgets should be handled within this class + m_windowLayout = new QGridLayout(this); + m_windowLayout->setMargin(0); + m_windowLayout->setSpacing(0); + + setCentralWidget(m_window); +} + +QtMaemo6Window::~QtMaemo6Window() +{ + qCritical() << "QtMaemo6Window deleted"; +} + +QSize QtMaemo6Window::maxViewportSize() const +{ + return m_centralWidget->maximumViewportSize(); +} + +void QtMaemo6Window::closeEvent(QCloseEvent *event) +{ + //prevent deleting the original Widget by Qt + if (m_scrollArea) + m_scrollArea->takeWidget(); + + //this must be set back to dialog, so that the dialog can be shown again! + m_window->setWindowFlags(m_originalFlags); + m_window->hide(); + QWidget::closeEvent(event); +} + +bool QtMaemo6Window::eventFilter(QObject *obj, QEvent *event) +{ + switch (event->type()) { + case QEvent::Hide: //intended fall trough + case QEvent::Close: + if (!m_closeFromChild) { + m_closeFromChild = true; + + // the decoration is closed, even if the widget is only hidden, + // because the decoration is created again, when the widget is + // shown + this->close(); + return true; + } + break; + case QEvent::Show: { + if (m_scrollArea && m_scrollArea->widget()) + m_scrollArea->widget()->setMinimumWidth(maxViewportSize().width()); + } + break; + default: + break; + } + return QWidget::eventFilter(obj, event); +} + +void QtMaemo6Window::showFastMaximized() +{ + // Size policy instead? + resize(DuiDeviceProfile::instance()->resolution()); + show(); +} + +void QtMaemo6Window::setCentralWidget(QWidget *widget) +{ + if (widget) { + m_window = widget; + m_originalFlags = m_window->windowFlags(); + m_window->setWindowFlags(Qt::Widget); + + m_window->installEventFilter(this); + + //remove the current central widget (and scrollArea if set) + // but don't delete the central widget + if (m_scrollArea) { + m_windowLayout->removeWidget(m_scrollArea); + m_scrollArea->takeWidget(); + delete m_scrollArea; + m_scrollArea = NULL; + } else { + if (m_centralWidget) + m_windowLayout->removeWidget(m_centralWidget); + } + m_centralWidget = NULL; + + if (qobject_cast(widget)) + m_centralWidget = qobject_cast(widget); + else { + m_centralWidget = m_scrollArea = new QScrollArea(); + m_scrollArea->setFrameShape(QFrame::NoFrame); + m_scrollArea->setWidget(widget); + } + m_windowLayout->addWidget(m_centralWidget, 1, 1, 1, 1); + } +} diff --git a/plainqt/style/qtmaemo6window.h b/plainqt/style/qtmaemo6window.h new file mode 100644 index 000000000..c23540671 --- /dev/null +++ b/plainqt/style/qtmaemo6window.h @@ -0,0 +1,94 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef QTMAEMO6WINDOW +#define QTMAEMO6WINDOW + +#include +#include +#include + +class QGridLayout; + +/*! + * this is an abstract base class for emulating dui windows, such as the + * application window, dialogs or menus. + * It may put some decoration around the window and puts the original Widget + * into a scrollarea, if it is not a scrollarea by itself. + * The window uses a layout like + * +------------------------------------------+ + * | topSpacer | + * +------------+---------------+-------------+ + * | leftSpacer | centralWidget | rightSpacer | + * +------------+---------------+-------------+ + * | bottomSpacer | + * +------------------------------------------+ + * the centralWidget is automatically added to the layout's center + * if you wan't to add spacing you must add the spacers by yourself + */ +class QtMaemo6Window : public QWidget +{ + Q_OBJECT +public: + /*! + * Consturct a new window + * \param originalWidget the widget that should be embedded in this window + * \param parent the parent widget + */ + explicit QtMaemo6Window(QWidget *originalWidget, QWidget *parent = NULL); + + virtual ~QtMaemo6Window(); + + /*! + * returns the maximum size the viewport of the scrollarea + * may take + */ + QSize maxViewportSize() const; + + /*! + * shows the window full screen + * use this instead of showMaximized() + */ + void showFastMaximized(); + + /*! + * sets the widget that is shown inside the window + */ + void setCentralWidget(QWidget *widget); + +protected: + QtMaemo6Window() {}; + + /*! \reimp */ + void closeEvent(QCloseEvent *event); + bool eventFilter(QObject *obj, QEvent *event); + /*! \reimp_end */ + +protected: + QGridLayout *m_windowLayout; + QAbstractScrollArea *m_centralWidget; + QScrollArea *m_scrollArea; + QPointer m_window; +private: + Qt::WindowFlags m_originalFlags; + bool m_closeFromChild; + bool m_hideFromChild; +}; + +#endif //QTMAEMO6WINDOW diff --git a/plainqt/style/qtmaemo6windowdecoration.cpp b/plainqt/style/qtmaemo6windowdecoration.cpp new file mode 100644 index 000000000..1bc237fca --- /dev/null +++ b/plainqt/style/qtmaemo6windowdecoration.cpp @@ -0,0 +1,110 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "qtmaemo6windowdecoration.h" +#include "qtmaemo6titlebar.h" +#include "qtmaemo6menuproxy.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +QtMaemo6WindowDecoration::QtMaemo6WindowDecoration(QWidget *mw, QWidget *parent /*= NULL*/) + : QtMaemo6Window(mw, parent), + m_menuBar(0), + m_statusBar(0), + m_statusBarParent(0) +{ + m_titleBar = new QtMaemo6TitleBar(NULL); + m_titleBar->setMenuButtonVisible(false); + m_titleBar->setTitle(mw->windowTitle()); + + m_windowLayout->addWidget(m_titleBar, 0, 1); + m_windowLayout->addWidget(m_scrollArea, 1, 1); + + connect(m_titleBar, SIGNAL(closeButtonClicked()), this, SLOT(close())); + connect(m_titleBar, SIGNAL(minimizeButtonClicked()), this, SLOT(hide())); + connect(m_titleBar, SIGNAL(menuLabelClicked()), this, SLOT(showMenuBar())); +} + +QtMaemo6WindowDecoration::~QtMaemo6WindowDecoration() +{ + //the statusBar must not be deleted by the window decoration on destruction + if (m_statusBar) { + m_windowLayout->removeWidget(m_statusBar); + m_statusBar->setParent(m_statusBarParent); + } +} + +void QtMaemo6WindowDecoration::setStatusBar(QStatusBar *statusBar) +{ + if (!m_windowLayout) + return; + + if (statusBar) { + m_statusBarParent = statusBar->parentWidget(); + m_windowLayout->addWidget(statusBar, 2, 1); + } else { + if (m_statusBar) { + m_windowLayout->removeWidget(m_statusBar); + m_statusBar->setParent(m_statusBarParent); + m_statusBarParent = NULL; + } + } + + m_statusBar = statusBar; +} + +void QtMaemo6WindowDecoration::setMenuBar(QMenuBar *menuBar) +{ + if (menuBar) { + m_menuBar = menuBar; + m_titleBar->setMenuButtonVisible(m_menuBar->actions().count() > 0); + } else { + m_menuBar = NULL; + m_titleBar->setMenuButtonVisible(false); + } +} + +void QtMaemo6WindowDecoration::showMenuBar() +{ + if (m_menuBar) { + QtMaemo6MenuProxy *menuProxy = new QtMaemo6MenuProxy(m_menuBar, this); + menuProxy->showFastMaximized(); + } +} + +bool QtMaemo6WindowDecoration::eventFilter(QObject *watched, QEvent *event) +{ + if (event->type() == QEvent::WindowTitleChange) { + m_titleBar->setTitle(m_window->windowTitle()); + } else if (event->type() == QEvent::Close) { + hide(); + } + + return QtMaemo6Window::eventFilter(watched, event); +} + diff --git a/plainqt/style/qtmaemo6windowdecoration.h b/plainqt/style/qtmaemo6windowdecoration.h new file mode 100644 index 000000000..52fc0d9f2 --- /dev/null +++ b/plainqt/style/qtmaemo6windowdecoration.h @@ -0,0 +1,74 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef QTMAEMO6WINDOWDECORATION_H +#define QTMAEMO6WINDOWDECORATION_H + +#include +#include +#include +#include + +#include "qtmaemo6window.h" + +class QStatusBar; +class QtMaemo6TitleBar; +class QVBoxLayout; +class QMenuBar; + +/*! + * this class emulates the dui windowdecoration + * it adds a titlebar and places an statusbar on the bottom of the screen, + * if available + */ +class QtMaemo6WindowDecoration : public QtMaemo6Window +{ + Q_OBJECT +public: + explicit QtMaemo6WindowDecoration(QWidget *mw, QWidget *parent = NULL); + ~QtMaemo6WindowDecoration(); + + /*! + * sets the given statusbar as the applications status bar + * this one stays on the bottom of the screen + * it takes the ownership of the menuBar + */ + void setStatusBar(QStatusBar *statusBar); + + /*! + * sets the menuBar for this windowDecoration + * it takes the ownership of the menuBar + */ + void setMenuBar(QMenuBar *menuBar); +protected Q_SLOTS: + void showMenuBar(); +protected: + QtMaemo6WindowDecoration() {}; + + /*! \reimp */ + bool eventFilter(QObject *obj, QEvent *event); + /*! \reimp_end */ +private: + QtMaemo6TitleBar *m_titleBar; + QMenuBar *m_menuBar; + QStatusBar *m_statusBar; + QWidget *m_statusBarParent; +}; + +#endif diff --git a/plainqt/style/sensorial_bg_3.png b/plainqt/style/sensorial_bg_3.png new file mode 100644 index 000000000..8e21b531f Binary files /dev/null and b/plainqt/style/sensorial_bg_3.png differ diff --git a/plainqt/style/style.pri b/plainqt/style/style.pri new file mode 100644 index 000000000..4eacd9518 --- /dev/null +++ b/plainqt/style/style.pri @@ -0,0 +1,39 @@ +INCLUDEPATH+=../../src/style +#../../src/widgets + +PUBLIC_HEADERS += \ + qtmaemo6style.h + +PRIVATE_HEADERS += \ + qtmaemo6teststyle.h \ + qtmaemo6teststyle_p.h \ + qtmaemo6style_p.h \ + qtmaemo6pangesture.h \ + qtmaemo6styleeventfilter.h \ + qtmaemo6scrollbareventfilter.h \ + qtmaemo6styleplugin.h \ + qtmaemo6titlebar.h \ + qtmaemo6windowdecoration.h \ + qtmaemo6dialogproxy.h \ + qtmaemo6dialogtitle.h \ + qtmaemo6clicklabel.h \ + qtmaemo6window.h \ + qtmaemo6menuproxy.h \ + qtmaemo6menu.h \ + qtmaemo6submenu.h + +SOURCES = \ + qtmaemo6teststyle.cpp \ + qtmaemo6style.cpp \ + qtmaemo6pangesture.cpp \ + qtmaemo6styleeventfilter.cpp \ + qtmaemo6scrollbareventfilter.cpp \ + qtmaemo6styleplugin.cpp \ + qtmaemo6titlebar.cpp \ + qtmaemo6windowdecoration.cpp \ + qtmaemo6dialogproxy.cpp \ + qtmaemo6dialogtitle.cpp \ + qtmaemo6window.cpp \ + qtmaemo6menuproxy.cpp \ + qtmaemo6menu.cpp \ + qtmaemo6submenu.cpp diff --git a/plainqt/style/style.pro b/plainqt/style/style.pro new file mode 100644 index 000000000..d6a1302dd --- /dev/null +++ b/plainqt/style/style.pro @@ -0,0 +1,46 @@ +QMAKE_CXXFLAGS += -Werror + +DUIROOT = ../.. + +include($$DUIROOT/mkspecs/common.pri) + +include(style.pri) + +DUILIB = $$DUIROOT/lib +DUISRC = $$DUIROOT/src +DUISRCINCLUDE = $$DUISRC/include +DUISFWINCLUDE = $$DUIROOT/servicefw/include + +INCLUDEPATH += . \ + $$DUISRCINCLUDE \ + $$DUISRC \ + +QMAKE_LIBDIR += \ + $$DUILIB \ + +win32|macx { + macx { + QMAKE_LFLAGS += -F../../lib + LIBS += -framework dui + } + win32:LIBS += -L../../lib -ldui0 +} else { + LIBS += ../../lib/libdui.so +} + +TEMPLATE = lib + CONFIG += plugin + +TARGET = duiqtstyleplugin +target.path = $$[QT_INSTALL_PLUGINS]/styles + +HEADERS += $$PUBLIC_HEADERS $$PRIVATE_HEADERS + +install_headers.path = $$DUI_INSTALL_HEADERS +install_headers.files = \ + $$PUBLIC_HEADERS + +INSTALLS += target \ + install_headers + +RESOURCES += style.qrc diff --git a/plainqt/style/style.qrc b/plainqt/style/style.qrc new file mode 100644 index 000000000..7635a3d2c --- /dev/null +++ b/plainqt/style/style.qrc @@ -0,0 +1,10 @@ + + + + bg2.png + ../icons/Icon-back.png + ../icons/Icon-close.png + ../icons/Icon-home.png + + + diff --git a/projects.pro b/projects.pro new file mode 100644 index 000000000..c36b483d3 --- /dev/null +++ b/projects.pro @@ -0,0 +1,77 @@ +##################################################################### +# DirectUI project file +##################################################################### + +CONFIG += ordered +TEMPLATE = subdirs + +!win32:!macx { + !exists(mkspecs/duiconfig.pri) { + error("Please run ./configure before proceeding") + } +} + +include(mkspecs/common.pri) +isEqual( IN_PWD, $${OUT_PWD} ) { + IS_OUT_OF_SOURCE = 0 +} else { + IS_OUT_OF_SOURCE = 1 +} + +isEmpty(DUI_BUILD_PARTS) { #defaults + DUI_BUILD_PARTS = libs demos +} else { #make sure the build order makes sense + contains(DUI_BUILD_PARTS, libs) { + DUI_BUILD_PARTS -= libs + DUI_BUILD_PARTS = libs $$DUI_BUILD_PARTS + } +} + +#process the projects +for(PROJECT, $$list($$lower($$unique(DUI_BUILD_PARTS)))) { + isEqual(PROJECT, libs) { + SUBDIRS += \ + duimoc \ + duigen \ + src \ + src/translations \ + + contains(DEFINES, HAVE_DBUS) { + SUBDIRS += \ + duiappletrunner \ + duiservicemapper \ + duithemedaemon \ + tools + } + } else:isEqual(PROJECT, plainqt) { + SUBDIRS += plainqt + } else:isEqual(PROJECT, tests) { + SUBDIRS += tests + macx:SUBDIRS -= tests + win32:SUBDIRS -= tests + } else:isEqual(PROJECT, benchmarks) { + SUBDIRS += benchmarks + macx:SUBDIRS -= benchmarks + win32:SUBDIRS -= benchmarks + } else:isEqual(PROJECT, demos) { + SUBDIRS += demos + } else { + message(Unknown PROJECT: $$PROJECT) + } + + # Docs are always explicitly built with "make doc" + include(doc/doc.pri) +} + +# note: proper way to clean up extradata would be running pkgdata --clean... +# but listing *.a & *.o is easier with qmake +QMAKE_CLEAN += lib/libdui* build-stamp configure-stamp tests/*/*.log.xml tests/*/*.log *.log.xml *.log **/*.gcda extradata/*.o extradata/*.a +QMAKE_DISTCLEAN += lib/libdui* build-stamp configure-stamp tests/*/*.log.xml tests/*/*.log *.log.xml *.log **/*.gcda extradata/*.o extradata/*.a + +check.target = check +check.CONFIG = recursive +QMAKE_EXTRA_TARGETS += check + +check-xml.target = check-xml +check-xml.CONFIG = recursive +QMAKE_EXTRA_TARGETS += check-xml diff --git a/src/.gitignore b/src/.gitignore new file mode 100644 index 000000000..c0dcc9bc6 --- /dev/null +++ b/src/.gitignore @@ -0,0 +1,11 @@ +README_extradata.txt +extradata.dat +extradata_static.lst +extradata_static.mak +libextradata.a +root.res +qtc-gdbmacros/ +Makefile.Debug +Makefile.Release +mashup/mashup/gen_*.* +.gen/ diff --git a/src/Dui.pc b/src/Dui.pc new file mode 100644 index 000000000..3f07d81a0 --- /dev/null +++ b/src/Dui.pc @@ -0,0 +1,11 @@ +prefix=/usr +exec_prefix=${prefix} +libdir=${exec_prefix}/lib +includedir=${prefix}/include/dui + +Name: Dui +Description: DirectUI Framework +Version: 0.18.0 +Requires: QtGui +Cflags: -I${includedir} +Libs: -L${libdir} -ldui diff --git a/src/animation/animation.pri b/src/animation/animation.pri new file mode 100644 index 000000000..8c3f71e94 --- /dev/null +++ b/src/animation/animation.pri @@ -0,0 +1,24 @@ +############################################################################### +# DuiAnimation module +# This module contains all classes that handle animations. +############################################################################### +ANIMATION_SRC_DIR=./animation +INCLUDEPATH+=./animation ./animation/core ./animation/particle ./animation/scene ./animation/widget ./animation/widget/core + +include(core/core.pri) +include(scene/scene.pri) +include(particle/particle.pri) +include(widget/widget.pri) + +#public +HEADERS += \ + $$ANIMATION_SRC_DIR/duiparticlecloud.h \ + $$ANIMATION_SRC_DIR/duiparticleexplosion.h \ + $$ANIMATION_SRC_DIR/duiparticlefountain.h \ + $$ANIMATION_SRC_DIR/duiwidgetanimation.h + +SOURCES += \ + $$ANIMATION_SRC_DIR/duiparticlecloud.cpp \ + $$ANIMATION_SRC_DIR/duiparticleexplosion.cpp \ + $$ANIMATION_SRC_DIR/duiparticlefountain.cpp \ + $$ANIMATION_SRC_DIR/duiwidgetanimation.cpp diff --git a/src/animation/core/core.pri b/src/animation/core/core.pri new file mode 100644 index 000000000..20e0d8f9e --- /dev/null +++ b/src/animation/core/core.pri @@ -0,0 +1,25 @@ +############################################################################### +# DuiAnimation/Core module +# This module contains core animation code. +############################################################################### + +ANIMATIONS_CORE_SRC_DIR=./animation/core + +#public +HEADERS += \ + $$ANIMATIONS_CORE_SRC_DIR/duianimation.h \ + $$ANIMATIONS_CORE_SRC_DIR/duigroupanimation.h \ + $$ANIMATIONS_CORE_SRC_DIR/duianimationcreator.h \ + $$ANIMATIONS_CORE_SRC_DIR/duiparallelanimationgroup.h \ + +#private +HEADERS += \ + $$ANIMATIONS_CORE_SRC_DIR/duianimation_p.h \ + $$ANIMATIONS_CORE_SRC_DIR/duigroupanimation_p.h \ + $$ANIMATIONS_CORE_SRC_DIR/duiparallelanimationgroup_p.h \ + +SOURCES += \ + $$ANIMATIONS_CORE_SRC_DIR/duianimation.cpp \ + $$ANIMATIONS_CORE_SRC_DIR/duigroupanimation.cpp \ + $$ANIMATIONS_CORE_SRC_DIR/duianimationcreator.cpp \ + $$ANIMATIONS_CORE_SRC_DIR/duiparallelanimationgroup.cpp \ diff --git a/src/animation/core/duianimation.cpp b/src/animation/core/duianimation.cpp new file mode 100644 index 000000000..94b75f81f --- /dev/null +++ b/src/animation/core/duianimation.cpp @@ -0,0 +1,89 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duianimation.h" +#include "duianimation_p.h" + +#include "duianimationstyle.h" +#include "duitheme.h" + +// protected constructor +DuiAnimation::DuiAnimation(DuiAnimationPrivate *dd, QObject *parent) : + QAbstractAnimation(parent), + d_ptr(dd) +{ + Q_D(DuiAnimation); + d->q_ptr = this; + d->styleContainer = 0; +} + +// public constructor +DuiAnimation::DuiAnimation(QObject *parent) : + QAbstractAnimation(parent), + d_ptr(new DuiAnimationPrivate) +{ + Q_D(DuiAnimation); + d->q_ptr = this; + d->styleContainer = 0; +} + +// destructor +DuiAnimation::~DuiAnimation() +{ + Q_D(DuiAnimation); + + delete d->styleContainer; + delete d_ptr; +} + +DuiAnimationStyleContainer &DuiAnimation::style() +{ + Q_D(DuiAnimation); + + if (!d->styleContainer) { + d->styleContainer = createStyleContainer(); + d->styleContainer->initialize(objectName(), "", NULL); + } + + return *d->styleContainer; +} + +const DuiAnimationStyleContainer &DuiAnimation::style() const +{ + Q_D(const DuiAnimation); + + if (!d->styleContainer) { + DuiAnimationPrivate *d_p = const_cast(d); + d_p->styleContainer = createStyleContainer(); + d_p->styleContainer->initialize(objectName(), "", NULL); + } + + return *d->styleContainer; +} + +const char *DuiAnimation::styleType() const +{ + return "DuiAnimationStyle"; +} + +DuiAnimationStyleContainer *DuiAnimation::createStyleContainer() const +{ + return new DuiAnimationStyleContainer(); +} + diff --git a/src/animation/core/duianimation.h b/src/animation/core/duianimation.h new file mode 100644 index 000000000..05a2b1f82 --- /dev/null +++ b/src/animation/core/duianimation.h @@ -0,0 +1,150 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIANIMATION_H +#define DUIANIMATION_H + +#define DUI_ANIMATION(STYLE) \ + protected: \ + inline virtual const char* styleType() const { return #STYLE; } \ + virtual DuiAnimationStyleContainer* createStyleContainer() const { return new STYLE##Container(); } \ + private: \ + inline STYLE##Container& style() { return static_cast(DuiAnimation::style()); } \ + inline const STYLE##Container& style() const { return static_cast(DuiAnimation::style()); } + +#include + +#include +#include + + +class DuiAnimationPrivate; + +/*! + * \class DuiAnimation + * \brief DuiAnimation provides an base class for animations. + * + * The class defines the functions for the functionality shared by all DUI + * animations. + * + * By inheriting this class, you can create custom, CSS-styled, animations that + * plug into the rest of the animation framework. + * + * The progress of an animation is given by its current time (currentTime()), + * which is measured in milliseconds from the start of the animation (0) to its + * end (duration()). The value is updated automatically while the animation is + * running. It can also be set directly with setCurrentTime(). + * + * See the base class documentation, QAbstractAnimation, for more details on + * running, pausing and stopping animations. + * + * Classes inheriting from this will need to implement the duration() and + * updateCurrentTime() virtual functions. The duration() function lets you + * report a duration for the animation (see QAbstractAnimation for more details) + * and the animation framework calls updateCurrentTime() when current time has + * changed. By reimplementing this function, you can track the animation + * progress. Note that neither the interval between calls nor the number of + * calls to this function are defined; though, it will normally be 60 updates + * per second. + * + * Classes inheriting DuiAnimation can be integrated into the rest of the Qt animation + * framework, and can be used in a QAnimationGroup, combined with a + * QVariantAnimation etc. + * + * Class inheriting DuiAnimation need to include the DUI_ANIMATION macro in the + * class definiton. For example: + * + * \code + * /// Fade in the given item over a period of 1 second + * class FadeInAnimation : public DuiAnimation { + * Q_OBJECT + * DUI_ANIMATION(FadeInAnimationStyle) + * + * public: + * FadeInAnimation(QGraphicsItem *item, QObject *parent = NULL) : DuiAnimation(parent),mItem(item); + * virtual void updateCurrentTime (int currentTime ) { + * item->setOpacity(currentTime/1000.0); + * } + * virtual int duration () const { return 1000; } + * protected: + * QGraphicsItem *item; + * }; + * \endcode + * + */ +class DUI_EXPORT DuiAnimation : public QAbstractAnimation +{ + Q_OBJECT + Q_DECLARE_PRIVATE(DuiAnimation) + +public: + /*! \brief Constructs the DuiAnimation base class, and passes + * \p parent to the QAbstractAnimation's constructor. + * + * \sa QAbstractAnimation, QAnimationGroup, QVariantAnimation, DuiGroupAnimation + */ + DuiAnimation(QObject *parent = NULL); + + /*! \brief Stops the animation if it's running, then destroys the DuiAnimation. + * + * If the animation is part of a QAnimationGroup, it is automatically removed + * before it's destroyed. + */ + virtual ~DuiAnimation(); + +protected: + /*! \brief Returns a style container object for this animation. + * + * The DUI_ANIMATION macro, added to inheriting classes, overrides this + * method with return the correct type. + */ + DuiAnimationStyleContainer &style(); + /*! \brief Returns a style container object for this animation - const version. + * + * The DUI_ANIMATION macro, added to inheriting classes, overrides this + * method to return the correct type. + */ + const DuiAnimationStyleContainer &style() const; + + /*! \brief Returns the type of the style this animation uses. + * + * This is the name used in the CSS file. + * + * The DUI_ANIMATION macro, added to inheriting classes, overrides this + * method with correct return type. + */ + virtual const char *styleType() const; + + /*! \brief Instantiates a style container for this animation. + * + * The DUI_ANIMATION macro, added to inheriting classes, overrides this + * method with correct return type. + */ + virtual DuiAnimationStyleContainer *createStyleContainer() const; + +protected: + /*! \internal */ + DuiAnimationPrivate *const d_ptr; + DuiAnimation(DuiAnimationPrivate *dd, QObject *parent); + /*! \internal_end */ + + +}; + +#endif diff --git a/src/animation/core/duianimation_p.h b/src/animation/core/duianimation_p.h new file mode 100644 index 000000000..68afc116b --- /dev/null +++ b/src/animation/core/duianimation_p.h @@ -0,0 +1,36 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIANIMATION_P_H +#define DUIANIMATION_P_H + +class DuiAnimationStyleContainer; + +class DuiAnimationPrivate +{ + Q_DECLARE_PUBLIC(DuiAnimation) +public: + virtual ~DuiAnimationPrivate() {} +protected: + class DuiAnimation *q_ptr; +private: + DuiAnimationStyleContainer *styleContainer; +}; + +#endif diff --git a/src/animation/core/duianimationcreator.cpp b/src/animation/core/duianimationcreator.cpp new file mode 100644 index 000000000..7858d501b --- /dev/null +++ b/src/animation/core/duianimationcreator.cpp @@ -0,0 +1,32 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duianimationcreator.h" +#include "duiclassfactory.h" + +DuiAnimationCreatorBase::DuiAnimationCreatorBase(const char *animationClassName) +{ + DuiClassFactory::instance()->registerAnimationCreator(this, animationClassName); +} + +DuiAnimationCreatorBase::~DuiAnimationCreatorBase() +{ + DuiClassFactory::instance()->unregisterAnimationCreator(this); +} + diff --git a/src/animation/core/duianimationcreator.h b/src/animation/core/duianimationcreator.h new file mode 100644 index 000000000..799a90c00 --- /dev/null +++ b/src/animation/core/duianimationcreator.h @@ -0,0 +1,74 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIANIMATIONCREATOR_H +#define DUIANIMATIONCREATOR_H + +#include "duiexport.h" + +#define DUI_REGISTER_ANIMATION(ANIMATION) \ + static const DuiAnimationCreator g_AnimationCreator(#ANIMATION); + +// forward declarations +class DuiAnimation; + +/*! + Interface for DuiAnimationCreators + you can implement your own creator or use DuiAnimationCreator template class with + DUI_REGISTER_ANIMATION-macro. + */ +class DUI_EXPORT DuiAnimationCreatorBase +{ +public: + /*! + Constructor + Registers this creator instance to DuiClassFactory. + */ + DuiAnimationCreatorBase(const char *animationClassName); + + /*! + Destructor + Unregisters this creator instance from DuiClassFactory. + */ + virtual ~DuiAnimationCreatorBase(); + + /*! + Returns a new animation instance. + Ownership is transferred to caller. + */ + virtual DuiAnimation *create() const = 0; +}; + +template +class DUI_EXPORT DuiAnimationCreator : public DuiAnimationCreatorBase +{ +public: + DuiAnimationCreator(const char *animationClassName) : + DuiAnimationCreatorBase(animationClassName) + {} + virtual ~DuiAnimationCreator() + {} + + virtual DuiAnimation *create() const { + return new ANIMATION(); + } +}; + +#endif + diff --git a/src/animation/core/duigroupanimation.cpp b/src/animation/core/duigroupanimation.cpp new file mode 100644 index 000000000..92d15028b --- /dev/null +++ b/src/animation/core/duigroupanimation.cpp @@ -0,0 +1,107 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duigroupanimation.h" +#include "duigroupanimation_p.h" + +#include +#include + +void DuiGroupAnimationPrivate::init(DuiGroupAnimation::Type type) +{ + Q_Q(DuiGroupAnimation); + + if (type == DuiGroupAnimation::Parallel) { + group = new QParallelAnimationGroup(q); + } else { + group = new QSequentialAnimationGroup(q); + } +} + +// protected constructor +DuiGroupAnimation::DuiGroupAnimation(DuiGroupAnimationPrivate *dd, DuiGroupAnimation::Type type, QObject *parent) : + DuiAnimation(dd, parent) +{ + Q_D(DuiGroupAnimation); + d->init(type); +} + +// public constructor +DuiGroupAnimation::DuiGroupAnimation(DuiGroupAnimation::Type type, QObject *parent) : + DuiAnimation(new DuiGroupAnimationPrivate, parent) +{ + Q_D(DuiGroupAnimation); + d->init(type); +} + +// destructor +DuiGroupAnimation::~DuiGroupAnimation() +{ + // no need to delete d->group (Qt's parent-child relationship) +} + +int DuiGroupAnimation::duration() const +{ + Q_D(const DuiGroupAnimation); + return d->group->duration(); +} + +QAnimationGroup *DuiGroupAnimation::group() +{ + Q_D(DuiGroupAnimation); + return d->group; +} + +const QAnimationGroup *DuiGroupAnimation::group() const +{ + Q_D(const DuiGroupAnimation); + return d->group; +} + +void DuiGroupAnimation::updateCurrentTime(int msecs) +{ + Q_D(DuiGroupAnimation); + d->group->setCurrentTime(msecs); +} + +void DuiGroupAnimation::updateState(QAbstractAnimation::State oldState, + QAbstractAnimation::State newState) +{ + Q_UNUSED(oldState); + Q_D(DuiGroupAnimation); + switch (newState) { + case Stopped: + d->group->stop(); + break; + case Paused: + d->group->pause(); + break; + case Running: + d->group->start(); + break; + default: + break; + } +} + +void DuiGroupAnimation::updateDirection(QAbstractAnimation::Direction direction) +{ + Q_D(DuiGroupAnimation); + d->group->setDirection(direction); +} diff --git a/src/animation/core/duigroupanimation.h b/src/animation/core/duigroupanimation.h new file mode 100644 index 000000000..81fc07721 --- /dev/null +++ b/src/animation/core/duigroupanimation.h @@ -0,0 +1,89 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIGROUPANIMATION_H +#define DUIGROUPANIMATION_H + +#include + +#include + +class DuiGroupAnimationPrivate; + +/*! \brief DuiGroupAnimation provides an base class for groups of animations. + */ +class DUI_EXPORT DuiGroupAnimation : public DuiAnimation +{ + Q_OBJECT + Q_DECLARE_PRIVATE(DuiGroupAnimation) + DUI_ANIMATION(DuiGroupAnimationStyle) + +public: + enum Type { + Parallel, + Sequential + }; + +protected: + /*! + \brief Constructs the animation with parallel animation group inside. + + This constructor is meant to be used inside the libdui to share the + private data class pointer. + */ + DuiGroupAnimation(DuiGroupAnimationPrivate *dd, DuiGroupAnimation::Type type = Parallel, QObject *parent = 0); + +public: + /*! + \brief Constructs the animation with paraller animation group inside. + */ + DuiGroupAnimation(DuiGroupAnimation::Type type = Parallel, QObject *parent = NULL); + + /*! + \brief Destructs the animation and all subanimations. + */ + virtual ~DuiGroupAnimation(); + + //! \reimp + // from QtAbstractAnimation + virtual int duration() const; + //! \reimp_end + +protected: + /*! + \brief Getter for the main animation group. + + Derived classes can use this to populate the animation group hierarchy. + */ + QAnimationGroup *group(); + + /*! + \brief Const getter for the main animation group. + */ + const QAnimationGroup *group() const; + + //! \reimp + // from QtAbstractAnimation + virtual void updateCurrentTime(int msecs); + virtual void updateState(QAbstractAnimation::State oldState, QAbstractAnimation::State newState); + virtual void updateDirection(QAbstractAnimation::Direction direction); + //! \reimp_end +}; + +#endif diff --git a/src/animation/core/duigroupanimation_p.h b/src/animation/core/duigroupanimation_p.h new file mode 100644 index 000000000..870723943 --- /dev/null +++ b/src/animation/core/duigroupanimation_p.h @@ -0,0 +1,38 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIGROUPANIMATION_P_H +#define DUIGROUPANIMATION_P_H + +class QAnimationGroup; + +#include "duianimation_p.h" +#include "duigroupanimation.h" + +class DuiGroupAnimationPrivate : public DuiAnimationPrivate +{ + Q_DECLARE_PUBLIC(DuiGroupAnimation) +private: + class QAnimationGroup *group; + +public: + void init(DuiGroupAnimation::Type type); +}; + +#endif diff --git a/src/animation/core/duiparallelanimationgroup.cpp b/src/animation/core/duiparallelanimationgroup.cpp new file mode 100644 index 000000000..f58ece94a --- /dev/null +++ b/src/animation/core/duiparallelanimationgroup.cpp @@ -0,0 +1,89 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiparallelanimationgroup.h" +#include "duiparallelanimationgroup_p.h" + +#include "duianimationstyle.h" +#include "duitheme.h" + +// protected constructor +DuiParallelAnimationGroup::DuiParallelAnimationGroup(DuiParallelAnimationGroupPrivate *dd, QObject *parent) : + QParallelAnimationGroup(parent), + d_ptr(dd) +{ + Q_D(DuiParallelAnimationGroup); + d->q_ptr = this; + d->styleContainer = 0; +} + +// public constructor +DuiParallelAnimationGroup::DuiParallelAnimationGroup(QObject *parent) : + QParallelAnimationGroup(parent), + d_ptr(new DuiParallelAnimationGroupPrivate) +{ + Q_D(DuiParallelAnimationGroup); + d->q_ptr = this; + d->styleContainer = 0; +} + +// destructor +DuiParallelAnimationGroup::~DuiParallelAnimationGroup() +{ + Q_D(DuiParallelAnimationGroup); + + delete d->styleContainer; + delete d_ptr; +} + +DuiAnimationStyleContainer &DuiParallelAnimationGroup::style() +{ + Q_D(DuiParallelAnimationGroup); + + if (!d->styleContainer) { + d->styleContainer = createStyleContainer(); + d->styleContainer->initialize(objectName(), "", NULL); + } + + return *d->styleContainer; +} + +const DuiAnimationStyleContainer &DuiParallelAnimationGroup::style() const +{ + Q_D(const DuiParallelAnimationGroup); + + if (!d->styleContainer) { + DuiParallelAnimationGroupPrivate *d_p = const_cast(d); + d_p->styleContainer = createStyleContainer(); + d_p->styleContainer->initialize(objectName(), "", NULL); + } + + return *d->styleContainer; +} + +const char *DuiParallelAnimationGroup::styleType() const +{ + return "DuiAnimationStyle"; +} + +DuiAnimationStyleContainer *DuiParallelAnimationGroup::createStyleContainer() const +{ + return new DuiAnimationStyleContainer(); +} + diff --git a/src/animation/core/duiparallelanimationgroup.h b/src/animation/core/duiparallelanimationgroup.h new file mode 100644 index 000000000..655653593 --- /dev/null +++ b/src/animation/core/duiparallelanimationgroup.h @@ -0,0 +1,136 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIPARALLELANIMATIONGROUP_H +#define DUIPARALLELANIMATIONGROUP_H + +#define DUI_ANIMATION_GROUP(STYLE) \ + protected: \ + inline virtual const char* styleType() const { return #STYLE; } \ + virtual DuiAnimationStyleContainer* createStyleContainer() const { return new STYLE##Container(); } \ + private: \ + inline STYLE##Container& style() { return static_cast(DuiParallelAnimationGroup::style()); } \ + inline const STYLE##Container& style() const { return static_cast(DuiParallelAnimationGroup::style()); } + +#include + +#include +#include + + +class DuiParallelAnimationGroupPrivate; + +/*! + \class DuiParallelAnimationGroup + \brief DuiParallelAnimationGroup provides styling support for QParallelAnimationGroup. + + This class extends QParallelAnimationGroup with a style() function, through which + a DuiAnimationStyleContainer derived class can be obtained containing a set of + animation properties read from CSS. + + This class is not meant to be used directly, itstead it serves as a base class for + other animations. Classes deriving from DuiParallelAnimationGroup should implement + a style derived from DuiAnimationStyle that describes the style properties of the + animations in the group. + + Classes inheriting DuiParallelAnimationGroup need to include the DUI_ANIMATION_GROUP + macro in the class definiton, specifying the classname of the style to be used. + For example: + + \code + // Fade out the given item with the duration and easing defined in the style + class FadeOutAnimation : public DuiParallelAnimationGroup { + Q_OBJECT + DUI_ANIMATION_GROUP(FadeOutAnimationStyle) + + public: + FadeOutAnimation(QGraphicsItem *item, QObject *parent = NULL) + : DuiParallelAnimationGroup(parent) + { + QPropertyAnimation *opacityAnimation = new QPropertyAnimation; + opacityAnimation->setPropertyName("opacity"); + opacityAnimation->setEasingCurve(style()->easingCurve()); + opacityAnimation->setDuration(style()->duration()); + opacityAnimation->setEndValue(0.0); + opacityAnimation->setTargetObject(item); + + addAnimation(opacityAnimation); + } + }; + \endcode + + */ +class DuiParallelAnimationGroup : public QParallelAnimationGroup +{ + Q_OBJECT + Q_DECLARE_PRIVATE(DuiParallelAnimationGroup) + +public: + /*! \brief Constructs the DuiParallelAnimationGroup base class, and passes + \p parent to the QParallelAnimationGroup's constructor. + + \sa QParallelAnimationGroup, QAnimationGroup, QVariantAnimation + */ + DuiParallelAnimationGroup(QObject *parent = NULL); + + /*! \brief Stops the animation if it's running, then destroys the DuiParallelAnimationGroup. + + If the animation is part of a QAnimationGroup, it is automatically removed + before it's destroyed. + */ + virtual ~DuiParallelAnimationGroup(); + +protected: + /*! \brief Returns a style container object for this animation. + + The DUI_ANIMATION_GROUP macro, added to inheriting classes, overrides this + method to return the correct type. + */ + DuiAnimationStyleContainer &style(); + /*! \brief Returns a style container object for this animation - const version. + + The DUI_ANIMATION_GROUP macro, added to inheriting classes, overrides this + method to return the correct type. + */ + const DuiAnimationStyleContainer &style() const; + + /*! \brief Returns the type of the style this animation uses. + + This is the name used in the CSS file. + + The DUI_ANIMATION_GROUP macro, added to inheriting classes, overrides this + method to return the correct type. + */ + virtual const char *styleType() const; + + /*! \brief Instantiates a style container for this animation. + + The DUI_ANIMATION macro, added to inheriting classes, overrides this + method to return the correct type. + */ + virtual DuiAnimationStyleContainer *createStyleContainer() const; + +protected: + /*! \internal */ + DuiParallelAnimationGroupPrivate *const d_ptr; + DuiParallelAnimationGroup(DuiParallelAnimationGroupPrivate *dd, QObject *parent); + /*! \internal_end */ +}; + +#endif diff --git a/src/animation/core/duiparallelanimationgroup_p.h b/src/animation/core/duiparallelanimationgroup_p.h new file mode 100644 index 000000000..76418ae46 --- /dev/null +++ b/src/animation/core/duiparallelanimationgroup_p.h @@ -0,0 +1,36 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIPARALLELANIMATIONGROUP_P_H +#define DUIPARALLELANIMATIONGROUP_P_H + +class DuiAnimationStyleContainer; + +class DuiParallelAnimationGroupPrivate +{ + Q_DECLARE_PUBLIC(DuiParallelAnimationGroup) +public: + virtual ~DuiParallelAnimationGroupPrivate() {} +protected: + class DuiParallelAnimationGroup *q_ptr; +private: + DuiAnimationStyleContainer *styleContainer; +}; + +#endif diff --git a/src/animation/duiparticlecloud.cpp b/src/animation/duiparticlecloud.cpp new file mode 100644 index 000000000..242976869 --- /dev/null +++ b/src/animation/duiparticlecloud.cpp @@ -0,0 +1,91 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiparticlecloud.h" + +#include +#if QT_VERSION >= 0x040600 + +#include "duiscenemanager.h" +#include + +DuiParticleCloud::DuiParticleCloud(QObject *parent) : + DuiParticleEngine(parent, DuiParticleEngine::Continuous) +{ +} + +DuiParticleCloud::~DuiParticleCloud() +{ +} + +int DuiParticleCloud::duration() const +{ + return -1; +} + +void DuiParticleCloud::setPos(const QPointF &pos) +{ + position = pos; +} + +void DuiParticleCloud::initParticle(DuiParticle &p, int curmsecs) +{ + p.alive = true; + + qreal targetX, targetY; + int size = 50; + int margin = 30; + + qreal dir = qrand() % 360; + qreal dist = size + qrand() % margin; + + targetX = cos(dir) * dist + position.x(); + targetY = sin(dir) * dist + position.y(); + + if (curmsecs == 0) { + p.px = targetX;//position.x(); + p.py = targetY;//position.y(); + } + + qreal t = 1000 + qrand() % 1000; + p.vx *= 0.5; + p.vy *= 0.5; + + p.killtime = curmsecs + t; + p.birthtime = curmsecs; + + p.ax = 2.0 * (targetX - p.vx * t - p.px) / (t * t); + p.ay = 2.0 * (targetY - p.vy * t - p.py) / (t * t); + + //p.color = qRgba(/*qrand() % 128, qrand() % 128,*/255,255, 128 + qrand() % 128, 0); + //p.color = qRgba(/*qrand() % 128, qrand() % 128,*/255,255, 0 + qrand() % 255, 0); + p.color = qRgba(qrand() % 164, qrand() % 128, 196 + qrand() % 60, 0); +} + +void DuiParticleCloud::stepParticle(DuiParticle &p, int dt, int msecs) +{ + qreal x = sin(3.1415 * (msecs - p.birthtime) / (p.killtime - p.birthtime)); + p.color = qRgba(qRed(p.color), qGreen(p.color), qBlue(p.color), 255.0 * x); + p.scale = x; + + DuiParticleEngine::stepParticle(p, dt, msecs); +} + +#endif + diff --git a/src/animation/duiparticlecloud.h b/src/animation/duiparticlecloud.h new file mode 100644 index 000000000..81d4e4525 --- /dev/null +++ b/src/animation/duiparticlecloud.h @@ -0,0 +1,48 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIPARTICLECLOUD_H +#define DUIPARTICLECLOUD_H + +#include +#if QT_VERSION >= 0x040600 + +#include "particle/duiparticleengine.h" + + +class DuiParticleCloud : public DuiParticleEngine +{ +public: + DuiParticleCloud(QObject *parent); + virtual ~DuiParticleCloud(); + + virtual int duration() const; + void setPos(const QPointF &pos); + +protected: + virtual void initParticle(DuiParticle &p, int curmsecs); + virtual void stepParticle(DuiParticle &p, int dt, int msecs); +private: + QPointF position; +}; + +#endif + +#endif + diff --git a/src/animation/duiparticleexplosion.cpp b/src/animation/duiparticleexplosion.cpp new file mode 100644 index 000000000..e2da482e5 --- /dev/null +++ b/src/animation/duiparticleexplosion.cpp @@ -0,0 +1,65 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiparticleexplosion.h" + +#include +#if QT_VERSION >= 0x040600 + +#include + +DuiParticleExplosion::DuiParticleExplosion(QObject *parent) : + DuiParticleEngine(parent, DuiParticleEngine::Single) +{ +} + +DuiParticleExplosion::~DuiParticleExplosion() +{ +} + +int DuiParticleExplosion::duration() const +{ + return -1; +} + +void DuiParticleExplosion::setPos(const QPointF &pos) +{ + position = pos; +} + +void DuiParticleExplosion::initParticle(DuiParticle &p, int curmsecs) +{ + p.alive = true; + p.px = position.x(); + p.py = position.y(); + + qreal vel = 0.05 + 0.5 * (qrand() % 1000) / 1000.0; + qreal dir = (qrand() % 61415) / 10000.0; // dir = [0, 2PI] + + p.vx = sin(dir) * vel; + p.vy = cos(dir) * vel; + + p.ax = -p.vx * 0.001; + p.ay = -p.vy * 0.001; + + p.killtime = curmsecs + 5000; +} + +#endif + diff --git a/src/animation/duiparticleexplosion.h b/src/animation/duiparticleexplosion.h new file mode 100644 index 000000000..8ec2d397f --- /dev/null +++ b/src/animation/duiparticleexplosion.h @@ -0,0 +1,47 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIPARTICLEEXPLOSION_H +#define DUIPARTICLEEXPLOSION_H + +#include +#if QT_VERSION >= 0x040600 + +#include "particle/duiparticleengine.h" + + +class DuiParticleExplosion : public DuiParticleEngine +{ +public: + DuiParticleExplosion(QObject *parent); + virtual ~DuiParticleExplosion(); + + virtual int duration() const; + void setPos(const QPointF &pos); + +protected: + virtual void initParticle(DuiParticle &p, int curmsecs); +private: + QPointF position; +}; + +#endif + +#endif + diff --git a/src/animation/duiparticlefountain.cpp b/src/animation/duiparticlefountain.cpp new file mode 100644 index 000000000..a5a94b3f9 --- /dev/null +++ b/src/animation/duiparticlefountain.cpp @@ -0,0 +1,59 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiparticlefountain.h" + +#include +#if QT_VERSION >= 0x040600 + +#include + +DuiParticleFountain::DuiParticleFountain(QObject *parent) : + DuiParticleEngine(parent, DuiParticleEngine::Continuous) +{ +} + +DuiParticleFountain::~DuiParticleFountain() +{ +} + +int DuiParticleFountain::duration() const +{ + return -1; +} + +void DuiParticleFountain::initParticle(DuiParticle &p, int curmsecs) +{ + p.alive = true; + p.px = 864 / 2; + p.py = 480 / 2; + + p.vx = -0.1 + 0.2 * (qrand() % 1000) / 1000.0; + p.vy = -0.3 - 0.2 * (qrand() % 1000) / 1000.0; + + p.ax = 0; + p.ay = 0.0005; + + p.color = qRgba(qrand() % 255, qrand() % 255, qrand() % 255, 255); + + p.killtime = curmsecs + 1000 + qrand() % 1000; +} + +#endif + diff --git a/src/animation/duiparticlefountain.h b/src/animation/duiparticlefountain.h new file mode 100644 index 000000000..ab4adbafc --- /dev/null +++ b/src/animation/duiparticlefountain.h @@ -0,0 +1,43 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIPARTICLEFOUNTAIN_H +#define DUIPARTICLEFOUNTAIN_H + +#include "particle/duiparticleengine.h" + +#include +#if QT_VERSION >= 0x040600 + +class DuiParticleFountain : public DuiParticleEngine +{ +public: + DuiParticleFountain(QObject *parent); + virtual ~DuiParticleFountain(); + + virtual int duration() const; + +protected: + virtual void initParticle(DuiParticle &p, int curmsecs); +}; + +#endif + +#endif + diff --git a/src/animation/duiwidgetanimation.cpp b/src/animation/duiwidgetanimation.cpp new file mode 100644 index 000000000..042eb97de --- /dev/null +++ b/src/animation/duiwidgetanimation.cpp @@ -0,0 +1,248 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiwidgetanimation.h" + +#if QT_VERSION >= 0x040600 + +#include "duiwidgetanimation_p.h" + +#include +#include +#include + +DuiWidgetAnimationPrivate::DuiWidgetAnimationPrivate() + : duration(500), + easingCurve() +{ +} + +DuiWidgetAnimationPrivate::~DuiWidgetAnimationPrivate() +{ +} + +QPropertyAnimation *DuiWidgetAnimationPrivate::getAnimation(QGraphicsWidget *widget, const QString &property) +{ + Q_Q(DuiWidgetAnimation); + + if (!animations.contains(widget)) + animations.insert(widget, Animations()); + + Animations &animationList = animations[widget]; + QPropertyAnimation *animation = animationList.value(property, NULL); + if (animation) { + return animation; + } else { + QPropertyAnimation *a = new QPropertyAnimation(); + a->setTargetObject(widget); + a->setPropertyName(property.toAscii()); + a->setDuration(duration); + a->setEasingCurve(easingCurve); + animationList.insert(property, a); + q->group()->addAnimation(a); + return a; + } +} + +void DuiWidgetAnimationPrivate::setTargetForAllWidgets(const QString &property, const QVariant &value) +{ + QMapIterator i(animations); + while (i.hasNext()) { + QGraphicsWidget *widget = i.key(); + QPropertyAnimation *a = getAnimation(widget, property); + if (a) { + a->setStartValue(widget->property(property.toAscii())); + a->setEndValue(value); + } + } +} + +// protected constructor +DuiWidgetAnimation::DuiWidgetAnimation(DuiWidgetAnimationPrivate *dd, QObject *parent) : + DuiGroupAnimation(dd, DuiGroupAnimation::Parallel, parent) +{ +} + +// public constructor +DuiWidgetAnimation::DuiWidgetAnimation(QObject *parent) : + DuiGroupAnimation(new DuiWidgetAnimationPrivate, DuiGroupAnimation::Parallel, parent) +{ +} + +// destructor +DuiWidgetAnimation::~DuiWidgetAnimation() +{ +} + +void DuiWidgetAnimation::addWidget(QGraphicsWidget *widget) +{ + Q_D(DuiWidgetAnimation); + + d->animations.insert(widget, Animations()); +} + +void DuiWidgetAnimation::removeWidget(QGraphicsWidget *widget) +{ + Q_D(DuiWidgetAnimation); + + if (d->animations.contains(widget)) { + Animations &animationList = d->animations[widget]; + + foreach(QPropertyAnimation * animation, animationList) { + group()->removeAnimation(animation); + delete animation; + } + + d->animations.remove(widget); + } +} + +void DuiWidgetAnimation::setDuration(int msecs, const QString &property) +{ + Q_D(DuiWidgetAnimation); + + if (property.isEmpty()) + d->duration = msecs; + + foreach(const Animations & list, d->animations) { + + if (property.isEmpty()) { + foreach(QPropertyAnimation * a, list) { + a->setDuration(msecs); + } + } else { + QPropertyAnimation *a = list.value(property, NULL); + if (a) { + a->setDuration(msecs); + } + } + } +} + +void DuiWidgetAnimation::setEasingCurve(const QEasingCurve &curve, const QString &property) +{ + Q_D(DuiWidgetAnimation); + + if (property.isEmpty()) + d->easingCurve = curve; + + foreach(const Animations & list, d->animations) { + + if (property.isEmpty()) { + foreach(QPropertyAnimation * a, list) { + a->setEasingCurve(curve); + } + } else { + QPropertyAnimation *a = list.value(property, NULL); + if (a) { + a->setEasingCurve(curve); + } + } + } +} + +//void setSourceValue(const QString& property, const QVariant& value); +//void enableAnimation(const QString& property, bool enable); + +void DuiWidgetAnimation::setTargetValue(QGraphicsWidget *widget, const QString &property, const QVariant &value) +{ + Q_D(DuiWidgetAnimation); + if (!widget) + d->setTargetForAllWidgets(property, value); + else { + d->getAnimation(widget, property)->setStartValue(widget->property(property.toAscii())); + d->getAnimation(widget, property)->setEndValue(value); + } +} + +void DuiWidgetAnimation::setKeyFrameAt(QGraphicsWidget *widget, const QString &property, qreal step, const QVariant &value) +{ + Q_D(DuiWidgetAnimation); + d->getAnimation(widget, property)->setKeyValueAt(step, value); +} + +void DuiWidgetAnimation::setKeyFrames(QGraphicsWidget *widget, const QString &property, const QVector& values) +{ + const int valuesSize = values.size(); + Q_D(DuiWidgetAnimation); + if (valuesSize == 0) + return; + else if (valuesSize == 1) { + d->getAnimation(widget, property)->setKeyValueAt(1.0, values.last()); + } + + QPropertyAnimation *a = d->getAnimation(widget, property); + const qreal step = 1.0 / (valuesSize - 1); + for (int i = 0; i < valuesSize - 1; ++i) { + a->setKeyValueAt(i * step, values[i]); + } + a->setKeyValueAt(1.0, values.last()); +} + +void DuiWidgetAnimation::setKeyFrames(QGraphicsWidget *widget, const QString &property, const QVector< QPair >& values) +{ + Q_D(DuiWidgetAnimation); + d->getAnimation(widget, property)->setKeyValues(values); +} + +void DuiWidgetAnimation::setTargetGeometry(QGraphicsWidget *widget, const QRectF &target) +{ + Q_D(DuiWidgetAnimation); + if (!widget) + d->setTargetForAllWidgets("geometry", target); + else { + d->getAnimation(widget, "geometry")->setStartValue(widget->geometry()); + d->getAnimation(widget, "geometry")->setEndValue(target); + } +} + +void DuiWidgetAnimation::setTargetOpacity(QGraphicsWidget *widget, qreal target) +{ + Q_D(DuiWidgetAnimation); + if (!widget) + d->setTargetForAllWidgets("opacity", target); + else { + d->getAnimation(widget, "opacity")->setStartValue(widget->opacity()); + d->getAnimation(widget, "opacity")->setEndValue(target); + } +} + +void DuiWidgetAnimation::setTargetSize(QGraphicsWidget *widget, const QSizeF &target) +{ + Q_D(DuiWidgetAnimation); + if (!widget) + d->setTargetForAllWidgets("size", target); + else { + d->getAnimation(widget, "size")->setStartValue(widget->size()); + d->getAnimation(widget, "size")->setEndValue(target); + } +} + +void DuiWidgetAnimation::setTargetPosition(QGraphicsWidget *widget, const QPointF &target) +{ + Q_D(DuiWidgetAnimation); + if (!widget) + d->setTargetForAllWidgets("pos", target); + else { + d->getAnimation(widget, "pos")->setStartValue(widget->pos()); + d->getAnimation(widget, "pos")->setEndValue(target); + } +} +#endif + diff --git a/src/animation/duiwidgetanimation.h b/src/animation/duiwidgetanimation.h new file mode 100644 index 000000000..6f64687b2 --- /dev/null +++ b/src/animation/duiwidgetanimation.h @@ -0,0 +1,210 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIWIDGETANIMATION_H +#define DUIWIDGETANIMATION_H + +#include + +#include +#include +#include +#include + +class DuiWidgetAnimationPrivate; +class QGraphicsWidget; +class QEasingCurve; +class QRectF; +class QSizeF; +class QPointF; + +/*! + \class DuiWidgetAnimation + \brief DuiWidgetAnimation class provides easy to use interface for animating + widgets. + + The class is based on the QVariantAnimation and QAnimationGroup classes. A + single QVariantAnimation class offers only interface for animating single + property of a single object. DuiWidgetAnimation combines these two animation + classes and provides an easy to use interface for animating several objects and + properties at the same time. + + \section examples Examples + + Animate single widget from it's current position to another. + \code + DuiWidgetAnimation* a = new DuiWidgetAnimation(NULL); + a->setTargetPosition(widget, QPointF(50,50)); + a->start(QAbstractAnimation::DeleteWhenStopped); + \endcode + + Animate several widgets at the same time. + \code + DuiWidgetAnimation* a = new DuiWidgetAnimation(NULL); + a->setTargetOpacity(widget0, 0.0); + a->setTargetOpacity(widget1, 0.0); + a->setTargetOpacity(widget2, 0.0); + a->setTargetOpacity(widget3, 0.0); + a->start(QAbstractAnimation::DeleteWhenStopped); + \endcode + + Animate multiple properties at different speed. + \code + DuiWidgetAnimation* a = new DuiWidgetAnimation(NULL); + a->setTargetOpacity(widget, 0.0); + a->setDuration(1000, "opacity"); + a->setTargetGeometry(widget, QRecF(0,0,50,50)); + a->setDuration(500, "geometry"); + a->start(QAbstractAnimation::DeleteWhenStopped); + \endcode + + Keyframed animation. + \code + DuiWidgetAnimation* a = new DuiWidgetAnimation(NULL); + QVector keyframes; + keyframes.add(QPointF(50,50)); + keyframes.add(QPointF(75,50)); + keyframes.add(QPointF(125,10)); + a->setKeyframes(widget, "position", keyframes); + a->start(QAbstractAnimation::DeleteWhenStopped); + \endcode + */ +class DuiWidgetAnimation : public DuiGroupAnimation +{ + Q_OBJECT + Q_DECLARE_PRIVATE(DuiWidgetAnimation) + DUI_ANIMATION(DuiAnimationStyle) + + /*! + \brief Constructs the widget animation. + + This constructor is meant to be used inside the libdui to share the + private data class pointer. + */ + DuiWidgetAnimation(DuiWidgetAnimationPrivate *dd, QObject *parent); + +public: + + /*! + \brief Constructs the widget animation. + */ + DuiWidgetAnimation(QObject *parent = NULL); + + /*! + \brief Destructs the widget animation. + */ + virtual ~DuiWidgetAnimation(); + + /*! + \brief Add new widget to animation + */ + void addWidget(QGraphicsWidget *widget); + + /*! + \brief Remove widget from animation + */ + void removeWidget(QGraphicsWidget *widget); + + /*! + \brief Set duration for an animation. + + If \a property equals to empty string the \a duration is used for all the + different property animations. If \a property defines a valid property + name the duration of the specific property animation is set. + */ + void setDuration(int msecs, const QString &property = QString()); + + /*! + \brief Set easing curve for an animation. + + If \a property equals to empty string the \a curve is used for all the + different property animations. If \a property defines a valid property + name the curve of the specific property animation is set. + */ + void setEasingCurve(const QEasingCurve &curve, const QString &property = QString()); + + /*! + \brief Sets target value for a property animation. + */ + void setTargetValue(QGraphicsWidget *widget, const QString &property, const QVariant &value); + //void enableAnimation(const QString& property, bool enable); + //void setSourceValue(const QString& property, const QVariant& value); + + /*! + \brief Creates a key frame for \a property at the given \a step with the given \a value. + + The given \a step must be in the range 0.0 to 1.0. + */ + void setKeyFrameAt(QGraphicsWidget *widget, const QString &property, qreal step, const QVariant &value); + + /*! + \brief Initializes keyframe animation for \a property with given keyframe \a values. + + The steps between the keyframes are equally sized. + */ + void setKeyFrames(QGraphicsWidget *widget, const QString &property, const QVector& values); + + /*! + \brief Initializes keyframe animation for \a property with given keyframe step and values pairs. + */ + void setKeyFrames(QGraphicsWidget *widget, const QString &property, const QVector< QPair >& values); + + //void setKeyframeAt(qreal step, const QRect& value); + //void setKeyframeAt(qreal step, qreal value); + //void setKeyframeAt(qreal step, const QSize& value); + //void setKeyframeAt(qreal step, const PointF& value); + + /*! + \brief Sets target for geometry animation. If \a widget == NULL, the same target + is set for all the added widgets, otherwise the target is set only for the + specific widget. + */ + void setTargetGeometry(QGraphicsWidget *widget, const QRectF &target); + //void enableGeometryAnimation(bool enable); + //void setSourceGeometry(const QRectF& geometry); + + /*! + \brief Sets target for opacity animation. If \a widget == NULL, the same target + is set for all the added widgets, otherwise the target is set only for the + specific widget. + */ + void setTargetOpacity(QGraphicsWidget *widget, qreal target); + //void enableOpacityAnimation(bool enable); + //void setSourceOpacity(qreal opacity); + + /*! + \brief Sets target for size animation. If \a widget == NULL, the same target + is set for all the added widgets, otherwise the target is set only for the + specific widget. + */ + void setTargetSize(QGraphicsWidget *widget, const QSizeF &target); + //void enableSizeAnimation(bool enable); + //void setSourceSize(const QSizeF& size); + + /*! + \brief Sets target for position animation. If \a widget == NULL, the same target + is set for all the added widgets, otherwise the target is set only for the + specific widget. + */ + void setTargetPosition(QGraphicsWidget *widget, const QPointF &target); + //void enablePositionAnimation(bool enable); + //void setSourcePosition(const QPointF& position); +}; + +#endif diff --git a/src/animation/duiwidgetanimation_p.h b/src/animation/duiwidgetanimation_p.h new file mode 100644 index 000000000..06b2ef7b1 --- /dev/null +++ b/src/animation/duiwidgetanimation_p.h @@ -0,0 +1,50 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIWIDGETANIMATION_P_H +#define DUIWIDGETANIMATION_P_H + +#include "duigroupanimation_p.h" + +#include +#include + +class QPropertyAnimation; + +typedef QMap Animations; + +class DuiWidgetAnimationPrivate : public DuiGroupAnimationPrivate +{ + Q_DECLARE_PUBLIC(DuiWidgetAnimation) + +public: + + DuiWidgetAnimationPrivate(); + virtual ~DuiWidgetAnimationPrivate(); + + QPropertyAnimation *getAnimation(QGraphicsWidget *widget, const QString &property); + + void setTargetForAllWidgets(const QString &property, const QVariant &value); + + QMap animations; + int duration; + QEasingCurve easingCurve; +}; + +#endif diff --git a/src/animation/particle/duiparticleengine.cpp b/src/animation/particle/duiparticleengine.cpp new file mode 100644 index 000000000..cd0d9a1dd --- /dev/null +++ b/src/animation/particle/duiparticleengine.cpp @@ -0,0 +1,211 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#if QT_VERSION >= 0x040600 + +#include "duiparticleengine.h" +#include "duiscenemanager.h" +#include "duiapplication.h" +#include "duiapplicationwindow.h" +#include "duiglrenderer.h" +#include + + +class DuiParticleEnginePrivate +{ + Q_DECLARE_PUBLIC(DuiParticleEngine) +protected: + DuiParticleEngine *q_ptr; +private: + DuiParticleEngine::Type type; + DuiParticle *particles; + int particleCount; + int lastmsecs; + QPixmap *pixmap; + QPixmap *pixmaps; +}; + +DuiParticleEngine::DuiParticleEngine(DuiParticleEnginePrivate *dd, QObject *parent, DuiParticleEngine::Type type) : + QAbstractAnimation(parent), + QGraphicsItem(NULL), + d_ptr(dd) +{ + Q_D(DuiParticleEngine); + d->q_ptr = this; + d->type = type; + d->lastmsecs = 0; + d->pixmap = new QPixmap("partikkeli.png"); +} + + +DuiParticleEngine::DuiParticleEngine(QObject *parent, DuiParticleEngine::Type type) : + QAbstractAnimation(parent), + QGraphicsItem(NULL), + d_ptr(new DuiParticleEnginePrivate) +{ + Q_D(DuiParticleEngine); + d->q_ptr = this; + d->type = type; + d->lastmsecs = 0; + d->pixmap = new QPixmap("partikkeli.png"); + d->pixmaps = new QPixmap[10]; + + QImage baseParticle = d->pixmap->toImage(); + + for (int i = 0; i < 10; ++i) { + QImage particle = baseParticle.copy(); + + const int particleHeight = particle.height(); + for (int y = 0; y < particleHeight; ++y) { + uchar *scanline = particle.scanLine(y); + + const int particleWidth = particle.width(); + for (int x = 0; x < particleWidth; ++x) { + uint *p = (uint *)scanline + x; + + qreal blueFactor = 0.3 + 0.7 * ((qreal)i) / 10.0; + *p = qRgba(qRed(*p), qGreen(*p), qBlue(*p) * blueFactor, qAlpha(*p)); + } + } + + d->pixmaps[i] = QPixmap::fromImage(particle); + } +} + +DuiParticleEngine::~DuiParticleEngine() +{ + delete [] d_ptr->particles; + delete d_ptr->pixmap; + delete d_ptr; +} + +QRectF DuiParticleEngine::boundingRect() const +{ + return QRectF(QPointF(0, 0), DuiApplication::activeWindow()->visibleSceneSize()); +} + +void DuiParticleEngine::init(int particleCount) +{ + Q_D(DuiParticleEngine); + d->particles = new DuiParticle[particleCount]; + d->particleCount = particleCount; + for (int i = 0; i < particleCount; ++i) { + DuiParticle &p = d->particles[i]; + p.id = i; + p.alive = false; + p.killtime = p.birthtime = 0; + p.px = p.py = p.vx = p.vy = p.ax = p.ay = 0.0; + p.scale = 1.0; + p.sx = 128.0; + p.sy = 128.0; + p.color = qRgba(255, 255, 255, 255); + initParticle(p, 0); + } +} + +void DuiParticleEngine::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + Q_UNUSED(option); + Q_UNUSED(widget); + + Q_D(DuiParticleEngine); + +#ifdef DUI_USE_OPENGL +#if QT_VERSION >= 0x040600 + if (painter->paintEngine()->type() == QPaintEngine::OpenGL2) { +#else + if (painter->paintEngine()->type() == QPaintEngine::OpenGL) { +#endif + DuiGLRenderer::instance()->drawParticles(d->particles, d->particleCount, *d->pixmap, painter->combinedTransform()); + } else +#endif + { + painter->save(); + painter->setCompositionMode(QPainter::CompositionMode_Plus); + for (int i = 0; i < d->particleCount; ++i) { + DuiParticle &p = d->particles[i]; + + // particle not alive + if (!p.alive) + continue; + + painter->setOpacity((qreal)qAlpha(p.color) / 255.0); + qreal sx = p.sx / 2.0; + qreal sy = p.sy / 2.0; + painter->drawPixmap(QRect(p.px - sx * p.scale, p.py - sy * p.scale, p.sx * p.scale, p.sy * p.scale), d->pixmaps[i%10]); + + // draw the particle with given color,opacity,scale + // to position p.px,p.py (as center) + } + painter->restore(); + } +} + +void DuiParticleEngine::updateCurrentTime(int msecs) +{ + Q_D(DuiParticleEngine); + bool done = true; + int dt = msecs - d->lastmsecs; + + for (int i = 0; i < d->particleCount; ++i) { + DuiParticle &p = d->particles[i]; + + // particle not alive + if (!p.alive) + continue; + + // should we kill the particle? + if (p.killtime <= msecs) { + p.alive = false; + if (d->type == Continuous) + initParticle(p, msecs); + + if (p.alive) + done = false; + + continue; + } + stepParticle(p, dt, msecs); + + done = false; + } + + // no more particles alive + if (done) { + stop(); + emit finished(); + } + + d->lastmsecs = msecs; + update(); +} + +void DuiParticleEngine::stepParticle(DuiParticle &p, int dt, int msecs) +{ + Q_UNUSED(msecs); + p.px += dt * dt * p.ax / 2.0 + p.vx * dt; + p.py += dt * dt * p.ay / 2.0 + p.vy * dt; + + p.vx += dt * p.ax; + p.vy += dt * p.ay; +} + +#endif + diff --git a/src/animation/particle/duiparticleengine.h b/src/animation/particle/duiparticleengine.h new file mode 100644 index 000000000..4c082592f --- /dev/null +++ b/src/animation/particle/duiparticleengine.h @@ -0,0 +1,97 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIPARTICLEENGINE_H +#define DUIPARTICLEENGINE_H + +#include +#include + +//! \internal + +/*! + \brief Struct which contains all information of a particle. +*/ +struct DuiParticle { + uint id; + bool alive; + int birthtime; // ms + int killtime; // ms + qreal px, py; // pixels + qreal vx, vy; // pixels / ms + qreal ax, ay; // pixels / ms^2 + qreal scale; + qreal sx, sy; + QRgb color; +}; + +#include +#include +#include + +class DuiParticleEnginePrivate; +class QPainter; + +class DuiParticleEngine : public QAbstractAnimation, public QGraphicsItem +{ + Q_OBJECT + Q_DECLARE_PRIVATE(DuiParticleEngine) + +public: + enum Type { + Single, + Continuous + }; +protected: + /*! + \brief Pointer to the private data class. + + This pointer should not be used directly, but through Q_D macro. + */ + DuiParticleEnginePrivate *const d_ptr; + + /*! + \brief Constructs the animation with paraller animation group inside. + + This constructor is meant to be used inside the libdui to share the + private data class pointer. + */ + DuiParticleEngine(DuiParticleEnginePrivate *dd, QObject *parent, DuiParticleEngine::Type type = Continuous); + +public: + + DuiParticleEngine(QObject *parent, DuiParticleEngine::Type type = Continuous); + virtual ~DuiParticleEngine(); + + virtual QRectF boundingRect() const; + + void init(int particleCount); + + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + +protected: + virtual void updateCurrentTime(int msecs); + + virtual void stepParticle(DuiParticle &p, int dt, int msecs); + virtual void initParticle(DuiParticle &p, int curmsecs) = 0; +}; + +//! \internal_end + +#endif diff --git a/src/animation/particle/particle.pri b/src/animation/particle/particle.pri new file mode 100644 index 000000000..c3f55339c --- /dev/null +++ b/src/animation/particle/particle.pri @@ -0,0 +1,16 @@ +############################################################################### +# DuiAnimation/Particle module +# This module contains particle animation code. +############################################################################### + +PARTICLE_ANIMATIONS_SRC_DIR=./animation/particle + +#public +HEADERS += \ + $$PARTICLE_ANIMATIONS_SRC_DIR/duiparticleengine.h \ + +#private +HEADERS += \ + +SOURCES += \ + $$PARTICLE_ANIMATIONS_SRC_DIR/duiparticleengine.cpp \ diff --git a/src/animation/scene/duibasicorientationanimation.cpp b/src/animation/scene/duibasicorientationanimation.cpp new file mode 100644 index 000000000..9597ec0e6 --- /dev/null +++ b/src/animation/scene/duibasicorientationanimation.cpp @@ -0,0 +1,489 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duibasicorientationanimation.h" + +#include "duibasicorientationanimation_p.h" + +#include +#include +#include + +#include +#include "duiscenewindow.h" +#include "duiapplicationpage.h" +#include + +void DuiBasicOrientationAnimationPrivate::_q_onPhase0Finished() +{ + Q_Q(DuiBasicOrientationAnimation); + + upcomingPhase = phase1; + hideComponents(); + + emit q->orientationChanged(); +} + +void DuiBasicOrientationAnimationPrivate::_q_onPhase1Finished() +{ + upcomingPhase = phase2; + showComponents(); +} + +void DuiBasicOrientationAnimationPrivate::_q_onPhase2Finished() +{ + upcomingPhase = phase0; +} + +void DuiBasicOrientationAnimationPrivate::hideComponents() +{ + if (navigationBar) { + navigationBar->hide(); + } + + if (homeButtonPanel) { + homeButtonPanel->hide(); + } + + if (escapeButtonPanel) { + escapeButtonPanel->hide(); + } + + if (dockWidget) { + dockWidget->hide(); + } +} + +void DuiBasicOrientationAnimationPrivate::showComponents() +{ + if (navigationBar) { + navigationBar->show(); + } + + if (homeButtonPanel) { + homeButtonPanel->show(); + } + + if (escapeButtonPanel) { + escapeButtonPanel->show(); + } + + // Show only if we're going to portrait + if (dockWidget && + (endOrientationAngle == Dui::Angle90 || endOrientationAngle == Dui::Angle270)) { + dockWidget->show(); + } +} + +void DuiBasicOrientationAnimationPrivate::setupHomeButtonAnimations() +{ + setupNavigationButtonAnimations(homeButtonPanel, + homeButtonSlideInAnimation, homeButtonSlideOutAnimation); +} + +void DuiBasicOrientationAnimationPrivate::setupEscapeButtonAnimations() +{ + setupNavigationButtonAnimations(escapeButtonPanel, + escapeButtonSlideInAnimation, escapeButtonSlideOutAnimation); +} + +void DuiBasicOrientationAnimationPrivate::setupNavigationButtonAnimations(DuiSceneWindow *button, + QPropertyAnimation *slideInAnimation, QPropertyAnimation *slideOutAnimation) +{ + slideOutAnimation->setStartValue(button->y()); + + float slideOutEndY; + + if (navigationBar) { + float navBarStartY = navigationBarSlideOutAnimation->startValue().toPointF().y(); + float navBarHeight = navigationBar->boundingRect().height(); + slideOutEndY = -navBarHeight + (button->y() - navBarStartY); + } else { + slideOutEndY = -button->boundingRect().height(); + } + + slideOutAnimation->setEndValue(slideOutEndY); + slideOutAnimation->setTargetObject(button); + + slideInAnimation->setTargetObject(button); + slideInAnimation->setStartValue(slideOutAnimation->endValue()); + slideInAnimation->setEndValue(slideOutAnimation->startValue()); +} + +void DuiBasicOrientationAnimationPrivate::setupDockWidgetAnimations() +{ + + if (startOrientationAngle == Dui::Angle0 || startOrientationAngle == Dui::Angle180) { + // landscape + dockWidgetSlideOutAnimation->setTargetObject(0); + } else { + // portrait + float initialScreenHeight = landscapeScreenSize.width(); + dockWidgetSlideOutAnimation->setStartValue(dockWidget->y()); + dockWidgetSlideOutAnimation->setEndValue(initialScreenHeight); + dockWidgetSlideOutAnimation->setTargetObject(dockWidget); + } + + if (endOrientationAngle == Dui::Angle0 || endOrientationAngle == Dui::Angle180) { + // landscape + dockWidgetSlideInAnimation->setTargetObject(0); + } else { + // portrait + float finalScreenHeight = landscapeScreenSize.width(); + dockWidgetSlideInAnimation->setTargetObject(dockWidget); + dockWidgetSlideInAnimation->setStartValue(finalScreenHeight); + dockWidgetSlideInAnimation->setEndValue(finalScreenHeight - dockWidget->boundingRect().height()); + } + +} + +void DuiBasicOrientationAnimationPrivate::addGenericSceneWindowAnimations(DuiSceneWindow *sceneWindow) +{ + Q_Q(DuiBasicOrientationAnimation); + SceneWindowAnimationPair animationPair; + + animationPair.fadeOutAnimation = new QPropertyAnimation(sceneWindow, "opacity", phase0); + animationPair.fadeOutAnimation->setStartValue(sceneWindow->opacity()); + animationPair.fadeOutAnimation->setEndValue(0.0); + animationPair.fadeOutAnimation->setDuration(q->style()->phaseZeroDuration()); + + animationPair.fadeInAnimation = new QPropertyAnimation(sceneWindow, "opacity", phase2); + animationPair.fadeInAnimation->setStartValue(0.0); + animationPair.fadeInAnimation->setDuration(q->style()->phaseTwoDuration()); + animationPair.fadeInAnimation->setEndValue(animationPair.fadeOutAnimation->startValue()); + + genericAnimationsHash[sceneWindow] = animationPair; +} + +void DuiBasicOrientationAnimationPrivate::removeGenericSceneWindowAnimations(DuiSceneWindow *sceneWindow) +{ + if (!genericAnimationsHash.contains(sceneWindow)) { + return; + } + + SceneWindowAnimationPair animationPair = genericAnimationsHash.take(sceneWindow); + + phase0->removeAnimation(animationPair.fadeOutAnimation); + delete animationPair.fadeOutAnimation; + + phase2->removeAnimation(animationPair.fadeInAnimation); + delete animationPair.fadeInAnimation; +} + +void DuiBasicOrientationAnimationPrivate::addApplicationPageAnimations(DuiSceneWindow *applicationPage) +{ + Q_Q(DuiBasicOrientationAnimation); + SceneWindowAnimationPair animationPair; + QList childItemsList = applicationPage->childItems(); + int childCount = childItemsList.count(); + int i = 0; + DuiPannableViewport *pageViewport = 0; + QGraphicsItem *childItem; + QGraphicsWidget *childWidget; + QGraphicsWidget *targetObject; + + // Try to find the page's pannable viewport + while (pageViewport == 0 && i < childCount) { + childItem = childItemsList.at(i); + + if (childItem->isWidget()) { + childWidget = static_cast(childItem); + pageViewport = qobject_cast(childWidget); + } + + ++i; + } + + if (pageViewport) { + targetObject = pageViewport; + } else { + // We will have to fade the central widget only. The drawback is that the position + // indicator of the pannable viewport will not get faded in & out, which is visually + // less appealing. :-) + targetObject = (static_cast(applicationPage))->centralWidget(); + } + + animationPair.fadeOutAnimation = new QPropertyAnimation(targetObject, "opacity", phase0); + animationPair.fadeOutAnimation->setStartValue(targetObject->opacity()); + animationPair.fadeOutAnimation->setEndValue(0.0); + animationPair.fadeOutAnimation->setDuration(q->style()->phaseZeroDuration()); + + animationPair.fadeInAnimation = new QPropertyAnimation(targetObject, "opacity", phase2); + animationPair.fadeInAnimation->setStartValue(0.0); + animationPair.fadeInAnimation->setDuration(q->style()->phaseTwoDuration()); + animationPair.fadeInAnimation->setEndValue(animationPair.fadeOutAnimation->startValue()); + + genericAnimationsHash[applicationPage] = animationPair; +} + +void DuiBasicOrientationAnimationPrivate::removeApplicationPageAnimations(DuiSceneWindow *applicationPage) +{ + removeGenericSceneWindowAnimations(applicationPage); +} + +DuiSceneWindow *DuiBasicOrientationAnimationPrivate::fetchLayerEffect(DuiSceneWindow *sceneWindow) +{ + DuiSceneWindow *layerEffect = 0; + + if (sceneWindow->parentItem() && sceneWindow->parentItem()->isWidget()) { + QGraphicsWidget *parentWidget = static_cast(sceneWindow->parentItem()); + + DuiSceneWindow *parentSceneWindow = qobject_cast(parentWidget); + if (parentSceneWindow && parentSceneWindow->windowType() == DuiSceneWindow::LayerEffect) { + layerEffect = parentSceneWindow; + } + } + + return layerEffect; +} + +DuiBasicOrientationAnimation::DuiBasicOrientationAnimation(const QSize &landscapeScreenSize, QObject *parent) : + DuiParallelAnimationGroup(new DuiBasicOrientationAnimationPrivate, parent) +{ + Q_D(DuiBasicOrientationAnimation); + + d->sequentialPhasesAnimation = new QSequentialAnimationGroup; + addAnimation(d->sequentialPhasesAnimation); + + d->landscapeScreenSize = landscapeScreenSize; + + d->phase0 = new QParallelAnimationGroup(d->sequentialPhasesAnimation); + d->phase1 = new QParallelAnimationGroup(d->sequentialPhasesAnimation); + d->phase2 = new QParallelAnimationGroup(d->sequentialPhasesAnimation); + d->upcomingPhase = d->phase0; + + d->navigationBarSlideOutAnimation = new QPropertyAnimation(NULL, "y", d->phase0); + d->navigationBarSlideOutAnimation->setDuration(style()->phaseZeroDuration()); + + d->homeButtonSlideOutAnimation = new QPropertyAnimation(NULL, "y", d->phase0); + d->homeButtonSlideOutAnimation->setDuration(style()->phaseZeroDuration()); + + d->escapeButtonSlideOutAnimation = new QPropertyAnimation(NULL, "y", d->phase0); + d->escapeButtonSlideOutAnimation->setDuration(style()->phaseZeroDuration()); + + d->dockWidgetSlideOutAnimation = new QPropertyAnimation(NULL, "y", d->phase0); + d->dockWidgetSlideOutAnimation->setDuration(style()->phaseZeroDuration()); + + d->rotationAnimation = new QPropertyAnimation(NULL, "rotation", d->phase1); + d->rotationAnimation->setDuration(style()->phaseOneDuration()); + d->positionAnimation = new QPropertyAnimation(NULL, "pos", d->phase1); + d->positionAnimation->setDuration(style()->phaseOneDuration()); + d->originAnimation = new QPropertyAnimation(NULL, "transformOriginPoint", d->phase1); + d->originAnimation->setDuration(style()->phaseOneDuration()); + + d->navigationBarSlideInAnimation = new QPropertyAnimation(NULL, "y", d->phase2); + d->navigationBarSlideInAnimation->setDuration(style()->phaseTwoDuration()); + + d->homeButtonSlideInAnimation = new QPropertyAnimation(NULL, "y", d->phase2); + d->homeButtonSlideInAnimation->setDuration(style()->phaseTwoDuration()); + + d->escapeButtonSlideInAnimation = new QPropertyAnimation(NULL, "y", d->phase2); + d->escapeButtonSlideInAnimation->setDuration(style()->phaseTwoDuration()); + + d->dockWidgetSlideInAnimation = new QPropertyAnimation(NULL, "y", d->phase2); + d->dockWidgetSlideInAnimation->setDuration(style()->phaseTwoDuration()); + + d->navigationBar = 0; + d->homeButtonPanel = 0; + d->escapeButtonPanel = 0; + d->dockWidget = 0; + + // would be better to be a state machine instead of just an animation group... + connect(d->phase0, SIGNAL(finished()), SLOT(_q_onPhase0Finished())); + connect(d->phase1, SIGNAL(finished()), SLOT(_q_onPhase1Finished())); + connect(d->phase2, SIGNAL(finished()), SLOT(_q_onPhase2Finished())); +} + +DuiBasicOrientationAnimation::~DuiBasicOrientationAnimation() +{ +} + +void DuiBasicOrientationAnimation::addSceneWindow(DuiSceneWindow *window) +{ + Q_D(DuiBasicOrientationAnimation); + + if (window->windowType() == DuiSceneWindow::NavigationBar) { + d->navigationBar = window; + + d->navigationBarSlideOutAnimation->setStartValue(window->y()); + d->navigationBarSlideOutAnimation->setEndValue(-window->boundingRect().height()); + d->navigationBarSlideOutAnimation->setTargetObject(window); + + d->navigationBarSlideInAnimation->setTargetObject(window); + d->navigationBarSlideInAnimation->setStartValue(d->navigationBarSlideOutAnimation->endValue()); + d->navigationBarSlideInAnimation->setEndValue(d->navigationBarSlideOutAnimation->startValue()); + + if (d->homeButtonPanel) { + d->setupHomeButtonAnimations(); + } + + if (d->escapeButtonPanel) { + d->setupEscapeButtonAnimations(); + } + + } else if (window->windowType() == DuiSceneWindow::ApplicationPage) { + + d->addApplicationPageAnimations(window); + + } else if (window->windowType() == DuiSceneWindow::HomeButtonPanel) { + + d->homeButtonPanel = window; + d->setupHomeButtonAnimations(); + + } else if (window->windowType() == DuiSceneWindow::EscapeButtonPanel) { + + d->escapeButtonPanel = window; + d->setupEscapeButtonAnimations(); + + } else if (window->windowType() == DuiSceneWindow::DockWidget) { + + d->dockWidget = window; + d->setupDockWidgetAnimations(); + if (d->upcomingPhase == d->phase1) { + // We're about to start or have started already + // phase 1. During that phase the dock widget must + // be hidden. + d->dockWidget->hide(); + } + } else { + DuiSceneWindow *layerEffect = d->fetchLayerEffect(window); + if (layerEffect) { + d->addGenericSceneWindowAnimations(layerEffect); + } else { + d->addGenericSceneWindowAnimations(window); + } + } +} + +void DuiBasicOrientationAnimation::removeSceneWindow(DuiSceneWindow *window) +{ + Q_D(DuiBasicOrientationAnimation); + + if (window->windowType() == DuiSceneWindow::NavigationBar) { + + d->navigationBar = 0; + d->navigationBarSlideInAnimation->setTargetObject(0); + d->navigationBarSlideOutAnimation->setTargetObject(0); + + if (d->homeButtonPanel) { + d->setupHomeButtonAnimations(); + } + + if (d->escapeButtonPanel) { + d->setupEscapeButtonAnimations(); + } + + } else if (window->windowType() == DuiSceneWindow::HomeButtonPanel) { + + d->homeButtonPanel = 0; + d->homeButtonSlideInAnimation->setTargetObject(0); + d->homeButtonSlideOutAnimation->setTargetObject(0); + + } else if (window->windowType() == DuiSceneWindow::EscapeButtonPanel) { + + d->escapeButtonPanel = 0; + d->escapeButtonSlideInAnimation->setTargetObject(0); + d->escapeButtonSlideOutAnimation->setTargetObject(0); + + } else if (window->windowType() == DuiSceneWindow::DockWidget) { + d->dockWidget = 0; + d->dockWidgetSlideInAnimation->setTargetObject(0); + d->dockWidgetSlideOutAnimation->setTargetObject(0); + + } else if (window->windowType() == DuiSceneWindow::ApplicationPage) { + + d->removeApplicationPageAnimations(window); + + } else { + DuiSceneWindow *layerEffect = d->fetchLayerEffect(window); + if (layerEffect) { + d->removeGenericSceneWindowAnimations(layerEffect); + } else { + d->removeGenericSceneWindowAnimations(window); + } + } + +} + +void DuiBasicOrientationAnimation::setTargetRotationAngle(Dui::OrientationAngle start, + Dui::OrientationAngle end) +{ + Q_D(DuiBasicOrientationAnimation); + + d->startOrientationAngle = start; + d->endOrientationAngle = end; + + if (start == Dui::Angle270 && end == Dui::Angle0) { + d->rotationAnimation->setStartValue(-90); + d->rotationAnimation->setEndValue(0); + } else if (start == Dui::Angle0 && end == Dui::Angle270) { + d->rotationAnimation->setStartValue(360); + d->rotationAnimation->setEndValue(270); + } else { + d->rotationAnimation->setStartValue(start); + d->rotationAnimation->setEndValue(end); + } + + if (start == Dui::Angle0 || start == Dui::Angle180) { + d->positionAnimation->setStartValue(QPointF(0, 0)); + d->originAnimation->setStartValue(QPointF(d->landscapeScreenSize.width() / 2, d->landscapeScreenSize.height() / 2)); + } else { + d->positionAnimation->setStartValue(QPointF((d->landscapeScreenSize.width() - d->landscapeScreenSize.height()) / 2, + (d->landscapeScreenSize.height() - d->landscapeScreenSize.width()) / 2)); + d->originAnimation->setStartValue(QPointF(d->landscapeScreenSize.height() / 2, d->landscapeScreenSize.width() / 2)); + } + + if (end == Dui::Angle0 || end == Dui::Angle180) { + d->positionAnimation->setEndValue(QPointF(0, 0)); + d->originAnimation->setEndValue(QPointF(d->landscapeScreenSize.width() / 2, d->landscapeScreenSize.height() / 2)); + } else { + d->positionAnimation->setEndValue(QPointF((d->landscapeScreenSize.width() - d->landscapeScreenSize.height()) / 2, + (d->landscapeScreenSize.height() - d->landscapeScreenSize.width()) / 2)); + d->originAnimation->setEndValue(QPointF(d->landscapeScreenSize.height() / 2, d->landscapeScreenSize.width() / 2)); + } + + if (d->dockWidget) { + d->setupDockWidgetAnimations(); + } +} + +void DuiBasicOrientationAnimation::rootElementChanged() +{ + Q_D(DuiBasicOrientationAnimation); + d->rotationAnimation->setTargetObject(rootElement()); + d->positionAnimation->setTargetObject(rootElement()); + d->originAnimation->setTargetObject(rootElement()); +} + +void DuiBasicOrientationAnimation::setRootElement(QGraphicsWidget *rootElement) +{ + Q_D(DuiBasicOrientationAnimation); + if (d->rootElement != rootElement) { + d->rootElement = rootElement; + rootElementChanged(); + } +} + +QGraphicsWidget *DuiBasicOrientationAnimation::rootElement() +{ + Q_D(DuiBasicOrientationAnimation); + return d->rootElement; +} + +#include "moc_duibasicorientationanimation.cpp" diff --git a/src/animation/scene/duibasicorientationanimation.h b/src/animation/scene/duibasicorientationanimation.h new file mode 100644 index 000000000..0968c4952 --- /dev/null +++ b/src/animation/scene/duibasicorientationanimation.h @@ -0,0 +1,93 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +// Make doxygen skip this internal class +//! \cond +#ifndef DUIBASICORIENTATIONANIMATION_H +#define DUIBASICORIENTATIONANIMATION_H + +#include +#include +#include +#include + +class DuiBasicOrientationAnimationPrivate; +class DuiSceneWindow; +class QGraphicsWidget; +class QAnimationGroup; + +/*! + \class DuiBasicOrientationAnimation + \brief DuiBasicOrientationAnimation class provides default 3-phased orientation animation. + + Phase 0: Navigation bar & dock widget slide out, scene windows fade out + Phase 1: Screen is rotated + Phase 2: Navigation bar & dock widget slide in, scene window fade in + */ +class DuiBasicOrientationAnimation : public DuiParallelAnimationGroup +{ + Q_OBJECT + Q_DECLARE_PRIVATE(DuiBasicOrientationAnimation) + DUI_ANIMATION_GROUP(DuiBasicOrientationAnimationStyle) + +public: + + /*! + \brief Constructs the orientation animation. + */ + DuiBasicOrientationAnimation(const QSize &landscapeScreenSize, QObject *parent = NULL); + + /*! + \brief Destroys the orientation animation. + */ + virtual ~DuiBasicOrientationAnimation(); + + //! \reimp + // from DuiOrientationAnimation + virtual void addSceneWindow(DuiSceneWindow *window); + virtual void removeSceneWindow(DuiSceneWindow *window); + virtual void setTargetRotationAngle(Dui::OrientationAngle start, Dui::OrientationAngle end); + //! \reimp_end + + void setRootElement(QGraphicsWidget *rootElement); + +Q_SIGNALS: + /*! + \brief Signals that orientation has changed + */ + void orientationChanged(); + + void finished(); + +protected: + //! \reimp + // from DuiOrientationAnimation + virtual void rootElementChanged(); + //! \reimp_end + + QGraphicsWidget *rootElement(); + +private: + Q_PRIVATE_SLOT(d_func(), void _q_onPhase0Finished()) + Q_PRIVATE_SLOT(d_func(), void _q_onPhase1Finished()) + Q_PRIVATE_SLOT(d_func(), void _q_onPhase2Finished()) +}; + +#endif +//! \endcond diff --git a/src/animation/scene/duibasicorientationanimation_p.h b/src/animation/scene/duibasicorientationanimation_p.h new file mode 100644 index 000000000..823100c4c --- /dev/null +++ b/src/animation/scene/duibasicorientationanimation_p.h @@ -0,0 +1,103 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIBASICORIENTATIONANIMATION_P_H +#define DUIBASICORIENTATIONANIMATION_P_H + +#include "duiparallelanimationgroup_p.h" + +#include + +class QParallelAnimationGroup; +class QPropertyAnimation; +class DuiBasicOrientationAnimation; +class DuiSceneWindowAnimation; +class DuiSceneWindow; + +class DuiBasicOrientationAnimationPrivate : public DuiParallelAnimationGroupPrivate +{ + Q_DECLARE_PUBLIC(DuiBasicOrientationAnimation) + +public: + void _q_onPhase0Finished(); + void _q_onPhase1Finished(); + void _q_onPhase2Finished(); + + void hideComponents(); + void showComponents(); + + void setupHomeButtonAnimations(); + void setupEscapeButtonAnimations(); + void setupNavigationButtonAnimations(DuiSceneWindow *button, + QPropertyAnimation *slideInAnimation, + QPropertyAnimation *slideOutAnimation); + void setupDockWidgetAnimations(); + + void addGenericSceneWindowAnimations(DuiSceneWindow *sceneWindow); + void removeGenericSceneWindowAnimations(DuiSceneWindow *sceneWindow); + + void addApplicationPageAnimations(DuiSceneWindow *applicationPage); + void removeApplicationPageAnimations(DuiSceneWindow *applicationPage); + + DuiSceneWindow *fetchLayerEffect(DuiSceneWindow *sceneWindow); + + QParallelAnimationGroup *phase0; + QParallelAnimationGroup *phase1; + QParallelAnimationGroup *phase2; + QParallelAnimationGroup *upcomingPhase; + + QPropertyAnimation *rotationAnimation; + QPropertyAnimation *positionAnimation; + QPropertyAnimation *originAnimation; + QPropertyAnimation *navigationBarSlideInAnimation; + QPropertyAnimation *navigationBarSlideOutAnimation; + + QPropertyAnimation *homeButtonSlideInAnimation; + QPropertyAnimation *homeButtonSlideOutAnimation; + + QPropertyAnimation *escapeButtonSlideInAnimation; + QPropertyAnimation *escapeButtonSlideOutAnimation; + + QPropertyAnimation *dockWidgetSlideInAnimation; + QPropertyAnimation *dockWidgetSlideOutAnimation; + + DuiSceneWindow *navigationBar; + DuiSceneWindow *homeButtonPanel; + DuiSceneWindow *escapeButtonPanel; + DuiSceneWindow *dockWidget; + + QSize landscapeScreenSize; + + Dui::OrientationAngle startOrientationAngle; + Dui::OrientationAngle endOrientationAngle; + + class SceneWindowAnimationPair + { + public: + QPropertyAnimation *fadeOutAnimation; + QPropertyAnimation *fadeInAnimation; + }; + + QHash genericAnimationsHash; + + class QAnimationGroup *sequentialPhasesAnimation; + QGraphicsWidget *rootElement; +}; + +#endif diff --git a/src/animation/scene/duifliporientationanimation.cpp b/src/animation/scene/duifliporientationanimation.cpp new file mode 100644 index 000000000..c29771712 --- /dev/null +++ b/src/animation/scene/duifliporientationanimation.cpp @@ -0,0 +1,147 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duifliporientationanimation.h" + +#if QT_VERSION >= 0x040600 + +#include "duifliporientationanimation_p.h" + +#include +#include +#include +#include "duiwidgetanimation.h" +#include "duiscenemanager.h" +#include "duiscenewindow.h" +#include "duinavigationbaranimation.h" + +/////////////////// +// Private class // +/////////////////// +DuiFlipOrientationAnimationPrivate::DuiFlipOrientationAnimationPrivate() +{ +} + +DuiFlipOrientationAnimationPrivate::~DuiFlipOrientationAnimationPrivate() +{ +} + +void DuiFlipOrientationAnimationPrivate::finishedPhase0() +{ + Q_Q(DuiFlipOrientationAnimation); + + //TODO: create own class for rootElement to be able to + // rotate around other axes as well. + + if (angle == Dui::Angle0 || angle == Dui::Angle180) { + q->rootElement()->setPos(0, 0); + q->rootElement()->setTransformOriginPoint(QPointF(432, 240)); + //q->rootElement()->setXRotation(0); + //q->rootElement()->setYRotation(0); + //q->rootElement()->setZRotation(angle); + } else { + q->rootElement()->setPos(192, -192); + q->rootElement()->setTransformOriginPoint(QPointF(240, 432)); + //q->rootElement()->setXRotation(0); + //q->rootElement()->setYRotation(0); + //q->rootElement()->setZRotation(angle); + } +} + +////////////////// +// Public class // +////////////////// + +DuiFlipOrientationAnimation::DuiFlipOrientationAnimation(QObject *parent) : + DuiOrientationAnimation(new DuiFlipOrientationAnimationPrivate(), parent, DuiGroupAnimation::Sequential) +{ + Q_D(DuiFlipOrientationAnimation); + + d->phase0 = new QPropertyAnimation(NULL, "xRotation", group()); + d->phase0->setDuration(500); + + + d->phase1 = new QPropertyAnimation(NULL, "yRotation", group()); + d->phase1->setDuration(500); + + connect(d->phase0, SIGNAL(finished()), SIGNAL(orientationChanged())); + connect(d->phase0, SIGNAL(finished()), SLOT(finishedPhase0())); +} + +DuiFlipOrientationAnimation::~DuiFlipOrientationAnimation() +{ +} + +void DuiFlipOrientationAnimation::addSceneWindow(DuiSceneWindow *window) +{ + Q_UNUSED(window); +} + +void DuiFlipOrientationAnimation::removeSceneWindow(DuiSceneWindow *window) +{ + Q_UNUSED(window); +} + +void DuiFlipOrientationAnimation::setTargetRotationAngle(Dui::OrientationAngle start, + Dui::OrientationAngle end) +{ + Q_D(DuiFlipOrientationAnimation); + + //TODO: create own class for rootElement to be able to + // rotate around other axes as well. + + + //d->phase0->setStartValue(0); + //d->phase0->setStartValue(rootElement()->xRotation()); + //d->phase1->setEndValue(0); + + int startDir = -1; + //if(start == Dui::Angle180/* || start == Dui::Angle270*/) + // startDir = 1; + + int endDir = -1; + //if(/*end == Dui::Angle180 || */end == Dui::Angle270) + // endDir = 1; + + d->phase0->setEndValue(90 * startDir); + d->phase1->setStartValue(-90 * endDir); + + + if (start == Dui::Angle0 || start == Dui::Angle180) { + // Landscape to portrait + d->phase0->setPropertyName("xRotation"); + d->phase1->setPropertyName("xRotation"); + } else { + // Portrait to landscape + d->phase0->setPropertyName("xRotation"); + d->phase1->setPropertyName("xRotation"); + } + + d->angle = end; +} + +void DuiFlipOrientationAnimation::rootElementChanged() +{ + Q_D(DuiFlipOrientationAnimation); + d->phase0->setTargetObject(rootElement()); + d->phase1->setTargetObject(rootElement()); +} + +#include "moc_duifliporientationanimation.cpp" +#endif diff --git a/src/animation/scene/duifliporientationanimation.h b/src/animation/scene/duifliporientationanimation.h new file mode 100644 index 000000000..8215aa4ba --- /dev/null +++ b/src/animation/scene/duifliporientationanimation.h @@ -0,0 +1,70 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIFLIPORIENTATIONANIMATION_H +#define DUIFLIPORIENTATIONANIMATION_H + +#include +#if QT_VERSION >= 0x040600 + +#include +#include + +class DuiFlipOrientationAnimationPrivate; +class DuiWindow; + +/*! + \class DuiFlipOrientationAnimation + */ +class DuiFlipOrientationAnimation : public DuiOrientationAnimation +{ + Q_OBJECT + DUI_ANIMATION(DuiAnimationStyle) + Q_DECLARE_PRIVATE(DuiFlipOrientationAnimation) + + Q_PRIVATE_SLOT(d_func(), void finishedPhase0()) +public: + + /*! + \brief Constructs the orientation animation. + */ + DuiFlipOrientationAnimation(QObject *parent = NULL); + + /*! + \brief Destroys the orientation animation. + */ + virtual ~DuiFlipOrientationAnimation(); + + //! \reimp + // from DuiOrientationAnimation + virtual void addSceneWindow(DuiSceneWindow *window); + virtual void removeSceneWindow(DuiSceneWindow *window); + virtual void setTargetRotationAngle(Dui::OrientationAngle start, Dui::OrientationAngle end); + //! \reimp_end + +protected: + //! \reimp + // from DuiOrientationAnimation + virtual void rootElementChanged(); + //! \reimp_end +}; + +#endif +#endif + diff --git a/src/animation/scene/duifliporientationanimation_p.h b/src/animation/scene/duifliporientationanimation_p.h new file mode 100644 index 000000000..8d51169f7 --- /dev/null +++ b/src/animation/scene/duifliporientationanimation_p.h @@ -0,0 +1,46 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIFLIPORIENTATIONANIMATION_P_H +#define DUIFLIPORIENTATIONANIMATION_P_H + +#include "duiorientationanimation_p.h" +#include "duinamespace.h" + +class QParallelAnimationGroup; +class QPropertyAnimation; +class DuiBasicOrientationAnimation; +class DuiSceneWindowAnimation; + +class DuiFlipOrientationAnimationPrivate : public DuiOrientationAnimationPrivate +{ + Q_DECLARE_PUBLIC(DuiFlipOrientationAnimation) +public: + DuiFlipOrientationAnimationPrivate(); + virtual ~DuiFlipOrientationAnimationPrivate(); +private: + void finishedPhase0(); + + QPropertyAnimation *phase0; + QPropertyAnimation *phase1; + + Dui::OrientationAngle angle; +}; + +#endif diff --git a/src/animation/scene/duinavigationbaranimation.cpp b/src/animation/scene/duinavigationbaranimation.cpp new file mode 100644 index 000000000..4582d6bd3 --- /dev/null +++ b/src/animation/scene/duinavigationbaranimation.cpp @@ -0,0 +1,93 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duinavigationbaranimation.h" + +#if QT_VERSION >= 0x040600 + + +#include "duinavigationbaranimation_p.h" +#include "duiscenewindow.h" +#include +#include + +DuiNavigationbarAnimation::DuiNavigationbarAnimation(DuiSceneWindow *window, QObject *parent) : + DuiSceneWindowAnimation(new DuiNavigationbarAnimationPrivate, window, parent) +{ + Q_D(DuiNavigationbarAnimation); + + d->positionAnimation = new QPropertyAnimation(window, "pos", group()); + d->opacityAnimation = new QPropertyAnimation(window, "opacity", group()); +} + +DuiNavigationbarAnimation::DuiNavigationbarAnimation(DuiNavigationbarAnimationPrivate *dd, DuiSceneWindow *window, QObject *parent) : + DuiSceneWindowAnimation(dd, window, parent) +{ + Q_D(DuiNavigationbarAnimation); + + d->positionAnimation = new QPropertyAnimation(window, "pos", group()); + d->opacityAnimation = new QPropertyAnimation(window, "opacity", group()); +} + +void DuiNavigationbarAnimation::setType(DuiSceneWindowAnimation::Type type, bool useCurrentAsStartValue) +{ + Q_D(DuiNavigationbarAnimation); + + if (useCurrentAsStartValue) { + d->positionAnimation->setStartValue(d->sceneWindow->pos()); + d->opacityAnimation->setStartValue(d->sceneWindow->opacity()); + } + + switch (type) { + case DuiSceneWindowAnimation::Show: + if (!useCurrentAsStartValue) { + d->positionAnimation->setStartValue(QPointF(0, -d->sceneWindow->geometry().height())); + d->opacityAnimation->setStartValue(0); + } + d->positionAnimation->setEndValue(QPointF(0, 0)); + d->opacityAnimation->setEndValue(1); + d->positionAnimation->setDuration(250); + d->opacityAnimation->setDuration(250); + break; + + case DuiSceneWindowAnimation::Hide: + if (!useCurrentAsStartValue) { + d->positionAnimation->setStartValue(QPointF(0, 0)); + d->opacityAnimation->setStartValue(1); + } + d->positionAnimation->setEndValue(QPointF(0, -d->sceneWindow->geometry().height())); + d->opacityAnimation->setEndValue(0); + d->positionAnimation->setDuration(250); + d->opacityAnimation->setDuration(250); + break; + + case DuiSceneWindowAnimation::Move: + if (!useCurrentAsStartValue) { + d->positionAnimation->setStartValue(QPointF(0, 0)); + d->opacityAnimation->setStartValue(1); + } + + d->positionAnimation->setEndValue(QPointF(0, 0)); + d->opacityAnimation->setEndValue(1); + d->positionAnimation->setDuration(500); + d->opacityAnimation->setDuration(500); + break; + } +} +#endif diff --git a/src/animation/scene/duinavigationbaranimation.h b/src/animation/scene/duinavigationbaranimation.h new file mode 100644 index 000000000..6dc06d6a6 --- /dev/null +++ b/src/animation/scene/duinavigationbaranimation.h @@ -0,0 +1,65 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUINAVIGATIONBARANIMATION_H +#define DUINAVIGATIONBARANIMATION_H + +#include +#if QT_VERSION >= 0x040600 + +#include +#include + +class DuiNavigationbarAnimationPrivate; + +/*! + \class DuiNavigationbarAnimation + \brief + */ +class DuiNavigationbarAnimation : public DuiSceneWindowAnimation +{ + Q_OBJECT + Q_DECLARE_PRIVATE(DuiNavigationbarAnimation) + DUI_ANIMATION(DuiSceneWindowAnimationStyle) + +protected: + + /*! + \brief Constructs the navigation bar animation. + + This constructor is meant to be used inside the libdui to share the + private data class pointer. + */ + DuiNavigationbarAnimation(DuiNavigationbarAnimationPrivate *dd, DuiSceneWindow *window, QObject *parent = NULL); + +public: + + /*! + \brief Constructs the scene window animation. + */ + DuiNavigationbarAnimation(DuiSceneWindow *window, QObject *parent = NULL); + + /*! + \brief Sets animation type. + */ + virtual void setType(DuiSceneWindowAnimation::Type type, bool useCurrentAsStartValue); +}; + +#endif +#endif diff --git a/src/animation/scene/duinavigationbaranimation_p.h b/src/animation/scene/duinavigationbaranimation_p.h new file mode 100644 index 000000000..0221a2ff6 --- /dev/null +++ b/src/animation/scene/duinavigationbaranimation_p.h @@ -0,0 +1,35 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUINAVIGATIONBARANIMATION_P_H +#define DUINAVIGATIONBARANIMATION_P_H + +#include "duiscenewindowanimation_p.h" +class QPropertyAnimation; + +class DuiNavigationbarAnimationPrivate : public DuiSceneWindowAnimationPrivate +{ + Q_DECLARE_PUBLIC(DuiNavigationbarAnimation) + +public: + QPropertyAnimation *positionAnimation; + QPropertyAnimation *opacityAnimation; +}; + +#endif diff --git a/src/animation/scene/duinotificationanimation.cpp b/src/animation/scene/duinotificationanimation.cpp new file mode 100644 index 000000000..8cb0979ac --- /dev/null +++ b/src/animation/scene/duinotificationanimation.cpp @@ -0,0 +1,99 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duinotificationanimation.h" + +#if QT_VERSION >= 0x040600 + +#include "duinotificationanimation_p.h" +#include "duiscenewindow.h" +#include "duiscenemanager.h" +#include "duiapplication.h" +#include "duiwindow.h" +#include +#include + +DuiNotificationAnimation::DuiNotificationAnimation(DuiSceneWindow *window, QObject *parent) : + DuiSceneWindowAnimation(new DuiNotificationAnimationPrivate, window, parent) +{ + Q_D(DuiNotificationAnimation); + + d->positionAnimation = new QPropertyAnimation(window, "pos", group()); +} + +DuiNotificationAnimation::DuiNotificationAnimation(DuiNotificationAnimationPrivate *dd, DuiSceneWindow *window, QObject *parent) : + DuiSceneWindowAnimation(dd, window, parent) +{ + Q_D(DuiNotificationAnimation); + + d->positionAnimation = new QPropertyAnimation(window, "pos", group()); +} + +void DuiNotificationAnimation::setType(DuiSceneWindowAnimation::Type type, bool useCurrentAsStartValue) +{ + Q_D(DuiNotificationAnimation); + + if (useCurrentAsStartValue) { + d->positionAnimation->setStartValue(d->sceneWindow->pos()); + } + + QSize screenSize = DuiApplication::activeWindow()->visibleSceneSize(); + + //TODO: Get the start, end and duration parameters from theme or somewhere. + + switch (type) { + case DuiSceneWindowAnimation::Show: + if (!useCurrentAsStartValue) { + if (d->sceneWindow->windowType() == DuiSceneWindow::NotificationEvent) + d->positionAnimation->setStartValue(QPointF(-d->sceneWindow->geometry().width(), screenSize.height() * .2)); + else + d->positionAnimation->setStartValue(QPointF(screenSize.width() + d->sceneWindow->geometry().width(), screenSize.height() * .2)); + } + if (d->sceneWindow->windowType() == DuiSceneWindow::NotificationEvent) + d->positionAnimation->setEndValue(QPointF(0, screenSize.height() * .2)); + else + d->positionAnimation->setEndValue(QPointF(screenSize.width() - d->sceneWindow->geometry().width(), screenSize.height() * .2)); + d->positionAnimation->setDuration(750); + break; + + case DuiSceneWindowAnimation::Hide: + if (!useCurrentAsStartValue) { + if (d->sceneWindow->windowType() == DuiSceneWindow::NotificationEvent) + d->positionAnimation->setStartValue(QPointF(0, screenSize.height() * .2)); + else + d->positionAnimation->setStartValue(QPointF(screenSize.width() - d->sceneWindow->geometry().width(), screenSize.height() * .2)); + } + if (d->sceneWindow->windowType() == DuiSceneWindow::NotificationEvent) + d->positionAnimation->setEndValue(QPointF(-d->sceneWindow->geometry().width(), screenSize.height() * .2)); + else + d->positionAnimation->setEndValue(QPointF(screenSize.width() + d->sceneWindow->geometry().width(), screenSize.height() * .2)); + d->positionAnimation->setDuration(750); + break; + + case DuiSceneWindowAnimation::Move: + if (!useCurrentAsStartValue) { + d->positionAnimation->setStartValue(QPointF(0, screenSize.height() * .2)); + } + + d->positionAnimation->setEndValue(QPointF(0, screenSize.height() * .2)); + d->positionAnimation->setDuration(500); + break; + } +} +#endif diff --git a/src/animation/scene/duinotificationanimation.h b/src/animation/scene/duinotificationanimation.h new file mode 100644 index 000000000..59d64262e --- /dev/null +++ b/src/animation/scene/duinotificationanimation.h @@ -0,0 +1,64 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUINOTIFICATIONANIMATION_H +#define DUINOTIFICATIONANIMATION_H +#include +#if QT_VERSION >= 0x040600 + +#include +#include + +class DuiNotificationAnimationPrivate; + +/*! + \class DuiNavigationbarAnimation + \brief + */ +class DuiNotificationAnimation : public DuiSceneWindowAnimation +{ + Q_OBJECT + Q_DECLARE_PRIVATE(DuiNotificationAnimation) + DUI_ANIMATION(DuiSceneWindowAnimationStyle) + +protected: + + /*! + \brief Constructs the navigation bar animation. + + This constructor is meant to be used inside the libdui to share the + private data class pointer. + */ + DuiNotificationAnimation(DuiNotificationAnimationPrivate *dd, DuiSceneWindow *window, QObject *parent = NULL); + +public: + + /*! + \brief Constructs the scene window animation. + */ + DuiNotificationAnimation(DuiSceneWindow *window, QObject *parent = NULL); + + /*! + \brief Sets animation type. + */ + virtual void setType(DuiSceneWindowAnimation::Type type, bool useCurrentAsStartValue); +}; + +#endif +#endif diff --git a/src/animation/scene/duinotificationanimation_p.h b/src/animation/scene/duinotificationanimation_p.h new file mode 100644 index 000000000..ed6ddd52d --- /dev/null +++ b/src/animation/scene/duinotificationanimation_p.h @@ -0,0 +1,34 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUINOTIFICATIONANIMATION_P_H +#define DUINOTIFICATIONANIMATION_P_H + +#include "duiscenewindowanimation_p.h" +class QPropertyAnimation; + +class DuiNotificationAnimationPrivate : public DuiSceneWindowAnimationPrivate +{ + Q_DECLARE_PUBLIC(DuiNotificationAnimation) + +public: + QPropertyAnimation *positionAnimation; +}; + +#endif diff --git a/src/animation/scene/duiorientationanimation.cpp b/src/animation/scene/duiorientationanimation.cpp new file mode 100644 index 000000000..7d2324f51 --- /dev/null +++ b/src/animation/scene/duiorientationanimation.cpp @@ -0,0 +1,73 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiorientationanimation.h" + +#if QT_VERSION >= 0x040600 + + +#include "duiorientationanimation_p.h" + +/////////////////// +// Private class // +/////////////////// + +DuiOrientationAnimationPrivate::DuiOrientationAnimationPrivate() : + rootElement(0) +{ +} + +DuiOrientationAnimationPrivate::~DuiOrientationAnimationPrivate() +{ +} + +////////////////// +// Public class // +////////////////// + +DuiOrientationAnimation::DuiOrientationAnimation(DuiOrientationAnimationPrivate *d, + QObject *parent, DuiGroupAnimation::Type type) : + DuiGroupAnimation(d, type, parent) +{ +} + +DuiOrientationAnimation::DuiOrientationAnimation(QObject *parent, DuiGroupAnimation::Type type) : + DuiGroupAnimation(new DuiOrientationAnimationPrivate(), type, parent) +{ +} + +void DuiOrientationAnimation::setRootElement(QGraphicsWidget *rootElement) +{ + Q_D(DuiOrientationAnimation); + if (d->rootElement != rootElement) { + d->rootElement = rootElement; + rootElementChanged(); + } +} + +QGraphicsWidget *DuiOrientationAnimation::rootElement() +{ + Q_D(DuiOrientationAnimation); + return d->rootElement; +} + +void DuiOrientationAnimation::rootElementChanged() +{ +} +#endif diff --git a/src/animation/scene/duiorientationanimation.h b/src/animation/scene/duiorientationanimation.h new file mode 100644 index 000000000..f9fb22c3b --- /dev/null +++ b/src/animation/scene/duiorientationanimation.h @@ -0,0 +1,105 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIORIENTATIONANIMATION_H +#define DUIORIENTATIONANIMATION_H + +#include +#if QT_VERSION >= 0x040600 + +#include +#include +#include + +class QGraphicsWidget; +class DuiWindow; +class DuiSceneWindow; +class DuiOrientationAnimationPrivate; + +/*! + \class DuiOrientationAnimation + \brief DuiOrientationAnimation class provides abstract interface for orientation animations. + */ +class DuiOrientationAnimation : public DuiGroupAnimation +{ + Q_OBJECT + Q_DECLARE_PRIVATE(DuiOrientationAnimation) + + DUI_ANIMATION(DuiGroupAnimationStyle) + +protected: + + /*! + \brief Constructs the orientation animation. + */ + DuiOrientationAnimation(DuiOrientationAnimationPrivate *d, + QObject *parent, + DuiGroupAnimation::Type type = DuiGroupAnimation::Parallel); + +Q_SIGNALS: + /*! + \brief Signals that orientation has changed + */ + void orientationChanged(); + +public: + + /*! + \brief Constructs the orientation animation. + */ + DuiOrientationAnimation(QObject *parent, DuiGroupAnimation::Type type = DuiGroupAnimation::Parallel); + /*! + \brief Destroys the orientation animation. + */ + virtual ~DuiOrientationAnimation() {}; + + /*! + \brief Sets the root element which contains all scene windows + */ + void setRootElement(QGraphicsWidget *rootElement); + + /*! + \brief Add new scene window to animation + */ + virtual void addSceneWindow(DuiSceneWindow *window) = 0; + + /*! + \brief Remove scene window from animation + */ + virtual void removeSceneWindow(DuiSceneWindow *window) = 0; + + /*! + \brief Sets target angle for rotation + */ + virtual void setTargetRotationAngle(Dui::OrientationAngle start, Dui::OrientationAngle end) = 0; + +protected: + /*! + \brief Returns the root element which contains all scene windows + */ + QGraphicsWidget *rootElement(); + + /*! + \brief Notification of root element change + */ + virtual void rootElementChanged(); +}; + +#endif +#endif diff --git a/src/animation/scene/duiorientationanimation_p.h b/src/animation/scene/duiorientationanimation_p.h new file mode 100644 index 000000000..18f845b25 --- /dev/null +++ b/src/animation/scene/duiorientationanimation_p.h @@ -0,0 +1,35 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIORIENTATIONANIMATION_P_H +#define DUIORIENTATIONANIMATION_P_H + +#include "duigroupanimation_p.h" + +class DuiOrientationAnimationPrivate : public DuiGroupAnimationPrivate +{ + Q_DECLARE_PUBLIC(DuiOrientationAnimation) +public: + DuiOrientationAnimationPrivate(); + virtual ~DuiOrientationAnimationPrivate(); +private: + QGraphicsWidget *rootElement; +}; + +#endif diff --git a/src/animation/scene/duipageswitchanimation.cpp b/src/animation/scene/duipageswitchanimation.cpp new file mode 100644 index 000000000..def4966d0 --- /dev/null +++ b/src/animation/scene/duipageswitchanimation.cpp @@ -0,0 +1,105 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include + +#include "duipageswitchanimation.h" +#include "duipageswitchanimation_p.h" +#include "duiscenewindow.h" + +DuiPageSwitchAnimation::DuiPageSwitchAnimation(QObject *parent) : + DuiParallelAnimationGroup(new DuiPageSwitchAnimationPrivate, parent) +{ + Q_D(DuiPageSwitchAnimation); + + d->newPage = 0; + d->oldPage = 0; + + d->positionNewPageAnimation = new QPropertyAnimation; + d->positionNewPageAnimation->setPropertyName("pos"); + d->positionNewPageAnimation->setEasingCurve(style()->easingCurve()); + d->positionNewPageAnimation->setDuration(style()->duration()); + d->positionNewPageAnimation->setEndValue(QPointF(0, 0)); + addAnimation(d->positionNewPageAnimation); + + d->positionOldPageAnimation = new QPropertyAnimation; + d->positionOldPageAnimation->setPropertyName("pos"); + d->positionOldPageAnimation->setEasingCurve(style()->easingCurve()); + d->positionOldPageAnimation->setDuration(style()->duration()); + d->positionOldPageAnimation->setStartValue(QPointF(0, 0)); + addAnimation(d->positionOldPageAnimation); +} + +DuiPageSwitchAnimation::DuiPageSwitchAnimation(DuiPageSwitchAnimationPrivate *dd, QObject *parent) : + DuiParallelAnimationGroup(dd, parent) +{ +} + +void DuiPageSwitchAnimation::setNewPage(DuiSceneWindow *newPage) +{ + Q_D(DuiPageSwitchAnimation); + + d->newPage = newPage; +} + +void DuiPageSwitchAnimation::setOldPage(DuiSceneWindow *oldPage) +{ + Q_D(DuiPageSwitchAnimation); + + if (d->oldPage) + disconnect(this, SIGNAL(finished()), d->oldPage, SLOT(disappearNow())); + + d->oldPage = oldPage; + + connect(this, SIGNAL(finished()), oldPage, SLOT(disappearNow())); +} + +void DuiPageSwitchAnimation::setPageTransitionDirection(PageTransitionDirection direction) +{ + Q_D(DuiPageSwitchAnimation); + + d->direction = direction; +} + +void DuiPageSwitchAnimation::updateState(QAbstractAnimation::State newState, + QAbstractAnimation::State oldState) +{ + Q_D(DuiPageSwitchAnimation); + Q_UNUSED(oldState); + + if (newState != Running) + return; + + d->positionNewPageAnimation->setTargetObject(d->newPage); + d->positionOldPageAnimation->setTargetObject(d->oldPage); + + if (d->newPage) { + if (d->direction == LeftToRight) + d->positionNewPageAnimation->setStartValue(QPointF(d->newPage->boundingRect().width(), 0)); + else + d->positionNewPageAnimation->setStartValue(QPointF(-d->newPage->boundingRect().width(), 0)); + } + + if (d->oldPage) { + if (d->direction == LeftToRight) + d->positionOldPageAnimation->setEndValue(QPointF(-d->oldPage->boundingRect().width(), 0)); + else + d->positionOldPageAnimation->setEndValue(QPointF(d->oldPage->boundingRect().width(), 0)); + } +} diff --git a/src/animation/scene/duipageswitchanimation.h b/src/animation/scene/duipageswitchanimation.h new file mode 100644 index 000000000..7106baf81 --- /dev/null +++ b/src/animation/scene/duipageswitchanimation.h @@ -0,0 +1,56 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIPAGESWITCHANIMATION_H +#define DUIPAGESWITCHANIMATION_H + +#include + +#include +#include + +class DuiPageSwitchAnimationPrivate; +class DuiSceneWindow; + +class DuiPageSwitchAnimation : public DuiParallelAnimationGroup +{ + Q_OBJECT + Q_DECLARE_PRIVATE(DuiPageSwitchAnimation) + DUI_ANIMATION_GROUP(DuiPageSwitchAnimationStyle) + +public: + enum PageTransitionDirection { + LeftToRight, + RightToLeft + }; + + DuiPageSwitchAnimation(QObject *parent = NULL); + void setNewPage(DuiSceneWindow *newPage); + void setOldPage(DuiSceneWindow *oldPage); + void setPageTransitionDirection(PageTransitionDirection direction); + +protected: + + DuiPageSwitchAnimation(DuiPageSwitchAnimationPrivate *dd, QObject *parent = NULL); + + virtual void updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState); + +}; + +#endif diff --git a/src/animation/scene/duipageswitchanimation_p.h b/src/animation/scene/duipageswitchanimation_p.h new file mode 100644 index 000000000..8cf6abe0b --- /dev/null +++ b/src/animation/scene/duipageswitchanimation_p.h @@ -0,0 +1,45 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIPAGESWITCHANIMATION_P_H +#define DUIPAGESWITCHANIMATION_P_H + +#include "duipageswitchanimation.h" +#include "duiparallelanimationgroup_p.h" + +class DuiSceneWindow; +class QPropertyAnimation; + +class DuiPageSwitchAnimationPrivate : public DuiParallelAnimationGroupPrivate +{ + Q_DECLARE_PUBLIC(DuiPageSwitchAnimation) +public: + DuiSceneWindow *sceneWindow; + +protected: + DuiSceneWindow *newPage; + DuiSceneWindow *oldPage; + + QPropertyAnimation *positionNewPageAnimation; + QPropertyAnimation *positionOldPageAnimation; + + DuiPageSwitchAnimation::PageTransitionDirection direction; +}; + +#endif diff --git a/src/animation/scene/duiscenefadeanimation.cpp b/src/animation/scene/duiscenefadeanimation.cpp new file mode 100644 index 000000000..323bd3a76 --- /dev/null +++ b/src/animation/scene/duiscenefadeanimation.cpp @@ -0,0 +1,86 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiscenefadeanimation.h" + +#if QT_VERSION >= 0x040600 + + +#include "duiscenefadeanimation_p.h" +#include "duiscenewindow.h" +#include "duiscenemanager.h" +#include "duiwidgetanimation.h" + +//#include +#include +#include + +DuiSceneFadeAnimation::DuiSceneFadeAnimation(DuiSceneWindow *window, QObject *parent) : + DuiSceneWindowAnimation(new DuiSceneFadeAnimationPrivate, window, parent) +{ + Q_D(DuiSceneFadeAnimation); + + //d->positionAnimation = new QPropertyAnimation(window, "pos", group()); + d->animation = new DuiWidgetAnimation(group()); + //d->animation->addWidget(window); +} + +DuiSceneFadeAnimation::DuiSceneFadeAnimation(DuiSceneFadeAnimationPrivate *dd, DuiSceneWindow *window, QObject *parent) : + DuiSceneWindowAnimation(dd, window, parent) +{ + Q_D(DuiSceneFadeAnimation); + + //d->positionAnimation = new QPropertyAnimation(window, "pos", group()); + d->animation = new DuiWidgetAnimation(group()); + d->animation->addWidget(window); +} + +void DuiSceneFadeAnimation::setType(DuiSceneWindowAnimation::Type type, bool useCurrentAsStartValue) +{ + Q_D(DuiSceneFadeAnimation); + + switch (type) { + case DuiSceneWindowAnimation::Show: { + + if (!useCurrentAsStartValue) + d->sceneWindow->setOpacity(0.0); + + /*d->sceneWindow->setTransformOrigin(QPointF(432, 240)); + d->sceneWindow->setXScale(0.0); + d->sceneWindow->setYScale(0.0); + d->animation->setTargetValue(d->sceneWindow, "xScale",1.0); + d->animation->setTargetValue(d->sceneWindow, "yScale",1.0); + d->animation->setDuration(500);*/ + //d->animation->setEasingCurve(QEasingCurve::OutBounce); + + d->animation->setTargetOpacity(d->sceneWindow, 1.0); + d->animation->setDuration(style()->showDuration(), "opacity"); + } break; + + case DuiSceneWindowAnimation::Hide: + + d->animation->setTargetOpacity(d->sceneWindow, 0.0); + d->animation->setDuration(style()->hideDuration()); + break; + + case DuiSceneWindowAnimation::Move: + break; + } +} +#endif diff --git a/src/animation/scene/duiscenefadeanimation.h b/src/animation/scene/duiscenefadeanimation.h new file mode 100644 index 000000000..f7e313002 --- /dev/null +++ b/src/animation/scene/duiscenefadeanimation.h @@ -0,0 +1,66 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISCENEFADEANIMATION_H +#define DUISCENEFADEANIMATION_H + +#include +#if QT_VERSION >= 0x040600 + +#include +#include + +class DuiSceneFadeAnimationPrivate; + +/*! + \class DuiNavigationbarAnimation + \brief + */ +class DuiSceneFadeAnimation : public DuiSceneWindowAnimation +{ + Q_OBJECT + Q_DECLARE_PRIVATE(DuiSceneFadeAnimation) + DUI_ANIMATION(DuiSceneWindowAnimationStyle) + +protected: + + /*! + \brief Constructs the navigation bar animation. + + This constructor is meant to be used inside the libdui to share the + private data class pointer. + */ + DuiSceneFadeAnimation(DuiSceneFadeAnimationPrivate *dd, DuiSceneWindow *window, QObject *parent = NULL); + +public: + + /*! + \brief Constructs the scene window animation. + */ + DuiSceneFadeAnimation(DuiSceneWindow *window, QObject *parent = NULL); + + /*! + \brief Sets animation type. + */ + virtual void setType(DuiSceneWindowAnimation::Type type, bool useCurrentAsStartValue); +}; + +#endif +#endif + diff --git a/src/animation/scene/duiscenefadeanimation_p.h b/src/animation/scene/duiscenefadeanimation_p.h new file mode 100644 index 000000000..af0fbe7c9 --- /dev/null +++ b/src/animation/scene/duiscenefadeanimation_p.h @@ -0,0 +1,34 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISCENEFADEANIMATION_P_H +#define DUISCENEFADEANIMATION_P_H + +#include "duiscenewindowanimation_p.h" +class DuiWidgetAnimation; + +class DuiSceneFadeAnimationPrivate : public DuiSceneWindowAnimationPrivate +{ + Q_DECLARE_PUBLIC(DuiSceneFadeAnimation) + +public: + DuiWidgetAnimation *animation; +}; + +#endif diff --git a/src/animation/scene/duiscenewindowanimation.cpp b/src/animation/scene/duiscenewindowanimation.cpp new file mode 100644 index 000000000..fcfda73b5 --- /dev/null +++ b/src/animation/scene/duiscenewindowanimation.cpp @@ -0,0 +1,67 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiscenewindowanimation.h" + +#if QT_VERSION >= 0x040600 + +#include "duiscenewindowanimation_p.h" + +#include +#include +#include + + +DuiSceneWindowAnimation::DuiSceneWindowAnimation(DuiSceneWindowAnimationPrivate *dd, + DuiSceneWindow *window, + QObject *parent, + DuiGroupAnimation::Type type) : + DuiGroupAnimation(dd, type, parent) +{ + Q_D(DuiSceneWindowAnimation); + + d->sceneWindow = window; +} + +DuiSceneWindowAnimation::DuiSceneWindowAnimation(DuiSceneWindow *window, + QObject *parent, + DuiGroupAnimation::Type type) : + DuiGroupAnimation(new DuiSceneWindowAnimationPrivate, type, parent) +{ + Q_D(DuiSceneWindowAnimation); + + d->sceneWindow = window; +} + +DuiSceneWindowAnimation::~DuiSceneWindowAnimation() +{ +} + +void DuiSceneWindowAnimation::updateState(QAbstractAnimation::State oldState, + QAbstractAnimation::State newState) +{ + DuiGroupAnimation::updateState(oldState, newState); + + if (newState == QAbstractAnimation::Stopped) { + Q_D(DuiSceneWindowAnimation); + emit animationDone(d->sceneWindow); + } +} +#endif + diff --git a/src/animation/scene/duiscenewindowanimation.h b/src/animation/scene/duiscenewindowanimation.h new file mode 100644 index 000000000..91617510e --- /dev/null +++ b/src/animation/scene/duiscenewindowanimation.h @@ -0,0 +1,90 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISCENEWINDOWANIMATION_H +#define DUISCENEWINDOWANIMATION_H + +#include +#if QT_VERSION >= 0x040600 + +#include +#include +#include +#include + +class DuiSceneWindow; +class DuiSceneWindowAnimationPrivate; + +/*! + \class DuiSceneWindowAnimation + \brief + */ +class DuiSceneWindowAnimation : public DuiGroupAnimation +{ + Q_OBJECT + Q_DECLARE_PRIVATE(DuiSceneWindowAnimation) + DUI_ANIMATION(DuiSceneWindowAnimationStyle) + +protected: + + /*! + \brief Constructs the scene window animation. + + This constructor is meant to be used inside the libdui to share the + private data class pointer. + */ + DuiSceneWindowAnimation(DuiSceneWindowAnimationPrivate *dd, + DuiSceneWindow *window, + QObject *parent = NULL, + DuiGroupAnimation::Type type = Parallel); + +public: + + enum Type { + Show, + Hide, + Move + }; + + /*! + \brief Constructs the scene window animation. + */ + DuiSceneWindowAnimation(DuiSceneWindow *window, + QObject *parent = NULL, + DuiGroupAnimation::Type type = Parallel); + + /*! + \brief Destructs the scene window animation. + */ + virtual ~DuiSceneWindowAnimation(); + + /*! + \brief Sets animation type. + */ + virtual void setType(Type type, bool useCurrentAsStartValue = true) = 0; + +Q_SIGNALS: + void animationDone(DuiSceneWindow *window); + +protected: + virtual void updateState(QAbstractAnimation::State oldState, QAbstractAnimation::State newState); +}; + +#endif +#endif diff --git a/src/animation/scene/duiscenewindowanimation_p.h b/src/animation/scene/duiscenewindowanimation_p.h new file mode 100644 index 000000000..c231fa920 --- /dev/null +++ b/src/animation/scene/duiscenewindowanimation_p.h @@ -0,0 +1,34 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISCENEWINDOWANIMATION_P_H +#define DUISCENEWINDOWANIMATION_P_H + +#include "duigroupanimation_p.h" + +class DuiSceneWindow; + +class DuiSceneWindowAnimationPrivate : public DuiGroupAnimationPrivate +{ + Q_DECLARE_PUBLIC(DuiSceneWindowAnimation) +public: + DuiSceneWindow *sceneWindow; +}; + +#endif diff --git a/src/animation/scene/scene.pri b/src/animation/scene/scene.pri new file mode 100644 index 000000000..d26dad43b --- /dev/null +++ b/src/animation/scene/scene.pri @@ -0,0 +1,38 @@ +############################################################################### +# DuiAnimation/Core module +# This module contains core animation code. +############################################################################### + +ANIMATIONS_SCENE_SRC_DIR=./animation/scene + +#public +HEADERS += \ + $$ANIMATIONS_SCENE_SRC_DIR/duiorientationanimation.h \ + $$ANIMATIONS_SCENE_SRC_DIR/duibasicorientationanimation.h \ + $$ANIMATIONS_SCENE_SRC_DIR/duifliporientationanimation.h \ + $$ANIMATIONS_SCENE_SRC_DIR/duiscenewindowanimation.h \ + $$ANIMATIONS_SCENE_SRC_DIR/duinavigationbaranimation.h \ + $$ANIMATIONS_SCENE_SRC_DIR/duinotificationanimation.h \ + $$ANIMATIONS_SCENE_SRC_DIR/duiscenefadeanimation.h \ + $$ANIMATIONS_SCENE_SRC_DIR/duipageswitchanimation.h \ + +#private +HEADERS += \ + $$ANIMATIONS_SCENE_SRC_DIR/duiorientationanimation_p.h \ + $$ANIMATIONS_SCENE_SRC_DIR/duibasicorientationanimation_p.h \ + $$ANIMATIONS_SCENE_SRC_DIR/duifliporientationanimation_p.h \ + $$ANIMATIONS_SCENE_SRC_DIR/duiscenewindowanimation_p.h \ + $$ANIMATIONS_SCENE_SRC_DIR/duinavigationbaranimation_p.h \ + $$ANIMATIONS_SCENE_SRC_DIR/duinotificationanimation_p.h \ + $$ANIMATIONS_SCENE_SRC_DIR/duiscenefadeanimation_p.h \ + $$ANIMATIONS_SCENE_SRC_DIR/duipageswitchanimation_p.h \ + +SOURCES += \ + $$ANIMATIONS_SCENE_SRC_DIR/duiorientationanimation.cpp \ + $$ANIMATIONS_SCENE_SRC_DIR/duibasicorientationanimation.cpp \ + $$ANIMATIONS_SCENE_SRC_DIR/duifliporientationanimation.cpp \ + $$ANIMATIONS_SCENE_SRC_DIR/duiscenewindowanimation.cpp \ + $$ANIMATIONS_SCENE_SRC_DIR/duinavigationbaranimation.cpp \ + $$ANIMATIONS_SCENE_SRC_DIR/duinotificationanimation.cpp \ + $$ANIMATIONS_SCENE_SRC_DIR/duiscenefadeanimation.cpp \ + $$ANIMATIONS_SCENE_SRC_DIR/duipageswitchanimation.cpp \ diff --git a/src/animation/widget/core/core.pri b/src/animation/widget/core/core.pri new file mode 100644 index 000000000..83e35e0db --- /dev/null +++ b/src/animation/widget/core/core.pri @@ -0,0 +1,17 @@ +############################################################################### +# DuiAnimation/Widget/Core module +# This module contains widget core animation code. +############################################################################### + +ANIMATIONS_WIDGET_CORE_SRC_DIR=./animation/widget/core + +#public +HEADERS += \ + $$ANIMATIONS_WIDGET_CORE_SRC_DIR/duiabstractwidgetanimation.h \ + +#private +HEADERS += \ + $$ANIMATIONS_WIDGET_CORE_SRC_DIR/duiabstractwidgetanimation_p.h \ + +SOURCES += \ + $$ANIMATIONS_WIDGET_CORE_SRC_DIR/duiabstractwidgetanimation.cpp \ diff --git a/src/animation/widget/core/duiabstractwidgetanimation.cpp b/src/animation/widget/core/duiabstractwidgetanimation.cpp new file mode 100644 index 000000000..1e1142234 --- /dev/null +++ b/src/animation/widget/core/duiabstractwidgetanimation.cpp @@ -0,0 +1,82 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiabstractwidgetanimation.h" +#include "duiabstractwidgetanimation_p.h" + +#include "duiwidgetview.h" +#include "private/duiwidgetview_p.h" + +DuiAbstractWidgetAnimation::DuiAbstractWidgetAnimation(DuiAbstractWidgetAnimationPrivate *dd, QObject *parent) : + DuiAnimation(dd, parent) +{ +} + +DuiAbstractWidgetAnimation::DuiAbstractWidgetAnimation(QObject *parent) : + DuiAnimation(new DuiAbstractWidgetAnimationPrivate, parent) +{ +} + +DuiAbstractWidgetAnimation::~DuiAbstractWidgetAnimation() +{ +} + +void DuiAbstractWidgetAnimation::resetToInitialState() +{ +} + +int DuiAbstractWidgetAnimation::duration() const +{ + return style()->duration(); +} + +DuiWidgetView *DuiAbstractWidgetAnimation::view() +{ + Q_D(DuiAbstractWidgetAnimation); + return d->view; +} + +const DuiWidgetView *DuiAbstractWidgetAnimation::view() const +{ + Q_D(const DuiAbstractWidgetAnimation); + return d->view; +} + +bool DuiAbstractWidgetAnimation::setView(DuiWidgetView *view) +{ + Q_D(DuiAbstractWidgetAnimation); + bool inherits = false; + const QMetaObject *mobj = view->metaObject(); + while (mobj) { + if (strcmp(viewType(), mobj->className()) == 0) { + inherits = true; + break; + } + mobj = mobj->superClass(); + } + + if (!inherits) + return false; + + d->view = view; + + style().setParent(view->d_func()->controller); + + return true; +} diff --git a/src/animation/widget/core/duiabstractwidgetanimation.h b/src/animation/widget/core/duiabstractwidgetanimation.h new file mode 100644 index 000000000..4db4b4e77 --- /dev/null +++ b/src/animation/widget/core/duiabstractwidgetanimation.h @@ -0,0 +1,104 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIABSTRACTWIDGETANIMATION_H +#define DUIABSTRACTWIDGETANIMATION_H + +#include +#include + +#define DUI_WIDGET_ANIMATION(STYLE,VIEW) \ + DUI_ANIMATION(STYLE) \ + public: \ + inline virtual const char* viewType() const { return #VIEW; } \ + private: \ + inline VIEW* view() { return static_cast(DuiAbstractWidgetAnimation::view()); } \ + inline const VIEW* view() const { return static_cast(DuiAbstractWidgetAnimation::view()); } + + +class DuiWidgetView; +class DuiAbstractWidgetAnimationPrivate; + +/*! + \class DuiAbstractWidgetAnimation + \brief DuiAbstractWidgetAnimation class is a base class for all widget animations. + + */ +class DuiAbstractWidgetAnimation : public DuiAnimation +{ + Q_OBJECT + Q_DECLARE_PRIVATE(DuiAbstractWidgetAnimation) + DUI_ANIMATION(DuiAbstractWidgetAnimationStyle) + + friend class DuiWidgetView; + friend class DuiSceneWindowView; + +protected: + /*! + \brief Constructs the widget animation. + + This constructor is meant to be used inside the libdui to share the + private data class pointer. + */ + DuiAbstractWidgetAnimation(DuiAbstractWidgetAnimationPrivate *dd, QObject *parent); + +public: + + /*! + \brief Constructs the widget animation. + */ + DuiAbstractWidgetAnimation(QObject *parent = NULL); + + /*! + \brief Destructs the widget animation. + */ + virtual ~DuiAbstractWidgetAnimation(); + + /*! + \brief Resets the initial state to the widget. + + Reimplement this method in your animation in so when the animation starts it + will animate from initial state to target values. + If this method is not called, then the animation should animate from + the current values to target values. + */ + virtual void resetToInitialState(); + + //! \reimp + virtual int duration() const; + //! \reimp_end + + /*! + \brief Returns the type of the view which this animation supports. + + This method gets automatically overriden by DUI_WIDGET_ANIMATION macro. + */ + virtual const char *viewType() const { + return "DuiWidgetView"; + } + +protected: + DuiWidgetView *view(); + const DuiWidgetView *view() const; + +private: + bool setView(DuiWidgetView *view); +}; + +#endif diff --git a/src/animation/widget/core/duiabstractwidgetanimation_p.h b/src/animation/widget/core/duiabstractwidgetanimation_p.h new file mode 100644 index 000000000..a7bddc50a --- /dev/null +++ b/src/animation/widget/core/duiabstractwidgetanimation_p.h @@ -0,0 +1,36 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIABSTRACTWIDGETANIMATION_P_H +#define DUIABSTRACTWIDGETANIMATION_P_H + +#include "duianimation_p.h" + +class DuiWidgetView; + +class DuiAbstractWidgetAnimationPrivate : public DuiAnimationPrivate +{ + Q_DECLARE_PUBLIC(DuiAbstractWidgetAnimation) +public: + virtual ~DuiAbstractWidgetAnimationPrivate() {} +private: + DuiWidgetView *view; +}; + +#endif diff --git a/src/animation/widget/duiwidgetfadeinanimation.cpp b/src/animation/widget/duiwidgetfadeinanimation.cpp new file mode 100644 index 000000000..d8b5d2367 --- /dev/null +++ b/src/animation/widget/duiwidgetfadeinanimation.cpp @@ -0,0 +1,66 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiwidgetfadeinanimation.h" +#include "duiwidgetfadeinanimation_p.h" +#include "duiwidgetview.h" +#include "duianimationcreator.h" + +DUI_REGISTER_ANIMATION(DuiWidgetFadeInAnimation) + +DuiWidgetFadeInAnimation::DuiWidgetFadeInAnimation(DuiWidgetFadeInAnimationPrivate *dd, QObject *parent) : + DuiAbstractWidgetAnimation(dd, parent) +{ + dd->startOpacity = 255; +} + +DuiWidgetFadeInAnimation::DuiWidgetFadeInAnimation(QObject *parent) : + DuiAbstractWidgetAnimation(new DuiWidgetFadeInAnimationPrivate, parent) +{ + Q_D(DuiWidgetFadeInAnimation); + d->startOpacity = 255; +} + +DuiWidgetFadeInAnimation::~DuiWidgetFadeInAnimation() +{ +} + +void DuiWidgetFadeInAnimation::resetToInitialState() +{ + view()->setOpacity(0.0); +} + +void DuiWidgetFadeInAnimation::updateCurrentTime(int currentTime) +{ + Q_D(DuiWidgetFadeInAnimation); + + qreal progress = ((qreal)currentTime) / ((qreal)style()->duration()); + qreal value = style()->easingCurve().valueForProgress(progress); + + view()->setOpacity(d->startOpacity + (style()->opacity() - d->startOpacity)*value); +} + +void DuiWidgetFadeInAnimation::updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState) +{ + Q_D(DuiWidgetFadeInAnimation); + if (oldState == QAbstractAnimation::Stopped && newState == QAbstractAnimation::Running) { + view()->show(); + d->startOpacity = view()->opacity(); + } +} diff --git a/src/animation/widget/duiwidgetfadeinanimation.h b/src/animation/widget/duiwidgetfadeinanimation.h new file mode 100644 index 000000000..5ef35104a --- /dev/null +++ b/src/animation/widget/duiwidgetfadeinanimation.h @@ -0,0 +1,67 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIWIDGETFADEINANIMATION_H +#define DUIWIDGETFADEINANIMATION_H + +#include +#include + +class DuiWidgetFadeInAnimationPrivate; + +//! \internal +class DuiWidgetFadeInAnimation : public DuiAbstractWidgetAnimation +{ + Q_OBJECT + Q_DECLARE_PRIVATE(DuiWidgetFadeInAnimation) + DUI_WIDGET_ANIMATION(DuiWidgetFadeInAnimationStyle, DuiWidgetView) + + /*! + \brief Constructs the widget animation. + + This constructor is meant to be used inside the libdui to share the + private data class pointer. + */ + DuiWidgetFadeInAnimation(DuiWidgetFadeInAnimationPrivate *dd, QObject *parent); + +public: + + /*! + \brief Constructs the widget animation. + */ + DuiWidgetFadeInAnimation(QObject *parent = NULL); + + /*! + \brief Destructs the widget animation. + */ + virtual ~DuiWidgetFadeInAnimation(); + + //! \reimp + virtual void resetToInitialState(); + //! \reimp_end + +protected: + //! \reimp + virtual void updateCurrentTime(int currentTime); + virtual void updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState); + //! \reimp_end +}; +//! \internal + +#endif diff --git a/src/animation/widget/duiwidgetfadeinanimation_p.h b/src/animation/widget/duiwidgetfadeinanimation_p.h new file mode 100644 index 000000000..4c83756d9 --- /dev/null +++ b/src/animation/widget/duiwidgetfadeinanimation_p.h @@ -0,0 +1,34 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIWIDGETFADEINANIMATION_P_H +#define DUIWIDGETFADEINANIMATION_P_H + +#include "duiabstractwidgetanimation_p.h" + +class DuiWidgetFadeInAnimationPrivate : public DuiAbstractWidgetAnimationPrivate +{ + Q_DECLARE_PUBLIC(DuiWidgetFadeInAnimation) +public: + virtual ~DuiWidgetFadeInAnimationPrivate() {} +private: + qreal startOpacity; +}; + +#endif diff --git a/src/animation/widget/duiwidgetfadeoutanimation.cpp b/src/animation/widget/duiwidgetfadeoutanimation.cpp new file mode 100644 index 000000000..bacfad542 --- /dev/null +++ b/src/animation/widget/duiwidgetfadeoutanimation.cpp @@ -0,0 +1,62 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiwidgetfadeoutanimation.h" +#include "duiwidgetfadeoutanimation_p.h" +#include "duiwidgetview.h" +#include "duianimationcreator.h" + +DUI_REGISTER_ANIMATION(DuiWidgetFadeOutAnimation) + +DuiWidgetFadeOutAnimation::DuiWidgetFadeOutAnimation(DuiWidgetFadeOutAnimationPrivate *dd, QObject *parent) : + DuiAbstractWidgetAnimation(dd, parent) +{ + dd->startOpacity = 255; +} + +DuiWidgetFadeOutAnimation::DuiWidgetFadeOutAnimation(QObject *parent) : + DuiAbstractWidgetAnimation(new DuiWidgetFadeOutAnimationPrivate, parent) +{ + Q_D(DuiWidgetFadeOutAnimation); + d->startOpacity = 255; +} + +DuiWidgetFadeOutAnimation::~DuiWidgetFadeOutAnimation() +{ +} + +void DuiWidgetFadeOutAnimation::updateCurrentTime(int currentTime) +{ + Q_D(DuiWidgetFadeOutAnimation); + + qreal progress = ((qreal)currentTime) / ((qreal)style()->duration()); + qreal value = style()->easingCurve().valueForProgress(progress); + + view()->setOpacity(d->startOpacity + (style()->opacity() - d->startOpacity)*value); +} + +void DuiWidgetFadeOutAnimation::updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState) +{ + Q_D(DuiWidgetFadeOutAnimation); + if (oldState == QAbstractAnimation::Stopped && newState == QAbstractAnimation::Running) { + d->startOpacity = view()->opacity(); + } else if (oldState == QAbstractAnimation::Running && newState == QAbstractAnimation::Stopped) { + view()->hide(); + } +} diff --git a/src/animation/widget/duiwidgetfadeoutanimation.h b/src/animation/widget/duiwidgetfadeoutanimation.h new file mode 100644 index 000000000..6ee3f4ecd --- /dev/null +++ b/src/animation/widget/duiwidgetfadeoutanimation.h @@ -0,0 +1,63 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIWIDGETFADEOUTANIMATION_H +#define DUIWIDGETFADEOUTANIMATION_H + +#include +#include + +class DuiWidgetFadeOutAnimationPrivate; + +//! \internal +class DuiWidgetFadeOutAnimation : public DuiAbstractWidgetAnimation +{ + Q_OBJECT + Q_DECLARE_PRIVATE(DuiWidgetFadeOutAnimation) + DUI_WIDGET_ANIMATION(DuiWidgetFadeOutAnimationStyle, DuiWidgetView) + + /*! + \brief Constructs the widget animation. + + This constructor is meant to be used inside the libdui to share the + private data class pointer. + */ + DuiWidgetFadeOutAnimation(DuiWidgetFadeOutAnimationPrivate *dd, QObject *parent); + +public: + + /*! + \brief Constructs the widget animation. + */ + DuiWidgetFadeOutAnimation(QObject *parent = NULL); + + /*! + \brief Destructs the widget animation. + */ + virtual ~DuiWidgetFadeOutAnimation(); + +protected: + //! \reimp + virtual void updateCurrentTime(int currentTime); + virtual void updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState); + //! \reimp_end +}; +//! \internal_end + +#endif diff --git a/src/animation/widget/duiwidgetfadeoutanimation_p.h b/src/animation/widget/duiwidgetfadeoutanimation_p.h new file mode 100644 index 000000000..394a39d3b --- /dev/null +++ b/src/animation/widget/duiwidgetfadeoutanimation_p.h @@ -0,0 +1,34 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIWIDGETFADEOUTANIMATION_P_H +#define DUIWIDGETFADEOUTANIMATION_P_H + +#include "duiabstractwidgetanimation_p.h" + +class DuiWidgetFadeOutAnimationPrivate : public DuiAbstractWidgetAnimationPrivate +{ + Q_DECLARE_PUBLIC(DuiWidgetFadeOutAnimation) +public: + virtual ~DuiWidgetFadeOutAnimationPrivate() {} +private: + qreal startOpacity; +}; + +#endif diff --git a/src/animation/widget/duiwidgetslideinanimation.cpp b/src/animation/widget/duiwidgetslideinanimation.cpp new file mode 100644 index 000000000..6c3731a65 --- /dev/null +++ b/src/animation/widget/duiwidgetslideinanimation.cpp @@ -0,0 +1,79 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiwidgetslideinanimation.h" +#include "duiwidgetslideinanimation_p.h" +#include "duiwidgetview.h" +#include "duianimationcreator.h" + +DUI_REGISTER_ANIMATION(DuiWidgetSlideInAnimation) + +DuiWidgetSlideInAnimation::DuiWidgetSlideInAnimation(DuiWidgetSlideInAnimationPrivate *dd, QObject *parent) : + DuiAbstractWidgetAnimation(dd, parent) +{ +} + +DuiWidgetSlideInAnimation::DuiWidgetSlideInAnimation(QObject *parent) : + DuiAbstractWidgetAnimation(new DuiWidgetSlideInAnimationPrivate, parent) +{ +} + +DuiWidgetSlideInAnimation::~DuiWidgetSlideInAnimation() +{ +} + +void DuiWidgetSlideInAnimation::resetToInitialState() +{ + if (style()->from() == "top") { + view()->setContentPosition(QPointF(0, -view()->boundingRect().height())); + } else if (style()->from() == "right") { + view()->setContentPosition(QPointF(view()->boundingRect().width(), 0)); + } else if (style()->from() == "bottom") { + view()->setContentPosition(QPointF(0, view()->boundingRect().height())); + } else if (style()->from() == "left") { + view()->setContentPosition(QPointF(-view()->boundingRect().width(), 0)); + } +} + +void DuiWidgetSlideInAnimation::updateCurrentTime(int currentTime) +{ + Q_D(DuiWidgetSlideInAnimation); + + qreal progress = ((qreal)currentTime) / ((qreal)style()->duration()); + qreal value = style()->easingCurve().valueForProgress(progress); + + view()->setContentPosition((1.0 - value) * d->startPos); +} + +void DuiWidgetSlideInAnimation::updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState) +{ + Q_D(DuiWidgetSlideInAnimation); + if (oldState == QAbstractAnimation::Stopped && newState == QAbstractAnimation::Running) { + view()->show(); + if (style()->from() == "top") { + d->startPos = QPointF(0, -view()->boundingRect().height()); + } else if (style()->from() == "right") { + d->startPos = QPointF(view()->boundingRect().width(), 0); + } else if (style()->from() == "bottom") { + d->startPos = QPointF(0, view()->boundingRect().height()); + } else if (style()->from() == "left") { + d->startPos = QPointF(-view()->boundingRect().width(), 0); + } + } +} diff --git a/src/animation/widget/duiwidgetslideinanimation.h b/src/animation/widget/duiwidgetslideinanimation.h new file mode 100644 index 000000000..d3fd0db65 --- /dev/null +++ b/src/animation/widget/duiwidgetslideinanimation.h @@ -0,0 +1,67 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIWIDGETSLIDEINANIMATION_H +#define DUIWIDGETSLIDEINANIMATION_H + +#include +#include + +class DuiWidgetSlideInAnimationPrivate; + +//! \internal +class DuiWidgetSlideInAnimation : public DuiAbstractWidgetAnimation +{ + Q_OBJECT + Q_DECLARE_PRIVATE(DuiWidgetSlideInAnimation) + DUI_WIDGET_ANIMATION(DuiWidgetSlideInAnimationStyle, DuiWidgetView) + + /*! + \brief Constructs the widget animation. + + This constructor is meant to be used inside the libdui to share the + private data class pointer. + */ + DuiWidgetSlideInAnimation(DuiWidgetSlideInAnimationPrivate *dd, QObject *parent); + +public: + + /*! + \brief Constructs the widget animation. + */ + DuiWidgetSlideInAnimation(QObject *parent = NULL); + + /*! + \brief Destructs the widget animation. + */ + virtual ~DuiWidgetSlideInAnimation(); + + //! \reimp + virtual void resetToInitialState(); + //! \reimp_end + +protected: + //! \reimp + virtual void updateCurrentTime(int currentTime); + virtual void updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState); + //! \reimp_end +}; +//! \internal_end + +#endif diff --git a/src/animation/widget/duiwidgetslideinanimation_p.h b/src/animation/widget/duiwidgetslideinanimation_p.h new file mode 100644 index 000000000..0fed80811 --- /dev/null +++ b/src/animation/widget/duiwidgetslideinanimation_p.h @@ -0,0 +1,35 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIWIDGETSLIDEINANIMATION_P_H +#define DUIWIDGETSLIDEINANIMATION_P_H + +#include "duiabstractwidgetanimation_p.h" +#include + +class DuiWidgetSlideInAnimationPrivate : public DuiAbstractWidgetAnimationPrivate +{ + Q_DECLARE_PUBLIC(DuiWidgetSlideInAnimation) +public: + virtual ~DuiWidgetSlideInAnimationPrivate() {} +private: + QPointF startPos; +}; + +#endif diff --git a/src/animation/widget/duiwidgetslideoutanimation.cpp b/src/animation/widget/duiwidgetslideoutanimation.cpp new file mode 100644 index 000000000..19a73ebf5 --- /dev/null +++ b/src/animation/widget/duiwidgetslideoutanimation.cpp @@ -0,0 +1,68 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiwidgetslideoutanimation.h" +#include "duiwidgetslideoutanimation_p.h" +#include "duiwidgetview.h" +#include "duianimationcreator.h" + +DUI_REGISTER_ANIMATION(DuiWidgetSlideOutAnimation) + +DuiWidgetSlideOutAnimation::DuiWidgetSlideOutAnimation(DuiWidgetSlideOutAnimationPrivate *dd, QObject *parent) : + DuiAbstractWidgetAnimation(dd, parent) +{ +} + +DuiWidgetSlideOutAnimation::DuiWidgetSlideOutAnimation(QObject *parent) : + DuiAbstractWidgetAnimation(new DuiWidgetSlideOutAnimationPrivate, parent) +{ +} + +DuiWidgetSlideOutAnimation::~DuiWidgetSlideOutAnimation() +{ +} + +void DuiWidgetSlideOutAnimation::updateCurrentTime(int currentTime) +{ + Q_D(DuiWidgetSlideOutAnimation); + + qreal progress = ((qreal)currentTime) / ((qreal)style()->duration()); + qreal value = style()->easingCurve().valueForProgress(progress); + + view()->setContentPosition(d->startPos + (d->endPos - d->startPos)*value); +} + +void DuiWidgetSlideOutAnimation::updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState) +{ + Q_D(DuiWidgetSlideOutAnimation); + if (oldState == QAbstractAnimation::Stopped && newState == QAbstractAnimation::Running) { + d->startPos = view()->contentPosition(); + if (style()->to() == "top") { + d->endPos = QPointF(0, -view()->boundingRect().height()); + } else if (style()->to() == "right") { + d->endPos = QPointF(view()->boundingRect().width(), 0); + } else if (style()->to() == "bottom") { + d->endPos = QPointF(0, view()->boundingRect().height()); + } else if (style()->to() == "left") { + d->endPos = QPointF(-view()->boundingRect().width(), 0); + } + } else if (oldState == QAbstractAnimation::Running && newState == QAbstractAnimation::Stopped) { + view()->hide(); + } +} diff --git a/src/animation/widget/duiwidgetslideoutanimation.h b/src/animation/widget/duiwidgetslideoutanimation.h new file mode 100644 index 000000000..36e0e2bc8 --- /dev/null +++ b/src/animation/widget/duiwidgetslideoutanimation.h @@ -0,0 +1,63 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIWIDGETSLIDEOUTANIMATION_H +#define DUIWIDGETSLIDEOUTANIMATION_H + +#include +#include + +class DuiWidgetSlideOutAnimationPrivate; + +//! \internal +class DuiWidgetSlideOutAnimation : public DuiAbstractWidgetAnimation +{ + Q_OBJECT + Q_DECLARE_PRIVATE(DuiWidgetSlideOutAnimation) + DUI_WIDGET_ANIMATION(DuiWidgetSlideOutAnimationStyle, DuiWidgetView) + + /*! + \brief Constructs the widget animation. + + This constructor is meant to be used inside the libdui to share the + private data class pointer. + */ + DuiWidgetSlideOutAnimation(DuiWidgetSlideOutAnimationPrivate *dd, QObject *parent); + +public: + + /*! + \brief Constructs the widget animation. + */ + DuiWidgetSlideOutAnimation(QObject *parent = NULL); + + /*! + \brief Destructs the widget animation. + */ + virtual ~DuiWidgetSlideOutAnimation(); + +protected: + //! \reimp + virtual void updateCurrentTime(int currentTime); + virtual void updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState); + //! \reimp_end +}; +//! \internal_end + +#endif diff --git a/src/animation/widget/duiwidgetslideoutanimation_p.h b/src/animation/widget/duiwidgetslideoutanimation_p.h new file mode 100644 index 000000000..077613034 --- /dev/null +++ b/src/animation/widget/duiwidgetslideoutanimation_p.h @@ -0,0 +1,36 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIWIDGETSLIDEOUTANIMATION_P_H +#define DUIWIDGETSLIDEOUTANIMATION_P_H + +#include "duiabstractwidgetanimation_p.h" +#include + +class DuiWidgetSlideOutAnimationPrivate : public DuiAbstractWidgetAnimationPrivate +{ + Q_DECLARE_PUBLIC(DuiWidgetSlideOutAnimation) +public: + virtual ~DuiWidgetSlideOutAnimationPrivate() {} +private: + QPointF startPos; + QPointF endPos; +}; + +#endif diff --git a/src/animation/widget/duiwidgetzoominanimation.cpp b/src/animation/widget/duiwidgetzoominanimation.cpp new file mode 100644 index 000000000..81ea9bdff --- /dev/null +++ b/src/animation/widget/duiwidgetzoominanimation.cpp @@ -0,0 +1,62 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiwidgetzoominanimation.h" +#include "duiwidgetzoominanimation_p.h" +#include "duiwidgetview.h" +#include "duianimationcreator.h" + +DUI_REGISTER_ANIMATION(DuiWidgetZoomInAnimation) + +DuiWidgetZoomInAnimation::DuiWidgetZoomInAnimation(DuiWidgetZoomInAnimationPrivate *dd, QObject *parent) : + DuiAbstractWidgetAnimation(dd, parent) +{ +} + +DuiWidgetZoomInAnimation::DuiWidgetZoomInAnimation(QObject *parent) : + DuiAbstractWidgetAnimation(new DuiWidgetZoomInAnimationPrivate, parent) +{ +} + +DuiWidgetZoomInAnimation::~DuiWidgetZoomInAnimation() +{ +} + +void DuiWidgetZoomInAnimation::resetToInitialState() +{ + view()->setScale(0.0); +} + +void DuiWidgetZoomInAnimation::updateCurrentTime(int currentTime) +{ + Q_D(DuiWidgetZoomInAnimation); + + qreal progress = ((qreal)currentTime) / ((qreal)style()->duration()); + qreal value = style()->easingCurve().valueForProgress(progress); + view()->setScale(d->startScale + (1 - d->startScale) * value); +} + +void DuiWidgetZoomInAnimation::updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState) +{ + Q_D(DuiWidgetZoomInAnimation); + if (oldState == QAbstractAnimation::Stopped && newState == QAbstractAnimation::Running) { + view()->show(); + d->startScale = view()->scale(); + } +} diff --git a/src/animation/widget/duiwidgetzoominanimation.h b/src/animation/widget/duiwidgetzoominanimation.h new file mode 100644 index 000000000..c02d9c91a --- /dev/null +++ b/src/animation/widget/duiwidgetzoominanimation.h @@ -0,0 +1,69 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIWIDGETZOOMINANIMATION_H +#define DUIWIDGETZOOMINANIMATION_H + +#include +#include + +class DuiWidgetZoomInAnimationPrivate; + + +//! \internal +class DuiWidgetZoomInAnimation : public DuiAbstractWidgetAnimation +{ + Q_OBJECT + Q_DECLARE_PRIVATE(DuiWidgetZoomInAnimation) + DUI_WIDGET_ANIMATION(DuiWidgetZoomInAnimationStyle, DuiWidgetView) + + /*! + \brief Constructs the widget animation. + + This constructor is meant to be used inside the libdui to share the + private data class pointer. + */ + DuiWidgetZoomInAnimation(DuiWidgetZoomInAnimationPrivate *dd, QObject *parent); + +public: + + /*! + \brief Constructs the widget animation. + */ + DuiWidgetZoomInAnimation(QObject *parent = NULL); + + /*! + \brief Destructs the widget animation. + */ + virtual ~DuiWidgetZoomInAnimation(); + + //! \reimp + virtual void resetToInitialState(); + //! \reimp_end + +protected: + //! \reimp + virtual void updateCurrentTime(int currentTime); + virtual void updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState); + //! \reimp_end +}; + +//! \internal_end + +#endif diff --git a/src/animation/widget/duiwidgetzoominanimation_p.h b/src/animation/widget/duiwidgetzoominanimation_p.h new file mode 100644 index 000000000..ceb0b5917 --- /dev/null +++ b/src/animation/widget/duiwidgetzoominanimation_p.h @@ -0,0 +1,34 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIWIDGETZOOMINANIMATION_P_H +#define DUIWIDGETZOOMINANIMATION_P_H + +#include "core/duiabstractwidgetanimation_p.h" + +class DuiWidgetZoomInAnimationPrivate : public DuiAbstractWidgetAnimationPrivate +{ + Q_DECLARE_PUBLIC(DuiWidgetZoomInAnimation) +public: + virtual ~DuiWidgetZoomInAnimationPrivate() {} +private: + qreal startScale; +}; + +#endif diff --git a/src/animation/widget/duiwidgetzoomoutanimation.cpp b/src/animation/widget/duiwidgetzoomoutanimation.cpp new file mode 100644 index 000000000..5759164b5 --- /dev/null +++ b/src/animation/widget/duiwidgetzoomoutanimation.cpp @@ -0,0 +1,57 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiwidgetzoomoutanimation.h" +#include "duiwidgetzoomoutanimation_p.h" +#include "duiwidgetview.h" +#include "duianimationcreator.h" + +DUI_REGISTER_ANIMATION(DuiWidgetZoomOutAnimation) + +DuiWidgetZoomOutAnimation::DuiWidgetZoomOutAnimation(DuiWidgetZoomOutAnimationPrivate *dd, QObject *parent) : + DuiAbstractWidgetAnimation(dd, parent) +{ +} + +DuiWidgetZoomOutAnimation::DuiWidgetZoomOutAnimation(QObject *parent) : + DuiAbstractWidgetAnimation(new DuiWidgetZoomOutAnimationPrivate, parent) +{ +} + +DuiWidgetZoomOutAnimation::~DuiWidgetZoomOutAnimation() +{ +} + +void DuiWidgetZoomOutAnimation::updateCurrentTime(int currentTime) +{ + Q_D(DuiWidgetZoomOutAnimation); + qreal progress = ((qreal)currentTime) / ((qreal)style()->duration()); + qreal value = style()->easingCurve().valueForProgress(progress); + view()->setScale(d->startScale - (d->startScale) * value); +} + +void DuiWidgetZoomOutAnimation::updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState) +{ + Q_D(DuiWidgetZoomOutAnimation); + if (oldState == QAbstractAnimation::Stopped && newState == QAbstractAnimation::Running) { + d->startScale = view()->scale(); + } else if (oldState == QAbstractAnimation::Running && newState == QAbstractAnimation::Stopped) { + view()->hide(); + } +} diff --git a/src/animation/widget/duiwidgetzoomoutanimation.h b/src/animation/widget/duiwidgetzoomoutanimation.h new file mode 100644 index 000000000..526d56d62 --- /dev/null +++ b/src/animation/widget/duiwidgetzoomoutanimation.h @@ -0,0 +1,63 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIWIDGETZOOMOUTANIMATION_H +#define DUIWIDGETZOOMOUTANIMATION_H + +#include +#include + +class DuiWidgetZoomOutAnimationPrivate; + +//! \internal +class DuiWidgetZoomOutAnimation : public DuiAbstractWidgetAnimation +{ + Q_OBJECT + Q_DECLARE_PRIVATE(DuiWidgetZoomOutAnimation) + DUI_WIDGET_ANIMATION(DuiWidgetZoomOutAnimationStyle, DuiWidgetView) + + /*! + \brief Constructs the widget animation. + + This constructor is meant to be used inside the libdui to share the + private data class pointer. + */ + DuiWidgetZoomOutAnimation(DuiWidgetZoomOutAnimationPrivate *dd, QObject *parent); + +public: + + /*! + \brief Constructs the widget animation. + */ + DuiWidgetZoomOutAnimation(QObject *parent = NULL); + + /*! + \brief Destructs the widget animation. + */ + virtual ~DuiWidgetZoomOutAnimation(); + +protected: + //! \reimp + virtual void updateCurrentTime(int currentTime); + virtual void updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState); + //! \reimp_end +}; +//! \internal_end + +#endif diff --git a/src/animation/widget/duiwidgetzoomoutanimation_p.h b/src/animation/widget/duiwidgetzoomoutanimation_p.h new file mode 100644 index 000000000..9c7c47789 --- /dev/null +++ b/src/animation/widget/duiwidgetzoomoutanimation_p.h @@ -0,0 +1,34 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIWIDGETZOOMOUTANIMATION_P_H +#define DUIWIDGETZOOMOUTANIMATION_P_H + +#include "core/duiabstractwidgetanimation_p.h" + +class DuiWidgetZoomOutAnimationPrivate : public DuiAbstractWidgetAnimationPrivate +{ + Q_DECLARE_PUBLIC(DuiWidgetZoomOutAnimation) +public: + virtual ~DuiWidgetZoomOutAnimationPrivate() {} +private: + qreal startScale; +}; + +#endif diff --git a/src/animation/widget/widget.pri b/src/animation/widget/widget.pri new file mode 100644 index 000000000..1d4adbb4d --- /dev/null +++ b/src/animation/widget/widget.pri @@ -0,0 +1,35 @@ +############################################################################### +# DuiAnimation/Widget module +# This module contains widget animation code. +############################################################################### + +include(core/core.pri) + +ANIMATIONS_WIDGET_SRC_DIR=./animation/widget + +#public +HEADERS += \ + $$ANIMATIONS_WIDGET_SRC_DIR/duiwidgetfadeinanimation.h \ + $$ANIMATIONS_WIDGET_SRC_DIR/duiwidgetfadeoutanimation.h \ + $$ANIMATIONS_WIDGET_SRC_DIR/duiwidgetslideinanimation.h \ + $$ANIMATIONS_WIDGET_SRC_DIR/duiwidgetslideoutanimation.h \ + $$ANIMATIONS_WIDGET_SRC_DIR/duiwidgetzoominanimation.h \ + $$ANIMATIONS_WIDGET_SRC_DIR/duiwidgetzoomoutanimation.h \ + +#private +HEADERS += \ + $$ANIMATIONS_WIDGET_SRC_DIR/duiwidgetfadeinanimation_p.h \ + $$ANIMATIONS_WIDGET_SRC_DIR/duiwidgetfadeoutanimation_p.h \ + $$ANIMATIONS_WIDGET_SRC_DIR/duiwidgetslideinanimation_p.h \ + $$ANIMATIONS_WIDGET_SRC_DIR/duiwidgetslideoutanimation_p.h \ + $$ANIMATIONS_WIDGET_SRC_DIR/duiwidgetzoominanimation_p.h \ + $$ANIMATIONS_WIDGET_SRC_DIR/duiwidgetzoomoutanimation_p.h \ + +SOURCES += \ + $$ANIMATIONS_WIDGET_SRC_DIR/duiwidgetfadeinanimation.cpp \ + $$ANIMATIONS_WIDGET_SRC_DIR/duiwidgetfadeoutanimation.cpp \ + $$ANIMATIONS_WIDGET_SRC_DIR/duiwidgetslideinanimation.cpp \ + $$ANIMATIONS_WIDGET_SRC_DIR/duiwidgetslideoutanimation.cpp \ + $$ANIMATIONS_WIDGET_SRC_DIR/duiwidgetzoominanimation.cpp \ + $$ANIMATIONS_WIDGET_SRC_DIR/duiwidgetzoomoutanimation.cpp \ + diff --git a/src/applicationextension/applicationextension.pri b/src/applicationextension/applicationextension.pri new file mode 100644 index 000000000..491a7e7c3 --- /dev/null +++ b/src/applicationextension/applicationextension.pri @@ -0,0 +1,25 @@ +EXTENSION_DIR=./applicationextension +INCLUDEPATH+=./applicationextension \ + $$GEN_DIR + +HEADERS += \ + $$EXTENSION_DIR/duiextensionarea.h \ + $$EXTENSION_DIR/duiextensionarea_p.h \ + $$EXTENSION_DIR/duiextensionareamodel.h \ + $$EXTENSION_DIR/duiextensionareaview.h \ + $$EXTENSION_DIR/duiextensionareaview_p.h \ + $$EXTENSION_DIR/duiapplicationextensionareamodel.h \ + $$EXTENSION_DIR/duiapplicationextensionareaview.h \ + $$EXTENSION_DIR/duiapplicationextensionareaview_p.h \ + $$EXTENSION_DIR/duiapplicationextensionarea.h \ + $$EXTENSION_DIR/duiapplicationextensionarea_p.h + +SOURCES += $$EXTENSION_DIR/duiextensionarea.cpp \ + $$EXTENSION_DIR/duiapplicationextensionarea.cpp \ + $$EXTENSION_DIR/duiapplicationextensionareaview.cpp \ + $$EXTENSION_DIR/duiextensionareaview.cpp \ + $$EXTENSION_DIR/duiextensionareamodel.cpp + +WIDGET_MODEL_HEADERS += $$EXTENSION_DIR/duiextensionareamodel.h \ + $$EXTENSION_DIR/duiapplicationextensionareamodel.h + diff --git a/src/applicationextension/duiapplicationextensionarea.cpp b/src/applicationextension/duiapplicationextensionarea.cpp new file mode 100644 index 000000000..a875a0092 --- /dev/null +++ b/src/applicationextension/duiapplicationextensionarea.cpp @@ -0,0 +1,76 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiapplicationextensionarea.h" +#include "duiapplicationextensionarea_p.h" +#include "duiappletinstancemanager.h" +#include "duidatastore.h" +#include "duiwidgetcreator.h" + +DUI_REGISTER_WIDGET_NO_CREATE(DuiApplicationExtensionArea) + +/////////////////// +// PRIVATE CLASS // +/////////////////// + +DuiApplicationExtensionAreaPrivate::DuiApplicationExtensionAreaPrivate() : instanceManager(NULL) +{ +} + +DuiApplicationExtensionAreaPrivate::~DuiApplicationExtensionAreaPrivate() +{ + delete instanceManager; +} + +void DuiApplicationExtensionAreaPrivate::init(const QString &interface) +{ + Q_Q(DuiApplicationExtensionArea); + + instanceManager = new DuiAppletInstanceManager(interface); + + // Connect applet instance manager signals and restore applet instances + q->connect(instanceManager, SIGNAL(appletInstantiated(DuiWidget *, DuiDataStore &)), SLOT(addWidget(DuiWidget *, DuiDataStore &))); + instanceManager->restoreApplets(); +} + +////////////////// +// PUBLIC CLASS // +////////////////// +DuiApplicationExtensionArea::DuiApplicationExtensionArea(const QString &interface, QGraphicsItem *parent) : + DuiExtensionArea(new DuiApplicationExtensionAreaPrivate, new DuiApplicationExtensionAreaModel, parent) +{ + // Initialize the private implementation + Q_D(DuiApplicationExtensionArea); + d->q_ptr = this; + d->init(interface); +} + +DuiApplicationExtensionArea::DuiApplicationExtensionArea(DuiApplicationExtensionAreaPrivate *dd, DuiApplicationExtensionAreaModel *model, + QGraphicsItem *parent, const QString &interface) : + DuiExtensionArea(dd, model, parent) +{ + Q_D(DuiApplicationExtensionArea); + + // Initialize the private implementation + d->init(interface); +} + +DuiApplicationExtensionArea::~DuiApplicationExtensionArea() +{ +} diff --git a/src/applicationextension/duiapplicationextensionarea.h b/src/applicationextension/duiapplicationextensionarea.h new file mode 100644 index 000000000..0e676e709 --- /dev/null +++ b/src/applicationextension/duiapplicationextensionarea.h @@ -0,0 +1,71 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLICATIONEXTENSIONAREA_H +#define DUIAPPLICATIONEXTENSIONAREA_H + +#include "duiextensionarea.h" +#include "duiapplicationextensionareamodel.h" + +class DuiApplicationExtensionAreaPrivate; + +/*! + * DuiApplicationExtensionArea is a widget which can be populated with application extensions. DuiApplicationExtensionArea + * can be placed on any view that wants to have application extension support. + * + * The DuiApplicationExtensionArea will load application extensions which implement the specified interface. + * + * \note The behaviour of this class will change in the future and cannot be used for real + * application extension development right now. + * + * \see \ref applicationextensions + */ +class DUI_EXPORT DuiApplicationExtensionArea : public DuiExtensionArea +{ + Q_OBJECT + DUI_CONTROLLER(DuiApplicationExtensionArea) + +public: + /*! + * Constructor + * \param interface Specifies which interface the application extensions must implement in order to be loaded to + * this application extension area. + * \param parent Optional Object's parent + */ + explicit DuiApplicationExtensionArea(const QString &interface, QGraphicsItem *parent = NULL); + + /*! + * Destructor + */ + virtual ~DuiApplicationExtensionArea(); + +protected: + /*! + * Protected constructor to be called by derived classes to set up the private implementation + * hierarchy. + */ + DuiApplicationExtensionArea(DuiApplicationExtensionAreaPrivate *dd, DuiApplicationExtensionAreaModel *model, + QGraphicsItem *parent, const QString &interface); + +private: + Q_DECLARE_PRIVATE(DuiApplicationExtensionArea) + Q_DISABLE_COPY(DuiApplicationExtensionArea) +}; + +#endif // DUIAPPLICATIONEXTENSIONAREA_H diff --git a/src/applicationextension/duiapplicationextensionarea_p.h b/src/applicationextension/duiapplicationextensionarea_p.h new file mode 100644 index 000000000..6f9ee3f41 --- /dev/null +++ b/src/applicationextension/duiapplicationextensionarea_p.h @@ -0,0 +1,58 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLICATIONEXTENSIONAREA_P_H +#define DUIAPPLICATIONEXTENSIONAREA_P_H + +#include "duiextensionarea_p.h" +#include "duiapplicationextensionarea.h" + +class DuiAppletInstanceManager; + +/*! + * Private class for DuiApplicationExtensionArea. + */ +class DuiApplicationExtensionAreaPrivate : public DuiExtensionAreaPrivate +{ + Q_DECLARE_PUBLIC(DuiApplicationExtensionArea) + +public: + /*! + * Constructor. + */ + DuiApplicationExtensionAreaPrivate(); + + /*! + * Destructor. + */ + virtual ~DuiApplicationExtensionAreaPrivate(); + + /*! + * Initializes this class. This method should be called before this class + * is used for anything else. + * + * \param interface the extension interface name for the application extension area. + */ + void init(const QString &interface); + + //! Applet instance manager + DuiAppletInstanceManager *instanceManager; +}; + +#endif // DUIAPPLICATIONEXTENSIONAREA_P_H diff --git a/src/applicationextension/duiapplicationextensionareamodel.h b/src/applicationextension/duiapplicationextensionareamodel.h new file mode 100644 index 000000000..a8f36a472 --- /dev/null +++ b/src/applicationextension/duiapplicationextensionareamodel.h @@ -0,0 +1,35 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLICATIONEXTENSIONAREAMODEL_H_ +#define DUIAPPLICATIONEXTENSIONAREAMODEL_H_ + +#include +#include "duiextensionareamodel.h" + +/*! + * DuiApplicationExtensionAreaModel is the model class for DuiApplicationExtensionArea. + */ +class DUI_EXPORT DuiApplicationExtensionAreaModel : public DuiExtensionAreaModel +{ + Q_OBJECT + DUI_MODEL_INTERNAL(DuiApplicationExtensionAreaModel) +}; + +#endif /* DUIAPPLICATIONEXTENSIONAREAMODEL_H_ */ diff --git a/src/applicationextension/duiapplicationextensionareaview.cpp b/src/applicationextension/duiapplicationextensionareaview.cpp new file mode 100644 index 000000000..34c8e2044 --- /dev/null +++ b/src/applicationextension/duiapplicationextensionareaview.cpp @@ -0,0 +1,74 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiviewcreator.h" +#include +#include "duiextensionareaview.h" +#include "duiapplicationextensionareaview.h" +#include "duiapplicationextensionareaview_p.h" +#include "duiapplicationextensionarea.h" + + +DuiApplicationExtensionAreaViewPrivate::DuiApplicationExtensionAreaViewPrivate() +{ +} + +DuiApplicationExtensionAreaViewPrivate::~DuiApplicationExtensionAreaViewPrivate() +{ +} + +void DuiApplicationExtensionAreaViewPrivate::init(DuiApplicationExtensionArea *controller) +{ + this->controller = controller; + + layout = new QGraphicsLinearLayout(Qt::Vertical); + controller->setLayout(layout); +} + +void DuiApplicationExtensionAreaViewPrivate::addToLayout(DuiWidget *widget, int index) +{ + QGraphicsLinearLayout *linearLayout = static_cast(layout); + if (index >= 0) { + linearLayout->insertItem(index, widget); + } else { + linearLayout->addItem(widget); + } + +} + +DuiApplicationExtensionAreaView::DuiApplicationExtensionAreaView(DuiApplicationExtensionArea *controller) : + DuiExtensionAreaView(* new DuiApplicationExtensionAreaViewPrivate, controller) +{ + Q_D(DuiApplicationExtensionAreaView); + d->q_ptr = this; + d->init(controller); +} + +DuiApplicationExtensionAreaView::DuiApplicationExtensionAreaView(DuiApplicationExtensionAreaViewPrivate &dd, DuiApplicationExtensionArea *controller) : + DuiExtensionAreaView(dd, controller) +{ + Q_D(DuiApplicationExtensionAreaView); + d->init(controller); +} + +DuiApplicationExtensionAreaView::~DuiApplicationExtensionAreaView() +{ +} + +DUI_REGISTER_VIEW_NEW(DuiApplicationExtensionAreaView, DuiApplicationExtensionArea) diff --git a/src/applicationextension/duiapplicationextensionareaview.h b/src/applicationextension/duiapplicationextensionareaview.h new file mode 100644 index 000000000..a9abb0aec --- /dev/null +++ b/src/applicationextension/duiapplicationextensionareaview.h @@ -0,0 +1,66 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLICATIONEXTENSIONAREAVIEW_H_ +#define DUIAPPLICATIONEXTENSIONAREAVIEW_H_ + +#include "duiextensionareaview.h" +#include "duiapplicationextensionareamodel.h" +#include "duiapplicationextensionareastyle.h" + +class DuiApplicationExtensionAreaViewPrivate; +class DuiApplicationExtensionArea; +class DuiContainer; + +/*! + * A view class for the DuiApplicationExtensionArea. + */ +class DUI_EXPORT DuiApplicationExtensionAreaView : public DuiExtensionAreaView +{ + Q_OBJECT + DUI_VIEW(DuiApplicationExtensionAreaModel, DuiApplicationExtensionAreaStyle) + +public: + /*! + * Constructs a new view for DuiApplicationExtensionArea. + * + * \param controller the DuiApplicationExtensionArea controller for the view. + */ + DuiApplicationExtensionAreaView(DuiApplicationExtensionArea *controller); + + /*! + * Destroys the DuiApplicationExtensionAreaView. + */ + virtual ~DuiApplicationExtensionAreaView(); + +protected: + /*! + * Constructs a new view for DuiApplicationExtensionArea. + * + * \param dd the DuiApplicationExtensionAreaViewPrivate private class instance to be used. + * \param controller the DuiApplicationExtensionArea controller for the view. + */ + DuiApplicationExtensionAreaView(DuiApplicationExtensionAreaViewPrivate &dd, DuiApplicationExtensionArea *controller); + +private: + Q_DISABLE_COPY(DuiApplicationExtensionAreaView) + Q_DECLARE_PRIVATE(DuiApplicationExtensionAreaView) +}; + +#endif /* DUIAPPLICATIONEXTENSIONAREAVIEW_H_ */ diff --git a/src/applicationextension/duiapplicationextensionareaview_p.h b/src/applicationextension/duiapplicationextensionareaview_p.h new file mode 100644 index 000000000..f5b8e8896 --- /dev/null +++ b/src/applicationextension/duiapplicationextensionareaview_p.h @@ -0,0 +1,68 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLICATIONEXTENSIONAREAVIEW_P_H_ +#define DUIAPPLICATIONEXTENSIONAREAVIEW_P_H_ + +#include "applicationextension/duiextensionareaview_p.h" + +class DuiLayout; +class DuiLinearLayoutPolicy; +class QGraphicsLinearLayout; +class DuiButton; +class DuiApplicationExtensionArea; +class DuiWidget; + +/*! + * DuiApplicationExtensionAreaViewPrivate is the private class for DuiApplicationExtensionAreaView. + */ +class DuiApplicationExtensionAreaViewPrivate : public DuiExtensionAreaViewPrivate +{ + Q_DECLARE_PUBLIC(DuiApplicationExtensionAreaView) + +public: + /*! + * Constructs a DuiApplicationExtensionAreaViewPrivate private class for + * DuiApplicationExtensionAreaView. + */ + DuiApplicationExtensionAreaViewPrivate(); + + /*! + * Destroys the DuiApplicationExtensionAreaViewPrivate. + */ + virtual ~DuiApplicationExtensionAreaViewPrivate(); + + /*! + * Initializes this class. This method should be called before this class + * is used for anything else. + */ + void init(DuiApplicationExtensionArea *controller); + + //! The DuiApplicationExtensionArea controller. + DuiApplicationExtensionArea *controller; + + /*! + * Adds a widget to the layout + * \param widget the widget + * \param index the index to insert or -1 to add to the end + */ + virtual void addToLayout(DuiWidget *widget, int index = -1); +}; + +#endif /* DUIAPPLICATIONEXTENSIONAREAVIEW_P_H_ */ diff --git a/src/applicationextension/duiextensionarea.cpp b/src/applicationextension/duiextensionarea.cpp new file mode 100644 index 000000000..35e5949a1 --- /dev/null +++ b/src/applicationextension/duiextensionarea.cpp @@ -0,0 +1,102 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiextensionarea.h" +#include "duiextensionarea_p.h" +#include "duidatastore.h" +#include "duidebug.h" + + +DuiExtensionAreaPrivate::DuiExtensionAreaPrivate() +{ +} + +DuiExtensionAreaPrivate::~DuiExtensionAreaPrivate() +{ +} + +void DuiExtensionAreaPrivate::addWidget(DuiWidget *widget, DuiDataStore &store) +{ + Q_Q(DuiExtensionArea); + + if (!dataStores.contains(widget)) { + // Add data store to data stores map + dataStores[widget] = &store; + + // Let the view know about the data store modification + q->model()->dataStoresModified(); + } else { + // Widget is already added to the mashup canvas. Bail out. + duiWarning("DuiExtensionArea") << "DuiExtensionArea::addWidget() - Widget was already added to extension area."; + } +} + +void DuiExtensionAreaPrivate::removeWidget(DuiWidget *widget) +{ + Q_Q(DuiExtensionArea); + + if (dataStores.contains(widget)) { + // Remove data store from the data stores map + dataStores.remove(widget); + q->model()->dataStoresModified(); + } +} + +void DuiExtensionAreaPrivate::init() +{ + Q_Q(DuiExtensionArea); + + // Put the data stores into the model + q->model()->setDataStores(&dataStores); +} + +DuiExtensionArea::DuiExtensionArea(DuiWidgetControllerPrivate *dd, DuiWidgetModel *model, QGraphicsItem *parent) + : DuiWidgetController(dd, model, parent) +{ + // Initialize the private implementation + Q_D(DuiExtensionArea); + d->init(); +} + +DuiExtensionArea::DuiExtensionArea(QGraphicsItem *parent) : + DuiWidgetController(new DuiExtensionAreaPrivate, new DuiExtensionAreaModel, parent) +{ + // Initialize the private implementation + Q_D(DuiExtensionArea); + d->q_ptr = this; + d->init(); +} + +DuiExtensionArea::~DuiExtensionArea() +{ +} + +void DuiExtensionArea::addWidget(DuiWidget *widget, DuiDataStore &store) +{ + Q_D(DuiExtensionArea); + + d->addWidget(widget, store); +} + +void DuiExtensionArea::removeWidget(DuiWidget *widget) +{ + Q_D(DuiExtensionArea); + + d->removeWidget(widget); +} diff --git a/src/applicationextension/duiextensionarea.h b/src/applicationextension/duiextensionarea.h new file mode 100644 index 000000000..b8198a094 --- /dev/null +++ b/src/applicationextension/duiextensionarea.h @@ -0,0 +1,83 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIEXTENSIONAREA_H +#define DUIEXTENSIONAREA_H + +#include +#include "duiextensionareamodel.h" + +class DuiDataStore; +class DuiExtensionAreaPrivate; + +/*! + * DuiExtensionArea is a baseclass for widgets that can load application extensions + */ +class DUI_EXPORT DuiExtensionArea : public DuiWidgetController +{ + Q_OBJECT + DUI_CONTROLLER(DuiExtensionArea) + +public: + /*! + * Default constructor + * \param parent Optional Object's parent + */ + explicit DuiExtensionArea(QGraphicsItem *parent = NULL); + + /*! + * Default destructor + */ + virtual ~DuiExtensionArea(); + +protected: + /*! + * Protected constructor to be called by derived classes to set up the private implementation + * hierarchy. + */ + DuiExtensionArea(DuiWidgetControllerPrivate *dd, DuiWidgetModel *model, QGraphicsItem *parent); + +protected Q_SLOTS: + /*! + * addWidget performs setup of an extension widget and it's datastore when the widget is being added to + * the extension area. The ownership of the widget remains on the caller of this slot. + * This slot can be overridden in specialised extension areas to provide additional setup. + * \param widget Widget to be added onto the DuiExtensionArea. + * \param store This DuiDataStore object can be used to store permanent extension area data related + * to this particular application extension instance. When the same application extension instance is + * reinstantiated, this API will be called with the data that was stored to the permanent storage the + * last time around. This can be used to store for instance layout data of an application extension instance + * or any other extension area specific data. + */ + virtual void addWidget(DuiWidget *widget, DuiDataStore &store); + + /*! + * removeWidget performs cleanup related to a widget that is being removed. + * The widget itself should not be deleted in this method, it will be deleted by the caller. + * + * \param widget The widget to be removed from the system. + */ + virtual void removeWidget(DuiWidget *widget); + +private: + Q_DECLARE_PRIVATE(DuiExtensionArea) + Q_DISABLE_COPY(DuiExtensionArea) +}; + +#endif // DUIEXTENSIONAREA_H diff --git a/src/applicationextension/duiextensionarea_p.h b/src/applicationextension/duiextensionarea_p.h new file mode 100644 index 000000000..0e83ed392 --- /dev/null +++ b/src/applicationextension/duiextensionarea_p.h @@ -0,0 +1,68 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIEXTENSIONAREA_P_H +#define DUIEXTENSIONAREA_P_H + +#include "private/duiwidgetcontroller_p.h" +#include "duiextensionarea.h" + +class DuiDataStore; + +/*! + * Private class for DuiExtensionArea. + */ +class DuiExtensionAreaPrivate : public DuiWidgetControllerPrivate +{ + Q_DECLARE_PUBLIC(DuiExtensionArea) + +public: + /*! + * Constructor. + */ + DuiExtensionAreaPrivate(); + + /*! + * Destructor. + */ + virtual ~DuiExtensionAreaPrivate(); + + /*! + * Adds a widget to the canvas. + * \see DuiExtensionArea::addWidget() + */ + virtual void addWidget(DuiWidget *widget, DuiDataStore &store); + + /*! + * Removes a widget from the canvas. + * \see DuiExtensionArea::removeWidget() + */ + virtual void removeWidget(DuiWidget *widget); + + //! Map to maintain DuiDataStore objects of associated widgets in. + QMap dataStores; + + /*! + * Initializes this class. This method should be called before this class + * is used for anything else. + */ + void init(); +}; + +#endif // DUIEXTENSIONAREA_P_H diff --git a/src/applicationextension/duiextensionareamodel.cpp b/src/applicationextension/duiextensionareamodel.cpp new file mode 100644 index 000000000..38e79381b --- /dev/null +++ b/src/applicationextension/duiextensionareamodel.cpp @@ -0,0 +1,26 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiextensionareamodel.h" +#include "gen_duiextensionareamodeldata.h" + +void DuiExtensionAreaModel::dataStoresModified() +{ + memberModified(DataStores); +} diff --git a/src/applicationextension/duiextensionareamodel.h b/src/applicationextension/duiextensionareamodel.h new file mode 100644 index 000000000..4af20ca35 --- /dev/null +++ b/src/applicationextension/duiextensionareamodel.h @@ -0,0 +1,49 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIEXTENSIONAREAMODEL_H_ +#define DUIEXTENSIONAREAMODEL_H_ + +#include + +class DuiDataStore; + +typedef QMap DataStoreMap; + +/*! + * DuiExtensionAreaModel is the model class for DuiExtensionArea. + */ +class DUI_EXPORT DuiExtensionAreaModel : public DuiWidgetModel +{ + Q_OBJECT + DUI_MODEL_INTERNAL(DuiExtensionAreaModel) + +public: + //! A map of widgets and the associated datastores + DUI_MODEL_PTR_PROPERTY(DataStoreMap *, dataStores, DataStores, true, NULL) + +public: + /*! + * Emits the memberModified() signal for dataStores. Can be used + * when the data pointed to by dataStores has changed. + */ + void dataStoresModified(); +}; + +#endif /* DUIEXTENSIONAREAMODEL_H_ */ diff --git a/src/applicationextension/duiextensionareaview.cpp b/src/applicationextension/duiextensionareaview.cpp new file mode 100644 index 000000000..470dc6ae9 --- /dev/null +++ b/src/applicationextension/duiextensionareaview.cpp @@ -0,0 +1,257 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include "duiextensionareaview.h" +#include "duiextensionareaview_p.h" +#include "duiextensionarea.h" +#include "duidatastore.h" +#include "duicontainer.h" + +DuiExtensionAreaViewPrivate::DuiExtensionAreaViewPrivate() +{ +} + +DuiExtensionAreaViewPrivate::~DuiExtensionAreaViewPrivate() +{ +} + +void DuiExtensionAreaViewPrivate::setContainerEnabled(DuiContainer *container, bool enabled) +{ + container->setHeaderVisible(enabled); + if (enabled) { + container->setObjectName(""); + } else { + container->setObjectName("DuiExtensionAreaInvisibleContainer"); + } +} + +DuiContainer *DuiExtensionAreaViewPrivate::createWidgetContainer(DuiWidget *widget) const +{ + DuiContainer *container = new DuiContainer(controller); + container->setCentralWidget(widget); + connectContainerToWidget(container, widget); + return container; +} + +void DuiExtensionAreaViewPrivate::setupContainers(bool enabled) +{ + // Iterate through the items in the layout and add container widgets + const int count = layout->count(); + for (int i = 0; i < count; ++i) { + DuiContainer *container = dynamic_cast(layout->itemAt(i)); + setContainerEnabled(container, enabled); + } +} + +void DuiExtensionAreaViewPrivate::connectContainerToWidget(DuiContainer *container, DuiWidget *widget) const +{ + const QMetaObject *mob = widget->metaObject(); + + // use widget properties to fill header of the container + int iconProperty = mob->indexOfProperty("appletIcon"); + int titleProperty = mob->indexOfProperty("appletTitle"); + int textProperty = mob->indexOfProperty("appletText"); + + if (iconProperty != -1) { + container->setIconID((mob->property(iconProperty).read(widget)).toString()); + } + + if (titleProperty != -1) { + container->setTitle((mob->property(titleProperty).read(widget)).toString()); + container->setHeaderVisible(true); + } + + if (textProperty != -1) { + container->setText((mob->property(textProperty).read(widget)).toString()); + } + + // connect signals from widget to the container + if (mob->indexOfSignal("appletIconChanged(QString)") != -1) { + QObject::connect(widget, SIGNAL(appletIconChanged(QString)), container, SLOT(setIconID(QString))); + } + + if (mob->indexOfSignal("appletTitleChanged(QString)") != -1) { + QObject::connect(widget, SIGNAL(appletTitleChanged(QString)), container, SLOT(setTitle(QString))); + } + + if (mob->indexOfSignal("appletTextChanged(QString)") != -1) { + QObject::connect(widget, SIGNAL(appletTextChanged(QString)), container, SLOT(setText(QString))); + } + + // connect deprecated signals from widget to the container + // TODO remove these after deprecation + if (mob->indexOfSignal("setAppletIcon(QString)") != -1) { + QObject::connect(widget, SIGNAL(setAppletIcon(QString)), container, SLOT(setIconID(QString))); + } + if (mob->indexOfSignal("setAppletTitle(QString)") != -1) { + QObject::connect(widget, SIGNAL(setAppletTitle(QString)), container, SLOT(setTitle(QString))); + } + if (mob->indexOfSignal("setAppletText(QString)") != -1) { + QObject::connect(widget, SIGNAL(setAppletText(QString)), container, SLOT(setText(QString))); + } + + // Copying actions from the widget to the container. + container->addActions(widget->actions()); +} + +void DuiExtensionAreaViewPrivate::updateData() +{ + Q_Q(DuiExtensionAreaView); + + DataStoreMap *dsMap = q->model()->dataStores(); + if (dsMap != NULL) { + // Iterate through the items in the layout and write their new geometries to data store. + const int count = layout->count(); + for (int i = 0; i < count; ++i) { + QGraphicsLayoutItem *layoutItem = layout->itemAt(i); + DuiContainer *container = dynamic_cast(layoutItem); + DuiWidget *centralWidget = container->centralWidget(); + + // Change the data in the store if item is still valid and geometry has changed. + if (centralWidget != NULL && dsMap->contains(centralWidget) && + (*dsMap)[centralWidget]->value("layoutIndex") != i) { + (*dsMap)[centralWidget]->createValue("layoutIndex", i); + } + } + } +} + +void DuiExtensionAreaViewPrivate::updateLayout() +{ + Q_Q(DuiExtensionAreaView); + + DataStoreMap *dsMap = q->model()->dataStores(); + if (dsMap != NULL) { + // Iterate through the items in the layout and remove items + // that don't exist in the data store + for (int i = layout->count() - 1; i >= 0; --i) { + DuiContainer *container = dynamic_cast(layout->itemAt(i)); + DuiWidget *centralWidget = container->centralWidget(); + + if (container != NULL && !dsMap->contains(centralWidget)) { + // Remove widget from layout + layout->removeAt(i); + centralWidget->setParentItem(controller); + // Delete the container of the widget, + // we need to delete it here as this view owns it + delete container; + } + } + + // Iterate through the items in the data store and add items that don't exist in the layout + foreach(DuiWidget * widget, dsMap->keys()) { + bool alreadyInLayout = false; + const int count = layout->count(); + for (int i = 0; i < count; ++i) { + DuiContainer *theContainer = dynamic_cast(layout->itemAt(i)); + if (widget == theContainer->centralWidget()) { + // Widget found from the layout, don't add again + alreadyInLayout = true; + break; + } + } + + if (!alreadyInLayout) { + // Widget not found in the layout so add it + DuiDataStore *store = dsMap->value(widget); + + // Create a container for the widget if container mode is enabled for the canvas + DuiContainer *container = createWidgetContainer(widget); + setContainerEnabled(container, q->style()->containerMode()); + + int layoutIndex = 0; + + // Add widget to the layout policy + if (store->allKeys().contains("layoutIndex") && + store->value("layoutIndex").type() == QVariant::Int) { + layoutIndex = store->value("layoutIndex").toInt(); + addToLayout(container, layoutIndex); + } else { + layoutIndex = layout->count(); + addToLayout(container); + } + + // Write the layout data to the permanent store + store->createValue("layoutIndex", layoutIndex); + } + } + } +} + +void DuiExtensionAreaViewPrivate::addToLayout(DuiWidget *, int) +{ +} + +DuiExtensionAreaView::DuiExtensionAreaView(DuiExtensionArea *controller) : + DuiWidgetView(* new DuiExtensionAreaViewPrivate, controller) +{ +} + +DuiExtensionAreaView::DuiExtensionAreaView(DuiExtensionAreaViewPrivate &dd, DuiExtensionArea *controller) : + DuiWidgetView(dd, controller) +{ +} + +DuiExtensionAreaView::~DuiExtensionAreaView() +{ +} + +void DuiExtensionAreaView::setupModel() +{ + Q_D(DuiExtensionAreaView); + + DuiWidgetView::setupModel(); + + d->updateLayout(); +} + +void DuiExtensionAreaView::applyStyle() +{ + Q_D(DuiExtensionAreaView); + d->setupContainers(style()->containerMode()); +} + +void DuiExtensionAreaView::setGeometry(const QRectF &rect) +{ + Q_D(DuiExtensionAreaView); + + // Set new geometry to the widget and to the layout + DuiWidgetView::setGeometry(rect); + + // Geometry change might have affected the geometry of widgets. Update all widgets data stores. + d->updateData(); +} + +void DuiExtensionAreaView::updateData(const QList& modifications) +{ + Q_D(DuiExtensionAreaView); + + bool layoutUpdateNeeded = false; + DuiWidgetView::updateData(modifications); + foreach(const char * member, modifications) { + if (member == DuiExtensionAreaModel::DataStores) { + layoutUpdateNeeded = true; + } + } + + if (layoutUpdateNeeded) { + d->updateLayout(); + } +} diff --git a/src/applicationextension/duiextensionareaview.h b/src/applicationextension/duiextensionareaview.h new file mode 100644 index 000000000..dca739b33 --- /dev/null +++ b/src/applicationextension/duiextensionareaview.h @@ -0,0 +1,72 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIEXTENSIONAREAVIEW_H_ +#define DUIEXTENSIONAREAVIEW_H_ + +#include +#include "duiextensionareamodel.h" +#include "duiextensionareastyle.h" + +class DuiExtensionAreaViewPrivate; +class DuiExtensionArea; + +/*! + * A view class for the DuiExtensionArea. + */ +class DUI_EXPORT DuiExtensionAreaView : public DuiWidgetView +{ + Q_OBJECT + DUI_VIEW(DuiExtensionAreaModel, DuiExtensionAreaStyle) + +public: + /*! + * Constructs a new view for DuiExtensionArea. + * + * \param controller the DuiExtensionArea controller for the view. + */ + DuiExtensionAreaView(DuiExtensionArea *controller); + + /*! + * Destroys the DuiExtensionAreaView. + */ + virtual ~DuiExtensionAreaView(); + +protected: + //! \reimp + virtual void setGeometry(const QRectF &rect); + virtual void setupModel(); + virtual void applyStyle(); + virtual void updateData(const QList& modifications); + //! \reimp_end + + /*! + * Constructs a new view for DuiExtensionArea. + * + * \param dd the DuiExtensionAreaViewPrivate private class instance to be used. + * \param controller the DuiExtensionArea controller for the view. + */ + DuiExtensionAreaView(DuiExtensionAreaViewPrivate &dd, DuiExtensionArea *controller); + +private: + Q_DISABLE_COPY(DuiExtensionAreaView) + Q_DECLARE_PRIVATE(DuiExtensionAreaView) +}; + +#endif /* DUIEXTENSIONAREAVIEW_H_ */ diff --git a/src/applicationextension/duiextensionareaview_p.h b/src/applicationextension/duiextensionareaview_p.h new file mode 100644 index 000000000..11891a761 --- /dev/null +++ b/src/applicationextension/duiextensionareaview_p.h @@ -0,0 +1,102 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIEXTENSIONAREAVIEW_P_H_ +#define DUIEXTENSIONAREAVIEW_P_H_ + +#include "private/duiwidgetview_p.h" +#include "applicationextension/duiextensionareaview.h" + +class DuiContainer; + +/*! + * DuiExtensionAreaViewPrivate is the private class for DuiExtensionAreaView. + */ +class DuiExtensionAreaViewPrivate : public DuiWidgetViewPrivate +{ + Q_DECLARE_PUBLIC(DuiExtensionAreaView) + +public: + /*! + * Constructs a DuiExtensionAreaViewPrivate private class for + * DuiExtensionAreaView. + */ + DuiExtensionAreaViewPrivate(); + + /*! + * Destroys the DuiExtensionAreaViewPrivate. + */ + virtual ~DuiExtensionAreaViewPrivate(); + + /*! + * Updates the geometry of each widget present in the layout into the data + * store. + */ + void updateData(); + + /*! + * Removes those widgets from the layout that are not present in the data + * store and adds those widgets to the layout which are present in the data + * store but not yet in the layout. + */ + void updateLayout(); + + /*! + * Creates a new container and inserts the given \p widget into the container. + * Sets up the container for the \p widget. + * \return Created container. + * \param widget Widget to be inserted into the container. + */ + DuiContainer *createWidgetContainer(DuiWidget *widget) const; + + /*! + * Sets up containers in this mashup canvas view. If the \p enabled is \c true the + * containers are made visible for all widgets in this mashup view. + * If the \p enabled is \c false all containers hidden in this mashup canvas + * + * \param enabled Whether containers are enabled or not. + */ + void setupContainers(bool enabled); + + /*! + * Toggles if the given container is visible or not. If the \p enabled is \c true the + * containers are set to visible, otherwise they are hidden. + * + * \param container The container whos visibility to modify + * \param enabled Whether containers are enabled or not. + */ + void setContainerEnabled(DuiContainer *container, bool enabled); + + /*! + * Used to check properties of widget and connect signals between it and the DuiContainer + */ + void connectContainerToWidget(DuiContainer *container, DuiWidget *widget) const; + + /*! + * Adds a widget to the layout + * \param widget the widget + * \param index the index to insert or -1 to add to the end + */ + virtual void addToLayout(DuiWidget *widget, int index = -1); + + //! Layout used to layout the widget instances on this extension area. + QGraphicsLayout *layout; +}; + +#endif /* DUIEXTENSIONAREAVIEW_P_H_ */ diff --git a/src/core/DuiApplicationAdaptor.xml b/src/core/DuiApplicationAdaptor.xml new file mode 100644 index 000000000..391fdae45 --- /dev/null +++ b/src/core/DuiApplicationAdaptor.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/src/core/TestabilityInterface b/src/core/TestabilityInterface new file mode 100644 index 000000000..5afdb4544 --- /dev/null +++ b/src/core/TestabilityInterface @@ -0,0 +1,2 @@ +#include "testabilityinterface.h" + diff --git a/src/core/core.pri b/src/core/core.pri new file mode 100644 index 000000000..023aacc7e --- /dev/null +++ b/src/core/core.pri @@ -0,0 +1,71 @@ +############################################################################### +# DuiCore module +# This module contains all classes that represent the most basic foundation +# of an application and have little to no relationship to the view classes. +############################################################################### +CORE_SRC_DIR=./core +INCLUDEPATH+=./core +HEADERS += \ + $$CORE_SRC_DIR/duiapplication.h \ + $$CORE_SRC_DIR/duiaction.h \ + $$CORE_SRC_DIR/duiassembly.h \ + $$CORE_SRC_DIR/duiassembly_p.h \ + $$CORE_SRC_DIR/duicomponentdata.h \ + $$CORE_SRC_DIR/duilibrary.h \ + $$CORE_SRC_DIR/duiwidgetaction.h \ + $$CORE_SRC_DIR/duidesktopentry.h \ + $$CORE_SRC_DIR/duidesktopentry_p.h \ + $$CORE_SRC_DIR/duinamespace.h \ + $$CORE_SRC_DIR/duirmiclient.h \ + $$CORE_SRC_DIR/duirmiserver.h \ + $$CORE_SRC_DIR/duiexport.h \ + $$CORE_SRC_DIR/duiclassfactory.h \ + $$CORE_SRC_DIR/duicpumonitor.h \ + $$CORE_SRC_DIR/duishareddata.h \ + $$CORE_SRC_DIR/duigconfitem.h \ + $$CORE_SRC_DIR/duitimestamp.h \ + $$CORE_SRC_DIR/duiinputmethodstate.h \ + $$CORE_SRC_DIR/duiinputmethodstate_p.h \ + $$CORE_SRC_DIR/duidebug.h \ + +contains(DEFINES, HAVE_DBUS) { + HEADERS += \ + $$CORE_SRC_DIR/duiapplicationservice.h \ + $$CORE_SRC_DIR/duiapplicationservice_p.h \ + $$CORE_SRC_DIR/duiapplicationifadaptor.h \ + $$CORE_SRC_DIR/duiapplicationifproxy.h \ + $$CORE_SRC_DIR/duiremoteaction.h \ + $$CORE_SRC_DIR/duidbusservicewaiter_p.h \ +} + +SOURCES += \ + $$CORE_SRC_DIR/duiapplication.cpp \ + $$CORE_SRC_DIR/duiaction.cpp \ + $$CORE_SRC_DIR/duiassembly.cpp \ + $$CORE_SRC_DIR/duicomponentdata.cpp \ + $$CORE_SRC_DIR/duilibrary.cpp \ + $$CORE_SRC_DIR/duiwidgetaction.cpp \ + $$CORE_SRC_DIR/duidesktopentry.cpp \ + $$CORE_SRC_DIR/duirmiclient.cpp \ + $$CORE_SRC_DIR/duirmiserver.cpp \ + $$CORE_SRC_DIR/duiclassfactory.cpp \ + $$CORE_SRC_DIR/duicpumonitor.cpp \ + $$CORE_SRC_DIR/duishareddata.cpp \ + $$CORE_SRC_DIR/duitimestamp.cpp \ + $$CORE_SRC_DIR/duiinputmethodstate.cpp \ + +contains(DEFINES, HAVE_DBUS) { + SOURCES += \ + $$CORE_SRC_DIR/duiapplicationservice.cpp \ + $$CORE_SRC_DIR/duiapplicationservice_p.cpp \ + $$CORE_SRC_DIR/duiapplicationifadaptor.cpp \ + $$CORE_SRC_DIR/duiapplicationifproxy.cpp \ + $$CORE_SRC_DIR/duiremoteaction.cpp \ + $$CORE_SRC_DIR/duidbusservicewaiter.cpp \ +} + +contains(DEFINES, HAVE_GCONF) { + SOURCES += $$CORE_SRC_DIR/duigconfitem.cpp +} else { + SOURCES += $$CORE_SRC_DIR/duigconfitem_stub.cpp +} diff --git a/src/core/duiaction.cpp b/src/core/duiaction.cpp new file mode 100644 index 000000000..a2deb479b --- /dev/null +++ b/src/core/duiaction.cpp @@ -0,0 +1,138 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiaction.h" +#include "duiaction_p.h" + +#include +#include +#include +#include + +DuiActionPrivate::DuiActionPrivate() + : location(DuiAction::EveryLocation), styleAction(false) +{ +} + +DuiActionPrivate::~DuiActionPrivate() +{ +} + +void DuiActionPrivate::sendDataChanged() +{ + Q_Q(DuiAction); + QActionEvent e(QEvent::ActionChanged, q); + + QList gWidgets = q->associatedGraphicsWidgets(); + + const int size = gWidgets.size(); + for (int i = 0; i < size; ++i) { + QGraphicsWidget *w = gWidgets.at(i); + QApplication::sendEvent(w, &e); + } + + QApplication::sendEvent(q, &e); + + emit q->changed(); +} + +DuiAction::DuiAction(QObject *parent) + : QAction(parent), + d_ptr(new DuiActionPrivate) +{ + Q_D(DuiAction); + d->q_ptr = this; +} + +DuiAction::DuiAction(DuiActionPrivate &dd, QObject *parent) + : QAction(parent), + d_ptr(& dd) +{ + Q_D(DuiAction); + d->q_ptr = this; +} + +DuiAction::DuiAction(const QString &text, QObject *parent) + : QAction(text, parent), + d_ptr(new DuiActionPrivate) +{ + Q_D(DuiAction); + d->q_ptr = this; +} + +DuiAction::DuiAction(const QString &iconID, const QString &text, QObject *parent) + : QAction(text, parent), + d_ptr(new DuiActionPrivate) +{ + Q_D(DuiAction); + d->iconID = iconID; + d->q_ptr = this; +} + +DuiAction::~DuiAction() +{ + delete d_ptr; +} + +QString DuiAction::iconID() const +{ + Q_D(const DuiAction); + return d->iconID; +} + +void DuiAction::setIconID(const QString &iconID) +{ + Q_D(DuiAction); + if (d->iconID == iconID) + return; + + d->iconID = iconID; + d->sendDataChanged(); +} + +DuiAction::Locations DuiAction::location() const +{ + Q_D(const DuiAction); + return d->location; +} + +void DuiAction::setLocation(DuiAction::Locations location) +{ + Q_D(DuiAction); + if (d->location == location) + return; + + d->location = location; + d->sendDataChanged(); +} + +void DuiAction::setStyleAction(bool styleAction) +{ + Q_D(DuiAction); + if (d->styleAction != styleAction) { + d->styleAction = styleAction; + d->sendDataChanged(); + } +} + +bool DuiAction::isStyleAction() const +{ + Q_D(const DuiAction); + return d->styleAction; +} diff --git a/src/core/duiaction.h b/src/core/duiaction.h new file mode 100644 index 000000000..4acb34af9 --- /dev/null +++ b/src/core/duiaction.h @@ -0,0 +1,139 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIACTION_H +#define DUIACTION_H + +#include "duiexport.h" + +#include + +class DuiActionPrivate; + +/** + \class DuiAction + \brief DuiAction implements an extension of the QAction for libdui + */ +class DUI_EXPORT DuiAction : public QAction +{ + Q_OBJECT + + /** + \brief properties handled by internal model + */ + Q_PROPERTY(QString text READ text WRITE setText) + Q_PROPERTY(QString iconID READ iconID WRITE setIconID) + + Q_FLAGS(Locations) + +public: + + /* + \brief Possible locations for an action to reside in + \detail An action may stay in different locations on the screen, but will have preferred ones. + This information is useful if actions should be shifted from one location to another automatically. + */ + enum Location { + NoLocation = 0x0000, + ToolBarPortraitLocation = 0x0001, + ToolBarLandscapeLocation = 0x0002, + ToolBarLocation = 0x0003, + ApplicationMenuLocation = 0x0004, + ObjectMenuLocation = 0x0008, + EveryLocation = 0xffff + }; + + Q_DECLARE_FLAGS(Locations, Location) + + /** + \brief Default constructor + \param parent Parent object + */ + explicit DuiAction(QObject *parent); + + /** + \brief Constructor + \param text Text to be used as label for action button + \param parent Parent object + This overloaded constructor is provided for convenience. + */ + DuiAction(const QString &text, QObject *parent); + + /** + \brief Constructor + \param iconID Identifier for icon to be shown on action button + \param text Text to be used as label for action button + \param parent Parent object + This overloaded constructor is provided for convenience. + */ + DuiAction(const QString &iconID, const QString &text, QObject *parent); + + /** + \brief Destructor for an action + */ + virtual ~DuiAction(); + + /** + \brief Return the iconID associated with this action + */ + QString iconID() const; + + /** + \brief set the iconID associated with this action + */ + void setIconID(const QString &id); + + /** + \brief Return the possible location this action may reside in + */ + Locations location() const; + + /** + \brief Set the location this action may reside in + \param location value of possible location + */ + void setLocation(Locations location); + + /*! + * \brief sets the action as style action, which can be used to + * set the style/order/presentation of the contents of the view. + */ + void setStyleAction(bool styleAction); + + /*! + * \brief Return whether this action is a style action or not + */ + bool isStyleAction() const; + +protected: + /** \internal */ + DuiActionPrivate *const d_ptr; + DuiAction(DuiActionPrivate &dd, QObject *parent = 0); + /** \internal_end */ + +private: + Q_DISABLE_COPY(DuiAction) + Q_DECLARE_PRIVATE(DuiAction) + +#ifdef UNIT_TEST + friend class Ut_DuiAction; +#endif +}; + +#endif diff --git a/src/core/duiaction_p.h b/src/core/duiaction_p.h new file mode 100644 index 000000000..667d54cb7 --- /dev/null +++ b/src/core/duiaction_p.h @@ -0,0 +1,47 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIACTION_P_H +#define DUIACTION_P_H + +#include "duiaction.h" + +class DuiActionPrivate +{ + Q_DECLARE_PUBLIC(DuiAction) + +public: + DuiActionPrivate(); + + virtual ~DuiActionPrivate(); + + void sendDataChanged(); + + QString iconID; + + DuiAction::Locations location; + + bool styleAction; + +protected: + + DuiAction *q_ptr; +}; + +#endif diff --git a/src/core/duiapplication.cpp b/src/core/duiapplication.cpp new file mode 100644 index 000000000..8df54473f --- /dev/null +++ b/src/core/duiapplication.cpp @@ -0,0 +1,434 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include + +#include "duiapplication.h" +#include "duicomponentdata.h" +#include "duiondisplaychangeevent.h" +#include "duiapplicationwindow.h" +#include +#include "duiapplication_p.h" + +/* Must be last, as it conflicts with some of the Qt defined types */ +#ifdef Q_WS_X11 +#include +#include +#include +#include +#endif + +DuiApplicationPrivate::DuiApplicationPrivate() +{ +#ifdef Q_WS_X11 + XDamageQueryExtension(QX11Info::display(), &xDamageEventBase, &xDamageErrorBase); +#endif +} + +DuiApplicationPrivate::~DuiApplicationPrivate() +{ + delete componentData; +} +#ifdef Q_WS_X11 +void DuiApplicationPrivate::setWindowVisibility(Window window, bool visible) +{ + if (!DuiApplication::windows().empty()) { + Q_FOREACH(DuiWindow * win, DuiApplication::windows()) { + if (win && win->winId() == window) { + DuiOnDisplayChangeEvent ev(visible, QRectF(QPointF(0, 0), win->visibleSceneSize())); + DuiApplication::instance()->sendEvent(win, &ev); + } + } + } +} + +int DuiApplicationPrivate::handleXError(Display *, XErrorEvent *) +{ + return 0; +} + +void DuiApplicationPrivate::removeWindowsFromSwitcher(bool remove) +{ + if (!DuiApplication::windows().empty()) { + Display *dpy = QX11Info::display(); + Atom stateAtom = XInternAtom(dpy, "_NET_WM_STATE", True); + if (stateAtom != None) { + Atom skipAtom = XInternAtom(dpy, "_NET_WM_STATE_SKIP_TASKBAR", True); + if (remove) { + Q_FOREACH(DuiWindow * win, DuiApplication::windows()) { + XChangeProperty(dpy, win->winId(), stateAtom, + XA_ATOM, 32, PropModeAppend, + reinterpret_cast(&skipAtom), 1); + } + } else { + Q_FOREACH(DuiWindow * win, DuiApplication::windows()) { + XChangeProperty(dpy, win->winId(), stateAtom, + XA_ATOM, 32, PropModePrepend, + reinterpret_cast(&skipAtom), 1); + } + } + } + } +} +#endif + +DuiApplication *DuiApplication::instance() +{ + return qobject_cast(QCoreApplication::instance()); +} + +DuiApplication::DuiApplication(int &argc, char **argv, const QString &appIdentifier, DuiApplicationService *service) + : QApplication(argc, argv), + d_ptr(new DuiApplicationPrivate) +{ + Q_D(DuiApplication); + d->q_ptr = this; + + d->init(argc, argv, appIdentifier, service); +} + +DuiApplication::DuiApplication(int &argc, char **argv, DuiApplicationService *service) : + QApplication(argc, argv), + d_ptr(new DuiApplicationPrivate) +{ + Q_D(DuiApplication); + d->q_ptr = this; + + d->init(argc, argv, QString(), service); +} + +void DuiApplicationPrivate::init(int &argc, char **argv, const QString &appIdentifier, DuiApplicationService *newService) +{ + componentData = new DuiComponentData(argc, argv, appIdentifier, newService); + QObject::connect(componentData, SIGNAL(localeSettingsChanged()), qApp, SIGNAL(localeSettingsChanged())); +} + +void DuiApplicationPrivate::releasePrestart() +{ + if (DuiApplication::prestartMode() != Dui::NoPrestart) { + + DuiComponentData::setPrestarted(false); + + // Call the virtual handler and emit the signal + DuiApplication *duiApp = DuiApplication::instance(); + if (duiApp) { + duiApp->releasePrestart(); + emit duiApp->prestartReleased(); + } + +#ifdef Q_WS_X11 + // Ensure that windows are visible in the switcher again + if (DuiApplication::prestartMode() == Dui::LazyShutdown) { + removeWindowsFromSwitcher(false); + } +#endif + } +} + +void DuiApplicationPrivate::restorePrestart() +{ + if (DuiApplication::prestartMode() == Dui::LazyShutdown) { + + DuiComponentData::setPrestarted(true); + + // Call the virtual handler and emit the signal + DuiApplication *duiApp = DuiApplication::instance(); + if (duiApp) { + duiApp->restorePrestart(); + emit duiApp->prestartRestored(); + } + +#ifdef Q_WS_X11 + // Explicitly remove windows from the switcher because they + // are hidden but should look like closed + removeWindowsFromSwitcher(true); +#endif + } +} + +DuiApplication::~DuiApplication() +{ + delete d_ptr; +} + +QString DuiApplication::deviceName() +{ + return DuiComponentData::deviceName(); +} + +bool DuiApplication::softwareRendering() +{ + return DuiComponentData::softwareRendering(); +} + +bool DuiApplication::fullScreen() +{ + return DuiComponentData::fullScreen(); +} + +bool DuiApplication::showBoundingRect() +{ + return DuiComponentData::showBoundingRect(); +} + +bool DuiApplication::showFps() +{ + return DuiComponentData::showFps(); +} + +bool DuiApplication::showSize() +{ + return DuiComponentData::showSize(); +} + +bool DuiApplication::showPosition() +{ + return DuiComponentData::showPosition(); +} + +bool DuiApplication::showMargins() +{ + return DuiComponentData::showMargins(); +} + +bool DuiApplication::showObjectNames() +{ + return DuiComponentData::showObjectNames(); +} + +bool DuiApplication::showCursor() +{ + return DuiComponentData::showCursor(); +} + +void DuiApplication::setShowPosition(bool show) +{ + DuiComponentData::setShowPosition(show); +} + +void DuiApplication::setShowSize(bool show) +{ + DuiComponentData::setShowSize(show); +} + +void DuiApplication::setShowMargins(bool show) +{ + DuiComponentData::setShowMargins(show); +} + +void DuiApplication::setShowObjectNames(bool show) +{ + DuiComponentData::setShowObjectNames(show); +} + +void DuiApplication::setShowBoundingRect(bool show) +{ + DuiComponentData::setShowBoundingRect(show); +} + +void DuiApplication::setShowFps(bool show) +{ + DuiComponentData::setShowFps(show); +} + +void DuiApplication::setShowCursor(bool show) +{ + DuiComponentData::setShowCursor(show); +} + +DuiApplicationWindow *DuiApplication::activeApplicationWindow() +{ + return DuiComponentData::activeApplicationWindow(); +} + +DuiWindow *DuiApplication::activeWindow() +{ + return DuiComponentData::activeWindow(); +} + +QList DuiApplication::windows() +{ + return DuiComponentData::windows(); +} + +DuiFeedbackPlayer *DuiApplication::feedbackPlayer() +{ + return DuiComponentData::feedbackPlayer(); +} + +bool DuiApplication::isLoadDuiInputContextEnabled() +{ + return DuiComponentData::isLoadDuiInputContextEnabled(); +} + +void DuiApplication::setLoadDuiInputContext(bool enable) +{ + DuiComponentData::setLoadDuiInputContext(enable); +} + +#ifdef Q_WS_X11 +bool DuiApplication::x11EventFilter(XEvent *event) +{ + Q_D(DuiApplication); + + if (event->type == VisibilityNotify) { + XVisibilityEvent *xevent = (XVisibilityEvent *) event; + + switch (xevent->state) { + case VisibilityFullyObscured: + DuiApplicationPrivate::setWindowVisibility(xevent->window, false); + break; + case VisibilityUnobscured: + DuiApplicationPrivate::setWindowVisibility(xevent->window, true); + break; + default: + break; + } + } else if (event->type == d->xDamageEventBase + XDamageNotify) { + XDamageNotifyEvent *xevent = (XDamageNotifyEvent *) event; + XserverRegion parts; + XRectangle *rects; + int n_rect; + + // It is possible that the Damage has already been destroyed so register an error handler to suppress X errors + XErrorHandler errh = XSetErrorHandler(DuiApplicationPrivate::handleXError); + + // Get the damaged rectangles from the damage event + parts = XFixesCreateRegion(QX11Info::display(), 0, 0); + // TODO does subtracting 0 regions really make any sense? + XDamageSubtract(QX11Info::display(), xevent->damage, None, parts); + rects = XFixesFetchRegion(QX11Info::display(), parts, &n_rect); + XFixesDestroyRegion(QX11Info::display(), parts); + + // Create separate damage event signals from the damaged rectangles + for (int i = 0; i < n_rect; ++i) + emit damageEvent(xevent->damage, rects[i].x, rects[i].y, rects[i].width, rects[i].height); + + // Free the rectangles and reset the original error handler + XFree(rects); + XSetErrorHandler(errh); + + return true; + } + + return false; +} +#endif + +QString DuiApplication::appName() +{ + return DuiComponentData::appName(); +} + +QString DuiApplication::binaryName() +{ + return DuiComponentData::binaryName(); +} + +void DuiApplicationPrivate::stdExit(int status) +{ + std::exit(status); +} + +void DuiApplication::setPrestartMode(Dui::PrestartMode mode) +{ + // Set prestart mode only if the app was started with -prestart. + // This way we can later check if the app was originally prestarted or not. + if (DuiComponentData::prestarted()) { + if (mode == Dui::LazyShutdown) { + DuiApplication::setQuitOnLastWindowClosed(false); + } + DuiComponentData::setPrestartMode(mode); + } +} + +Dui::PrestartMode DuiApplication::prestartMode() +{ + return DuiComponentData::prestartMode(); +} + +void DuiApplication::releasePrestart() +{ + if (DuiApplication::activeApplicationWindow()) { + DuiApplication::activeApplicationWindow()->show(); + DuiApplication::activeApplicationWindow()->activateWindow(); + DuiApplication::activeApplicationWindow()->raise(); + } +} + +void DuiApplication::restorePrestart() +{ + if (DuiApplication::activeApplicationWindow()) { + DuiApplication::activeApplicationWindow()->hide(); + DuiApplication::activeApplicationWindow()->lower(); + } +} + +bool DuiApplication::isPrestarted() +{ + return (DuiComponentData::prestartMode() != Dui::NoPrestart) && DuiComponentData::prestarted(); +} + +#ifdef __arm__ +/* + * When in "runfast" mode, single-precision VFP instructions execute in the + * NEON pipeline. If using gcc, adding the flags -ffast-math -fno-math-errno, + * and avoiding double precision is advisable, assuming results are still + * accurate enough. + */ +static int set_runfast() +{ + int tmp; + __asm__ volatile( + "fmrx %[tmp], fpscr\n\t" + "orr %[tmp], %[tmp], #(1 << 24)\n\t" /* flush-to-zero */ + "orr %[tmp], %[tmp], #(1 << 25)\n\t" /* default NaN */ + "bic %[tmp], %[tmp], #((1 << 15) | (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8))\n\t" /* clear exception bits */ + "fmxr fpscr, %[tmp]\n\t" + : [tmp] "=r"(tmp)); + return tmp; +} + +/* + * IEEE standard floating point calculation + */ +static int set_ieee() +{ + int tmp; + __asm__ volatile( + "fmrx %[tmp], fpscr\n\t" + "bic %[tmp], %[tmp], #(1 << 24)\n\t" /* flush-to-zero */ + "bic %[tmp], %[tmp], #(1 << 25)\n\t" /* default NaN */ + "fmxr fpscr, %[tmp]\n\t" + : [tmp] "=r"(tmp)); + return tmp; +} + +void DuiApplication::fastFloatMath(bool val) +{ + if (val) { + set_runfast(); + } else { + set_ieee(); + } +} + +#endif diff --git a/src/core/duiapplication.h b/src/core/duiapplication.h new file mode 100644 index 000000000..97c82dbfb --- /dev/null +++ b/src/core/duiapplication.h @@ -0,0 +1,257 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLICATION_H +#define DUIAPPLICATION_H + +#include +#ifdef Q_WS_X11 +#include +#endif + +#include "duiexport.h" +#include "duinamespace.h" + +class DuiApplicationPrivate; +class DuiWindow; +class DuiApplicationWindow; +class DuiApplicationService; +class DuiFeedbackPlayer; +class DuiSceneWindow; + + +/*! + * \class DuiApplication + * \brief DuiApplication manages the GUI application's control flow and main settings. + * + * DuiApplication instance automatically extracts application name from the arguments + * given in the constructor. It also loads css - stylesheet, svg file and adds application + * specific image paths to the pixmap search paths used by the current DuiTheme instance. + * + * CSS and SVG files are searched for in order from the following places: + *
    + *
  1. Directory in which application was launched.
  2. + *
  3. Application specific theme path (global theme path appended with the application name)
  4. + *
  5. Global theme path (Qt data path appended by themes/dui)
  6. + *
+ * When first instance of CSS or SVG file is found it is loaded to the current DuiTheme. + * Also image - subdirectory of each of the aforementioned paths is appended to the pixmap search + * paths used by DuiTheme. + * + * DuiApplication will also create a QDBus service with name made by prepending 'com.nokia.' to + * the application name provided in the constructor (or the binary name if no name is provided + * in the constructor). It will provide an interface called DuiApplicationIf which calls service + * methods in an instance of DuiApplicationService. By default, DuiApplication will construct an + * instance of DuiApplicationService, but the application programmer can derive a class from + * DuiApplicationService and provide a pointer to that in the constructor for DuiApplication to + * use instead. This way, the application programmer can override the methods in + * DuiApplicationService and change the behaviour of the application's interface. + * + * The default behaviour is to only allow a single instance of any + * application. When an application is launched, it attempts to register + * itself as a dbus service (as above). Only the first instance of the + * application will be successful, and subsequent attempts will fail. When + * dbus registration fails, the default behaviour is to call the first + * instance's DuiApplicationService launch() method, and then quit. This + * causes the first instance to become visible (raises the window). + * + * If other behaviour is required, for example if you want multiple + * instances of an application, then it is necessary to derive a class from + * DuiApplicationService and override its methods. + */ + +class DUI_EXPORT DuiApplication : public QApplication +{ + Q_OBJECT + +public: + //! Initializes the window system and constructs an application object. + /*! + * \param argc number of arguments passed to the application from the command line + * \param argv argument strings passed to the application from the command line + * \param appIdentifier an optional identifier for the application. Can + * contain alphabetical characters, numbers, dashes and underscores. If + * an empty string is given (the default) the application binary file + * name is used. + * + * \note Warning: The data referred to by argc and argv must stay valid for the entire + * lifetime of the DuiApplication object. In addition, argc must be greater than zero and + * argv must contain at least one valid character string. + */ + DuiApplication(int &argc, char **argv, const QString &appIdentifier = QString(), DuiApplicationService *service = 0); + DuiApplication(int &argc, char **argv, DuiApplicationService *service); + + //! Cleans up any window system resources that were allocated by this application. + virtual ~DuiApplication(); + + static DuiApplication *instance(); + + //! Target device name + static QString deviceName(); + //! Software rendering command line option set + static bool softwareRendering(); + //! Full screen command line option set + static bool fullScreen(); + //! Show bounding rectangles command line option set + static bool showBoundingRect(); + //! Show frame rate command line option set + static bool showFps(); + //! Show widgets sizes + static bool showSize(); + //! Show widgets positions + static bool showPosition(); + //! Show widgets margins + static bool showMargins(); + //! Show object names + static bool showObjectNames(); + //! Show cursor + static bool showCursor(); + //! Sets if position of widgets should be shown or not + static void setShowPosition(bool show); + //! Sets if margins of widgets should be shown or not + static void setShowMargins(bool show); + //! Sets if names of objects should be shown or not + static void setShowObjectNames(bool show); + //! Sets if sizes of widgets should be shown or not + static void setShowSize(bool show); + //! Sets if bounding rects of widgets should be shown or not + static void setShowBoundingRect(bool show); + //! Sets if a frames-per-second counter should be shown or not + static void setShowFps(bool show); + //! Sets if the cursor should be shown or not + static void setShowCursor(bool show); + + /*! + * Returns the currently active application window. + * \note If the active window is of type DuiWindow (and not DuiApplicationWindow) + * this method will return a null pointer. + * \sa activeWindow() + */ + static DuiApplicationWindow *activeApplicationWindow(); + /*! Returns the currently active window. + * \note In comparison to QApplication::activeWindow(), this method will return + * a pointer to the DuiWindow even if it doesn't have focus. For single-window + * applications this method will return a pointer to the window once it's + * created (even before it's shown). For multiple-window applications this method + * will return a pointer to the current topmost window. + */ + static DuiWindow *activeWindow(); + //! Returns a list of all windows in the application + static QList windows(); + //! Returns the application's app name + static QString appName(); + //! Returns the application's binary name + static QString binaryName(); + + //! Returns object which provide interface for nonvisual feedback or NULL + static DuiFeedbackPlayer *feedbackPlayer(); + + //! Returns whether automatic loading of DuiInputContext is enabled + static bool isLoadDuiInputContextEnabled(); + + //! Sets whether DuiApplication should automatically load dui input context + static void setLoadDuiInputContext(bool enable); + +#ifdef __arm__ + static void fastFloatMath(bool val); +#endif + + /*! + * \brief Select the prestart mode. + * \param mode Prestart mode + */ + static void setPrestartMode(Dui::PrestartMode mode); + + /*! + * \brief Return the current prestart mode + * \return prestart mode + */ + static Dui::PrestartMode prestartMode(); + + /*! + *\brief Return true if application is in the prestarted state. + *\return true if application is in the prestarted state. + */ + static bool isPrestarted(); + + /*! + * \brief Called when DuiApplication returns to prestarted state (if supported by the mode) + * Re-imp this if desired + */ + virtual void restorePrestart(); + + /*! + * \brief Called when DuiApplication is released from the prestarted state + * Re-imp this if desired + */ + virtual void releasePrestart(); + +Q_SIGNALS: + + /*! + * \brief The application is requested to release as much memory as possible + */ + void releaseMemoryRequested(); + + /*! + * This signal is emitted when there is a change in any of the locale + * settings (language, country, script, and variant) + */ + void localeSettingsChanged(); + + /*! + * Signal that is emitted when the application has been released from the + * prestarted state. Next the application should show a window. + */ + void prestartReleased(); + + /*! + * Signal that is emitted when the application has been restored + * to the prestarted state. + */ + void prestartRestored(); + +#ifdef Q_WS_X11 + /*! + * Signal application about a changed X pixmap + */ + void damageEvent(Qt::HANDLE &damage, short &x, short &y, unsigned short &width, unsigned short &height); +#endif + +protected: + DuiApplication(DuiApplicationPrivate &dd, int &argc, char **argv, const QString &appIdentifier = QString()); + DuiApplicationPrivate *const d_ptr; + +#ifdef Q_WS_X11 + //! \reimp + bool x11EventFilter(XEvent *event); + //! \reimp_end +#endif + +private: + + Q_DECLARE_PRIVATE(DuiApplication) + Q_DISABLE_COPY(DuiApplication) + +#ifdef UNIT_TEST + friend class Ut_DuiApplication; +#endif +}; + +#endif diff --git a/src/core/duiapplication_p.h b/src/core/duiapplication_p.h new file mode 100644 index 000000000..d90554088 --- /dev/null +++ b/src/core/duiapplication_p.h @@ -0,0 +1,75 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLICATION_P_H +#define DUIAPPLICATION_P_H + +#include +#include "duicomponentdata.h" +#include +#ifdef Q_WS_X11 +#include +#endif + +#include + +class DuiTheme; +class DuiApplication; +class DuiSceneWindow; +class DuiFeedbackPlayer; +class DuiApplicationService; +class DuiDeviceProfile; + +class DuiApplicationPrivate +{ + Q_DECLARE_PUBLIC(DuiApplication) + +public: + DuiApplicationPrivate(); + virtual ~DuiApplicationPrivate(); + + DuiComponentData *componentData; + + int xDamageEventBase; + int xDamageErrorBase; + +#ifdef Q_WS_X11 + static int handleXError(Display *display, XErrorEvent *event); +#endif + +protected: + DuiApplication *q_ptr; + +private: + void init(int &argc, char **argv, const QString &appIdentifier, DuiApplicationService *service); + + static void releasePrestart(); + static void restorePrestart(); + + static void stdExit(int status); +#ifdef Q_WS_X11 + static void setWindowVisibility(Window window, bool visible); + static void removeWindowsFromSwitcher(bool remove); +#endif + friend class DuiApplicationServicePrivate; + friend bool DuiApplicationWindow::close(); +}; + + +#endif diff --git a/src/core/duiapplicationifadaptor.cpp b/src/core/duiapplicationifadaptor.cpp new file mode 100644 index 000000000..1ecc5ac9a --- /dev/null +++ b/src/core/duiapplicationifadaptor.cpp @@ -0,0 +1,56 @@ +/* + * This file was generated by qdbusxml2cpp version 0.7 + * Command line was: qdbusxml2cpp -c DuiApplicationIfAdaptor -a duiapplicationadaptor.h:duiapplicationadaptor.cpp DuiApplicationIfAdaptor.xml + * + * qdbusxml2cpp is Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#include "duiapplicationifadaptor.h" +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Implementation of adaptor class DuiApplicationIfAdaptor + */ + +DuiApplicationIfAdaptor::DuiApplicationIfAdaptor(QObject *parent) + : QDBusAbstractAdaptor(parent) +{ + // constructor + setAutoRelaySignals(true); +} + +DuiApplicationIfAdaptor::~DuiApplicationIfAdaptor() +{ + // destructor +} + +void DuiApplicationIfAdaptor::close() +{ + duiDebug("DuiApplicationIfAdaptor") << "DuiApplicationIfAdaptor::close()"; + // handle method call com.nokia.DuiApplicationIfAdaptor.close + QMetaObject::invokeMethod(parent(), "close"); +} + +void DuiApplicationIfAdaptor::exit() +{ + duiDebug("DuiApplicationIfAdaptor") << "DuiApplicationIfAdaptor::exit()"; + // handle method call com.nokia.DuiApplicationIfAdaptor.exit + QMetaObject::invokeMethod(parent(), "exit"); +} + +void DuiApplicationIfAdaptor::launch() +{ + duiDebug("DuiApplicationIfAdaptor") << "DuiApplicationIfAdaptor::launch()"; + QMetaObject::invokeMethod(parent(), "launch"); +} + diff --git a/src/core/duiapplicationifadaptor.h b/src/core/duiapplicationifadaptor.h new file mode 100644 index 000000000..378a1b33f --- /dev/null +++ b/src/core/duiapplicationifadaptor.h @@ -0,0 +1,77 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +// Make doxygen skip this internal class +//! \cond + +// Command line was: qdbusxml2cpp -c DuiApplicationIfAdaptor -a duiapplicationadaptor.h:duiapplicationadaptor.cpp DuiApplicationIfAdaptor.xml + +#ifndef DUIAPPLICATIONIFADAPTOR_H +#define DUIAPPLICATIONIFADAPTOR_H + +#include +#include +#include "duiexport.h" + +class QByteArray; +template class QList; +template class QMap; +class QString; +class QStringList; +class QVariant; + +/*! + * \class DuiApplicationIfAdaptor + * \brief Adaptor class for interface com.nokia.DuiApplicationIf + * + * This is the adaptor for the DuiApplication QDBus service. + * Do not use this class directly. + */ +class DUI_EXPORT DuiApplicationIfAdaptor: public QDBusAbstractAdaptor +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "com.nokia.DuiApplicationIf") + Q_CLASSINFO("D-Bus Introspection", "" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "") +public: + DuiApplicationIfAdaptor(QObject *parent); + virtual ~DuiApplicationIfAdaptor(); + +public Q_SLOTS: // METHODS + + //! Close the GUI. + Q_NOREPLY void close(); + + //! Exit the application. + Q_NOREPLY void exit(); + + //! Launch the application. + Q_NOREPLY void launch(); +}; + +#endif +//! \cond diff --git a/src/core/duiapplicationifproxy.cpp b/src/core/duiapplicationifproxy.cpp new file mode 100644 index 000000000..9411a8da3 --- /dev/null +++ b/src/core/duiapplicationifproxy.cpp @@ -0,0 +1,47 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +// Command line was: qdbusxml2cpp -c DuiApplicationIfProxy -p duiapplicationifproxy.h:duiapplicationifproxy.cpp com.nokia.DuiApplicationIf.xml + +#include "duiapplicationifproxy.h" + +DuiApplicationIfProxy::DuiApplicationIfProxy(const QString &service, QObject *parent) : + QDBusAbstractInterface(service, "/org/maemo/dui", "com.nokia.DuiApplicationIf", QDBusConnection::sessionBus(), parent) +{ +} + +DuiApplicationIfProxy::~DuiApplicationIfProxy() +{ +} + +QDBusPendingReply<> DuiApplicationIfProxy::close() +{ + return asyncCall(QLatin1String("close")); +} + +QDBusPendingReply<> DuiApplicationIfProxy::exit() +{ + return asyncCall(QLatin1String("exit")); +} + +QDBusPendingReply<> DuiApplicationIfProxy::launch() +{ + return asyncCallWithArgumentList(QLatin1String("launch"), QList()); +} + diff --git a/src/core/duiapplicationifproxy.h b/src/core/duiapplicationifproxy.h new file mode 100644 index 000000000..175fc98e7 --- /dev/null +++ b/src/core/duiapplicationifproxy.h @@ -0,0 +1,70 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +// Make doxygen skip this internal class +//! \cond + +// Command line was: qdbusxml2cpp -c DuiApplicationIfProxy -p duiapplicationifproxy.h:duiapplicationifproxy.cpp com.nokia.DuiApplicationIf.xml + +#ifndef DUIAPPLICATIONIFPROXY_H +#define DUIAPPLICATIONIFPROXY_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "duiexport.h" + +/*! + * \class DuiApplicationIfProxy + * \brief Proxy class for interface com.nokia.DuiApplicationIf + * + * This is the proxy for the DuiApplication QDBus service. + */ +class DUI_EXPORT DuiApplicationIfProxy: public QDBusAbstractInterface +{ + Q_OBJECT + +public: + DuiApplicationIfProxy(const QString &service, QObject *parent = 0); + + ~DuiApplicationIfProxy(); + +public Q_SLOTS: // METHODS + QDBusPendingReply<> close(); + QDBusPendingReply<> exit(); + QDBusPendingReply<> launch(); + +Q_SIGNALS: // SIGNALS +}; + +namespace com +{ + namespace nokia + { + typedef ::DuiApplicationIfProxy DuiApplicationIf; + } +} +#endif +//! \cond diff --git a/src/core/duiapplicationservice.cpp b/src/core/duiapplicationservice.cpp new file mode 100644 index 000000000..832df5890 --- /dev/null +++ b/src/core/duiapplicationservice.cpp @@ -0,0 +1,210 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiapplication.h" +#include "duiapplicationservice.h" +#include "duiapplicationservice_p.h" +#include "duiwindow.h" +#include "duiapplicationifproxy.h" +#include "duiapplicationifadaptor.h" +#include "duiapplication_p.h" +#include + +DuiApplicationService::DuiApplicationService(const QString &newServiceName, QObject *parent): + d_ptr(new DuiApplicationServicePrivate(newServiceName)) +{ + Q_UNUSED(parent); +} + +DuiApplicationService::~DuiApplicationService() +{ + delete d_ptr; +} + +void DuiApplicationService::launch() +{ + Q_D(DuiApplicationService); + duiDebug("DuiApplicationService") << "launch()"; + + if (d->isPrestarted()) { + d->releasePrestart(); + } else { + if (d->activeWindowSet()) { + duiDebug("DuiApplicationService") << "launch() raising window"; + d->activateActiveWindow(); + d->raiseActiveWindow(); + } else { + duiDebug("DuiApplicationService") << "launch() no window to raise"; + } + } +} + +void DuiApplicationService::launchAnotherWithQProcess() +{ + Q_D(DuiApplicationService); + + static bool firstCall = true; + bool thisAppRunWithDBus = d->thisAppRunWithDBus(); + + duiDebug("DuiApplicationService") << "launch()"; + duiDebug("DuiApplicationService") << "thisAppRunWithDBus = " << thisAppRunWithDBus; + + if (firstCall && thisAppRunWithDBus) { + duiDebug("DuiApplicationService") << "launch() : first dbus call so doing nothing"; + } else { + QString binaryName = d->binaryName(); + QStringList arguments = d->arguments(); + + arguments.removeFirst(); // remove program name + + d->launchNewProcess(binaryName, arguments); + } + + firstCall = false; +} + +void DuiApplicationService::close() +{ + Q_D(DuiApplicationService); + + // Return to prestarted state if in LazyShutdown mode + if (d->prestartModeIsLazyShutdown()) { + d->restorePrestart(); + } + + duiDebug("DuiApplicationService") << "close()"; + d->closeAllWindows(); +} + +void DuiApplicationService::exit() +{ + Q_D(DuiApplicationService); + + // Do not really exit the app if it was prestarted (lazy shutdown) + if (d->prestartModeIsLazyShutdown()) { + d->restorePrestart(); + } else { + d->stdExit(0); + } + + duiDebug("DuiApplicationService") << "exit()"; +} + +void DuiApplicationService::handleServiceRegistrationFailure() +{ + Q_D(DuiApplicationService); + + DuiApplication *duiApp = DuiApplication::instance(); + + DuiApplicationIfProxy duiApplicationIfProxy(registeredName(), duiApp); + + if (duiApplicationIfProxy.connection().isConnected()) { + duiDebug("DuiApplicationService") << "Calling launch() in other application with service :" << registeredName(); + duiApplicationIfProxy.launch(); + d->stdExit(0); + } else { + duiDebug("DuiApplicationService") << "DBus not connected; not launching"; + } +} + +void DuiApplicationService::incrementAndRegister() +{ + Q_D(DuiApplicationService); + + QString appName = d->appName(); + + const int MaxNoInstances = 10; + + if (++d->instanceCounter == MaxNoInstances) { + duiDebug("DuiApplicationService") << "Reached maximum number instances of this application."; + d->stdExit(0); + } + + QString baseServiceName = "com.nokia." + appName; + QString serviceName = baseServiceName + QString::number(d->instanceCounter); + + // register dbus service + new DuiApplicationIfAdaptor(this); + + bool anotherAppRunning = !d->registerService(serviceName); + while (anotherAppRunning) { + duiDebug("DuiApplicationService") << "registering failed"; + + if (++d->instanceCounter == MaxNoInstances) { + duiDebug("DuiApplicationService") << "Reached maximum number instances of this application."; + d->stdExit(0); + } + + serviceName = baseServiceName + QString::number(d->instanceCounter); + + duiDebug("DuiApplicationService") << "attempting to register service :" << serviceName; + anotherAppRunning = !d->registerService(serviceName); + } + + d->unregisterObject("/org/maemo/dui"); + d->registerObject("/org/maemo/dui", this); + + setServiceName(serviceName); +} + +QString DuiApplicationService::registeredName() +{ + Q_D(DuiApplicationService); + + return d->serviceName; +} + +bool DuiApplicationService::isRegistered() +{ + Q_D(DuiApplicationService); + + return !d->serviceName.isEmpty(); +} + +bool DuiApplicationService::registerService() +{ + Q_D(DuiApplicationService); + + bool success = false; + + if (isRegistered()) { + new DuiApplicationIfAdaptor(this); + + bool anotherAppRunning = !d->registerService(d->serviceName); + if (anotherAppRunning) { + duiDebug("DuiApplicationService") << "registerService() registering failed"; + handleServiceRegistrationFailure(); + success = false; + } else { + duiDebug("DuiApplicationService") << "registerService() registering successful"; + d->unregisterObject("/org/maemo/dui"); + d->registerObject("/org/maemo/dui", this); + success = true; + } + } + + return success; +} + +void DuiApplicationService::setServiceName(const QString &newServiceName) +{ + Q_D(DuiApplicationService); + + d->serviceName = newServiceName; +} diff --git a/src/core/duiapplicationservice.h b/src/core/duiapplicationservice.h new file mode 100644 index 000000000..cf3193145 --- /dev/null +++ b/src/core/duiapplicationservice.h @@ -0,0 +1,166 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLICATIONSERVICE_H +#define DUIAPPLICATIONSERVICE_H + +#include + +#include "duiexport.h" + +class DuiApplicationServicePrivate; + +/*! + * \class DuiApplicationService + * \brief Adaptor class for interface com.nokia.DuiApplicationIf + * + * This is the implementation for the DuiApplication QDBus service. + * Derive from this class to implement alternative behaviour. + * + * If multiple processes are required, override the launch() method and + * from there call launchAnotherWithQProcess(). + * + * If it is desired for the subsequent processes to also have a + * DuiApplicationIf, then override handleServiceRegistrationFailure() + * and from there call incrementAndRegister(). + * + * If it is desired that there be no DuiApplicationIf interface, override + * registeredName() so that it returns QString(), isRegistered() to + * return false, and registerService() to return true. + * + * Here is a code sample that allows multiple instances, each with its own + * DBus service : + * \dontinclude multipleinstances/main.cpp + * \skip class MyApplicationService + * \until DuiApplication app + * + * Tip: You can use qdbusviewer from the qt4-dev-tools package to see the + * services appearing and disappearing when you run/kill multiple instances. + * + */ +class DUI_EXPORT DuiApplicationService : public QObject +{ + Q_OBJECT + +public: + DuiApplicationService(const QString &serviceName, QObject *parent = 0); + virtual ~DuiApplicationService(); + +public Q_SLOTS: // METHODS + /** + * \brief Launch the application. + * + * \return void + * By default, this method will raise the application's window + * + * If it is required that it launch another instance of this + * application, derive a class from DuiApplicationService and override + * launch() to call launchAnotherWithQProcess(). + **/ + virtual void launch(); + + /** + * \brief Close the GUI. + * + * \return void + **/ + virtual void close(); + + /** + * \brief Exit the application. + * + * \return void + **/ + virtual void exit(); + + /** + * \brief launch another process using QProcess + * + * \return void + **/ + virtual void launchAnotherWithQProcess(); + + /** + * \brief Handles the situation when a service is already registered with this application's name. + * + * \return void + * + * This method implements the default behaviour when there is already + * a service registrated with our service name, which is to call + * 'launch()' on that service and then exit. + * This method can be overridden and alternative behaviour + * implemented. One alternative behaviour is to register with another + * name and this is implemented in incrementAndRegister() which can + * be called from an overridden handleServiceRegistrationFailure(). + **/ + virtual void handleServiceRegistrationFailure(); + + /** + * \brief increment service name and register + * + * \return void + * + * It is intended that this method be called from within an overridden handleServiceRegistrationFailure() method. + * The behaviour is to add an integer to the name of the service being registered until registration succeeds, or the maximum number of attempts (10) is exceeded. + **/ + virtual void incrementAndRegister(); + + /** + * \brief return the registered service name + * + * \return registered service name + * + * If you want no DuiApplicationIf, override this to return QString(). + **/ + virtual QString registeredName(); + + /** + * \brief return if the service is registered + * + * \return true if the service is registered + * + * If you want no DuiApplicationIf, override this to always return false. + **/ + virtual bool isRegistered(); + + /** + * \brief registers the service + * + * \return true is registration was successful + * + * If you want no DuiApplicationIf, override this to always return true. + **/ + virtual bool registerService(); + + /** + * \brief sets the service name + * + * \return void + **/ + void setServiceName(const QString &serviceName); + +protected: + DuiApplicationServicePrivate *const d_ptr; + +private: + Q_DECLARE_PRIVATE(DuiApplicationService) + Q_DISABLE_COPY(DuiApplicationService) +}; + +#endif diff --git a/src/core/duiapplicationservice_p.cpp b/src/core/duiapplicationservice_p.cpp new file mode 100644 index 000000000..9d533c117 --- /dev/null +++ b/src/core/duiapplicationservice_p.cpp @@ -0,0 +1,137 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include +#include + +#include "duiapplication.h" +#include "duiapplication_p.h" +#include "duiapplicationservice_p.h" + +DuiApplicationServicePrivate::DuiApplicationServicePrivate(const QString &newServiceName): + serviceName(newServiceName), + registered(false), + instanceCounter(0), + dBusConnection(QDBusConnection::sessionBus()), + duiApp(DuiApplication::instance()) +{ +} + +DuiApplicationServicePrivate::~DuiApplicationServicePrivate() +{ +} + +void DuiApplicationServicePrivate::launchNewProcess(const QString &binaryName, const QStringList &arguments) +{ + QProcess *myProcess = new QProcess(); + + duiDebug("DuiApplicationService") << "launch() starting" << binaryName; + bool success = myProcess->startDetached(binaryName, arguments); + if (!success) { + duiDebug("DuiApplicationService") << "launch(): failed to start" << binaryName; + } +} + +bool DuiApplicationServicePrivate::registerService(const QString &serviceName) +{ + return dBusConnection.registerService(serviceName); +} + +void DuiApplicationServicePrivate::registerObject(const QString &path, QObject *object) +{ + dBusConnection.registerObject(path, object); +} + +void DuiApplicationServicePrivate::unregisterObject(const QString &path) +{ + dBusConnection.unregisterObject(path); +} + +QString DuiApplicationServicePrivate::appName() +{ + QString appName = DuiApplication::instance()->appName(); + return appName; +} + +void DuiApplicationServicePrivate::stdExit(int exitValue) +{ + DuiApplicationPrivate::stdExit(exitValue); +} + +bool DuiApplicationServicePrivate::isPrestarted() +{ + return duiApp->isPrestarted(); +} + +bool DuiApplicationServicePrivate::activeWindowSet() +{ + return (duiApp->activeWindow() != 0); +} + +void DuiApplicationServicePrivate::activateActiveWindow() +{ + duiApp->activeWindow()->activateWindow(); +} + +void DuiApplicationServicePrivate::raiseActiveWindow() +{ + duiApp->activeWindow()->raise(); +} + +bool DuiApplicationServicePrivate::thisAppRunWithDBus() +{ + bool thisAppRunWithDBus = !QProcess::systemEnvironment().filter("DBUS_STARTER_BUS_TYPE=").empty(); + return thisAppRunWithDBus; +} + +QString DuiApplicationServicePrivate::binaryName() +{ + QString binaryName = DuiApplication::instance()->binaryName(); + return binaryName; +} + +QStringList DuiApplicationServicePrivate::arguments() +{ + QStringList arguments = QCoreApplication::arguments(); + return arguments; +} + +void DuiApplicationServicePrivate::closeAllWindows() +{ + duiApp->closeAllWindows(); +} + +bool DuiApplicationServicePrivate::prestartModeIsLazyShutdown() +{ + bool retVal = (DuiApplication::prestartMode() == Dui::LazyShutdown); + + return retVal; +} + +void DuiApplicationServicePrivate::releasePrestart() +{ + DuiApplicationPrivate::releasePrestart(); +} + +void DuiApplicationServicePrivate::restorePrestart() +{ + DuiApplicationPrivate::restorePrestart(); +} diff --git a/src/core/duiapplicationservice_p.h b/src/core/duiapplicationservice_p.h new file mode 100644 index 000000000..9dcf4411d --- /dev/null +++ b/src/core/duiapplicationservice_p.h @@ -0,0 +1,69 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLICATIONSERVICE_P_H +#define DUIAPPLICATIONSERVICE_P_H + +#include +#include + +class DuiApplicationService; + +class DuiApplicationServicePrivate +{ + Q_DECLARE_PUBLIC(DuiApplicationService) + +public: + DuiApplicationServicePrivate(const QString &newService); + virtual ~DuiApplicationServicePrivate(); + + QString serviceName; + bool registered; + int instanceCounter; + +protected: + DuiApplicationService *q_ptr; + + void launchNewProcess(const QString &binaryName, const QStringList &arguments); + + QString appName(); + QString binaryName(); + QStringList arguments(); + bool registerService(const QString &serviceName); + void registerObject(const QString &path, QObject *object); + void unregisterObject(const QString &path); + void stdExit(int exitValue); + void activateActiveWindow(); + void raiseActiveWindow(); + bool thisAppRunWithDBus(); + void closeAllWindows(); + bool prestartModeIsLazyShutdown(); + void releasePrestart(); + void restorePrestart(); + bool isPrestarted(); + bool activeWindowSet(); + +private: + QDBusConnection dBusConnection; + DuiApplication *duiApp; + +}; + +#endif + diff --git a/src/core/duiassembly.cpp b/src/core/duiassembly.cpp new file mode 100644 index 000000000..013ab22f4 --- /dev/null +++ b/src/core/duiassembly.cpp @@ -0,0 +1,163 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include + +#include "duigconfitem.h" +#include "duiassembly.h" +#include "duiassembly_p.h" +#include "duidebug.h" +#include "duiwidgetcontroller.h" + +bool DuiAssemblyPrivate::loadViewConfiguration(const QStringList &themeInheritance) +{ + viewConfiguration.clear(); + // load all view configuration files in inheritance order + foreach(const QString & themePath, themeInheritance) { + // resolve filename for configuration file + QString filename = themePath + "dui" + QDir::separator() + name + QDir::separator() + name + ".conf"; + + // check that we have such file + if (!QFile::exists(filename)) + continue; + + // load it + QSettings config(filename, QSettings::IniFormat); + if (config.status() != QSettings::NoError) { + duiWarning("DuiAssembly") << "Invalid view configuration file:" << filename; + return false; + } + + // copy all the loaded keys to our configuration table + const QStringList keys(config.allKeys()); + foreach(const QString & key, keys) { + QVariant value = config.value(key); + if (!viewConfiguration.contains(key)) + viewConfiguration.insert(key, value.toString()); + } + } + + return true; +} + +void DuiAssemblyPrivate::loadStylesheet(const QString &filename, const DuiLogicalValues &logicalValues) +{ + // load stylesheet to new sheet + DuiStyleSheet *newStylesheet = new DuiStyleSheet(&logicalValues); + bool result = newStylesheet->load(filename); + if (result) { + // loaded succesfully + if (stylesheet) { + // existing stylesheet data, append + *stylesheet += *newStylesheet; + delete newStylesheet; + newStylesheet = NULL; + } else { + // no existing data, this is the first sheet which was loaded + stylesheet = newStylesheet; + } + } else { + duiWarning("DuiAssembly") << "Failed to load stylesheet:" << filename; + delete newStylesheet; + newStylesheet = NULL; + } +} + +void DuiAssemblyPrivate::loadStylesheets(const QStringList &themeInheritance, const DuiLogicalValues &logicalValues) +{ + delete stylesheet; + stylesheet = NULL; + + // load in reverse order, base first + for (int j = themeInheritance.count() - 1; j >= 0; --j) { + + QString path = themeInheritance.at(j) + "dui" + QDir::separator() + name + QDir::separator(); + QString filename = path + "style" + QDir::separator() + name + ".css"; + + if (QFile::exists(filename)) { + loadStylesheet(filename, logicalValues); + } else { + if (j == themeInheritance.count() - 1) { + // warnings only if the stylesheet is missing from the base theme + duiWarning("DuiAssembly") << "Stylesheet missing!" << filename; + } + } + } +} + +DuiAssembly::DuiAssembly(const QString &name) : + d_ptr(new DuiAssemblyPrivate) +{ + d_ptr->name = name; + d_ptr->stylesheet = NULL; +} + +DuiAssembly::~DuiAssembly() +{ + delete d_ptr->stylesheet; + delete d_ptr; +} + +QString DuiAssembly::name() const +{ + return d_ptr->name; +} + +QString DuiAssembly::viewType(const DuiWidgetController *widget, bool &exactMatch) const +{ + QString viewClassName; + + exactMatch = false; + // use whole inheritance chain to figure out best-matching view for this controller + for (const QMetaObject *metaObject = widget->metaObject(); metaObject->superClass(); metaObject = metaObject->superClass()) { + + // Figure out the class name of the controller + QString controllerClassName = metaObject->className(); + + QString view = d_ptr->viewConfiguration.value(controllerClassName + '/' + widget->viewType(), QString()); + if (view.isEmpty()) { + // try to get default if nothing has been found so far + if (viewClassName.isEmpty()) + viewClassName = d_ptr->viewConfiguration.value(controllerClassName + "/default", QString()); + } else { + exactMatch = true; + viewClassName = view; + break; + } + } + + return viewClassName; +} + +DuiStyleSheet *DuiAssembly::stylesheet() const +{ + return d_ptr->stylesheet; +} + +void DuiAssembly::themeChanged(const QStringList &themeInheritance, const DuiLogicalValues &logicalValues) +{ + // (re)load view configuration + d_ptr->loadViewConfiguration(themeInheritance); + + // (re)load stylesheet + d_ptr->loadStylesheets(themeInheritance, logicalValues); +} + + diff --git a/src/core/duiassembly.h b/src/core/duiassembly.h new file mode 100644 index 000000000..2cae9945f --- /dev/null +++ b/src/core/duiassembly.h @@ -0,0 +1,72 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIASSEMBLY_H +#define DUIASSEMBLY_H + +#include +#include + +// forward declarations +class DuiAssemblyPrivate; +class DuiWidgetController; +class DuiStyleSheet; +class DuiLogicalValues; + +/*! + \class DuiAssembly + \brief This class provides the assembly information to DuiTheme which uses it to load the correct .css & .conf files. + */ +class DUI_EXPORT DuiAssembly +{ + DuiAssemblyPrivate *const d_ptr; +public: + + /*! + \brief Constructs the DuiAssembly object. + */ + DuiAssembly(const QString &assemblyName); + + /*! + \brief Destroys the DuiAssembly object. + */ + virtual ~DuiAssembly(); + + /*! + \brief Returns the name of the assembly. + */ + QString name() const; + + /*! + \brief Returns view type for widget. + */ + QString viewType(const DuiWidgetController *widget, bool &exactMatch) const; + + /*! + \brief Returns stylesheet for this assembly. + */ + DuiStyleSheet *stylesheet() const; + + /*! + \brief Reloads all theme-related data + */ + void themeChanged(const QStringList &themeInheritance, const DuiLogicalValues &logicalValues); +}; + +#endif diff --git a/src/core/duiassembly_p.h b/src/core/duiassembly_p.h new file mode 100644 index 000000000..2bf3ec36d --- /dev/null +++ b/src/core/duiassembly_p.h @@ -0,0 +1,42 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIASSEMBLY_P_H +#define DUIASSEMBLY_P_H + +#include +#include "duistylesheet.h" + +class DuiWidgetController; +class DuiLogicalValues; + +class DuiAssemblyPrivate +{ +public: + + QString name; + QHash viewConfiguration; + DuiStyleSheet *stylesheet; + + bool loadViewConfiguration(const QStringList &themeInheritance); + void loadStylesheet(const QString &stylesheet, const DuiLogicalValues &logicalValues); + void loadStylesheets(const QStringList &themeInheritance, const DuiLogicalValues &logicalValues); +}; + +#endif diff --git a/src/core/duiclassfactory.cpp b/src/core/duiclassfactory.cpp new file mode 100644 index 000000000..b7494ef4e --- /dev/null +++ b/src/core/duiclassfactory.cpp @@ -0,0 +1,262 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiclassfactory.h" +#include "duiviewcreator.h" +#include "duistylecreator.h" +#include "duiwidgetcreator.h" +#include "duianimationcreator.h" + +#include +#include +#include + +static const QString NULL_STRING; + +class DuiClassFactoryPrivate +{ +public: + QMap widgetCreators; + QMap viewCreators; + QMap styleCreators; + QMap animationCreators; +}; + +DuiClassFactory::DuiClassFactory() : + d_ptr(new DuiClassFactoryPrivate) +{ +} + +DuiClassFactory::~DuiClassFactory() +{ + delete d_ptr; +} + +DuiClassFactory *DuiClassFactory::instance() +{ + static DuiClassFactory gFactory; + return &gFactory; +} + +//////////// +// Widget // +//////////// +void DuiClassFactory::registerWidgetCreator(DuiWidgetCreatorBase *creator, const char *widgetClassName) +{ + QString type(widgetClassName); + if (type.isEmpty()) + qFatal("DuiClassFactory cannot register DuiWidgetCreator with empty type identifier"); + + if (d_ptr->widgetCreators.contains(type)) { + qWarning("DuiClassFactory already contains DuiWidgetCreator for %s", widgetClassName); + } else { + d_ptr->widgetCreators.insert(type, creator); + } +} + +void DuiClassFactory::unregisterWidgetCreator(DuiWidgetCreatorBase *creator) +{ + QString widgetClassName = d_ptr->widgetCreators.key(creator); + if (widgetClassName.isEmpty()) { + qWarning("DuiClassFactory cannot unregister DuiWidgetCreator which is not registered"); + } else { + d_ptr->widgetCreators.remove(widgetClassName); + } +} + +QString DuiClassFactory::widgetAssemblyName(const QString &widgetClassName) const +{ + const DuiWidgetCreatorBase *widgetCreator = d_ptr->widgetCreators.value(widgetClassName, NULL); + if (!widgetCreator) { + duiWarning("DuiClassFactory") << "could not find assembly name for" << widgetClassName; + return NULL_STRING; + } + return widgetCreator->assemblyName(); +} + +Dui::AssemblyType DuiClassFactory::widgetAssemblyType(const QString &widgetClassName) const +{ + const DuiWidgetCreatorBase *widgetCreator = d_ptr->widgetCreators.value(widgetClassName, NULL); + if (!widgetCreator) { + duiWarning("DuiClassFactory") << "could not find assembly type for" << widgetClassName; + return (Dui::AssemblyType) - 1; + } + return widgetCreator->assemblyType(); +} + +////////// +// View // +////////// +void DuiClassFactory::registerViewCreator(DuiViewCreatorBase *creator, const char *viewClassName) +{ + QString type(viewClassName); + if (type.isEmpty()) + qFatal("DuiClassFactory cannot register DuiViewCreator with empty type identifier"); + + if (d_ptr->viewCreators.contains(type)) { + qWarning("DuiClassFactory already contains DuiViewCreator for %s", viewClassName); + } else { + d_ptr->viewCreators.insert(type, creator); + } +} + +void DuiClassFactory::unregisterViewCreator(DuiViewCreatorBase *creator) +{ + QString viewClassName = d_ptr->viewCreators.key(creator); + if (viewClassName.isEmpty()) { + qWarning("DuiClassFactory cannot unregister DuiViewCreator which is not registered"); + } else { + d_ptr->viewCreators.remove(viewClassName); + } +} + +DuiWidgetView *DuiClassFactory::createView(const char *viewClassName, const DuiWidgetController *controller) const +{ + const DuiViewCreatorBase *viewCreator = d_ptr->viewCreators.value(QString(viewClassName), NULL); + if (!viewCreator) { + duiWarning("DuiClassFactory") << "could not create" << viewClassName; + return NULL; + } + return viewCreator->create(controller); +} + +const char *DuiClassFactory::viewStyleType(const char *viewClassName) const +{ + const DuiViewCreatorBase *viewCreator = d_ptr->viewCreators.value(QString(viewClassName), NULL); + if (!viewCreator) { + duiWarning("DuiClassFactory") << "could not find" << viewClassName; + return NULL; + } + return viewCreator->styleType(); +} + +/////////// +// Style // +/////////// +void DuiClassFactory::registerStyleCreator(DuiStyleCreatorBase *creator, const char *styleClassName) +{ + QString type(styleClassName); + if (type.isEmpty()) + qFatal("DuiClassFactory cannot register DuiStyleCreator with empty type identifier"); + + if (d_ptr->styleCreators.contains(type)) { + qWarning("DuiClassFactory already contains DuiStyleCreator for %s", styleClassName); + } else { + d_ptr->styleCreators.insert(type, creator); + } +} + +void DuiClassFactory::unregisterStyleCreator(DuiStyleCreatorBase *creator) +{ + QString styleClassName = d_ptr->styleCreators.key(creator); + if (styleClassName.isEmpty()) { + qWarning("DuiClassFactory cannot unregister DuiStyleCreator which is not registered"); + } else { + d_ptr->styleCreators.remove(styleClassName); + } +} + +DuiStyle *DuiClassFactory::createStyle(const char *styleClassName) const +{ + const DuiStyleCreatorBase *styleCreator = d_ptr->styleCreators.value(QString(styleClassName), NULL); + if (!styleCreator) { + duiWarning("DuiClassFactory") << "could not create" << styleClassName; + return NULL; + } + return styleCreator->create(); +} + +const char *DuiClassFactory::styleAttributeType(const char *styleClassName, const char *attributeName) const +{ + const DuiStyleCreatorBase *styleCreator = d_ptr->styleCreators.value(QString(styleClassName), NULL); + if (!styleCreator) { + duiWarning("DuiClassFactory") << "could not find" << styleClassName; + return NULL; + } + return styleCreator->attributeType(attributeName); +} + +const QMetaObject *DuiClassFactory::styleMetaObject(const char *styleClassName) const +{ + const DuiStyleCreatorBase *styleCreator = d_ptr->styleCreators.value(QString(styleClassName), NULL); + if (!styleCreator) { + duiWarning("DuiClassFactory") << "could not find meta object for" << styleClassName; + return NULL; + } + return styleCreator->metaObject(); +} + +QString DuiClassFactory::styleAssemblyName(const char *styleClassName) const +{ + const DuiStyleCreatorBase *styleCreator = d_ptr->styleCreators.value(QString(styleClassName), NULL); + if (!styleCreator) { + duiWarning("DuiClassFactory") << "could not find assembly name for" << styleClassName; + return NULL_STRING; + } + return styleCreator->assemblyName(); +} + +Dui::AssemblyType DuiClassFactory::styleAssemblyType(const char *styleClassName) const +{ + const DuiStyleCreatorBase *styleCreator = d_ptr->styleCreators.value(QString(styleClassName), NULL); + if (!styleCreator) { + duiWarning("DuiClassFactory") << "could not find assembly type for" << styleClassName; + return (Dui::AssemblyType) - 1; + } + return styleCreator->assemblyType(); +} + +/////////////// +// Animation // +/////////////// + +void DuiClassFactory::registerAnimationCreator(DuiAnimationCreatorBase *creator, const char *animationClassName) +{ + QString type(animationClassName); + if (type.isEmpty()) + qFatal("DuiClassFactory cannot register DuiAnimationCreator with empty type identifier"); + + if (d_ptr->animationCreators.contains(type)) { + qWarning("DuiClassFactory already contains DuiAnimationCreator for %s", animationClassName); + } else { + d_ptr->animationCreators.insert(type, creator); + } +} + +void DuiClassFactory::unregisterAnimationCreator(DuiAnimationCreatorBase *creator) +{ + QString animationClassName = d_ptr->animationCreators.key(creator); + if (animationClassName.isEmpty()) { + qWarning("DuiClassFactory cannot unregister DuiAnimationCreator which is not registered"); + } else { + d_ptr->animationCreators.remove(animationClassName); + } +} + +DuiAnimation *DuiClassFactory::createAnimation(const char *animationClassName) const +{ + const DuiAnimationCreatorBase *animationCreator = d_ptr->animationCreators.value(QString(animationClassName), NULL); + if (!animationCreator) { + duiWarning("DuiClassFactory") << "could not create" << animationClassName; + return NULL; + } + return animationCreator->create(); +} + + diff --git a/src/core/duiclassfactory.h b/src/core/duiclassfactory.h new file mode 100644 index 000000000..b22fdc3d9 --- /dev/null +++ b/src/core/duiclassfactory.h @@ -0,0 +1,181 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUICLASSFACTORY_H +#define DUICLASSFACTORY_H + +#include "duiexport.h" +#include + +// forward declarations +class DuiViewCreatorBase; +class DuiStyleCreatorBase; +class DuiWidgetCreatorBase; +class DuiAnimationCreatorBase; +class DuiWidgetView; +class DuiStyle; +class DuiAnimation; +class QMetaObject; + +class DuiWidgetController; + +// DuiClassFactory +class DUI_EXPORT DuiClassFactory +{ +public: + static DuiClassFactory *instance(); + + //////////////////// + // widget classes // + //////////////////// + /*! + Returns the name of the assembly where the given widget class was introduced. + If the widget class was not found, returns NULL. + */ + QString widgetAssemblyName(const QString &controllerClassName) const; + + /*! + Returns the type of the assembly where the given widget class was introduced. + If the widget class was not found, returns -1. + */ + Dui::AssemblyType widgetAssemblyType(const QString &widgetClassName) const; + + ////////////////// + // view classes // + ////////////////// + + /*! + Retrns a new instance of a view. Ownership is transferred to caller. + */ + DuiWidgetView *createView(const char *viewClassName, const DuiWidgetController *controller) const; + + /*! + Returns style type for a given view. + If view is not registered return value is NULL. + */ + const char *viewStyleType(const char *viewClassName) const; + + + /////////////////// + // style classes // + /////////////////// + + /*! + Returns a new instance of a style. Ownership is transferred to caller. + */ + DuiStyle *createStyle(const char *styleClassName) const; + + /*! + Returns the type name of given attribute. + If attribute was not found from given styleClassName, returns NULL. + */ + const char *styleAttributeType(const char *styleClassName, const char *attributeName) const; + + /*! + Returns the meta object of given class type. + If meta object was not found, returns NULL. + */ + const QMetaObject *styleMetaObject(const char *styleClassName) const; + + /*! + Returns the name of the assembly where the given style class was introduced. + If the style class was not found, returns NULL. + */ + QString styleAssemblyName(const char *styleClassName) const; + + /*! + Returns the type of the assembly where the given style class was introduced. + If the style class was not found, returns -1. + */ + Dui::AssemblyType styleAssemblyType(const char *styleClassName) const; + + /////////////////////// + // animation classes // + /////////////////////// + + /*! + Returns a new instance of an animation. Ownership is transferred to caller. + */ + DuiAnimation *createAnimation(const char *animationClassName) const; + +private: + ///////// + // widgets + friend class DuiWidgetCreatorBase; + /*! + Registers a new widget creator for this factory. This method gets called automatically + from DuiWidgetCreatorBase constructor and should not be called from anywhere else. + */ + void registerWidgetCreator(DuiWidgetCreatorBase *widgetCreator, const char *widgetClassName); + /*! + Unregisters a widget creator from this factory. This method gets called automatically + from DuiWidgetCreatorBase destructor and should not be called from anywhere else. + */ + void unregisterWidgetCreator(DuiWidgetCreatorBase *widgetCreator); + + ///////// + // views + friend class DuiViewCreatorBase; + /*! + Registers a new view creator for this factory. This method gets called automatically + from DuiViewCreatorBase constructor and should not be called from anywhere else. + */ + void registerViewCreator(DuiViewCreatorBase *viewCreator, const char *viewClassName); + /*! + Unregisters a view creator from this factory. This method gets called automatically + from DuiViewCreatorBase destructor and should not be called from anywhere else. + */ + void unregisterViewCreator(DuiViewCreatorBase *viewCreator); + + ////////// + // styles + friend class DuiStyleCreatorBase; + /*! + Registers a new style creator for this factory. This method gets called automatically + from DuiStyleCreatorBase constructor and should not be called from anywhere else. + */ + void registerStyleCreator(DuiStyleCreatorBase *styleCreator, const char *styleClassName); + /*! + Unregisters a style creator from this factory. This method gets called automatically + from DuiStyleCreatorBase destructor and should not be called from anywhere else. + */ + void unregisterStyleCreator(DuiStyleCreatorBase *styleCreator); + + ////////////// + // animations + friend class DuiAnimationCreatorBase; + /*! + Registers a new animation creator for this factory. This method gets called automatically + from DuiAnimationCreatorBase constructor and should not be called from anywhere else. + */ + void registerAnimationCreator(DuiAnimationCreatorBase *animationCreator, const char *animationClassName); + /*! + Unregisters a animation creator from this factory. This method gets called automatically + from DuiAnimationCreatorBase destructor and should not be called from anywhere else. + */ + void unregisterAnimationCreator(DuiAnimationCreatorBase *animationCreator); + +private: + DuiClassFactory(); + ~DuiClassFactory(); + class DuiClassFactoryPrivate *d_ptr; +}; + +#endif + diff --git a/src/core/duicomponentdata.cpp b/src/core/duicomponentdata.cpp new file mode 100644 index 000000000..5f6df3fe7 --- /dev/null +++ b/src/core/duicomponentdata.cpp @@ -0,0 +1,827 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +#include "duiinputmethodstate.h" +#include "duitheme.h" +#include "duicomponentdata.h" +#include "duiscenemanager.h" +#include "duideviceprofile.h" +#include "duilocale.h" +#include "duifeedbackplayer.h" +#include "duifeedbackplayer_p.h" +#include "duiapplicationifproxy.h" +#include "duiapplicationifadaptor.h" +#include "duiapplicationservice.h" +#include "duicomponentdata_p.h" +#include "duiwindow.h" +#include "duiapplicationwindow.h" +#include + +#ifdef TESTABLE +/// for testability plugin +#include +#include +#include +#include "testabilityinterface.h" +// end testability +#endif + + +namespace +{ + QStringList g_debug_prefixes; + bool g_has_debug_whitelist(false); + bool g_has_debug_blacklist(false); + QtMsgType g_debug_level(QtCriticalMsg); + bool g_loadDuiInputContext(true); + FILE *debugingOutput; +} + + +bool duiRedirectOutput(const QString &filename) +{ + if (debugingOutput) { + fclose(debugingOutput); + } + + debugingOutput = fopen(filename.toUtf8(), "w"); + return debugingOutput != 0; +} + +void duiMessageHandler(QtMsgType type, const char *msg) +{ + if (type < g_debug_level) + return; + + if (type == QtDebugMsg || type == QtWarningMsg) { + if (g_has_debug_whitelist) { + QString msg_string(msg); + bool passed(false); + + foreach(const QString & prefix, g_debug_prefixes) { + if (msg_string.startsWith(prefix)) { + passed = true; + break; + } + } + + if (!passed) + return; + } else if (g_has_debug_blacklist) { // black list + QString msg_string(msg); + foreach(const QString & prefix, g_debug_prefixes) { + if (msg_string.startsWith(prefix)) + return; + } + } + } + + FILE *out = debugingOutput; + if (!out) { + out = stderr; + } + fprintf(out, "%s\n", msg); + if (type == QtFatalMsg) + abort(); +} + +DuiComponentData *DuiComponentData::self = 0; + +DuiComponentDataPrivate::DuiComponentDataPrivate() + : +#ifdef QT_OPENGL_LIB + softwareRendering(false), +#else + softwareRendering(true), +#endif + fullScreen(false), + showBoundingRect(false), + showSize(false), + showPosition(false), + showMargins(false), + showObjectNames(false), + showFps(false), +#ifdef __arm__ + showCursor(false), +#else + showCursor(true), +#endif + reverseLayout(false), + prestarted(false), + prestartMode(Dui::NoPrestart), + theme(0), + deviceProfile(0), + feedbackPlayer(0), + deviceName(0), + service(0) + +#ifdef TESTABLE + , + testabilityInterface(0) +#endif +{ + +#ifdef TESTABLE + // Activate testability plugin if exists + QString testabilityPluginPostfix = ".so"; + QString testabilityPlugin = "testability/libtestability"; + + testabilityPlugin = QLibraryInfo::location(QLibraryInfo::PluginsPath) + QDir::separator() + testabilityPlugin + testabilityPluginPostfix; + QPluginLoader loader(testabilityPlugin.toLatin1().data()); + + QObject *plugin = loader.instance(); + if (plugin) { + duiDebug("DuiComponentData") << "Testability plugin loaded successfully!"; + testabilityInterface = qobject_cast(plugin); + + if (testabilityInterface) { + duiDebug("DuiComponentData") << "Testability interface obtained!"; + testabilityInterface->Initialize(); + } else { + duiDebug("DuiComponentData") << "Failed to get testability interface!"; + } + } else { + duiDebug("DuiComponentData") << QString("Testability plugin %1 load failed with error: %2") + .arg(testabilityPlugin).arg(loader.errorString()); + } +//end testability +#endif +} + +DuiComponentDataPrivate::~DuiComponentDataPrivate() +{ +#ifdef TESTABLE + //remove the testability plugin if it exists + //makes sure that all resources used by the plugin + //are free when the application exits + if (testabilityInterface) { + delete testabilityInterface; + } +#endif + + delete theme; + theme = 0; + + delete feedbackPlayer; + feedbackPlayer = 0; + + delete service; + service = 0; + + delete deviceProfile; + deviceProfile = 0; +} + +void DuiComponentDataPrivate::debugInit(bool levelSet) +{ + //Command line variables override environment variables + if (!g_has_debug_whitelist && !g_has_debug_blacklist) { + // Check whether we got environment variables + QByteArray list; + list = qgetenv("DUI_OUTPUT_PREFIX"); + if (!list.isEmpty()) { + g_has_debug_whitelist = true; + } + list = qgetenv("DUI_NO_OUTPUT_PREFIX"); + if (!list.isEmpty()) { + if (g_has_debug_whitelist) { + qCritical("Error: Please export either DUI_OUTPUT_PREFIX or DUI_NO_OUTPUT_PREFIX, not both"); + exit(EXIT_FAILURE); + } + g_has_debug_blacklist = true; + } + g_debug_prefixes = QString(list).split(':'); + } + + // check environment variable for debug level if no command line overrides it + if (!levelSet) { + QByteArray level = qgetenv("DUI_OUTPUT_LEVEL"); + + if (!level.isEmpty()) { + if (level == "debug") { + g_debug_level = QtDebugMsg; + } else if (level == "warning") { + g_debug_level = QtWarningMsg; + } else if (level == "critical") { + g_debug_level = QtCriticalMsg; + } + } + } +} + +DuiComponentData *DuiComponentData::instance() +{ + return self; +} + +static DuiComponentDataPrivate *gDuiComponentDataPrivate = 0; + +DuiComponentData::DuiComponentData(int &argc, char **argv, const QString &appIdentifier, DuiApplicationService *service) + : QObject(), + d_ptr(new DuiComponentDataPrivate) +{ + Q_D(DuiComponentData); + d->q_ptr = this; + + Q_ASSERT_X(!self, "DuiComponentData", "There should be one component data object only."); + DuiComponentData::self = this; + + d->init(argc, argv, appIdentifier, service); +} + +DuiComponentData::DuiComponentData(DuiApplicationService *service) : + QObject(), + d_ptr(new DuiComponentDataPrivate) +{ + Q_D(DuiComponentData); + d->q_ptr = this; + + Q_ASSERT_X(!self, "DuiComponentData", "There should be one component data object only."); + DuiComponentData::self = this; + + int argc = 0; + char *argv = 0; + + d->init(argc, &argv, QString(), service); +} + +void DuiComponentDataPrivate::init(int &argc, char **argv, const QString &appIdentifier, DuiApplicationService *newService) +{ + Q_Q(DuiComponentData); + + gDuiComponentDataPrivate = this; + locale.connectSettings(); + QObject::connect(&locale, SIGNAL(settingsChanged()), q, SIGNAL(localeSettingsChanged())); + + // Remember if we were given the -reverse parameter + // (we have to do it this way, because the QApplication + // constructor "eats" the "-reverse" command line parameter. + // Therefore, we can not parse it here.) + reverseLayout = qApp->layoutDirection() == Qt::RightToLeft; + + DuiTheme::ThemeService themeService = DuiTheme::AnyTheme; + bool outputLevelSet = false; + + // Configure application according to switches + for (int i = 1; i < argc; ++i) { + QString s(argv[i]); + if (s == "-software") + softwareRendering = true; + else if (s == "-fullscreen") + fullScreen = true; + else if (s == "-show-br") + showBoundingRect = true; + else if (s == "-show-fps") + showFps = true; + else if (s == "-show-size") + showSize = true; + else if (s == "-show-position") + showPosition = true; + else if (s == "-show-cursor") + showCursor = true; + else if (s == "-show-object-names") + q->setShowObjectNames(true); + else if (s == "-dev") { + showSize = true; + showPosition = true; + } else if (s == "-genimglist") { + if (i < (argc - 1)) { + imglistFilename = argv[i+1]; + i++; + } + } else if (s == "-remote-theme") { + themeService = DuiTheme::RemoteTheme; + } else if (s == "-output-level") { + if (i < (argc - 1)) { + i++; + QString debugLevelString = argv[i]; + outputLevelSet = true; + + if (debugLevelString == "debug") { + g_debug_level = QtDebugMsg; + } else if (debugLevelString == "warning") { + g_debug_level = QtWarningMsg; + } else if (debugLevelString == "critical") { + g_debug_level = QtCriticalMsg; + } else { + qCritical("%s: Error: Provide one of debug, warning or error to -output-level", + argv[0]); + exit(EXIT_FAILURE); + } + } else { + qCritical("%s: Error: Provide one of debug, warning or error to -output-level", + argv[0]); + exit(EXIT_FAILURE); + } + } else if (s == "-output-prefix" || s == "-no-output-prefix") { + if (s == "-output-prefix") + g_has_debug_whitelist = true; + else + g_has_debug_blacklist = true; + + if (g_has_debug_blacklist && g_has_debug_whitelist) { + qCritical("%s: Error: Provide either -output-prefix or -no-output-prefix, not both", + argv[0]); + exit(EXIT_FAILURE); + } + if (i < (argc - 1)) { + i++; + g_debug_prefixes << argv[i]; + } else { + qCritical("%s: Error: Provide a prefix to filter for to %s", + argv[0], argv[i]); + exit(EXIT_FAILURE); + } + } else if (s == "-output-file") { + if (i < (argc - 1)) { + i++; + + bool ok = duiRedirectOutput(argv[ i ]); + + if (! ok) { + qCritical("%s: Error: Opening of log file failed: %s", + argv[0], argv[i]); + exit(EXIT_FAILURE); + } + + } else { + qCritical("%s: Error: Please provide a log file name", + argv[0]); + exit(EXIT_FAILURE); + } + } else if (s == "-disable-dui-input-context") { + g_loadDuiInputContext = false; + } else if (s == "-target") { + if (i < (argc - 1)) { + i++; + deviceName = argv[i]; + + } else { + qCritical("%s: Error: Provide a device name to -target", + argv[0]); + exit(EXIT_FAILURE); + } + + } else if (s == "-h" || s.startsWith("-help") || s.startsWith("--help")) { + duiDebug("DuiComponentData") << "Usage: " << argv[0] << "\n" + << " [-software] Enable software rendering\n" + << " [-fullscreen] Make the application fullscreen\n" + << " [-show-br] Show the bounding rectangle for all scene items\n" + << " [-show-fps] Show the FPS for the view (only with OpenGL rendering)\n" + << " [-show-size] Show widget sizes in the scene\n" + << " [-show-object-names] Show the names of the objects in the scene\n" + << " [-show-position] Show widget positions in the scene\n" + << " [-show-cursor] Force the cursor to be visible\n" + << " [-reverse] Change the layout direction to right-to-left direction\n" + << " [-dev] Enable development visualization mode\n" + << " [-genimglist filename] Generate list of requested images to filename\n" + << " [-remote-theme] Wait until remote theme daemon is available\n" + << " [-output-level debug|warning|critical] Only show messages of given output level or above\n" + << " [-output-prefix ] Only show debug messages that start with the given prefix\n" + << " [-no-output-prefix ] Only show debug messages that do not start with the given prefix\n" + << " [-target ] Use the target device profile\n" + << " [-prestart] Prestart the application (if supported)\n" + << "\n"; + exit(0); + + } else if (s == "-prestart") { + prestarted = true; + } + } + + //Setup duiDebug() + debugInit(outputLevelSet); + + // If there was already a message handler, remove + // own message handler again. + QtMsgHandler handler(qInstallMsgHandler(duiMessageHandler)); + if (handler != 0) { + qInstallMsgHandler(handler); + } + + if (themeService == DuiTheme::RemoteTheme && !imglistFilename.isEmpty()) { + qFatal("-genimglist switch can't be used with remote theme daemon"); + } + + QFileInfo fileInfo(argv[0]); + QString themeIdentifier = fileInfo.fileName(); + if (!appIdentifier.isEmpty()) { + QRegExp regExp("[0-9a-zA-Z_-]*"); + if (regExp.exactMatch(appIdentifier)) { + themeIdentifier = appIdentifier; + } + } + theme = new DuiTheme(themeIdentifier, imglistFilename, themeService); + deviceProfile = new DuiDeviceProfile(); + + QString catalog = appIdentifier; + if (catalog.isEmpty()) + catalog = fileInfo.fileName(); + + locale.addTranslationPath(TRANSLATION_DIR); + // installs the libdui translations for the “Engineering English”: + locale.installTrCatalog("libdui.qm"); + // installs the catalog for the “Engineering English”: + locale.installTrCatalog(catalog + ".qm"); + // installs the libdui translations for the real translation: + locale.installTrCatalog("libdui"); + // installs the real translations from the common translation catalog: + locale.installTrCatalog("common"); + // installs the catalog for the real translation: + locale.installTrCatalog(catalog); + DuiLocale::setDefault(locale); + + // DuiLocale::setDefault(locale) also sets the + // layoutDirection(). This overrides the effects of the -reverse + // command line switch. Therefore, if the -reverse command line switch + // was used, we have to set the RTL direction again here: + if (reverseLayout) + qApp->setLayoutDirection(Qt::RightToLeft); + + // set the input context + if (g_loadDuiInputContext == true) { + // QApplication::setInputContext takes ownership of this input context, + // but it does not call setParent( qApp ); on the input context yet. + // a bug for this is filed to qt software. + QInputContext *ic = QInputContextFactory::create("DuiInputContext", 0); + + if (ic != 0) { + qApp->setInputContext(ic); + } + } + + feedbackPlayer = new DuiFeedbackPlayer(); + if (!feedbackPlayer->d_ptr->init(themeIdentifier)) { + delete feedbackPlayer; + feedbackPlayer = 0; + } + + // register dbus service + appName = themeIdentifier; + binaryName = argv[0]; + + //appName cannot begin with number + if (appName[0].isDigit()) { + qFatal("DuiComponentData - application identifier must not begin with a digit."); + } + +#ifdef HAVE_DBUS + // here we check for a working dbus session bus and give a big + // fat error message when it does not exist. + + QDBusConnection connection = QDBusConnection::sessionBus(); + + if (connection.isConnected() == false) { + qFatal("ERROR: No DBUS session bus found. Exiting now. Please make sure that a dbus session bus\n" + "is running. In Scratchbox you should execute dui-sb-session start. On the target device\n" + "it should already be running. You should also make sure that the DBUS_SESSION_BUS_ADDRESS\n" + "environment variable is set correctly. For that you can execute the following command:\n" + "source /tmp/session_bus_address.user\n"); + + qApp->exit(-1); + } + + + if (newService == 0) { + QString serviceName = "com.nokia." + appName; + duiDebug("DuiComponentData") << "creating DuiComponentDataService with name:" << serviceName; + service = new DuiApplicationService(serviceName); + } else { + service = newService; + } + + service->registerService(); +#else + Q_UNUSED(newService); +#endif + + q->setShowCursor(showCursor); +} + +DuiComponentData::~DuiComponentData() +{ + delete d_ptr; + gDuiComponentDataPrivate = 0; + self = 0; +} + +QString DuiComponentData::deviceName() +{ + if (!gDuiComponentDataPrivate) { + qFatal("DuiComponentData::deviceName() - DuiComponentData instance not yet created."); + } + return gDuiComponentDataPrivate->deviceName; +} + +bool DuiComponentData::softwareRendering() +{ + if (!gDuiComponentDataPrivate) { + qFatal("DuiComponentData::softwareRendering() - DuiComponentData instance not yet created."); + } + return gDuiComponentDataPrivate->softwareRendering; +} + +bool DuiComponentData::fullScreen() +{ + if (!gDuiComponentDataPrivate) { + qFatal("DuiComponentData::fullScreen() - DuiComponentData instance not yet created."); + } + return gDuiComponentDataPrivate->fullScreen; +} + +bool DuiComponentData::prestarted() +{ + if (!gDuiComponentDataPrivate) { + qFatal("DuiComponentData::prestarted() - DuiComponentData instance not yet created."); + } + return gDuiComponentDataPrivate->prestarted; +} + +Dui::PrestartMode DuiComponentData::prestartMode() +{ + if (!gDuiComponentDataPrivate) { + qFatal("DuiComponentData::prestartMode() - DuiComponentData instance not yet created."); + } + return gDuiComponentDataPrivate->prestartMode; +} + +bool DuiComponentData::showBoundingRect() +{ + if (!gDuiComponentDataPrivate) { + qFatal("DuiComponentData::showBoundingRect() - DuiComponentData instance not yet created."); + } + return gDuiComponentDataPrivate->showBoundingRect; +} + +bool DuiComponentData::showFps() +{ + if (!gDuiComponentDataPrivate) { + qFatal("DuiComponentData::showFps() - DuiComponentData instance not yet created."); + } + return gDuiComponentDataPrivate->showFps; +} + +bool DuiComponentData::showSize() +{ + if (!gDuiComponentDataPrivate) { + qFatal("DuiComponentData::showSizes() - DuiComponentData instance not yet created."); + } + return gDuiComponentDataPrivate->showSize; +} + +bool DuiComponentData::showPosition() +{ + if (!gDuiComponentDataPrivate) { + qFatal("DuiComponentData::showPositions() - DuiComponentData instance not yet created."); + } + return gDuiComponentDataPrivate->showPosition; +} + +bool DuiComponentData::showMargins() +{ + if (!gDuiComponentDataPrivate) { + qFatal("DuiComponentData::showMargins() - DuiComponentData instance not yet created."); + } + return gDuiComponentDataPrivate->showMargins; +} + +bool DuiComponentData::showObjectNames() +{ + if (!gDuiComponentDataPrivate) { + qFatal("DuiComponentData::showObject() - DuiComponentData instance not yet created."); + } + return gDuiComponentDataPrivate->showObjectNames; +} + +bool DuiComponentData::showCursor() +{ + if (!gDuiComponentDataPrivate) { + qFatal("DuiComponentData::showCursor() - DuiComponentData instance not yet created."); + } + return gDuiComponentDataPrivate->showCursor; +} + +void DuiComponentData::setShowPosition(bool show) +{ + if (!gDuiComponentDataPrivate) { + qFatal("DuiComponentData::setPositions() - DuiComponentData instance not yet created."); + } + gDuiComponentDataPrivate->showPosition = show; +} + +void DuiComponentData::setShowSize(bool show) +{ + if (!gDuiComponentDataPrivate) { + qFatal("DuiComponentData::setPositions() - DuiComponentData instance not yet created."); + } + gDuiComponentDataPrivate->showSize = show; +} + +void DuiComponentData::setShowMargins(bool show) +{ + if (!gDuiComponentDataPrivate) { + qFatal("DuiComponentData::setMargins() - DuiComponentData instance not yet created."); + } + gDuiComponentDataPrivate->showMargins = show; +} + +void DuiComponentData::setShowObjectNames(bool show) +{ + if (!gDuiComponentDataPrivate) { + qFatal("DuiComponentData::setShowObjectNames() - DuiComponentData instance not yet created."); + } + gDuiComponentDataPrivate->showObjectNames = show; +} + +void DuiComponentData::setShowBoundingRect(bool show) +{ + if (!gDuiComponentDataPrivate) { + qFatal("DuiComponentData::setShowBoundingRect() - DuiComponentData instance not yet created."); + } + gDuiComponentDataPrivate->showBoundingRect = show; +} + +void DuiComponentData::setShowFps(bool show) +{ + if (!gDuiComponentDataPrivate) { + qFatal("DuiComponentData::setShowFps() - DuiComponentData instance not yet created."); + } + gDuiComponentDataPrivate->showFps = show; +} + +void DuiComponentData::setShowCursor(bool show) +{ + if (!gDuiComponentDataPrivate) { + qFatal("DuiComponentData::setShowCursor() - DuiComponentData instance not yet created."); + } + + if (show) { + qApp->restoreOverrideCursor(); + } else { + QPixmap cursor(QSize(1, 1)); + cursor.fill(Qt::transparent); + qApp->setOverrideCursor(cursor); + } + + gDuiComponentDataPrivate->showCursor = show; +} + + +void DuiComponentData::setPrestarted(bool flag) +{ + if (!gDuiComponentDataPrivate) { + qFatal("DuiComponentData::setPrestarted() - DuiComponentData instance not yet created."); + } + gDuiComponentDataPrivate->prestarted = flag; +} + +void DuiComponentData::setPrestartMode(Dui::PrestartMode mode) +{ + if (!gDuiComponentDataPrivate) { + qFatal("DuiComponentData::setPrestartMode() - DuiComponentData instance not yet created."); + } + gDuiComponentDataPrivate->prestartMode = mode; +} + +QList DuiComponentData::windows() +{ + if (!gDuiComponentDataPrivate) { + qFatal("DuiComponentData::windows() - DuiComponentData instance not yet created."); + } + return gDuiComponentDataPrivate->windows; +} + +DuiWindow *DuiComponentData::activeWindow() +{ + if (!gDuiComponentDataPrivate) { + qFatal("DuiComponentData::activeWindow() - DuiComponentData instance not yet created."); + } + + if (gDuiComponentDataPrivate->windows.isEmpty()) + return 0; + + return gDuiComponentDataPrivate->windows.first(); +} + +DuiApplicationWindow *DuiComponentData::activeApplicationWindow() +{ + if (!gDuiComponentDataPrivate) { + qFatal("DuiComponentData::activeApplicationWindow() - DuiComponentData instance not yet created."); + } + + return qobject_cast(activeWindow()); +} + +void DuiComponentData::setActiveWindow(DuiWindow *w) +{ + if (!gDuiComponentDataPrivate) { + qFatal("DuiComponentData::setActiveWindow() - DuiComponentData instance not yet created."); + } + DuiWindow *activeWindow = DuiComponentData::activeWindow(); + if (activeWindow) { + QObject::disconnect(activeWindow, + SIGNAL(orientationAngleChanged(Dui::OrientationAngle)), + DuiInputMethodState::instance(), + SLOT(setActiveWindowOrientationAngle(Dui::OrientationAngle))); + } + if (w) { + QObject::connect(w, SIGNAL(orientationAngleChanged(Dui::OrientationAngle)), + DuiInputMethodState::instance(), + SLOT(setActiveWindowOrientationAngle(Dui::OrientationAngle))); + DuiInputMethodState::instance()->setActiveWindowOrientationAngle(w->orientationAngle()); + } + int oldIndex = gDuiComponentDataPrivate->windows.indexOf(w); + + if (oldIndex == -1) + duiWarning("DuiComponentData::setActiveWindow()") << "attempting to activate unregistered window"; + else + gDuiComponentDataPrivate->windows.move(oldIndex, 0); +} + +void DuiComponentData::registerWindow(DuiWindow *w) +{ + if (!gDuiComponentDataPrivate) { + qFatal("DuiComponentData::registerWindow() - DuiComponentData instance not yet created."); + } + if (!gDuiComponentDataPrivate->windows.contains(w)) + gDuiComponentDataPrivate->windows.append(w); +} + +void DuiComponentData::unregisterWindow(DuiWindow *w) +{ + if (!gDuiComponentDataPrivate) { + qFatal("DuiComponentData::unregisterWindow() - DuiComponentData instance not yet created."); + } + gDuiComponentDataPrivate->windows.removeAll(w); +} + +DuiFeedbackPlayer *DuiComponentData::feedbackPlayer() +{ + if (!gDuiComponentDataPrivate) { + qFatal("DuiComponentData::feedbackPlayer() - DuiComponentData instance not yet created."); + } + return gDuiComponentDataPrivate->feedbackPlayer; +} + + +bool DuiComponentData::isLoadDuiInputContextEnabled() +{ + return g_loadDuiInputContext; +} + + +void DuiComponentData::setLoadDuiInputContext(bool enable) +{ + g_loadDuiInputContext = enable; +} + +QString DuiComponentData::appName() +{ + if (!gDuiComponentDataPrivate) { + qFatal("DuiComponentData::appName() - DuiComponentData instance not yet created."); + } + return gDuiComponentDataPrivate->appName; +} + +QString DuiComponentData::binaryName() +{ + if (!gDuiComponentDataPrivate) { + qFatal("DuiComponentData::binaryName() - DuiComponentData instance not yet created."); + } + return gDuiComponentDataPrivate->binaryName; +} + +QString DuiComponentData::serviceName() +{ + if (!gDuiComponentDataPrivate) { + qFatal("DuiComponentData::serviceName() - DuiComponentData instance not yet created."); + } else if (!gDuiComponentDataPrivate->service) { + qFatal("DuiComponentData::serviceName() - DuiComponentData->service not yet created."); + } + + return gDuiComponentDataPrivate->service->registeredName(); +} diff --git a/src/core/duicomponentdata.h b/src/core/duicomponentdata.h new file mode 100644 index 000000000..d25237ef0 --- /dev/null +++ b/src/core/duicomponentdata.h @@ -0,0 +1,192 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUICOMPONENTDATA_H +#define DUICOMPONENTDATA_H + +#include + +#include "duiexport.h" +#include "duinamespace.h" + +class DuiComponentDataPrivate; +class DuiWindow; +class DuiApplicationWindow; +class DuiApplicationService; +class DuiFeedbackPlayer; + +/*! + * \class DuiComponentData + * \brief DuiComponentData manages the GUI application's control flow and main settings. + * + * DuiComponentData provides all the settings that are necessary for a QApplication in + * order to initialize the DUI framework. As such it is used by DuiApplication. + * which adds the event loop. DuiComponentData can be used by plain Qt applications + * in order to provide access to resources of the DUI framework. + * + * DuiComponentData instance automatically extracts application name from the arguments + * given in the constructor. It also loads css - stylesheet, svg file and adds application + * specific image paths to the pixmap search paths used by the current DuiTheme instance. + * + * CSS and SVG files are searched for in order from the following places: + *
    + *
  1. Directory in which application was launched.
  2. + *
  3. Application specific theme path (global theme path appended with the application name)
  4. + *
  5. Global theme path (Qt data path appended by themes/dui)
  6. + *
+ * When first instance of CSS or SVG file is found it is loaded to the current DuiTheme. + * Also image - subdirectory of each of the aforementioned paths is appended to the pixmap search + * paths used by DuiTheme. + * + * DuiComponentData will also create a QDBus service with name made by prepending 'com.nokia.' to + * the application name provided in the constructor (or the binary name if no name is provided + * in the constructor). It will provide an interface called DuiComponentDataIf which calls service + * methods in an instance of DuiApplicationService. By default, DuiComponentData will construct an + * instance of DuiApplicationService, but the application programmer can derive a class from + * DuiApplicationService and provide a pointer to that in the constructor for DuiComponentData to + * use instead. This way, the application programmer can override the methods in + * DuiComponentDataSerivce and change the behaviour of the application's interface. + * + * For some applications, it is necessary to implement a custom DuiApplicationService. See + * DuiApplicationService for more information. + * + */ + +class DUI_EXPORT DuiComponentData : public QObject +{ + Q_OBJECT + +public: + //! Initializes the window system and constructs an application object. + /*! + * \param argc number of arguments passed to the application from the command line + * \param argv argument strings passed to the application from the command line + * \param appIdentifier an optional identifier for the application. Can + * contain alphabetical characters, numbers, dashes and underscores. If + * an empty string is given (the default) the application binary file + * name is used. + */ + DuiComponentData(int &argc, char **argv, const QString &appIdentifier = QString(), DuiApplicationService *service = 0); + explicit DuiComponentData(DuiApplicationService *service); + + //! Cleans up any window system resources that were allocated by this application. + virtual ~DuiComponentData(); + + //! returns the DuiComponentData instance + static DuiComponentData *instance(); + + //! Target device name + static QString deviceName(); + //! Software rendering command line option set + static bool softwareRendering(); + //! Full screen command line option set + static bool fullScreen(); + //! Show bounding rectangles command line option set + static bool showBoundingRect(); + //! Show frame rate command line option set + static bool showFps(); + //! Show widgets sizes + static bool showSize(); + //! Show widgets positions + static bool showPosition(); + //! Show widgets margins + static bool showMargins(); + //! Show object names + static bool showObjectNames(); + //! Show cursor + static bool showCursor(); + //! Return true if prestarted state active + static bool prestarted(); + //! Returns the prestart mode + static Dui::PrestartMode prestartMode(); + //! Sets if position of widgets should be shown or not + static void setShowPosition(bool show); + //! Sets if margins of widgets should be shown or not + static void setShowMargins(bool show); + //! Sets if names of objects should be shown or not + static void setShowObjectNames(bool show); + //! Sets if sizes of widgets should be shown or not + static void setShowSize(bool show); + //! Sets if bounding rects of widgets should be shown or not + static void setShowBoundingRect(bool show); + //! Sets if a frames-per-second counter should be shown or not + static void setShowFps(bool show); + //! Sets if the cursor should be shown or not + static void setShowCursor(bool show); + //! Sets the prestarted flag + static void setPrestarted(bool flag); + //! Sets the prestart mode + static void setPrestartMode(Dui::PrestartMode mode); + + /*! + * Returns the currently active application window. + * \note If the active window is of type DuiWindow (and not DuiApplicationWindow) + * this method will return a null pointer. + * \sa activeWindow() + */ + static DuiApplicationWindow *activeApplicationWindow(); + //! Returns the currently active window + static DuiWindow *activeWindow(); + //! Returns a list of all windows in the application + static QList windows(); + + //! Returns the application's app name + static QString appName(); + //! Returns the application's binary name + static QString binaryName(); + //! Returns the application's service name + static QString serviceName(); + + //! Returns object which provide interface for nonvisual feedback or NULL + static DuiFeedbackPlayer *feedbackPlayer(); + + //! Returns whether automatic loading of DuiInputContext is enabled + static bool isLoadDuiInputContextEnabled(); + + //! Sets whether DuiComponentData should automatically load dui input context + static void setLoadDuiInputContext(bool enable); + +Q_SIGNALS: + /*! + * This signal is emitted when there is a change in any of the locale + * settings (language, country, script, and variant) + */ + void localeSettingsChanged(); + +protected: + DuiComponentData(DuiComponentDataPrivate &dd, int &argc, char **argv, const QString &appIdentifier = QString()); + DuiComponentDataPrivate *const d_ptr; + +private: + static DuiComponentData *self; + static void registerWindow(DuiWindow *); + static void unregisterWindow(DuiWindow *); + static void setActiveWindow(DuiWindow *); + + Q_DECLARE_PRIVATE(DuiComponentData) + Q_DISABLE_COPY(DuiComponentData) + + friend class DuiWindow; + friend class DuiApplicationWindow; + friend class DuiSceneWindow; + friend class DuiTheme; + friend class DuiDeviceProfile; +}; + +#endif diff --git a/src/core/duicomponentdata_p.h b/src/core/duicomponentdata_p.h new file mode 100644 index 000000000..95125c6fb --- /dev/null +++ b/src/core/duicomponentdata_p.h @@ -0,0 +1,83 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUICOMPONENTDATA_P_H +#define DUICOMPONENTDATA_P_H + +#include +#include +#ifdef Q_WS_X11 +#include +#endif + +class DuiTheme; +class DuiComponentData; +class DuiFeedbackPlayer; +class DuiApplicationService; +class DuiWindow; +class DuiApplicationWindow; +class DuiDeviceProfile; +#ifdef TESTABLE +class TestabilityInterface; +#endif + +class DuiComponentDataPrivate +{ + Q_DECLARE_PUBLIC(DuiComponentData) + +public: + DuiComponentDataPrivate(); + virtual ~DuiComponentDataPrivate(); + + bool softwareRendering; + bool fullScreen; + bool showBoundingRect; + bool showSize; + bool showPosition; + bool showMargins; + bool showObjectNames; + bool showFps; + bool showCursor; + bool reverseLayout; + bool prestarted; + Dui::PrestartMode prestartMode; + DuiTheme *theme; + DuiDeviceProfile *deviceProfile; + QList windows; + DuiFeedbackPlayer *feedbackPlayer; + DuiLocale locale; + QString imglistFilename; + QString appName; + QString binaryName; + QString deviceName; + DuiApplicationService *service; +#ifdef TESTABLE + // member to hold reference to the testability plugin in order to destroy plugin when the application is destructed + TestabilityInterface *testabilityInterface; +#endif + +protected: + DuiComponentData *q_ptr; +private: + void init(int &argc, char **argv, const QString &appIdentifier, DuiApplicationService *service); + void debugInit(bool levelSet); +}; + + +#endif diff --git a/src/core/duicpumonitor.cpp b/src/core/duicpumonitor.cpp new file mode 100644 index 000000000..a840dfbc3 --- /dev/null +++ b/src/core/duicpumonitor.cpp @@ -0,0 +1,155 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include +#include + +#include "duicpumonitor.h" + + +class DuiCpuMonitorPrivate +{ +public: + QTimer timer; + + bool usable; + int lastFrameUsage; + +#ifdef __linux__ + unsigned long jiffies_total; + unsigned long jiffies_idle; + + void getCpuUsageInformation(unsigned long &total, unsigned long &idle); +#endif +}; + + +DuiCpuMonitor::DuiCpuMonitor() : d_ptr(new DuiCpuMonitorPrivate) +{ + Q_D(DuiCpuMonitor); + + d->usable = false; + +#ifdef __linux__ + d->getCpuUsageInformation(d->jiffies_total, d->jiffies_idle); +#endif + + connect(&d->timer, SIGNAL(timeout()), SLOT(timedOut())); +} + +DuiCpuMonitor::~DuiCpuMonitor() +{ + Q_D(DuiCpuMonitor); + + d->timer.stop(); + + delete d_ptr; +} + + +int DuiCpuMonitor::usage() +{ + Q_D(DuiCpuMonitor); + + if (!d->usable) + return -1; + + return d->lastFrameUsage; +} + + +void DuiCpuMonitor::start(unsigned msec) +{ + Q_D(DuiCpuMonitor); + + d->timer.start(msec); +} + +void DuiCpuMonitor::stop() +{ + Q_D(DuiCpuMonitor); + + d->timer.stop(); +} + + +void DuiCpuMonitor::timedOut() +{ +#ifdef __linux__ + Q_D(DuiCpuMonitor); + + unsigned long n_tot = 0; + unsigned long n_idle = 0; + + d->getCpuUsageInformation(n_tot, n_idle); + + if (n_tot - d->jiffies_total) { + d->lastFrameUsage = 100 - 100 * (n_idle - d->jiffies_idle) / (n_tot - d->jiffies_total); + d->usable = true; + + emit newCpuFrameAvailable(); + + d->jiffies_idle = n_idle; + d->jiffies_total = n_tot; + } +#endif +} + + +#ifdef __linux__ +void DuiCpuMonitorPrivate::getCpuUsageInformation(unsigned long &total, unsigned long &idle) +{ + QFile statFile("/proc/stat"); + + if (statFile.exists() && statFile.open(QIODevice::ReadOnly)) { + char buf[256]; + QStringList l; + unsigned long sum = 0; + unsigned long tmp; + + statFile.readLine(buf, 256); + l = QString::fromAscii(buf).split(' '); + + int idx = 0; + QStringList::const_iterator end = l.constEnd(); + for (QStringList::const_iterator i = l.constBegin(); i != end; ++i) { + if (!i->isEmpty()) { + if (idx) { + bool success = true; + + tmp = i->toULong(&success); + if (success) { + sum += tmp; + + if (idx == 4) + idle = tmp; + } + } + + idx++; + } + } + + total = sum; + } +} +#endif + diff --git a/src/core/duicpumonitor.h b/src/core/duicpumonitor.h new file mode 100644 index 000000000..f60abdbee --- /dev/null +++ b/src/core/duicpumonitor.h @@ -0,0 +1,82 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUICPUMONITOR_H +#define DUICPUMONITOR_H + + +#include + + +class DuiCpuMonitorPrivate; + + +/*! + * Utility class to monitor CPU usage on system + * + * Gets frame every timeout and has function to get usage for last frame. The + * timer must be started in order to get frames. + */ +class DuiCpuMonitor : public QObject +{ + Q_OBJECT + +public: + DuiCpuMonitor(); + ~DuiCpuMonitor(); + + /*! + * Gets CPU usage for last frame. + * + * \return CPU usage for last frame in %. If there is no data avaialble + * yet, -1 is returned. + */ + int usage(); + +public Q_SLOTS: + /*! + * Starts the timer. Each time timer times out, new CPU frame becomes + * available and newCpuFrameAvailable signal is emitted. + * + * \param msec Timeout in milliseconds. + */ + void start(unsigned msec); + + /*! + * Stops the timer. CPU usage frames will be no longer read. + */ + void stop(); + +Q_SIGNALS: + /*! + * Emitted when there is new CPU frame available. + */ + void newCpuFrameAvailable(); + +private Q_SLOTS: + void timedOut(); + +private: + DuiCpuMonitorPrivate *const d_ptr; + Q_DECLARE_PRIVATE(DuiCpuMonitor) +}; + + +#endif + diff --git a/src/core/duidbusservicewaiter.cpp b/src/core/duidbusservicewaiter.cpp new file mode 100644 index 000000000..46f288319 --- /dev/null +++ b/src/core/duidbusservicewaiter.cpp @@ -0,0 +1,86 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include + +#include +#include + +#include "duidbusservicewaiter_p.h" + + +DuiDBusServiceWaiter::DuiDBusServiceWaiter(const QString &name, QObject *parent) : + QObject(parent), success(false), finished(false), serviceName(name), m_timeout(-1), isInvalid(false) +{ + QDBusConnectionInterface *iface = QDBusConnection::sessionBus().interface(); + + if (!QDBusConnection::sessionBus().isConnected() || !iface->isValid()) { + isInvalid = true; + } else { + QObject::connect(iface, SIGNAL(serviceOwnerChanged(QString, QString, QString)), + this, SLOT(serviceOwnerChanged(QString, QString, QString))); + } +} + + +bool DuiDBusServiceWaiter::waitForRegistration() +{ + if (isInvalid) + return false; + + if (QDBusConnection::sessionBus().interface()->isServiceRegistered(serviceName)) + return true; + + if (timeout() > 0) + QTimer::singleShot(timeout(), this, SLOT(serviceTimedOut())); + + while (!finished) + QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents); + + return success; +} + + +int DuiDBusServiceWaiter::timeout() const +{ + return m_timeout; +} + +void DuiDBusServiceWaiter::setTimeout(int newTimeout) +{ + m_timeout = newTimeout; +} + + +void DuiDBusServiceWaiter::serviceTimedOut() +{ + finished = true; +} + +void DuiDBusServiceWaiter::serviceOwnerChanged(const QString &name, const QString &oldOwner, const QString &newOwner) +{ + Q_UNUSED(oldOwner) + + if (name == serviceName && !newOwner.isEmpty()) { + finished = true; + success = true; + } +} + diff --git a/src/core/duidbusservicewaiter_p.h b/src/core/duidbusservicewaiter_p.h new file mode 100644 index 000000000..e0cdf961e --- /dev/null +++ b/src/core/duidbusservicewaiter_p.h @@ -0,0 +1,81 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIDBUSSERVICEWAITER_P_H +#define DUIDBUSSERVICEWAITER_P_H + + +#include + +#include + + +/*! + * A class which has functionality to wait until D-BUS service has been registered. + * + * Utility class which is intended to be used before entering QCoreApplication::exec(). The + * class has function to block until the service is registered (or timeout occurs) which is + * meant to be used right after construction. The instances of the class are intended to be + * lightweight and have short lifespan, the class itself is needed mainly for receiving + * appropriate signals. + */ +class DuiDBusServiceWaiter : public QObject +{ + Q_OBJECT + Q_PROPERTY(int timeout READ timeout WRITE setTimeout) + +public: + + /*! + * Constructor for the waiter class. + * Initializes timeout and monitoring of D-BUS service registration. + * \param name name of the D-BUS service that is going to be waited for. + * \param parent parent object. + */ + DuiDBusServiceWaiter(const QString &name, QObject *parent = 0); + + /*! + * Function which will wait until the service has been registered. If the service is + * initially registered when calling this function, the function will return immediately + * true. + * \return true if service has been registered before timeout occurs, otherwise false. + * If no connection to session bus is present, this function will return immediately + * false. + */ + bool waitForRegistration(); + + int timeout() const; + void setTimeout(int newTimeout); + +private slots: + void serviceTimedOut(); + void serviceOwnerChanged(const QString &name, const QString &oldOwner, const QString &newOwner); + +private: + bool success; + bool finished; + QString serviceName; + + int m_timeout; + + bool isInvalid; +}; + + +#endif diff --git a/src/core/duidebug.h b/src/core/duidebug.h new file mode 100644 index 000000000..61a8b8cf2 --- /dev/null +++ b/src/core/duidebug.h @@ -0,0 +1,81 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIDEBUG_H +#define DUIDEBUG_H + +#include + +/*! + * \brief Redirects all debugging output from qDebug, qWarning, qCritical and qFatal + * to specified file. + * \param filename const char* Specifies file name + * \return true if file was opened successfully + */ +bool duiRedirectOutput(const QString &filename); + +#ifdef QT_NO_DEBUG_OUTPUT +#define duiDebug(x) qDebug() +#else + +/** + * Returns an object to send debug messages to the message handler. + * Use as a replacement for qDebug. Pass the name of the module + * as QString to categorize the output. + * + * Example: + *\code + * #include + * + * duiDebug("CSS Parser") << "Reading one line"; + *\endcode + * + * The user can now decide which debug messages are visible by command line arguments to DuiApplication. + */ +inline QDebug duiDebugStream(const QString &module) +{ + // Use qPrintable around QString to avoid "" around it + return qDebug() << qPrintable(QString("%1:").arg(module)); +} + +#define duiDebug(x) duiDebugStream(x) +#endif + +#ifdef QT_NO_WARNING_OUTPUT +#define duiWarning(x) qDebug() +#else + +/** + * Returns an object to send warning messages to the message handler. + * Use as a replacement for qWarning. Pass the name of the module + * as QString to categorize the output. + * + * \sa duiDebug(const QString &) + */ +inline QDebug duiWarningStream(const QString &module) +{ + // Use qPrintable around QString to avoid "" around it + return qWarning() << qPrintable(QString("%1:").arg(module)); +} + +#define duiWarning(x) duiWarningStream(x) +#endif // QT_NO_WARNING_OUTPUT + +#endif + diff --git a/src/core/duidesktopentry.cpp b/src/core/duidesktopentry.cpp new file mode 100644 index 000000000..a13eb07a8 --- /dev/null +++ b/src/core/duidesktopentry.cpp @@ -0,0 +1,389 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include +#include +#include "duidesktopentry.h" +#include "duidesktopentry_p.h" +#include + +const QString TypeKey("Desktop Entry/Type"); +const QString VersionKey("Desktop Entry/Version"); +const QString NameKey("Desktop Entry/Name"); +const QString GenericNameKey("Desktop Entry/GenericName"); +const QString NoDisplayKey("Desktop Entry/NoDisplay"); +const QString CommentKey("Desktop Entry/Comment"); +const QString IconKey("Desktop Entry/Icon"); +const QString HiddenKey("Desktop Entry/Hidden"); +const QString OnlyShowInKey("Desktop Entry/OnlyShowIn"); +const QString NotShowInKey("Desktop Entry/NotShowIn"); +const QString TryExecKey("Desktop Entry/TryExec"); +const QString ExecKey("Desktop Entry/Exec"); +const QString PathKey("Desktop Entry/Path"); +const QString TerminalKey("Desktop Entry/Terminal"); +const QString MimeTypeKey("Desktop Entry/MimeType"); +const QString CategoriesKey("Desktop Entry/Categories"); +const QString StartupNotifyKey("Desktop Entry/StartupNotify"); +const QString StartupWMClassKey("Desktop Entry/StartupWMClass"); +const QString URLKey("Desktop Entry/URL"); +const QString LogicalIdKey("Desktop Entry/X-DUI-logical-id"); +const QString TranslationCatalogKey("Desktop Entry/X-DUI-translation-catalog"); +const QString XMaemoServiceKey("Desktop Entry/X-Maemo-Service"); +const QString XMaemoPrestartedKey("Desktop Entry/X-Maemo-Prestarted"); + +DuiDesktopEntryPrivate::DuiDesktopEntryPrivate(const QString &fileName) : + sourceFileName(fileName), + valid(true) +{ + QFile file(fileName); + + //Checks if the file exists and opens it in readonly mode + if (file.exists() && file.open(QIODevice::ReadOnly)) { + if (readDesktopFile(file, desktopEntriesMap)) { + // Load the translation catalog if it has been defined for the entry. + if (desktopEntriesMap.contains(TranslationCatalogKey)) { + DuiLocale locale; + // Load the catalog from disk if it's not yet loaded + locale.installTrCatalog(desktopEntriesMap.value(TranslationCatalogKey)); + DuiLocale::setDefault(locale); + } + } + } else { + duiWarning("DuiDesktopEntryPrivate") << "Specified Desktop file does not exist" << fileName; + } +} + +DuiDesktopEntryPrivate::~DuiDesktopEntryPrivate() +{ +} + +bool DuiDesktopEntryPrivate::readDesktopFile(QIODevice &device, QMap &desktopEntriesMap) +{ + // Group header is of form [groupname] + // The group name is captured + // Group names may contain all ASCII characters except for [ and ] and control characters + QRegExp groupHeaderRE("\\[([\\0040-\\0132\\0134\\0136-\\0176]+)\\]"); + // Key-value pair is of form Key=Value or Key[localization]=Value + // The first capture is the key and the second capture is the value + QRegExp keyValueRE("([A-Za-z0-9-]+" // key + "(?:\\[[A-Za-z0-9_@.-]+\\])?" // optional localization + ")" // end key capturing + "\\s*=\\s*" // equals + "(.*)"); // value + QString currentGroup; + QStringList groupNames; + while (device.bytesAvailable()) { + QString line = QString(device.readLine()).trimmed(); + if (!line.isEmpty() && !line.startsWith('#')) { + if (keyValueRE.exactMatch(line) && !currentGroup.isEmpty()) { + // A key-value line was found. Prepend the key with the current group name. + QString desktopKey = currentGroup + '/' + keyValueRE.cap(1); + + // Check whether it's already in the map + if (!desktopEntriesMap.contains(desktopKey)) { + QString value = keyValueRE.cap(2); + + // Check whether this is a known multivalue key + if (desktopKey == CategoriesKey || desktopKey == OnlyShowInKey || + desktopKey == NotShowInKey || desktopKey == MimeTypeKey) { + if (value.endsWith("\\;") || !value.endsWith(';')) { + // Multivalue doesn't end with a semicolon so mark the desktop entry invalid + duiWarning("DuiDesktopEntryPrivate") << "Value for multivalue key" << desktopKey << "does not end in a semicolon"; + valid = false; + } + } + + // Add the value to the desktop entries map + desktopEntriesMap.insert(desktopKey, value); + } else { + // Key is already present in the map so issue a warning + duiWarning("DuiDesktopEntryPrivate") << "Key" << desktopKey << "already defined. Value" << keyValueRE.cap(2) << "is ignored"; + } + } else if (groupHeaderRE.exactMatch(line)) { + // A group header line was found and if it's not already defined, set it as current group + if (!groupNames.contains(groupHeaderRE.cap(1), Qt::CaseSensitive)) { + if (groupNames.isEmpty() && groupHeaderRE.cap(1) != "Desktop Entry") { + duiWarning("DuiDesktopEntryPrivate") << "Desktop entry should start with group name \"Desktop Entry\" "; + valid = false; + } else { + groupNames.push_back(groupHeaderRE.cap(1)); + currentGroup = groupHeaderRE.cap(1); + } + } + // Redefining a group name will cause the desktop entry to become invalid but still parsed by the parser. + else { + currentGroup = groupHeaderRE.cap(1); + duiWarning("DuiDesktopEntryPrivate") << "Multiple definitions of group" << groupHeaderRE.cap(1); + valid = false; + } + } else { + duiWarning("DuiDesktopEntryPrivate") << "Invalid .desktop entry line:" << line; + } + } + } + return valid; +} + +bool DuiDesktopEntryPrivate::boolValue(const QString &key) const +{ + return desktopEntriesMap.value(key) == "true"; +} + +QStringList DuiDesktopEntryPrivate::stringListValue(const QString &key) const +{ + QStringList list; + QString value = desktopEntriesMap.value(key); + + // Split the string using ; but not \; as the separator + const int valueLength = value.length(); + for (int current = 0; current < valueLength;) { + bool previousIsBackslash = false; + const int start = current; + for (int end = current; end < valueLength; ++current, ++end) { + if (value.at(end) == ';' && !previousIsBackslash) { + // Replace \; with ; + list.append(value.mid(start, end - start).replace("\\;", ";")); + current++; + break; + } + + previousIsBackslash = value.at(end) == '\\'; + } + } + + return list; +} + +DuiDesktopEntry::DuiDesktopEntry(const QString &fileName) : + d_ptr(new DuiDesktopEntryPrivate(fileName)) +{ +} + +DuiDesktopEntry::DuiDesktopEntry(DuiDesktopEntryPrivate &dd) : + d_ptr(&dd) +{ +} + +DuiDesktopEntry::~DuiDesktopEntry() +{ + delete d_ptr; +} + +QString DuiDesktopEntry::fileName() const +{ + return d_ptr->sourceFileName; +} + +bool DuiDesktopEntry::contains(const QString &key) const +{ + return d_ptr->desktopEntriesMap.contains(key); +} + +bool DuiDesktopEntry::contains(const QString &group, const QString &key) const +{ + return d_ptr->desktopEntriesMap.contains(group + '/' + key); +} + +QString DuiDesktopEntry::value(const QString &key) const +{ + return d_ptr->desktopEntriesMap.value(key); +} + +QString DuiDesktopEntry::value(const QString &group, const QString &key) const +{ + return d_ptr->desktopEntriesMap.value(group + '/' + key); +} + +bool DuiDesktopEntry::isValid() const +{ + // The Type and Name keys always have to be present + if (!contains(TypeKey)) { + return false; + } + + if (!contains(NameKey)) { + return false; + } + + // In case of an application the Exec key needs to be present + if (type() == "Application" && !contains(ExecKey)) { + return false; + } + + // In case of a link the URL key needs to be present + if (type() == "Link" && !contains(URLKey)) { + return false; + } + + // In case the desktop entry is invalid for some explicit reason + // Some cases are: + // 1. Group name defined multiple times + // 2. Desktop entry's first group should be "Desktop Entry" + if (!d_ptr->valid) { + return false; + } + return true; +} + +uint DuiDesktopEntry::hash() const +{ + return qHash(type() + name()); +} + +QString DuiDesktopEntry::type() const +{ + return value(TypeKey); +} + +QString DuiDesktopEntry::version() const +{ + return value(VersionKey); +} + +QString DuiDesktopEntry::name() const +{ + QString name = value(NameKey); + + if (contains(LogicalIdKey)) { + // Get the name from the translation catalog; + // if it does not exist use the unlocalized name prefixed + // by the engineering English marker "!! ": + QString translation = qtTrId(value(LogicalIdKey).toAscii().data()); + if (translation == value(LogicalIdKey)) + name = "!! " + name; + else + name = translation; + } else { + DuiLocale locale; + QString lang(locale.language()); + QString country(locale.country()); + QString variant(locale.variant()); + QString postfixKey; + if (contains(postfixKey = NameKey + '[' + lang + '_' + + country + '@' + + variant + ']') || + contains(postfixKey = NameKey + '[' + lang + '_' + + country + ']') || + contains(postfixKey = NameKey + '[' + lang + '@' + + variant + ']') || + contains(postfixKey = NameKey + '[' + lang + ']')) { + // Use the freedesktop.org standard localization style + name = value(postfixKey); + } + } + + return name; +} + +QString DuiDesktopEntry::nameUnlocalized() const +{ + return value(NameKey); +} + +QString DuiDesktopEntry::genericName() const +{ + return value(GenericNameKey); +} + +bool DuiDesktopEntry::noDisplay() const +{ + return d_ptr->boolValue(NoDisplayKey); +} + +QString DuiDesktopEntry::comment() const +{ + return value(CommentKey); +} + +QString DuiDesktopEntry::icon() const +{ + return value(IconKey); +} + +bool DuiDesktopEntry::hidden() const +{ + return d_ptr->boolValue(HiddenKey); +} + +QStringList DuiDesktopEntry::onlyShowIn() const +{ + return d_ptr->stringListValue(OnlyShowInKey); +} + +QStringList DuiDesktopEntry::notShowIn() const +{ + return d_ptr->stringListValue(NotShowInKey); +} + +QString DuiDesktopEntry::tryExec() const +{ + return value(TryExecKey); +} + +QString DuiDesktopEntry::exec() const +{ + return value(ExecKey); +} + +QString DuiDesktopEntry::xMaemoService() const +{ + return value(XMaemoServiceKey); +} + +QString DuiDesktopEntry::path() const +{ + return value(PathKey); +} + +bool DuiDesktopEntry::terminal() const +{ + return d_ptr->boolValue(TerminalKey); +} + +QStringList DuiDesktopEntry::mimeType() const +{ + return d_ptr->stringListValue(MimeTypeKey); +} + +QStringList DuiDesktopEntry::categories() const +{ + return d_ptr->stringListValue(CategoriesKey); +} + +bool DuiDesktopEntry::startupNotify() const +{ + return d_ptr->boolValue(StartupNotifyKey); +} + +bool DuiDesktopEntry::xMaemoPrestarted() const +{ + return d_ptr->boolValue(XMaemoPrestartedKey); +} + +QString DuiDesktopEntry::startupWMClass() const +{ + return value(StartupWMClassKey); +} + +QString DuiDesktopEntry::url() const +{ + return value(URLKey); +} diff --git a/src/core/duidesktopentry.h b/src/core/duidesktopentry.h new file mode 100644 index 000000000..09ff6a62b --- /dev/null +++ b/src/core/duidesktopentry.h @@ -0,0 +1,252 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIDESKTOPENTRY_H_ +#define DUIDESKTOPENTRY_H_ + +#include "duiexport.h" +#include +#include + +class DuiDesktopEntryPrivate; + +/*! + * DuiDesktopEntry provides the means to read freedesktop.org desktop entry + * files. + * + * DuiDesktopEntry object reads desktop file data from the desktop file given as + * a construction parameter. + * + * The isValid() method determines whether the input desktop file conforms to the + * standard defined by freedesktop.org. + * + * For more information see: + * http://standards.freedesktop.org/desktop-entry-spec/latest/index.html + * + */ +class DUI_EXPORT DuiDesktopEntry +{ +public: + /*! + * Reads input desktop file and constructs new DuiDesktopEntry object + * of it. + * + * \param fileName the name of the file to read the desktop entry from + */ + DuiDesktopEntry(const QString &fileName); + + /*! + * Destroys the DuiDesktopEntry. + */ + virtual ~DuiDesktopEntry(); + + /*! + * Returns the name of the file where the information for this + * desktop entry was read from. + * \return The desktop entry file name. + */ + QString fileName() const; + + /*! + * Indicates whether desktop entry information adheres to the requirements + * set in the freedesktop.org standard. + * Freedesktop.org defines required keys that one has to fill to have a + * valid desktop file. This checks whether those keys are defined. + */ + virtual bool isValid() const; + + /*! + * Calculates a hash value based on the required type and name keys + * of the desktop definition. + */ + virtual uint hash() const; + + /*! + * Returns the value of Type key or an empty string if it is + * not defined in the input desktop entry file. + */ + QString type() const; + + /*! + * Returns the value of Version key or an empty string if it is + * not defined in the input desktop entry file. + */ + QString version() const; + + /*! + * Returns the localized value of Name key or an empty string if it is + * not defined in the input desktop entry file. The localization + * requires either a X-DUI-logical-id attribute with optional + * X-DUI-translation-catalog attribute or freedesktop.org standard + * style localized name attribute. Returns the name as unlocalized + * if the logical id cannot be found from the catalog. \see nameUnlocalized + */ + QString name() const; + + /*! + * Returns the unlocalized value of Name key or an empty string if it is + * not defined in the input desktop entry file. + */ + QString nameUnlocalized() const; + + /*! + * Returns the value of GenericName key or an empty string if it is + * not defined in the input desktop entry file. + */ + QString genericName() const; + + /*! + * Indicates whether value of NoDisplay key is true or false. + * Returns false if NoDisplay key is undefined. + */ + bool noDisplay() const; + + /*! + * Returns the value of Comment key or an empty string if it is + * not defined in the input desktop entry file. + */ + QString comment() const; + + /*! + * Returns the value of Icon key or an empty string if it is + * not defined in the input desktop entry file. + */ + QString icon() const; + + /*! + * Indicates whether value of Hidden key is true or false. + * Returns false if Hidden key is undefined. + */ + bool hidden() const; + + /*! + * Returns the value of OnlyShowIn key or an empty string list if it is + * not defined in the input desktop entry file. + */ + QStringList onlyShowIn() const; + + /*! + * Returns the value of NotShowIn key or an empty string list if it is + * not defined in the input desktop entry file. + */ + QStringList notShowIn() const; + + /*! + * Returns the value of TryExec key or an empty string if it is + * not defined in the input desktop entry file. + */ + QString tryExec() const; + + /*! + * Returns the value of Exec key or an empty string if it is + * not defined in the input desktop entry file. + */ + QString exec() const; + + /*! + * Returns the value of Path key or an empty string if it is + * not defined in the input desktop entry file. + */ + QString path() const; + + /*! + * Indicates whether value of Terminal key is true or false. + * Returns false if Terminal key is undefined. + */ + bool terminal() const; + + /*! + * Returns the value of MimeTypes key or an empty string list if it is + * not defined in the input desktop entry file. + */ + QStringList mimeType() const; + + /*! + * Returns the value of Categories key or an empty string list if it is + * not defined in the input desktop entry file. + */ + QStringList categories() const; + + /*! + * Indicates whether value of StartupNotify key is true or false. + * Returns false if StartupNotify key is undefined. + */ + bool startupNotify() const; + + /*! + * Returns the value of StartupWMClass key or an empty string if it is + * not defined in the input desktop entry file. + */ + QString startupWMClass() const; + + /*! + * Returns the value of URL key or an empty string if it is + * not defined in the input desktop entry file. + */ + QString url() const; + + /*! + * Returns the value of X-Osso-Service key or an empty string if it is + * not defined in the input desktop entry file. + */ + QString xMaemoService() const; + + /*! + * Returns the value of X-Maemo-Prestarted key or false if it is + * not defined in the input desktop entry file. + */ + bool xMaemoPrestarted() const; + + /*! + * Returns the value of the key- key or an empty string if it is + * not defined in the input desktop entry file. + */ + QString value(const QString &key) const; + + /*! + * Returns the value of the group-key stored as "group/key" + * key or an empty string if it is not defined in the input desktop entry file. + */ + QString value(const QString &group, const QString &key) const; + + /*! + * Indicates whether map contains key or not. + * Returns false if key is not present. + */ + bool contains(const QString &key) const; + + /*! + * Indicates whether map contains group/key or not. + * Returns false if key is not present. + */ + bool contains(const QString &group, const QString &key) const; + +protected: + /*! \internal */ + //! Pointer to the private class + DuiDesktopEntryPrivate *const d_ptr; + DuiDesktopEntry(DuiDesktopEntryPrivate &dd); + /*! \internal_end */ + +private: + Q_DISABLE_COPY(DuiDesktopEntry) + Q_DECLARE_PRIVATE(DuiDesktopEntry) +}; +#endif /* DUIDESKTOPENTRY_H_ */ + diff --git a/src/core/duidesktopentry_p.h b/src/core/duidesktopentry_p.h new file mode 100644 index 000000000..2fc3e8cef --- /dev/null +++ b/src/core/duidesktopentry_p.h @@ -0,0 +1,87 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIDESKTOPENTRY_P_H +#define DUIDESKTOPENTRY_P_H + +class DuiDesktopEntry; + +/*! + * DuiDesktopEntryPrivate is the private class for DuiDesktopEntry. + */ +class DuiDesktopEntryPrivate +{ + Q_DECLARE_PUBLIC(DuiDesktopEntry) + +public: + /*! + * Constructs a new DuiDesktopEntryPrivate class. + * + * \param fileName the name of the file to read the desktop entry from + */ + DuiDesktopEntryPrivate(const QString &fileName); + + /*! + * Destroys the DuiDesktopEntryPrivate. + */ + virtual ~DuiDesktopEntryPrivate(); + + /*! + * Parses a desktop entry file. + * + * \param device the QIODevice to read the desktop file from + * \param map the QMap to store key-value pairs to + * \return true if desktop file can be parsed + */ + bool readDesktopFile(QIODevice &device, QMap &map); + + //! The name of the file where the information for this desktop entry was read from. + QString sourceFileName; + + //! A map for storing the desktop entries keys and their corresponding values + QMap desktopEntriesMap; + + /*! + * Returns the boolean value of a key. + * + * \param key the key to return the boolean value for + * \return true if the value of specified key is set to "true" and false otherwise. + */ + bool boolValue(const QString &key) const; + + /*! + * Returns the string list value of a key. The list will be populated + * with semicolon separated parts of the key value. + * + * \param key the key to return the string list value for + * \return a string list containing the semicolon separated parts of the key value + */ + QStringList stringListValue(const QString &key) const; + + //! Flag to indicate whether the desktop entry is valid during parsing + bool valid; + +protected: + /* + * \brief this q_ptr starts the inheritance hierarchy + */ + DuiDesktopEntry *q_ptr; +}; + +#endif diff --git a/src/core/duiexport.h b/src/core/duiexport.h new file mode 100644 index 000000000..2658122e8 --- /dev/null +++ b/src/core/duiexport.h @@ -0,0 +1,44 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIEXPORT_H +#define DUIEXPORT_H + +#include + +#if defined(DUI_EXPORTS) +# define DUI_EXPORT Q_DECL_EXPORT +#else +# if defined (Q_OS_WIN) +# define DUI_EXPORT Q_DECL_IMPORT +# else +# define DUI_EXPORT Q_DECL_EXPORT +# endif +#endif + +#if defined(Q_OS_WIN) && defined (Q_CC_MSVC) +# ifndef __func__ +# define __func__ __FUNCTION__ +# endif +# ifndef __PRETTY_FUNCTION__ +# define __PRETTY_FUNCTION__ __FUNCTION__ +# endif +#endif + +#endif // Header guard diff --git a/src/core/duigconfitem.cpp b/src/core/duigconfitem.cpp new file mode 100644 index 000000000..78eb35a2a --- /dev/null +++ b/src/core/duigconfitem.cpp @@ -0,0 +1,343 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include +#include +#include + +#include "duigconfitem.h" + +#include +#include + +struct DuiGConfItemPrivate { + QString key; + QVariant value; + guint notify_id; + + static void notify_trampoline(GConfClient *, guint, GConfEntry *, gpointer); +}; + +#define withClient(c) for(GConfClient *c = (g_type_init(), gconf_client_get_default()); c; g_object_unref(c), c=NULL) + +static QByteArray convertKey(const QString &key) +{ + if (key.startsWith('/')) + return key.toUtf8(); + else { + QString replaced = key; + replaced.replace('.', '/'); + duiWarning("duiconfigitem.cpp") << "Using dot-separated key names with DuiGConfItem is deprecated."; + duiWarning("duiconfigitem.cpp") << "Please use" << '/' + replaced << "instead of" << key; + return '/' + replaced.toUtf8(); + } +} + +static QString convertKey(const char *key) +{ + return QString::fromUtf8(key); +} + +static QVariant convertValue(GConfValue *src) +{ + if (!src) { + return QVariant(); + } else { + switch (src->type) { + case GCONF_VALUE_INVALID: + return QVariant(QVariant::Invalid); + case GCONF_VALUE_BOOL: + return QVariant((bool)gconf_value_get_bool(src)); + case GCONF_VALUE_INT: + return QVariant(gconf_value_get_int(src)); + case GCONF_VALUE_FLOAT: + return QVariant(gconf_value_get_float(src)); + case GCONF_VALUE_STRING: + return QVariant(QString::fromUtf8(gconf_value_get_string(src))); + case GCONF_VALUE_LIST: + switch (gconf_value_get_list_type(src)) { + case GCONF_VALUE_STRING: { + QStringList result; + for (GSList *elts = gconf_value_get_list(src); elts; elts = elts->next) + result.append(QString::fromUtf8(gconf_value_get_string((GConfValue *)elts->data))); + return QVariant(result); + } + default: { + QList result; + for (GSList *elts = gconf_value_get_list(src); elts; elts = elts->next) + result.append(convertValue((GConfValue *)elts->data)); + return QVariant(result); + } + } + case GCONF_VALUE_SCHEMA: + default: + return QVariant(); + } + } +} + +static GConfValue *convertString(const QString &str) +{ + GConfValue *v = gconf_value_new(GCONF_VALUE_STRING); + gconf_value_set_string(v, str.toUtf8().data()); + return v; +} + +static GConfValueType primitiveType(const QVariant &elt) +{ + switch (elt.type()) { + case QVariant::String: + return GCONF_VALUE_STRING; + case QVariant::Int: + return GCONF_VALUE_INT; + case QVariant::Double: + return GCONF_VALUE_FLOAT; + case QVariant::Bool: + return GCONF_VALUE_BOOL; + default: + return GCONF_VALUE_INVALID; + } +} + +static GConfValueType uniformType(const QList &list) +{ + GConfValueType result = GCONF_VALUE_INVALID; + + foreach(const QVariant & elt, list) { + GConfValueType elt_type = primitiveType(elt); + + if (elt_type == GCONF_VALUE_INVALID) + return GCONF_VALUE_INVALID; + + if (result == GCONF_VALUE_INVALID) + result = elt_type; + else if (result != elt_type) + return GCONF_VALUE_INVALID; + } + + if (result == GCONF_VALUE_INVALID) + return GCONF_VALUE_STRING; // empty list. + else + return result; +} + +static int convertValue(const QVariant &src, GConfValue **valp) +{ + GConfValue *v; + + switch (src.type()) { + case QVariant::Invalid: + v = NULL; + break; + case QVariant::Bool: + v = gconf_value_new(GCONF_VALUE_BOOL); + gconf_value_set_bool(v, src.toBool()); + break; + case QVariant::Int: + v = gconf_value_new(GCONF_VALUE_INT); + gconf_value_set_int(v, src.toInt()); + break; + case QVariant::Double: + v = gconf_value_new(GCONF_VALUE_FLOAT); + gconf_value_set_float(v, src.toDouble()); + break; + case QVariant::String: + v = convertString(src.toString()); + break; + case QVariant::StringList: { + GSList *elts = NULL; + v = gconf_value_new(GCONF_VALUE_LIST); + gconf_value_set_list_type(v, GCONF_VALUE_STRING); + foreach(const QString & str, src.toStringList()) + elts = g_slist_prepend(elts, convertString(str)); + gconf_value_set_list_nocopy(v, g_slist_reverse(elts)); + break; + } + case QVariant::List: { + GConfValueType elt_type = uniformType(src.toList()); + if (elt_type == GCONF_VALUE_INVALID) + v = NULL; + else { + GSList *elts = NULL; + v = gconf_value_new(GCONF_VALUE_LIST); + gconf_value_set_list_type(v, elt_type); + foreach(const QVariant & elt, src.toList()) { + GConfValue *val = NULL; + convertValue(elt, &val); // guaranteed to succeed. + elts = g_slist_prepend(elts, val); + } + gconf_value_set_list_nocopy(v, g_slist_reverse(elts)); + } + break; + } + default: + return 0; + } + + *valp = v; + return 1; +} + +void DuiGConfItemPrivate::notify_trampoline(GConfClient *, + guint, + GConfEntry *, + gpointer data) +{ + DuiGConfItem *item = (DuiGConfItem *)data; + item->update_value(true); +} + +void DuiGConfItem::update_value(bool emit_signal) +{ + QVariant new_value; + + withClient(client) { + GError *error = NULL; + QByteArray k = convertKey(priv->key); + GConfValue *v = gconf_client_get(client, k.data(), &error); + + if (error) { + duiWarning("DuiGConfItem") << error->message; + g_error_free(error); + new_value = priv->value; + } else { + new_value = convertValue(v); + if (v) + gconf_value_free(v); + } + } + + if (new_value != priv->value) { + priv->value = new_value; + if (emit_signal) + emit valueChanged(); + } +} + +QString DuiGConfItem::key() const +{ + return priv->key; +} + +QVariant DuiGConfItem::value() const +{ + return priv->value; +} + +QVariant DuiGConfItem::value(const QVariant &def) const +{ + if (priv->value.isNull()) + return def; + else + return priv->value; +} + +void DuiGConfItem::set(const QVariant &val) +{ + withClient(client) { + QByteArray k = convertKey(priv->key); + GConfValue *v; + if (convertValue(val, &v)) { + GError *error = NULL; + + if (v) { + gconf_client_set(client, k.data(), v, &error); + gconf_value_free(v); + } else { + gconf_client_unset(client, k.data(), &error); + } + + if (error) { + duiWarning("DuiGConfItem") << error->message; + g_error_free(error); + } else if (priv->value != val) { + priv->value = val; + emit valueChanged(); + } + + } else + duiWarning("DuiGConfItem") << "Can't store a" << val.typeName(); + } +} + +void DuiGConfItem::unset() +{ + set(QVariant()); +} + +QList DuiGConfItem::listDirs() const +{ + QList children; + + withClient(client) { + QByteArray k = convertKey(priv->key); + GSList *dirs = gconf_client_all_dirs(client, k.data(), NULL); + for (GSList *d = dirs; d; d = d->next) { + children.append(convertKey((char *)d->data)); + g_free(d->data); + } + g_slist_free(dirs); + } + + return children; +} + +QList DuiGConfItem::listEntries() const +{ + QList children; + + withClient(client) { + QByteArray k = convertKey(priv->key); + GSList *entries = gconf_client_all_entries(client, k.data(), NULL); + for (GSList *e = entries; e; e = e->next) { + children.append(convertKey(((GConfEntry *)e->data)->key)); + gconf_entry_free((GConfEntry *)e->data); + } + g_slist_free(entries); + } + + return children; +} + +DuiGConfItem::DuiGConfItem(const QString &key, QObject *parent) + : QObject(parent) +{ + priv = new DuiGConfItemPrivate; + priv->key = key; + withClient(client) { + update_value(false); + QByteArray k = convertKey(priv->key); + gconf_client_add_dir(client, k.data(), GCONF_CLIENT_PRELOAD_ONELEVEL, NULL); + priv->notify_id = gconf_client_notify_add(client, k.data(), + DuiGConfItemPrivate::notify_trampoline, this, + NULL, NULL); + } +} + +DuiGConfItem::~DuiGConfItem() +{ + withClient(client) { + QByteArray k = convertKey(priv->key); + gconf_client_notify_remove(client, priv->notify_id); + gconf_client_remove_dir(client, k.data(), NULL); + } + delete priv; +} diff --git a/src/core/duigconfitem.h b/src/core/duigconfitem.h new file mode 100644 index 000000000..ea9009f23 --- /dev/null +++ b/src/core/duigconfitem.h @@ -0,0 +1,146 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIGCONFITEM_H +#define DUIGCONFITEM_H + +#include +#include +#include + +#include "duiexport.h" + +/*! + + \brief DuiGConfItem is a simple C++ wrapper for GConf. + + Creating a DuiGConfItem instance gives you access to a single GConf + key. You can get and set its value, and connect to its + valueChanged() signal to be notified about changes. + + The value of a GConf key is returned to you as a QVariant, and you + pass in a QVariant when setting the value. DuiGConfItem converts + between a QVariant and GConf values as needed, and according to the + following rules: + + - A QVariant of type QVariant::Invalid denotes an unset GConf key. + + - QVariant::Int, QVariant::Double, QVariant::Bool are converted to + and from the obvious equivalents. + + - QVariant::String is converted to/from a GConf string and always + uses the UTF-8 encoding. No other encoding is supported. + + - QVariant::StringList is converted to a list of UTF-8 strings. + + - QVariant::List (which denotes a QList) is converted + to/from a GConf list. All elements of such a list must have the + same type, and that type must be one of QVariant::Int, + QVariant::Double, QVariant::Bool, or QVariant::String. (A list of + strings is returned as a QVariant::StringList, however, when you + get it back.) + + - Any other QVariant or GConf value is essentially ignored. + + \warning DuiGConfItem is as thread-safe as GConf. + +*/ + +class DUI_EXPORT DuiGConfItem : public QObject +{ + Q_OBJECT + +public: + /*! Initializes a DuiGConfItem to access the GConf key denoted by + \a key. Key names should follow the normal GConf conventions + like "/myapp/settings/first". + + \param key The name of the key. + \param parent Parent object + */ + explicit DuiGConfItem(const QString &key, QObject *parent = 0); + + /*! Finalizes a DuiGConfItem. + */ + virtual ~DuiGConfItem(); + + /*! Returns the key of this item, as given to the constructor. + */ + QString key() const; + + /*! Returns the current value of this item, as a QVariant. + */ + QVariant value() const; + + /*! Returns the current value of this item, as a QVariant. If + * there is no value for this item, return \a def instead. + */ + QVariant value(const QVariant &def) const; + + /*! Set the value of this item to \a val. If \a val can not be + represented in GConf or GConf refuses to accept it for other + reasons, the current value is not changed and nothing happens. + + When the new value is different from the old value, the + changedValue() signal is emitted on this DuiGConfItem as part + of calling set(), but other DuiGConfItem:s for the same key do + only receive a notification once the main loop runs. + + \param val The new value. + */ + void set(const QVariant &val); + + /*! Unset this item. This is equivalent to + + \code + item.set(QVariant(QVariant::Invalid)); + \endcode + */ + void unset(); + + /*! Return a list of the directories below this item. The + returned strings are absolute key names like + "/myapp/settings". + + A directory is a key that has children. The same key might + also have a value, but that is confusing and best avoided. + */ + QList listDirs() const; + + /*! Return a list of entries below this item. The returned + strings are absolute key names like "/myapp/settings/first". + + A entry is a key that has a value. The same key might also + have children, but that is confusing and is best avoided. + */ + QList listEntries() const; + +Q_SIGNALS: + /*! Emitted when the value of this item has changed. + */ + void valueChanged(); + +private: + friend struct DuiGConfItemPrivate; + struct DuiGConfItemPrivate *priv; + + void update_value(bool emit_signal); +}; + +#endif // DUIGCONFITEM_H diff --git a/src/core/duigconfitem_stub.cpp b/src/core/duigconfitem_stub.cpp new file mode 100644 index 000000000..f1a3746eb --- /dev/null +++ b/src/core/duigconfitem_stub.cpp @@ -0,0 +1,74 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include + +#include "duigconfitem.h" + +void DuiGConfItem::update_value(bool emit_signal) +{ + Q_UNUSED(emit_signal); +} + +QString DuiGConfItem::key() const +{ + return QString(); +} + +QVariant DuiGConfItem::value() const +{ + return QVariant(); +} + +QVariant DuiGConfItem::value(const QVariant &def) const +{ + Q_UNUSED(def); + return QVariant(); +} + +void DuiGConfItem::set(const QVariant &val) +{ + Q_UNUSED(val); +} + +void DuiGConfItem::unset() +{ +} + +QList DuiGConfItem::listDirs() const +{ + return QList(); +} + +QList DuiGConfItem::listEntries() const +{ + return QList(); +} + +DuiGConfItem::DuiGConfItem(const QString &key, QObject *parent) + : QObject(parent) +{ + Q_UNUSED(key); +} + +DuiGConfItem::~DuiGConfItem() +{ +} diff --git a/src/core/duiinputmethodstate.cpp b/src/core/duiinputmethodstate.cpp new file mode 100644 index 000000000..931c912fe --- /dev/null +++ b/src/core/duiinputmethodstate.cpp @@ -0,0 +1,78 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiinputmethodstate.h" +#include "duiinputmethodstate_p.h" + + +DuiInputMethodStatePrivate::DuiInputMethodStatePrivate() + : orientation(Dui::Angle0) +{ +} + +DuiInputMethodState::DuiInputMethodState() + : d_ptr(new DuiInputMethodStatePrivate) +{ +} + +DuiInputMethodState::~DuiInputMethodState() +{ + delete d_ptr; +} + +DuiInputMethodState *DuiInputMethodState::instance() +{ + static DuiInputMethodState singleton; + + return &singleton; +} + +void DuiInputMethodState::setInputMethodArea(const QRect &newRegion) +{ + Q_D(DuiInputMethodState); + + if (d->region != newRegion) { + d->region = newRegion; + emit inputMethodAreaChanged(newRegion); + } +} + +QRect DuiInputMethodState::inputMethodArea() const +{ + Q_D(const DuiInputMethodState); + + return d->region; +} + +void DuiInputMethodState::setActiveWindowOrientationAngle(Dui::OrientationAngle newOrientation) +{ + Q_D(DuiInputMethodState); + + if (d->orientation != newOrientation) { + d->orientation = newOrientation; + emit activeWindowOrientationAngleChanged(newOrientation); + } +} + +Dui::OrientationAngle DuiInputMethodState::activeWindowOrientationAngle() const +{ + Q_D(const DuiInputMethodState); + + return d->orientation; +} diff --git a/src/core/duiinputmethodstate.h b/src/core/duiinputmethodstate.h new file mode 100644 index 000000000..16964078b --- /dev/null +++ b/src/core/duiinputmethodstate.h @@ -0,0 +1,84 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIINPUTMETHODSTATE_H +#define DUIINPUTMETHODSTATE_H + +#include +#include + +#include "duinamespace.h" +#include "duiexport.h" + +class DuiInputMethodStatePrivate; + +/*! + * \brief A mediator between DuiInputContext and applications/libdui that use it + * + * This class allows DuiInputContext (technically other input contexts too) to + * communicate input method area on display to the application and application + * to communicate its active window's orientation to the input context. The + * application can be a DUI application or a plain Qt application (which needs + * to link against libdui to get access to this class). The input method area + * can be used by the application to avoid obstructing the input method. + */ +class DUI_EXPORT DuiInputMethodState : public QObject +{ + Q_OBJECT + +public: + //! \brief Get singleton instance + //! \return singleton instance + static DuiInputMethodState *instance(); + + //! \brief Get current input method area + //! \return current input method area + QRect inputMethodArea() const; + + //! \brief Get the orientation of application's active window + //! \return orientation of application's active window + Dui::OrientationAngle activeWindowOrientationAngle() const; + +public Q_SLOTS: + //! \brief Set the orientation of application's active window to \a newOrientation + void setActiveWindowOrientationAngle(Dui::OrientationAngle newOrientation); + + //! \brief Set input method area to \a newRegion + void setInputMethodArea(const QRect &newRegion); + +Q_SIGNALS: + //! Emitted when input method area is changed + //! \param region new input method area + void inputMethodAreaChanged(const QRect ®ion); + + //! Emitted when the orientation of application's active window is changed + //! \param orientation new orientation angle + void activeWindowOrientationAngleChanged(Dui::OrientationAngle orientation); + +private: + //! Disable default construction + DuiInputMethodState(); + ~DuiInputMethodState(); + Q_DISABLE_COPY(DuiInputMethodState) + Q_DECLARE_PRIVATE(DuiInputMethodState) + + DuiInputMethodStatePrivate *const d_ptr; +}; + +#endif diff --git a/src/core/duiinputmethodstate_p.h b/src/core/duiinputmethodstate_p.h new file mode 100644 index 000000000..c5aee2fea --- /dev/null +++ b/src/core/duiinputmethodstate_p.h @@ -0,0 +1,43 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIINPUTMETHODSTATE_P_H +#define DUIINPUTMETHODSTATE_P_H + +#include + +#include "duiinputmethodstate.h" +#include "duinamespace.h" + +class DuiInputMethodStatePrivate +{ +public: + DuiInputMethodStatePrivate(); + + //! Current input method area + QRect region; + + //! Current orientation of application's active window + Dui::OrientationAngle orientation; + +private: + Q_DISABLE_COPY(DuiInputMethodStatePrivate) +}; + +#endif diff --git a/src/core/duilibrary.cpp b/src/core/duilibrary.cpp new file mode 100644 index 000000000..5f822b302 --- /dev/null +++ b/src/core/duilibrary.cpp @@ -0,0 +1,34 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duilibrary.h" +#include "duiassembly_p.h" +#include "duitheme_p.h" + + +DuiLibrary::DuiLibrary(const QString &libraryName) : + DuiAssembly(libraryName) +{ + DuiThemePrivate::registerLibrary(this); +} + +DuiLibrary::~DuiLibrary() +{ + DuiThemePrivate::unregisterLibrary(this); +} diff --git a/src/core/duilibrary.h b/src/core/duilibrary.h new file mode 100644 index 000000000..a3f120ded --- /dev/null +++ b/src/core/duilibrary.h @@ -0,0 +1,68 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUILIBRARY_H +#define DUILIBRARY_H + +#include +#include + +// Defines DUI_LIBRARY macro, which creates a static DuiLibrary object. +// There should be always exactly one static DuiLibrary object per library +// which uses dui. +#if defined DUI_LIBRARY_NAME +#define DUI_LIBRARY \ + static const DuiLibrary g_Library(DUI_LIBRARY_NAME); +#elif !defined DUI_APPLICATION_NAME +#error "You must have CONFIG += dui in your .pro file in order to register a library!" \ +"If the library you're developing doesn't provide any stylesheets then you shouldn't include DuiLibrary header!" +#endif + + +// forward declarations +class DuiLibraryPrivate; + +/*! + \class DuiLibrary + \brief This class provides the library information to DuiTheme which uses it to load the correct css files. + + This class should not be used manually, but with DUI_LIBRARY macro. The macro will use + DUI_LIBRARY_NAME as the name of the library. DUI_LIBRARY_NAME is automatically defined by dui.prf when .pro file + has CONFIG += dui. + + You must use DUI_LIBRARY macro in one of your library source files to instantiate the static + DuiLibrary object. This object will be instantiated while the library gets loaded, and destroyed when + the library gets unloaded. + */ +class DUI_EXPORT DuiLibrary : public DuiAssembly +{ +public: + + /*! + \brief Constructs the DuiLibrary object and registers it to DuiTheme. + */ + DuiLibrary(const QString &libraryName); + + /*! + \brief Destructs the DuiLibrary object and unregisters it from DuiTheme. + */ + virtual ~DuiLibrary(); +}; + +#endif diff --git a/src/core/duinamespace.h b/src/core/duinamespace.h new file mode 100644 index 000000000..494cb925b --- /dev/null +++ b/src/core/duinamespace.h @@ -0,0 +1,192 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUINAMESPACE_H +#define DUINAMESPACE_H + +#include + +namespace Dui +{ + enum AssemblyType { + Library, + Application + }; + + /*! + * This enum contains values of the orientation angle of windows in the application. + * + * \sa Orientation + */ + enum OrientationAngle { + Angle0 = 0, + Angle90 = 90, + Angle180 = 180, + Angle270 = 270 + }; + + /*! + * This enum contains possible values for orientation of windows in the application. + * + * \sa OrientationAngle + */ + enum Orientation { + Portrait, //!< equal to either Dui::Angle90 or Dui::Angle270 orientation angles + Landscape //!< equal to either Dui::Angle0 or Dui::Angle180 orientation angles + }; + + /*! + * Defines whether directories should be traversed recursively. + */ + enum RecursionMode { + Recursive, + NonRecursive + }; + + /*! + * This enum is used to describe whether the orientation change + * invoked manually should be animated or not. + * + * \sa DuiWindow::setOrientationAngle() + */ + enum OrientationChangeMode { + AnimatedOrientationChange, + ImmediateOrientationChange + }; + + //! extensions for Qt::inputMethodQuery + enum InputMethodQueryExtensions { + InputEnabledQuery = 10000, // as workaround for qgraphicsview inputmethod shortcomings - DEPRECATED + VisualizationPriorityQuery, //! Tells if input method widget wants to have high + //! priority for visualization. Input method should + //! honor this and stay out of widgets space. + PreeditRectangleQuery, //! Retrieve bounding rectangle for current preedit text. + ImCorrectionEnabledQuery, //! explicit correction enabling for text entries + ImModeQuery, //! Retrieve mode: normal, direct or proxy + InputMethodToolbarQuery //! custom toolbar for text entry + }; + + enum PreeditFace { + PreeditDefault, + PreeditNoCandidates + }; + + //! Content type for text entries. Used at least with DuiTextEdit + enum TextContentType { + //! all characters allowed + FreeTextContentType, + + //! only integer numbers allowed + NumberContentType, + + //! allows numbers and certain other characters used in phone numbers + PhoneNumberContentType, + + //! allows only characters permitted in email address + EmailContentType, + + //! allows only character permitted in URL address + UrlContentType, + + //! allows content with user defined format + CustomContentType + }; + + enum InputMethodMode { + //! Normal mode allows to use preedit and error correction + InputMethodModeNormal, + + //! Virtual keyboard sends QKeyEvent for every key press or release + InputMethodModeDirect, + + //! Used with proxy widget + InputMethodModeProxy + }; + + enum PrestartMode { + //! Default mode: no prestarting + NoPrestart, + + /*! enable prestart mode and return back + * to the prestarted state after being launched and closed + */ + LazyShutdown, + + /*! + * enable prestart mode and restart automatically + * after being launched and closed + */ + TerminateOnClose + }; + + /*! + * \brief This enum describes flags for standard buttons. Each button has a defined caption. + * + */ + enum StandardButton { + //! An invalid button. \b NOTE: it's not the button witn "No" caption. + NoStandardButton = QMessageBox::NoButton, + //! An "OK" button. + OkButton = QMessageBox::Ok, + //! A "Save" button. + SaveButton = QMessageBox::Save, + //! A "Save All" button. + SaveAllButton = QMessageBox::SaveAll, + //! A "Open" button. + OpenButton = QMessageBox::Open, + //! A "Yes" button. + YesButton = QMessageBox::Yes, + //! A "Yes to all" button. + YesToAllButton = QMessageBox::YesToAll, + //! A "No" button. + NoButton = QMessageBox::No, + //! A "No to all" button. + NoToAllButton = QMessageBox::NoToAll, + //! An "Abort" button. + AbortButton = QMessageBox::Abort, + //! A "Retry" button. + RetryButton = QMessageBox::Retry, + //! An "Ignore" button. + IgnoreButton = QMessageBox::Ignore, + //! A "Close" button. + CloseButton = QMessageBox::Close, + //! A "Cancel" button. + CancelButton = QMessageBox::Cancel, + //! A "Discard" button. + DiscardButton = QMessageBox::Discard, + //! A "Help" button. + HelpButton = QMessageBox::Help, + //! An "Apply" button. + ApplyButton = QMessageBox::Apply, + //! A "Reset" button. + ResetButton = QMessageBox::Reset, + //! A "Restore defaults" button. + RestoreDefaultsButton = QMessageBox::RestoreDefaults, + //! A "Done" button. + DoneButton = 0x10000000, + + FirstButton = OkButton, + LastButton = DoneButton + }; + Q_DECLARE_FLAGS(StandardButtons, StandardButton) +} + +Q_DECLARE_OPERATORS_FOR_FLAGS(Dui::StandardButtons) + +#endif diff --git a/src/core/duiremoteaction.cpp b/src/core/duiremoteaction.cpp new file mode 100644 index 000000000..fe64c4377 --- /dev/null +++ b/src/core/duiremoteaction.cpp @@ -0,0 +1,131 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiremoteaction.h" +#include "duiremoteaction_p.h" +#include +#include + +DuiRemoteActionPrivate::DuiRemoteActionPrivate() : + DuiActionPrivate() +{ +} + +DuiRemoteActionPrivate::~DuiRemoteActionPrivate() +{ +} + +DuiRemoteAction::DuiRemoteAction(const QString &serviceName, const QString &objectPath, const QString &interface, const QString &methodName, const QList &arguments, QObject *parent) : DuiAction(*new DuiRemoteActionPrivate, parent) +{ + Q_D(DuiRemoteAction); + + d->serviceName = serviceName; + d->objectPath = objectPath; + d->interface = interface; + d->methodName = methodName; + d->arguments = arguments; + + connect(this, SIGNAL(triggered()), this, SLOT(call())); +} + +DuiRemoteAction::DuiRemoteAction(const QString &string, QObject *parent) : DuiAction(*new DuiRemoteActionPrivate, parent) +{ + fromString(string); + + connect(this, SIGNAL(triggered()), this, SLOT(call())); +} + +DuiRemoteAction::DuiRemoteAction(DuiRemoteActionPrivate &dd, QObject *parent) : DuiAction(dd, parent) +{ + connect(this, SIGNAL(triggered()), this, SLOT(call())); +} + +DuiRemoteAction::~DuiRemoteAction() +{ +} + +QString DuiRemoteAction::toString() const +{ + Q_D(const DuiRemoteAction); + + QString s; + if (!d->serviceName.isEmpty() && !d->objectPath.isEmpty() && !d->interface.isEmpty() && !d->methodName.isEmpty()) { + s.append(d->serviceName).append(' '); + s.append(d->objectPath).append(' '); + s.append(d->interface).append(' '); + s.append(d->methodName); + + foreach(const QVariant & arg, d->arguments) { + // Serialize the QVariant into a QBuffer + QBuffer buffer; + buffer.open(QIODevice::ReadWrite); + QDataStream stream(&buffer); + stream << arg; + buffer.close(); + + // Encode the contents of the QBuffer in Base64 + s.append(' '); + s.append(buffer.buffer().toBase64().data()); + } + } + + return s; +} + +void DuiRemoteAction::fromString(const QString &string) +{ + Q_D(DuiRemoteAction); + + QStringList l = string.split(' '); + + if (l.count() > 3) { + d->serviceName = l.at(0); + d->objectPath = l.at(1); + d->interface = l.at(2); + d->methodName = l.at(3); + } + + const int count = l.count(); + for (int i = 4; i < count; ++i) { + QByteArray byteArray = QByteArray::fromBase64(l.at(i).toAscii()); + QBuffer buffer(&byteArray); + buffer.open(QIODevice::ReadOnly); + QDataStream stream(&buffer); + QVariant arg; + stream >> arg; + buffer.close(); + + d->arguments.append(arg); + } +} + +DuiRemoteAction::DuiRemoteAction(const DuiRemoteAction &action) : DuiAction(*new DuiRemoteActionPrivate, action.parent()) +{ + fromString(action.toString()); + + connect(this, SIGNAL(triggered()), this, SLOT(call())); +} + +void DuiRemoteAction::call() +{ + Q_D(DuiRemoteAction); + + QDBusInterface interface(d->serviceName, d->objectPath, d->interface); + interface.callWithArgumentList(QDBus::NoBlock, d->methodName, d->arguments); +} diff --git a/src/core/duiremoteaction.h b/src/core/duiremoteaction.h new file mode 100644 index 000000000..486927367 --- /dev/null +++ b/src/core/duiremoteaction.h @@ -0,0 +1,100 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIREMOTEACTION_H_ +#define DUIREMOTEACTION_H_ + +#include +#include + +class DuiRemoteActionPrivate; + +/*! + * \class DuiRemoteAction + * + * \brief DuiRemoteAction implements a DuiAction that executes a D-Bus call when triggered. + * The D-Bus related parameters can be serialized and unserialized into a string. + */ +class DUI_EXPORT DuiRemoteAction : public DuiAction +{ + Q_OBJECT + +public: + /*! + * \brief Constructs a DuiRemoteAction from a D-Bus service path, object path, interface and arguments. + * + * \param serviceName the service path of the D-Bus object to be called + * \param objectPath the object path of the D-Bus object to be called + * \param interface the interface of the D-Bus object to be called + * \param methodName the name of the D-Bus method to call + * \param arguments the arguments of the D-Bus call. Defaults to no arguments. + * \param parent Parent object + */ + explicit DuiRemoteAction(const QString &serviceName, const QString &objectPath, const QString &interface, const QString &methodName, const QList &arguments = QList(), QObject *parent = NULL); + + /*! + * \brief Constructs a DuiRemoteAction from a string representation of a D-Bus remote action acquired with toString(). + * + * \param string the QString to construct the DuiRemoteAction from + * \param parent Parent object + */ + explicit DuiRemoteAction(const QString &string = QString(), QObject *parent = NULL); + + /*! + * \brief Constructs a copy of another DuiRemoteAction. + * + * \param action the DuiRemoteAction to copy + */ + DuiRemoteAction(const DuiRemoteAction &action); + + /*! + * \brief Destroys the DuiRemoteAction. + */ + virtual ~DuiRemoteAction(); + + /*! + * Returns a string representation of this remote action. + * + * \return a string representation of this remote action + */ + QString toString() const; + +protected Q_SLOTS: + /*! + * \brief A slot for calling the D-Bus function when the action is triggered + */ + void call(); + +protected: + /*! + * \brief Initializes the DuiRemoteAction from a string representation + * + * \param string a string representation of a remote action + */ + void fromString(const QString &string); + + //! \internal + DuiRemoteAction(DuiRemoteActionPrivate &dd, QObject *parent = NULL); + //! \internal_end + +private: + Q_DECLARE_PRIVATE(DuiRemoteAction) +}; + +#endif /* DUIREMOTEACTION_H_ */ diff --git a/src/core/duiremoteaction_p.h b/src/core/duiremoteaction_p.h new file mode 100644 index 000000000..093769a49 --- /dev/null +++ b/src/core/duiremoteaction_p.h @@ -0,0 +1,49 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIREMOTEACTION_P_H +#define DUIREMOTEACTION_P_H + +#include "duiaction_p.h" +#include + +class DuiRemoteAction; +class QDBusInterface; + +class DuiRemoteActionPrivate : public DuiActionPrivate +{ + Q_DECLARE_PUBLIC(DuiRemoteAction) + +public: + DuiRemoteActionPrivate(); + virtual ~DuiRemoteActionPrivate(); + + //! The name of the D-Bus service to call + QString serviceName; + //! The path of the D-Bus object to call + QString objectPath; + //! The name of the D-Bus interface to call + QString interface; + //! The name of the D-Bus method to call + QString methodName; + //! The arguments of the D-Bus call + QList arguments; +}; + +#endif diff --git a/src/core/duirmiclient.cpp b/src/core/duirmiclient.cpp new file mode 100644 index 000000000..c410fc048 --- /dev/null +++ b/src/core/duirmiclient.cpp @@ -0,0 +1,280 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duirmiclient_p.h" +#include "duirmiclient.h" +#include +#include +#include + +DuiRmiClientPrivate:: DuiRmiClientPrivate(const QString &key) + : _key(key) +{ +} + +DuiRmiClientPrivate::~DuiRmiClientPrivate() +{ +} + +void DuiRmiClientPrivate::initConnection() +{ + //unused +} + +void DuiRmiClientPrivate::finalizeConnection() +{ + // unused +} + +QString DuiRmiClientPrivate::key() const +{ + return _key; +} + +DuiRmiClientPrivateSocket::DuiRmiClientPrivateSocket(const QString &key, DuiRmiClient *q) + : DuiRmiClientPrivate(key), + return_sz(0) +{ + q_ptr = q; + QObject::connect(&_socket, SIGNAL(readyRead()), q_ptr, SLOT(_q_readyRead())); +} + + +void DuiRmiClientPrivateSocket::initConnection() +{ + _buf.clear(); + _stream = new QDataStream(&_buf, QIODevice::WriteOnly); + _stream->setVersion(QDataStream::Qt_4_0); + + connectToServer(); + if (!_socket.waitForConnected()) + duiDebug("DuiRmiClientPrivateSocket") << _socket.errorString() << key(); +} + +void DuiRmiClientPrivateSocket::finalizeConnection() +{ + uint sz = _buf.size(); + duiDebug("DuiRmiClientPrivateSocket") << sz; + _stream->device()->seek(0); + *_stream << (quint16)(sz - sizeof(quint16)); + + if (_socket.state() == QLocalSocket::ConnectedState) { + writeData(_buf); + } + + _socket.close(); + delete _stream; +} + +QDataStream &DuiRmiClientPrivateSocket::stream() +{ + return *_stream; +} + +void DuiRmiClientPrivateSocket::writeData(const QByteArray &buffer) +{ + _socket.write(buffer); + _socket.waitForBytesWritten(); + // _socket.disconnect(); +} + +void DuiRmiClientPrivateSocket::connectToServer() +{ + if (_socket.state() == QLocalSocket::UnconnectedState) + _socket.connectToServer(key()); +} + +void DuiRmiClientPrivateSocket::_q_readyRead() +{ + Q_Q(DuiRmiClient); + QDataStream stream(&_socket); + stream.setVersion(QDataStream::Qt_4_0); + + if (return_sz == 0) { + if (_socket.bytesAvailable() < (int)sizeof(quint16)) + return; + stream >> return_sz; + } + + if (_socket.bytesAvailable() < return_sz) + return; + + QVariant v; + stream >> v; + emit q->returnValue(v); +} + +DuiRmiClient::DuiRmiClient(const QString &key, QObject *p) + : QObject(p), + d_ptr(new DuiRmiClientPrivateSocket(key, this)) +{ +} +DuiRmiClient::~DuiRmiClient() +{ + delete d_ptr; +} + +void DuiRmiClient::initConnection() +{ + Q_D(DuiRmiClient); + d->initConnection(); +} + +void DuiRmiClient::finalizeConnection() +{ + Q_D(DuiRmiClient); + d->finalizeConnection(); +} + +void DuiRmiClient::invoke(const char *objectName, const char *method) +{ + Q_D(DuiRmiClient); + initConnection(); + + /* packet is composed of |block size|argument length|arguments...| */ + d->stream() << (quint16)0 << (quint16)0 << objectName << method; + + finalizeConnection(); +} + + +void DuiRmiClient::invoke(const char *objectName, const char *method, + const QVariant &arg0) +{ + Q_D(DuiRmiClient); + initConnection(); + d->stream() << (quint16)0 << (quint16)1 << objectName << method << arg0; + finalizeConnection(); +} + +void DuiRmiClient::invoke(const char *objectName, const char *method, + const QVariant &arg0, const QVariant &arg1) +{ + Q_D(DuiRmiClient); + initConnection(); + d->stream() << (quint16)0 << (quint16)2 << objectName << method << arg0 + << arg1; + finalizeConnection(); +} + +void DuiRmiClient::invoke(const char *objectName, const char *method, + const QVariant &arg0, const QVariant &arg1, + const QVariant &arg2) +{ + Q_D(DuiRmiClient); + initConnection(); + d->stream() << (quint16)0 << (quint16)3 << objectName << method << arg0 + << arg1 << arg2; + finalizeConnection(); +} + +void DuiRmiClient::invoke(const char *objectName, const char *method, + const QVariant &arg0, const QVariant &arg1, + const QVariant &arg2, const QVariant &arg3) +{ + Q_D(DuiRmiClient); + initConnection(); + d->stream() << (quint16)0 << (quint16)4 << objectName << method << arg0 + << arg1 << arg2 << arg3; + finalizeConnection(); +} + +void DuiRmiClient::invoke(const char *objectName, const char *method, + const QVariant &arg0, const QVariant &arg1, + const QVariant &arg2, const QVariant &arg3, + const QVariant &arg4) +{ + Q_D(DuiRmiClient); + initConnection(); + d->stream() << (quint16)0 << (quint16)5 << objectName << method << arg0 + << arg1 << arg2 << arg3 << arg4; + finalizeConnection(); +} + +void DuiRmiClient::invoke(const char *objectName, const char *method, + const QVariant &arg0, const QVariant &arg1, + const QVariant &arg2, const QVariant &arg3, + const QVariant &arg4, const QVariant &arg5) +{ + Q_D(DuiRmiClient); + initConnection(); + d->stream() << (quint16)0 << (quint16)6 << objectName << method << arg0 + << arg1 << arg2 << arg3 << arg4 << arg5; + finalizeConnection(); + +} + +void DuiRmiClient::invoke(const char *objectName, const char *method, + const QVariant &arg0, const QVariant &arg1, + const QVariant &arg2, const QVariant &arg3, + const QVariant &arg4, const QVariant &arg5, + const QVariant &arg6) +{ + Q_D(DuiRmiClient); + initConnection(); + d->stream() << (quint16)0 << (quint16)7 << objectName << method << arg0 + << arg1 << arg2 << arg3 << arg4 << arg5 << arg6; + finalizeConnection(); +} + +void DuiRmiClient::invoke(const char *objectName, const char *method, + const QVariant &arg0, const QVariant &arg1, + const QVariant &arg2, const QVariant &arg3, + const QVariant &arg4, const QVariant &arg5, + const QVariant &arg6, const QVariant &arg7) +{ + Q_D(DuiRmiClient); + initConnection(); + d->stream() << (quint16)0 << (quint16)8 << objectName << method << arg0 + << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7; + finalizeConnection(); + +} + +void DuiRmiClient::invoke(const char *objectName, const char *method, + const QVariant &arg0, const QVariant &arg1, + const QVariant &arg2, const QVariant &arg3, + const QVariant &arg4, const QVariant &arg5, + const QVariant &arg6, const QVariant &arg7, + const QVariant &arg8) +{ + Q_D(DuiRmiClient); + initConnection(); + d->stream() << (quint16)0 << (quint16)9 << objectName << method << arg0 + << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8; + finalizeConnection(); +} + +void DuiRmiClient::invoke(const char *objectName, const char *method, + const QVariant &arg0, const QVariant &arg1, + const QVariant &arg2, const QVariant &arg3, + const QVariant &arg4, const QVariant &arg5, + const QVariant &arg6, const QVariant &arg7, + const QVariant &arg8, const QVariant &arg9) +{ + Q_D(DuiRmiClient); + initConnection(); + d->stream() << (quint16)0 << (quint16)10 << objectName << method << arg0 + << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 + << arg9; + finalizeConnection(); +} + +#include "moc_duirmiclient.cpp" + diff --git a/src/core/duirmiclient.h b/src/core/duirmiclient.h new file mode 100644 index 000000000..ada9a7c22 --- /dev/null +++ b/src/core/duirmiclient.h @@ -0,0 +1,126 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +// -*- C++ -*- +#ifndef DUIRMICLIENT_H +#define DUIRMICLIENT_H + +#include +#include +#include + +class DuiRmiClientPrivate; +class DuiRmiClientPrivateSocket; + +/*! + * \class DuiRmiClient + * + * \brief The DuiRmiClient allows member functions of QObjects exported by + * DuiRmiServer from another process to be invoked remotely. + */ +class DUI_EXPORT DuiRmiClient: public QObject +{ + Q_OBJECT + +public: + + /*! + * Creates a DuiRmiClient + * + * \param key the key used to identify the remote DuiRmiServer + * \param parent the parent QObject + */ + explicit DuiRmiClient(const QString &key, QObject *parent = 0); + + /*! + * Disconnects all connections and destroys this object + */ + virtual ~DuiRmiClient(); + + /*! + * Invoked the remote function + * + * \param objectName the name of the remote object. Currently unused + * \param method literal string of the method name of the remote object + * \param argN QVariant representation of the arguments of the remote method + */ + void invoke(const char *objectName, const char *method); + void invoke(const char *objectName, const char *method, + const QVariant &arg0); + void invoke(const char *objectName, const char *method, + const QVariant &arg0, const QVariant &arg1); + void invoke(const char *objectName, const char *method, + const QVariant &arg0, const QVariant &arg1, + const QVariant &arg2); + void invoke(const char *objectName, const char *method, + const QVariant &arg0, const QVariant &arg1, + const QVariant &arg2, const QVariant &arg3); + void invoke(const char *objectName, const char *method, + const QVariant &arg0, const QVariant &arg1, + const QVariant &arg2, const QVariant &arg3, + const QVariant &arg4); + void invoke(const char *objectName, const char *method, + const QVariant &arg0, const QVariant &arg, + const QVariant &arg2, const QVariant &arg3, + const QVariant &arg4, const QVariant &arg5); + void invoke(const char *objectName, const char *method, + const QVariant &arg0, const QVariant &arg1, + const QVariant &arg2, const QVariant &arg3, + const QVariant &arg4, const QVariant &arg5, + const QVariant &arg6); + void invoke(const char *objectName, const char *method, + const QVariant &arg0, const QVariant &arg1, + const QVariant &arg2, const QVariant &arg3, + const QVariant &arg4, const QVariant &arg5, + const QVariant &arg6, const QVariant &arg7); + void invoke(const char *objectName, const char *method, + const QVariant &arg0, const QVariant &arg1, + const QVariant &arg2, const QVariant &arg3, + const QVariant &arg4, const QVariant &arg5, + const QVariant &arg6, const QVariant &arg7, + const QVariant &arg8); + void invoke(const char *objectName, const char *method, + const QVariant &arg0, const QVariant &arg1, + const QVariant &arg2, const QVariant &arg3, + const QVariant &arg4, const QVariant &arg5, + const QVariant &arg6, const QVariant &arg7, + const QVariant &arg8, const QVariant &arg9); + +Q_SIGNALS: + /*! + * Signal emitted when a remote function has a return value expected + * + * \param arg QVariant representation of the data returned. + */ + void returnValue(const QVariant &arg); + +private: + Q_DISABLE_COPY(DuiRmiClient) + Q_DECLARE_PRIVATE(DuiRmiClient) + + void initConnection(); + void finalizeConnection(); + + DuiRmiClientPrivate *const d_ptr; + friend class DuiRmiClientPrivateSocket; + + Q_PRIVATE_SLOT(d_func(), void _q_readyRead()) +}; + +#endif // QRMICLIENT_H diff --git a/src/core/duirmiclient_p.h b/src/core/duirmiclient_p.h new file mode 100644 index 000000000..4583ba5f3 --- /dev/null +++ b/src/core/duirmiclient_p.h @@ -0,0 +1,75 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIRMICLIENT_P_H +#define DUIRMICLIENT_P_H + +#include +#include + +class QDataStream; +class DuiRmiClient; + +class DuiRmiClientPrivate +{ + Q_DECLARE_PUBLIC(DuiRmiClient) +public: + DuiRmiClientPrivate(const QString &key); + virtual ~DuiRmiClientPrivate(); + virtual void writeData(const QByteArray &) = 0; + virtual void connectToServer() = 0; + virtual QDataStream &stream() = 0; + + virtual void initConnection(); + virtual void finalizeConnection(); + + QString key() const; + + void returnValue(const QVariant &v); + + DuiRmiClient *q_ptr; + + virtual void _q_readyRead() = 0; +private: + QString _key; +}; + +class DuiRmiClientPrivateSocket: public DuiRmiClientPrivate +{ + Q_DECLARE_PUBLIC(DuiRmiClient) +public: + + DuiRmiClientPrivateSocket(const QString &key, DuiRmiClient *q); + + void writeData(const QByteArray &); + void connectToServer(); + void initConnection(); + void finalizeConnection(); + QDataStream &stream(); + + virtual void _q_readyRead(); + +private: + QLocalSocket _socket; + QByteArray _buf; + QDataStream *_stream; + quint16 return_sz; +}; + +#endif //DUIRMICLIENT_P_H diff --git a/src/core/duirmiserver.cpp b/src/core/duirmiserver.cpp new file mode 100644 index 000000000..28160d4f1 --- /dev/null +++ b/src/core/duirmiserver.cpp @@ -0,0 +1,319 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duirmiserver.h" +#include "duirmiserver_p.h" + +#include +#include +#include +#include +#include +#include +#include + +QGenericArgument unmarshall(const char *name, const void *data) +{ + return QGenericArgument(name, data); +} + +DuiRmiServerPrivate::DuiRmiServerPrivate(const QString &key) + : _key(key), _obj(0) +{ +} + +DuiRmiServerPrivate::~DuiRmiServerPrivate() +{ +} + +void DuiRmiServerPrivate::exportObject(QObject *p) +{ + _obj = p; +} + +// TODO object selection from multiple sources +QObject *DuiRmiServerPrivate::currentObject() +{ + return _obj; +} + +QString DuiRmiServerPrivate::key() const +{ + return _key; +} + +DuiRmiServerPrivateSocket::DuiRmiServerPrivateSocket(const QString &key) + : DuiRmiServerPrivate(key), method_size(0) +{ +} + +void DuiRmiServerPrivateSocket::exportObject(QObject *p) +{ + Q_Q(DuiRmiServer); + DuiRmiServerPrivate::exportObject(p); + + q->connect(&_serv, SIGNAL(newConnection()), q, SLOT(_q_incoming())); + + if (QFile::exists("/tmp/" + key())) + QFile::remove("/tmp/" + key()); + + if (!_serv.listen(key())) + duiDebug("DuiRmiServerPrivateSocket") << "system error, can't listen to local socket"; +} + +void DuiRmiServerPrivateSocket::_q_incoming() +{ + Q_Q(DuiRmiServer); + QLocalSocket *s = _serv.nextPendingConnection(); + q->connect(s, SIGNAL(disconnected()), s, SLOT(deleteLater())); + if (!s) + return; + _sock = s; + q->connect(_sock, SIGNAL(readyRead()), q, SLOT(_q_readData())); +} + +void DuiRmiServerPrivateSocket::_q_readData() +{ + uint sz = _sock->bytesAvailable(); + + QDataStream stream(_sock); + stream.setVersion(QDataStream::Qt_4_0); + + if (method_size == 0) { + if (sz < (int)sizeof(quint16)) + return; + stream >> method_size; + } + + if (sz < method_size) + return; + + invoke(stream); +} + +void DuiRmiServerPrivateSocket::invoke(QDataStream &stream) +{ + char *className = 0; + char *methodName = 0; + quint16 arglength = 0; + + QVariant arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9; + + stream >> arglength >> className >> methodName; + switch (arglength) { + case 0: + QMetaObject::invokeMethod(currentObject(), + methodName); + break; + case 1: + stream >> arg0; + QMetaObject::invokeMethod(currentObject(), + methodName, + unmarshall(arg0.typeName(), + arg0.data())); + + break; + case 2: + stream >> arg0 >> arg1; + QMetaObject::invokeMethod(currentObject(), + methodName, + unmarshall(arg0.typeName(), + arg0.data()), + unmarshall(arg1.typeName(), + arg1.data())); + break; + case 3: + stream >> arg0 >> arg1 >> arg2; + QMetaObject::invokeMethod(currentObject(), + methodName, + unmarshall(arg0.typeName(), + arg0.data()), + unmarshall(arg1.typeName(), + arg1.data()), + unmarshall(arg2.typeName(), + arg2.data())); + break; + case 4: + stream >> arg0 >> arg1 >> arg2 >> arg3; + QMetaObject::invokeMethod(currentObject(), + methodName, + unmarshall(arg0.typeName(), + arg0.data()), + unmarshall(arg1.typeName(), + arg1.data()), + unmarshall(arg2.typeName(), + arg2.data()), + unmarshall(arg3.typeName(), + arg3.data())); + break; + case 5: + stream >> arg0 >> arg1 >> arg2 >> arg3 >> arg4; + QMetaObject::invokeMethod(currentObject(), + methodName, + unmarshall(arg0.typeName(), + arg0.data()), + unmarshall(arg1.typeName(), + arg1.data()), + unmarshall(arg2.typeName(), + arg2.data()), + unmarshall(arg3.typeName(), + arg3.data()), + unmarshall(arg4.typeName(), + arg4.data())); + break; + case 6: + stream >> arg0 >> arg1 >> arg2 >> arg3 >> arg4 >> arg5; + QMetaObject::invokeMethod(currentObject(), + methodName, + unmarshall(arg0.typeName(), + arg0.data()), + unmarshall(arg1.typeName(), + arg1.data()), + unmarshall(arg2.typeName(), + arg2.data()), + unmarshall(arg3.typeName(), + arg3.data()), + unmarshall(arg4.typeName(), + arg4.data()), + unmarshall(arg5.typeName(), + arg5.data())); + break; + case 7: + stream >> arg0 >> arg1 >> arg2 >> arg3 >> arg4 >> arg5 >> arg6; + QMetaObject::invokeMethod(currentObject(), + methodName, + unmarshall(arg0.typeName(), + arg0.data()), + unmarshall(arg1.typeName(), + arg1.data()), + unmarshall(arg2.typeName(), + arg2.data()), + unmarshall(arg3.typeName(), + arg3.data()), + unmarshall(arg4.typeName(), + arg4.data()), + unmarshall(arg5.typeName(), + arg5.data()), + unmarshall(arg6.typeName(), + arg6.data())); + break; + case 8: + stream >> arg0 >> arg1 >> arg2 >> arg3 >> arg4 >> arg5 >> arg6 >> arg7; + QMetaObject::invokeMethod(currentObject(), + methodName, + unmarshall(arg0.typeName(), + arg0.data()), + unmarshall(arg1.typeName(), + arg1.data()), + unmarshall(arg2.typeName(), + arg2.data()), + unmarshall(arg3.typeName(), + arg3.data()), + unmarshall(arg4.typeName(), + arg4.data()), + unmarshall(arg5.typeName(), + arg5.data()), + unmarshall(arg6.typeName(), + arg6.data()), + unmarshall(arg7.typeName(), + arg7.data())); + break; + case 9: + stream >> arg0 >> arg1 >> arg2 >> arg3 >> arg4 >> arg5 >> arg6 >> arg7 + >> arg8; + QMetaObject::invokeMethod(currentObject(), + methodName, + unmarshall(arg0.typeName(), + arg0.data()), + unmarshall(arg1.typeName(), + arg1.data()), + unmarshall(arg2.typeName(), + arg2.data()), + unmarshall(arg3.typeName(), + arg3.data()), + unmarshall(arg4.typeName(), + arg4.data()), + unmarshall(arg5.typeName(), + arg5.data()), + unmarshall(arg6.typeName(), + arg6.data()), + unmarshall(arg7.typeName(), + arg7.data()), + unmarshall(arg8.typeName(), + arg8.data())); + break; + case 10: + stream >> arg0 >> arg1 >> arg2 >> arg3 >> arg4 >> arg5 >> arg6 >> arg7 + >> arg8 >> arg9; + QMetaObject::invokeMethod(currentObject(), + methodName, + unmarshall(arg0.typeName(), + arg0.data()), + unmarshall(arg1.typeName(), + arg1.data()), + unmarshall(arg2.typeName(), + arg2.data()), + unmarshall(arg3.typeName(), + arg3.data()), + unmarshall(arg4.typeName(), + arg4.data()), + unmarshall(arg5.typeName(), + arg5.data()), + unmarshall(arg6.typeName(), + arg6.data()), + unmarshall(arg7.typeName(), + arg7.data()), + unmarshall(arg8.typeName(), + arg8.data()), + unmarshall(arg9.typeName(), + arg9.data())); + break; + default: + break; + + } + + delete[] className; + delete[] methodName; + method_size = 0; +} + + +DuiRmiServer::DuiRmiServer(const QString &key, QObject *p) + : QObject(p), + d_ptr(new DuiRmiServerPrivateSocket(key)) +{ + d_ptr->q_ptr = this; +} + + +DuiRmiServer::~DuiRmiServer() +{ + delete d_ptr; +} + + +void DuiRmiServer::exportObject(QObject *obj) +{ + Q_D(DuiRmiServer); + d->exportObject(obj); +} + +#include "moc_duirmiserver.cpp" + diff --git a/src/core/duirmiserver.h b/src/core/duirmiserver.h new file mode 100644 index 000000000..53adb2471 --- /dev/null +++ b/src/core/duirmiserver.h @@ -0,0 +1,89 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +// -*- C++ -*- + +#ifndef DUIRMISERVER_H +#define DUIRMISERVER_H + +#include + +#include "duiexport.h" + +class DuiRmiServerPrivate; +class DuiRmiServerPrivateSocket; + +/*! + * \class DuiRmiServer + * \brief The DuiRmiServer provides a way for member functions of QObject-based + * classes to be directly invoked from another process without relying on an + * external transport such as d-bus. + * + * To make a QObject-based class remotely callable from another process, + * ensure that the object has Q_OBJECT macro and the member functions you want + * to export are public slots themselves. + * + * The types of the arguments of those member functions need to be supported + * by QVariant as well. Most Qt types are supported. This include from plain + * old data types to complex GUI types such as QRect, QColor, QImages, and more. + * Container types such as QList are even supported. + * + * If needed, custom complex classes can also be sent across the wire + * provided the operator QVariant(), operator<<() and + * operator>>() are overloaded, and the class is declared in Qt's metaobject + * system using qRegisterMetaType(). Qt uses this class internally for + * mashalling/unmarshalling types (see QMetaType for details). + */ +class DUI_EXPORT DuiRmiServer: public QObject +{ + Q_OBJECT + +public: + /*! + * Creates a DuiRmiServer + * + * \param key a unique key that identifies this server + * \param parent QObject. + */ + explicit DuiRmiServer(const QString &key, QObject *parent = 0); + + /*! + * Disconnects all connections and destroys this object + */ + virtual ~DuiRmiServer(); + + /*! + * Export a QObject for remote invocation. Currently only one QObject per + * DuiRmiServer is supported. + * + * \param object QObject to be exported. + */ + void exportObject(QObject *object); + +private: + Q_DISABLE_COPY(DuiRmiServer) + Q_DECLARE_PRIVATE(DuiRmiServer) + Q_PRIVATE_SLOT(d_func(), void _q_incoming()) + Q_PRIVATE_SLOT(d_func(), void _q_readData()) + + DuiRmiServerPrivate *const d_ptr; + friend class DuiRmiServerPrivateSocket; +}; + +#endif diff --git a/src/core/duirmiserver_p.h b/src/core/duirmiserver_p.h new file mode 100644 index 000000000..b29508dce --- /dev/null +++ b/src/core/duirmiserver_p.h @@ -0,0 +1,68 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIRMISERVER_P_H +#define DUIRMISERVER_P_H + +#include +#include + +class QDataStream; + +class DuiRmiServerPrivate +{ + Q_DECLARE_PUBLIC(DuiRmiServer) +public: + + DuiRmiServerPrivate(const QString &key); + virtual ~DuiRmiServerPrivate(); + virtual void exportObject(QObject *p); + QObject *currentObject(); + QString key() const; + + virtual void _q_incoming() = 0; + virtual void _q_readData() = 0; + + DuiRmiServer *q_ptr; +private: + QString _key; + QObject *_obj; +}; + +class DuiRmiServerPrivateSocket: public DuiRmiServerPrivate +{ + Q_DECLARE_PUBLIC(DuiRmiServer) + +public: + DuiRmiServerPrivateSocket(const QString &key); + + virtual void exportObject(QObject *p); + + virtual void _q_incoming(); + virtual void _q_readData(); + +private: + void invoke(QDataStream &); + + QLocalServer _serv; + QLocalSocket *_sock; + quint16 method_size; +}; + +#endif //DUIRMISERVER_P_H diff --git a/src/core/duishareddata.cpp b/src/core/duishareddata.cpp new file mode 100644 index 000000000..1aeac05f6 --- /dev/null +++ b/src/core/duishareddata.cpp @@ -0,0 +1,529 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include + +#include "duishareddata.h" +#include "duishareddata_p.h" + +void DuiSharedDataPrivate::setKey(const QString &newKey) +{ + key = newKey; + shm = new QSharedMemory(key); +} + +// allocate page identified as [key]_page[num] +QSharedMemory *DuiSharedDataPrivate::allocateNewPage(int num) +{ + QString pageName = key + QString("_page") + QString("%1").arg(num); + + QSharedMemory *newPage = new QSharedMemory(pageName); + + if (!newPage->create(pageSize)) { + if (!newPage->attach()) { + errorString = QString("cannot attach to ") + pageName; + qDebug() << errorString; + delete newPage; + return NULL; + } + + } else { + ownedPages.push_back(newPage); + } + + return newPage; +} + +// allocate new page and set the currentPage to it, update currentPageOffset +QSharedMemory *DuiSharedDataPrivate::allocateNewPage() +{ + int i = 0; + + // find out which value of the index page is not initialized yet + while (*((int *)shm->data() + i)) i++; + + currentPage = allocateNewPage(i); + currentPageNum = i; + + if (i == 0) { + currentPageOffset = 0; + + } else { + currentPageOffset = *((int *)shm->data() + i - 1); + } + + dataByteArray = QByteArray::fromRawData((const char *)currentPage->data(), currentPage->size()); + dataBuffer.setData(dataByteArray); + dataBuffer.open(QIODevice::ReadWrite); + dataStream.setDevice(&dataBuffer); + + return currentPage; +} + +// attach to an existing page identified as [key]_page[num] +QSharedMemory *DuiSharedDataPrivate::attachToPage(int num) +{ + QString pageName = key + QString("_page") + QString("%1").arg(num); + + QSharedMemory *page = new QSharedMemory(pageName); + if (!page->attach(QSharedMemory::ReadOnly)) { + errorString = QString("cannot attach to page ") + pageName + QString(" ") + page->errorString(); + qDebug() << errorString; + return NULL; + } + + if (currentPage) { + dataBuffer.close(); + currentPage->detach(); + delete currentPage; + } + + currentPage = page; + currentPageNum = num; + + if (num > 0) { + currentPageOffset = *((int *)shm->data() + num - 1); + } else { + currentPageOffset = 0; + } + + nextPageOffset = *((int *)shm->data() + num); + + dataByteArray = QByteArray::fromRawData((const char *)currentPage->data(), currentPage->size()); + dataBuffer.setData(dataByteArray); + + if (!dataBuffer.open(QIODevice::ReadOnly)) { + errorString = dataBuffer.errorString(); + delete currentPage; + currentPage = NULL; + + } else { + dataStream.setDevice(&dataBuffer); + errorString = QString(""); + } + +// qDebug() << "attached to " << pageName << " " << currentPage->size() << dataBuffer.buffer().size(); + + return currentPage; +} + +// before each write, save the old pos +// it is restored if the page gets overflown +void DuiSharedDataPrivate::savePos() +{ + oldPos = dataBuffer.pos(); +} + +// check whether we have written beyond the boundary of the current page +// if that's the case then try again after creating new one +bool DuiSharedDataPrivate::pageOverflown() +{ + if (dataBuffer.pos() >= pageSize) { + dataBuffer.seek(oldPos); + flushPage(); + dataBuffer.close(); + allocateNewPage(); + return true; + } + + return false; +} + +// switch to next page if all data on current page has been read +void DuiSharedDataPrivate::nextPage() +{ + if (currentPageOffset + dataBuffer.pos() >= nextPageOffset) { + attachToPage(currentPageNum + 1); + } +} + +// save the current page +void DuiSharedDataPrivate::flushPage() +{ + // update page data + memcpy(currentPage->data(), dataBuffer.data(), currentPage->size()); + *((int *)shm->data() + currentPageNum) = dataBuffer.pos() + currentPageOffset; +} + +DuiSharedData::DuiSharedData(const QString &key, int pageSize) : d_ptr(new DuiSharedDataPrivate) +{ + Q_D(DuiSharedData); + + d->q_ptr = this; + d->pageSize = pageSize; + d->setKey(key); + d->mode = -1; + + const int indexSize = 10000; + + if (!d->shm->create(indexSize)) { + //qDebug() << "unable to allocate shared memory " << key; + + if (!d->shm->attach()) { + d->errorString = QString("unable to attach ") + key; + qDebug() << d->errorString; + } + + } else { + // clean the index page + memset((unsigned char *)d->shm->data(), 0, d->shm->size()); + } + + d->currentPage = NULL; +} + +DuiSharedData::~DuiSharedData() +{ + Q_D(DuiSharedData); + + foreach(QSharedMemory * mem, d->ownedPages) { + mem->detach(); + delete mem; + } + + d->shm->detach(); + delete d->shm; + + delete d_ptr; +} + +QString DuiSharedData::errorString() const +{ + Q_D(const DuiSharedData); + return d->errorString; +} + +DuiSharedData &DuiSharedData::operator<< (int i) +{ + Q_D(DuiSharedData); + + if (d->mode != DuiSharedData::Write) { + qDebug() << "cannot write. Buffer not open or ReadOnly"; + return *this; + } + + d->savePos(); + d->dataStream << i; + if (d->pageOverflown()) { + d->dataStream << i; + } + return *this; +} + +DuiSharedData &DuiSharedData::operator<< (bool flag) +{ + Q_D(DuiSharedData); + + if (d->mode != DuiSharedData::Write) { + qDebug() << "cannot write. Buffer not open or ReadOnly"; + return *this; + } + + d->savePos(); + d->dataStream << flag; + if (d->pageOverflown()) { + d->dataStream << flag; + } + return *this; +} + +DuiSharedData &DuiSharedData::operator<< (qreal r) +{ + Q_D(DuiSharedData); + + if (d->mode != DuiSharedData::Write) { + qDebug() << "cannot write. Buffer not open or ReadOnly"; + return *this; + } + + d->savePos(); + d->dataStream << r; + if (d->pageOverflown()) { + d->dataStream << r; + } + return *this; +} + +DuiSharedData &DuiSharedData::operator<< (QFont font) +{ + Q_D(DuiSharedData); + + if (d->mode != DuiSharedData::Write) { + qDebug() << "cannot write. Buffer not open or ReadOnly"; + return *this; + } + + d->savePos(); + d->dataStream << font; + if (d->pageOverflown()) { + d->dataStream << font; + } + return *this; +} + +DuiSharedData &DuiSharedData::operator<< (QVariant v) +{ + Q_D(DuiSharedData); + + if (d->mode != DuiSharedData::Write) { + qDebug() << "cannot write. Buffer not open or ReadOnly"; + return *this; + } + + d->savePos(); + d->dataStream << v; + if (d->pageOverflown()) { + d->dataStream << v; + } + return *this; +} + +DuiSharedData &DuiSharedData::operator<< (QString str) +{ + Q_D(DuiSharedData); + + if (d->mode != DuiSharedData::Write) { + qDebug() << "cannot write. Buffer not open or ReadOnly"; + return *this; + } + + d->savePos(); + d->dataStream << str; + if (d->pageOverflown()) { + d->dataStream << str; + } + + return *this; +} + +DuiSharedData &DuiSharedData::operator>> (int &i) +{ + Q_D(DuiSharedData); + + if (d->mode != DuiSharedData::ReadOnly) { + qDebug() << "cannot read. Buffer not open or open for writing"; + return *this; + } + + d->nextPage(); + d->dataStream >> i; + + return *this; +} + +DuiSharedData &DuiSharedData::operator>> (bool &flag) +{ + Q_D(DuiSharedData); + + if (d->mode != DuiSharedData::ReadOnly) { + qDebug() << "cannot read. Buffer not open or open for writing"; + return *this; + } + + d->nextPage(); + d->dataStream >> flag; + + return *this; +} + +DuiSharedData &DuiSharedData::operator>> (qreal &r) +{ + Q_D(DuiSharedData); + + if (d->mode != DuiSharedData::ReadOnly) { + qDebug() << "cannot read. Buffer not open or open for writing"; + return *this; + } + + d->nextPage(); + d->dataStream >> r; + + return *this; +} + +DuiSharedData &DuiSharedData::operator>> (QFont &font) +{ + Q_D(DuiSharedData); + + if (d->mode != DuiSharedData::ReadOnly) { + qDebug() << "cannot read. Buffer not open or open for writing"; + return *this; + } + + d->nextPage(); + d->dataStream >> font; + + return *this; +} + +DuiSharedData &DuiSharedData::operator>> (QVariant &v) +{ + Q_D(DuiSharedData); + + if (d->mode != DuiSharedData::ReadOnly) { + qDebug() << "cannot read. Buffer not open or open for writing"; + return *this; + } + + d->nextPage(); + d->dataStream >> v; + + return *this; +} + +DuiSharedData &DuiSharedData::operator>> (QString &str) +{ + Q_D(DuiSharedData); + + if (d->mode != DuiSharedData::ReadOnly) { + qDebug() << "cannot read. Buffer not open or open for writing"; + return *this; + } + + d->nextPage(); + d->dataStream >> str; + + return *this; +} + +bool DuiSharedData::setPageSize(int pageSize) +{ + Q_D(DuiSharedData); + + if (d->mode != -1) { + d->errorString = "cannot change pageSize after shared data buffer was open"; + qDebug() << d->errorString; + return false; + + } else { + d->pageSize = pageSize; + return true; + } +} + +int DuiSharedData::pageSize() const +{ + Q_D(const DuiSharedData); + return d->pageSize; +} + +qint64 DuiSharedData::pos() const +{ + Q_D(const DuiSharedData); + return d->currentPageOffset + d->dataBuffer.pos(); +} + +bool DuiSharedData::seek(qint64 offset) +{ + Q_D(DuiSharedData); + int i = 0, pageOffset; + bool res = false; + + if (d->mode != DuiSharedData::ReadOnly) { + d->errorString = "Cannot seek in buffer which is not ReadOnly"; + qDebug() << d->errorString; + return false; + } + + while ((pageOffset = *((int *)d->shm->data() + i))) { + + if (offset < pageOffset) { + d->attachToPage(i); + qint64 realOffset = (i == 0) ? offset : offset - *((int *)d->shm->data() + i - 1); + + res = d->dataBuffer.seek(realOffset); + if (!res) + d->errorString = d->dataBuffer.errorString(); + + return res; + } + i++; + } + + d->errorString = QString("Offset %1 not found").arg(offset); + qDebug() << d->errorString; + return false; +} + +bool DuiSharedData::open(DuiSharedData::OpenMode mode) +{ + Q_D(DuiSharedData); + + if (!d->errorString.isEmpty()) + return false; + + if (d->mode != -1) { + d->errorString = "Cannot open again. This shared data object is already open"; + qDebug() << d->errorString; + return false; + } + + d->errorString = ""; + d->mode = mode; + + if (mode == DuiSharedData::Write) { + memset((unsigned char *)d->shm->data(), 0, d->shm->size()); + if (d->allocateNewPage()) + return true; + else + return false; + + } else if (mode == DuiSharedData::ReadOnly) { + if (d->attachToPage(0)) + return true; + else + return false; + + } else { + d->errorString = "Unknown openmode. Only DuiSharedData::Write and DuiSharedData::ReadOnly are possible"; + qDebug() << d->errorString; + return false; + } +} + +void DuiSharedData::close() +{ + Q_D(DuiSharedData); + + if (d->mode == DuiSharedData::Write) { + if (d->dataBuffer.pos() != 0) { + d->flushPage(); + + } else { + // nothing was written on that page, destroy it + + d->currentPage->detach(); + d->ownedPages.removeOne(d->currentPage); + delete d->currentPage; + } + + } else if (d->mode == DuiSharedData::ReadOnly) { + if (d->currentPage) { + d->currentPage->detach(); + delete d->currentPage; + } + } + + d->currentPage = 0; + d->dataBuffer.close(); + d->mode = -1; + d->errorString = ""; +} + diff --git a/src/core/duishareddata.h b/src/core/duishareddata.h new file mode 100644 index 000000000..d2a56dc35 --- /dev/null +++ b/src/core/duishareddata.h @@ -0,0 +1,209 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISHARED_DATA_H +#define DUISHARED_DATA_H + +#include +#include +#include +#include +#include +#include + +#include "duiexport.h" + +/*! + + \class DuiSharedData + \brief DuiSharedData is a helper ilass that implements a shared memory buffer. + It can have an arbitrary size and support complex data structures through serialization. + Internally, DuiSharedData uses QSharedMemory. + + DuiSharedMemory is optimized in terms of its memory consumption. It uses paging to vary its size. + Initially, only 1 page is allocated. However, additional pages are allocated as needed. + + QSharedMemory provides a plain buffer. It is often needed to store data structures with + internal pointers, for example QList. Serialization is a mechanism that allows saving such + data structures to hard drives. We are employing the same mechanism to store such a data structure + in a shared memory buffer. + Similar to QDataStream, DuiSharedData provides operators << and >> to save and load complex data + structures. + It is possible to open DuiSharedData in either of two modes: ReadOnly and Write. + + Even though DuiSharedData employs paging mechanism to facilitate gradual buffer growth, + to the programmer it appears as one continuous area of memory. Therefore, functions pos() and + seek() use continuous offset which always increases as more data is written into the memory, even + after new pages are created. + + The use case is as follows. The theme daemon creates a shared memory buffer and populates it with data: + + \code + DuiSharedData *shm = new DuiSharedData("buffer"); + shm->open(DuiSharedData::Write); + *shm << QString("data"); + *shm << qVariantFromValue(QColor(Qt::white)); + shm->close(); + \endcode + + The application opens the shared buffer for reading and de-serializes the data: + + \code + DuiSharedData *shm = new DuiSharedData("buffer"); + shm->open(DuiSharedData::ReadOnly); + QString str; + QVariant color; + *shm >> str >> color; + shm->close(); + \endcode + +*/ + +class DuiSharedDataPrivate; + +class DUI_EXPORT DuiSharedData : public QObject +{ + Q_OBJECT + + Q_PROPERTY(int pageSize READ pageSize WRITE setPageSize) + Q_ENUMS(OpenMode) + +public: + enum OpenMode { ReadOnly, Write }; + + /*! + * \brief A constructor. Creates a shared memory buffer with a given key. + */ + DuiSharedData(const QString &key, int pageSize = 8192); + + /*! + * \brief A destructor. Detaches from every page it was attached to. + */ + ~DuiSharedData(); + + /*! + * \brief Opens the shared memory buffer for reading or for writing. + */ + bool open(OpenMode mode); + + /*! + * \brief Closes the memory buffer and flushes all updated pages. + */ + void close(); + + /*! + * \brief Returns the error string. Empty if no error has occurred. + */ + QString errorString() const; + + /*! + * \brief Sets the page size. The default value is 8192 bytes. + * Returns true if the new page size was set, false if there was an error. + * \sa pageSize() + */ + bool setPageSize(int pageSize); + + /*! + * \brief Returns the page size. + * \sa setPageSize() + */ + int pageSize() const; + + /*! + * Returns the current offset within the shared memory buffer. + * \sa seek() + */ + qint64 pos() const; + + /*! + * Sets the current offset within the shared memory buffer. + * \sa pos() + */ + bool seek(qint64 offset); + + /*! + * Writes integer to shared memory + */ + DuiSharedData &operator<< (int i); + + /*! + * Writes boolean to shared memory + */ + DuiSharedData &operator<< (bool flag); + + /*! + * Writes qreal to shared memory + */ + DuiSharedData &operator<< (qreal r); + + /*! + * Write QFont to shared memory + */ + DuiSharedData &operator<< (QFont font); + + /*! + * Writes QVariant to shared memory + */ + DuiSharedData &operator<< (QVariant v); + + /*! + * Writes QString to shared memory + */ + DuiSharedData &operator<< (QString str); + + /*! + * Reads integer from shared memory + */ + DuiSharedData &operator>> (int &i); + + /*! + * Reads boolean from shared memory + */ + DuiSharedData &operator>> (bool &i); + + /*! + * Reads qreal from shared memory + */ + DuiSharedData &operator>> (qreal &r); + + /*! + * Reads QFont from shared memory + */ + DuiSharedData &operator>> (QFont &font); + + /*! + * Reads QVariant from shared memory + */ + DuiSharedData &operator>> (QVariant &v); + + /*! + * Reads QString from shared memory + */ + DuiSharedData &operator>> (QString &str); + +protected: + DuiSharedDataPrivate *const d_ptr; + +private: + Q_DISABLE_COPY(DuiSharedData) + Q_DECLARE_PRIVATE(DuiSharedData) +}; + +#endif + diff --git a/src/core/duishareddata_p.h b/src/core/duishareddata_p.h new file mode 100644 index 000000000..284b891d6 --- /dev/null +++ b/src/core/duishareddata_p.h @@ -0,0 +1,71 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISHARED_DATA_P_H +#define DUISHARED_DATA_P_H + +#include +#include +#include +#include + +class DuiSharedData; + +class DuiSharedDataPrivate +{ + Q_DECLARE_PUBLIC(DuiSharedData) + +public: + QSharedMemory *shm; + QByteArray dataByteArray; + QBuffer dataBuffer; + QDataStream dataStream; + qint64 oldPos; + + QSharedMemory *allocateNewPage(); + QSharedMemory *allocateNewPage(int num); + + QSharedMemory *attachToPage(int num); + + void flushPage(); + bool pageOverflown(); + void nextPage(); + void savePos(); + + void setKey(const QString &key); + + int currentPageOffset; + int nextPageOffset; + int currentPageNum; + QSharedMemory *currentPage; + + int mode; + + int pageSize; + QString key; + QList ownedPages; + + QString errorString; + +protected: + DuiSharedData *q_ptr; +}; + +#endif + diff --git a/src/core/duitimestamp.cpp b/src/core/duitimestamp.cpp new file mode 100644 index 000000000..20c2cd0d7 --- /dev/null +++ b/src/core/duitimestamp.cpp @@ -0,0 +1,40 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duitimestamp.h" + +#include "duidebug.h" +#include +#include +#include +#include +#include + +void DUI_EXPORT duiTimestampStream(const QString &module, const QString &file, const QString &scope, const QString &msg) +{ + static const QString format("%1.%2 MARK|%3|%4|%5"); + static const QChar fill('0'); + QString output; + struct timeval tv; + + gettimeofday(&tv, 0); + + output = format.arg(tv.tv_sec).arg(tv.tv_usec, 6, 10, fill).arg(file).arg(scope).arg(msg); + duiWarning(module) << output; +} diff --git a/src/core/duitimestamp.h b/src/core/duitimestamp.h new file mode 100644 index 000000000..051417532 --- /dev/null +++ b/src/core/duitimestamp.h @@ -0,0 +1,50 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUITIMESTAMP_H +#define DUITIMESTAMP_H + +#include +#include "duiexport.h" + +void DUI_EXPORT duiTimestampStream(const QString &module, const QString &file, const QString &scope, const QString &msg); + +#if defined(QT_NO_WARNING_OUTPUT) || !defined(DUI_TIMESTAMP) +#define duiTimestamp(x, msg) +#else + +/** + * Prints debug message with timestamp. + * This function do nothing if macro DUI_TIMESTAMP is not defined. + * + * Example: + *\code + * #include + * + * duiTimestamp("ModuleName", "Do something"); + *\endcode + * + */ + +#define duiTimestamp(x, msg) duiTimestampStream(x, __FILE__, __PRETTY_FUNCTION__, msg) + +#endif + +#endif + diff --git a/src/core/duiwidgetaction.cpp b/src/core/duiwidgetaction.cpp new file mode 100644 index 000000000..a86122838 --- /dev/null +++ b/src/core/duiwidgetaction.cpp @@ -0,0 +1,127 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiwidgetaction.h" +#include "duiwidgetaction_p.h" + +#include +#include + +#include "duiwidget.h" + +DuiWidgetActionPrivate::DuiWidgetActionPrivate() + : widget(0) + , widgetInUse(false) +{ +} + +DuiWidgetActionPrivate::~DuiWidgetActionPrivate() +{ + if (widget) { + delete widget; + widget = 0; + } +} + +DuiWidgetAction::DuiWidgetAction(QObject *parent) + : DuiAction(*new DuiWidgetActionPrivate, parent) +{ +} + +DuiWidgetAction::~DuiWidgetAction() +{ +} + +void DuiWidgetAction::setWidget(DuiWidget *widget) +{ + Q_D(DuiWidgetAction); + + if (widget == d->widget || d->widgetInUse) + return; + + // we are the owner, delete evtl. set widget + delete d->widget; + + // set new default widget + d->widget = widget; + if (!widget) + return; + + setVisible(widget->isVisible()); + + d->widget->hide(); + d->widget->setParentItem(0); + d->widgetInUse = false; + + if (! isEnabled()) + d->widget->setEnabled(false); +} + +DuiWidget *DuiWidgetAction::widget() const +{ + Q_D(const DuiWidgetAction); + + return d->widget; +} + +DuiWidget *DuiWidgetAction::requestWidget(DuiWidget *parent) +{ + Q_D(DuiWidgetAction); + + if (d->widgetInUse || !d->widget) + return 0; + + d->widget->setParentItem(parent); + d->widgetInUse = true; + + return d->widget; +} + +void DuiWidgetAction::releaseWidget(DuiWidget *widget) +{ + Q_D(DuiWidgetAction); + + if (widget == d->widget && d->widget) { + d->widget->hide(); + d->widget->setParentItem(0); + d->widgetInUse = false; + } +} + +bool DuiWidgetAction::isWidgetInUse() const +{ + Q_D(const DuiWidgetAction); + return d->widgetInUse; +} + +bool DuiWidgetAction::event(QEvent *event) +{ + Q_D(DuiWidgetAction); + + if (event->type() == QEvent::ActionChanged) { + if (d->widget) + d->widget->setEnabled(isEnabled()); + } + return DuiAction::event(event); +} + +bool DuiWidgetAction::eventFilter(QObject *obj, QEvent *event) +{ + return DuiAction::eventFilter(obj, event); +} diff --git a/src/core/duiwidgetaction.h b/src/core/duiwidgetaction.h new file mode 100644 index 000000000..e7bd7a71c --- /dev/null +++ b/src/core/duiwidgetaction.h @@ -0,0 +1,111 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIWIDGETACTION_H +#define DUIWIDGETACTION_H + +#include "duiaction.h" + +class DuiWidget; +class DuiWidgetActionPrivate; + +/** + \class DuiWidgetAction + \brief The DuiWidgetAction class extends DuiAction by an interface + for inserting custom widgets into action based containers, such as DuiToolBar. + + A custom widget can be set using setWidget() and that widget will then be used + if the action is added to a DuiToolBar, or in general to an action container that + supports DuiWidgetAction. If a DuiWidgetAction is added to two toolbars (e.g.) at the + same time then the widget is shown only in the first toolbar the action was added + to. DuiWidgetAction takes over ownership of the widget. + + Note that it is up to the widget to activate the action, for example by + reimplementing mouse event handlers and calling DuiAction::trigger(). + + \sa DuiAction +*/ + +class DUI_EXPORT DuiWidgetAction : public DuiAction +{ + Q_OBJECT + +public: + /** + \brief Default constructor + \param parent Pointer to parent object + */ + explicit DuiWidgetAction(QObject *parent); + + /** + \brief Destructor + */ + virtual ~DuiWidgetAction(); + + /** + \brief Sets \a widget to the action. The ownership is + transferred to DuiWidgetAction. + */ + void setWidget(DuiWidget *w); + + /** + \brief Returns the widget attached. + */ + DuiWidget *widget() const; + + /** + \brief Returns a widget that represents the action, with the given \a parent. + + Container widgets that support actions can call this function to + request a widget as visual representation of the action. + \sa releaseWidget(), widget() + */ + DuiWidget *requestWidget(DuiWidget *parent); + + /** + \brief Releases the specified \a widget. + + Container widgets that support actions call this function when a widget + action is removed. + \sa requestWidget(), widget() + */ + void releaseWidget(DuiWidget *widget); + + /*! + \brief Returns the status whether the default widget is in use or not + */ + bool isWidgetInUse() const; + +protected: + + //! \reimp + virtual bool event(QEvent *); + virtual bool eventFilter(QObject *, QEvent *); + //! \reimp_end + +private: + Q_DECLARE_PRIVATE(DuiWidgetAction) + Q_DISABLE_COPY(DuiWidgetAction) + +#ifdef UNIT_TEST + friend class Ut_DuiWidgetAction; +#endif +}; + +#endif // DUIWIDGETACTION_H diff --git a/src/core/duiwidgetaction_p.h b/src/core/duiwidgetaction_p.h new file mode 100644 index 000000000..30b0e8d3c --- /dev/null +++ b/src/core/duiwidgetaction_p.h @@ -0,0 +1,39 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIWIDGETACTION_P_H +#define DUIWIDGETACTION_P_H + +#include "duiaction_p.h" + +#include + +#include "duiwidget.h" + +class DuiWidgetActionPrivate : public DuiActionPrivate +{ +public: + DuiWidgetActionPrivate(); + virtual ~DuiWidgetActionPrivate(); + + QPointer widget; + bool widgetInUse; +}; + +#endif diff --git a/src/core/testabilityinterface.h b/src/core/testabilityinterface.h new file mode 100644 index 000000000..0f3158f3e --- /dev/null +++ b/src/core/testabilityinterface.h @@ -0,0 +1,41 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include + +//! \internal +class TestabilityInterface +{ +public: + virtual ~TestabilityInterface() {} + + /*! + + Initializes the plugin once loaded. + + */ + virtual void Initialize() = 0; + + +}; +//! \internal_end + +Q_DECLARE_INTERFACE(TestabilityInterface, + "com.nokia.testability.TestabilityInterface/1.0") diff --git a/src/dui.prf b/src/dui.prf new file mode 100644 index 000000000..1a158922a --- /dev/null +++ b/src/dui.prf @@ -0,0 +1,54 @@ +###################################################################### +# DuiFeature +###################################################################### +macx { + INCLUDEPATH += /Library/Frameworks/dui.framework/Headers + LIBS += -framework dui +} else { + + contains(TEMPLATE, app) { + DEFINES += DUI_APPLICATION_NAME=\\\"${QMAKE_TARGET}\\\" + } else { + contains(TEMPLATE, lib) { + DEFINES += DUI_LIBRARY_NAME=\\\"lib${QMAKE_TARGET}\\\" + } else { + # error(Unknown template) + } + } + + !contains(DEFINES, BUILD_DUI) { + DUI_INC_DIR = /usr/include/dui + DUI_LIB_DIR = /usr/lib + + GSTREAMER_INC = /usr/include/gstreamer-0.10 /usr/include/glib-2.0 /usr/lib/glib-2.0/include /usr/include/libxml2 + + INCLUDEPATH += $${DUI_INC_DIR} $${GSTREAMER_INC} + DEPENDPATH += $${DUI_INC_DIR} + + unix: QMAKE_LFLAGS += $${QMAKE_RPATH}$${DUI_LIB_DIR} + LIBS += -L$${DUI_LIB_DIR} -ldui + QMAKE_MOC = duimoc + + isEmpty(DUIGEN_OUTDIR) { + DUIGEN_OUTDIR = . + } + + duigenerator_model.name = duigenerator model + duigenerator_model.input = MODEL_HEADERS + duigenerator_model.output = $$DUIGEN_OUTDIR/gen_${QMAKE_FILE_BASE}data.cpp + duigenerator_model.commands += duigen --model ${QMAKE_FILE_NAME} $$DUIGEN_OUTDIR + duigenerator_model.clean += $$DUIGEN_OUTDIR/gen_* + duigenerator_model.CONFIG = target_predeps no_link + duigenerator_model.variable_out = GENERATED_SOURCES + QMAKE_EXTRA_COMPILERS += duigenerator_model + + duigenerator_style.name = duigenerator style + duigenerator_style.input = STYLE_HEADERS + duigenerator_style.output = $$DUIGEN_OUTDIR/gen_${QMAKE_FILE_BASE}data.cpp + duigenerator_style.commands += duigen --style ${QMAKE_FILE_NAME} $$DUIGEN_OUTDIR + duigenerator_style.clean += $$DUIGEN_OUTDIR/gen_* + duigenerator_style.CONFIG = target_predeps no_link + duigenerator_style.variable_out = GENERATED_SOURCES + QMAKE_EXTRA_COMPILERS += duigenerator_style + } +} diff --git a/src/dui_defines.prf b/src/dui_defines.prf new file mode 100644 index 000000000..8a846e672 --- /dev/null +++ b/src/dui_defines.prf @@ -0,0 +1,91 @@ +################################################################## +# DuiDefinesFeature +# +# Global DirectUI definitions +###################################################################### + +DUI_MAJOR_VERSION = 0 +DUI_MINOR_VERSION = 19 +DUI_PATCH_VERSION = 0 +DUI_VERSION=$${DUI_MAJOR_VERSION}.$${DUI_MINOR_VERSION}.$${DUI_PATCH_VERSION} + +# Directories +unix { + DUI_PREFIX = /usr + + DUI_INSTALL_BIN = $$DUI_PREFIX/bin + DUI_INSTALL_LIBS = $$DUI_PREFIX/lib + DUI_INSTALL_DATA = $$DUI_PREFIX/share + DUI_INSTALL_HEADERS = $$DUI_PREFIX/include/dui + DUI_INSTALL_SYSCONF = /etc + DUI_INSTALL_XSESSION = $$DUI_INSTALL_SYSCONF/X11 + DUI_INSTALL_LOCALSTATE = /var + + DUI_THEME_DIR = $$DUI_INSTALL_DATA/themes + DUI_THEME_PRELOAD_DIR = $$DUI_INSTALL_LOCALSTATE/lib/dui/theme/preload.d + DUI_THEME_POST_PRELOAD_DIR = $$DUI_INSTALL_LOCALSTATE/lib/dui/theme/preload.post + + DUI_APPLET_DIR = $$DUI_PREFIX/lib/dui/applets + DUI_APPLET_INSTALLATION_SOURCES_DIR = $$DUI_PREFIX/lib/dui/appletinstallationsources + DUI_APPLET_DATA_DIR = $$DUI_INSTALL_DATA/dui/applets + DUI_APPLET_SETTINGS_DIR = $$DUI_INSTALL_DATA/dui/applets/settings + + DUI_NOTIFICATIONS_EVENT_TYPES_DIR=$$DUI_INSTALL_DATA/dui/notifications/eventtypes + DUI_XDG_DIR = $$DUI_INSTALL_SYSCONF/xdg + DUI_TRANSLATION_DIR = $$DUI_INSTALL_DATA/l10n/dui + DUI_DBUS_INTERFACES_DIR = /usr/share/dbus-1/interfaces + DUI_DBUS_SERVICES_DIR = $$system(pkg-config --variable session_bus_services_dir dbus-1) + + DUI_SHADER_SOURCE_DIR = $$DUI_INSTALL_DATA/dui/shaders + DUI_SHADER_BINARY_DIR = $$DUI_INSTALL_LOCALSTATE/cache/dui/shaders +} +mac { + DUI_PREFIX = /usr + + DUI_INSTALL_BIN = $$DUI_PREFIX/bin + DUI_INSTALL_LIBS = $$DUI_PREFIX/lib + DUI_INSTALL_DATA = $$DUI_PREFIX/share + DUI_INSTALL_HEADERS = $$DUI_PREFIX/include/dui + DUI_INSTALL_SYSCONF = /etc + DUI_INSTALL_LOCALSTATE = /var + + DUI_THEME_DIR = $$DUI_INSTALL_DATA/themes + + DUI_APPLET_DIR = $$DUI_PREFIX/lib/dui/applets + DUI_APPLET_INSTALLATION_SOURCES_DIR = $$DUI_PREFIX/lib/dui/appletinstallationsources + DUI_APPLET_DATA_DIR = $$DUI_INSTALL_DATA/dui/applets + DUI_APPLET_SETTINGS_DIR = $$DUI_INSTALL_DATA/dui/applets/settings + + DUI_NOTIFICATIONS_EVENT_TYPES_DIR=$$DUI_INSTALL_DATA/dui/notifications/eventtypes + DUI_XDG_DIR = $$DUI_INSTALL_SYSCONF/xdg + DUI_TRANSLATION_DIR = $$DUI_INSTALL_DATA/l10n/dui + DUI_DBUS_INTERFACES_DIR = $$DUI_INSTALL_DATA/dbus-1/interfaces + DUI_DBUS_SERVICES_DIR = $$DUI_INSTALL_DATA/dbus-1/services + + DUI_SHADER_SOURCE_DIR = $$DUI_INSTALL_DATA/dui/shaders + DUI_SHADER_BINARY_DIR = $$DUI_INSTALL_LOCALSTATE/cache/dui/shaders +} +win32 { + DUI_PREFIX = + + DUI_INSTALL_BIN = /bin + DUI_INSTALL_LIBS = /bin + DUI_INSTALL_DATA = /share + DUI_INSTALL_HEADERS = /include/dui + DUI_INSTALL_SYSCONF = /etc + DUI_INSTALL_LOCALSTATE = /var + + DUI_THEME_DIR = /themes + + DUI_APPLET_DIR = /lib/dui/applets + DUI_APPLET_INSTALLATION_SOURCES_DIR = /lib/dui/appletinstallationsources + DUI_APPLET_DATA_DIR = $$DUI_INSTALL_DATA/dui/applets + + DUI_NOTIFICATIONS_EVENT_TYPES_DIR=$$DUI_INSTALL_DATA/dui/notifications/eventtypes + DUI_TRANSLATION_DIR = $$DUI_INSTALL_DATA/l10n/dui + DUI_DBUS_INTERFACES_DIR = $$DUI_INSTALL_DATA/dbus-1/interfaces + DUI_DBUS_SERVICES_DIR = $$DUI_INSTALL_DATA/dbus-1/services + + DUI_SHADER_SOURCE_DIR = $$DUI_INSTALL_DATA/dui/shaders + DUI_SHADER_BINARY_DIR = $$DUI_INSTALL_LOCALSTATE/cache/dui/shaders +} diff --git a/src/events/duicancelevent.cpp b/src/events/duicancelevent.cpp new file mode 100644 index 000000000..63b2f7c4b --- /dev/null +++ b/src/events/duicancelevent.cpp @@ -0,0 +1,36 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duicancelevent.h" + +static int duiCancelEventNumber = -1; + +DuiCancelEvent::DuiCancelEvent() + : QGraphicsSceneEvent(DuiCancelEvent::eventNumber()) +{ + +} + +//Static +QEvent::Type DuiCancelEvent::eventNumber() +{ + if (duiCancelEventNumber < 0) + duiCancelEventNumber = QEvent::registerEventType(); + return (QEvent::Type)duiCancelEventNumber; +} diff --git a/src/events/duicancelevent.h b/src/events/duicancelevent.h new file mode 100644 index 000000000..1810b5132 --- /dev/null +++ b/src/events/duicancelevent.h @@ -0,0 +1,53 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUICANCELEVENT_H +#define DUICANCELEVENT_H + +#include +#include "duiexport.h" + +/*! + * Class instantiated when the result of previously sent event + * should be cancelled. + * The cancel event can for example be sent when the user presses + * the touchscreen and starts to move his/her finger to pan the view. + * At the moment of first press event the mousePressEvent is sent + * to the widgets below pannable viewport, but it needs to be + * "cancelled" if the user wanted to pan the viewport. + */ +class DUI_EXPORT DuiCancelEvent : public QGraphicsSceneEvent +{ +public: + + /*! + * \brief Cancel Event definition. + */ + static QEvent::Type eventNumber(); + + /*! + * \brief Default constructor, no need for any parameters. + */ + explicit DuiCancelEvent(); + +private: + Q_DISABLE_COPY(DuiCancelEvent) +}; + +#endif diff --git a/src/events/duidismissevent.cpp b/src/events/duidismissevent.cpp new file mode 100644 index 000000000..59a0f53f8 --- /dev/null +++ b/src/events/duidismissevent.cpp @@ -0,0 +1,37 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duidismissevent.h" + +static int _duiDismissEventTypeValue = -1; + +DuiDismissEvent::DuiDismissEvent() + : QEvent(eventType()) +{ + +} + +QEvent::Type DuiDismissEvent::eventType() +{ + if (_duiDismissEventTypeValue < 0) { + _duiDismissEventTypeValue = QEvent::registerEventType(); + } + return (QEvent::Type) _duiDismissEventTypeValue; +} + diff --git a/src/events/duidismissevent.h b/src/events/duidismissevent.h new file mode 100644 index 000000000..f714d9774 --- /dev/null +++ b/src/events/duidismissevent.h @@ -0,0 +1,79 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIDISMISSEVENT_H +#define DUIDISMISSEVENT_H + +#include +#include "duiexport.h" + +/*! + * Dismiss events are sent to scene windows that the user wants to dismiss. Usually + * by tapping the back button (for DuiApplicationPage), a close button (e.g. in the + * title bar of a DuiDialog) or by tapping outside a modal scene window. They are + * also sent when you call DuiSceneWindow::dismiss() to dismiss a scene window + * programmatically. + * + * Dismiss events contain a flag that indicates whether the receiver wants the + * scene window to be dismissed or not. When a scene window accepts the dismiss + * event, it disappears (and is destroyed if DuiSceneWindow::DestroyWhenDone + * was used). If it refuses to accept the dismiss event nothing happens. + * The event handler DuiScenewindow::dismissEvent() receives dismiss events. The + * default implementation of this event handler accepts the dismiss event. If + * you do not want your scene window to disappear, or want some special handing, + * you should reimplement the event handler and ignore() the event. + * + * The difference between DuiDismissEvent and QCloseEvent is that the former + * causes the scene window to disappear (which makes it leave the scene with an + * optionally animated transition and finally hides it) where the latter only + * hides the scene window (it will still occupy the scene and no transition + * animation will take place). + * + * If you want the scene window to be deleted after it disappears, pass + * DuiSceneWindow::DestroyWhenDone when calling DuiSceneWindow::appear() or + * DuiSceneWindow::appearNow(). This is very useful for independent scene windows. + * + * QObjects emits the destroyed() signal when they are deleted. + * + * The isAccepted() method returns true if the event's receiver has agreed to + * dismiss the scene window; call accept() to agree to dismiss the scene window + * and call ignore() if the receiver of this event does not want the scene window + * to be closed. + * + * \sa DuiSceneWindow::dismiss() + */ +class DUI_EXPORT DuiDismissEvent : public QEvent +{ +public: + /*! + * \brief Default constructor, no need for any parameters. + */ + explicit DuiDismissEvent(); + + /*! + * \brief Event type for DuiDismissEvent. + */ + static QEvent::Type eventType(); + +private: + Q_DISABLE_COPY(DuiDismissEvent) +}; + + +#endif diff --git a/src/events/duiondisplaychangeevent.cpp b/src/events/duiondisplaychangeevent.cpp new file mode 100644 index 000000000..bfec37b62 --- /dev/null +++ b/src/events/duiondisplaychangeevent.cpp @@ -0,0 +1,66 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiondisplaychangeevent.h" +#include "duiondisplaychangeevent_p.h" + +static int duiOnDisplayChangeEventNumber = -1; + +DuiOnDisplayChangeEventPrivate::DuiOnDisplayChangeEventPrivate(DuiOnDisplayChangeEvent::State newState, const QRectF &newViewRect) : + state(newState), + viewRect(newViewRect) +{} + +DuiOnDisplayChangeEventPrivate::~DuiOnDisplayChangeEventPrivate() +{} + +DuiOnDisplayChangeEvent::DuiOnDisplayChangeEvent(State state, const QRectF &viewRect) : + QGraphicsSceneEvent(DuiOnDisplayChangeEvent::eventNumber()), + d_ptr(new DuiOnDisplayChangeEventPrivate(state, viewRect)) +{} + +DuiOnDisplayChangeEvent::DuiOnDisplayChangeEvent(bool visible, const QRectF &viewRect) : + QGraphicsSceneEvent(DuiOnDisplayChangeEvent::eventNumber()), + d_ptr(new DuiOnDisplayChangeEventPrivate(visible ? FullyOnDisplay : FullyOffDisplay, viewRect)) +{} + +DuiOnDisplayChangeEvent::State DuiOnDisplayChangeEvent::state() const +{ + Q_D(const DuiOnDisplayChangeEvent); + return d->state; +} + +QRectF DuiOnDisplayChangeEvent::viewRect() const +{ + Q_D(const DuiOnDisplayChangeEvent); + return d->viewRect; +} + +DuiOnDisplayChangeEvent::~DuiOnDisplayChangeEvent() +{ + delete d_ptr; +} + +//Static +QEvent::Type DuiOnDisplayChangeEvent::eventNumber() +{ + if (duiOnDisplayChangeEventNumber < 0) + duiOnDisplayChangeEventNumber = QEvent::registerEventType(); + return (QEvent::Type)duiOnDisplayChangeEventNumber; +} diff --git a/src/events/duiondisplaychangeevent.h b/src/events/duiondisplaychangeevent.h new file mode 100644 index 000000000..7d78742c4 --- /dev/null +++ b/src/events/duiondisplaychangeevent.h @@ -0,0 +1,94 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIONDISPLAYCHANGEEVENT_H +#define DUIONDISPLAYCHANGEEVENT_H + +#include +#include "duiexport.h" + +class DuiOnDisplayChangeEventPrivate; + +/*! + * This event is sent to a DuiWidget so that it can notify subscribers + * about changes on its presence on display. The event can be triggered by + * e.g. panning or switching a DuiApplicationPage or obscuring the DuiApplicationWindow + * with another window. Note that this differs from Qt's explicit hide()/show() + * semantics. DuiWidget forwards this event to its children. + */ +class DUI_EXPORT DuiOnDisplayChangeEvent : public QGraphicsSceneEvent +{ +public: + + /*! + * \brief Possible visibility states. + */ + enum State {FullyOnDisplay = 0, /*!< Widget is definitely fully on display */ + FullyOffDisplay, /*!< Widget is definitely fully off display */ + MustBeResolved, /*!< Widget must use viewRect to verify its presence on the display, + as well as of all its children. */ + PartiallyOnDisplay /*!< Widget is partially present on the display, according to its + bounding rectangle. Widget may still use viewRect to get a more + precise (and therefore more computationally expensive) assertion + by comparing it against its shape, for instance. */ + }; + + /*! + * \brief Cancel Event definition. + */ + static QEvent::Type eventNumber(); + + /*! + * \brief Constructor + * \param newState new visibility state + * \param Viewport rectangle. Used to resolve the visibility if + * widget may be only partially on the display + */ + DuiOnDisplayChangeEvent(State state, const QRectF &viewRect); + + /*! + * \brief Convenience constructor + * \param visible true : FullyOnDisplay, false : FullyOffDisplay + * \param Viewport rectangle. Used to resolve the visibility if + * widget may be only partially on the display + */ + DuiOnDisplayChangeEvent(bool visible, const QRectF &viewRect); + + //! Destructor + virtual ~DuiOnDisplayChangeEvent(); + + /*! + * \brief Return the state. + */ + State state() const; + + /*! + * \brief Return the viewport rectangle. + */ + QRectF viewRect() const; + +protected: + DuiOnDisplayChangeEventPrivate *const d_ptr; + +private: + Q_DECLARE_PRIVATE(DuiOnDisplayChangeEvent) + Q_DISABLE_COPY(DuiOnDisplayChangeEvent) +}; + +#endif // DUIONDISPLAYCHANGEEVENT_H diff --git a/src/events/duiondisplaychangeevent_p.h b/src/events/duiondisplaychangeevent_p.h new file mode 100644 index 000000000..83fef5769 --- /dev/null +++ b/src/events/duiondisplaychangeevent_p.h @@ -0,0 +1,33 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIONDISPLAYCHANGEEVENT_P_H +#define DUIONDISPLAYCHANGEEVENT_P_H + +class DuiOnDisplayChangeEventPrivate +{ +public: + DuiOnDisplayChangeEventPrivate(DuiOnDisplayChangeEvent::State newState, const QRectF &newViewRect); + virtual ~DuiOnDisplayChangeEventPrivate(); + + DuiOnDisplayChangeEvent::State state; + QRectF viewRect; +}; + +#endif // DUIONDISPLAYCHANGEEVENT_P_H diff --git a/src/events/duiorientationchangeevent.cpp b/src/events/duiorientationchangeevent.cpp new file mode 100644 index 000000000..d2792f94a --- /dev/null +++ b/src/events/duiorientationchangeevent.cpp @@ -0,0 +1,40 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiorientationchangeevent.h" + +static int duiOrientationChangeEventNumber = -1; + +DuiOrientationChangeEvent::DuiOrientationChangeEvent(Dui::Orientation newOrientation) : + QGraphicsSceneEvent(DuiOrientationChangeEvent::eventNumber()), + o(newOrientation) +{ +} + +QEvent::Type DuiOrientationChangeEvent::eventNumber() +{ + if (duiOrientationChangeEventNumber < 0) + duiOrientationChangeEventNumber = QEvent::registerEventType(); + return (QEvent::Type)duiOrientationChangeEventNumber; +} + +Dui::Orientation DuiOrientationChangeEvent::orientation() const +{ + return o; +} diff --git a/src/events/duiorientationchangeevent.h b/src/events/duiorientationchangeevent.h new file mode 100644 index 000000000..f5b19eb71 --- /dev/null +++ b/src/events/duiorientationchangeevent.h @@ -0,0 +1,67 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIORIENTATIONCHANGEEVENT_H +#define DUIORIENTATIONCHANGEEVENT_H + +#include +#include "duiexport.h" +#include "duinamespace.h" + +/*! + * \brief This class contains event parameters for orientation change events. + * + * The orientation change event occurs whenever the viewport changes its + * orientation between landscape and portrait (note that it doesn't occur + * when changing angle e.g. from 0 directly to 180 degrees). + * + * It is used to notify widgets about the orientation change. It can be asked + * about the new orientation of the viewport. You can handle this event + * either by catching it in QGraphicsItem::event() or reimplementing + * DuiWidget::orientationChangeEvent(). + * + * \sa DuiWidget::orientationChangeEvent() + */ +class DUI_EXPORT DuiOrientationChangeEvent : public QGraphicsSceneEvent +{ +public: + + /*! + * Orientation change event definition. Used to identify the type of the event. + */ + static QEvent::Type eventNumber(); + + /*! + * Creates a new orientation change event with the orientation specified by \a newOrientation. + */ + explicit DuiOrientationChangeEvent(Dui::Orientation newOrientation = Dui::Landscape); + + /*! + * Holds the new orientation of the viewport. + */ + Dui::Orientation orientation() const; + +protected: + Dui::Orientation o; + +private: + Q_DISABLE_COPY(DuiOrientationChangeEvent) +}; + +#endif diff --git a/src/events/duiorientationtracker.cpp b/src/events/duiorientationtracker.cpp new file mode 100644 index 000000000..3870a5d7c --- /dev/null +++ b/src/events/duiorientationtracker.cpp @@ -0,0 +1,145 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiorientationtracker.h" +#include "duiorientationtracker_p.h" +#include "duiapplication.h" +#include "duiwindow.h" +#include +#include +#include + +#include + +DuiOrientationTracker *DuiOrientationTrackerPrivate::tracker = 0; + +DuiOrientationTrackerPrivate::DuiOrientationTrackerPrivate(DuiOrientationTracker *controller) : + currentAngle(Dui::Angle0), + currentIsCovered(false) +#ifdef HAVE_CONTEXTSUBSCRIBER + , topEdgeProperty("Screen.TopEdge") + , isCoveredProperty("Screen.IsCovered") +#endif + , q_ptr(controller) +{ +#ifdef HAVE_CONTEXTSUBSCRIBER + connect(&topEdgeProperty, SIGNAL(valueChanged()), + this, SLOT(topEdgeChanged())); + connect(&isCoveredProperty, SIGNAL(valueChanged()), + this, SLOT(isCoveredChanged())); +#endif + + initContextSubscriber(); +} + +void DuiOrientationTrackerPrivate::initContextSubscriber() +{ +#ifdef HAVE_CONTEXTSUBSCRIBER + //waiting for properties to synchronize + topEdgeProperty.waitForSubscription(); + isCoveredProperty.waitForSubscription(); + + //initiating the variables to current orientation + topEdgeChanged(); + isCoveredChanged(); +#endif +} + +void DuiOrientationTrackerPrivate::topEdgeChanged() +{ +#ifdef HAVE_CONTEXTSUBSCRIBER + Dui::OrientationAngle angle; + Dui::Orientation orientation; + QString edge = topEdgeProperty.value().toString(); + + if (edge == "top") { + angle = Dui::Angle0; + orientation = Dui::Landscape; + } else if (edge == "left") { + angle = Dui::Angle270; + orientation = Dui::Portrait; + } else if (edge == "right") { + angle = Dui::Angle90; + orientation = Dui::Portrait; + } else if (edge == "bottom") { + angle = Dui::Angle180; + orientation = Dui::Landscape; + } else { + angle = currentAngle; + } + + if (angle != currentAngle) { + currentAngle = angle; + // instead of emitting a signal we have to explicitely call setOrientationAngle + // on windows, because this is very often excuted before the application's + // event loop is started and leads to crash in QMetaObject + foreach(DuiWindow * window, DuiApplication::windows()) { + if (!window->isOrientationAngleLocked()) { + if (!window->isOrientationLocked() || window->orientation() == orientation) + window->setOrientationAngle(angle); + } + } + } +#endif +} + +void DuiOrientationTrackerPrivate::isCoveredChanged() +{ +#ifdef HAVE_CONTEXTSUBSCRIBER + Q_Q(DuiOrientationTracker); + + bool isCovered = isCoveredProperty.value().toBool(); + + if (isCovered != currentIsCovered) { + duiDebug("DuiOrientationTracker") << "Covered:" << isCovered; + + currentIsCovered = isCovered; + if (isCovered) + emit q->faceFlippedDown(); + else + emit q->faceUp(); + } +#endif +} + +DuiOrientationTracker::DuiOrientationTracker() : + d_ptr(new DuiOrientationTrackerPrivate(this)) +{ + setParent(QCoreApplication::instance()); //get collected when needed. +} + +DuiOrientationTracker *DuiOrientationTracker::instance() +{ + if (!DuiOrientationTrackerPrivate::tracker) + DuiOrientationTrackerPrivate::tracker = new DuiOrientationTracker(); + return DuiOrientationTrackerPrivate::tracker; +} + +DuiOrientationTracker::~DuiOrientationTracker() +{ + if (this == DuiOrientationTrackerPrivate::tracker) + DuiOrientationTrackerPrivate::tracker = 0; +} + +Dui::OrientationAngle DuiOrientationTracker::orientationAngle() const +{ + Q_D(const DuiOrientationTracker); + + return d->currentAngle; +} diff --git a/src/events/duiorientationtracker.h b/src/events/duiorientationtracker.h new file mode 100644 index 000000000..ef00bf5d7 --- /dev/null +++ b/src/events/duiorientationtracker.h @@ -0,0 +1,61 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIORIENTATIONTRACKER_H +#define DUIORIENTATIONTRACKER_H + +#include + +#include "duinamespace.h" + +class DuiOrientationTrackerPrivate; + +/*! + * Class responsible for tracking the accelerometer properties and signaling events + * when the device should change it's orientation. + * At the moment this is not a part of DUI api - use DuiDeviceProfile for the information. + * Initially designed as singleton as DuiDeviceProfile might need to access some more information about + * the concrete phone position, that is not available from fired events. + */ +class DuiOrientationTracker: public QObject +{ + Q_OBJECT +public: + static DuiOrientationTracker *instance(); + + Dui::OrientationAngle orientationAngle() const; + +Q_SIGNALS: + void faceFlippedDown(); + void faceUp(); + +protected: + DuiOrientationTrackerPrivate *const d_ptr; + +private: + DuiOrientationTracker(); + virtual ~DuiOrientationTracker(); + + Q_DISABLE_COPY(DuiOrientationTracker) + Q_DECLARE_PRIVATE(DuiOrientationTracker) + + friend class DuiDeviceProfile; +}; + +#endif // DUIORIENTATIONTRACKER_H diff --git a/src/events/duiorientationtracker_p.h b/src/events/duiorientationtracker_p.h new file mode 100644 index 000000000..f8c669ccd --- /dev/null +++ b/src/events/duiorientationtracker_p.h @@ -0,0 +1,60 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIORIENTATIONTRACKER_P_H +#define DUIORIENTATIONTRACKER_P_H + +#ifdef HAVE_CONTEXTSUBSCRIBER +#include "contextproperty.h" +#endif + +#include +#include + +class DuiOrientationTracker; + +class DuiOrientationTrackerPrivate : public QObject +{ + Q_OBJECT +public: + DuiOrientationTrackerPrivate(DuiOrientationTracker *controller); + static DuiOrientationTracker *tracker; + Dui::OrientationAngle currentAngle; + bool currentIsCovered; + +#ifdef HAVE_CONTEXTSUBSCRIBER + ContextProperty topEdgeProperty; + ContextProperty isCoveredProperty; +#endif + +public slots: + void topEdgeChanged(); + void isCoveredChanged(); + +protected: + DuiOrientationTracker *q_ptr; + +private slots: + void initContextSubscriber(); + +private: + Q_DECLARE_PUBLIC(DuiOrientationTracker) +}; + +#endif // DUIORIENTATIONTRACKER_P_H diff --git a/src/events/duipreeditinjectionevent.cpp b/src/events/duipreeditinjectionevent.cpp new file mode 100644 index 000000000..382abb02f --- /dev/null +++ b/src/events/duipreeditinjectionevent.cpp @@ -0,0 +1,83 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include + +#include "duipreeditinjectionevent.h" +#include "duipreeditinjectionevent_p.h" + + +static int sPreeditEventNumber = -1; +static QMutex sPreeditInjectionMutex; + +DuiPreeditInjectionEventPrivate::DuiPreeditInjectionEventPrivate(const QString &preedit) + : preedit(preedit) +{ + // nothing +} + + +DuiPreeditInjectionEventPrivate::~DuiPreeditInjectionEventPrivate() +{ + // nothing +} + + +/////////////////////// +// class implementation + + +DuiPreeditInjectionEvent::DuiPreeditInjectionEvent(const QString &preedit) + : QEvent(DuiPreeditInjectionEvent::eventNumber()), + d_ptr(new DuiPreeditInjectionEventPrivate(preedit)) +{ + setAccepted(false); +} + + +DuiPreeditInjectionEvent::~DuiPreeditInjectionEvent() +{ + delete d_ptr; +} + + +QString DuiPreeditInjectionEvent::preedit() const +{ + Q_D(const DuiPreeditInjectionEvent); + return d->preedit; +} + + +// static +QEvent::Type DuiPreeditInjectionEvent::eventNumber() +{ + if (sPreeditEventNumber < 0) { + // no event number yet registered, do it now + sPreeditInjectionMutex.lock(); + + if (sPreeditEventNumber < 0) { + sPreeditEventNumber = QEvent::registerEventType(); + } + + sPreeditInjectionMutex.unlock(); + } + + return static_cast(sPreeditEventNumber); +} diff --git a/src/events/duipreeditinjectionevent.h b/src/events/duipreeditinjectionevent.h new file mode 100644 index 000000000..16b53bb32 --- /dev/null +++ b/src/events/duipreeditinjectionevent.h @@ -0,0 +1,47 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIPREEDITINJECTIONEVENT_H +#define DUIPREEDITINJECTIONEVENT_H + +#include "duiexport.h" + +#include + +class DuiPreeditInjectionEventPrivate; + +class DUI_EXPORT DuiPreeditInjectionEvent : public QEvent +{ +public: + DuiPreeditInjectionEvent(const QString &preedit); + virtual ~DuiPreeditInjectionEvent(); + + QString preedit() const; + + static QEvent::Type eventNumber(); + +protected: + DuiPreeditInjectionEventPrivate *const d_ptr; + +private: + Q_DECLARE_PRIVATE(DuiPreeditInjectionEvent) + Q_DISABLE_COPY(DuiPreeditInjectionEvent) +}; + +#endif diff --git a/src/events/duipreeditinjectionevent_p.h b/src/events/duipreeditinjectionevent_p.h new file mode 100644 index 000000000..52bff4692 --- /dev/null +++ b/src/events/duipreeditinjectionevent_p.h @@ -0,0 +1,32 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIPREEDITINJECTIONEVENT_P_H +#define DUIPREEDITINJECTIONEVENT_P_H + +class DuiPreeditInjectionEventPrivate +{ +public: + DuiPreeditInjectionEventPrivate(const QString &preedit); + virtual ~DuiPreeditInjectionEventPrivate(); + + QString preedit; +}; + +#endif diff --git a/src/events/duiscenewindowevent_p.cpp b/src/events/duiscenewindowevent_p.cpp new file mode 100644 index 000000000..525efafa9 --- /dev/null +++ b/src/events/duiscenewindowevent_p.cpp @@ -0,0 +1,73 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiscenewindowevent_p.h" + +static int duiSceneWindowAppearEventNumber = -1; +static int duiSceneWindowDisappearEventNumber = -1; +static int duiSceneWindowDismissEventNumber = -1; + +DuiSceneWindowEvent::DuiSceneWindowEvent(QEvent::Type type, + DuiSceneWindow *sceneWindow, + bool animatedTransition) + : QEvent(type), + m_sceneWindow(sceneWindow), + m_animatedTransition(animatedTransition) +{ + if (type != eventTypeAppear() && type != eventTypeDisappear() && type != eventTypeDismiss()) { + qFatal("DuiSceneWindowEvent: Invalid event type passed on to constructor."); + } +} + +QEvent::Type DuiSceneWindowEvent::eventTypeAppear() +{ + if (duiSceneWindowAppearEventNumber < 0) { + duiSceneWindowAppearEventNumber = QEvent::registerEventType(); + } + + return (QEvent::Type) duiSceneWindowAppearEventNumber; +} + +QEvent::Type DuiSceneWindowEvent::eventTypeDisappear() +{ + if (duiSceneWindowDisappearEventNumber < 0) { + duiSceneWindowDisappearEventNumber = QEvent::registerEventType(); + } + + return (QEvent::Type) duiSceneWindowDisappearEventNumber; +} + +QEvent::Type DuiSceneWindowEvent::eventTypeDismiss() +{ + if (duiSceneWindowDismissEventNumber < 0) { + duiSceneWindowDismissEventNumber = QEvent::registerEventType(); + } + + return (QEvent::Type) duiSceneWindowDismissEventNumber; +} + +DuiSceneWindow *DuiSceneWindowEvent::sceneWindow() const +{ + return m_sceneWindow; +} + +bool DuiSceneWindowEvent::animatedTransition() const +{ + return m_animatedTransition; +} diff --git a/src/events/duiscenewindowevent_p.h b/src/events/duiscenewindowevent_p.h new file mode 100644 index 000000000..ddd4969e4 --- /dev/null +++ b/src/events/duiscenewindowevent_p.h @@ -0,0 +1,74 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISCENEWINDOWAPPEARANCECHANGEEVENT_H +#define DUISCENEWINDOWAPPEARANCECHANGEEVENT_H + +#include + +class DuiSceneWindow; + +/* + * Sent by DuiSceneManager to the DuiWindows currently rendering its DuiScene + * when some interesting state change of a DuiSceneWindow managed by him has + * happened (or is about to happen). + * + * This event informs DuiWindows when, for instance, scene windows enter or leave + * the scene, enabling them to connect the signals of that upcoming scene + * window to slots of other existing scene windows, etc. + */ +class DuiSceneWindowEvent : public QEvent +{ +public: + // scene window is about to appear + static QEvent::Type eventTypeAppear(); + + // scene window is about to disappear + static QEvent::Type eventTypeDisappear(); + + // scene window is about to be dismissed + static QEvent::Type eventTypeDismiss(); + + /* + * Contructs a new DuiSceneWindowEvent + * \param type Either eventTypeAppear() or eventTypeDisappear(). + * \param sceneWindow The scene window that has changed (or is about to change). + * \param animatedTransition Whether the state change is going to be animated + * (true) or immediate (false). + */ + DuiSceneWindowEvent(QEvent::Type type, + DuiSceneWindow *sceneWindow, + bool animatedTransition); + + /* + * The scene window that has changed (or is about to change). + */ + DuiSceneWindow *sceneWindow() const; + + /* + * Whether the state change was (or is going to be) animated. + */ + bool animatedTransition() const; + +private: + DuiSceneWindow *m_sceneWindow; + bool m_animatedTransition; +}; + +#endif diff --git a/src/events/events.pri b/src/events/events.pri new file mode 100644 index 000000000..06072c993 --- /dev/null +++ b/src/events/events.pri @@ -0,0 +1,26 @@ +############################################################################### +# events and gestures module. Separated to events folder, used for multitouch +# prototype. +############################################################################### +EVENTS_SRC_DIR= ./events +INCLUDEPATH+=./events +PRIVATE_HEADERS += \ + $$EVENTS_SRC_DIR/duiorientationtracker.h \ + $$EVENTS_SRC_DIR/duiorientationtracker_p.h \ + $$EVENTS_SRC_DIR/duiscenewindowevent_p.h \ + +HEADERS += \ + $$EVENTS_SRC_DIR/duicancelevent.h \ + $$EVENTS_SRC_DIR/duidismissevent.h \ + $$EVENTS_SRC_DIR/duipreeditinjectionevent.h \ + $$EVENTS_SRC_DIR/duiondisplaychangeevent.h \ + $$EVENTS_SRC_DIR/duiorientationchangeevent.h \ + +SOURCES += \ + $$EVENTS_SRC_DIR/duiorientationtracker.cpp \ + $$EVENTS_SRC_DIR/duicancelevent.cpp \ + $$EVENTS_SRC_DIR/duidismissevent.cpp \ + $$EVENTS_SRC_DIR/duipreeditinjectionevent.cpp \ + $$EVENTS_SRC_DIR/duiondisplaychangeevent.cpp \ + $$EVENTS_SRC_DIR/duiorientationchangeevent.cpp \ + $$EVENTS_SRC_DIR/duiscenewindowevent_p.cpp \ diff --git a/src/feedback/duifeedback.cpp b/src/feedback/duifeedback.cpp new file mode 100644 index 000000000..49be9c7a6 --- /dev/null +++ b/src/feedback/duifeedback.cpp @@ -0,0 +1,71 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duifeedback.h" +#include "duifeedback_p.h" + +DuiFeedback::DuiFeedback(const DuiFeedback &feedback) + : QObject(0), d_ptr(new DuiFeedbackPrivate) +{ + Q_D(DuiFeedback); + d->name = feedback.name(); +} + +DuiFeedback::DuiFeedback(QObject *parent) + : QObject(parent), d_ptr(new DuiFeedbackPrivate) +{ +} + +DuiFeedback::DuiFeedback(const QString &name, QObject *parent) + : QObject(parent), d_ptr(new DuiFeedbackPrivate) +{ + Q_D(DuiFeedback); + d->name = name; +} + +DuiFeedback::~DuiFeedback() +{ + delete d_ptr; +} + +DuiFeedback &DuiFeedback::operator=(const DuiFeedback &other) +{ + Q_D(DuiFeedback); + d->name = other.name(); + + return *this; +} + +void DuiFeedback::setName(const QString &name) +{ + Q_D(DuiFeedback); + d->name = name; +} + +QString DuiFeedback::name() const +{ + Q_D(const DuiFeedback); + return d->name; +} + +void DuiFeedback::play() const +{ + Q_D(const DuiFeedback); + d->play(); +} diff --git a/src/feedback/duifeedback.h b/src/feedback/duifeedback.h new file mode 100644 index 000000000..dd1ca4975 --- /dev/null +++ b/src/feedback/duifeedback.h @@ -0,0 +1,111 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIFEEDBACK_H +#define DUIFEEDBACK_H + +#include "duiexport.h" + +#include +#include + +class DuiFeedbackPrivate; + +/*! + * \class DuiFeedback + * \brief Used to easily play non-graphical input feedbacks. + * + * This class can be used to play non-graphical input feedbacks such as + * vibra, audio or tactile effects. DuiFeedback has a name which is used + * to play the correct feedback(s) when play() function is called. + * + * \sa DuiFeedbackPlayer + */ +class DUI_EXPORT DuiFeedback : public QObject +{ + Q_OBJECT + +public: + /*! + * \brief Default constructor + * + * Creates a DuiFeedback with no name. + * + * \note Calling play() for DuiFeedback with no name causes no feedback + * to be played. + * + * \param parent Parent object + */ + DuiFeedback(QObject *parent = 0); + + /*! + * \brief Copy constructor + * + * \note The underlying QObject is not copied, an empty QObject is created + * instead. + */ + DuiFeedback(const DuiFeedback &); + + /*! + * \brief Constructor + * + * \param name Name of the feedback + * \param parent Parent object + */ + DuiFeedback(const QString &name, QObject *parent = 0); + + /*! + * \brief Assigment operator + * + * \note The underlying QObject is not copied, an empty QObject is created + * instead. + */ + DuiFeedback &operator=(const DuiFeedback &other); + + /*! + * \brief Destructor + */ + ~DuiFeedback(); + + /*! + * \brief Sets the name of the feedback. + * + * \param name Name of the feedback + */ + void setName(const QString &name); + + /*! + * \brief Returns the name of the feedback. + * + * \return Name of the feedback. + */ + QString name() const; + +public Q_SLOTS: + /*! + * \brief Plays the feedback. + */ + void play() const; + +protected: + Q_DECLARE_PRIVATE(DuiFeedback) + DuiFeedbackPrivate *const d_ptr; +}; + +#endif diff --git a/src/feedback/duifeedback_p.cpp b/src/feedback/duifeedback_p.cpp new file mode 100644 index 000000000..1979ec576 --- /dev/null +++ b/src/feedback/duifeedback_p.cpp @@ -0,0 +1,35 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duifeedback_p.h" + +#include "duiapplication.h" +#include "duifeedbackplayer.h" + +DuiFeedbackPrivate::DuiFeedbackPrivate() +{ + feedbackPlayer = DuiApplication::feedbackPlayer(); +} + +void DuiFeedbackPrivate::play() const +{ + if (feedbackPlayer != 0) { + feedbackPlayer->play(name); + } +} diff --git a/src/feedback/duifeedback_p.h b/src/feedback/duifeedback_p.h new file mode 100644 index 000000000..d09c513a3 --- /dev/null +++ b/src/feedback/duifeedback_p.h @@ -0,0 +1,38 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIFEEDBACKPRIV_H +#define DUIFEEDBACKPRIV_H + +#include + +class DuiFeedbackPlayer; + +class DuiFeedbackPrivate +{ +public: + DuiFeedbackPrivate(); + + void play() const; + + QString name; + DuiFeedbackPlayer *feedbackPlayer; +}; + +#endif diff --git a/src/feedback/duifeedbackplayer.cpp b/src/feedback/duifeedbackplayer.cpp new file mode 100644 index 000000000..84e227fff --- /dev/null +++ b/src/feedback/duifeedbackplayer.cpp @@ -0,0 +1,43 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duifeedbackplayer.h" +#include "duifeedbackplayer_p.h" + +const QString DuiFeedbackPlayer::Press = "press"; +const QString DuiFeedbackPlayer::Release = "release"; +const QString DuiFeedbackPlayer::Cancel = "cancel"; +const QString DuiFeedbackPlayer::Error = "error"; + +DuiFeedbackPlayer::DuiFeedbackPlayer(QObject *parent) + : QObject(parent), d_ptr(new DuiFeedbackPlayerPrivate(this)) +{ +} + +DuiFeedbackPlayer::~DuiFeedbackPlayer() +{ + delete d_ptr; +} + +void DuiFeedbackPlayer::play(const QString &feedbackName) +{ + Q_D(DuiFeedbackPlayer); + + d->sendPlaybackRequest(feedbackName); +} diff --git a/src/feedback/duifeedbackplayer.h b/src/feedback/duifeedbackplayer.h new file mode 100644 index 000000000..b7ca5750e --- /dev/null +++ b/src/feedback/duifeedbackplayer.h @@ -0,0 +1,108 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIFEEDBACKPLAYER_H +#define DUIFEEDBACKPLAYER_H + +#include "duiexport.h" + +#include +#include + +class DuiApplicationPrivate; +class DuiFeedbackPlayerPrivate; + +/*! + * \class DuiFeedbackPlayer + * \brief Used to give non-graphical input feedback. + * + * DuiFeedbackPlayer is used to give non-graphical instantaneous feedback to user + * actions. Non-graphical feedback can mean auditive, tactile, vibrational, etc. + * + * You use it as way to add supporting instantaneous feedback for your + * graphical user interface (such as a "button pressing" tactile feedback when the + * user pokes your custom widget on a touchscreen) + * + * DuiFeedbackPlayer also ensures that the instantaneous feedback given is going + * to comply with the system's current "look and feel" (more especifically, to the + * "feel" part) and will also be in harmony with the context/situation at hand. + */ +class DUI_EXPORT DuiFeedbackPlayer : public QObject +{ + Q_OBJECT + + /*! + * \brief Constructor + * \param parent Parent object + */ + DuiFeedbackPlayer(QObject *parent = 0); + + /*! + * \brief Destructor + */ + virtual ~DuiFeedbackPlayer(); + + // Only DuiApplication may create or destroy instances of this + // class + friend class DuiApplicationPrivate; + friend class DuiComponentDataPrivate; + +public: + + /*! + * Press feedback. Used when the user presses on an object. + * It is also used when the user presses off an object, + * but slides the finger onto one. + */ + static const QString Press; + + /*! + * Release feedback. Used when finger is released on the object. + * Indicates that an action was done. + */ + static const QString Release; + + /*! + * Cancel feedback. Used when finger slides off the object, onto an + * inactive area. + * + * Also used in cases where a Tap turns into another stroke. + */ + static const QString Cancel; + + /*! + * Error feedback. + */ + static const QString Error; + + /*! + * Plays a feedback, given its name. + * + * \param feedbackName Name of the desired feedback. + */ + void play(const QString &feedbackName); + +private: + Q_DECLARE_PRIVATE(DuiFeedbackPlayer) + DuiFeedbackPlayerPrivate *const d_ptr; + Q_DISABLE_COPY(DuiFeedbackPlayer) + +}; + +#endif diff --git a/src/feedback/duifeedbackplayer_p.cpp b/src/feedback/duifeedbackplayer_p.cpp new file mode 100644 index 000000000..5a09a7b60 --- /dev/null +++ b/src/feedback/duifeedbackplayer_p.cpp @@ -0,0 +1,108 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duifeedbackplayer_p.h" + +#include +#include +#include + +static const char gSocketServer[] = "/tmp/duifeedbackd/player.sock"; + +DuiFeedbackPlayerPrivate::DuiFeedbackPlayerPrivate(QObject *parent) + : QObject(parent) +{ + socketStream.setDevice(&socket); + connect(&socket, SIGNAL(connected()), SLOT(onConnected())); + connect(&socket, SIGNAL(error(QLocalSocket::LocalSocketError)), + SLOT(onSocketError(QLocalSocket::LocalSocketError))); + + reconnectionAttempts = 0; + + // TODO: Load from a config file? + reconnectionIntervalsList << 300; + reconnectionIntervalsList << 600; + reconnectionIntervalsList << 1000; + reconnectionIntervalsList << 2000; + reconnectionIntervalsList << 2000; + reconnectionIntervalsList << 5000; + reconnectionIntervalsList << 5000; + reconnectionIntervalsList << 10000; + reconnectionIntervalsList << 30000; + reconnectionIntervalsList << 300000; // 5*60*1000 (five minutes) +} + +DuiFeedbackPlayerPrivate::~DuiFeedbackPlayerPrivate() +{ + // socket emits disconnected() in its destructor. If we don't + // disconnect from this signal we will get called after being + // destroyed which will cause a SIGSEGV + socket.disconnect(this); +} + +bool DuiFeedbackPlayerPrivate::init(const QString &applicationName) +{ + this->applicationName = applicationName; + + // Initial connection to server is immediate + connectIdle(); + + return true; +} + +void DuiFeedbackPlayerPrivate::sendPlaybackRequest(const QString &name) +{ + if (socket.state() == QLocalSocket::ConnectedState && + name.isEmpty() == false) { + socketStream << name; + socket.flush(); + } +} + +void DuiFeedbackPlayerPrivate::onConnected() +{ + reconnectionAttempts = 0; + socketStream << applicationName; +} + +void DuiFeedbackPlayerPrivate::connectIdle() +{ + socket.connectToServer(gSocketServer); +} + +void DuiFeedbackPlayerPrivate::onSocketError(QLocalSocket::LocalSocketError socketError) +{ + Q_UNUSED(socketError); + + if (reconnectionAttempts <= reconnectionIntervalsList.size()) { + reconnectionAttempts++; + + if (reconnectionAttempts <= 1) { + // First reconnection attempt is done immediately + connectIdle(); + } else { + // Following attempts are done after a delay + QTimer::singleShot(reconnectionIntervalsList[reconnectionAttempts-2], + this, SLOT(connectIdle())); + } + } else { + // Give up + qWarning("DuiFeedbackPlayer: Couldn't establish connection with duifeedbackd."); + } +} diff --git a/src/feedback/duifeedbackplayer_p.h b/src/feedback/duifeedbackplayer_p.h new file mode 100644 index 000000000..a25142d9a --- /dev/null +++ b/src/feedback/duifeedbackplayer_p.h @@ -0,0 +1,65 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIFEEDBACKPLAYERPRIV_H +#define DUIFEEDBACKPLAYERPRIV_H + +#include +#include +#include +#include +#include + +#include "duiexport.h" + +class DuiFeedbackPlayerPrivate : public QObject +{ + Q_OBJECT +public: + DuiFeedbackPlayerPrivate(QObject *parent); + virtual ~DuiFeedbackPlayerPrivate(); + + bool init(const QString &applicationName); + + void sendPlaybackRequest(const QString &name); + +private slots: + void onConnected(); + void onSocketError(QLocalSocket::LocalSocketError socketError); + void connectIdle(); + +public: + QLocalSocket socket; + QDataStream socketStream; + QString applicationName; + + // Number of reconnection attempts. This value is zeroed when a connection is + // successfully established. + int reconnectionAttempts; + + // Contains the intervals, in milliseconds, to wait before attempting + // to reconnect to feedback-manager daemon. + // list[0] is the time to wait before trying to connect and reconnect for the first time. + // If the first attempt fails then it waits list[1] milliseconds before attempting + // to reconnect for the second time and so on. + // It gives up trying to reconnect when failedReconnections == list.size() + QList reconnectionIntervalsList; +}; + +#endif diff --git a/src/feedback/feedback.pri b/src/feedback/feedback.pri new file mode 100644 index 000000000..76cec151e --- /dev/null +++ b/src/feedback/feedback.pri @@ -0,0 +1,19 @@ +############################################################################### +# DuiFeedback module +# This module contains all classes which deal with feedback to user input +############################################################################### +FEEDBACK_SRC_DIR=./feedback +INCLUDEPATH+= ./feedback + +PUBLIC_HEADERS += \ + $$FEEDBACK_SRC_DIR/duifeedback.h \ + $$FEEDBACK_SRC_DIR/duifeedbackplayer.h \ + +PRIVATE_HEADERS += \ + $$FEEDBACK_SRC_DIR/duifeedbackplayer_p.h \ + $$FEEDBACK_SRC_DIR/duifeedback_p.h + +SOURCES += $$FEEDBACK_SRC_DIR/duifeedback.cpp \ + $$FEEDBACK_SRC_DIR/duifeedback_p.cpp \ + $$FEEDBACK_SRC_DIR/duifeedbackplayer.cpp \ + $$FEEDBACK_SRC_DIR/duifeedbackplayer_p.cpp diff --git a/src/getCoverage b/src/getCoverage new file mode 100755 index 000000000..5ae41c4ca --- /dev/null +++ b/src/getCoverage @@ -0,0 +1,171 @@ +#! /usr/bin/perl + +my @files = (); + +my $valid=90.0; +my $gcovDir = ".gcov"; + +my @subDirs = ( "." ); + +push @subDirs, getSubdirs(); + +foreach $subDir ( @subDirs ) { + push @files, <$subDir/*.cpp>; + push @files, <$subDir/*.h>; +} + +my %total = (); +my %percentages = (); +my %lines = (); +my %maxLen = (); + +$maxLen{ "files" } = length( "File" ); +$maxLen{ "%" } = length( "%" ); +$maxLen{ "lines" } = length( "Lines" ); + +$numArgs = $#ARGV + 1; +$xml = 0; + +if ($numArgs == 2 && $ARGV[0] == "-xml" ) { + $xml = 1; + $filename = $ARGV[1]; + open(OUT,">$filename") or die("Cant open $filename for writing!"); + printf("Create coverage log $filename ... \n"); +} elsif ($numArgs == 0) { + $xml = 0; +} else { + die("Danger danger will robinson!") +} + +foreach $file ( @files ) { + my $filterNextLine = 0; + my $gcovCommand = "gcov --object-directory .obj $file 2>/dev/null"; + open( GCOV, "$gcovCommand|" ) || die( "Could not open $gcovCommand: $!" ); + while ( ) { + chomp; + if ( ( $filterNextLine ) && ( /Lines executed:(\S+) of (\S+)/ ) ) { + $percentages{ $file } = $1; + $lines{ $file } = $2; + + $total{"%"}+=$percentages{ $file }; + $total{"lines"}+=$lines{ $file }; + $total{"files"}++; + setMaxLen( "%", length( $percentages{ $file } ) ); + setMaxLen( "lines", length( $lines{ $file } ) ); + setMaxLen( "files", length( $file ) ); + + last; + } + $filterNextLine = ( /File \'$file\'/ ); + } + close( GCOV ); + +} + +# tidy up +mkdir $gcovDir if ( ! -d $gcovDir ); +foreach $file ( <*.gcov> ) { + rename( $file, ".gcov/$file" ); +} + +# print out table +# + +if ($xml) { + print OUT sprintf("\n"); + print OUT sprintf("\n"); + print OUT sprintf("\n"); + print OUT sprintf("4.5.0\n"); + print OUT sprintf(" 4.5.0\n"); + print OUT sprintf("\n"); + + printTestFunction("initTestCase","",100); + +} else { + printf( " %-*s %*s %*s\n", $maxLen{ "files" }, "File", $maxLen{ "%" }, "%", $maxLen{ "lines" }, "Lines" ); +} + +my @groups = (); + +my $counter = 1; +foreach $file ( @files ) { + if ( $lines{ $file } > 0 ) { + if ($xml ) { + printTestFunction("Line Coverage of $file",$file,$percentages{$file}); + } else { + printf( "%3d ", $counter ); + printf( "%-*s ", $maxLen{ "files" }, $file ); + printf( "%*s ", $maxLen{ "%" }, $percentages{ $file } ); + printf( "%*s", $maxLen{ "lines" }, $lines{ $file } ); + printf( "\n" ); + + my ( $group, $filename ) = split( /\//, $file ); + push @groups, $group if ( !grep( /$group/, @groups ) ); + $total{ "%$group" } += $percentages{ $file }; + $total{ "lines$group" } += $lines{ $file }; + $total{ "files$group" } ++; + } + $counter++; + } +} + +# print out totals +{ + if ($xml) { + printTestFunction("Total Coverage","",$total{ "%" }/$total{ "files" }); + printTestFunction("cleanupTestCase","",100); + print OUT sprintf("\n"); + } else { + print "Total lines=", $total{ "lines" }, "\n"; + printf( "Mean percentage=%2.2f\%\n", ($total{ "files" }==0)?"0":($total{ "%" }/$total{ "files" }) ); + } + + print "\n"; + print "Mean percentages by subdirectory\n"; + foreach my $group ( @groups ) { + printf( + "%s(%d)\t%6s\%\n", + $group, $total{ "files$group" }, + sprintf( "%.2f", $total{ "%$group" }/$total{ "files$group" } ) + ); + } +} + +close(OUT); + +sub printTestFunction +{ + my ( $testname, $filename, $percentage ) = @_; + local $pass = $percentage>=$valid; + + print OUT sprintf("\n",$testname); + print OUT sprintf("\n", $pass?"pass":"fail",$filename, $pass?"/":""); + if (not $pass) { + print OUT sprintf("\n","Coverage ($percentage) below set $valid%"); + print OUT sprintf("\n"); + } + print OUT sprintf("\n"); + +} +sub setMaxLen +{ + my ( $field, $length ) = @_; + + $maxLen{ $field } = $length if ( defined( $maxLen{ $field } ) && $length > $maxLen{ $field } ); +} + +sub getSubdirs +{ + my @retVal = (); + my $projectFile = "src.pro"; + + open( PROJECT, "<$projectFile" ) || die( "Could not open $projectFile:$!" ); + while () { + if ( /include\s*\((\w+)\/\w+.pri\)/ ) { + push @retVal, $1; + } + } + close( PROJECT ); + + return @retVal; +} diff --git a/src/i18n/duibreakiterator.cpp b/src/i18n/duibreakiterator.cpp new file mode 100644 index 000000000..2bf716101 --- /dev/null +++ b/src/i18n/duibreakiterator.cpp @@ -0,0 +1,274 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duibreakiterator.h" + +#include "duilocale.h" + +#include "duibreakiteratorif.h" + +#ifdef HAVE_ICU +#include "duiicubreakiterator.h" +#else +#include "duinullbreakiterator.h" +#endif + +class DuiBreakIteratorPrivate +{ +public: + DuiBreakIteratorPrivate(); + virtual ~DuiBreakIteratorPrivate(); + + void init(const DuiLocale &locale, const QString &text, DuiBreakIterator::Type type); + + DuiBreakIteratorIf *impl; +}; + + +DuiBreakIteratorPrivate::DuiBreakIteratorPrivate() + : impl(0) +{ + // nothing +} + + +DuiBreakIteratorPrivate::~DuiBreakIteratorPrivate() +{ + delete impl; +} + + +void DuiBreakIteratorPrivate::init(const DuiLocale &locale, const QString &text, + DuiBreakIterator::Type type) +{ + if (impl) { + delete impl; + } + +#ifdef HAVE_ICU + impl = new DuiIcuBreakIterator(locale, text, type); +#else + impl = new DuiNullBreakIterator(locale, text, type); +#endif +} + + +/////////////////////////////////// + + +/*! + \class DuiBreakIterator + + \brief DuiBreakIterator allows to iterate strings in order to get the indexes of word boundaries + and possible line breaks. + + Example to iterate string: + \verbatim + DuiLocale locale; // default + QString text("This is a string to iterate"); + DuiBreakIterator it(locale, text, DuiBreakIterator::WordIterator); + while (it.hasNext()) { + int index = it.next(); + duiDebug() << "index at " << i; + } + \endverbatim + + Another common use is to get indexes around cursor: + \verbatim + DuiLocale locale; // default + QString text("This is a string to iterate"); + DuiBreakIterator it(locale, text, DuiBreakIterator::WordIterator); + int cursor = 12; + int previous = it.previousInclusive(cursor); + int next = it.next(cursor); + \endverbatim + + */ + + +//! Creates a DuiBreakIterator for a string based on rules derived from the given locale. +//! The index is set to be before the actual string so next() returns the first index. +//! \param locale used locale +//! \param text text to iterate. SHOULD NOT be changed while iterating. +//! \param type (optional) type of iterator. Default is word iterator +DuiBreakIterator::DuiBreakIterator(const DuiLocale &locale, const QString &text, Type type) + : d_ptr(new DuiBreakIteratorPrivate) +{ + Q_D(DuiBreakIterator); + d->init(locale, text, type); +} + + +///! Creates a DuiBreakIterator using default locale +DuiBreakIterator::DuiBreakIterator(const QString &text, Type type) + : d_ptr(new DuiBreakIteratorPrivate) +{ + Q_D(DuiBreakIterator); + DuiLocale locale; // get default + d->init(locale, text, type); +} + + +//! Destructor +DuiBreakIterator::~DuiBreakIterator() +{ + delete d_ptr; +} + + +//! returns true if a boundary exists after current index +bool DuiBreakIterator::hasNext() const +{ + Q_D(const DuiBreakIterator); + + return d->impl->hasNext(); +} + + +//! returns true if boundary exists before current index +bool DuiBreakIterator::hasPrevious() const +{ + Q_D(const DuiBreakIterator); + + return d->impl->hasPrevious(); +} + + +//! returns the next boundary index after the current index or -1 if none exists. +//! current index is updated to the resulting value. +int DuiBreakIterator::next() +{ + Q_D(const DuiBreakIterator); + + return d->impl->next(); +} + + +//! returns the next boundary after the given index. Returns the boundary or -1 +//! if none exists. Updates the current index to the resulting value. +int DuiBreakIterator::next(int index) +{ + Q_D(const DuiBreakIterator); + + return d->impl->next(index); +} + + +//! returns the next boundary index value. The current index is not updated. +int DuiBreakIterator::peekNext() +{ + Q_D(const DuiBreakIterator); + + return d->impl->peekNext(); +} + + +//! returns the previous boundary index value. The current index is not updated. +int DuiBreakIterator::peekPrevious() +{ + Q_D(const DuiBreakIterator); + + return d->impl->peekPrevious(); +} + + +//! returns the previous boundary index or -1 if none exists. +//! The current index is updated to the resulting value. +int DuiBreakIterator::previous() +{ + Q_D(const DuiBreakIterator); + + return d->impl->previous(); +} + + +//! returns the previous boundary from the given index value or -1 if none exists. +//! The current index is updated to the resulting value. +int DuiBreakIterator::previous(int index) +{ + Q_D(const DuiBreakIterator); + + return d->impl->previous(index); +} + + +//! returns the previous boundary including the current index in the search. +//! If current index is a boundary, it is returned and current is decreased by one, +//! otherwise works as previous() +int DuiBreakIterator::previousInclusive() +{ + Q_D(const DuiBreakIterator); + + return d->impl->previousInclusive(); +} + +//! returns the previous boundary from given index, including the index in the search. +//! If index is a boundary, it is returned and current is decreased by one, +//! otherwise works as previous() +int DuiBreakIterator::previousInclusive(int index) +{ + Q_D(const DuiBreakIterator); + + return d->impl->previousInclusive(index); +} + + +//! Sets the current index to the given value +void DuiBreakIterator::setIndex(int index) +{ + Q_D(DuiBreakIterator); + + d->impl->setIndex(index); +} + + +//! Sets the current index to the end of the string +void DuiBreakIterator::toBack() +{ + Q_D(DuiBreakIterator); + + d->impl->toBack(); +} + + +//! Sets the current index to the beginning of the string +void DuiBreakIterator::toFront() +{ + Q_D(DuiBreakIterator); + + d->impl->toFront(); +} + + +//! Checks if current index is a boundary. +bool DuiBreakIterator::isBoundary() +{ + Q_D(DuiBreakIterator); + + return d->impl->isBoundary(); +} + + +//! Checks if given index is a boundary. +bool DuiBreakIterator::isBoundary(int index) +{ + Q_D(DuiBreakIterator); + + return d->impl->isBoundary(index); +} diff --git a/src/i18n/duibreakiterator.h b/src/i18n/duibreakiterator.h new file mode 100644 index 000000000..5e820d1b7 --- /dev/null +++ b/src/i18n/duibreakiterator.h @@ -0,0 +1,63 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIBREAKITERATOR_H +#define DUIBREAKITERATOR_H + +#include "duiexport.h" +#include "duilocale.h" + +#include + +class DuiBreakIteratorPrivate; + +class DUI_EXPORT DuiBreakIterator +{ +public: + enum Type {LineIterator, WordIterator}; // would also be supported: character, sentence, title + + DuiBreakIterator(const DuiLocale &locale, const QString &text, Type type = WordIterator); + explicit DuiBreakIterator(const QString &text, Type type = WordIterator); + virtual ~DuiBreakIterator(); + + // java-style iterator interface: + bool hasNext() const; + bool hasPrevious() const; + int next(); + int next(int index); // searching from explicit index + int peekNext(); + int peekPrevious(); + int previous(); + int previous(int index); + int previousInclusive(); + int previousInclusive(int index); + void toBack(); + void toFront(); + void setIndex(int index); + bool isBoundary(); + bool isBoundary(int index); + +private: + Q_DISABLE_COPY(DuiBreakIterator) + Q_DECLARE_PRIVATE(DuiBreakIterator) + DuiBreakIteratorPrivate *const d_ptr; +}; + + +#endif diff --git a/src/i18n/duibreakiteratorif.h b/src/i18n/duibreakiteratorif.h new file mode 100644 index 000000000..a2174b898 --- /dev/null +++ b/src/i18n/duibreakiteratorif.h @@ -0,0 +1,58 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIBREAKITERATORIF_H +#define DUIBREAKITERATORIF_H + +#include "duiexport.h" +#include "duilocale.h" + +#include + +/*! \internal + * This class describes the interface that both DuiIcuIterator + * and DuiNullIterator implement. It is used to have the possibility + * to choose one of both backend implementations at compile time + * and to keep the number of needed "#ifdef" small. + */ +class DUI_EXPORT DuiBreakIteratorIf +{ +public: + virtual ~DuiBreakIteratorIf() {}; + + // java-style iterator interface: + virtual bool hasNext() const = 0; + virtual bool hasPrevious() const = 0; + virtual int next() = 0; + virtual int next(int index) = 0; // searching from explicit index + virtual int peekNext() = 0; + virtual int peekPrevious() = 0; + virtual int previous() = 0; + virtual int previous(int index) = 0; + virtual int previousInclusive() = 0; + virtual int previousInclusive(int index) = 0; + virtual void toBack() = 0; + virtual void toFront() = 0; + virtual void setIndex(int index) = 0; + virtual bool isBoundary() = 0; + virtual bool isBoundary(int index) = 0; +}; +//! \internal_end + +#endif diff --git a/src/i18n/duicalendar.cpp b/src/i18n/duicalendar.cpp new file mode 100644 index 000000000..49abf2258 --- /dev/null +++ b/src/i18n/duicalendar.cpp @@ -0,0 +1,779 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duicalendar.h" +#include "duicalendar_p.h" + +#include +#include + +#include "duilocale_p.h" +#include "duiicuconversions.h" + + +DuiCalendarPrivate::DuiCalendarPrivate(DuiLocale::Calendar calendar) + : _calendar(0), _calendarType(calendar), _valid(true) +{ + if (_calendarType == DuiLocale::DefaultCalendar) { + DuiLocale defaultLocale; + _calendarType = defaultLocale.calendar(); + } +} + + +// copy constructor +DuiCalendarPrivate::DuiCalendarPrivate(const DuiCalendarPrivate &other) + : _calendar(other._calendar->clone()), + _calendarType(other._calendarType), + _valid(other._valid) +{ + // nothing +} + + +DuiCalendarPrivate::~DuiCalendarPrivate() +{ + delete _calendar; +} + + +DuiCalendarPrivate &DuiCalendarPrivate::operator=(const DuiCalendarPrivate &other) +{ + delete _calendar; + _calendar = other._calendar->clone(); + _calendarType = other._calendarType; + _valid = other._valid; + return *this; +} + + +DuiLocale::Weekday DuiCalendarPrivate::icuWeekdayToDuiWeekday(int uweekday) +{ + switch (uweekday) { + case(UCAL_MONDAY): + return DuiLocale::Monday; + + case(UCAL_TUESDAY): + return DuiLocale::Tuesday; + + case(UCAL_WEDNESDAY): + return DuiLocale::Wednesday; + + case(UCAL_THURSDAY): + return DuiLocale::Thursday; + + case(UCAL_FRIDAY): + return DuiLocale::Friday; + + case(UCAL_SATURDAY): + return DuiLocale::Saturday; + + case(UCAL_SUNDAY): + return DuiLocale::Sunday; + + default: + return static_cast(0); + } +} + + +/////////////////////// +// DuiCalendar class + +/*! + \class DuiCalendar + + \brief DuiCalendar can hold date and time value for with different calendar systems + + \note insufficient information: default values are used. e.g. with gregorian calendar + the epoch value (1970-1-1) + + \note inconsistent information: preference is on fields set more recently +*/ + + +//! Constructs a DuiCalendar with explicit calendar type +//! \param calendar Calendar type. Default is the type used for default locale. +//! \param timezone Timezone to be used. Default is timezone of the default locale. +//! Possible values: id, e.g. PST, country/city, e.g. Europe/Helsinki or GMT offset, e.g. GTM+2:00. +//! supportedTimezones() can be used to enumerate choices. +DuiCalendar::DuiCalendar(DuiLocale::Calendar calendar, + const QString &timezone) : d_ptr(new DuiCalendarPrivate(calendar)) +{ + Q_D(DuiCalendar); + + // fetch default calendar system + DuiLocale defaultLocale; + + QString timeCategory = defaultLocale.d_ptr->categoryName(DuiLocale::DuiLcTime); + + icu::Locale calLocale = DuiIcuConversions::createLocale(timeCategory, calendar); + + UErrorCode status = U_ZERO_ERROR; + + if (timezone.isEmpty() == false) { + // with explicit time zone + UnicodeString tzString; + tzString = DuiIcuConversions::qStringToUnicodeString(timezone); + icu::TimeZone *tz = icu::TimeZone::createTimeZone(tzString); + d->_calendar = icu::Calendar::createInstance(tz, calLocale, status); + + } else { + // gets the timezone from system default automatically + d->_calendar = icu::Calendar::createInstance(calLocale, status); + } + + if (!U_SUCCESS(status)) { + d->_valid = false; + } +} + + +//! Constructs a DuiCalendar based on calendar system used by given DuiLocale +DuiCalendar::DuiCalendar(const DuiLocale &duiLocale, const QString &timezone) + : d_ptr(new DuiCalendarPrivate(duiLocale.calendar())) +{ + Q_D(DuiCalendar); + + UErrorCode status = U_ZERO_ERROR; + icu::Locale calLocale + = duiLocale.d_ptr->getCategoryLocale(DuiLocale::DuiLcTime); + + if (timezone.isEmpty() == false) { + UnicodeString tzString; + tzString = DuiIcuConversions::qStringToUnicodeString(timezone); + icu::TimeZone *tz = icu::TimeZone::createTimeZone(tzString); + d->_calendar = icu::Calendar::createInstance(tz, calLocale, status); + + } else { + d->_calendar = icu::Calendar::createInstance(calLocale, status); + } + + if (!U_SUCCESS(status)) { + d->_valid = false; + } +} + + +//! Copy constructor +DuiCalendar::DuiCalendar(const DuiCalendar &other) + : d_ptr(new DuiCalendarPrivate(*other.d_ptr)) +{ + // nothing +} + +/*! + \brief Destroys the calendar. + */ +DuiCalendar::~DuiCalendar() +{ + delete d_ptr; +} + + +//! Assignment operator +DuiCalendar &DuiCalendar::operator=(const DuiCalendar &other) +{ + *d_ptr = *other.d_ptr; + return *this; +} + + + +//! checks the validity of the information of the calendar. Returns true if calendar is valid. +bool DuiCalendar::isValid() const +{ + Q_D(const DuiCalendar); + + // TODO: we might also check that there's enough information set for + // unambiguous moment of time. + return d->_valid; +} + + +//! returns the used calendar system +DuiLocale::Calendar DuiCalendar::type() const +{ + Q_D(const DuiCalendar); + + return d->_calendarType; +} + + +//! Sets the calendar date. Parameters self explanatory +void DuiCalendar::setDate(int year, int month, int day) +{ + Q_D(DuiCalendar); + + // icu calendar uses 0 based numbering for months + d->_calendar->set(year, month - 1, day); +} + + +//! Sets the calendar date from QDate +void DuiCalendar::setDate(const QDate &date) +{ + QDateTime datetime(date); + setDateTime(datetime); +} + + +//! Sets the calendar according to given QDate +void DuiCalendar::setDateTime(QDateTime date) +{ + Q_D(DuiCalendar); + + UErrorCode status = U_ZERO_ERROR; + + // we avoid time conversions made by qt + Qt::TimeSpec originalTimeSpec = date.timeSpec(); + date.setTimeSpec(Qt::UTC); + UDate icuDate = date.toTime_t() * 1000.0; + + // time needs to be adjusted to UTC time + if (originalTimeSpec == Qt::LocalTime) { + const icu::TimeZone &tz = d->_calendar->getTimeZone(); + qint32 rawOffset; + qint32 dstOffset; + tz.getOffset(icuDate, true /*local */, rawOffset, dstOffset, status); + + icuDate = icuDate - rawOffset - dstOffset; + } + + d->_calendar->setTime(icuDate, status); +} + + +//! Converts calendar into QDate +//! \param spec (optional) specification for resulting QDateTime, Qt::LocalTime (default) or Qt::UTC +QDateTime DuiCalendar::qDateTime(Qt::TimeSpec spec) const +{ + Q_D(const DuiCalendar); + + QDateTime time; + + UErrorCode status = U_ZERO_ERROR; + UDate icuDate = d->_calendar->getTime(status); + + if (spec == Qt::LocalTime) { + // adjust to UTC + const icu::TimeZone &tz = d->_calendar->getTimeZone(); + qint32 rawOffset; + qint32 dstOffset; + tz.getOffset(icuDate, true /*local */, rawOffset, dstOffset, status); + icuDate = icuDate - rawOffset - dstOffset; + } + + time.setTime_t(icuDate / 1000.0); // takes time in seconds since epoch + // note: we set time spec after time value so Qt will not any conversions + // of its own to UTC. We might let Qt handle it but this might be more robust + time.setTimeSpec(spec); + return time; +} + + +/*! + \brief Set the year of the date to \a year. + */ +void DuiCalendar::setYear(int year) +{ + Q_D(DuiCalendar); + + d->_calendar->set(UCAL_YEAR, year); +} + + +/*! + \brief Set the month of the date to \a month. + */ +void DuiCalendar::setMonth(int month) +{ + Q_D(DuiCalendar); + + d->_calendar->set(UCAL_MONTH, month - 1); +} + +/*! + \brief Set the day of the date to \a day. + */ +void DuiCalendar::setDay(int day) +{ + Q_D(DuiCalendar); + + d->_calendar->set(UCAL_DAY_OF_MONTH, day); +} + + +//! returns day number of the year. returns zero on error. +int DuiCalendar::dayOfYear() const +{ + Q_D(const DuiCalendar); + + UErrorCode status = U_ZERO_ERROR; + // status value is ignored because get returns zero on error + return d->_calendar->get(UCAL_DAY_OF_YEAR, status); +} + + +//! Returns week number in the year +int DuiCalendar::weekOfYear() const +{ + Q_D(const DuiCalendar); + + UErrorCode status = U_ZERO_ERROR; + return d->_calendar->get(UCAL_WEEK_OF_YEAR, status); +} + + +//! Returns month number +int DuiCalendar::month() const +{ + Q_D(const DuiCalendar); + + UErrorCode status = U_ZERO_ERROR; + return d->_calendar->get(UCAL_MONTH, status) + 1; // icu month is zero based +} + + +//! Returns year number +int DuiCalendar::year() const +{ + Q_D(const DuiCalendar); + + UErrorCode status = U_ZERO_ERROR; + return d->_calendar->get(UCAL_YEAR, status); +} + + +//! returns the year the current week "belongs to". +// +// e.g. 2008-12-31 belongs to week 1 of year 2009 +int DuiCalendar::yearOfWeek() const +{ + Q_D(const DuiCalendar); + + UErrorCode status = U_ZERO_ERROR; + return d->_calendar->get(UCAL_YEAR_WOY, status); +} + + +//! Returns day of month +int DuiCalendar::dayOfMonth() const +{ + Q_D(const DuiCalendar); + + UErrorCode status = U_ZERO_ERROR; + return d->_calendar->get(UCAL_DAY_OF_MONTH, status); +} + + +//! Returns day of week. Monday = 1 +int DuiCalendar::dayOfWeek() const +{ + Q_D(const DuiCalendar); + + UErrorCode status = U_ZERO_ERROR; + int uweekday = d->_calendar->get(UCAL_DAY_OF_WEEK, status); + return DuiCalendarPrivate::icuWeekdayToDuiWeekday(uweekday); +} + +/*! + \brief Set the hours of the date/time to \a hours. + */ +void DuiCalendar::setHours(int hours) +{ + Q_D(DuiCalendar); + + d->_calendar->set(UCAL_HOUR_OF_DAY, hours); +} + +/*! + \brief Set the minutes of the time to \a minutes. + */ +void DuiCalendar::setMinutes(int minutes) +{ + Q_D(DuiCalendar); + + d->_calendar->set(UCAL_MINUTE, minutes); +} + +/*! + \brief Set the seconds of the time to \a seconds. + */ +void DuiCalendar::setSeconds(int seconds) +{ + Q_D(DuiCalendar); + + d->_calendar->set(UCAL_SECOND, seconds); +} + + +//! Set calendar time of the day +void DuiCalendar::setTime(int hours, int minutes, int seconds) +{ + setHours(hours); + setMinutes(minutes); + setSeconds(seconds); +} + + +/*! + \brief Returns the current hours. + */ +int DuiCalendar::hour() const +{ + Q_D(const DuiCalendar); + + UErrorCode status = U_ZERO_ERROR; + // hour of day follows 24h clock + return d->_calendar->get(UCAL_HOUR_OF_DAY, status); +} + +/*! + \brief Returns the current minutes. + */ +int DuiCalendar::minute() const +{ + Q_D(const DuiCalendar); + + UErrorCode status = U_ZERO_ERROR; + return d->_calendar->get(UCAL_MINUTE, status); +} + +/*! + \brief Returns the current seconds. + */ +int DuiCalendar::second() const +{ + Q_D(const DuiCalendar); + + UErrorCode status = U_ZERO_ERROR; + return d->_calendar->get(UCAL_SECOND, status); +} + +/*! + \brief Add number of \a years years to the current date. + */ +void DuiCalendar::addYears(int years) +{ + Q_D(DuiCalendar); + + UErrorCode status = U_ZERO_ERROR; + d->_calendar->add(UCAL_YEAR, years, status); +} + +/*! + \brief Add number of \a months months to the current date. + */ +void DuiCalendar::addMonths(int months) +{ + Q_D(DuiCalendar); + + UErrorCode status = U_ZERO_ERROR; + d->_calendar->add(UCAL_MONTH, months, status); +} + +/*! + \brief Add number of \a days days to the current date. + */ +void DuiCalendar::addDays(int days) +{ + Q_D(DuiCalendar); + + UErrorCode status = U_ZERO_ERROR; + d->_calendar->add(UCAL_DATE, days, status); +} + +/*! + \brief Add number of \a hours hours to the current time. + */ +void DuiCalendar::addHours(int hours) +{ + Q_D(DuiCalendar); + + UErrorCode status = U_ZERO_ERROR; + d->_calendar->add(UCAL_HOUR, hours, status); +} + +/*! + \brief Add number of \a minutes minutes to the current time. + */ +void DuiCalendar::addMinutes(int minutes) +{ + Q_D(DuiCalendar); + + UErrorCode status = U_ZERO_ERROR; + d->_calendar->add(UCAL_MINUTE, minutes, status); +} + +/*! + \brief Add number of \a seconds seconds to the current time. + */ +void DuiCalendar::addSeconds(int seconds) +{ + Q_D(DuiCalendar); + + UErrorCode status = U_ZERO_ERROR; + d->_calendar->add(UCAL_SECOND, seconds, status); +} + + +/*! + \brief Returns first day of a month. + */ +int DuiCalendar::firstDayOfMonth() const +{ + Q_D(const DuiCalendar); + + UErrorCode status = U_ZERO_ERROR; + return d->_calendar->getActualMinimum(UCAL_DATE, status); +} + +/*! + \brief Returns last day of a month. + */ +int DuiCalendar::lastDayOfMonth() const +{ + Q_D(const DuiCalendar); + + UErrorCode status = U_ZERO_ERROR; + return d->_calendar->getActualMaximum(UCAL_DATE, status); +} + +/*! + \brief Sets the first day of the week to \a weekday. + */ +void DuiCalendar::setFirstDayOfWeek(int weekday) +{ + Q_D(DuiCalendar); + + d->_calendar->setFirstDayOfWeek(DuiIcuConversions::icuWeekday(weekday)); +} + +/*! + \brief Returns the first day of a week. + */ +int DuiCalendar::firstDayOfWeek() const +{ + Q_D(const DuiCalendar); + + UErrorCode status = U_ZERO_ERROR; + int weekday = d->_calendar->getFirstDayOfWeek(status); + return DuiCalendarPrivate::icuWeekdayToDuiWeekday(weekday); +} + + +//! sets what is the required amount of days for the first week of the year. +void DuiCalendar::setMinimalDaysInFirstWeek(int days) +{ + Q_D(DuiCalendar); + + d->_calendar->setMinimalDaysInFirstWeek(days); +} + + +//! returns the number of days required for the first week in the year +int DuiCalendar::minimalDaysInFirstWeek() const +{ + Q_D(const DuiCalendar); + + return d->_calendar->getMinimalDaysInFirstWeek(); +} + +/*! + \brief Returns the current week number. + */ +int DuiCalendar::weekNumber() const +{ + Q_D(const DuiCalendar); + + UErrorCode status = U_ZERO_ERROR; + return d->_calendar->get(UCAL_WEEK_OF_YEAR, status); +} + +/*! + \brief Returns the maximum number of weeks in a month. + */ +int DuiCalendar::maximumWeeksInMonth() const +{ + Q_D(const DuiCalendar); + + // unfortunately week numbering in the month doesn't necessarily + // start from the first day of month. + icu::Calendar *tmpCal = d->_calendar->clone(); + tmpCal->setMinimalDaysInFirstWeek(1); + int val = tmpCal->getMaximum(UCAL_WEEK_OF_MONTH); + delete tmpCal; + return val; +} + +/*! + \brief Returns the maximum number of days in a week. + */ +int DuiCalendar::daysInWeek() const +{ + Q_D(const DuiCalendar); + + return d->_calendar->getMaximum(UCAL_DAY_OF_WEEK); +} + +/*! + \brief Returns true if the current date/time of this calendar is after \a other. + */ +bool DuiCalendar::after(const DuiCalendar &other) const +{ + Q_D(const DuiCalendar); + + UErrorCode status = U_ZERO_ERROR; + return d->_calendar->after(*other.d_ptr->_calendar, status); +} + +/*! + \brief Returns true if the current date/time of this calendar is before \a other. + */ +bool DuiCalendar::before(const DuiCalendar &other) const +{ + Q_D(const DuiCalendar); + + UErrorCode status = U_ZERO_ERROR; + return d->_calendar->before(*other.d_ptr->_calendar, status); +} + +/*! + \brief Returns true if the current date/time of this calendar is equal to \a other. + */ +bool DuiCalendar::equals(const DuiCalendar &other) const +{ + Q_D(const DuiCalendar); + + UErrorCode status = U_ZERO_ERROR; + return d->_calendar->equals(*other.d_ptr->_calendar, status); +} + +/*! + \brief Returns true if the current date/time of this calendar is before \a other. + */ +bool DuiCalendar::operator<(const DuiCalendar &other) const +{ + return before(other); +} + +/*! + \brief Returns true if the current date/time of this calendar is equal or before \a other. + */ +bool DuiCalendar::operator<=(const DuiCalendar &other) const +{ + return before(other) || equals(other); +} + +/*! + \brief Returns true if the current date/time of this calendar is equal to \a other. + */ +bool DuiCalendar::operator==(const DuiCalendar &other) const +{ + return equals(other); +} + +/*! + \brief Returns true if the current date/time of this calendar is different than \a other. + */ +bool DuiCalendar::operator!=(const DuiCalendar &other) const +{ + return !equals(other); +} + +/*! + \brief Returns true if the current date/time of this calendar is after \a other. + */ +bool DuiCalendar::operator>(const DuiCalendar &other) const +{ + return after(other); +} + +/*! + \brief Returns true if the current date/time of this calendar is equal or after \a other. + */ +bool DuiCalendar::operator>=(const DuiCalendar &other) const +{ + return after(other) || equals(other); +} + + +//! Returns the system time zone string +QString DuiCalendar::systemTimeZone() +{ + icu::TimeZone *defaultTz = icu::TimeZone::createDefault(); + icu::UnicodeString id; + defaultTz->getID(id); + delete defaultTz; + return DuiIcuConversions::unicodeStringToQString(id); +} + + +//static +//! Sets system time zone +void DuiCalendar::setSystemTimeZone(const QString &timezone) +{ + icu::UnicodeString tzString = DuiIcuConversions::qStringToUnicodeString(timezone); + icu::TimeZone *tz = icu::TimeZone::createTimeZone(tzString); + // FIXME: should we check the creation succeeds with the string? + icu::TimeZone::adoptDefault(tz); +} + + +//static +//! Enumerates possible timezone IDs +QStringList DuiCalendar::supportedTimeZones() +{ + icu::StringEnumeration *strEnum = icu::TimeZone::createEnumeration(); + + QStringList result; + UErrorCode status = U_ZERO_ERROR; + const UnicodeString *next = strEnum->snext(status); + + while (next != 0) { + result << DuiIcuConversions::unicodeStringToQString(*next); + next = strEnum->snext(status); + } + + delete strEnum; + + return result; +} + + +//static +//! Enumerates possible timezone IDS for a specific country +QStringList DuiCalendar::supportedTimeZones(const QString &country) +{ + icu::StringEnumeration *strEnum = icu::TimeZone::createEnumeration(qPrintable(country)); + + QStringList result; + UErrorCode status = U_ZERO_ERROR; + const UnicodeString *next = strEnum->snext(status); + + while (next != 0) { + result << DuiIcuConversions::unicodeStringToQString(*next); + next = strEnum->snext(status); + } + + delete strEnum; + + return result; +} diff --git a/src/i18n/duicalendar.h b/src/i18n/duicalendar.h new file mode 100644 index 000000000..13b879a68 --- /dev/null +++ b/src/i18n/duicalendar.h @@ -0,0 +1,126 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUICALENDAR_H +#define DUICALENDAR_H + +#include + +#include "duilocale.h" +#include "duiexport.h" + +class DuiCalendarPrivate; +class QDateTime; +class QDate; + +class DUI_EXPORT DuiCalendar +{ +public: + explicit DuiCalendar(DuiLocale::Calendar calendar = DuiLocale::DefaultCalendar, + const QString &timezone = QString()); + explicit DuiCalendar(const DuiLocale &duiLocale, const QString &timezone = QString()); + + DuiCalendar(const DuiCalendar &other); + + virtual ~DuiCalendar(); + + DuiCalendar &operator=(const DuiCalendar &other); + + + bool isValid() const; + + DuiLocale::Calendar type() const; + + // TODO: do we need to set era, week of year, week of month, day of year etc? + + void setDate(int year, int month, int day); + void setDate(const QDate &date); + + void setDateTime(QDateTime datetime); + + QDateTime qDateTime(Qt::TimeSpec spec = Qt::LocalTime) const; + + void setYear(int year); + void setMonth(int month); + void setDay(int day); + + + int dayOfYear() const; + int weekOfYear() const; + int month() const; + int year() const; + int yearOfWeek() const; + int dayOfMonth() const; + int dayOfWeek() const; + + void setTime(int hours, int minutes, int seconds); + void setHours(int hours); + void setMinutes(int minutes); + void setSeconds(int seconds); + + int hour() const; + int minute() const; + int second() const; + + void addYears(int years); + void addMonths(int months); + void addDays(int days); + void addHours(int hours); + void addMinutes(int minutes); + void addSeconds(int seconds); + + int firstDayOfMonth() const; + int lastDayOfMonth() const; + + void setFirstDayOfWeek(int weekday); + int firstDayOfWeek() const; + + void setMinimalDaysInFirstWeek(int days); + int minimalDaysInFirstWeek() const; + + int weekNumber() const; + int maximumWeeksInMonth() const; + int daysInWeek() const; + + bool after(const DuiCalendar &other) const; + bool before(const DuiCalendar &other) const; + bool equals(const DuiCalendar &other) const; + + bool operator<(const DuiCalendar &other) const; + bool operator<=(const DuiCalendar &other) const; + bool operator==(const DuiCalendar &other) const; + bool operator!=(const DuiCalendar &other) const; + bool operator>(const DuiCalendar &other) const; + bool operator>=(const DuiCalendar &other) const; + + static void setSystemTimeZone(const QString &timezone); + static QString systemTimeZone(); + + static QStringList supportedTimeZones(); + static QStringList supportedTimeZones(const QString &country); + + +private: + DuiCalendarPrivate *const d_ptr; + Q_DECLARE_PRIVATE(DuiCalendar) + + friend class DuiLocale; +}; + +#endif diff --git a/src/i18n/duicalendar_p.h b/src/i18n/duicalendar_p.h new file mode 100644 index 000000000..376e1adae --- /dev/null +++ b/src/i18n/duicalendar_p.h @@ -0,0 +1,49 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUICALENDAR_P_H +#define DUICALENDAR_P_H + +#include + +#include "duilocale.h" +#include "duicalendar.h" + +class DuiCalendarPrivate +{ +public: + DuiCalendarPrivate(DuiLocale::Calendar calendar); + DuiCalendarPrivate(const DuiCalendarPrivate &other); + + virtual ~DuiCalendarPrivate(); + + DuiCalendarPrivate &operator=(const DuiCalendarPrivate &other); + + static DuiLocale::Weekday icuWeekdayToDuiWeekday(int uweekday); + + icu::Calendar *_calendar; + DuiLocale::Calendar _calendarType; + bool _valid; + +private: + + +}; + +#endif diff --git a/src/i18n/duicollator.cpp b/src/i18n/duicollator.cpp new file mode 100644 index 000000000..76c329797 --- /dev/null +++ b/src/i18n/duicollator.cpp @@ -0,0 +1,178 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duicollator.h" +#include "duicollator_p.h" + +#include +#include + +#include "duilocale.h" +#include "duiicuconversions.h" +#include "duilocale_p.h" + + +///////////////////// +// DuiCollatorPrivate + +DuiCollatorPrivate::DuiCollatorPrivate() + : _coll(0) +{ + // nothing +} + + +DuiCollatorPrivate::~DuiCollatorPrivate() +{ + delete _coll; +} + + +// allocates an icu collator based on locale +void DuiCollatorPrivate::initCollator(icu::Locale locale) +{ + UErrorCode status = U_ZERO_ERROR; + _coll = icu::Collator::createInstance(locale, status); +} + + +////////////////////// +// Actual DuiCollator + + +/*! + \class DuiCollator + + \brief DuiCollator is a DuiLocale dependant class that is used to do locale aware string comparisons. + + DuiCollator can be created using DuiLocale::collator(). It is used + as a functor or with the comparison methods. + + Example: + \verbatim + DuiLocale loc; // default locale + DuiCollator comp = loc.collator(); + + QStringList stringList; + stringList << "bb" << "da" << "aa" << "ab"; + + qSort(stringList.begin(), stringList.end(), comp); // sorts the list + \endverbatim + + */ + +//! Constructor, gets locale data from default locale +DuiCollator::DuiCollator() + : d_ptr(new DuiCollatorPrivate) +{ + Q_D(DuiCollator); + + DuiLocale defaultLocale; + + icu::Locale icuLocale + = defaultLocale.d_ptr->getCategoryLocale(DuiLocale::DuiLcCollate); + d->initCollator(icuLocale); +} + + +//! Constructor, creates a collator based on given DuiLocale +DuiCollator::DuiCollator(const DuiLocale &locale) + : d_ptr(new DuiCollatorPrivate) +{ + Q_D(DuiCollator); + + icu::Locale icuLocale + = locale.d_ptr->getCategoryLocale(DuiLocale::DuiLcCollate); + d->initCollator(icuLocale); +} + + +//! Copy constructor +DuiCollator::DuiCollator(const DuiCollator &other) + : d_ptr(new DuiCollatorPrivate) +{ + Q_D(DuiCollator); + + d->_coll = other.d_ptr->_coll->safeClone(); +} + + +DuiCollator::~DuiCollator() +{ + delete d_ptr; +} + + +//! operator () works as lessThan comparison. +//! Returns true if first string is less than the second +bool DuiCollator::operator()(const QString &s1, const QString &s2) const +{ + Q_D(const DuiCollator); + + const icu::UnicodeString us1 = DuiIcuConversions::qStringToUnicodeString(s1); + const icu::UnicodeString us2 = DuiIcuConversions::qStringToUnicodeString(s2); + icu::Collator::EComparisonResult result = d->_coll->compare(us1, us2); + + if (result == Collator::LESS) { + return true; + } else { + return false; + } +} + + +//! Compares two strings with the default DuiLocale +DuiLocale::Comparison DuiCollator::compare(const QString &first, + const QString &second) +{ + DuiLocale defaultLocale; + return compare(defaultLocale, first, second); +} + + +//! Compares two string using given locale +DuiLocale::Comparison DuiCollator::compare(DuiLocale &locale, const QString &first, + const QString &second) +{ + UErrorCode status = U_ZERO_ERROR; + icu::Locale icuLocale + = locale.d_ptr->getCategoryLocale(DuiLocale::DuiLcCollate); + icu::Collator *collator = icu::Collator::createInstance(icuLocale, status); + + if (!U_SUCCESS(status)) { + return DuiLocale::Equal; // ERROR + } + + const icu::UnicodeString us1 = DuiIcuConversions::qStringToUnicodeString(first); + const icu::UnicodeString us2 = DuiIcuConversions::qStringToUnicodeString(second); + + // do the comparison + icu::Collator::EComparisonResult result = collator->compare(us1, us2); + delete collator; + + if (result == icu::Collator::LESS) { + return DuiLocale::LessThan; + + } else if (result == icu::Collator::EQUAL) { + return DuiLocale::Equal; + + } else { + return DuiLocale::GreaterThan; + } +} diff --git a/src/i18n/duicollator.h b/src/i18n/duicollator.h new file mode 100644 index 000000000..257ea5349 --- /dev/null +++ b/src/i18n/duicollator.h @@ -0,0 +1,57 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUICOLLATOR_H +#define DUICOLLATOR_H + +#include "duiexport.h" +#include "duilocale.h" + +class QString; +class DuiCollatorPrivate; + +class DUI_EXPORT DuiCollator +{ +public: + DuiCollator(); + DuiCollator(const DuiLocale &locale); + DuiCollator(const DuiCollator &other); + virtual ~DuiCollator(); + + bool operator()(const QString &s1, const QString &s2) const; + + static DuiLocale::Comparison compare(const QString &first, const QString &second); + + static DuiLocale::Comparison compare(DuiLocale &locale, const QString &first, + const QString &second); + +private: + // not implemented + bool operator==(const DuiCollator &other) const; + bool operator!=(const DuiCollator &other) const; + DuiCollator &operator=(const DuiCollator &other); + + Q_DECLARE_PRIVATE(DuiCollator) + DuiCollatorPrivate *const d_ptr; + + friend class DuiLocale; +}; + + +#endif diff --git a/src/i18n/duicollator_p.h b/src/i18n/duicollator_p.h new file mode 100644 index 000000000..a7a06b5e0 --- /dev/null +++ b/src/i18n/duicollator_p.h @@ -0,0 +1,39 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUICOLLATOR_P_H +#define DUICOLLATOR_P_H + +#include + +class DuiCollatorPrivate +{ +public: + DuiCollatorPrivate(); + virtual ~DuiCollatorPrivate(); + + void initCollator(icu::Locale locale); + + icu::Collator *_coll; + +private: + DuiCollatorPrivate(const DuiCollatorPrivate &other); +}; + +#endif diff --git a/src/i18n/duiicubreakiterator.cpp b/src/i18n/duiicubreakiterator.cpp new file mode 100644 index 000000000..345a4b1d6 --- /dev/null +++ b/src/i18n/duiicubreakiterator.cpp @@ -0,0 +1,297 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiicubreakiterator.h" +#include + +#ifdef HAVE_ICU +#include +#include +#include "duilocale_p.h" +#endif + +/* + * internally used by DuiBreakIterator + */ +class DuiIcuBreakIteratorPrivate +{ +public: + DuiIcuBreakIteratorPrivate(); + virtual ~DuiIcuBreakIteratorPrivate(); + + void init(const DuiLocale &locale, const QString &text, DuiBreakIterator::Type type); + + int current; + + icu::BreakIterator *icuIterator; +}; + +DuiIcuBreakIteratorPrivate::DuiIcuBreakIteratorPrivate() + : current(-1), icuIterator(0) +{ + // nothing +} + +DuiIcuBreakIteratorPrivate::~DuiIcuBreakIteratorPrivate() +{ + delete icuIterator; +} + +void DuiIcuBreakIteratorPrivate::init(const DuiLocale &locale, const QString &text, + DuiBreakIterator::Type type) +{ + UErrorCode status = U_ZERO_ERROR; + + icu::Locale msgLocale + = locale.d_ptr->getCategoryLocale(DuiLocale::DuiLcMessages); + + switch (type) { + case DuiBreakIterator::LineIterator: + icuIterator = icu::BreakIterator::createLineInstance(msgLocale, status); + break; + + case DuiBreakIterator::WordIterator: + icuIterator = icu::BreakIterator::createWordInstance(msgLocale, status); + break; + } + + if (U_FAILURE(status)) { + duiWarning("DuiIcuBreakIteratorPrivate") << "failed creating iterator:" << u_errorName(status); + return; + } + + UCharCharacterIterator *it = new UCharCharacterIterator(text.utf16(), text.length()); + icuIterator->adoptText(it); +} + +DuiIcuBreakIterator::DuiIcuBreakIterator(const DuiLocale &locale, + const QString &text, + DuiBreakIterator::Type type) + : d_ptr(new DuiIcuBreakIteratorPrivate) +{ + Q_D(DuiIcuBreakIterator); + d->init(locale, text, type); +} + +///! Creates a DuiIcuBreakIterator using default locale +DuiIcuBreakIterator::DuiIcuBreakIterator(const QString &text, + DuiBreakIterator::Type type) + : d_ptr(new DuiIcuBreakIteratorPrivate) +{ + Q_D(DuiIcuBreakIterator); + DuiLocale locale; // get default + d->init(locale, text, type); +} + +//! Destructor +DuiIcuBreakIterator::~DuiIcuBreakIterator() +{ + delete d_ptr; +} + +//! returns true if a boundary exists after current index +bool DuiIcuBreakIterator::hasNext() const +{ + Q_D(const DuiIcuBreakIterator); + + int next = d->icuIterator->following(d->current); + + if (next != BreakIterator::DONE) { + return true; + } else { + return false; + } +} + +//! returns true if boundary exists before current index +bool DuiIcuBreakIterator::hasPrevious() const +{ + Q_D(const DuiIcuBreakIterator); + + int previous = d->icuIterator->preceding(d->current); + + if (previous != BreakIterator::DONE) { + return true; + } else { + return false; + } +} + +//! returns the next boundary index after the current index or -1 if none exists. +//! current index is updated to the resulting value. +int DuiIcuBreakIterator::next() +{ + Q_D(DuiIcuBreakIterator); + + int next = d->icuIterator->following(d->current); + + if (next == BreakIterator::DONE) { + next = -1; + toBack(); + } else { + d->current = next; + } + + return next; +} + +//! returns the next boundary after the given index. Returns the boundary or -1 +//! if none exists. Updates the current index to the resulting value. +int DuiIcuBreakIterator::next(int index) +{ + Q_D(DuiIcuBreakIterator); + + int result = d->icuIterator->following(index); + + if (result == BreakIterator::DONE) { + result = -1; + toBack(); + } + + return result; +} + +//! returns the next boundary index value. The current index is not updated. +int DuiIcuBreakIterator::peekNext() +{ + Q_D(DuiIcuBreakIterator); + + int next = d->icuIterator->following(d->current); + + if (next == BreakIterator::DONE) { + next = -1; + } + + return next; +} + +//! returns the previous boundary index value. The current index is not updated. +int DuiIcuBreakIterator::peekPrevious() +{ + Q_D(DuiIcuBreakIterator); + + int previous = d->icuIterator->preceding(d->current); + + if (previous == BreakIterator::DONE) { + previous = -1; + } + + return previous; +} + +//! returns the previous boundary index or -1 if none exists. +//! The current index is updated to the resulting value. +int DuiIcuBreakIterator::previous() +{ + Q_D(DuiIcuBreakIterator); + + int result = d->icuIterator->preceding(d->current); + + if (result == BreakIterator::DONE) { + result = -1; + toFront(); + } + + d->current = result; + + return result; +} + +//! returns the previous boundary from the given index value or -1 if none exists. +//! The current index is updated to the resulting value. +int DuiIcuBreakIterator::previous(int index) +{ + Q_D(DuiIcuBreakIterator); + + int result = d->icuIterator->preceding(index); + + if (result == BreakIterator::DONE) { + result = -1; + toFront(); + } + + d->current = result; + return result; +} + +//! returns the previous boundary including the current index in the search. +//! If current index is a boundary, it is returned and current is decreased by one, +//! otherwise works as previous() +int DuiIcuBreakIterator::previousInclusive() +{ + Q_D(DuiIcuBreakIterator); + if (isBoundary()) { + int result = d->current; + --d->current; + return result; + + } else { + return previous(); + } +} + +//! returns the previous boundary from given index, including the index in the search. +//! If index is a boundary, it is returned and current is decreased by one, +//! otherwise works as previous() +int DuiIcuBreakIterator::previousInclusive(int index) +{ + Q_D(DuiIcuBreakIterator); + if (isBoundary(index)) { + d->current = index - 1; + return index; + } else { + return previous(index); + } +} + +//! Sets the current index to the given value +void DuiIcuBreakIterator::setIndex(int index) +{ + Q_D(DuiIcuBreakIterator); + d->current = index; +} + +//! Sets the current index to the end of the string +void DuiIcuBreakIterator::toBack() +{ + Q_D(DuiIcuBreakIterator); + // API reference says last() gives index _beyond_ the last character. not so. + d->current = d->icuIterator->last() + 1; +} + +//! Sets the current index to the beginning of the string +void DuiIcuBreakIterator::toFront() +{ + Q_D(DuiIcuBreakIterator); + d->current = -1; +} + +//! Checks if current index is a boundary. +bool DuiIcuBreakIterator::isBoundary() +{ + Q_D(DuiIcuBreakIterator); + return isBoundary(d->current); +} + +//! Checks if given index is a boundary. +bool DuiIcuBreakIterator::isBoundary(int index) +{ + Q_D(DuiIcuBreakIterator); + return d->icuIterator->isBoundary(index); +} diff --git a/src/i18n/duiicubreakiterator.h b/src/i18n/duiicubreakiterator.h new file mode 100644 index 000000000..76775f0ea --- /dev/null +++ b/src/i18n/duiicubreakiterator.h @@ -0,0 +1,71 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIICUBREAKITERATOR_H +#define DUIICUBREAKITERATOR_H + +// Make doxygen skip this internal class +//! \cond + +#include "duiexport.h" +#include "duilocale.h" +#include "duibreakiterator.h" +#include "duibreakiteratorif.h" + +#include + +class DuiIcuBreakIteratorPrivate; + +//! \internal Used by DuiBreakIterator +class DuiIcuBreakIterator : public DuiBreakIteratorIf +{ +public: + DuiIcuBreakIterator(const DuiLocale &locale, + const QString &text, + DuiBreakIterator::Type type = DuiBreakIterator::WordIterator); + explicit DuiIcuBreakIterator(const QString &text, + DuiBreakIterator::Type type = DuiBreakIterator::WordIterator); + virtual ~DuiIcuBreakIterator(); + + // java-style iterator interface: + bool hasNext() const; + bool hasPrevious() const; + int next(); + int next(int index); // searching from explicit index + int peekNext(); + int peekPrevious(); + int previous(); + int previous(int index); + int previousInclusive(); + int previousInclusive(int index); + void toBack(); + void toFront(); + void setIndex(int index); + bool isBoundary(); + bool isBoundary(int index); + +private: + Q_DISABLE_COPY(DuiIcuBreakIterator) + Q_DECLARE_PRIVATE(DuiIcuBreakIterator) + DuiIcuBreakIteratorPrivate *const d_ptr; +}; +//! \internal_end + +//! \endcond +#endif diff --git a/src/i18n/duiicuconversions.cpp b/src/i18n/duiicuconversions.cpp new file mode 100644 index 000000000..a129996ab --- /dev/null +++ b/src/i18n/duiicuconversions.cpp @@ -0,0 +1,212 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiicuconversions.h" + +#include +#include +#include + +#include "duilocale_p.h" + +namespace +{ +// string presentations for DuiLocale::Collate and DuiLocale::Calendar +// Keep in sync! + + const char *const CollationNames[] = {"", "phonebook", "pinyin", "traditional", "stroke", "direct", + "posix", "big5han", "gb2312han" + }; + + + const char *const CalendarNames[] = {"", "gregorian", "islamic", "chinese", "islamic-civil", "hebrew", + "japanese", "buddhist", "persian", "coptic", "ethiopic" + }; +} + +icu::UnicodeString DuiIcuConversions::qStringToUnicodeString(const QString &sourceStr) +{ + return UnicodeString(static_cast(sourceStr.utf16())); +} + +QString DuiIcuConversions::unicodeStringToQString(const icu::UnicodeString &sourceStr) +{ + return QString(reinterpret_cast(sourceStr.getBuffer()), + sourceStr.length()); +} + +icu::DateFormat::EStyle DuiIcuConversions::toEStyle(DuiLocale::DateType &dateType) +{ + if (dateType == DuiLocale::DateNone) { + return icu::DateFormat::kNone; + } + + if (dateType == DuiLocale::DateShort) { + return icu::DateFormat::kShort; + } + + if (dateType == DuiLocale::DateMedium) { + return icu::DateFormat::kMedium; + } + + if (dateType == DuiLocale::DateLong) { + return icu::DateFormat::kLong; + } + + return icu::DateFormat::kFull; +} + +icu::DateFormat::EStyle DuiIcuConversions::toEStyle(DuiLocale::TimeType &timeType) +{ + if (timeType == DuiLocale::TimeNone) { + return icu::DateFormat::kNone; + } + + if (timeType == DuiLocale::TimeShort) { + return icu::DateFormat::kShort; + } + + if (timeType == DuiLocale::TimeMedium) { + return icu::DateFormat::kMedium; + } + + if (timeType == DuiLocale::TimeLong) { + return DateFormat::kLong; + } + + return icu::DateFormat::kFull; +} + +QString DuiIcuConversions::collationToString(DuiLocale::Collation coll) +{ + if (static_cast(coll) >= (sizeof(CollationNames) / sizeof(char *))) { + return ""; + } + + return CollationNames[coll]; +} + +QString DuiIcuConversions::calendarToString(DuiLocale::Calendar cal) +{ + if (static_cast(cal) >= (sizeof(CalendarNames) / sizeof(char *))) { + return ""; + } + + return CalendarNames[cal]; +} + +icu::DateFormatSymbols::DtContextType +DuiIcuConversions::duiDateContextToIcu(DuiLocale::DateSymbolContext context) +{ + icu::DateFormatSymbols::DtContextType icuContext; + + if (context == DuiLocale::DateSymbolFormat) { + icuContext = icu::DateFormatSymbols::FORMAT; + } else { + icuContext = icu::DateFormatSymbols::STANDALONE; + } + + return icuContext; +} + + +icu::DateFormatSymbols::DtWidthType +DuiIcuConversions::duiDateWidthToIcu(DuiLocale::DateSymbolLength length) +{ + icu::DateFormatSymbols::DtWidthType icuWidth; + + switch (length) { + case DuiLocale::DateSymbolAbbreviated: + icuWidth = icu::DateFormatSymbols::ABBREVIATED; + break; + + case DuiLocale::DateSymbolWide: + icuWidth = icu::DateFormatSymbols::WIDE; + break; + + case DuiLocale::DateSymbolNarrow: + default: + icuWidth = icu::DateFormatSymbols::NARROW; + break; + } + + return icuWidth; +} + +UCalendarDaysOfWeek DuiIcuConversions::icuWeekday(int duiWeekday) +{ + int weekdayNum = duiWeekday; + + // sunday = 1, monday = 2 etc on the array + if (duiWeekday == DuiLocale::Sunday) { + weekdayNum = 1; + } else { + weekdayNum++; + } + + return static_cast(weekdayNum); +} + +int DuiIcuConversions::duiWeekday(int icuWeekday) +{ + if (icuWeekday == UCAL_SUNDAY) { + return DuiLocale::Sunday; // 1 -> 7 + } else { + return icuWeekday - 1; + } +} + +QString DuiIcuConversions::escapeIcuDatePattern(const QString &str) +{ + QString result = str; + return result.replace('\'', "''"); +} + +icu::Locale DuiIcuConversions::createLocale(const QString &baseString, + DuiLocale::Calendar calendar, + DuiLocale::Collation collation) +{ + // calendar and collation are appended as @keyword=value;keyword2=value2; + // first create the attribute part keyword=value;... + QString attributeAccu; + + if (collation != DuiLocale::DefaultCollation) { + attributeAccu.append("collation="); + + QString collName = DuiIcuConversions::collationToString(collation); + attributeAccu.append(collName); + attributeAccu.append(";"); + } + + if (calendar != DuiLocale::DefaultCalendar) { + attributeAccu.append("calendar="); + QString calendarName = DuiIcuConversions::calendarToString(calendar); + attributeAccu.append(calendarName); + } + + QString baseStringModified = baseString; + // ICU doesn't accept trailing "@" with no actual attributes + if (!attributeAccu.isEmpty()) { + baseStringModified.append("@"); + baseStringModified.append(attributeAccu); + } + + return icu::Locale(qPrintable(baseStringModified)); +} + diff --git a/src/i18n/duiicuconversions.h b/src/i18n/duiicuconversions.h new file mode 100644 index 000000000..410f8c157 --- /dev/null +++ b/src/i18n/duiicuconversions.h @@ -0,0 +1,147 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIICUCONVERSIONS_H +#define DUIICUCONVERSIONS_H + +#include +#include +#include + +#include "duilocale.h" + +class QString; + +//! \internal + +namespace DuiIcuConversions +{ + /*! + * \brief converts a QString into an icu::UnicodeString + * + * @param sourceStr The QString which will be converted into an icu::UnicodeString. + * + * \sa DuiIcuConversions::unicodeStringToQString() + */ + icu::UnicodeString qStringToUnicodeString(const QString &sourceStr); + + /*! + * \brief converts an icu::UnicodeString into a QString + * + * @param sourceStr The icu::UnicodeString which will be converted into a QString. + * + * \sa DuiIcuConversions::qStringToUnicodeString() + */ + QString unicodeStringToQString(const icu::UnicodeString &sourceStr); + + /*! + * \brief transforms DuiLocale::DateType enums to icu::DateFormat::EStyle enums + * + * @param dateType The DuiLocale::DateType enum + * + * \sa DuiIcuConversions::toEStyle(DuiLocale::TimeType &timeType) + */ + icu::DateFormat::EStyle toEStyle(DuiLocale::DateType &dateType); + + /*! + * \brief transforms DuiLocale::TimeType enums to icu::DateFormat::EStyle enums + * + * @param timeType The DuiLocale::TimeType enum + * + * \sa DuiIcuConversions::toEStyle(DuiLocale::DateType &dateType) + */ + icu::DateFormat::EStyle toEStyle(DuiLocale::TimeType &timeType); + + /*! + * \brief transforms DuiLocale::Collation enum to icu string presentations + * + * @param coll DuiLocale::Collation enum + * + * \sa DuiIcuConversions::calendarToString(DuiLocale::Calendar cal) + */ + QString collationToString(DuiLocale::Collation coll); + + /*! + * \brief transforms DuiLocale::Calendar enum to icu string presentations + * + * @param cal DuiLocale::Calendar enum + * + * \sa DuiIcuConversions::collationToString(DuiLocale::Collation coll); + */ + QString calendarToString(DuiLocale::Calendar cal); + + /*! + * \brief transforms DuiLocale::DateSymbolContext to icu::DateFormatSymbols::DtContextType + * + * @param context DuiLocale::DateSymbolContext + * + * \sa DuiIcuConversions::duiDateWidthToIcu(DuiLocale::DateSymbolLength length) + */ + icu::DateFormatSymbols::DtContextType duiDateContextToIcu(DuiLocale::DateSymbolContext context); + + /*! + * \brief transforms DuiLocale::DateSymbolLength to icu::DateFormatSymbols::DtWidthType + * + * @param length DuiLocale::DateSymbolLength + * + * \sa DuiIcuConversions::duiDateContextToIcu(DuiLocale::DateSymbolContext context) + */ + icu::DateFormatSymbols::DtWidthType duiDateWidthToIcu(DuiLocale::DateSymbolLength length); + + /*! + * \brief transforms a Dui weekday to an ICU weekday. + * + * ICU and Dui use different numbering for weekdays: + * ICU: 1 = Sunday, 2 Monday, ..., 7 = Saturday + * Dui: 1 = Monday, 2 = Tuesday, ..., 7 = Sunday + * + * \sa duiWeekday(int icuWeekday) + */ + UCalendarDaysOfWeek icuWeekday(int duiWeekday); + + /*! + * \brief transforms an ICU weekday to a Dui weekday + * + * ICU and Dui use different numbering for weekdays: + * ICU: 1 = Sunday, 2 Monday, ..., 7 = Saturday + * Dui: 1 = Monday, 2 = Tuesday, ..., 7 = Sunday + * + * \sa icuWeekday(int duiWeekday); + */ + int duiWeekday(int icuWeekday); + + /*! + * \brief escapes all 's in a string as '' + * + * ICU date patterns need to have 's escaped as '' + * + */ + QString escapeIcuDatePattern(const QString &str); + + /*! + * \brief creates an icu::Locale based on a locale string and additional parameters + */ + icu::Locale createLocale(const QString &baseString, + DuiLocale::Calendar calendar = DuiLocale::DefaultCalendar, + DuiLocale::Collation collation = DuiLocale::DefaultCollation); +} + +//! \internal_end + +#endif diff --git a/src/i18n/duilocale.cpp b/src/i18n/duilocale.cpp new file mode 100644 index 000000000..3a0245bb4 --- /dev/null +++ b/src/i18n/duilocale.cpp @@ -0,0 +1,2016 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duilocale.h" +#include "duilocale_p.h" + +#ifdef HAVE_ICU +#include +#include +#include +#include +#include +#include +#include // SimpleDateFormat +#include +#include +#include // date format symbols +#include // u_setDataDirectory +#endif + +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_ICU +#include "duicollator.h" +#include "duicalendar.h" +#include "duicalendar_p.h" +#include "duiicuconversions.h" +#endif + +namespace +{ + const char *const BackupNameFormatString = "%d%t%g%t%m%t%f"; + const char *const ExtraDataBundleName = "extradata"; + const QString RtlLanguages("am:ar:fa:he:ps:ur:"); + const char *const Languages = "Languages"; + const char *const Countries = "Countries"; + + const QString ScriptLatin("Latn"); + + const QString SettingsLanguage("/Dui/i18n/Language"); + const QString SettingsCountry("/Dui/i18n/Country"); + const QString SettingsScript("/Dui/i18n/Script"); + const QString SettingsVariant("/Dui/i18n/Variant"); +} + +/// Helper +// Copied from Qt's QCoreApplication +static void replacePercentN(QString *result, int n) +{ + if (n >= 0) { + int percentPos = 0; + int len = 0; + while ((percentPos = result->indexOf(QLatin1Char('%'), percentPos + len)) != -1) { + len = 1; + //TODO replace fmt to other type to do our own native digit conversions + QString fmt; + if (result->at(percentPos + len) == QLatin1Char('L')) { + ++len; + fmt = QLatin1String("%L1"); + } else { + fmt = QLatin1String("%1"); + } + if (result->at(percentPos + len) == QLatin1Char('n')) { + fmt = fmt.arg(n); + ++len; + result->replace(percentPos, len, fmt); + len = fmt.length(); + } + } + } +} + + +///////////////////////////////////////////////// +//// The private Duitranslationcatalog class //// + +//! \internal +class DuiTranslationCatalog: public QSharedData +{ +public: + + DuiTranslationCatalog(const QString &name); + virtual ~DuiTranslationCatalog(); + + // called by detach + DuiTranslationCatalog(const DuiTranslationCatalog &other); + + /*! + * \brief Load the actual translation file using locale and category info + * + * As an example lets assume that + * + * - DuiLocale::translationPaths() + * is the list ("/usr/share/l10n/dui", "/usr/share/l10n") + * - the category is DuiLocale::DuiLcMessages + * - the name of the locale (returned by duilocale->categoryName(category)) + * is "en_US" + * - the base name of the translation file is "foo" + * + * then the function will try to load translation catalogs in the following order: + * + * /usr/share/l10n/dui/LC_MESSAGES/foo_en_US.qm + * /usr/share/l10n/dui/LC_MESSAGES/foo_en_US + * /usr/share/l10n/dui/LC_MESSAGES/foo_en.qm + * /usr/share/l10n/dui/LC_MESSAGES/foo_en + * /usr/share/l10n/dui/LC_MESSAGES/foo.qm + * /usr/share/l10n/dui/LC_MESSAGES/foo + * /usr/share/l10n/dui/foo_en_US.qm + * /usr/share/l10n/dui/foo_en_US + * /usr/share/l10n/dui/foo_en.qm + * /usr/share/l10n/dui/foo_en + * /usr/share/l10n/dui/foo.qm + * /usr/share/l10n/dui/foo + * /usr/share/l10n/LC_MESSAGES/foo_en_US.qm + * /usr/share/l10n/LC_MESSAGES/foo_en_US + * /usr/share/l10n/LC_MESSAGES/foo_en.qm + * /usr/share/l10n/LC_MESSAGES/foo_en + * /usr/share/l10n/LC_MESSAGES/foo.qm + * /usr/share/l10n/LC_MESSAGES/foo + * /usr/share/l10n/foo_en_US.qm + * /usr/share/l10n/foo_en_US + * /usr/share/l10n/foo_en.qm + * /usr/share/l10n/foo_en + * /usr/share/l10n/foo.qm + * /usr/share/l10n/foo + * + * and return when the first translation catalog was found. + * If no translation can be found this function returns false. + * + * The way locale specific parts are successively cut away from the + * translation file name is inherited from + * QTranslator::load() + * because this is used to load the translation files. + * + * @param duilocale the locale for which the translations are loaded + * @param category this is usually DuiLocale::DuiLcMessages but it could + * also be DuiLocale::DuiLcTime, DuiLocale::DuiLcNumeric, + * etc... + * + * @return true if translations could be found, false if not. + */ + bool loadWith(DuiLocale *duilocale, DuiLocale::Category category); + + // the abstract name for a translation. together with locale info and + // category a concrete path is created when the file is loaded + QString _name; + + // the actual translator + QTranslator _translator; + +private: + DuiTranslationCatalog &operator=(const DuiTranslationCatalog &other); +}; +//! \endinternal + +// ////// +// DuiTranslationCatalog implementation + +DuiTranslationCatalog::DuiTranslationCatalog(const QString &name) + : _name(name), _translator() +{ + // nothing +} + +DuiTranslationCatalog::~DuiTranslationCatalog() +{ + // nothing +} + +DuiTranslationCatalog::DuiTranslationCatalog(const DuiTranslationCatalog &other) + : QSharedData(), _name(other._name) +{ + // nothing +} + +bool DuiTranslationCatalog::loadWith(DuiLocale *duilocale, DuiLocale::Category category) +{ + QStringList localeDirs = DuiLocale::translationPaths(); + QString categoryPathSuffix = '/' + DuiLocalePrivate::categoryToDirectoryName(category) + '/'; + + const int size = localeDirs.size(); + for (int i = 0; i < size; ++i) { + if (_translator.load(_name + '_' + duilocale->categoryName(category), + QDir(localeDirs.at(i) + categoryPathSuffix).absolutePath())) + return true; + if (_translator.load(_name + '_' + duilocale->categoryName(category), + QDir(localeDirs.at(i)).absolutePath())) + return true; + } + + return false; +} + +//////////////////////////////// +//// Private stuff for DuiLocale + +QStringList DuiLocalePrivate::translationPaths; + +// categories have their translations in their own subdirectories. +QString DuiLocalePrivate::categoryToDirectoryName(DuiLocale::Category category) +{ + switch (category) { + case DuiLocale::DuiLcMessages: + return "LC_MESSAGES"; + + case DuiLocale::DuiLcTime: + return "LC_TIME"; + + default: + return QString(); + } +} + + +QString DuiLocalePrivate::createLocaleString(const QString &language, + const QString &country, + const QString &script, + const QString &variant) +{ + if (language.isEmpty()) + return ""; + + // construct the locale string from the parameters + QString localeString(language); + + if (!script.isEmpty()) + localeString += '_' + script; + + if (!country.isEmpty()) + localeString += '_' + country; + + if (!variant.isEmpty()) + localeString += '_' + variant; + + return localeString; +} + +#ifdef HAVE_ICU +icu::DateFormatSymbols *DuiLocalePrivate::createDateFormatSymbols(icu::Locale locale) +{ + // This is a bit dirty but the only way to currently get the symbols + // is like this. only internal API supports directly creating DateFormatSymbols + // with arbitrary calendar + UErrorCode status = U_ZERO_ERROR; + SimpleDateFormat dummyFormatter("", locale, status); + + if (U_FAILURE(status)) { + return 0; + } + + const DateFormatSymbols *dfs = dummyFormatter.getDateFormatSymbols(); + return new DateFormatSymbols(*dfs); +} +#endif + +// Constructors + +DuiLocalePrivate::DuiLocalePrivate() + : _valid(true), + _calendar(DuiLocale::DefaultCalendar), + _collation(DuiLocale::DefaultCollation) +#ifdef HAVE_ICU + , _numberFormat(0) +#endif +#ifdef HAVE_GCONF + , currentLanguageItem(SettingsLanguage), + currentCountryItem(SettingsCountry), + currentScriptItem(SettingsScript), + currentVariantItem(SettingsVariant) +#endif +{ +} + +// copy constructor +DuiLocalePrivate::DuiLocalePrivate(const DuiLocalePrivate &other) + : _valid(other._valid), + _defaultLocale(other._defaultLocale), + _messageLocale(other._messageLocale), + _numericLocale(other._numericLocale), + _collationLocale(other._collationLocale), + _calendarLocale(other._calendarLocale), + _monetaryLocale(other._monetaryLocale), + _nameLocale(other._nameLocale), + _calendar(other._calendar), + _collation(other._collation), +#ifdef HAVE_ICU + _numberFormat(0), +#endif + _messageTranslations(other._messageTranslations), + _timeTranslations(other._timeTranslations), + _trTranslations(other._trTranslations) +#ifdef HAVE_GCONF + , currentLanguageItem(SettingsLanguage), + currentCountryItem(SettingsCountry), + currentScriptItem(SettingsScript), + currentVariantItem(SettingsVariant) +#endif +{ +#ifdef HAVE_ICU + if (other._numberFormat != 0) { + _numberFormat = static_cast((other._numberFormat)->clone()); + } +#endif +} + +DuiLocalePrivate::~DuiLocalePrivate() +{ +#ifdef HAVE_ICU + delete _numberFormat; +#endif + // note: if tr translations are inserted into QCoreApplication + // deleting the QTranslator removes them from the QCoreApplication +} + +DuiLocalePrivate &DuiLocalePrivate::operator=(const DuiLocalePrivate &other) +{ + _valid = other._valid; + _defaultLocale = other._defaultLocale; + _messageLocale = other._messageLocale; + _numericLocale = other._numericLocale; + _collationLocale = other._collationLocale; + _calendarLocale = other._calendarLocale; + _monetaryLocale = other._monetaryLocale; + _nameLocale = other._nameLocale; + _calendar = other._calendar; + _collation = other._collation; + _messageTranslations = other._messageTranslations; + _timeTranslations = other._timeTranslations; + _trTranslations = other._trTranslations; + +#ifdef HAVE_ICU + delete _numberFormat; + + if (other._numberFormat) { + _numberFormat = static_cast((other._numberFormat)->clone()); + + } else { + _numberFormat = 0; + } +#endif + + return *this; +} + +#ifdef HAVE_ICU +// creates icu::Locale presenting a category +Locale DuiLocalePrivate::getCategoryLocale(DuiLocale::Category category) const +{ + QString baseString = categoryName(category); + return DuiIcuConversions::createLocale(baseString, _calendar, _collation); +} +#endif + +// creates an QString for category or default as a fallback +QString DuiLocalePrivate::categoryName(DuiLocale::Category category) const +{ + switch (category) { + case(DuiLocale::DuiLcMessages): + if (!_messageLocale.isEmpty()) { + return _messageLocale; + } + break; + + case(DuiLocale::DuiLcNumeric): + if (!_numericLocale.isEmpty()) { + return _numericLocale; + } + break; + + case(DuiLocale::DuiLcCollate): + if (!_collationLocale.isEmpty()) { + return _collationLocale; + } + break; + + case(DuiLocale::DuiLcMonetary): + if (!_monetaryLocale.isEmpty()) { + return _monetaryLocale; + } + break; + + case(DuiLocale::DuiLcTime): + if (!_calendarLocale.isEmpty()) { + return _calendarLocale; + } + break; + + case(DuiLocale::DuiLcName): + if (!_nameLocale.isEmpty()) { + return _nameLocale; + } + break; + } + + return _defaultLocale; +} + + +// reloads translations +void DuiLocalePrivate::reloadCatalogList(CatalogList &cataloglist, + DuiLocale *duilocale, + DuiLocale::Category category) +{ + DuiLocalePrivate::CatalogList::iterator end = cataloglist.end(); + for (DuiLocalePrivate::CatalogList::iterator it = cataloglist.begin(); + it != end; ++it) { + // if the duitranslationcatalog is shared we need to make a new copy + (*it).detach(); + (*it)->loadWith(duilocale, category); + } +} + +// sets category to specific locale +void DuiLocalePrivate::setCategoryLocale(DuiLocale *duilocale, + DuiLocale::Category category, + const QString &localeName) +{ + if (category == DuiLocale::DuiLcMessages) { + _messageLocale = localeName; + + // detach message translations + reloadCatalogList(_messageTranslations, duilocale, DuiLocale::DuiLcMessages); + reloadCatalogList(_trTranslations, duilocale, DuiLocale::DuiLcMessages); + + + } else if (category == DuiLocale::DuiLcTime) { + _calendarLocale = localeName; + reloadCatalogList(_timeTranslations, duilocale, DuiLocale::DuiLcTime); + + + } else if (category == DuiLocale::DuiLcNumeric) { + _numericLocale = localeName; + +#ifdef HAVE_ICU + // recreate the number formatter + delete _numberFormat; + + UErrorCode status = U_ZERO_ERROR; + icu::Locale numericLocale = getCategoryLocale(DuiLocale::DuiLcNumeric); + _numberFormat = icu::NumberFormat::createInstance(numericLocale, status); + + if (!U_SUCCESS(status)) { + duiDebug("DuiLocalePrivate") << "Unable to create number format"; + _valid = false; + } +#endif + + } else if (category == DuiLocale::DuiLcCollate) { + _collationLocale = localeName; + + } else if (category == DuiLocale::DuiLcMonetary) { + _monetaryLocale = localeName; + + } else if (category == DuiLocale::DuiLcName) { + _nameLocale = localeName; + + } else { + //duiDebug("DuiLocalePrivate") << "unimplemented category change"; // DEBUG + } +} + + +QString DuiLocalePrivate::parseLanguage(const QString &localeString) +{ + int endOfLanguage = localeString.indexOf('_'); + + if (endOfLanguage > 0) { + return localeString.left(endOfLanguage); + } else { + return localeString; + } +} + + +QString DuiLocalePrivate::parseCountry(const QString &localeString) +{ + int startOfCountry = localeString.indexOf('_') + 1; + int endOfCountry = localeString.indexOf('_', startOfCountry); + + if (startOfCountry > 0) { + QString candidate = localeString.mid(startOfCountry, endOfCountry - startOfCountry); + if (candidate.size() == 4) { + startOfCountry = endOfCountry + 1; + endOfCountry = localeString.indexOf('_', startOfCountry); + if (startOfCountry > 0) { + return localeString.mid(startOfCountry, endOfCountry - startOfCountry); + } else { + return ""; + } + } else { + return candidate; + } + } else { + return ""; + } +} + +QString DuiLocalePrivate::parseScript(const QString &localeString) +{ + int startOfScript = localeString.indexOf('_') + 1; + int endOfScript = localeString.indexOf('_', startOfScript); + + if (startOfScript > 0) { + QString candidate = localeString.mid(startOfScript, endOfScript - startOfScript); + if (candidate.size() == 4) { + return candidate; + } else { + return ScriptLatin; + } + } else { + return ScriptLatin; + } +} + +QString DuiLocalePrivate::parseVariant(const QString &localeString) +{ + int startOfCountry = localeString.indexOf('_') + 1; + int startOfVariant = localeString.indexOf('_', startOfCountry) + 1; + + if (startOfVariant > 0) { + QString candidate = localeString.mid(startOfVariant); + int startOfVariant = candidate.indexOf('_') + 1; + + if (startOfVariant > 0) { + return candidate.mid(startOfVariant); + } else { + return candidate; + } + } else { + return ""; + } +} + +////////////////////////////////// +///// DuiLocale class implementation + + +// icu handles this string as synonym for posix locale behaviour +namespace +{ + const char *const PosixStr = "en_US_POSIX"; +} + +// Converts POSIX style locale code to Nokia (ICU) style without variant +// eg. snd_AF.UTF-8@Arab (POSIX) to snd_Arab_AF (Nokia) +// +// The syntax of the locale string in the POSIX environment variables +// related to locale is: +// +// [language[_territory][.codeset][@modifier]] +// +// (see: http://www.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap08.html) +// +// language is usually lower case in Linux but according to the above specification +// it may start with uppercase as well (i.e. LANG=Fr_FR is allowed). +// +static QString +cleanLanguageCountryPosix(QString &localeString) +{ + // we do not need the encoding and therefore use non-capturing + // parentheses for the encoding part here: + QRegExp regexp("([a-z]{2,3})(_([A-Z]{2,2}))?(?:.(?:[a-zA-Z0-9-]+))?(@([A-Z][a-z]+))?"); + + if (regexp.indexIn(localeString) == 0 && + regexp.capturedTexts().size() == 6) { // size of regexp pattern above + QStringList strings; + + strings << regexp.capturedTexts().at(1); // language + + // POSIX locale modifier, interpreted as script + if (!regexp.capturedTexts().at(5).isEmpty()) + strings << regexp.capturedTexts().at(5); + + if (!regexp.capturedTexts().at(3).isEmpty()) + strings << regexp.capturedTexts().at(3); // country + + // we don't need variant + return strings.join("_"); + } else { + //Malformed locale code + return QString(PosixStr); + } +} + +DuiLocale * +DuiLocale::createSystemDuiLocale() +{ +#ifdef HAVE_GCONF + DuiGConfItem languageItem(SettingsLanguage); + DuiGConfItem countryItem(SettingsCountry); + DuiGConfItem scriptItem(SettingsScript); + DuiGConfItem variantItem(SettingsVariant); + + QString language = languageItem.value().toString(); + QString country = countryItem.value().toString(); + QString script = scriptItem.value().toString(); + QString variant = variantItem.value().toString(); + + DuiLocale *systemLocale; + + if (language.isEmpty()) { + language = qgetenv("LANG"); + QString locale = cleanLanguageCountryPosix(language); + + if (locale.isEmpty()) + locale = PosixStr; + + // No need to set the category according to env here + systemLocale = new DuiLocale(locale); + } else { + systemLocale = new DuiLocale( + DuiLocalePrivate::createLocaleString(QString(language), + QString(country), + QString(script), + QString(variant))); + } + + return systemLocale; +#else + QString language = qgetenv("LANG"); + QString locale = cleanLanguageCountryPosix(language); + if (language.isEmpty()) + language = PosixStr; + + return new DuiLocale(locale); +#endif +} + + +//! creates a "C" locale +DuiLocale DuiLocale::createCLocale() +{ + return DuiLocale(PosixStr); +} + +void +DuiLocale::connectSettings() +{ +#ifdef HAVE_GCONF + Q_D(DuiLocale); + + QObject::connect(&d->currentLanguageItem, SIGNAL(valueChanged()), + this, SLOT(refreshSettings())); + + QObject::connect(&d->currentCountryItem, SIGNAL(valueChanged()), + this, SLOT(refreshSettings())); + + QObject::connect(&d->currentScriptItem, SIGNAL(valueChanged()), + this, SLOT(refreshSettings())); + + QObject::connect(&d->currentVariantItem, SIGNAL(valueChanged()), + this, SLOT(refreshSettings())); +#endif +} + +void +DuiLocale::disconnectSettings() +{ +#ifdef HAVE_GCONF + Q_D(DuiLocale); + + QObject::disconnect(&d->currentLanguageItem, SIGNAL(valueChanged()), + this, SLOT(refreshSettings())); + + QObject::disconnect(&d->currentCountryItem, SIGNAL(valueChanged()), + this, SLOT(refreshSettings())); + + QObject::disconnect(&d->currentScriptItem, SIGNAL(valueChanged()), + this, SLOT(refreshSettings())); + + QObject::disconnect(&d->currentVariantItem, SIGNAL(valueChanged()), + this, SLOT(refreshSettings())); +#endif +} + +///// Constructors ///// + +//! Constructs a DuiLocale with data copied from default Locale +DuiLocale::DuiLocale(QObject *parent) + : QObject(parent), + d_ptr(new DuiLocalePrivate) +{ + // copy the system default + DuiLocale &defaultLocale = getDefault(); + *this = defaultLocale; +} + +DuiLocale::DuiLocale(const QString &localeName, QObject *parent) + : QObject(parent), + d_ptr(new DuiLocalePrivate) +{ + Q_D(DuiLocale); + d->_defaultLocale = qPrintable(localeName); + +#ifdef HAVE_ICU + // we cache the number formatter for better performance + UErrorCode status = U_ZERO_ERROR; + d->_numberFormat = icu::NumberFormat::createInstance(d->getCategoryLocale(DuiLcNumeric), + status); + + if (!U_SUCCESS(status)) { + qWarning() << "NumberFormat creating failed:" << u_errorName(status); + d->_valid = false; + } +#endif +} + + +//! Copy constructor +DuiLocale::DuiLocale(const DuiLocale &other, QObject *parent) + : QObject(parent), + d_ptr(new DuiLocalePrivate(*other.d_ptr)) +{ + // nothing +} + + +//! Destructor +DuiLocale::~DuiLocale() +{ + // do not delete the d_ptr of s_systemDefault unless we are s_systemDefault + if (d_ptr) { + if (s_systemDefault == 0) { + delete d_ptr; + } else if (d_ptr != s_systemDefault->d_ptr) { + delete d_ptr; + } else if (this == s_systemDefault) { + delete d_ptr; + s_systemDefault = 0; + } + } +} + +//! Assignment operator +DuiLocale &DuiLocale::operator=(const DuiLocale &other) +{ + if (this == &other) { + return *this; + } + + *d_ptr = *other.d_ptr; + + return *this; +} + + + +/////////////////// +//// normal methods + +// mutex to guard default locale +static QMutex defaultLocaleMutex; + +// The static default locale +DuiLocale *DuiLocale::s_systemDefault = 0; + +void DuiLocale::setDefault(const DuiLocale &locale) +{ + defaultLocaleMutex.lock(); + + if (s_systemDefault == 0) { + s_systemDefault = new DuiLocale(locale); + } else if (&locale == s_systemDefault || locale.d_ptr == s_systemDefault->d_ptr) { + defaultLocaleMutex.unlock(); + return; + } else { + // remove the previous tr translations + s_systemDefault->removeTrFromQCoreApp(); + *s_systemDefault = locale; + } + // Setting the default QLocale here is needed to get localized number + // support in translations via %Ln, %L1, %L2, ...: + QLocale qlocale(locale.language() + '_' + locale.country()); + QLocale::setDefault(qlocale); + defaultLocaleMutex.unlock(); + + // tr translations have to be found from the qcoreapplication in order to + // make QCoreApplication::translate() work + s_systemDefault->insertTrToQCoreApp(); + + qApp->setLayoutDirection(s_systemDefault->textDirection()); +} + +DuiLocale &DuiLocale::getDefault() +{ + if (s_systemDefault == 0) { + // no default created, do it now + + // avoid race condition for multiple getDefaults() + defaultLocaleMutex.lock(); + + if (s_systemDefault == 0) { + // we won the race + s_systemDefault = createSystemDuiLocale(); + } + + defaultLocaleMutex.unlock(); + } + + return *s_systemDefault; +} + +bool DuiLocale::isValid() const +{ + Q_D(const DuiLocale); + return d->_valid; +} + +void DuiLocale::setCategoryLocale(Category category, const QString &localeName) +{ + Q_D(DuiLocale); + d->setCategoryLocale(this, category, localeName); +} + +void DuiLocale::setCollation(Collation collation) +{ + Q_D(DuiLocale); + d->_collation = collation; +} + +DuiLocale::Collation DuiLocale::collation() const +{ + Q_D(const DuiLocale); + return d->_collation; +} + +void DuiLocale::setCalendar(Calendar calendar) +{ + Q_D(DuiLocale); + d->_calendar = calendar; +} + + +DuiLocale::Calendar DuiLocale::calendar() const +{ + Q_D(const DuiLocale); + return d->_calendar; +} + +#ifdef HAVE_ICU +DuiCollator DuiLocale::collator() const +{ + return DuiCollator(*this); +} +#endif + +QString DuiLocale::language() const +{ + return DuiLocalePrivate::parseLanguage(name()); +} + +QString DuiLocale::country() const +{ + return DuiLocalePrivate::parseCountry(name()); +} + +//TODO This shall return an enum +QString DuiLocale::script() const +{ + return DuiLocalePrivate::parseScript(name()); +} + +QString DuiLocale::variant() const +{ + return DuiLocalePrivate::parseVariant(name()); +} + +QString DuiLocale::name() const +{ + Q_D(const DuiLocale); + return d->_defaultLocale; +} + +QString DuiLocale::categoryLanguage(Category category) const +{ + QString wholeName = categoryName(category); + return DuiLocalePrivate::parseLanguage(wholeName); +} + +QString DuiLocale::categoryCountry(Category category) const +{ + QString wholeName = categoryName(category); + return DuiLocalePrivate::parseCountry(wholeName); +} + +QString DuiLocale::categoryVariant(Category category) const +{ + QString wholeName = categoryName(category); + return DuiLocalePrivate::parseVariant(wholeName); +} + +QString DuiLocale::categoryName(Category category) const +{ + Q_D(const DuiLocale); + return d->categoryName(category); +} + +////////////////////////// +//// Formatting stuff //// + +QString DuiLocale::formatNumber(qlonglong i) const +{ +#ifdef HAVE_ICU + Q_D(const DuiLocale); + UnicodeString str; + // This might generate a warning by the Krazy code analyzer, + // but it allows the code to compile with ICU 4.0 + d->_numberFormat->format(static_cast(i), str); + return DuiIcuConversions::unicodeStringToQString(str); +#else + return QString::number(i); +#endif +} + + +QString DuiLocale::formatNumber(short i) const +{ +#ifdef HAVE_ICU + Q_D(const DuiLocale); + UnicodeString str; + d->_numberFormat->format(i, str); + return DuiIcuConversions::unicodeStringToQString(str); +#else + return QString::number(i); +#endif +} + + +QString DuiLocale::formatNumber(int i) const +{ +#ifdef HAVE_ICU + Q_D(const DuiLocale); + UnicodeString str; + d->_numberFormat->format(i, str); + return DuiIcuConversions::unicodeStringToQString(str); +#else + return QString::number(i); +#endif +} + +QString DuiLocale::formatNumber(double i, int prec) const +{ +#ifdef HAVE_ICU + Q_D(const DuiLocale); + icu::UnicodeString str; + icu::FieldPosition pos; + + if (prec == -1) { + d->_numberFormat->format(i, str, pos); + } else { + // the cached number formatter isn't sufficient + UErrorCode status = U_ZERO_ERROR; + icu::NumberFormat *nf; + + nf = icu::NumberFormat::createInstance(d->getCategoryLocale(DuiLcNumeric), + status); + + if (!U_SUCCESS(status)) { + qWarning() << "NumberFormat creating failed"; + return QString(); // "null" string + } + + nf->setMaximumFractionDigits(prec); + nf->format(i, str); + delete nf; + } + + return DuiIcuConversions::unicodeStringToQString(str); +#else + return QString::number(i, 'g', prec); +#endif +} + +QString DuiLocale::formatNumber(float i) const +{ +#ifdef HAVE_ICU + Q_D(const DuiLocale); + icu::UnicodeString str; + icu::FieldPosition pos; + d->_numberFormat->format(i, str, pos); + return DuiIcuConversions::unicodeStringToQString(str); +#else + return QString::number(i, 'g'); +#endif +} + +#ifdef HAVE_ICU +QString DuiLocale::formatPercent(double i, int decimals) const +{ + Q_D(const DuiLocale); + icu::UnicodeString str; + UErrorCode status = U_ZERO_ERROR; + icu::Locale numericLocale = d->getCategoryLocale(DuiLcNumeric); + icu::NumberFormat *nf = NumberFormat::createPercentInstance(numericLocale, status); + + if (!U_SUCCESS(status)) { + qWarning() << "NumberFormat creating failed"; + return QString(); + } + + nf->setMinimumFractionDigits(decimals); + nf->format(i, str); + delete nf; + + return DuiIcuConversions::unicodeStringToQString(str); +} +#endif + +#ifdef HAVE_ICU +QString DuiLocale::formatCurrency(double amount, const QString ¤cy) const +{ + Q_D(const DuiLocale); + UErrorCode status = U_ZERO_ERROR; + icu::Locale monetaryLocale = d->getCategoryLocale(DuiLcMonetary); + icu::NumberFormat *nf = icu::NumberFormat::createCurrencyInstance(monetaryLocale, status); + + if (!U_SUCCESS(status)) { + qWarning() << "NumberFormat creating failed"; + return QString(); + } + + icu::UnicodeString currencyString = DuiIcuConversions::qStringToUnicodeString(currency); + nf->setCurrency(currencyString.getTerminatedBuffer(), status); + + if (!U_SUCCESS(status)) { + qWarning() << "currency setting failed"; + delete nf; + return QString(); + } + + icu::UnicodeString str; + nf->format(amount, str); + delete nf; + + return DuiIcuConversions::unicodeStringToQString(str); +} +#endif + +#ifdef HAVE_ICU +QString DuiLocale::formatDateTime(const QDateTime &dateTime, DateType dateType, + TimeType timeType, Calendar calendarType) const +{ + DuiCalendar calendar(calendarType); + calendar.setDateTime(dateTime); + return formatDateTime(calendar, dateType, timeType); +} +#endif + +#ifdef HAVE_ICU +QString DuiLocale::formatDateTime(const DuiCalendar &duicalendar, + DateType datetype, TimeType timetype) const +{ + if (datetype == DateNone && timetype == TimeNone) + return QString(""); + + Q_D(const DuiLocale); + // Create calLocale which has the time pattern we want to use + icu::Locale calLocale = DuiIcuConversions::createLocale(d->categoryName(DuiLcTime), + duicalendar.type()); + + icu::DateFormat::EStyle dateStyle = DuiIcuConversions::toEStyle(datetype); + icu::DateFormat::EStyle timeStyle = DuiIcuConversions::toEStyle(timetype); + icu::DateFormat *df + = icu::DateFormat::createDateTimeInstance(dateStyle, timeStyle, calLocale); + + // Symbols come from the messages locale + icu::Locale symbolLocale + = DuiIcuConversions::createLocale(d->categoryName(DuiLcMessages), + duicalendar.type()); + + DateFormatSymbols *dfs = DuiLocalePrivate::createDateFormatSymbols(symbolLocale); + + // This is not nice but seems to be the only way to set the + // symbols with the public API + static_cast(df)->adoptDateFormatSymbols(dfs); + + icu::FieldPosition pos; + icu::UnicodeString resString; + icu::Calendar *cal = duicalendar.d_ptr->_calendar; + df->format(*cal, resString, pos); + delete df; + + return DuiIcuConversions::unicodeStringToQString(resString); +} +#endif + +#ifdef HAVE_ICU +QString DuiLocale::formatDateTime(const QDateTime &dateTime, Calendar calendarType) const +{ + return formatDateTime(dateTime, DateLong, TimeLong, calendarType); +} +#endif + +#ifdef HAVE_ICU +QString DuiLocale::formatDateTime(const QDateTime &dateTime, + const QString &formatString) const +{ + // convert QDateTime to DuiCalendar and format + DuiCalendar calendar(*this); + calendar.setDateTime(dateTime); + return formatDateTime(calendar, formatString); +} +#endif + +#ifdef HAVE_ICU +//! creates a string presentation for a QDateTime with specific format string +//! \param dateTime QDateTime to format +//! \param formatString in ICU SimpleDateFormat format +//! \note THIS MAY BE REMOVED FROM PUBLIC API +QString DuiLocale::formatDateTimeICU(const QDateTime &dateTime, + const QString &formatString) const +{ + // convert QDateTime to DuiCalendar and format + DuiCalendar calendar(*this); + calendar.setDateTime(dateTime); + return formatDateTimeICU(calendar, formatString); +} +#endif + +#ifdef HAVE_ICU +//! Formats the date time with ICU pattern +//! \note THIS MAY BE REMOVED FROM PUBLIC API +QString DuiLocale::formatDateTimeICU(const DuiCalendar &duiCalendar, + const QString &formatString) const +{ + Q_D(const DuiLocale); + // Note: using MESSAGES locale here to get symbols in right language + UErrorCode status = U_ZERO_ERROR; + icu::SimpleDateFormat formatter(DuiIcuConversions::qStringToUnicodeString(formatString), + d->getCategoryLocale(DuiLcMessages), status); + + if (U_FAILURE(status)) { + return QString(); + } + + icu::FieldPosition pos; + icu::UnicodeString resString; + + formatter.format(*duiCalendar.d_ptr->_calendar, resString, pos); + + return DuiIcuConversions::unicodeStringToQString(resString); +} +#endif + +#ifdef HAVE_ICU +// return weeknumber based on first week starting from the first given weekday of the year +// i.e. using sunday week 1 is the first week that contains sunday, zero before it +// note: week also starts from given weekday +// TODO: should this be moved to DuiCalendar? +static int weekNumberStartingFromDay(const DuiCalendar &calendar, int weekday) +{ + DuiCalendar calendarCopy = calendar; + calendarCopy.setFirstDayOfWeek(weekday); + calendarCopy.setMinimalDaysInFirstWeek(1); + // this is icu week number, starts from 1 + int weeknumber = calendarCopy.weekNumber(); + + // check if there's week 0 + bool weekZero = true; + int year = calendarCopy.year(); + calendarCopy.setDate(year, 1, 1); // reuse the copy + + // a bit crude. check if the first week includes sunday + // note: should start always from week 1 because minimal days is 1. + while (calendarCopy.weekOfYear() == 1) { + if (calendarCopy.dayOfWeek() == weekday) { + weekZero = false; + } + + calendarCopy.addDays(1); + } + + if (weekZero == true) { + weeknumber--; + } + + return weeknumber; +} +#endif + +#ifdef HAVE_ICU +QString DuiLocale::formatDateTime(const DuiCalendar &duiCalendar, + const QString &formatString) const +{ + Q_D(const DuiLocale); + // convert POSIX format string into ICU format + + QString icuFormat; + + bool isInNormalText = false; // a-zA-Z should be between <'>-quotations + + const int length = formatString.length(); + for (int i = 0; i < length; ++i) { + + QChar current = formatString.at(i); + + if (current == '%') { + i++; + QChar next = formatString.at(i); + + // end plain text icu quotation + if (isInNormalText == true) { + icuFormat.append('\''); + isInNormalText = false; + } + + switch (next.unicode()) { + + case 'a': + // abbreviated weekday name + icuFormat.append("EEE"); + break; + + case 'A': + // full weekday name + icuFormat.append("EEEE"); + break; + + case 'b': + case 'h': + // abbreviated month name + icuFormat.append("MMM"); + break; + + case 'B': + // full month name + icuFormat.append("MMMM"); + break; + + case 'c': { + // FDCC-set's appropriate date and time representation + + // This is ugly but possibly the only way to get the appropriate presentation + icu::Locale msgLocale = d->getCategoryLocale(DuiLcMessages); + DateFormat *df + = icu::DateFormat::createDateTimeInstance(icu::DateFormat::kDefault, + icu::DateFormat::kDefault, + msgLocale); + icu::UnicodeString dateTime; + icu::FieldPosition fieldPos; + dateTime = df->format(*duiCalendar.d_ptr->_calendar, dateTime, fieldPos); + icuFormat.append('\''); + QString pattern = DuiIcuConversions::unicodeStringToQString(dateTime); + icuFormat.append(DuiIcuConversions::escapeIcuDatePattern(pattern)); + icuFormat.append('\''); + delete df; + break; + } + + case 'C': { + // century, no corresponding icu pattern + int century = duiCalendar.year() / 100; + icuFormat.append(QString::number(century)); + break; + } + + case 'd': + // Day of the month as a decimal number (01-31) + icuFormat.append("dd"); + break; + + case 'D': + // %D Date in the format mm/dd/yy. + icuFormat.append("MM/dd/yy"); // yy really shortened? + break; + + case 'e': + // correct? there should be explicit space fill or something? + icuFormat.append("d"); + break; + + case 'F': + //The date in the format YYYY-MM-DD (An ISO 8601 format). + icuFormat.append("yyyy-MM-dd"); + break; + + case 'g': + icuFormat.append("YY"); + break; + + case 'G': + icuFormat.append("YYYY"); + break; + + case 'H': + // 24 hour clock + icuFormat.append("kk"); + break; + + case 'I': + // 12 hour clock + icuFormat.append("KK"); + break; + + case 'j': + // day of year + icuFormat.append("DDD"); + break; + + case 'm': + // month + icuFormat.append("MM"); + break; + + case 'M': + // minute + icuFormat.append("mm"); + break; + + case 'n': + // newline + icuFormat.append('\n'); + break; + + case 'p': + // AM/PM + icuFormat.append("aaa"); + break; + + case 'r': + // 12 hour clock with am/pm + icuFormat.append("KK aaa"); // correct? + break; + + case 'R': + // 24-hour clock time, in the format "%H:%M" + icuFormat.append("kk:mm"); + break; + + case 'S': + // seconds + icuFormat.append("ss"); + break; + + case 't': + // tab + icuFormat.append('\t'); + break; + + case 'T': + // 24 hour clock HH:MM:SS + icuFormat.append("kk:mm:ss"); + break; + + case 'u': + // Weekday, as a decimal number (1(Monday)-7) + // no corresponding icu pattern for monday based weekday + icuFormat.append(QString::number(duiCalendar.dayOfWeek())); + break; + + case 'U': { + // Week number of the year (Sunday as the first day of the week) as a + // decimal number (00-53). first week starts from first sunday. + int weeknumber = weekNumberStartingFromDay(duiCalendar, DuiLocale::Sunday); + icuFormat.append(QString::number(weeknumber)); + break; + } + + case 'v': + // week number of the year in two digits + icuFormat.append("ww"); + break; + + case 'V': { + // Week of the year (Monday as the first day of the week), as a decimal + // number (01-53). according to ISO-8601 + + DuiCalendar calendarCopy = duiCalendar; + calendarCopy.setFirstDayOfWeek(DuiLocale::Monday); + calendarCopy.setMinimalDaysInFirstWeek(4); + int weeknumber = calendarCopy.weekNumber(); + icuFormat.append(QString::number(weeknumber)); + break; + } + + case 'w': { + // Weekday, as a decimal number (0(Sunday)-6) + int weekday = duiCalendar.dayOfWeek(); + + if (weekday == Sunday) { + weekday = 0; + } + + icuFormat.append(QString::number(weekday)); + break; + } + + case 'W': { + // Week number of the year (Monday as the first day of the week), as a + // decimal number (00-53). Week starts from the first monday + int weeknumber = weekNumberStartingFromDay(duiCalendar, DuiLocale::Monday); + icuFormat.append(QString::number(weeknumber)); + break; + } + + case 'x': { + // appropriate date representation + icu::Locale msgLocale = d->getCategoryLocale(DuiLcMessages); + DateFormat *df + = icu::DateFormat::createDateInstance(icu::DateFormat::kDefault, + msgLocale); + icu::UnicodeString dateTime; + icu::FieldPosition fieldPos; + dateTime = df->format(*duiCalendar.d_ptr->_calendar, dateTime, fieldPos); + icuFormat.append('\''); + QString pattern = DuiIcuConversions::unicodeStringToQString(dateTime); + icuFormat.append(DuiIcuConversions::escapeIcuDatePattern(pattern)); + icuFormat.append('\''); + delete df; + break; + } + + case 'X': { + // appropriate time representation + icu::Locale msgLocale = d->getCategoryLocale(DuiLcMessages); + DateFormat *df + = icu::DateFormat::createTimeInstance(icu::DateFormat::kDefault, + msgLocale); + icu::UnicodeString dateTime; + icu::FieldPosition fieldPos; + dateTime = df->format(*duiCalendar.d_ptr->_calendar, dateTime, fieldPos); + icuFormat.append('\''); + QString pattern = DuiIcuConversions::unicodeStringToQString(dateTime); + icuFormat.append(DuiIcuConversions::escapeIcuDatePattern(pattern)); + icuFormat.append('\''); + delete df; + break; + } + + case 'y': + // year within century + icuFormat.append("yy"); + break; + + case 'Y': + // year with century + icuFormat.append("yyyy"); + break; + + case 'z': + // The offset from UTC in the ISO 8601 format "-0430" (meaning 4 hours + // 30 minutes behind UTC, west of Greenwich), or by no characters if no + // time zone is determinable + icuFormat.append("Z"); // correct? + break; + + case 'Z': + // ISO-14652 (draft): + // Time-zone name, or no characters if no time zone is determinable + // Linux date command, strftime (glibc): + // alphabetic time zone abbreviation (e.g., EDT) + // note that the ISO-14652 draft does not mention abbreviation, + // i.e. it is a bit unclear how exactly this should look like. + icuFormat.append("vvvv"); // generic time zone info + break; + + case '%': + icuFormat.append("%"); + break; + } + + } else { + if (current == '\'') { + icuFormat.append("''"); // icu escape + + } else if ((current >= 'a' && current <= 'z') || (current >= 'A' && current <= 'Z')) { + if (isInNormalText == false) { + icuFormat.append('\''); + isInNormalText = true; + } + + icuFormat.append(current); + + } else { + icuFormat.append(current); + } + } + } + + return formatDateTimeICU(duiCalendar, icuFormat); +} +#endif + +#ifdef HAVE_ICU +QString DuiLocale::monthName(const DuiCalendar &duiCalendar, int monthNumber) const +{ + Q_D(const DuiLocale); + monthNumber--; // months in array starting from index zero + + // use message locale as the output language + icu::Locale symbolLocale + = DuiIcuConversions::createLocale(d->categoryName(DuiLcMessages), + duiCalendar.type()); + + icu::DateFormatSymbols *dfs = DuiLocalePrivate::createDateFormatSymbols(symbolLocale); + + int len; + const UnicodeString *months = dfs->getMonths(len); + + QString result; + + if (monthNumber < len && monthNumber >= 0) { + result = DuiIcuConversions::unicodeStringToQString(months[monthNumber]); + } + + delete dfs; + + return result; +} +#endif + +#ifdef HAVE_ICU +QString DuiLocale::monthName(const DuiCalendar &duiCalendar, int monthNumber, + DateSymbolContext context, + DateSymbolLength symbolLength) const +{ + Q_D(const DuiLocale); + + monthNumber--; // months in array starting from index zero + + icu::Locale symbolLocale + = DuiIcuConversions::createLocale(d->categoryName(DuiLcMessages), + duiCalendar.type()); + + icu::DateFormatSymbols *dfs = DuiLocalePrivate::createDateFormatSymbols(symbolLocale); + + // map context type + icu::DateFormatSymbols::DtContextType icuContext = + DuiIcuConversions::duiDateContextToIcu(context); + + // map length type + icu::DateFormatSymbols::DtWidthType icuWidth = + DuiIcuConversions::duiDateWidthToIcu(symbolLength); + + int len; + const UnicodeString *months = dfs->getMonths(len, icuContext, icuWidth); + + QString result; + + if (monthNumber < len && monthNumber >= 0) { + result = DuiIcuConversions::unicodeStringToQString(months[monthNumber]); + } + + delete dfs; + + return result; +} +#endif + +#ifdef HAVE_ICU +QString DuiLocale::weekdayName(const DuiCalendar &duiCalendar, int weekday) const +{ + Q_D(const DuiLocale); + // use message locale as the output language + icu::Locale symbolLocale + = DuiIcuConversions::createLocale(d->categoryName(DuiLcMessages), + duiCalendar.type()); + + icu::DateFormatSymbols *dfs = DuiLocalePrivate::createDateFormatSymbols(symbolLocale); + + int len; + const UnicodeString *weekdayNames = dfs->getWeekdays(len); + int weekdayNum = DuiIcuConversions::icuWeekday(weekday); + + QString result; + + if (weekdayNum < len && weekdayNum > 0) { + result = DuiIcuConversions::unicodeStringToQString(weekdayNames[weekdayNum]); + } + + delete dfs; + + return result; +} +#endif + +#ifdef HAVE_ICU +QString DuiLocale::weekdayName(const DuiCalendar &duiCalendar, int weekday, + DateSymbolContext context, + DateSymbolLength symbolLength) const +{ + Q_D(const DuiLocale); + icu::Locale symbolLocale + = DuiIcuConversions::createLocale(d->categoryName(DuiLcMessages), + duiCalendar.type()); + + icu::DateFormatSymbols *dfs = DuiLocalePrivate::createDateFormatSymbols(symbolLocale); + + icu::DateFormatSymbols::DtContextType icuContext + = DuiIcuConversions::duiDateContextToIcu(context); + + icu::DateFormatSymbols::DtWidthType icuWidth + = DuiIcuConversions::duiDateWidthToIcu(symbolLength); + + int len; + const UnicodeString *weekdayNames = dfs->getWeekdays(len, icuContext, icuWidth); + int weekdayNum = DuiIcuConversions::icuWeekday(weekday); + + QString result; + + if (weekdayNum < len && weekdayNum > 0) { + result = DuiIcuConversions::unicodeStringToQString(weekdayNames[weekdayNum]); + } + + delete dfs; + + return result; +} +#endif + +#ifdef HAVE_ICU +namespace +{ +// fetches a resource bundle for name formats + UResourceBundle *nameFmtsResourceBundle() + { + UErrorCode status = U_ZERO_ERROR; + + UResourceBundle *extraData = ures_openDirect(ExtraDataBundleName, "", &status); + + if (U_FAILURE(status)) { + duiDebug("duilocale.cpp") << "Error ures_open" << u_errorName(status); + } + + UResourceBundle *posixData = ures_getByKey(extraData, "posixdata", NULL, &status); + + if (U_FAILURE(status)) { + duiDebug("duilocale.cpp") << "Error ures_open posixData" << u_errorName(status); + } + + UResourceBundle *nameFmts = ures_getByKey(posixData, "nameFmts", NULL, &status); + if (U_FAILURE(status)) { + duiDebug("duilocale.cpp") << "Error ures_open nameFmts" << u_errorName(status); + } + + ures_close(extraData); + ures_close(posixData); + + return nameFmts; + } +} +#endif + +#ifdef HAVE_ICU +QString DuiLocale::languageEndonym() const +{ + Q_D(const DuiLocale); + UErrorCode status = U_ZERO_ERROR; + + UResourceBundle *res = ures_open(NULL, qPrintable(d->_defaultLocale), &status); + if (U_FAILURE(status)) { + duiDebug("DuiLocale") << "Error ures_open" << u_errorName(status); + } + + res = ures_getByKey(res, Languages, res, &status); + if (U_FAILURE(status)) { + duiDebug("DuiLocale") << "Error ures_getByKey" << u_errorName(status); + } + + QString lang = language(); + + int len; + const UChar *val = ures_getStringByKey(res, qPrintable(lang), &len, &status); + + QString convertedValue = lang; + + if (U_SUCCESS(status)) { + convertedValue = QString::fromUtf16(val, len); + } + + ures_close(res); + return convertedValue; +} +#endif + +#ifdef HAVE_ICU +QString DuiLocale::countryEndonym() const +{ + Q_D(const DuiLocale); + UErrorCode status = U_ZERO_ERROR; + + UResourceBundle *res = ures_open(NULL, qPrintable(d->_defaultLocale), &status); + if (U_FAILURE(status)) { + duiDebug("DuiLocale") << "Error ures_open" << u_errorName(status); + } + + res = ures_getByKey(res, Countries, res, &status); + if (U_FAILURE(status)) { + duiDebug("DuiLocale") << "Error ures_getByKey" << u_errorName(status); + } + + QString c = country(); + + int len; + const UChar *val = ures_getStringByKey(res, c.toStdString().c_str(), &len, &status); + + QString convertedValue = c; + + if (U_SUCCESS(status)) { + convertedValue = QString::fromUtf16(val, len); + } + + ures_close(res); + return convertedValue; +} +#endif + +void DuiLocale::installCategoryCatalog(Category category, const QString &name) +{ + Q_D(DuiLocale); + + if (category != DuiLcMessages && category != DuiLcTime) { + duiDebug("DuiLocale") << __PRETTY_FUNCTION__ << ": unknown category"; + return; + } + + // don't load the catalog if it has been loaded already. + // + // The following function cannot be called because it is marked as + // deprecated, therefore, I copy the code from + // hasCategoryCatalog() here: + // + // if(hasCategoryCatalog(category, name)) { + // return; + //} + bool hasCategoryCatalog = false; + if (category != DuiLcMessages && category != DuiLcTime) { + hasCategoryCatalog = false; + } else { + DuiLocalePrivate::CatalogList *catList; + + if (category == DuiLcMessages) { + catList = &d->_messageTranslations; + } else { + catList = &d->_timeTranslations; + } + + // find the DuiTranslationCatalog + for (DuiLocalePrivate::CatalogList::iterator i = catList->begin(); + i != catList->end(); ++i) { + if (name == (*i)->_name) { + hasCategoryCatalog = true; + } + } + } + if (hasCategoryCatalog) + return; + + DuiTranslationCatalog *catalog = new DuiTranslationCatalog(name); + catalog->loadWith(this, category); + + if (category == DuiLcMessages) { + d->_messageTranslations.append(QExplicitlySharedDataPointer(catalog)); + } else { + d->_timeTranslations.append(QExplicitlySharedDataPointer(catalog)); + } +} + +bool DuiLocale::hasCategoryCatalog(Category category, const QString &name) +{ + Q_D(DuiLocale); + + if (category != DuiLcMessages && category != DuiLcTime) { + return false; + } + + DuiLocalePrivate::CatalogList *catList; + + if (category == DuiLcMessages) { + catList = &d->_messageTranslations; + } else { + catList = &d->_timeTranslations; + } + + // find the DuiTranslationCatalog + for (DuiLocalePrivate::CatalogList::iterator i = catList->begin(); + i != catList->end(); ++i) { + if (name == (*i)->_name) { + return true; + } + } + + return false; +} + +void DuiLocale::removeCategoryCatalog(Category category, const QString &name) +{ + Q_D(DuiLocale); + if (category != DuiLcMessages && category != DuiLcTime) { + return; + } + + DuiLocalePrivate::CatalogList *catList; + + if (category == DuiLcMessages) { + catList = &d->_messageTranslations; + } else { + catList = &d->_timeTranslations; + } + + // find, delete and remove the DuiTranslationCatalog + for (DuiLocalePrivate::CatalogList::iterator i = catList->begin(); + i != catList->end(); ++i) { + if (name == (*i)->_name) { + // erasing should delete the duitranslationcatalog if necessary + catList->erase(i); + } + } +} + +void DuiLocale::copyCatalogsFrom(const DuiLocale &other) +{ + Q_D(DuiLocale); + + DuiLocalePrivate::CatalogList::const_iterator end = + other.d_ptr->_messageTranslations.constEnd(); + + for (DuiLocalePrivate::CatalogList::const_iterator i + = other.d_ptr->_messageTranslations.constBegin(); + i != end; ++i) { + + // copy the name info + DuiTranslationCatalog *tempCatalog = new DuiTranslationCatalog(**i); + + // reload the file + tempCatalog->loadWith(this, DuiLcMessages); + d->_messageTranslations.append(QExplicitlySharedDataPointer(tempCatalog)); + + } + + end = other.d_ptr->_timeTranslations.constEnd(); + for (DuiLocalePrivate::CatalogList::const_iterator i = other.d_ptr->_timeTranslations.constBegin(); + i != end; ++i) { + + DuiTranslationCatalog *tempCatalog = new DuiTranslationCatalog(**i); + tempCatalog->loadWith(this, DuiLcTime); + d->_timeTranslations.append(QExplicitlySharedDataPointer(tempCatalog)); + } + + end = other.d_ptr->_trTranslations.constEnd(); + for (DuiLocalePrivate::CatalogList::const_iterator i = other.d_ptr->_trTranslations.constBegin(); + i != end; ++i) { + + DuiTranslationCatalog *tempCatalog = new DuiTranslationCatalog(**i); + tempCatalog->loadWith(this, DuiLcMessages); + d->_trTranslations.append(QExplicitlySharedDataPointer(tempCatalog)); + + } + +} + +void DuiLocale::installTrCatalog(const QString &name) +{ + Q_D(DuiLocale); + DuiTranslationCatalog *catalog = new DuiTranslationCatalog(name); + catalog->loadWith(this, DuiLcMessages); + d->_trTranslations.append(QExplicitlySharedDataPointer(catalog)); +} + +void DuiLocale::insertTrToQCoreApp() +{ + Q_D(DuiLocale); + + foreach(const QExplicitlySharedDataPointer& sharedCatalog, d->_trTranslations) { + QCoreApplication::installTranslator(&sharedCatalog->_translator); + } + + // QCoreApplication does not send the QEvent::LanguageChange to + // the widgets, so we send the language change event here. + QEvent ev(QEvent::LanguageChange); + qApp->sendEvent(qApp, &ev); +} + +void DuiLocale::removeTrFromQCoreApp() +{ + Q_D(DuiLocale); + + foreach(const QExplicitlySharedDataPointer& sharedCatalog, d->_trTranslations) { + QCoreApplication::removeTranslator(&sharedCatalog->_translator); + } +} + +///////////////////////////// +//// translation methods //// + +QString DuiLocale::translate(const char *context, const char *sourceText, + const char *comment, int n) +{ + Q_D(DuiLocale); + const DuiLocalePrivate::CatalogList::const_iterator begin = d->_trTranslations.constBegin(); + DuiLocalePrivate::CatalogList::const_iterator it = d->_trTranslations.constEnd(); + while (it != begin) { + --it; + + QString translation = (*it)->_translator.translate(context, sourceText, + comment, n); + + if (translation.isEmpty() == false) { + replacePercentN(&translation, n); + return translation; + } + } + + return sourceText; +} + +void DuiLocale::setDataPaths(const QStringList &dataPaths) +{ +#ifdef HAVE_ICU + QString pathString; + + foreach(QString string, dataPaths) { + string.replace('/', U_FILE_SEP_CHAR); + pathString.append(string); + // separator gets appended to the end of the list. I hope Icu doesn't mind + pathString.append(U_PATH_SEP_CHAR); + } + + u_setDataDirectory(qPrintable(pathString)); +#else + Q_UNUSED(dataPaths); +#endif +} + +// convenience method for just one path +void DuiLocale::setDataPath(const QString &dataPath) +{ + setDataPaths(QStringList(dataPath)); +} + +/////// +// the static convenience methods for translation + +void DuiLocale::setTranslationPaths(const QStringList &paths) +{ + DuiLocalePrivate::translationPaths = paths; +} + +void DuiLocale::addTranslationPath(const QString &path) +{ + if (DuiLocalePrivate::translationPaths.contains(path) == false) { + DuiLocalePrivate::translationPaths << path; + } +} + +void DuiLocale::removeTranslationPath(const QString &path) +{ + DuiLocalePrivate::translationPaths.removeOne(path); +} + +QStringList DuiLocale::translationPaths() +{ + return DuiLocalePrivate::translationPaths; +} + +Qt::LayoutDirection DuiLocale::textDirection() const +{ + Qt::LayoutDirection dir = Qt::LeftToRight; + + // Checking for the script "arab" is needed for + // locales where the language can be written in several scripts. + // Eg the Uyghur language can be written in Chinese, Cyrillic, + // or Arabic script. + if (script().contains("arab", Qt::CaseInsensitive)) + dir = Qt::RightToLeft; + else if (!language().isEmpty() + && RtlLanguages.contains(language() + ':')) + dir = Qt::RightToLeft; + + return dir; +} + +void DuiLocale::refreshSettings() +{ +#ifdef HAVE_GCONF + Q_D(DuiLocale); + + QString language = d->currentLanguageItem.value().toString(); + QString country = d->currentCountryItem.value().toString(); + QString script = d->currentScriptItem.value().toString(); + QString variant = d->currentVariantItem.value().toString(); + QString localeName = d->createLocaleString(language, country, script, variant); + + d->_defaultLocale = localeName; + setCategoryLocale(DuiLcMessages, localeName); + setCategoryLocale(DuiLcTime, localeName); + setCategoryLocale(DuiLcNumeric, localeName); + setCategoryLocale(DuiLcCollate, localeName); + setCategoryLocale(DuiLcMonetary, localeName); + setCategoryLocale(DuiLcName, localeName); + + emit settingsChanged(); +#endif +} + diff --git a/src/i18n/duilocale.h b/src/i18n/duilocale.h new file mode 100644 index 000000000..bbb592a29 --- /dev/null +++ b/src/i18n/duilocale.h @@ -0,0 +1,692 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUILOCALE_H +#define DUILOCALE_H + +#include "duiexport.h" + +#include +#include + +class QString; +class QStringList; +class QDateTime; + +class DuiCollator; +class DuiAbstractName; +class DuiCalendar; +class DuiBreakIteratorPrivate; + +class DuiLocalePrivate; + +/*! + * \class DuiLocale + * + * \brief DuiLocale is a class that implements locale dependent data formatting as well as translation, collation and calendar systems. + * + * For more general information about Internationalization in libdui + * see also the Internationalization Guidelines + * + * The locale system in Direct UI is separated into different + * categories. These correspond roughly with the LC_* environment + * variables of POSIX. DuiLocale is created with one main + * language/country information for it, but can be overridden with + * category specific settings. E.g. having messages in + * english/u.s. but using finnish collation (DuiLcCollation category) + * and number formatting (DuiLcNumeric). + * + * The calendar system in Direct UI supports a number of non-Gregorian + * calendar systems. The calendar is used to create presentations of + * date and time. + * + * The collation system in Direct UI supports a number of collation + * systems. The actual collation is done with the DuiCollator class. + * + * The translation system in Direct UI differs a bit from the usual + * practice used in any other translation system (e.g, Qt's tr() or + * GNU's gettext). In Direct UI, a developer uses both logical names + * and Engineering English to translate a string. The logical names are + * useful when you have to maintain tens of thousands strings in your + * translation file sets. Whenever no translation is available, the + * Engineering English version, which is auto-generated from the source code, + * is displayed instead of the logical names to make testing easier. + * The displayed Engineering English is prefixed with "!! " to make it + * obvious that no translation was found and a proper translation still + * needs to be added. Internally, the Direct UI translation system + * uses the Qt translation system (using the QTranslator class). The + * translation source file is in .ts format version 3.0. Usually the + * translation source file is not generated from code, but rather + * generated by some other means (e.g from the UI specification). + * + * If DuiLocale is instantiated without any parameters, it will create + * the locale based on the settings in the global settings. If the + * settings are not available it creates the locale based on the LANG + * environment variable. If one wants to react when the settings are + * changed, one can connect to the settingsChanged() signal and call + * the connectSettings() method. + * + * \note The methods are not thread-safe. For number/string formatting etc. the class is re-entrant. If one needs to have formatting in multiple threads it is suggested to create separate locales. + * + * Examples: + * + * \verbatim + * DuiLocale locale("en_US"); + * // format a number to a string using US English conventions: + * QString numberString = locale.formatNumber(123456789); + * \endverbatim + * + * Install a translation catalog for Finnish, make Finnish the defautl + * and translate a message to Finnish: + * + * \verbatim + * DuiLocale locale("fi"); + * // install a translation catalog: + * locale.installTrCatalog("catalogname"); + * // make the locale with this translation catalog the default: + * DuiLocale::setDefault(locale); + * + * //% "Hello" + * QString translatedString = qtTrId("hello_msg"); + * DuiLocale defaultLocale; // English settings are copied + * \endverbatim + */ + + +class DUI_EXPORT DuiLocale : public QObject +{ + Q_OBJECT +public: + + /*! + * \brief enum for Date formatting. + * + * This correlates closely with the + * date type in ICU and Unicode CLDR + */ + enum DateType { + DateNone, + DateShort, + DateMedium, + DateLong, + DateFull + }; + + /*! + * \brief enum for Time formatting. + * + * This correlates closely with the + * time type in ICU and Unicode CLDR + */ + enum TimeType { + TimeNone, + TimeShort, + TimeMedium, + TimeLong, + TimeFull + }; + + // NOTE: could add LC_CTYPE, LC_PAPER, LC_ADDRESS, LC_TELEPHONE, + // LC_MEASUREMENT, LC_IDENTIFICATION? + + //! Category type for the locale + enum Category {DuiLcMessages, DuiLcTime, DuiLcCollate, + DuiLcNumeric, DuiLcMonetary, DuiLcName + }; + + //! Set of possible collations + enum Collation {DefaultCollation, PhonebookCollation, PinyinCollation, + TraditionalCollation, StrokeCollation, DirectCollation, + PosixCollation, Big5hanCollation, Gb2312hanCollation + }; + + //! Calendar type. + enum Calendar {DefaultCalendar, GregorianCalendar, IslamicCalendar, + ChineseCalendar, IslamicCivilCalendar, HebrewCalendar, + JapaneseCalendar, BuddhistCalendar, PersianCalendar, + CopticCalendar, EthiopicCalendar + }; + + enum Weekday {Monday = 1, Tuesday, Wednesday, Thursday, Friday, + Saturday, Sunday + }; + + + //! Return type for DuiCollator::compare(). Denotes the order of two strings. + enum Comparison {LessThan = -1, Equal = 0, GreaterThan = 1}; + + + //! Type for locale dependant date symbol presentation + enum DateSymbolContext {DateSymbolFormat, DateSymbolStandalone}; + + //! Length type for date symbol presentation + enum DateSymbolLength {DateSymbolAbbreviated, DateSymbolWide, DateSymbolNarrow}; + + + + static DuiLocale *createSystemDuiLocale(); + static DuiLocale createCLocale(); + + DuiLocale(QObject *parent = 0); + + /*! + * Constructs a DuiLocale from a ICU format locale ID string + * \param localeName ICU format locale ID string. + * \param parent the Object’s parent + * + * For details about ICU format locale ID strings + * see http://userguide.icu-project.org/locale . + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ + explicit DuiLocale(const QString &localeName, QObject *parent = 0); + DuiLocale(const DuiLocale &other, QObject *parent = 0); + + virtual ~DuiLocale(); + + DuiLocale &operator=(const DuiLocale &other); + + + /*! + * \brief Sets the default locale. + */ + static void setDefault(const DuiLocale &locale); + + /*! + * \brief Returns true if DuiLocale is valid and can be used + */ + bool isValid() const; + + /*! + * \brief Sets category with specified locale string + * \param localeName ICU format locale ID string. + */ + void setCategoryLocale(Category category, const QString &localeName); + + /*! + * \brief Sets the collation mode + */ + void setCollation(Collation collation); + + /*! + * \brief Returns the collation mode + */ + Collation collation() const; + + /*! + * \brief Sets calendar + */ + void setCalendar(Calendar calendar); + + /*! + * \brief Returns calendar + */ + Calendar calendar() const; + + /*! + * \brief Returns a DuiCollator which compares QStrings based on language/country/collation rules + */ + DuiCollator collator() const; + + /*! + * \brief Returns the endonym of the language of the locale, which is the name of the language which is used by the native speaker of this language. + */ + QString languageEndonym() const; + + /*! + * \brief Returns the endonym of the country of the locale, which is the name of the country which is used by the inhabitant of the country. + */ + QString countryEndonym() const; + + /*! + * \brief Returns the language code of the locale in ISO-639 format + */ + QString language() const; + + /*! + * \brief Returns the country code of the locale in ISO-3166 format + */ + QString country() const; + + /*! + * \brief Returns the script code of the locale in ISO-15924 format + */ + QString script() const; + + /*! + * \brief Returns the variant appended to the locale + */ + QString variant() const; + + /*! + * \brief Returns the string representation of the locale + */ + QString name() const; + + /*! + * \brief Returns the text direction of the locale + */ + Qt::LayoutDirection textDirection() const; + + /*! + * \brief Returns the language code of the category in ISO-639 format + */ + QString categoryLanguage(Category category) const; + + /*! + * \brief Returns the country code of the category in ISO-3166 format + */ + QString categoryCountry(Category category) const; + + /*! + * \brief Returns the variant code appended to the category + */ + QString categoryVariant(Category category) const; + + /*! + * \brief Returns the string representation of the category + */ + QString categoryName(Category category) const; + + //////////////////////////////////////// + ///// number formatting methods: ///// + + /*! + * \brief Returns the string representation of a number + * \param i number to format + */ + QString formatNumber(qlonglong i) const; + + /*! + * \brief Returns the string representation of a number + * \param i number to format + */ + QString formatNumber(short i) const; + + /*! + * \brief Returns the string representation of a number + * \param i number to format + */ + QString formatNumber(int i) const; + + /*! + * \brief Returns the string representation of a number + * \param i number to format + * \param precision number of fractional digits + */ + QString formatNumber(double i, int precision = -1) const; + + /*! + * \brief Returns the string representation of a number + * \param i number to format + */ + QString formatNumber(float i) const; + + /*! + * \brief Returns the string representation of a number as percentage + * \param i number to format + * \param decimals number of digits shown after decimal separator + */ + QString formatPercent(double i, int decimals = 0) const; + + /*! + * \brief Formats an amount of currency + * \param amount amount to format + * \param currency three letter currency code in ISO-4217 format, e.g. EUR or USD + */ + QString formatCurrency(double amount, const QString ¤cy) const; + + /*! + * \brief Creates a string presentation for a date time with explicit format lengths + * \param dateTime time object to create representation from + * \param dateType style of date formatting + * \param timeType style of time formatting + * \param calendarType calendar to use for formatting + * + * If dateType is DuiLocale::DateNone and timeType is DuiLocale::TimeNone, + * an empty string is returned. + */ + QString formatDateTime(const QDateTime &dateTime, DateType dateType = DateLong, + TimeType timeType = TimeLong, + Calendar calendarType = DefaultCalendar) const; + + /*! + * \brief String presentation with explicit calendar type + * \param dateTime time to format + * \param calendarType calendar to use + */ + QString formatDateTime(const QDateTime &dateTime, Calendar calendarType) const; + + /*! + * \brief Formats DuiCalendar using its native calendar system + * \param duiCalendar Calendar holding the datetime to format + * \param datetype format for date + * \param timetype format for time + * + * If dateType is DuiLocale::DateNone and timeType is DuiLocale::TimeNone, + * an empty string is returned. + */ + QString formatDateTime(const DuiCalendar &duiCalendar, DateType datetype = DateLong, + TimeType timetype = TimeLong) const; + + QString formatDateTimeICU(const QDateTime &dateTime, + const QString &formatString) const; + QString formatDateTimeICU(const DuiCalendar &duiCalendar, + const QString &formatString) const; + /*! + * \brief creates a string presentation for a QDateTime with specific format string + * \param dateTime QDateTime to format + * \param formatString in ISO-14652 date time format + * + * \sa formatDateTime(const DuiCalendar &duiCalendar, const QString &formatString) const + */ + QString formatDateTime(const QDateTime &dateTime, + const QString &formatString) const; + // divergence: not implemented modified field descriptors (%Ec, %EC, %EY etc) + + /** + \brief Formats a date string based on ISO-14652 (draft) pattern + + \sa formatDateTime(const QDateTime &dateTime, const QString &formatString) const; + + For more information about the format characters used here see + + ISO-14652 (draft) + + or + + the man page of date + + or + + the documentation of the glibc function strftime + . + + The pattern may contain the following symbols to be replaced with + the corresponding information: + - \%a FDCC-set's abbreviated weekday name. + - \%A FDCC-set's full weekday name. + - \%b FDCC-set's abbreviated month name. + - \%B FDCC-set's full month name. + - \%c FDCC-set's appropriate date and time representation. + - \%C Century (a year divided by 100 and truncated to integer) as decimal number (00-99). + - \%d Day of the month as a decimal number (01-31). + - \%D Date in the format mm/dd/yy. + - \%e Day of the month as a decimal number (1-31 in at two-digit field with leading <space> fill). + - \%F The date in the format YYYY-MM-DD (An ISO 8601 format). + - \%g Week-based year within century, as a decimal number (00-99). + - \%G Week-based year with century, as a decimal number (for example 1997). + - \%h A synonym for %b. + - \%H Hour (24-hour clock), as a decimal number (00-23). + - \%I Hour (12-hour clock), as a decimal number (01-12). + - \%j Day of the year, as a decimal number (001-366). + - \%m Month, as a decimal number (01-13). + - \%M Minute, as a decimal number (00-59). + - \%n A <newline> character. + - \%p FDCC-set's equivalent of either AM or PM. + - \%r 12-hour clock time (01-12), using the AM/PM notation. + - \%R 24-hour clock time, in the format "%H:%M". + - \%S Seconds, as a decimal number (00-61). + - \%t A <tab> character. + - \%T 24-hour clock time, in the format HH:MM:SS. + - \%u Weekday, as a decimal number (1(Monday)-7). + - \%U Week number of the year (Sunday as the first day of the week) as a + decimal number (00-53). All days in a new year preceding the first + Sunday are considered to be in week 0. + - \%v Week number of the year, as a decimal number with two digits including + a possible leading zero, according to "week" keyword. + - \%V Week of the year (Monday as the first day of the week), as a decimal + number (01-53). The method for determining the week number is as + specified by ISO 8601. + - \%w Weekday, as a decimal number (0(Sunday)-6). + - \%W Week number of the year (Monday as the first day of the week), as a + decimal number (00-53). All days in a new year preceding the first + Monday are considered to be in week 0. + - \%x FDCC-set's appropriate date representation. + - \%X FDCC-set's appropriate time representation. + - \%y Year within century (00-99). + - \%Y Year with century, as a decimal number. + - \%z The offset from UTC in the ISO 8601 format "-0430" (meaning 4 hours + 30 minutes behind UTC, west of Greenwich), or by no characters if no + time zone is determinable. + - \%Z Time-zone name, or no characters if no time zone is determinable. + - \%% A <percent-sign> character. + */ + QString formatDateTime(const DuiCalendar &duiCalendar, + const QString &formatString) const; + + /*! + * \brief Returns the locale dependant name for a month number + */ + QString monthName(const DuiCalendar &duiCalendar, int monthNumber) const; + + /*! + * \brief Returns the locale dependant name for a month using context information + */ + QString monthName(const DuiCalendar &duiCalendar, int monthNumber, + DateSymbolContext context, DateSymbolLength symbolLength) const; + + + /*! + * \brief Returns locale dependant weekday name + */ + QString weekdayName(const DuiCalendar &duiCalendar, int weekday) const; + + + /*! + * \brief Returns locale dependant weekday name using context information + */ + QString weekdayName(const DuiCalendar &duiCalendar, int weekday, + DateSymbolContext context, DateSymbolLength symbolLength) const; + + + + // TODO: add versions for QDate and QTime? + + + //////////////////////////////// + //// ID translation scheme ///// + + /*! + * \brief Adds a catalog of translations. If the catalog is already installed, + * it doesn't do anything. + * \deprecated This method is deprecated since 0.18. + * It was used to load translations for + * trid() which has already been removed from libdui (qtTrId() is used instead + * of trid() now). Translations for qtTrId() are added with installTrCatalog(). + * Therefore, installCategoryCatalog() has become useless + * + * \param category Category to load the catalog for + * \param name abstract name for the catalog. Concrete file is searched based on this. + */ + void Q_DECL_DEPRECATED installCategoryCatalog(Category category, const QString &name); + + /*! + * \brief removes a translation catalog + * \deprecated This method is deprecated since 0.18 + * It was needed to remove translation catalogs loaded for trid(). + * trid() has been removed already from libdui, therefore this + * method has become useless. + */ + void Q_DECL_DEPRECATED removeCategoryCatalog(Category category, const QString &name); + + /*! + * \brief Copies translations from another DuiLocale + * the catalogs are reloaded based on the locale settings + */ + void copyCatalogsFrom(const DuiLocale &other); + + /*! + * \brief Searches the installed catalogs by name and returns true if found + * \deprecated This method is deprecated since 0.18 + * It was needed to check whether translation catalogs were loaded for trid(). + * trid() has been removed already from libdui, therefore this + * method has become useless. + */ + bool Q_DECL_DEPRECATED hasCategoryCatalog(Category category, const QString &name); + + /*! + * \brief installs a translation catalog + * The catalog will be used when translating strings with qtTrId() or tr(). + */ + void installTrCatalog(const QString &name); + + /*! + * \brief tr() compatibility translation method. + * \param context context of the translation + * \param sourceText text to translate + * \param comment about the translation. may be helpful when creating translation files + * \param n plurality + */ + QString translate(const char *context, const char *sourceText, + const char *comment = 0, int n = -1); + + /*! + * \brief Sets the DataPaths for locale system to given paths. + * This should be called at most once before creating any DuiLocale instances + * Data itself should be in the ICU specific subdirectory at the given paths, e.g. + * somePath/icudt42l/ + */ + static void setDataPaths(const QStringList &dataPaths); + + /*! + * \brief Sets the DatPaths to given path + */ + static void setDataPath(const QString &dataPath); + + /*! + * \brief Sets the paths that are used as base directories for using translations + * The translation path modification methods are not thread-safe. + */ + static void setTranslationPaths(const QStringList &paths); + + /*! + * \brief Append a path to the translation file lookup directories. + */ + static void addTranslationPath(const QString &path); + + /*! + * \brief Removes a path + */ + static void removeTranslationPath(const QString &path); + + /*! + * \brief Returns the list of current translation file base paths + */ + static QStringList translationPaths(); + + /*! + * \brief Monitors all changes in settings + * After calling this method, all changes in the settings + * will emit settingsChanged() signal + */ + void connectSettings(); + + /*! + * \brief Disconnects from change monitoring in settings + * After calling this method, all changes in the settings + * will no longer emit settingsChanged() signal + */ + void disconnectSettings(); + +Q_SIGNALS: + // TODO: Connect with DuiGConfItem valueChanged() + void settingsChanged(); + +protected: + /*! + * \brief Installs the Tr compatibility translations into QCoreApplication + */ + void insertTrToQCoreApp(); + + /*! + * \brief Removes the Tr compatibility translations from QCoreApplication + */ + void removeTrFromQCoreApp(); + + /*! + * \brief Returns the default locale object. + */ + static DuiLocale &getDefault(); + + +private: + // not implemented now + bool operator==(const DuiLocale &other) const; + bool operator!=(const DuiLocale &other) const; + + // global default locale + static DuiLocale *s_systemDefault; + + // private info is kept away from the public header + DuiLocalePrivate *const d_ptr; + Q_DECLARE_PRIVATE(DuiLocale) + + friend class DuiCalendar; + friend class DuiCollator; + friend class DuiIcuBreakIteratorPrivate; + +private Q_SLOTS: + void refreshSettings(); +}; + +#endif diff --git a/src/i18n/duilocale_p.h b/src/i18n/duilocale_p.h new file mode 100644 index 000000000..7c7c8759b --- /dev/null +++ b/src/i18n/duilocale_p.h @@ -0,0 +1,130 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUILOCALE_P_H +#define DUILOCALE_P_H + +#include +#include +#include +#include + +#ifdef HAVE_ICU +#include +#include +#include +#include +#endif + +#ifdef HAVE_GCONF +#include "duigconfitem.h" +#endif + +#include "duilocale.h" + +class QString; +class DuiTranslationCatalog; + +class DuiLocalePrivate +{ +public: + DuiLocalePrivate(); + DuiLocalePrivate(const DuiLocalePrivate &other); + + virtual ~DuiLocalePrivate(); + + + DuiLocalePrivate &operator=(const DuiLocalePrivate &other); + + + static QString categoryToDirectoryName(DuiLocale::Category category); + + // returns string presentation for category. + static QString createLocaleString(const QString &language, + const QString &country, + const QString &script, + const QString &variant); + + typedef QList > CatalogList; + + // return string for a category, default if category is not set + QString categoryName(DuiLocale::Category category) const; + + void reloadCatalogList(CatalogList &cataloglist, DuiLocale *duilocale, + DuiLocale::Category category); + + + void setCategoryLocale(DuiLocale *duilocale, DuiLocale::Category category, + const QString &localeName); + +#ifdef HAVE_ICU + // creates an icu::Locale for specific category + icu::Locale getCategoryLocale(DuiLocale::Category category) const; + + static icu::DateFormatSymbols *createDateFormatSymbols(icu::Locale locale); +#endif + + // these return the requested part of a locale string, + // e.g. parseLanguage("fi_FI") -> "fi" + static QString parseLanguage(const QString &localeString); + static QString parseCountry(const QString &localeString); + static QString parseScript(const QString &localeString); + static QString parseVariant(const QString &localeString); + + bool _valid; + + // the default locale is used for messages and other categories if not + // overridden + QString _defaultLocale; + QString _messageLocale; + QString _numericLocale; + QString _collationLocale; + QString _calendarLocale; + QString _monetaryLocale; + QString _nameLocale; + + // the used calendar and collation may be overridden + DuiLocale::Calendar _calendar; + DuiLocale::Collation _collation; + // add currency? + +#ifdef HAVE_ICU + // number format caching for better performance. + icu::NumberFormat *_numberFormat; +#endif + + // translations for two supported translation categories + CatalogList _messageTranslations; + CatalogList _timeTranslations; + + // tr translations are kept separate because they have to be loaded when inserted + // into QCoreApplication + CatalogList _trTranslations; + + static QStringList translationPaths; + +#ifdef HAVE_GCONF + DuiGConfItem currentLanguageItem; + DuiGConfItem currentCountryItem; + DuiGConfItem currentScriptItem; + DuiGConfItem currentVariantItem; +#endif +}; + +#endif diff --git a/src/i18n/duinullbreakiterator.cpp b/src/i18n/duinullbreakiterator.cpp new file mode 100644 index 000000000..fc2da1574 --- /dev/null +++ b/src/i18n/duinullbreakiterator.cpp @@ -0,0 +1,245 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duinullbreakiterator.h" + +/*! \internal + * internally used by DuiBreakIterator + */ +class DuiNullBreakIteratorPrivate +{ +public: + DuiNullBreakIteratorPrivate(); + virtual ~DuiNullBreakIteratorPrivate(); + + int current; + QString string; +}; + + +DuiNullBreakIteratorPrivate::DuiNullBreakIteratorPrivate() + : current(-1) +{ + // nothing +} + + +DuiNullBreakIteratorPrivate::~DuiNullBreakIteratorPrivate() +{ +} + + +DuiNullBreakIterator::DuiNullBreakIterator(const DuiLocale &locale, + const QString &text, + DuiBreakIterator::Type type) + : d_ptr(new DuiNullBreakIteratorPrivate) +{ + Q_UNUSED(locale); + Q_UNUSED(type); + Q_D(DuiNullBreakIterator); + d->string = text; +} + + +DuiNullBreakIterator::DuiNullBreakIterator(const QString &text, + DuiBreakIterator::Type type) + : d_ptr(new DuiNullBreakIteratorPrivate) +{ + Q_UNUSED(type); + Q_D(DuiNullBreakIterator); + d->string = text; +} + + +DuiNullBreakIterator::~DuiNullBreakIterator() +{ + delete d_ptr; +} + + +bool DuiNullBreakIterator::hasNext() const +{ + Q_D(const DuiNullBreakIterator); + + int next = d->current + 1; + + if (next >= d->string.length()) { + return false; + } + + return true; +} + + +bool DuiNullBreakIterator::hasPrevious() const +{ + Q_D(const DuiNullBreakIterator); + + int prev = d->current - 1; + + if (prev < 0) { + return false; + } + + return true; +} + + +int DuiNullBreakIterator::next() +{ + Q_D(DuiNullBreakIterator); + + int next = d->current + 1; + + if (next >= d->string.length()) { + next = -1; + toBack(); + } else { + d->current = next; + } + + return next; +} + + +int DuiNullBreakIterator::next(int index) +{ + Q_D(DuiNullBreakIterator); + + int next = index + 1; + + if (next >= d->string.length()) { + next = -1; + toBack(); + } else { + d->current = next; + } + + return next; +} + + +int DuiNullBreakIterator::peekNext() +{ + Q_D(DuiNullBreakIterator); + + int next = d->current + 1; + + if (next >= d->string.length()) { + next = -1; + } + + return next; +} + + +int DuiNullBreakIterator::peekPrevious() +{ + Q_D(DuiNullBreakIterator); + + int previous = d->current - 1; + + if (previous < 0) { + previous = -1; + } + + return previous; +} + + +int DuiNullBreakIterator::previous() +{ + Q_D(DuiNullBreakIterator); + + int previous = d->current - 1; + + if (previous < 0) { + previous = -1; + toFront(); + } + + d->current = previous; + + return previous; +} + + +int DuiNullBreakIterator::previous(int index) +{ + Q_D(DuiNullBreakIterator); + + int previous = index - 1; + + if (previous < 0) { + previous = -1; + toFront(); + } + + d->current = previous; + + return previous; +} + + +int DuiNullBreakIterator::previousInclusive() +{ + return previous(); +} + + +int DuiNullBreakIterator::previousInclusive(int index) +{ + return previous(index); +} + + +void DuiNullBreakIterator::setIndex(int index) +{ + Q_D(DuiNullBreakIterator); + d->current = index; +} + + +void DuiNullBreakIterator::toBack() +{ + Q_D(DuiNullBreakIterator); + d->current = d->string.length(); +} + + +void DuiNullBreakIterator::toFront() +{ + Q_D(DuiNullBreakIterator); + d->current = -1; +} + + +bool DuiNullBreakIterator::isBoundary() +{ + Q_D(DuiNullBreakIterator); + return isBoundary(d->current); +} + + +bool DuiNullBreakIterator::isBoundary(int index) +{ + Q_UNUSED(index); + return true; +} +/*! \internal_end */ diff --git a/src/i18n/duinullbreakiterator.h b/src/i18n/duinullbreakiterator.h new file mode 100644 index 000000000..49bae40df --- /dev/null +++ b/src/i18n/duinullbreakiterator.h @@ -0,0 +1,66 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUINULLBREAKITERATOR_H +#define DUINULLBREAKITERATOR_H + +#include "duiexport.h" +#include "duibreakiterator.h" +#include "duibreakiteratorif.h" + +#include + +class DuiNullBreakIteratorPrivate; + +//! \internal Used by DuiBreakIterator +class DUI_EXPORT DuiNullBreakIterator : public DuiBreakIteratorIf +{ +public: + DuiNullBreakIterator(const DuiLocale &locale, + const QString &text, + DuiBreakIterator::Type type = DuiBreakIterator::WordIterator); + explicit DuiNullBreakIterator(const QString &text, + DuiBreakIterator::Type type = DuiBreakIterator::WordIterator); + virtual ~DuiNullBreakIterator(); + + // java-style iterator interface: + bool hasNext() const; + bool hasPrevious() const; + int next(); + int next(int index); // searching from explicit index + int peekNext(); + int peekPrevious(); + int previous(); + int previous(int index); + int previousInclusive(); + int previousInclusive(int index); + void toBack(); + void toFront(); + void setIndex(int index); + bool isBoundary(); + bool isBoundary(int index); + +private: + Q_DISABLE_COPY(DuiNullBreakIterator) + Q_DECLARE_PRIVATE(DuiNullBreakIterator) + DuiNullBreakIteratorPrivate *const d_ptr; +}; +//! \internal_end + +#endif diff --git a/src/i18n/i18n.pri b/src/i18n/i18n.pri new file mode 100644 index 000000000..9895a2639 --- /dev/null +++ b/src/i18n/i18n.pri @@ -0,0 +1,34 @@ +############################################################################### +# DuiInternationalization module +############################################################################### +I18N_SRC_DIR=./i18n +INCLUDEPATH+=./i18n + + +HEADERS += \ + $$I18N_SRC_DIR/duibreakiterator.h \ + $$I18N_SRC_DIR/duilocale.h + +SOURCES += \ + $$I18N_SRC_DIR/duibreakiterator.cpp \ + $$I18N_SRC_DIR/duilocale.cpp + +contains(DEFINES, HAVE_ICU) { + HEADERS += \ + $$I18N_SRC_DIR/duicalendar.h \ + $$I18N_SRC_DIR/duicollator.h \ + $$I18N_SRC_DIR/duiicubreakiterator.h \ + $$I18N_SRC_DIR/duiicuconversions.h + + SOURCES += \ + $$I18N_SRC_DIR/duicalendar.cpp \ + $$I18N_SRC_DIR/duicollator.cpp \ + $$I18N_SRC_DIR/duiicubreakiterator.cpp \ + $$I18N_SRC_DIR/duiicuconversions.cpp +} else { + HEADERS += \ + $$I18N_SRC_DIR/duinullbreakiterator.h \ + + SOURCES += \ + $$I18N_SRC_DIR/duinullbreakiterator.cpp +} diff --git a/src/icu-extradata/extradata.pri b/src/icu-extradata/extradata.pri new file mode 100644 index 000000000..6b091956d --- /dev/null +++ b/src/icu-extradata/extradata.pri @@ -0,0 +1,11 @@ +extradata.name = libextradata builder +extradata.input = EXTRADATA_SOURCE +extradata.output = $$DESTDIR/lib${QMAKE_FILE_BASE}.a +extradata.commands += genrb -d $$OBJECTS_DIR -s $$IN_PWD -e UTF-8 ${QMAKE_FILE_BASE}.txt; +extradata.commands += pkgdata --name ${QMAKE_FILE_BASE} --mode static -v -d $$DESTDIR -T $$OBJECTS_DIR -s $$OBJECTS_DIR $$IN_PWD/packagelist.txt + + +extradata.clean += $$OBJECTS_DIR/*.mak $$OBJECTS_DIR/*.lst $$OBJECTS_DIR/*.ao $$OBJECTS_DIR/*.o $$OBJECTS_DIR/*.res $$OBJECTS_DIR/*.c $$DESTDIR/lib${QMAKE_FILE_BASE}.a $$DESTDIR/README_${QMAKE_FILE_BASE}.txt +extradata.CONFIG = target_predeps + +QMAKE_EXTRA_COMPILERS += extradata diff --git a/src/icu-extradata/extradata.txt b/src/icu-extradata/extradata.txt new file mode 100644 index 000000000..a7dad1a40 --- /dev/null +++ b/src/icu-extradata/extradata.txt @@ -0,0 +1,1322 @@ +root { +posixdata { + postalFmts { + DJ {"%z%c%T%s%b%e%r"} + ER {"%z%c%T%s%b%e%r"} + ET {"%z%c%T%s%b%e%r"} + ZA {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + ES {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + AE {"%z%c%T%s%b%e%r"} + BH {"%z%c%T%s%b%e%r"} + DZ {"%z%c%T%s%b%e%r"} + EG {"%z%c%T%s%b%e%r"} + IN {"%z%c%T%s%b%e%r"} + IQ {"%z%c%T%s%b%e%r"} + JO {"%z%c%T%s%b%e%r"} + KW {"%z%c%T%s%b%e%r"} + LB {"%z%c%T%s%b%e%r"} + LY {"%z%c%T%s%b%e%r"} + MA {"%z%c%T%s%b%e%r"} + OM {"%z%c%T%s%b%e%r"} + QA {"%z%c%T%s%b%e%r"} + SA {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + SD {"%z%c%T%s%b%e%r"} + SY {"%z%c%T%s%b%e%r"} + TN {"%z%c%T%s%b%e%r"} + YE {"%z%c%T%s%b%e%r"} + AZ {"???"} + BY {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + BG {"%f%N%a%N%d%N%b%N%sN%h, %e, %r%N%z %T%N%c%N"} + BD {"%a%N%f%N%d%N%b%N%h %s %e %r%N%T %z%N%c%N"} + FR {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + BA {"%a%N%f%N%d%N%b%N%h %s %e %r%N%T %z%N%c%N"} + AD {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + IT {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + UA {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + CZ {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + PL {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + GB {"%d%N%f%N%d%N%b%N%s %h 5e %r%N%C%z %T%N%c%N"} + DK {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + AT {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + BE {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + CH {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + DE {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + LI {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + LU {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + BT {"%f%N%a%N%d%N%r%t%e%t%b%N%h%t%s%N%T%N%S%N%z%c%N"} + CY {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + GR {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + AU {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + BW {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + CA {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + HK {"%z%c%T%s%b%e%r"} + IE {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + NG {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + NZ {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + PH {"%z%c%T%s%b%e%r"} + SG {"%z%c%T%s%b%e%r"} + US {"%a%N%f%N%d%N%b%N%h %s %e %r%N%T, %S %z%N%c%N"} + ZW {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + AR {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + BO {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + CL {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + CO {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + CR {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + DO {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + EC {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + GT {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + HN {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + MX {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + NI {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + PA {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + PE {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + PR {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + PY {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + SV {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + UY {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + VE {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + EE {"%a%N%f%N%d%N%b%N%s%t%h%t%e%t%r%N%C-%z %T%N%c%N"} + IR {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + FI {"TISSIS FINLAND %f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + FO {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + NL {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + IL {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + HR {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + HU {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + AM {"%d%N%f%N%d%N%b%N%s %h 5e %r%N%C%z %T%N%c%N"} + ID {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + IS {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + JP {"%z%c%T%s%b%e%r"} + GE {"%d%N%f%N%d%N%b%N%s %h 5e %r%N%C%z %T%N%c%N"} + KZ {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + GL {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + KH {"%f%N%a%N%d%N%r%t%e%t%b%N%h%t%s%N%T%N%S%N%z%c%N"} + KR {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + TR {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + KG {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + UG {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + LA {"%f%N%a%N%d%N%r%t%e%t%b%N%h%t%s%N%T%N%S%N%z%c%N"} + LT {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + LV {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + MG {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + MK {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + MN {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + MY {"%z%c%T%s%b%e%r"} + MT {"%z%c%T%s%b%e%r"} + NO {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + NP {"%z%c%T%s%b%e%r"} + KE {"%z%c%T%s%b%e%r"} + PK {"%a%N%f%N%d%N%b%N%h %s %e %r%N%T %z%N%c%N"} + AN {"%d%N%f%N%d%N%b%N%s %h 5e %r%N%C%z %T%N%c%N"} + BR {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + PT {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + RO {"%f%N%a%d%N%s%t%h%N%b%t%e%t%r%N%z%t%T%N%S%t%c%N"} + RU {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + RW {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + LK {"%z%c%T%s%b%e%r"} + SK {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + SI {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + SO {"%z%c%T%s%b%e%r"} + AL {"%z%c%T%s%b%e%r"} + ME {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + RS {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + SE {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + TJ {"%a%N%f%N%d%N%b%N%h %s %e %r%N%T %z%N%c%N"} + TH {"%f%N%a%N%d%N%r%t%e%t%b%N%h%t%s%N%T%N%S%N%z%c%N"} + TM {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + CN {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + UZ {"%C%N%T%N%s %h%N%f%N%b%N%d%N%e %r%N%a%N%z"} + VN {"%z%c%T%s%b%e%r"} + SN {"%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"} + } + + nameFmts { + aa_DJ { + name_fmt {"%d%t%g%t%m%t%f"} + name_gen {""} + name_miss {"Maqanxa"} + name_mr {"Toobokoyta"} + name_mrs {"Gisti"} + name_ms {""} + } + aa_ER { + name_fmt {"%d%t%g%t%m%t%f"} + name_gen {""} + name_miss {"Maqanxa"} + name_mr {"Toobokoyta"} + name_mrs {"Gisti"} + name_ms {""} + } + aa_ET { + name_fmt {"%d%t%g%t%m%t%f"} + name_gen {""} + name_miss {"Maqanxa"} + name_mr {"Toobokoyta"} + name_mrs {"Gisti"} + name_ms {""} + } + af_ZA { + name_fmt {"%d%t%g%t%m%t%f"} + name_gen {""} + name_miss {"mej"} + name_mr {"mnr"} + name_mrs {"mev"} + name_ms {"me"} + } + am_ET { + name_fmt {"%d%t%g%t%m%t%f"} + name_gen {""} + name_miss {"ወ/ሪት"} + name_mr {"አቶ"} + name_mrs {"ወ/ሮ"} + name_ms {"ወ/ሪት"} + } + an_ES { + name_fmt {"%d%t%g%t%m%t%f"} + } + ar_AE { + name_fmt {"%p%t%f%t%g"} + name_gen {"-san"} + name_miss {"Miss."} + name_mr {"Mr."} + name_mrs {"Mrs."} + name_ms {"Ms."} + } + ar_BH { + name_fmt {"%p%t%f%t%g"} + name_gen {"-san"} + name_miss {"Miss."} + name_mr {"Mr."} + name_mrs {"Mrs."} + name_ms {"Ms."} + } + ar_DZ { + name_fmt {"%p%t%f%t%g"} + name_gen {"-san"} + name_miss {"Miss."} + name_mr {"Mr."} + name_mrs {"Mrs."} + name_ms {"Ms."} + } + ar_EG { + name_fmt {"%p%t%f%t%g"} + name_gen {"-san"} + name_miss {"Miss."} + name_mr {"Mr."} + name_mrs {"Mrs."} + name_ms {"Ms."} + } + ar_IN { + name_fmt {"%p%t%f%t%g"} + name_gen {""} + name_miss {"Miss."} + name_mr {"Mr."} + name_mrs {"Mrs."} + name_ms {"Ms."} + } + ar_IQ { + name_fmt {"%p%t%f%t%g"} + name_gen {"-san"} + name_miss {"Miss."} + name_mr {"Mr."} + name_mrs {"Mrs."} + name_ms {"Ms."} + } + ar_JO { + name_fmt {"%p%t%f%t%g"} + name_gen {"-san"} + name_miss {"Miss."} + name_mr {"Mr."} + name_mrs {"Mrs."} + name_ms {"Ms."} + } + ar_KW { + name_fmt {"%p%t%f%t%g"} + name_gen {"-san"} + name_miss {"Miss."} + name_mr {"Mr."} + name_mrs {"Mrs."} + name_ms {"Ms."} + } + ar_LB { + name_fmt {"%p%t%f%t%g"} + name_gen {"-san"} + name_miss {"Miss."} + name_mr {"Mr."} + name_mrs {"Mrs."} + name_ms {"Ms."} + } + ar_LY { + name_fmt {"%p%t%f%t%g"} + name_gen {"-san"} + name_miss {"Miss."} + name_mr {"Mr."} + name_mrs {"Mrs."} + name_ms {"Ms."} + } + ar_MA { + name_fmt {"%p%t%f%t%g"} + name_gen {"-san"} + name_miss {"Miss."} + name_mr {"Mr."} + name_mrs {"Mrs."} + name_ms {"Ms."} + } + ar_OM { + name_fmt {"%p%t%f%t%g"} + name_gen {"-san"} + name_miss {"Miss."} + name_mr {"Mr."} + name_mrs {"Mrs."} + name_ms {"Ms."} + } + ar_QA { + name_fmt {"%p%t%f%t%g"} + name_gen {"-san"} + name_miss {"Miss."} + name_mr {"Mr."} + name_mrs {"Mrs."} + name_ms {"Ms."} + } + ar_SA { + name_fmt {"%d%t%g%t%m%t%f"} + } + ar_SD { + name_fmt {"%p%t%f%t%g"} + name_gen {"-san"} + name_miss {"Miss."} + name_mr {"Mr."} + name_mrs {"Mrs."} + name_ms {"Ms."} + } + ar_SY { + name_fmt {"%p%t%f%t%g"} + name_gen {"-san"} + name_miss {"Miss."} + name_mr {"Mr."} + name_mrs {"Mrs."} + name_ms {"Ms."} + } + ar_TN { + name_fmt {"%p%t%f%t%g"} + name_gen {"-san"} + name_miss {"Miss."} + name_mr {"Mr."} + name_mrs {"Mrs."} + name_ms {"Ms."} + } + ar_YE { + name_fmt {"%p%t%f%t%g"} + name_gen {"-san"} + name_miss {"Miss."} + name_mr {"Mr."} + name_mrs {"Mrs."} + name_ms {"Ms."} + } + as_IN { + name_fmt {"%p%t%f%t%g"} + name_gen {""} + name_miss {"কুমাৰী"} + name_mr {"শ্ৰী"} + name_mrs {"শ্ৰীমতী"} + name_ms {"কুমাৰী"} + } + ast_ES { + name_fmt {"%d%t%g%t%m%t%f"} + } + az_AZ { + name_fmt {"???"} + } + be_BY { + name_fmt {"%d%t%g%t%m%t%f"} + } + ber_DZ { + name_fmt {"%p%t%f%t%g"} + name_gen {"-san"} + name_miss {"Miss."} + name_mr {"Mr."} + name_mrs {"Mrs."} + name_ms {"Ms."} + } + ber_MA { + name_fmt {"%p%t%f%t%g"} + name_gen {"-san"} + name_miss {"Miss."} + name_mr {"Mr."} + name_mrs {"Mrs."} + name_ms {"Ms."} + } + bg_BG { + name_fmt {"%s%t%g%t%m%t%f"} + name_miss {"г-жица"} + name_mr {"г-дин"} + name_mrs {"г-жа"} + name_ms {"г-жа"} + } + bn_BD { + name_fmt {"%p%t%f%t%m%t%g"} + name_gen {""} + name_miss {"বেগম"} + name_mr {"জনাব"} + name_mrs {"বেগম"} + name_ms {"বেগম"} + } + bn_IN { + name_fmt {"%p%t%f%t%g"} + name_gen {""} + name_miss {"কুমারী"} + name_mr {"শ্রী"} + name_mrs {"শ্রীমতী"} + name_ms {"শ্রীমতী"} + } + br_FR { + name_fmt {"%d%t%g%t%m%t%f"} + name_gen {""} + name_miss {"Mlle"} + name_mr {"M."} + name_mrs {"Mme"} + name_ms {""} + } + bs_BA { + name_fmt {"%d%t%g%t%m%t%f"} + } + byn_ER { + name_fmt {"%d%t%g%t%m%t%f"} + name_gen {""} + name_miss {"ወ/ሪት"} + name_mr {"ኣቶ"} + name_mrs {"ወ/ሮ"} + name_ms {"ወ/ሪት"} + } + ca_AD { + name_fmt {"%d%t%g%t%m%t%f"} + } + ca_ES { + name_fmt {"%d%t%g%t%m%t%f"} + } + ca_FR { + name_fmt {"%d%t%g%t%m%t%f"} + } + ca_IT { + name_fmt {"%d%t%g%t%m%t%f"} + } + crh_UA { + name_fmt {"%d%t%g%t%m%t%f"} + } + cs_CZ { + name_fmt {"%d%t%g%t%m%t%f"} + name_miss {"Slečna"} + name_mr {"Pan"} + name_mrs {"Paní"} + name_ms {"Paní"} + } + csb_PL { + name_fmt {"%d%t%g%t%m%t%f"} + } + cy_GB { + name_fmt {"%d%t%g%t%m%t%f"} + name_miss {"Miss."} + name_mr {"Mr."} + name_mrs {"Mrs."} + name_ms {"Ms."} + } + da_DK { + name_fmt {"%d%t%g%t%m%t%f"} + } + de_AT { + name_fmt {"%d%t%g%t%m%t%f"} + } + de_BE { + name_fmt {"%d%t%g%t%m%t%f"} + } + de_CH { + name_fmt {"%d%t%g%t%m%t%f"} + } + de_DE { + name_fmt {"%d%t%g%t%m%t%f"} + name_miss {"Fräulein"} + name_mr {"Herr"} + name_mrs {"Frau"} + name_ms {"Frau"} + } + de_LI { + name_fmt {"%d%t%g%t%m%t%f"} + } + de_LU { + name_fmt {"%d%t%g%t%m%t%f"} + } + dz_BT { + name_fmt {"%p%t%g%t%m%t%f"} + name_gen {""} + name_miss {"མོ"} + name_mr {"ཕོ"} + name_mrs {"ཨམ"} + } + el_CY { + name_fmt {"%d%t%g%t%m%t%f"} + } + el_GR { + name_fmt {"%d%t%g%t%m%t%f"} + } + en_AU { + name_fmt {"%d%t%g%t%m%t%f"} + } + en_BW { + name_fmt {"%d%t%g%t%m%t%f"} + } + en_CA { + name_fmt {"%d%t%g%t%m%t%f"} + } + en_DK { + name_fmt {"%d%t%g%t%m%t%f"} + } + en_GB { + name_fmt {"%d%t%g%t%m%t%f"} + name_miss {"Miss."} + name_mr {"Mr."} + name_mrs {"Mrs."} + name_ms {"Ms."} + } + en_HK { + name_fmt {"%p%t%g%t%m%t%f"} + name_gen {""} + name_miss {"Ms."} + name_mr {"Mr."} + name_mrs {"Mrs."} + name_ms {""} + } + en_IE { + name_fmt {"%d%t%g%t%m%t%f"} + } + en_IN { + name_fmt {"%p%t%g%t%m%t%f"} + name_gen {""} + name_miss {"Ms."} + name_mr {"Mr."} + name_mrs {"Mrs."} + name_ms {""} + } + en_NG { + name_fmt {"%d%t%g%t%m%t%f"} + } + en_NZ { + name_fmt {"%d%t%g%t%m%t%f"} + } + en_PH { + name_fmt {"%p%t%f%t%g"} + name_gen {""} + name_miss {"Miss."} + name_mr {"Mr."} + name_mrs {"Mrs."} + name_ms {"Ms."} + } + en_SG { + name_fmt {"%p%t%f%t%g"} + name_gen {""} + name_miss {"Miss."} + name_mr {"Mr."} + name_mrs {"Mrs."} + name_ms {"Ms."} + } + en_US { + name_fmt {"%d%t%g%t%m%t%f"} + name_miss {"Miss."} + name_mr {"Mr."} + name_mrs {"Mrs."} + name_ms {"Ms."} + } + en_ZA { + name_fmt {"%d%t%g%t%m%t%f"} + name_gen {""} + name_miss {"Miss"} + name_mr {"Mr"} + name_mrs {"Mrs"} + name_ms {"Ms"} + } + en_ZW { + name_fmt {"%d%t%g%t%m%t%f"} + } + eo_US { + name_fmt {"%d%t%g%t%m%t%f"} + name_mr {"s-ro"} + name_mrs {"s-ino"} + name_ms {"s-ino"} + } + es_AR { + name_fmt {"%d%t%g%t%m%t%f"} + } + es_BO { + name_fmt {"%d%t%g%t%m%t%f"} + } + es_CL { + name_fmt {"%d%t%g%t%m%t%f"} + } + es_CO { + name_fmt {"%d%t%g%t%m%t%f"} + } + es_CR { + name_fmt {"%d%t%g%t%m%t%f"} + } + es_DO { + name_fmt {"%d%t%g%t%m%t%f"} + } + es_EC { + name_fmt {"%d%t%g%t%m%t%f"} + } + es_ES { + name_fmt {"%d%t%g%t%m%t%f"} + } + es_GT { + name_fmt {"%d%t%g%t%m%t%f"} + } + es_HN { + name_fmt {"%d%t%g%t%m%t%f"} + } + es_MX { + name_fmt {"%d%t%g%t%m%t%f"} + } + es_NI { + name_fmt {"%d%t%g%t%m%t%f"} + } + es_PA { + name_fmt {"%d%t%g%t%m%t%f"} + } + es_PE { + name_fmt {"%d%t%g%t%m%t%f"} + } + es_PR { + name_fmt {"%d%t%g%t%m%t%f"} + } + es_PY { + name_fmt {"%d%t%g%t%m%t%f"} + } + es_SV { + name_fmt {"%d%t%g%t%m%t%f"} + } + es_US { + name_fmt {"%d%t%g%t%m%t%f"} + } + es_UY { + name_fmt {"%d%t%g%t%m%t%f"} + } + es_VE { + name_fmt {"%d%t%g%t%m%t%f"} + } + et_EE { + name_fmt {"%d%t%g%t%m%t%f"} + } + eu_ES { + name_fmt {"%d%t%g%t%m%t%f"} + } + eu_FR { + name_fmt {"%d%t%g%t%m%t%f"} + } + fa_IR { + name_fmt {"%d%t%s%t%g%t%m%t%f"} + name_gen {""} + name_miss {"خانم"} + name_mr {"آقای"} + name_mrs {"خانم"} + name_ms {"خانم"} + } + fi_FI { + name_fmt {"%d%t%g%t%m%t%f"} + } + fil_PH { + name_fmt {"%d%t%g%t%m%t%f"} + name_gen {""} + name_miss {"Bb."} + name_mr {"G."} + name_mrs {"Gng."} + name_ms {"Bb."} + } + fo_FO { + name_fmt {"%d%t%g%t%m%t%f"} + } + fr_BE { + name_fmt {"%d%t%g%t%m%t%f"} + name_gen {""} + name_miss {"Mlle"} + name_mr {"M."} + name_mrs {"Mme"} + name_ms {""} + } + fr_CA { + name_fmt {"%d%t%g%t%m%t%f"} + name_gen {""} + name_miss {"Mlle"} + name_mr {"M."} + name_mrs {"Mme"} + name_ms {""} + } + fr_CH { + name_fmt {"%d%t%g%t%m%t%f"} + name_gen {""} + name_miss {"Mlle"} + name_mr {"M."} + name_mrs {"Mme"} + name_ms {""} + } + fr_FR { + name_fmt {"%d%t%g%t%m%t%f"} + name_gen {""} + name_miss {"Mlle"} + name_mr {"M."} + name_mrs {"Mme"} + name_ms {""} + } + fr_LU { + name_fmt {"%d%t%g%t%m%t%f"} + name_gen {""} + name_miss {"Mlle"} + name_mr {"M."} + name_mrs {"Mme"} + name_ms {""} + } + fur_IT { + name_fmt {"%d%t%g%t%m%t%f"} + } + fy_DE { + name_fmt {"%d%t%g%t%m%t%f"} + name_miss {"Fräulein"} + name_mr {"Herr"} + name_mrs {"Frau"} + name_ms {"Frau"} + } + fy_NL { + name_fmt {"%d%t%g%t%m%t%f"} + } + ga_IE { + name_fmt {"%d%t%g%t%m%t%f"} + } + gd_GB { + name_fmt {"%d%t%g%t%m%t%f"} + name_miss {"Miss."} + name_mr {"Mr."} + name_mrs {"Mrs."} + name_ms {"Ms."} + } + gez_ER { + name_fmt {"%d%t%g%t%m%t%f"} + name_gen {""} + name_miss {"ወ/ሪት"} + name_mr {"ኣቶ"} + name_mrs {"ወ/ሮ"} + name_ms {"ወ/ሪት"} + } + gez_ET { + name_fmt {"%d%t%g%t%m%t%f"} + name_gen {""} + name_miss {"ወ/ሪት"} + name_mr {"አቶ"} + name_mrs {"ወ/ሮ"} + name_ms {"ወ/ሪት"} + } + gl_ES { + name_fmt {"%d%t%g%t%m%t%f"} + } + gu_IN { + name_fmt {"%p%t%f%t%g"} + name_gen {"જાતિ"} + name_miss {"કુમારી"} + name_mr {"શ્રીમાન"} + name_mrs {"શ્રીમતિ"} + name_ms {"સશ્રી"} + } + gv_GB { + name_fmt {"%d%t%g%t%m%t%f"} + } + ha_NG { + name_fmt {"%d%t%g%t%m%t%f"} + } + he_IL { + name_fmt {"%d%t%g%t%m%t%f"} + } + hi_IN { + name_fmt {"%p%t%f%t%g"} + name_gen {""} + name_miss {"Miss."} + name_mr {"Mr."} + name_mrs {"Mrs."} + name_ms {"Ms."} + } + hr_HR { + name_fmt {"%d%t%g%t%m%t%f"} + } + hsb_DE { + name_fmt {"%d%t%g%t%m%t%f"} + name_miss {"knježna"} + name_mr {"knjez"} + name_mrs {"knjeni"} + } + hu_HU { + name_fmt {"%d%t%g%t%m%t%f"} + } + hy_AM { + name_fmt {"%d%t%g%t%m%t%f"} + name_miss {"օրիորդ"} + name_mr {"պրն"} + name_mrs {"տկն"} + } + id_ID { + name_fmt {"%d%t%g%t%m%t%f"} + } + ig_NG { + name_fmt {"%d%t%g%t%m%t%f"} + } + ik_CA { + name_fmt {"%d%t%g%t%m%t%f"} + } + is_IS { + name_fmt {"%d%t%g%t%m%t%f"} + } + it_CH { + name_fmt {"%d%t%g%t%m%t%f"} + } + it_IT { + name_fmt {"%d%t%g%t%m%t%f"} + } + iu_CA { + name_fmt {"%d%t%g%t%m%t%f"} + } + iw_IL { + name_fmt {"%d%t%g%t%m%t%f"} + } + ja_JP { + name_fmt {"%p%t%f%t%g"} + name_gen {"様"} + name_miss {"Miss."} + name_mr {"Mr."} + name_mrs {"Mrs."} + name_ms {"Ms."} + } + ka_GE { + name_fmt {"%d%t%g%t%m%t%f"} + } + kk_KZ { + name_fmt {"%d%t%g%t%m%t%f"} + } + kl_GL { + name_fmt {"%d%t%g%t%m%t%f"} + } + km_KH { + name_fmt {"%d%t%g%t%m%t%f"} + name_mr {"ທ"} + name_mrs {"ນ"} + } + kn_IN { + name_fmt {"%p%t%f%t%g"} + name_gen {""} + name_miss {"Miss."} + name_mr {"Mr."} + name_mrs {"Mrs."} + name_ms {"Ms."} + } + ko_KR { + name_fmt {"%d%t%g%t%m%t%f"} + } + ks_IN { + name_fmt {"%p%t%f%t%g"} + name_gen {""} + name_miss {"Miss."} + name_mr {"Mr."} + name_mrs {"Mrs."} + name_ms {"Ms."} + } + ku_TR { + name_fmt {"%d%t%g%t%m%t%f"} + name_gen {"Barêz"} + name_miss {"Barêz"} + name_mr {"Barêz"} + name_mrs {"Barêz"} + name_ms {"Barêz"} + } + kw_GB { + name_fmt {"%d%t%g%t%m%t%f"} + } + ky_KG { + name_fmt {"%d%t%g%t%m%t%f"} + } + lg_UG { + name_fmt {"%d%t%g%t%m%t%f"} + name_miss {"Mla"} + name_mr {"Mw"} + name_mrs {"Mla"} + name_ms {"Mla"} + } + li_BE { + name_fmt {"%d%t%g%t%m%t%f"} + } + li_NL { + name_fmt {"%d%t%g%t%m%t%f"} + } + lo_LA { + name_fmt {"%d%t%g%t%m%t%f"} + name_mr {"ທ"} + name_mrs {"ນ"} + } + lt_LT { + name_fmt {"%d%t%g%t%m%t%f"} + } + lv_LV { + name_fmt {"%d%t%g%t%m%t%f"} + } + mai_IN { + name_fmt {"%p%t%f%t%g"} + name_gen {""} + name_miss {"Miss."} + name_mr {"Mr."} + name_mrs {"Mrs."} + name_ms {"Ms."} + } + mg_MG { + name_fmt {"%d%t%g%t%m%t%f"} + } + mi_NZ { + name_fmt {"%d%t%g%t%m%t%f"} + } + mk_MK { + name_fmt {"%g%t%f"} + name_gen {"почитуван"} + name_miss {"г-ѓица"} + name_mr {"г-дин"} + name_mrs {"г-ѓа"} + name_ms {"г-ѓа"} + } + ml_IN { + name_fmt {"%p%t%f%t%g"} + name_gen {"ശ്രീ"} + name_miss {"കുമാരി"} + name_mr {"ശ്രീമാനു്"} + name_mrs {"ശ്രീമതി"} + name_ms {"ശ്രീമതി"} + } + mn_MN { + name_fmt {"%d%t%g%t%m%t%f"} + name_miss {"Хатагтай"} + name_mr {"Ноён"} + name_mrs {"Хатагтай"} + name_ms {"Хатагтай"} + } + mr_IN { + name_fmt {"%p%t%f%t%g"} + name_gen {""} + name_miss {"Miss."} + name_mr {"Mr."} + name_mrs {"Mrs."} + name_ms {"Ms."} + } + ms_MY { + name_fmt {"%p%t%f%t%g"} + name_gen {""} + name_miss {"cik"} + name_mr {"Eecik"} + name_mrs {"Puan"} + name_ms {"cik/Puan"} + } + mt_MT { + name_fmt {"%p%t%f%t%g"} + name_gen {""} + name_miss {"Miss."} + name_mr {"Mr."} + name_mrs {"Mrs."} + name_ms {"Ms."} + } + nb_NO { + name_fmt {"%d%t%g%t%m%t%f"} + } + nds_DE { + name_fmt {"%d%t%g%t%m%t%f"} + name_miss {"Fräulein"} + name_mr {"Herr"} + name_mrs {"Frau"} + name_ms {"Frau"} + } + nds_NL { + name_fmt {"%d%t%g%t%m%t%f"} + } + ne_NP { + name_fmt {"%p%t%f%t%g"} + name_gen {""} + name_miss {"Miss."} + name_mr {"Mr."} + name_mrs {"Mrs."} + name_ms {"Ms."} + } + nl_BE { + name_fmt {"%d%t%g%t%m%t%f"} + } + nl_NL { + name_fmt {"%d%t%g%t%m%t%f"} + } + nn_NO { + name_fmt {"%d%t%g%t%m%t%f"} + } + nr_ZA { + name_fmt {"%d%t%g%t%m%t%f"} + } + nso_ZA { + name_fmt {"%d%t%g%t%m%t%f"} + } + oc_FR { + name_fmt {"%d%t%g%t%m%t%f"} + name_gen {""} + name_miss {"Mlle"} + name_mr {"M."} + name_mrs {"Mme"} + name_ms {""} + } + om_ET { + name_fmt {"%d%t%g%t%m%t%f"} + name_gen {""} + name_miss {"Du"} + name_mr {"Ob"} + name_mrs {"Ad"} + name_ms {""} + } + om_KE { + name_fmt {"%d%t%g%t%m%t%f"} + name_gen {""} + name_miss {"Du"} + name_mr {"Ob"} + name_mrs {"Ad"} + name_ms {""} + } + or_IN { + name_fmt {"%p%t%f%t%g"} + name_gen {""} + name_miss {"Miss."} + name_mr {"Mr."} + name_mrs {"Mrs."} + name_ms {"Ms."} + } + pa_IN { + name_fmt {"%p%t%f%t%g"} + name_gen {""} + name_miss {"Miss."} + name_mr {"Mr."} + name_mrs {"Mrs."} + name_ms {"Ms."} + } + pa_PK { + name_fmt {"%d%t%g%t%m%t%f"} + } + pap_AN { + name_fmt {"%d%t%g%t%m%t%f"} + } + pl_PL { + name_fmt {"%d%t%g%t%m%t%f"} + } + pt_BR { + name_fmt {"%d%t%g%t%m%t%f"} + } + pt_PT { + name_fmt {"%d%t%g%t%m%t%f"} + } + ro_RO { + name_fmt {"%d%t%s%t%f%t%g%t%m"} + name_miss {"D-ra."} + name_mr {"Dl."} + name_mrs {"D-na."} + } + ru_RU { + name_fmt {"%d%t%g%t%m%t%f"} + } + ru_UA { + name_fmt {"%d%t%g%t%m%t%f"} + } + rw_RW { + name_fmt {"%d%t%g%t%m%t%f"} + } + sa_IN { + name_fmt {"%p%t%f%t%g"} + name_gen {""} + name_miss {"कुमारी"} + name_mr {"श्री"} + name_mrs {"श्रीमती"} + name_ms {"श्रीमती"} + } + sc_IT { + name_fmt {"%d%t%g%t%m%t%f"} + } + se_NO { + name_fmt {"%d%t%g%t%m%t%f"} + } + shs_CA { + name_fmt {"%d%t%g%t%m%t%f"} + } + si_LK { + name_fmt {"%g%t%m%t%f%t%s"} + name_gen {""} + name_miss {"මිය"} + name_mr {"මයා"} + name_mrs {"මිය"} + name_ms {"මිය"} + } + sid_ET { + name_fmt {"%d%t%g%t%m%t%f"} + name_gen {""} + name_miss {"Beeto"} + name_mr {"Kalaa"} + name_mrs {"Dukko"} + name_ms {""} + } + sk_SK { + name_fmt {"%d%t%g%t%m%t%f"} + } + sl_SI { + name_fmt {"%d%t%g%t%m%t%f"} + } + so_DJ { + name_fmt {"%d%t%g%t%m%t%f"} + name_gen {""} + name_miss {""} + name_mr {"Md"} + name_mrs {"Mw"} + name_ms {"Mw"} + } + so_ET { + name_fmt {"%d%t%g%t%m%t%f"} + name_gen {""} + name_miss {""} + name_mr {"Md"} + name_mrs {"Mw"} + name_ms {"Mw"} + } + so_KE { + name_fmt {"%d%t%g%t%m%t%f"} + name_gen {""} + name_miss {""} + name_mr {"Md"} + name_mrs {"Mw"} + name_ms {"Mw"} + } + so_SO { + name_fmt {"%d%t%g%t%m%t%f"} + name_gen {""} + name_miss {""} + name_mr {"Md"} + name_mrs {"Mw"} + name_ms {"Mw"} + } + sq_AL { + name_fmt {"%p%t%f%t%g"} + name_gen {""} + name_miss {"Miss."} + name_mr {"Mr."} + name_mrs {"Mrs."} + name_ms {"Ms."} + } + sr_ME { + name_fmt {"%d%t%g%t%m%t%f"} + name_gen {""} + name_miss {"г-ђица"} + name_mr {"г-дин"} + name_mrs {"г-ђа"} + name_ms {"г-ђа"} + } + sr_RS { + name_fmt {"%d%t%g%t%m%t%f"} + name_gen {""} + name_miss {"г-ђица"} + name_mr {"г-дин"} + name_mrs {"г-ђа"} + name_ms {"г-ђа"} + } + ss_ZA { + name_fmt {"%d%t%g%t%m%t%f"} + } + st_ZA { + name_fmt {"%d%t%g%t%m%t%f"} + } + sv_FI { + name_fmt {"%d%t%g%t%m%t%f"} + } + sv_SE { + name_fmt {"%d%t%g%t%m%t%f"} + } + ta_IN { + name_fmt {"%p%t%f%t%g"} + name_gen {""} + name_miss {"செல்வி "} + name_mr {"திரு "} + name_mrs {"திருமதி "} + name_ms {"Ms."} + } + te_IN { + name_fmt {"%p%t%f%t%g%t%m"} + name_gen {""} + name_miss {"కుమారి "} + name_mr {"శ్రీ "} + name_mrs {"శ్రీమతి "} + name_ms {""} + } + tg_TJ { + name_fmt {"%d%t%g%t%m%t%f"} + } + th_TH { + name_fmt {"%d%t%g%t%m%t%f"} + name_gen {"คุณ"} + name_miss {"นางสาว"} + name_mr {"นาย"} + name_mrs {"นาง"} + } + ti_ER { + name_fmt {"%d%t%g%t%m%t%f"} + name_gen {""} + name_miss {"ወ/ሪት"} + name_mr {"ኣቶ"} + name_mrs {"ወ/ሮ"} + name_ms {"ወ/ሪት"} + } + ti_ET { + name_fmt {"%d%t%g%t%m%t%f"} + name_gen {""} + name_miss {"ወ/ሪት"} + name_mr {"አቶ"} + name_mrs {"ወ/ሮ"} + name_ms {"ወ/ሪት"} + } + tig_ER { + name_fmt {"%d%t%g%t%m%t%f"} + name_gen {""} + name_miss {"ወ/ሪት"} + name_mr {"ኣቶ"} + name_mrs {"ወ/ሮ"} + name_ms {"ወ/ሪት"} + } + tk_TM { + name_fmt {"%d%t%g%t%m%t%f"} + name_gen {""} + name_miss {""} + name_mr {""} + name_mrs {""} + name_ms {""} + } + tl_PH { + name_fmt {"%d%t%g%t%m%t%f"} + name_miss {"Miss."} + name_mr {"Mr."} + name_mrs {"Mrs."} + name_ms {"Ms."} + } + tn_ZA { + name_fmt {"%d%t%g%t%m%t%f"} + } + tr_CY { + name_fmt {"%d%t%g%t%m%t%f"} + name_gen {"Sayın"} + name_miss {"Bayan"} + name_mr {"Bay"} + name_mrs {"Bayan"} + name_ms {"Bayan"} + } + tr_TR { + name_fmt {"%d%t%g%t%m%t%f"} + name_gen {"Sayın"} + name_miss {"Bayan"} + name_mr {"Bay"} + name_mrs {"Bayan"} + name_ms {"Bayan"} + } + ts_ZA { + name_fmt {"%d%t%g%t%m%t%f"} + } + tt_RU { + name_fmt {"???"} + } + ug_CN { + name_fmt {"%d%t%g%t%m%t%f"} + } + uk_UA { + name_fmt {"%d%t%g%t%m%t%f"} + name_gen {"шановний(-на)"} + name_miss {"панна"} + name_mr {"пан"} + name_mrs {"пані"} + name_ms {"пані"} + } + ur_PK { + name_fmt {"%d%t%g%t%m%t%f"} + } + uz_UZ { + name_fmt {"%d%t%f%t%g%t%m"} + name_gen {"Hurmatli"} + name_miss {""} + name_mr {"Janob"} + name_mrs {"Xonim"} + name_ms {""} + } + ve_ZA { + name_fmt {"%d%t%g%t%m%t%f"} + } + vi_VN { + name_fmt {"%p%t%f%t%m%t%g"} + name_gen {""} + name_miss {"C."} + name_mr {"Ô."} + name_mrs {"B."} + name_ms {""} + } + wa_BE { + name_fmt {"%d%t%g%t%m%t%f"} + name_gen {""} + name_miss {"Mle"} + name_mr {"M."} + name_mrs {"Mme"} + name_ms {"Mme"} + } + wal_ET { + name_fmt {"%d%t%g%t%m%t%f"} + name_gen {""} + name_miss {"ኬታዩ"} + name_mr {"ሚሲያ"} + name_mrs {"ኬታዋ"} + name_ms {"ኬታዩ"} + } + wo_SN { + name_fmt {"%d%t%g%t%m%t%f"} + } + xh_ZA { + name_fmt {"%d%t%g%t%m%t%f"} + name_miss {"Nkosazana"} + name_mr {"Mnumzana"} + name_mrs {"Nkosikazi"} + name_ms {""} + } + yi_US { + name_fmt {"%d%t%g%t%m%t%f"} + name_miss {"Miss."} + name_mr {"Mr."} + name_mrs {"Mrs."} + name_ms {"Ms."} + } + yo_NG { + name_fmt {"%d%t%g%t%m%t%f"} + } + zh_HK { + name_fmt {"%f%t%d1"} + name_gen {"君"} + name_miss {"小姐"} + name_mr {"先生"} + name_mrs {"夫人."} + name_ms {"女士"} + } + zh_SG { + name_fmt {"%p%t%f%t%g"} + name_gen {""} + name_miss {"Miss."} + name_mr {"Mr."} + name_mrs {"Mrs."} + name_ms {"Ms."} + } + zu_ZA { + name_fmt {"%d%t%g%t%m%t%f"} + name_miss {"Nkosazane"} + name_mr {"Mnumzane"} + name_mrs {"Nkosikazi"} + name_ms {""} + } + } +} +} diff --git a/src/icu-extradata/packagelist.txt b/src/icu-extradata/packagelist.txt new file mode 100644 index 000000000..41992931a --- /dev/null +++ b/src/icu-extradata/packagelist.txt @@ -0,0 +1 @@ +root.res diff --git a/src/include/DuiAbstractCellCreator b/src/include/DuiAbstractCellCreator new file mode 100644 index 000000000..fdf52a6d4 --- /dev/null +++ b/src/include/DuiAbstractCellCreator @@ -0,0 +1,2 @@ +#include "duiabstractcellcreator.h" + diff --git a/src/include/DuiAbstractLayoutPolicy b/src/include/DuiAbstractLayoutPolicy new file mode 100644 index 000000000..474a0406c --- /dev/null +++ b/src/include/DuiAbstractLayoutPolicy @@ -0,0 +1,2 @@ +#include "duiabstractlayoutpolicy.h" + diff --git a/src/include/DuiAbstractLayoutPolicyStyle b/src/include/DuiAbstractLayoutPolicyStyle new file mode 100644 index 000000000..be2111c33 --- /dev/null +++ b/src/include/DuiAbstractLayoutPolicyStyle @@ -0,0 +1 @@ +#include "duiabstractlayoutpolicystyle.h" diff --git a/src/include/DuiAbstractWidgetAnimation b/src/include/DuiAbstractWidgetAnimation new file mode 100644 index 000000000..5ca250a3d --- /dev/null +++ b/src/include/DuiAbstractWidgetAnimation @@ -0,0 +1,2 @@ +#include "duiabstractwidgetanimation.h" + diff --git a/src/include/DuiAbstractWidgetAnimationStyle b/src/include/DuiAbstractWidgetAnimationStyle new file mode 100644 index 000000000..7ee11c5ef --- /dev/null +++ b/src/include/DuiAbstractWidgetAnimationStyle @@ -0,0 +1 @@ +#include "duiabstractwidgetanimationstyle.h" diff --git a/src/include/DuiAction b/src/include/DuiAction new file mode 100644 index 000000000..a420fb8d6 --- /dev/null +++ b/src/include/DuiAction @@ -0,0 +1,2 @@ +#include "duiaction.h" + diff --git a/src/include/DuiActionProvider b/src/include/DuiActionProvider new file mode 100644 index 000000000..83aa80315 --- /dev/null +++ b/src/include/DuiActionProvider @@ -0,0 +1 @@ +#include "duiactionprovider.h" diff --git a/src/include/DuiAnimation b/src/include/DuiAnimation new file mode 100644 index 000000000..a1db5fb88 --- /dev/null +++ b/src/include/DuiAnimation @@ -0,0 +1 @@ +#include "duianimation.h" diff --git a/src/include/DuiAnimationStyle b/src/include/DuiAnimationStyle new file mode 100644 index 000000000..8da74bb3b --- /dev/null +++ b/src/include/DuiAnimationStyle @@ -0,0 +1,2 @@ +#include "duianimationstyle.h" + diff --git a/src/include/DuiAppletInstallationSourceInterface b/src/include/DuiAppletInstallationSourceInterface new file mode 100644 index 000000000..872910d47 --- /dev/null +++ b/src/include/DuiAppletInstallationSourceInterface @@ -0,0 +1 @@ +#include "duiappletinstallationsourceinterface.h" diff --git a/src/include/DuiAppletInstantiator b/src/include/DuiAppletInstantiator new file mode 100644 index 000000000..07625d6f1 --- /dev/null +++ b/src/include/DuiAppletInstantiator @@ -0,0 +1 @@ +#include "duiappletinstantiator.h" diff --git a/src/include/DuiAppletInterface b/src/include/DuiAppletInterface new file mode 100644 index 000000000..ec36ce3f1 --- /dev/null +++ b/src/include/DuiAppletInterface @@ -0,0 +1 @@ +#include "duiappletinterface.h" diff --git a/src/include/DuiAppletMetaData b/src/include/DuiAppletMetaData new file mode 100644 index 000000000..0f8fc2fee --- /dev/null +++ b/src/include/DuiAppletMetaData @@ -0,0 +1 @@ +#include "duiappletmetadata.h" diff --git a/src/include/DuiApplication b/src/include/DuiApplication new file mode 100644 index 000000000..032673145 --- /dev/null +++ b/src/include/DuiApplication @@ -0,0 +1 @@ +#include "duiapplication.h" diff --git a/src/include/DuiApplicationExtensionArea b/src/include/DuiApplicationExtensionArea new file mode 100644 index 000000000..165b1820f --- /dev/null +++ b/src/include/DuiApplicationExtensionArea @@ -0,0 +1 @@ +#include "duiapplicationextensionarea.h" diff --git a/src/include/DuiApplicationIfAdaptor b/src/include/DuiApplicationIfAdaptor new file mode 100644 index 000000000..563a0bb94 --- /dev/null +++ b/src/include/DuiApplicationIfAdaptor @@ -0,0 +1 @@ +#include "duiapplicationifadaptor.h" diff --git a/src/include/DuiApplicationIfProxy b/src/include/DuiApplicationIfProxy new file mode 100644 index 000000000..38a0e3b97 --- /dev/null +++ b/src/include/DuiApplicationIfProxy @@ -0,0 +1 @@ +#include "duiapplicationifproxy.h" diff --git a/src/include/DuiApplicationMenu b/src/include/DuiApplicationMenu new file mode 100644 index 000000000..903eee576 --- /dev/null +++ b/src/include/DuiApplicationMenu @@ -0,0 +1,2 @@ +#include "duiapplicationmenu.h" + diff --git a/src/include/DuiApplicationMenuButtonStyle b/src/include/DuiApplicationMenuButtonStyle new file mode 100644 index 000000000..50877b468 --- /dev/null +++ b/src/include/DuiApplicationMenuButtonStyle @@ -0,0 +1 @@ +#include "duiapplicationmenubuttonstyle.h" diff --git a/src/include/DuiApplicationMenuView b/src/include/DuiApplicationMenuView new file mode 100644 index 000000000..ce99ab52a --- /dev/null +++ b/src/include/DuiApplicationMenuView @@ -0,0 +1,2 @@ +#include "duiapplicationmenuview.h" + diff --git a/src/include/DuiApplicationPage b/src/include/DuiApplicationPage new file mode 100644 index 000000000..53a7f9cc7 --- /dev/null +++ b/src/include/DuiApplicationPage @@ -0,0 +1,2 @@ +#include "duiapplicationpage.h" + diff --git a/src/include/DuiApplicationService b/src/include/DuiApplicationService new file mode 100644 index 000000000..2910b858b --- /dev/null +++ b/src/include/DuiApplicationService @@ -0,0 +1 @@ +#include "duiapplicationservice.h" diff --git a/src/include/DuiApplicationWindow b/src/include/DuiApplicationWindow new file mode 100644 index 000000000..54038e3ef --- /dev/null +++ b/src/include/DuiApplicationWindow @@ -0,0 +1 @@ +#include "duiapplicationwindow.h" diff --git a/src/include/DuiAssembly b/src/include/DuiAssembly new file mode 100644 index 000000000..9824bb2c0 --- /dev/null +++ b/src/include/DuiAssembly @@ -0,0 +1,2 @@ +#include "duiassembly.h" + diff --git a/src/include/DuiBasicLayoutAnimation b/src/include/DuiBasicLayoutAnimation new file mode 100644 index 000000000..72165755f --- /dev/null +++ b/src/include/DuiBasicLayoutAnimation @@ -0,0 +1,2 @@ +#include "duibasiclayoutanimation.h" + diff --git a/src/include/DuiBasicLayoutAnimationStyle b/src/include/DuiBasicLayoutAnimationStyle new file mode 100644 index 000000000..30e8343cf --- /dev/null +++ b/src/include/DuiBasicLayoutAnimationStyle @@ -0,0 +1 @@ +#include "duibasiclayoutanimationstyle.h" diff --git a/src/include/DuiBreakIterator b/src/include/DuiBreakIterator new file mode 100644 index 000000000..00588ec58 --- /dev/null +++ b/src/include/DuiBreakIterator @@ -0,0 +1,2 @@ +#include "duibreakiterator.h" + diff --git a/src/include/DuiButton b/src/include/DuiButton new file mode 100644 index 000000000..a8aacd640 --- /dev/null +++ b/src/include/DuiButton @@ -0,0 +1 @@ +#include "duibutton.h" diff --git a/src/include/DuiButtonGroup b/src/include/DuiButtonGroup new file mode 100644 index 000000000..ce94e8d11 --- /dev/null +++ b/src/include/DuiButtonGroup @@ -0,0 +1,2 @@ +#include "duibuttongroup.h" + diff --git a/src/include/DuiButtonIconView b/src/include/DuiButtonIconView new file mode 100644 index 000000000..751720635 --- /dev/null +++ b/src/include/DuiButtonIconView @@ -0,0 +1,2 @@ +#include "duibuttoniconview.h" + diff --git a/src/include/DuiButtonView b/src/include/DuiButtonView new file mode 100644 index 000000000..8583de043 --- /dev/null +++ b/src/include/DuiButtonView @@ -0,0 +1,2 @@ +#include "duibuttonview.h" + diff --git a/src/include/DuiCalendar b/src/include/DuiCalendar new file mode 100644 index 000000000..47f7d0161 --- /dev/null +++ b/src/include/DuiCalendar @@ -0,0 +1 @@ +#include "duicalendar.h" diff --git a/src/include/DuiCancelEvent b/src/include/DuiCancelEvent new file mode 100644 index 000000000..8017f0363 --- /dev/null +++ b/src/include/DuiCancelEvent @@ -0,0 +1 @@ +#include "duicancelevent.h" diff --git a/src/include/DuiCollator b/src/include/DuiCollator new file mode 100644 index 000000000..2e0da3cf6 --- /dev/null +++ b/src/include/DuiCollator @@ -0,0 +1 @@ +#include "duicollator.h" diff --git a/src/include/DuiComboBox b/src/include/DuiComboBox new file mode 100644 index 000000000..a379a784a --- /dev/null +++ b/src/include/DuiComboBox @@ -0,0 +1,2 @@ +#include "duicombobox.h" + diff --git a/src/include/DuiCompleter b/src/include/DuiCompleter new file mode 100644 index 000000000..977f971bb --- /dev/null +++ b/src/include/DuiCompleter @@ -0,0 +1 @@ +#include "duicompleter.h" diff --git a/src/include/DuiCompleterView b/src/include/DuiCompleterView new file mode 100644 index 000000000..5deabca7b --- /dev/null +++ b/src/include/DuiCompleterView @@ -0,0 +1 @@ +#include "duicompleterview.h" diff --git a/src/include/DuiComponentData b/src/include/DuiComponentData new file mode 100644 index 000000000..237c71708 --- /dev/null +++ b/src/include/DuiComponentData @@ -0,0 +1 @@ +#include "duicomponentdata.h" diff --git a/src/include/DuiContainer b/src/include/DuiContainer new file mode 100644 index 000000000..bc6c10653 --- /dev/null +++ b/src/include/DuiContainer @@ -0,0 +1 @@ +#include "duicontainer.h" diff --git a/src/include/DuiContainerView b/src/include/DuiContainerView new file mode 100644 index 000000000..62934e54d --- /dev/null +++ b/src/include/DuiContainerView @@ -0,0 +1,2 @@ +#include "duicontainerview.h" + diff --git a/src/include/DuiContentItem b/src/include/DuiContentItem new file mode 100644 index 000000000..aa06f2cc0 --- /dev/null +++ b/src/include/DuiContentItem @@ -0,0 +1 @@ +#include "duicontentitem.h" \ No newline at end of file diff --git a/src/include/DuiDataAccess b/src/include/DuiDataAccess new file mode 100644 index 000000000..7d1fbb641 --- /dev/null +++ b/src/include/DuiDataAccess @@ -0,0 +1 @@ +#include "duidataaccess.h" diff --git a/src/include/DuiDataStore b/src/include/DuiDataStore new file mode 100644 index 000000000..dcc1f0833 --- /dev/null +++ b/src/include/DuiDataStore @@ -0,0 +1 @@ +#include "duidatastore.h" diff --git a/src/include/DuiDebug b/src/include/DuiDebug new file mode 100644 index 000000000..10d9f16c1 --- /dev/null +++ b/src/include/DuiDebug @@ -0,0 +1 @@ +#include "duidebug.h" diff --git a/src/include/DuiDeclarativeSettings b/src/include/DuiDeclarativeSettings new file mode 100644 index 000000000..d61de6806 --- /dev/null +++ b/src/include/DuiDeclarativeSettings @@ -0,0 +1 @@ +#include "duisettingslanguagewidget.h" diff --git a/src/include/DuiDeclarativeSettingsBinary b/src/include/DuiDeclarativeSettingsBinary new file mode 100644 index 000000000..17600ba51 --- /dev/null +++ b/src/include/DuiDeclarativeSettingsBinary @@ -0,0 +1 @@ +#include "duisettingslanguagebinary.h" diff --git a/src/include/DuiDeclarativeSettingsFactory b/src/include/DuiDeclarativeSettingsFactory new file mode 100644 index 000000000..e2e249fdc --- /dev/null +++ b/src/include/DuiDeclarativeSettingsFactory @@ -0,0 +1 @@ +#include "duisettingslanguagewidgetfactory.h" diff --git a/src/include/DuiDeclarativeSettingsParser b/src/include/DuiDeclarativeSettingsParser new file mode 100644 index 000000000..894a65f2d --- /dev/null +++ b/src/include/DuiDeclarativeSettingsParser @@ -0,0 +1 @@ +#include "duisettingslanguageparser.h" diff --git a/src/include/DuiDesktopEntry b/src/include/DuiDesktopEntry new file mode 100644 index 000000000..1a88ed934 --- /dev/null +++ b/src/include/DuiDesktopEntry @@ -0,0 +1,2 @@ +#include "duidesktopentry.h" + diff --git a/src/include/DuiDeviceProfile b/src/include/DuiDeviceProfile new file mode 100644 index 000000000..20fc28e83 --- /dev/null +++ b/src/include/DuiDeviceProfile @@ -0,0 +1 @@ +#include "duideviceprofile.h" diff --git a/src/include/DuiDialog b/src/include/DuiDialog new file mode 100644 index 000000000..cf0e5e1a7 --- /dev/null +++ b/src/include/DuiDialog @@ -0,0 +1,2 @@ +#include "duidialog.h" + diff --git a/src/include/DuiDismissEvent b/src/include/DuiDismissEvent new file mode 100644 index 000000000..fa51713da --- /dev/null +++ b/src/include/DuiDismissEvent @@ -0,0 +1 @@ +#include "duidismissevent.h" diff --git a/src/include/DuiEscapeButtonPanel b/src/include/DuiEscapeButtonPanel new file mode 100644 index 000000000..9251bcb1e --- /dev/null +++ b/src/include/DuiEscapeButtonPanel @@ -0,0 +1 @@ +#include "duiescapebuttonpanel.h" diff --git a/src/include/DuiExport b/src/include/DuiExport new file mode 100644 index 000000000..b813ab8e0 --- /dev/null +++ b/src/include/DuiExport @@ -0,0 +1 @@ +#include "duiexport.h" diff --git a/src/include/DuiExtendingBackgroundStyle b/src/include/DuiExtendingBackgroundStyle new file mode 100644 index 000000000..f7e56993e --- /dev/null +++ b/src/include/DuiExtendingBackgroundStyle @@ -0,0 +1,2 @@ +#include "duiextendingbackgroundstyle.h" + diff --git a/src/include/DuiFeedback b/src/include/DuiFeedback new file mode 100644 index 000000000..e03b3d353 --- /dev/null +++ b/src/include/DuiFeedback @@ -0,0 +1 @@ +#include "duifeedback.h" diff --git a/src/include/DuiFeedbackPlayer b/src/include/DuiFeedbackPlayer new file mode 100644 index 000000000..9e34f9ccc --- /dev/null +++ b/src/include/DuiFeedbackPlayer @@ -0,0 +1 @@ +#include "duifeedbackplayer.h" diff --git a/src/include/DuiFlowLayoutPolicy b/src/include/DuiFlowLayoutPolicy new file mode 100644 index 000000000..a0d879aa0 --- /dev/null +++ b/src/include/DuiFlowLayoutPolicy @@ -0,0 +1,2 @@ +#include "duiflowlayoutpolicy.h" + diff --git a/src/include/DuiFreestyleLayoutPolicy b/src/include/DuiFreestyleLayoutPolicy new file mode 100644 index 000000000..ac8ecc96f --- /dev/null +++ b/src/include/DuiFreestyleLayoutPolicy @@ -0,0 +1,2 @@ +#include "duifreestylelayoutpolicy.h" + diff --git a/src/include/DuiGConfDataStore b/src/include/DuiGConfDataStore new file mode 100644 index 000000000..2485f1c1b --- /dev/null +++ b/src/include/DuiGConfDataStore @@ -0,0 +1 @@ +#include "duigconfdatastore.h" diff --git a/src/include/DuiGConfItem b/src/include/DuiGConfItem new file mode 100644 index 000000000..99bd3c496 --- /dev/null +++ b/src/include/DuiGConfItem @@ -0,0 +1 @@ +#include "duigconfitem.h" diff --git a/src/include/DuiGLES2Renderer b/src/include/DuiGLES2Renderer new file mode 100644 index 000000000..f44ac62a9 --- /dev/null +++ b/src/include/DuiGLES2Renderer @@ -0,0 +1 @@ +#include "duigles2renderer.h" diff --git a/src/include/DuiGLRenderer b/src/include/DuiGLRenderer new file mode 100644 index 000000000..d71bf5667 --- /dev/null +++ b/src/include/DuiGLRenderer @@ -0,0 +1 @@ +#include "duiglrenderer.h" diff --git a/src/include/DuiGLShader b/src/include/DuiGLShader new file mode 100644 index 000000000..4a41510e9 --- /dev/null +++ b/src/include/DuiGLShader @@ -0,0 +1 @@ +#include "duiglshader.h" diff --git a/src/include/DuiGLShaderProgram b/src/include/DuiGLShaderProgram new file mode 100644 index 000000000..9f2c76665 --- /dev/null +++ b/src/include/DuiGLShaderProgram @@ -0,0 +1 @@ +#include "duiglshaderprogram.h" diff --git a/src/include/DuiGLShaderUniform b/src/include/DuiGLShaderUniform new file mode 100644 index 000000000..860129907 --- /dev/null +++ b/src/include/DuiGLShaderUniform @@ -0,0 +1 @@ +#include "duiglshaderuniform.h" diff --git a/src/include/DuiGridItem b/src/include/DuiGridItem new file mode 100644 index 000000000..2b3e18c60 --- /dev/null +++ b/src/include/DuiGridItem @@ -0,0 +1 @@ +#include "duigriditem.h" diff --git a/src/include/DuiGridLayoutPolicy b/src/include/DuiGridLayoutPolicy new file mode 100644 index 000000000..95de41804 --- /dev/null +++ b/src/include/DuiGridLayoutPolicy @@ -0,0 +1,2 @@ +#include "duigridlayoutpolicy.h" + diff --git a/src/include/DuiGroupAnimation b/src/include/DuiGroupAnimation new file mode 100644 index 000000000..ee8cf29a9 --- /dev/null +++ b/src/include/DuiGroupAnimation @@ -0,0 +1 @@ +#include "duigroupanimation.h" diff --git a/src/include/DuiGroupAnimationStyle b/src/include/DuiGroupAnimationStyle new file mode 100644 index 000000000..d380281a0 --- /dev/null +++ b/src/include/DuiGroupAnimationStyle @@ -0,0 +1,2 @@ +#include "duigroupanimationstyle.h" + diff --git a/src/include/DuiHomeButtonPanel b/src/include/DuiHomeButtonPanel new file mode 100644 index 000000000..c5c1591f6 --- /dev/null +++ b/src/include/DuiHomeButtonPanel @@ -0,0 +1 @@ +#include "duihomebuttonpanel.h" diff --git a/src/include/DuiImageWidget b/src/include/DuiImageWidget new file mode 100644 index 000000000..6de85d5dd --- /dev/null +++ b/src/include/DuiImageWidget @@ -0,0 +1 @@ +#include "duiimagewidget.h" diff --git a/src/include/DuiImageWidgetView b/src/include/DuiImageWidgetView new file mode 100644 index 000000000..d904f7bba --- /dev/null +++ b/src/include/DuiImageWidgetView @@ -0,0 +1,2 @@ +#include "duiimagewidgetview.h" + diff --git a/src/include/DuiInfoBanner b/src/include/DuiInfoBanner new file mode 100644 index 000000000..7e06f79c3 --- /dev/null +++ b/src/include/DuiInfoBanner @@ -0,0 +1,2 @@ +#include "duiinfobanner.h" + diff --git a/src/include/DuiInfoBannerEventView b/src/include/DuiInfoBannerEventView new file mode 100644 index 000000000..4f13a863b --- /dev/null +++ b/src/include/DuiInfoBannerEventView @@ -0,0 +1,2 @@ +#include "duiinfobannereventview.h" + diff --git a/src/include/DuiInfoBannerInformationView b/src/include/DuiInfoBannerInformationView new file mode 100644 index 000000000..53c848f4a --- /dev/null +++ b/src/include/DuiInfoBannerInformationView @@ -0,0 +1,2 @@ +#include "duiinfobannerinformationview.h" + diff --git a/src/include/DuiInfoBannerView b/src/include/DuiInfoBannerView new file mode 100644 index 000000000..39c6d537f --- /dev/null +++ b/src/include/DuiInfoBannerView @@ -0,0 +1,2 @@ +#include "duiinfobannerview.h" + diff --git a/src/include/DuiInputMethodState b/src/include/DuiInputMethodState new file mode 100644 index 000000000..df628f12d --- /dev/null +++ b/src/include/DuiInputMethodState @@ -0,0 +1 @@ +#include "duiinputmethodstate.h" diff --git a/src/include/DuiLabel b/src/include/DuiLabel new file mode 100644 index 000000000..4a855ecf4 --- /dev/null +++ b/src/include/DuiLabel @@ -0,0 +1 @@ +#include "duilabel.h" diff --git a/src/include/DuiLabelHighlighter b/src/include/DuiLabelHighlighter new file mode 100644 index 000000000..fe221389b --- /dev/null +++ b/src/include/DuiLabelHighlighter @@ -0,0 +1 @@ +#include "duilabelhighlighter.h" diff --git a/src/include/DuiLabelView b/src/include/DuiLabelView new file mode 100644 index 000000000..7cfd0c638 --- /dev/null +++ b/src/include/DuiLabelView @@ -0,0 +1,2 @@ +#include "duilabelview.h" + diff --git a/src/include/DuiLayout b/src/include/DuiLayout new file mode 100644 index 000000000..ce42eb308 --- /dev/null +++ b/src/include/DuiLayout @@ -0,0 +1 @@ +#include "duilayout.h" diff --git a/src/include/DuiLayoutAnimation b/src/include/DuiLayoutAnimation new file mode 100644 index 000000000..29d60cebd --- /dev/null +++ b/src/include/DuiLayoutAnimation @@ -0,0 +1,2 @@ +#include "duilayoutanimation.h" + diff --git a/src/include/DuiLayoutAnimationStyle b/src/include/DuiLayoutAnimationStyle new file mode 100644 index 000000000..13c243ad1 --- /dev/null +++ b/src/include/DuiLayoutAnimationStyle @@ -0,0 +1 @@ +#include "duilayoutanimationstyle.h" diff --git a/src/include/DuiLibrary b/src/include/DuiLibrary new file mode 100644 index 000000000..1d91728ae --- /dev/null +++ b/src/include/DuiLibrary @@ -0,0 +1,2 @@ +#include "duilibrary.h" + diff --git a/src/include/DuiLinearLayoutPolicy b/src/include/DuiLinearLayoutPolicy new file mode 100644 index 000000000..ec0f706f9 --- /dev/null +++ b/src/include/DuiLinearLayoutPolicy @@ -0,0 +1,2 @@ +#include "duilinearlayoutpolicy.h" + diff --git a/src/include/DuiList b/src/include/DuiList new file mode 100644 index 000000000..080d0d77c --- /dev/null +++ b/src/include/DuiList @@ -0,0 +1,2 @@ +#include "duilist.h" + diff --git a/src/include/DuiListView b/src/include/DuiListView new file mode 100644 index 000000000..226fd7575 --- /dev/null +++ b/src/include/DuiListView @@ -0,0 +1,2 @@ +#include "duilistview.h" + diff --git a/src/include/DuiLocale b/src/include/DuiLocale new file mode 100644 index 000000000..3a3ee3017 --- /dev/null +++ b/src/include/DuiLocale @@ -0,0 +1 @@ +#include "duilocale.h" diff --git a/src/include/DuiMashupCanvas b/src/include/DuiMashupCanvas new file mode 100644 index 000000000..63fae9575 --- /dev/null +++ b/src/include/DuiMashupCanvas @@ -0,0 +1 @@ +#include "duimashupcanvas.h" diff --git a/src/include/DuiMenuObjectView b/src/include/DuiMenuObjectView new file mode 100644 index 000000000..727bd4346 --- /dev/null +++ b/src/include/DuiMenuObjectView @@ -0,0 +1,2 @@ +#include "duimenuobjectview.h" + diff --git a/src/include/DuiMessageBox b/src/include/DuiMessageBox new file mode 100644 index 000000000..4062fb56a --- /dev/null +++ b/src/include/DuiMessageBox @@ -0,0 +1,2 @@ +#include "duimessagebox.h" + diff --git a/src/include/DuiMessageBoxView b/src/include/DuiMessageBoxView new file mode 100644 index 000000000..86e35309a --- /dev/null +++ b/src/include/DuiMessageBoxView @@ -0,0 +1,2 @@ +#include "duimessageboxview.h" + diff --git a/src/include/DuiModalSceneWindow b/src/include/DuiModalSceneWindow new file mode 100644 index 000000000..98366e6a4 --- /dev/null +++ b/src/include/DuiModalSceneWindow @@ -0,0 +1,2 @@ +#include "duimodalscenewindow.h" + diff --git a/src/include/DuiMultiLayout b/src/include/DuiMultiLayout new file mode 100644 index 000000000..c7576030d --- /dev/null +++ b/src/include/DuiMultiLayout @@ -0,0 +1,2 @@ +#include "duimultilayout.h" + diff --git a/src/include/DuiNamespace b/src/include/DuiNamespace new file mode 100644 index 000000000..bdb804f10 --- /dev/null +++ b/src/include/DuiNamespace @@ -0,0 +1,2 @@ +#include "duinamespace.h" + diff --git a/src/include/DuiNavigationBar b/src/include/DuiNavigationBar new file mode 100644 index 000000000..09a7b082a --- /dev/null +++ b/src/include/DuiNavigationBar @@ -0,0 +1,2 @@ +#include "duinavigationbar.h" + diff --git a/src/include/DuiNavigationBarView b/src/include/DuiNavigationBarView new file mode 100644 index 000000000..42358bd29 --- /dev/null +++ b/src/include/DuiNavigationBarView @@ -0,0 +1,2 @@ +#include "duinavigationbarview.h" + diff --git a/src/include/DuiNotification b/src/include/DuiNotification new file mode 100644 index 000000000..22fe914c5 --- /dev/null +++ b/src/include/DuiNotification @@ -0,0 +1,2 @@ +#include "duinotification.h" + diff --git a/src/include/DuiNotificationGroup b/src/include/DuiNotificationGroup new file mode 100644 index 000000000..fab1369a1 --- /dev/null +++ b/src/include/DuiNotificationGroup @@ -0,0 +1,2 @@ +#include "duinotificationgroup.h" + diff --git a/src/include/DuiOnDisplayChangeEvent b/src/include/DuiOnDisplayChangeEvent new file mode 100644 index 000000000..054175084 --- /dev/null +++ b/src/include/DuiOnDisplayChangeEvent @@ -0,0 +1 @@ +#include "duiondisplaychangeevent.h" diff --git a/src/include/DuiOrientationChangeEvent b/src/include/DuiOrientationChangeEvent new file mode 100644 index 000000000..558e0970a --- /dev/null +++ b/src/include/DuiOrientationChangeEvent @@ -0,0 +1 @@ +#include "duiorientationchangeevent.h" diff --git a/src/include/DuiOverlay b/src/include/DuiOverlay new file mode 100644 index 000000000..f06d228bf --- /dev/null +++ b/src/include/DuiOverlay @@ -0,0 +1 @@ +#include "duioverlay.h" diff --git a/src/include/DuiOverlayView b/src/include/DuiOverlayView new file mode 100644 index 000000000..a9f6ec81c --- /dev/null +++ b/src/include/DuiOverlayView @@ -0,0 +1,2 @@ +#include "duioverlayview.h" + diff --git a/src/include/DuiPannableViewport b/src/include/DuiPannableViewport new file mode 100644 index 000000000..f0aa2f764 --- /dev/null +++ b/src/include/DuiPannableViewport @@ -0,0 +1 @@ +#include "duipannableviewport.h" diff --git a/src/include/DuiPannableWidget b/src/include/DuiPannableWidget new file mode 100644 index 000000000..b430f122c --- /dev/null +++ b/src/include/DuiPannableWidget @@ -0,0 +1 @@ +#include "duipannablewidget.h" diff --git a/src/include/DuiPannableWidgetView b/src/include/DuiPannableWidgetView new file mode 100644 index 000000000..358c6dca3 --- /dev/null +++ b/src/include/DuiPannableWidgetView @@ -0,0 +1,2 @@ +#include "duipannablewidgetview.h" + diff --git a/src/include/DuiPathLayout b/src/include/DuiPathLayout new file mode 100644 index 000000000..10a39127e --- /dev/null +++ b/src/include/DuiPathLayout @@ -0,0 +1,2 @@ +#include "duipathlayout.h" + diff --git a/src/include/DuiPhysics2DPanning b/src/include/DuiPhysics2DPanning new file mode 100644 index 000000000..a0826afe9 --- /dev/null +++ b/src/include/DuiPhysics2DPanning @@ -0,0 +1,2 @@ +#include "duiphysics2dpanning.h" + diff --git a/src/include/DuiPopupList b/src/include/DuiPopupList new file mode 100644 index 000000000..c95169ab3 --- /dev/null +++ b/src/include/DuiPopupList @@ -0,0 +1 @@ +#include "duipopuplist.h" diff --git a/src/include/DuiPopupListView b/src/include/DuiPopupListView new file mode 100644 index 000000000..358b369d4 --- /dev/null +++ b/src/include/DuiPopupListView @@ -0,0 +1 @@ +#include "duipopuplistview.h" diff --git a/src/include/DuiPositionIndicator b/src/include/DuiPositionIndicator new file mode 100644 index 000000000..ac5b42bb9 --- /dev/null +++ b/src/include/DuiPositionIndicator @@ -0,0 +1 @@ +#include "duipositionindicator.h" diff --git a/src/include/DuiPositionIndicatorView b/src/include/DuiPositionIndicatorView new file mode 100644 index 000000000..f153c4f2a --- /dev/null +++ b/src/include/DuiPositionIndicatorView @@ -0,0 +1,2 @@ +#include "duipositionindicatorview.h" + diff --git a/src/include/DuiPreeditInjectionEvent b/src/include/DuiPreeditInjectionEvent new file mode 100644 index 000000000..555c68adf --- /dev/null +++ b/src/include/DuiPreeditInjectionEvent @@ -0,0 +1,2 @@ +#include "duipreeditinjectionevent.h" + diff --git a/src/include/DuiProgressIndicator b/src/include/DuiProgressIndicator new file mode 100644 index 000000000..a8973b7ad --- /dev/null +++ b/src/include/DuiProgressIndicator @@ -0,0 +1 @@ +#include "duiprogressindicator.h" diff --git a/src/include/DuiProgressIndicatorBarView b/src/include/DuiProgressIndicatorBarView new file mode 100644 index 000000000..8b7a62837 --- /dev/null +++ b/src/include/DuiProgressIndicatorBarView @@ -0,0 +1 @@ +#include "duiprogressindicatorbarview.h" diff --git a/src/include/DuiProgressIndicatorCircularView b/src/include/DuiProgressIndicatorCircularView new file mode 100644 index 000000000..ee15844ff --- /dev/null +++ b/src/include/DuiProgressIndicatorCircularView @@ -0,0 +1 @@ +#include "duiprogressindicatorcircularview.h" diff --git a/src/include/DuiRemoteAction b/src/include/DuiRemoteAction new file mode 100644 index 000000000..13a277326 --- /dev/null +++ b/src/include/DuiRemoteAction @@ -0,0 +1,2 @@ +#include "duiremoteaction.h" + diff --git a/src/include/DuiRmiClient b/src/include/DuiRmiClient new file mode 100644 index 000000000..d87ac7c9c --- /dev/null +++ b/src/include/DuiRmiClient @@ -0,0 +1,2 @@ +#include "duirmiclient.h" + diff --git a/src/include/DuiRmiServer b/src/include/DuiRmiServer new file mode 100644 index 000000000..1f24d6c06 --- /dev/null +++ b/src/include/DuiRmiServer @@ -0,0 +1,2 @@ +#include "duirmiserver.h" + diff --git a/src/include/DuiScalableImage b/src/include/DuiScalableImage new file mode 100644 index 000000000..05859c5b2 --- /dev/null +++ b/src/include/DuiScalableImage @@ -0,0 +1 @@ +#include "duiscalableimage.h" diff --git a/src/include/DuiScene b/src/include/DuiScene new file mode 100644 index 000000000..f8e3aaba5 --- /dev/null +++ b/src/include/DuiScene @@ -0,0 +1,2 @@ +#include "duiscene.h" + diff --git a/src/include/DuiSceneLayerEffect b/src/include/DuiSceneLayerEffect new file mode 100644 index 000000000..c76fedebb --- /dev/null +++ b/src/include/DuiSceneLayerEffect @@ -0,0 +1,2 @@ +#include "duiscenelayereffect.h" + diff --git a/src/include/DuiSceneManager b/src/include/DuiSceneManager new file mode 100644 index 000000000..13e6b8ea0 --- /dev/null +++ b/src/include/DuiSceneManager @@ -0,0 +1,2 @@ +#include "duiscenemanager.h" + diff --git a/src/include/DuiSceneWindow b/src/include/DuiSceneWindow new file mode 100644 index 000000000..24ebce63f --- /dev/null +++ b/src/include/DuiSceneWindow @@ -0,0 +1,2 @@ +#include "duiscenewindow.h" + diff --git a/src/include/DuiSceneWindowAnimator b/src/include/DuiSceneWindowAnimator new file mode 100644 index 000000000..a9bd861fd --- /dev/null +++ b/src/include/DuiSceneWindowAnimator @@ -0,0 +1,2 @@ +#include "duiscenewindowanimator.h" + diff --git a/src/include/DuiSeekBar b/src/include/DuiSeekBar new file mode 100644 index 000000000..ecf78a118 --- /dev/null +++ b/src/include/DuiSeekBar @@ -0,0 +1,2 @@ +#include "duiseekbar.h" + diff --git a/src/include/DuiSeparator b/src/include/DuiSeparator new file mode 100644 index 000000000..fdff35381 --- /dev/null +++ b/src/include/DuiSeparator @@ -0,0 +1 @@ +#include "duiseparator.h" diff --git a/src/include/DuiServiceFwBaseIf b/src/include/DuiServiceFwBaseIf new file mode 100644 index 000000000..edf2b1cd0 --- /dev/null +++ b/src/include/DuiServiceFwBaseIf @@ -0,0 +1 @@ +#include "duiservicefwbaseif.h" diff --git a/src/include/DuiServiceFwProxy b/src/include/DuiServiceFwProxy new file mode 100644 index 000000000..6c8818111 --- /dev/null +++ b/src/include/DuiServiceFwProxy @@ -0,0 +1 @@ +#include "duiservicefwproxy.h" diff --git a/src/include/DuiSettingsLanguageBinary b/src/include/DuiSettingsLanguageBinary new file mode 100644 index 000000000..17600ba51 --- /dev/null +++ b/src/include/DuiSettingsLanguageBinary @@ -0,0 +1 @@ +#include "duisettingslanguagebinary.h" diff --git a/src/include/DuiSettingsLanguageParser b/src/include/DuiSettingsLanguageParser new file mode 100644 index 000000000..894a65f2d --- /dev/null +++ b/src/include/DuiSettingsLanguageParser @@ -0,0 +1 @@ +#include "duisettingslanguageparser.h" diff --git a/src/include/DuiSettingsLanguageWidget b/src/include/DuiSettingsLanguageWidget new file mode 100644 index 000000000..d61de6806 --- /dev/null +++ b/src/include/DuiSettingsLanguageWidget @@ -0,0 +1 @@ +#include "duisettingslanguagewidget.h" diff --git a/src/include/DuiSettingsLanguageWidgetFactory b/src/include/DuiSettingsLanguageWidgetFactory new file mode 100644 index 000000000..e2e249fdc --- /dev/null +++ b/src/include/DuiSettingsLanguageWidgetFactory @@ -0,0 +1 @@ +#include "duisettingslanguagewidgetfactory.h" diff --git a/src/include/DuiSlider b/src/include/DuiSlider new file mode 100644 index 000000000..b94b70a22 --- /dev/null +++ b/src/include/DuiSlider @@ -0,0 +1 @@ +#include "duislider.h" diff --git a/src/include/DuiSliderContinuousView b/src/include/DuiSliderContinuousView new file mode 100644 index 000000000..fa1b35835 --- /dev/null +++ b/src/include/DuiSliderContinuousView @@ -0,0 +1,2 @@ +#include "duislidercontinuousview.h" + diff --git a/src/include/DuiSliderView b/src/include/DuiSliderView new file mode 100644 index 000000000..decae815e --- /dev/null +++ b/src/include/DuiSliderView @@ -0,0 +1,2 @@ +#include "duisliderview.h" + diff --git a/src/include/DuiStylableWidget b/src/include/DuiStylableWidget new file mode 100644 index 000000000..340194f1a --- /dev/null +++ b/src/include/DuiStylableWidget @@ -0,0 +1 @@ +#include "duistylablewidget.h" diff --git a/src/include/DuiStyle b/src/include/DuiStyle new file mode 100644 index 000000000..7c412c7ac --- /dev/null +++ b/src/include/DuiStyle @@ -0,0 +1 @@ +#include "duistyle.h" diff --git a/src/include/DuiStyleCreator b/src/include/DuiStyleCreator new file mode 100644 index 000000000..63fad4dbb --- /dev/null +++ b/src/include/DuiStyleCreator @@ -0,0 +1 @@ +#include "duistylecreator.h" diff --git a/src/include/DuiStyleDescription b/src/include/DuiStyleDescription new file mode 100644 index 000000000..8d63b7a6d --- /dev/null +++ b/src/include/DuiStyleDescription @@ -0,0 +1 @@ +#include "duistyledescription.h" diff --git a/src/include/DuiTextEdit b/src/include/DuiTextEdit new file mode 100644 index 000000000..8c6e1ed8e --- /dev/null +++ b/src/include/DuiTextEdit @@ -0,0 +1 @@ +#include "duitextedit.h" diff --git a/src/include/DuiTextEditView b/src/include/DuiTextEditView new file mode 100644 index 000000000..53cb76e69 --- /dev/null +++ b/src/include/DuiTextEditView @@ -0,0 +1,2 @@ +#include "duitexteditview.h" + diff --git a/src/include/DuiTheme b/src/include/DuiTheme new file mode 100644 index 000000000..fd714ee14 --- /dev/null +++ b/src/include/DuiTheme @@ -0,0 +1 @@ +#include "duitheme.h" diff --git a/src/include/DuiTimestamp b/src/include/DuiTimestamp new file mode 100644 index 000000000..1b5284ae8 --- /dev/null +++ b/src/include/DuiTimestamp @@ -0,0 +1 @@ +#include "duitimestamp.h" diff --git a/src/include/DuiToolBar b/src/include/DuiToolBar new file mode 100644 index 000000000..fd1b42346 --- /dev/null +++ b/src/include/DuiToolBar @@ -0,0 +1,2 @@ +#include "duitoolbar.h" + diff --git a/src/include/DuiToolBarView b/src/include/DuiToolBarView new file mode 100644 index 000000000..965e794dd --- /dev/null +++ b/src/include/DuiToolBarView @@ -0,0 +1,2 @@ +#include "duitoolbarview.h" + diff --git a/src/include/DuiVideoWidget b/src/include/DuiVideoWidget new file mode 100644 index 000000000..855a31562 --- /dev/null +++ b/src/include/DuiVideoWidget @@ -0,0 +1 @@ +#include "duivideowidget.h" diff --git a/src/include/DuiViewCreator b/src/include/DuiViewCreator new file mode 100644 index 000000000..83fa45f08 --- /dev/null +++ b/src/include/DuiViewCreator @@ -0,0 +1 @@ +#include "duiviewcreator.h" diff --git a/src/include/DuiWidget b/src/include/DuiWidget new file mode 100644 index 000000000..97106f9bf --- /dev/null +++ b/src/include/DuiWidget @@ -0,0 +1 @@ +#include "duiwidget.h" diff --git a/src/include/DuiWidgetAction b/src/include/DuiWidgetAction new file mode 100644 index 000000000..0d28d9bc7 --- /dev/null +++ b/src/include/DuiWidgetAction @@ -0,0 +1,2 @@ +#include "duiwidgetaction.h" + diff --git a/src/include/DuiWidgetController b/src/include/DuiWidgetController new file mode 100644 index 000000000..0d07cff03 --- /dev/null +++ b/src/include/DuiWidgetController @@ -0,0 +1 @@ +#include "duiwidgetcontroller.h" diff --git a/src/include/DuiWidgetCreator b/src/include/DuiWidgetCreator new file mode 100644 index 000000000..efcbab370 --- /dev/null +++ b/src/include/DuiWidgetCreator @@ -0,0 +1 @@ +#include "duiwidgetcreator.h" diff --git a/src/include/DuiWidgetFadeInAnimationStyle b/src/include/DuiWidgetFadeInAnimationStyle new file mode 100644 index 000000000..8e634a669 --- /dev/null +++ b/src/include/DuiWidgetFadeInAnimationStyle @@ -0,0 +1 @@ +#include "duiwidgetfadeinanimationstyle.h" diff --git a/src/include/DuiWidgetFadeOutAnimationStyle b/src/include/DuiWidgetFadeOutAnimationStyle new file mode 100644 index 000000000..b2fc16a70 --- /dev/null +++ b/src/include/DuiWidgetFadeOutAnimationStyle @@ -0,0 +1,2 @@ +#include "duiwidgetfadeoutanimationstyle.h" + diff --git a/src/include/DuiWidgetListModel b/src/include/DuiWidgetListModel new file mode 100644 index 000000000..c2d24263b --- /dev/null +++ b/src/include/DuiWidgetListModel @@ -0,0 +1 @@ +#include "duiwidgetlistmodel.h" diff --git a/src/include/DuiWidgetModel b/src/include/DuiWidgetModel new file mode 100644 index 000000000..c940e2dfd --- /dev/null +++ b/src/include/DuiWidgetModel @@ -0,0 +1,2 @@ +#include "duiwidgetmodel.h" + diff --git a/src/include/DuiWidgetRecycler b/src/include/DuiWidgetRecycler new file mode 100644 index 000000000..0ef767827 --- /dev/null +++ b/src/include/DuiWidgetRecycler @@ -0,0 +1 @@ +#include "duiwidgetrecycler.h" diff --git a/src/include/DuiWidgetStyle b/src/include/DuiWidgetStyle new file mode 100644 index 000000000..25fa4770b --- /dev/null +++ b/src/include/DuiWidgetStyle @@ -0,0 +1,2 @@ +#include "duiwidgetstyle.h" + diff --git a/src/include/DuiWidgetView b/src/include/DuiWidgetView new file mode 100644 index 000000000..965cb6714 --- /dev/null +++ b/src/include/DuiWidgetView @@ -0,0 +1,2 @@ +#include "duiwidgetview.h" + diff --git a/src/include/DuiWindow b/src/include/DuiWindow new file mode 100644 index 000000000..0e4d3ed61 --- /dev/null +++ b/src/include/DuiWindow @@ -0,0 +1 @@ +#include "duiwindow.h" diff --git a/src/include/TestabilityInterface b/src/include/TestabilityInterface new file mode 100644 index 000000000..240a2dd4c --- /dev/null +++ b/src/include/TestabilityInterface @@ -0,0 +1,2 @@ +#include "../core/testabilityinterface.h" + diff --git a/src/include/duiabstractcellcreator.h b/src/include/duiabstractcellcreator.h new file mode 100644 index 000000000..63a9e52af --- /dev/null +++ b/src/include/duiabstractcellcreator.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duiabstractcellcreator.h" + diff --git a/src/include/duiabstractlayoutpolicy.h b/src/include/duiabstractlayoutpolicy.h new file mode 100644 index 000000000..6b32437e5 --- /dev/null +++ b/src/include/duiabstractlayoutpolicy.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../layout/duiabstractlayoutpolicy.h" + diff --git a/src/include/duiabstractlayoutpolicystyle.h b/src/include/duiabstractlayoutpolicystyle.h new file mode 100644 index 000000000..2e343e2bb --- /dev/null +++ b/src/include/duiabstractlayoutpolicystyle.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../style/duiabstractlayoutpolicystyle.h" + diff --git a/src/include/duiabstractwidgetanimationstyle.h b/src/include/duiabstractwidgetanimationstyle.h new file mode 100644 index 000000000..a2d4e307c --- /dev/null +++ b/src/include/duiabstractwidgetanimationstyle.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../style/duiabstractwidgetanimationstyle.h" diff --git a/src/include/duiaction.h b/src/include/duiaction.h new file mode 100644 index 000000000..7b33fb204 --- /dev/null +++ b/src/include/duiaction.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../core/duiaction.h" + diff --git a/src/include/duiactionprovider.h b/src/include/duiactionprovider.h new file mode 100644 index 000000000..cff650b9c --- /dev/null +++ b/src/include/duiactionprovider.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../service/duiactionprovider.h" diff --git a/src/include/duianimation.h b/src/include/duianimation.h new file mode 100644 index 000000000..e6b8ef2a9 --- /dev/null +++ b/src/include/duianimation.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../animation/core/duianimation.h" + diff --git a/src/include/duianimationcreator.h b/src/include/duianimationcreator.h new file mode 100644 index 000000000..c052b5b6d --- /dev/null +++ b/src/include/duianimationcreator.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../animation/core/duianimationcreator.h" + diff --git a/src/include/duianimationstyle.h b/src/include/duianimationstyle.h new file mode 100644 index 000000000..eb789b6ca --- /dev/null +++ b/src/include/duianimationstyle.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../style/duianimationstyle.h" + diff --git a/src/include/duiappletinstallationsourceinterface.h b/src/include/duiappletinstallationsourceinterface.h new file mode 100644 index 000000000..50297bad2 --- /dev/null +++ b/src/include/duiappletinstallationsourceinterface.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../mashup/appletinstallation/duiappletinstallationsourceinterface.h" diff --git a/src/include/duiappletinstantiator.h b/src/include/duiappletinstantiator.h new file mode 100644 index 000000000..69c6fdce6 --- /dev/null +++ b/src/include/duiappletinstantiator.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../mashup/appletinstallation/duiappletinstantiator.h" diff --git a/src/include/duiappletinterface.h b/src/include/duiappletinterface.h new file mode 100644 index 000000000..f21ef5c28 --- /dev/null +++ b/src/include/duiappletinterface.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../mashup/appletinterface/duiappletinterface.h" diff --git a/src/include/duiappletmetadata.h b/src/include/duiappletmetadata.h new file mode 100644 index 000000000..479de849c --- /dev/null +++ b/src/include/duiappletmetadata.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../mashup/appletinterface/duiappletmetadata.h" diff --git a/src/include/duiapplication.h b/src/include/duiapplication.h new file mode 100644 index 000000000..538bca102 --- /dev/null +++ b/src/include/duiapplication.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../core/duiapplication.h" diff --git a/src/include/duiapplicationextensionarea.h b/src/include/duiapplicationextensionarea.h new file mode 100644 index 000000000..06eebabf2 --- /dev/null +++ b/src/include/duiapplicationextensionarea.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../applicationextension/duiapplicationextensionarea.h" diff --git a/src/include/duiapplicationextensionareamodel.h b/src/include/duiapplicationextensionareamodel.h new file mode 100644 index 000000000..dba47101c --- /dev/null +++ b/src/include/duiapplicationextensionareamodel.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../applicationextension/duiapplicationextensionareamodel.h" diff --git a/src/include/duiapplicationifadaptor.h b/src/include/duiapplicationifadaptor.h new file mode 100644 index 000000000..16bb8ac26 --- /dev/null +++ b/src/include/duiapplicationifadaptor.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../core/duiapplicationifadaptor.h" diff --git a/src/include/duiapplicationifproxy.h b/src/include/duiapplicationifproxy.h new file mode 100644 index 000000000..ef1a50e13 --- /dev/null +++ b/src/include/duiapplicationifproxy.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../core/duiapplicationifproxy.h" diff --git a/src/include/duiapplicationmenu.h b/src/include/duiapplicationmenu.h new file mode 100644 index 000000000..e4a7eebd4 --- /dev/null +++ b/src/include/duiapplicationmenu.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duiapplicationmenu.h" + diff --git a/src/include/duiapplicationmenubuttonstyle.h b/src/include/duiapplicationmenubuttonstyle.h new file mode 100644 index 000000000..5bf4881bd --- /dev/null +++ b/src/include/duiapplicationmenubuttonstyle.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../style/duiapplicationmenubuttonstyle.h" diff --git a/src/include/duiapplicationmenumodel.h b/src/include/duiapplicationmenumodel.h new file mode 100644 index 000000000..22b098b3c --- /dev/null +++ b/src/include/duiapplicationmenumodel.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duiapplicationmenumodel.h" + diff --git a/src/include/duiapplicationmenustyle.h b/src/include/duiapplicationmenustyle.h new file mode 100644 index 000000000..8ceb9e0f5 --- /dev/null +++ b/src/include/duiapplicationmenustyle.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../style/duiapplicationmenustyle.h" diff --git a/src/include/duiapplicationmenuview.h b/src/include/duiapplicationmenuview.h new file mode 100644 index 000000000..fb4d8ac1c --- /dev/null +++ b/src/include/duiapplicationmenuview.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/views/duiapplicationmenuview.h" + diff --git a/src/include/duiapplicationpage.h b/src/include/duiapplicationpage.h new file mode 100644 index 000000000..aacf053fe --- /dev/null +++ b/src/include/duiapplicationpage.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duiapplicationpage.h" + diff --git a/src/include/duiapplicationpagemodel.h b/src/include/duiapplicationpagemodel.h new file mode 100644 index 000000000..5b80a8890 --- /dev/null +++ b/src/include/duiapplicationpagemodel.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duiapplicationpagemodel.h" + diff --git a/src/include/duiapplicationpagestyle.h b/src/include/duiapplicationpagestyle.h new file mode 100644 index 000000000..f3eb10560 --- /dev/null +++ b/src/include/duiapplicationpagestyle.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../style/duiapplicationpagestyle.h" + diff --git a/src/include/duiapplicationservice.h b/src/include/duiapplicationservice.h new file mode 100644 index 000000000..c3c290581 --- /dev/null +++ b/src/include/duiapplicationservice.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../core/duiapplicationservice.h" diff --git a/src/include/duiapplicationwindow.h b/src/include/duiapplicationwindow.h new file mode 100644 index 000000000..a272db48d --- /dev/null +++ b/src/include/duiapplicationwindow.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duiapplicationwindow.h" diff --git a/src/include/duiassembly.h b/src/include/duiassembly.h new file mode 100644 index 000000000..bcff91d68 --- /dev/null +++ b/src/include/duiassembly.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../core/duiassembly.h" + diff --git a/src/include/duibasiclayoutanimation.h b/src/include/duibasiclayoutanimation.h new file mode 100644 index 000000000..c3f4f092f --- /dev/null +++ b/src/include/duibasiclayoutanimation.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../layout/duibasiclayoutanimation.h" + diff --git a/src/include/duibasiclayoutanimationstyle.h b/src/include/duibasiclayoutanimationstyle.h new file mode 100644 index 000000000..03192dace --- /dev/null +++ b/src/include/duibasiclayoutanimationstyle.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../style/duibasiclayoutanimationstyle.h" diff --git a/src/include/duibreakiterator.h b/src/include/duibreakiterator.h new file mode 100644 index 000000000..a3a6c8096 --- /dev/null +++ b/src/include/duibreakiterator.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../i18n/duibreakiterator.h" + diff --git a/src/include/duibutton.h b/src/include/duibutton.h new file mode 100644 index 000000000..794f2a392 --- /dev/null +++ b/src/include/duibutton.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duibutton.h" diff --git a/src/include/duibuttongroup.h b/src/include/duibuttongroup.h new file mode 100644 index 000000000..0a820f7d5 --- /dev/null +++ b/src/include/duibuttongroup.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duibuttongroup.h" + diff --git a/src/include/duibuttoniconstyle.h b/src/include/duibuttoniconstyle.h new file mode 100644 index 000000000..c4e01729e --- /dev/null +++ b/src/include/duibuttoniconstyle.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../style/duibuttoniconstyle.h" + diff --git a/src/include/duibuttoniconview.h b/src/include/duibuttoniconview.h new file mode 100644 index 000000000..774a21f40 --- /dev/null +++ b/src/include/duibuttoniconview.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/views/duibuttoniconview.h" + diff --git a/src/include/duibuttonmodel.h b/src/include/duibuttonmodel.h new file mode 100644 index 000000000..03b97618d --- /dev/null +++ b/src/include/duibuttonmodel.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duibuttonmodel.h" + diff --git a/src/include/duibuttonstyle.h b/src/include/duibuttonstyle.h new file mode 100644 index 000000000..7f6b27b90 --- /dev/null +++ b/src/include/duibuttonstyle.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../style/duibuttonstyle.h" + diff --git a/src/include/duibuttonview.h b/src/include/duibuttonview.h new file mode 100644 index 000000000..140b16801 --- /dev/null +++ b/src/include/duibuttonview.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/views/duibuttonview.h" + diff --git a/src/include/duicalendar.h b/src/include/duicalendar.h new file mode 100644 index 000000000..191f41fce --- /dev/null +++ b/src/include/duicalendar.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../i18n/duicalendar.h" diff --git a/src/include/duicancelevent.h b/src/include/duicancelevent.h new file mode 100644 index 000000000..d7b9328c7 --- /dev/null +++ b/src/include/duicancelevent.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../events/duicancelevent.h" diff --git a/src/include/duicollator.h b/src/include/duicollator.h new file mode 100644 index 000000000..b9ce650ea --- /dev/null +++ b/src/include/duicollator.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../i18n/duicollator.h" diff --git a/src/include/duicombobox.h b/src/include/duicombobox.h new file mode 100644 index 000000000..df0cff733 --- /dev/null +++ b/src/include/duicombobox.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duicombobox.h" diff --git a/src/include/duicomboboxstyle.h b/src/include/duicomboboxstyle.h new file mode 100644 index 000000000..5bcdcf075 --- /dev/null +++ b/src/include/duicomboboxstyle.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../style/duicomboboxstyle.h" + diff --git a/src/include/duicompleter.h b/src/include/duicompleter.h new file mode 100644 index 000000000..571fc3379 --- /dev/null +++ b/src/include/duicompleter.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duicompleter.h" diff --git a/src/include/duicompletermodel.h b/src/include/duicompletermodel.h new file mode 100644 index 000000000..25725871c --- /dev/null +++ b/src/include/duicompletermodel.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duicompletermodel.h" + diff --git a/src/include/duicompleterview.h b/src/include/duicompleterview.h new file mode 100644 index 000000000..3b4ceb54c --- /dev/null +++ b/src/include/duicompleterview.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/views/duicompleterview.h" diff --git a/src/include/duicomponentdata.h b/src/include/duicomponentdata.h new file mode 100644 index 000000000..31cb68204 --- /dev/null +++ b/src/include/duicomponentdata.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../core/duicomponentdata.h" diff --git a/src/include/duicontainer.h b/src/include/duicontainer.h new file mode 100644 index 000000000..2910c5fdf --- /dev/null +++ b/src/include/duicontainer.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duicontainer.h" diff --git a/src/include/duicontainermodel.h b/src/include/duicontainermodel.h new file mode 100644 index 000000000..a82dda107 --- /dev/null +++ b/src/include/duicontainermodel.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duicontainermodel.h" + diff --git a/src/include/duicontainerstyle.h b/src/include/duicontainerstyle.h new file mode 100644 index 000000000..236737aac --- /dev/null +++ b/src/include/duicontainerstyle.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../style/duicontainerstyle.h" + diff --git a/src/include/duicontainerview.h b/src/include/duicontainerview.h new file mode 100644 index 000000000..49853e2dd --- /dev/null +++ b/src/include/duicontainerview.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/views/duicontainerview.h" + diff --git a/src/include/duicontentitem.h b/src/include/duicontentitem.h new file mode 100644 index 000000000..b03000188 --- /dev/null +++ b/src/include/duicontentitem.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duicontentitem.h" diff --git a/src/include/duidataaccess.h b/src/include/duidataaccess.h new file mode 100644 index 000000000..3f85ccbe8 --- /dev/null +++ b/src/include/duidataaccess.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../mashup/mashup/duidataaccess.h" diff --git a/src/include/duidatastore.h b/src/include/duidatastore.h new file mode 100644 index 000000000..2fca6d3c2 --- /dev/null +++ b/src/include/duidatastore.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../mashup/mashup/duidatastore.h" diff --git a/src/include/duidebug.h b/src/include/duidebug.h new file mode 100644 index 000000000..aedd09297 --- /dev/null +++ b/src/include/duidebug.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../core/duidebug.h" diff --git a/src/include/duidesktopentry.h b/src/include/duidesktopentry.h new file mode 100644 index 000000000..f8ff04b6c --- /dev/null +++ b/src/include/duidesktopentry.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../core/duidesktopentry.h" + diff --git a/src/include/duideviceprofile.h b/src/include/duideviceprofile.h new file mode 100644 index 000000000..d33c038a7 --- /dev/null +++ b/src/include/duideviceprofile.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../workspace/duideviceprofile.h" diff --git a/src/include/duidialog.h b/src/include/duidialog.h new file mode 100644 index 000000000..fd38bbe2b --- /dev/null +++ b/src/include/duidialog.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duidialog.h" + diff --git a/src/include/duidialogmodel.h b/src/include/duidialogmodel.h new file mode 100644 index 000000000..12ddac0a3 --- /dev/null +++ b/src/include/duidialogmodel.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duidialogmodel.h" + diff --git a/src/include/duidismissevent.h b/src/include/duidismissevent.h new file mode 100644 index 000000000..c7db0e44b --- /dev/null +++ b/src/include/duidismissevent.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../events/duidismissevent.h" diff --git a/src/include/duiescapebuttonpanel.h b/src/include/duiescapebuttonpanel.h new file mode 100644 index 000000000..fbce31239 --- /dev/null +++ b/src/include/duiescapebuttonpanel.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duiescapebuttonpanel.h" diff --git a/src/include/duiescapebuttonpanelmodel.h b/src/include/duiescapebuttonpanelmodel.h new file mode 100644 index 000000000..cfbf1bb25 --- /dev/null +++ b/src/include/duiescapebuttonpanelmodel.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duiescapebuttonpanelmodel.h" diff --git a/src/include/duiexport.h b/src/include/duiexport.h new file mode 100644 index 000000000..ed58a9594 --- /dev/null +++ b/src/include/duiexport.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../core/duiexport.h" diff --git a/src/include/duiextendingbackgroundstyle.h b/src/include/duiextendingbackgroundstyle.h new file mode 100644 index 000000000..e63b6d9e8 --- /dev/null +++ b/src/include/duiextendingbackgroundstyle.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../style/duiextendingbackgroundstyle.h" + diff --git a/src/include/duiextendingbackgroundview.h b/src/include/duiextendingbackgroundview.h new file mode 100644 index 000000000..967c5189c --- /dev/null +++ b/src/include/duiextendingbackgroundview.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/views/duiextendingbackgroundview.h" diff --git a/src/include/duifeedback.h b/src/include/duifeedback.h new file mode 100644 index 000000000..e8b0f4f6e --- /dev/null +++ b/src/include/duifeedback.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../feedback/duifeedback.h" diff --git a/src/include/duifeedbackplayer.h b/src/include/duifeedbackplayer.h new file mode 100644 index 000000000..36463903c --- /dev/null +++ b/src/include/duifeedbackplayer.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../feedback/duifeedbackplayer.h" diff --git a/src/include/duiflowlayoutpolicy.h b/src/include/duiflowlayoutpolicy.h new file mode 100644 index 000000000..c601dd119 --- /dev/null +++ b/src/include/duiflowlayoutpolicy.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../layout/duiflowlayoutpolicy.h" + diff --git a/src/include/duifreestylelayoutpolicy.h b/src/include/duifreestylelayoutpolicy.h new file mode 100644 index 000000000..7b518030b --- /dev/null +++ b/src/include/duifreestylelayoutpolicy.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../layout/duifreestylelayoutpolicy.h" + diff --git a/src/include/duigconfdatastore.h b/src/include/duigconfdatastore.h new file mode 100644 index 000000000..a7c8b3c16 --- /dev/null +++ b/src/include/duigconfdatastore.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../mashup/mashup/duigconfdatastore.h" diff --git a/src/include/duigconfitem.h b/src/include/duigconfitem.h new file mode 100644 index 000000000..1bab4f399 --- /dev/null +++ b/src/include/duigconfitem.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../core/duigconfitem.h" diff --git a/src/include/duigles2renderer.h b/src/include/duigles2renderer.h new file mode 100644 index 000000000..ea6260cbb --- /dev/null +++ b/src/include/duigles2renderer.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../painting/duigles2renderer.h" diff --git a/src/include/duiglrenderer.h b/src/include/duiglrenderer.h new file mode 100644 index 000000000..b47a9edec --- /dev/null +++ b/src/include/duiglrenderer.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../painting/duiglrenderer.h" diff --git a/src/include/duiglshader.h b/src/include/duiglshader.h new file mode 100644 index 000000000..a5316d033 --- /dev/null +++ b/src/include/duiglshader.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../painting/duiglshader.h" diff --git a/src/include/duiglshaderprogram.h b/src/include/duiglshaderprogram.h new file mode 100644 index 000000000..e54d10dd1 --- /dev/null +++ b/src/include/duiglshaderprogram.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../painting/duiglshaderprogram.h" diff --git a/src/include/duiglshaderuniform.h b/src/include/duiglshaderuniform.h new file mode 100644 index 000000000..1eadba614 --- /dev/null +++ b/src/include/duiglshaderuniform.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../painting/duiglshaderuniform.h" diff --git a/src/include/duigridlayoutpolicy.h b/src/include/duigridlayoutpolicy.h new file mode 100644 index 000000000..a82149ff4 --- /dev/null +++ b/src/include/duigridlayoutpolicy.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../layout/duigridlayoutpolicy.h" diff --git a/src/include/duigroupanimation.h b/src/include/duigroupanimation.h new file mode 100644 index 000000000..65b035c2e --- /dev/null +++ b/src/include/duigroupanimation.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../animation/core/duigroupanimation.h" + diff --git a/src/include/duigroupanimationstyle.h b/src/include/duigroupanimationstyle.h new file mode 100644 index 000000000..93b644833 --- /dev/null +++ b/src/include/duigroupanimationstyle.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../style/duigroupanimationstyle.h" diff --git a/src/include/duihomebuttonpanel.h b/src/include/duihomebuttonpanel.h new file mode 100644 index 000000000..af01d2620 --- /dev/null +++ b/src/include/duihomebuttonpanel.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duihomebuttonpanel.h" diff --git a/src/include/duiimagewidget.h b/src/include/duiimagewidget.h new file mode 100644 index 000000000..0545c58b2 --- /dev/null +++ b/src/include/duiimagewidget.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duiimagewidget.h" diff --git a/src/include/duiimagewidgetview.h b/src/include/duiimagewidgetview.h new file mode 100644 index 000000000..e35a13167 --- /dev/null +++ b/src/include/duiimagewidgetview.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/views/duiimagewidgetview.h" + diff --git a/src/include/duiinfobanner.h b/src/include/duiinfobanner.h new file mode 100644 index 000000000..3d3e6e6b8 --- /dev/null +++ b/src/include/duiinfobanner.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duiinfobanner.h" + diff --git a/src/include/duiinfobannereventview.h b/src/include/duiinfobannereventview.h new file mode 100644 index 000000000..9580c3d76 --- /dev/null +++ b/src/include/duiinfobannereventview.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/views/duiinfobannereventview.h" + diff --git a/src/include/duiinfobannerinformationview.h b/src/include/duiinfobannerinformationview.h new file mode 100644 index 000000000..d2d7789f6 --- /dev/null +++ b/src/include/duiinfobannerinformationview.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/views/duiinfobannerinformationview.h" + diff --git a/src/include/duiinfobannermodel.h b/src/include/duiinfobannermodel.h new file mode 100644 index 000000000..ba1f85dbf --- /dev/null +++ b/src/include/duiinfobannermodel.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duiinfobannermodel.h" + diff --git a/src/include/duiinputmethodstate.h b/src/include/duiinputmethodstate.h new file mode 100644 index 000000000..0e81eb34a --- /dev/null +++ b/src/include/duiinputmethodstate.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../core/duiinputmethodstate.h" diff --git a/src/include/duilabel.h b/src/include/duilabel.h new file mode 100644 index 000000000..7b89c51c5 --- /dev/null +++ b/src/include/duilabel.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duilabel.h" diff --git a/src/include/duilabelhighlighter.h b/src/include/duilabelhighlighter.h new file mode 100644 index 000000000..240d03a1b --- /dev/null +++ b/src/include/duilabelhighlighter.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duilabelhighlighter.h" diff --git a/src/include/duilabelmodel.h b/src/include/duilabelmodel.h new file mode 100644 index 000000000..212b575fe --- /dev/null +++ b/src/include/duilabelmodel.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duilabelmodel.h" + diff --git a/src/include/duilabelstyle.h b/src/include/duilabelstyle.h new file mode 100644 index 000000000..a7e221612 --- /dev/null +++ b/src/include/duilabelstyle.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../style/duilabelstyle.h" + diff --git a/src/include/duilabelview.h b/src/include/duilabelview.h new file mode 100644 index 000000000..a4a459c8f --- /dev/null +++ b/src/include/duilabelview.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/views/duilabelview.h" + diff --git a/src/include/duilayout.h b/src/include/duilayout.h new file mode 100644 index 000000000..e8b266dbf --- /dev/null +++ b/src/include/duilayout.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../layout/duilayout.h" diff --git a/src/include/duilayoutanimation.h b/src/include/duilayoutanimation.h new file mode 100644 index 000000000..5ca537f02 --- /dev/null +++ b/src/include/duilayoutanimation.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../layout/duilayoutanimation.h" diff --git a/src/include/duilayoutanimationstyle.h b/src/include/duilayoutanimationstyle.h new file mode 100644 index 000000000..d8005e5d0 --- /dev/null +++ b/src/include/duilayoutanimationstyle.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../style/duilayoutanimationstyle.h" diff --git a/src/include/duilibrary.h b/src/include/duilibrary.h new file mode 100644 index 000000000..235c19f05 --- /dev/null +++ b/src/include/duilibrary.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../core/duilibrary.h" + diff --git a/src/include/duilinearlayoutpolicy.h b/src/include/duilinearlayoutpolicy.h new file mode 100644 index 000000000..339a26628 --- /dev/null +++ b/src/include/duilinearlayoutpolicy.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../layout/duilinearlayoutpolicy.h" diff --git a/src/include/duilist.h b/src/include/duilist.h new file mode 100644 index 000000000..0d4c3c6aa --- /dev/null +++ b/src/include/duilist.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duilist.h" + diff --git a/src/include/duilistmodel.h b/src/include/duilistmodel.h new file mode 100644 index 000000000..70e766aad --- /dev/null +++ b/src/include/duilistmodel.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duilistmodel.h" + diff --git a/src/include/duiliststyle.h b/src/include/duiliststyle.h new file mode 100644 index 000000000..3458405e6 --- /dev/null +++ b/src/include/duiliststyle.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../style/duiliststyle.h" + diff --git a/src/include/duilocale.h b/src/include/duilocale.h new file mode 100644 index 000000000..a5806cf62 --- /dev/null +++ b/src/include/duilocale.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../i18n/duilocale.h" diff --git a/src/include/duimashupcanvas.h b/src/include/duimashupcanvas.h new file mode 100644 index 000000000..8905d083a --- /dev/null +++ b/src/include/duimashupcanvas.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../mashup/mashup/duimashupcanvas.h" diff --git a/src/include/duimashupcanvasmodel.h b/src/include/duimashupcanvasmodel.h new file mode 100644 index 000000000..24c5a1993 --- /dev/null +++ b/src/include/duimashupcanvasmodel.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../mashup/mashup/duimashupcanvasmodel.h" diff --git a/src/include/duimenuobjectview.h b/src/include/duimenuobjectview.h new file mode 100644 index 000000000..7573a28aa --- /dev/null +++ b/src/include/duimenuobjectview.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/views/duimenuobjectview.h" + diff --git a/src/include/duimessagebox.h b/src/include/duimessagebox.h new file mode 100644 index 000000000..e14ef4de3 --- /dev/null +++ b/src/include/duimessagebox.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duimessagebox.h" + diff --git a/src/include/duimessageboxmodel.h b/src/include/duimessageboxmodel.h new file mode 100644 index 000000000..61d2b08ca --- /dev/null +++ b/src/include/duimessageboxmodel.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duimessageboxmodel.h" + diff --git a/src/include/duimessageboxview.h b/src/include/duimessageboxview.h new file mode 100644 index 000000000..88905aaa0 --- /dev/null +++ b/src/include/duimessageboxview.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/views/duimessageboxview.h" + diff --git a/src/include/duimodalscenewindow.h b/src/include/duimodalscenewindow.h new file mode 100644 index 000000000..80b0c69f8 --- /dev/null +++ b/src/include/duimodalscenewindow.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duimodalscenewindow.h" + diff --git a/src/include/duimodalscenewindowmodel.h b/src/include/duimodalscenewindowmodel.h new file mode 100644 index 000000000..2e5fd6207 --- /dev/null +++ b/src/include/duimodalscenewindowmodel.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duimodalscenewindowmodel.h" + diff --git a/src/include/duinamespace.h b/src/include/duinamespace.h new file mode 100644 index 000000000..1fc837ec8 --- /dev/null +++ b/src/include/duinamespace.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../core/duinamespace.h" + diff --git a/src/include/duinavigationbar.h b/src/include/duinavigationbar.h new file mode 100644 index 000000000..e7f920ac7 --- /dev/null +++ b/src/include/duinavigationbar.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duinavigationbar.h" + diff --git a/src/include/duinavigationbarmodel.h b/src/include/duinavigationbarmodel.h new file mode 100644 index 000000000..5bd59f1b2 --- /dev/null +++ b/src/include/duinavigationbarmodel.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duinavigationbarmodel.h" + diff --git a/src/include/duinavigationbarstyle.h b/src/include/duinavigationbarstyle.h new file mode 100644 index 000000000..11e8c3343 --- /dev/null +++ b/src/include/duinavigationbarstyle.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../style/duinavigationbarstyle.h" + diff --git a/src/include/duinavigationbarview.h b/src/include/duinavigationbarview.h new file mode 100644 index 000000000..5671ca204 --- /dev/null +++ b/src/include/duinavigationbarview.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/views/duinavigationbarview.h" + diff --git a/src/include/duinotification.h b/src/include/duinotification.h new file mode 100644 index 000000000..92ba58ba3 --- /dev/null +++ b/src/include/duinotification.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../notification/duinotification.h" diff --git a/src/include/duinotificationgroup.h b/src/include/duinotificationgroup.h new file mode 100644 index 000000000..ecf332946 --- /dev/null +++ b/src/include/duinotificationgroup.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../notification/duinotificationgroup.h" + diff --git a/src/include/duiondisplaychangeevent.h b/src/include/duiondisplaychangeevent.h new file mode 100644 index 000000000..bca909fe7 --- /dev/null +++ b/src/include/duiondisplaychangeevent.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../events/duiondisplaychangeevent.h" diff --git a/src/include/duiorientationchangeevent.h b/src/include/duiorientationchangeevent.h new file mode 100644 index 000000000..4df272f1e --- /dev/null +++ b/src/include/duiorientationchangeevent.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../events/duiorientationchangeevent.h" diff --git a/src/include/duioverlay.h b/src/include/duioverlay.h new file mode 100644 index 000000000..ad5db6b50 --- /dev/null +++ b/src/include/duioverlay.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duioverlay.h" diff --git a/src/include/duioverlayview.h b/src/include/duioverlayview.h new file mode 100644 index 000000000..3d59de529 --- /dev/null +++ b/src/include/duioverlayview.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/views/duioverlayview.h" diff --git a/src/include/duipageswitchanimation.h b/src/include/duipageswitchanimation.h new file mode 100644 index 000000000..440cf1fbe --- /dev/null +++ b/src/include/duipageswitchanimation.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../animation/scene/duipageswitchanimation.h" diff --git a/src/include/duipannableviewport.h b/src/include/duipannableviewport.h new file mode 100644 index 000000000..a66f6a32f --- /dev/null +++ b/src/include/duipannableviewport.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duipannableviewport.h" diff --git a/src/include/duipannableviewportmodel.h b/src/include/duipannableviewportmodel.h new file mode 100644 index 000000000..bc3663441 --- /dev/null +++ b/src/include/duipannableviewportmodel.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duipannableviewportmodel.h" + diff --git a/src/include/duipannablewidget.h b/src/include/duipannablewidget.h new file mode 100644 index 000000000..9981c56ab --- /dev/null +++ b/src/include/duipannablewidget.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duipannablewidget.h" diff --git a/src/include/duipannablewidgetmodel.h b/src/include/duipannablewidgetmodel.h new file mode 100644 index 000000000..70ede943b --- /dev/null +++ b/src/include/duipannablewidgetmodel.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duipannablewidgetmodel.h" + diff --git a/src/include/duipannablewidgetview.h b/src/include/duipannablewidgetview.h new file mode 100644 index 000000000..80b997ef4 --- /dev/null +++ b/src/include/duipannablewidgetview.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/views/duipannablewidgetview.h" + diff --git a/src/include/duiparallelanimationgroup.h b/src/include/duiparallelanimationgroup.h new file mode 100644 index 000000000..00b42a61a --- /dev/null +++ b/src/include/duiparallelanimationgroup.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../animation/core/duiparallelanimationgroup.h" diff --git a/src/include/duiphysics2dpanning.h b/src/include/duiphysics2dpanning.h new file mode 100644 index 000000000..23918706e --- /dev/null +++ b/src/include/duiphysics2dpanning.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duiphysics2dpanning.h" + diff --git a/src/include/duipopuplist.h b/src/include/duipopuplist.h new file mode 100644 index 000000000..8a170df5c --- /dev/null +++ b/src/include/duipopuplist.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duipopuplist.h" diff --git a/src/include/duipopupliststyle.h b/src/include/duipopupliststyle.h new file mode 100644 index 000000000..199307c89 --- /dev/null +++ b/src/include/duipopupliststyle.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../style/duipopupliststyle.h" + diff --git a/src/include/duipopuplistview.h b/src/include/duipopuplistview.h new file mode 100644 index 000000000..bc031de43 --- /dev/null +++ b/src/include/duipopuplistview.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/views/duipopuplistview.h" diff --git a/src/include/duipositionindicator.h b/src/include/duipositionindicator.h new file mode 100644 index 000000000..bc49ec4ec --- /dev/null +++ b/src/include/duipositionindicator.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duipositionindicator.h" + diff --git a/src/include/duipositionindicatormodel.h b/src/include/duipositionindicatormodel.h new file mode 100644 index 000000000..8150a8e4e --- /dev/null +++ b/src/include/duipositionindicatormodel.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duipositionindicatormodel.h" + diff --git a/src/include/duipositionindicatorstyle.h b/src/include/duipositionindicatorstyle.h new file mode 100644 index 000000000..8722f8954 --- /dev/null +++ b/src/include/duipositionindicatorstyle.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../style/duipositionindicatorstyle.h" + diff --git a/src/include/duipositionindicatorview.h b/src/include/duipositionindicatorview.h new file mode 100644 index 000000000..5e8340a55 --- /dev/null +++ b/src/include/duipositionindicatorview.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/views/duipositionindicatorview.h" + diff --git a/src/include/duipreeditinjectionevent.h b/src/include/duipreeditinjectionevent.h new file mode 100644 index 000000000..7d25e126f --- /dev/null +++ b/src/include/duipreeditinjectionevent.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../events/duipreeditinjectionevent.h" + diff --git a/src/include/duiprogressindicator.h b/src/include/duiprogressindicator.h new file mode 100644 index 000000000..db8c18cba --- /dev/null +++ b/src/include/duiprogressindicator.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duiprogressindicator.h" diff --git a/src/include/duiprogressindicatorbarview.h b/src/include/duiprogressindicatorbarview.h new file mode 100644 index 000000000..fc422e877 --- /dev/null +++ b/src/include/duiprogressindicatorbarview.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/views/duiprogressindicatorbarview.h" diff --git a/src/include/duiprogressindicatormodel.h b/src/include/duiprogressindicatormodel.h new file mode 100644 index 000000000..e09cb6bc3 --- /dev/null +++ b/src/include/duiprogressindicatormodel.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duiprogressindicatormodel.h" diff --git a/src/include/duiremoteaction.h b/src/include/duiremoteaction.h new file mode 100644 index 000000000..4cb8d0176 --- /dev/null +++ b/src/include/duiremoteaction.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../core/duiremoteaction.h" + diff --git a/src/include/duirmiclient.h b/src/include/duirmiclient.h new file mode 100644 index 000000000..b35501271 --- /dev/null +++ b/src/include/duirmiclient.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../core/duirmiclient.h" + diff --git a/src/include/duirmiserver.h b/src/include/duirmiserver.h new file mode 100644 index 000000000..471affa0b --- /dev/null +++ b/src/include/duirmiserver.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../core/duirmiserver.h" + diff --git a/src/include/duiscalableimage.h b/src/include/duiscalableimage.h new file mode 100644 index 000000000..e68a0f5cc --- /dev/null +++ b/src/include/duiscalableimage.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../painting/duiscalableimage.h" diff --git a/src/include/duiscene.h b/src/include/duiscene.h new file mode 100644 index 000000000..ad4f39801 --- /dev/null +++ b/src/include/duiscene.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../scene/duiscene.h" + diff --git a/src/include/duiscenelayereffect.h b/src/include/duiscenelayereffect.h new file mode 100644 index 000000000..fc72052a3 --- /dev/null +++ b/src/include/duiscenelayereffect.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../scene/duiscenelayereffect.h" + diff --git a/src/include/duiscenemanager.h b/src/include/duiscenemanager.h new file mode 100644 index 000000000..1d69bd317 --- /dev/null +++ b/src/include/duiscenemanager.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../scene/duiscenemanager.h" + diff --git a/src/include/duiscenewindow.h b/src/include/duiscenewindow.h new file mode 100644 index 000000000..0cee66d77 --- /dev/null +++ b/src/include/duiscenewindow.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duiscenewindow.h" + diff --git a/src/include/duiscenewindowmodel.h b/src/include/duiscenewindowmodel.h new file mode 100644 index 000000000..e8a6d8478 --- /dev/null +++ b/src/include/duiscenewindowmodel.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duiscenewindowmodel.h" + diff --git a/src/include/duiscenewindowstyle.h b/src/include/duiscenewindowstyle.h new file mode 100644 index 000000000..ce1f74c17 --- /dev/null +++ b/src/include/duiscenewindowstyle.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../style/duiscenewindowstyle.h" + diff --git a/src/include/duiseekbar.h b/src/include/duiseekbar.h new file mode 100644 index 000000000..c10824429 --- /dev/null +++ b/src/include/duiseekbar.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duiseekbar.h" + diff --git a/src/include/duiseekbarmodel.h b/src/include/duiseekbarmodel.h new file mode 100644 index 000000000..8575652e3 --- /dev/null +++ b/src/include/duiseekbarmodel.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duiseekbarmodel.h" + diff --git a/src/include/duiseparator.h b/src/include/duiseparator.h new file mode 100644 index 000000000..cd8da504e --- /dev/null +++ b/src/include/duiseparator.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duiseparator.h" diff --git a/src/include/duiseparatorstyle.h b/src/include/duiseparatorstyle.h new file mode 100644 index 000000000..c5f6ddcc6 --- /dev/null +++ b/src/include/duiseparatorstyle.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../style/duiseparatorstyle.h" + diff --git a/src/include/duiservicefwbaseif.h b/src/include/duiservicefwbaseif.h new file mode 100644 index 000000000..4472f451f --- /dev/null +++ b/src/include/duiservicefwbaseif.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../servicefwif/duiservicefwbaseif.h" diff --git a/src/include/duiservicefwproxy.h b/src/include/duiservicefwproxy.h new file mode 100644 index 000000000..8acab1c6d --- /dev/null +++ b/src/include/duiservicefwproxy.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../servicefwif/include/duiservicefwproxy.h" diff --git a/src/include/duisettingslanguagebinary.h b/src/include/duisettingslanguagebinary.h new file mode 100644 index 000000000..adf5c60f8 --- /dev/null +++ b/src/include/duisettingslanguagebinary.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../settingslanguage/duisettingslanguagebinary.h" diff --git a/src/include/duisettingslanguageparser.h b/src/include/duisettingslanguageparser.h new file mode 100644 index 000000000..ff96603bf --- /dev/null +++ b/src/include/duisettingslanguageparser.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../settingslanguage/duisettingslanguageparser.h" diff --git a/src/include/duisettingslanguagewidget.h b/src/include/duisettingslanguagewidget.h new file mode 100644 index 000000000..5c5f670a8 --- /dev/null +++ b/src/include/duisettingslanguagewidget.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../settingslanguage/duisettingslanguagewidget.h" diff --git a/src/include/duisettingslanguagewidgetfactory.h b/src/include/duisettingslanguagewidgetfactory.h new file mode 100644 index 000000000..c1a7c18aa --- /dev/null +++ b/src/include/duisettingslanguagewidgetfactory.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../settingslanguage/duisettingslanguagewidgetfactory.h" diff --git a/src/include/duishareddata.h b/src/include/duishareddata.h new file mode 100644 index 000000000..58f0be7bb --- /dev/null +++ b/src/include/duishareddata.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../core/duishareddata.h" diff --git a/src/include/duislider.h b/src/include/duislider.h new file mode 100644 index 000000000..295fda845 --- /dev/null +++ b/src/include/duislider.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duislider.h" diff --git a/src/include/duislidermodel.h b/src/include/duislidermodel.h new file mode 100644 index 000000000..3e38e609f --- /dev/null +++ b/src/include/duislidermodel.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duislidermodel.h" + diff --git a/src/include/duisliderstyle.h b/src/include/duisliderstyle.h new file mode 100644 index 000000000..5e814003e --- /dev/null +++ b/src/include/duisliderstyle.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../style/duisliderstyle.h" + diff --git a/src/include/duisliderview.h b/src/include/duisliderview.h new file mode 100644 index 000000000..74eb193aa --- /dev/null +++ b/src/include/duisliderview.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/views/duisliderview.h" + diff --git a/src/include/duistylablewidget.h b/src/include/duistylablewidget.h new file mode 100644 index 000000000..e81ac405d --- /dev/null +++ b/src/include/duistylablewidget.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duistylablewidget.h" diff --git a/src/include/duistyle.h b/src/include/duistyle.h new file mode 100644 index 000000000..ac0c05370 --- /dev/null +++ b/src/include/duistyle.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../style/duistyle.h" diff --git a/src/include/duistylecreator.h b/src/include/duistylecreator.h new file mode 100644 index 000000000..ffeb19f83 --- /dev/null +++ b/src/include/duistylecreator.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../style/duistylecreator.h" diff --git a/src/include/duistylesheet.h b/src/include/duistylesheet.h new file mode 100644 index 000000000..90bdd43fc --- /dev/null +++ b/src/include/duistylesheet.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../style/duistylesheet.h" diff --git a/src/include/duistylesheetattribute.h b/src/include/duistylesheetattribute.h new file mode 100644 index 000000000..c97b34ce8 --- /dev/null +++ b/src/include/duistylesheetattribute.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../style/duistylesheetattribute.h" diff --git a/src/include/duistylesheetparser.h b/src/include/duistylesheetparser.h new file mode 100644 index 000000000..45e767b57 --- /dev/null +++ b/src/include/duistylesheetparser.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../style/duistylesheetparser.h" diff --git a/src/include/duistylesheetselector.h b/src/include/duistylesheetselector.h new file mode 100644 index 000000000..9af564f01 --- /dev/null +++ b/src/include/duistylesheetselector.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../style/duistylesheetselector.h" diff --git a/src/include/duitextedit.h b/src/include/duitextedit.h new file mode 100644 index 000000000..e9b8a7577 --- /dev/null +++ b/src/include/duitextedit.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duitextedit.h" diff --git a/src/include/duitexteditmodel.h b/src/include/duitexteditmodel.h new file mode 100644 index 000000000..a91e76aa0 --- /dev/null +++ b/src/include/duitexteditmodel.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duitexteditmodel.h" + diff --git a/src/include/duitexteditstyle.h b/src/include/duitexteditstyle.h new file mode 100644 index 000000000..55ab42f5f --- /dev/null +++ b/src/include/duitexteditstyle.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../style/duitexteditstyle.h" + diff --git a/src/include/duitexteditview.h b/src/include/duitexteditview.h new file mode 100644 index 000000000..fa1f9cf25 --- /dev/null +++ b/src/include/duitexteditview.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/views/duitexteditview.h" + diff --git a/src/include/duitheme.h b/src/include/duitheme.h new file mode 100644 index 000000000..641e415d0 --- /dev/null +++ b/src/include/duitheme.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../theme/duitheme.h" diff --git a/src/include/duithemedaemon.h b/src/include/duithemedaemon.h new file mode 100644 index 000000000..af268c56f --- /dev/null +++ b/src/include/duithemedaemon.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../theme/duithemedaemon.h" + diff --git a/src/include/duitoolbar.h b/src/include/duitoolbar.h new file mode 100644 index 000000000..cf58a9b57 --- /dev/null +++ b/src/include/duitoolbar.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duitoolbar.h" + diff --git a/src/include/duitoolbarview.h b/src/include/duitoolbarview.h new file mode 100644 index 000000000..4daff5bfa --- /dev/null +++ b/src/include/duitoolbarview.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/views/duitoolbarview.h" + diff --git a/src/include/duiviewcreator.h b/src/include/duiviewcreator.h new file mode 100644 index 000000000..a9feca32a --- /dev/null +++ b/src/include/duiviewcreator.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duiviewcreator.h" diff --git a/src/include/duiwidget.h b/src/include/duiwidget.h new file mode 100644 index 000000000..bf14e7cbc --- /dev/null +++ b/src/include/duiwidget.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/core/duiwidget.h" diff --git a/src/include/duiwidgetaction.h b/src/include/duiwidgetaction.h new file mode 100644 index 000000000..d5ba0cf7e --- /dev/null +++ b/src/include/duiwidgetaction.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../core/duiwidgetaction.h" + diff --git a/src/include/duiwidgetcontroller.h b/src/include/duiwidgetcontroller.h new file mode 100644 index 000000000..7e52ff926 --- /dev/null +++ b/src/include/duiwidgetcontroller.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/core/duiwidgetcontroller.h" diff --git a/src/include/duiwidgetcreator.h b/src/include/duiwidgetcreator.h new file mode 100644 index 000000000..88537baec --- /dev/null +++ b/src/include/duiwidgetcreator.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/core/duiwidgetcreator.h" diff --git a/src/include/duiwidgetfadeinanimationstyle.h b/src/include/duiwidgetfadeinanimationstyle.h new file mode 100644 index 000000000..46ceeb527 --- /dev/null +++ b/src/include/duiwidgetfadeinanimationstyle.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../style/duiwidgetfadeinanimationstyle.h" diff --git a/src/include/duiwidgetfadeoutanimationstyle.h b/src/include/duiwidgetfadeoutanimationstyle.h new file mode 100644 index 000000000..f9fc49f61 --- /dev/null +++ b/src/include/duiwidgetfadeoutanimationstyle.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../style/duiwidgetfadeoutanimationstyle.h" diff --git a/src/include/duiwidgetmodel.h b/src/include/duiwidgetmodel.h new file mode 100644 index 000000000..a8f4a17f9 --- /dev/null +++ b/src/include/duiwidgetmodel.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duiwidgetmodel.h" + diff --git a/src/include/duiwidgetrecycler.h b/src/include/duiwidgetrecycler.h new file mode 100644 index 000000000..cf803ed2d --- /dev/null +++ b/src/include/duiwidgetrecycler.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duiwidgetrecycler.h" diff --git a/src/include/duiwidgetstyle.h b/src/include/duiwidgetstyle.h new file mode 100644 index 000000000..2c5397d09 --- /dev/null +++ b/src/include/duiwidgetstyle.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../style/duiwidgetstyle.h" + diff --git a/src/include/duiwidgetview.h b/src/include/duiwidgetview.h new file mode 100644 index 000000000..81a012356 --- /dev/null +++ b/src/include/duiwidgetview.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/core/duiwidgetview.h" + diff --git a/src/include/duiwindow.h b/src/include/duiwindow.h new file mode 100644 index 000000000..2d70a7a84 --- /dev/null +++ b/src/include/duiwindow.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/duiwindow.h" diff --git a/src/include/iduithemedaemon.h b/src/include/iduithemedaemon.h new file mode 100644 index 000000000..6d296a891 --- /dev/null +++ b/src/include/iduithemedaemon.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../theme/iduithemedaemon.h" + diff --git a/src/include/private/duiextendingbackgroundview_p.h b/src/include/private/duiextendingbackgroundview_p.h new file mode 100644 index 000000000..e315d2122 --- /dev/null +++ b/src/include/private/duiextendingbackgroundview_p.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/views/duiextendingbackgroundview_p.h" diff --git a/src/include/private/duiwidget_p.h b/src/include/private/duiwidget_p.h new file mode 100644 index 000000000..d2bca918d --- /dev/null +++ b/src/include/private/duiwidget_p.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/core/duiwidget_p.h" diff --git a/src/include/private/duiwidgetcontroller_p.h b/src/include/private/duiwidgetcontroller_p.h new file mode 100644 index 000000000..e5ba66040 --- /dev/null +++ b/src/include/private/duiwidgetcontroller_p.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/core/duiwidgetcontroller_p.h" diff --git a/src/include/private/duiwidgetview_p.h b/src/include/private/duiwidgetview_p.h new file mode 100644 index 000000000..f9695d44e --- /dev/null +++ b/src/include/private/duiwidgetview_p.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../widgets/core/duiwidgetview_p.h" diff --git a/src/include/testabilityinterface.h b/src/include/testabilityinterface.h new file mode 100644 index 000000000..4276223f1 --- /dev/null +++ b/src/include/testabilityinterface.h @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "../core/testabilityinterface.h" + diff --git a/src/layout/duiabstractlayoutpolicy.cpp b/src/layout/duiabstractlayoutpolicy.cpp new file mode 100644 index 000000000..8e60e56db --- /dev/null +++ b/src/layout/duiabstractlayoutpolicy.cpp @@ -0,0 +1,358 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiabstractlayoutpolicy.h" +#include "duiabstractlayoutpolicy_p.h" +#include "duiabstractlayoutpolicystyle.h" + +#include "duilayout_p.h" +#include "duiapplication.h" +#include "duiapplicationwindow.h" +#include "duitheme.h" +#include + +DuiAbstractLayoutPolicy::DuiAbstractLayoutPolicy(DuiLayout *layout) + : + d_ptr(new DuiAbstractLayoutPolicyPrivate(layout)) +{ + Q_ASSERT(layout); + d_ptr->q_ptr = this; + Q_D(DuiAbstractLayoutPolicy); + d->layout->d_ptr->registerPolicy(this); + +} +DuiAbstractLayoutPolicy::DuiAbstractLayoutPolicy( + DuiAbstractLayoutPolicyPrivate &p) : + d_ptr(&p) +{ + Q_ASSERT(0 != d_ptr); + d_ptr->q_ptr = this; + Q_D(DuiAbstractLayoutPolicy); + d->layout->d_ptr->registerPolicy(this); +} + +DuiAbstractLayoutPolicy::~DuiAbstractLayoutPolicy() +{ + Q_D(DuiAbstractLayoutPolicy); + d->layout->d_ptr->unregisterPolicy(this); + DuiTheme::releaseStyle(d->style); + delete d_ptr; +} + +DuiLayout *DuiAbstractLayoutPolicy::layout() const +{ + Q_D(const DuiAbstractLayoutPolicy); + return d->layout; +} + +void DuiAbstractLayoutPolicy::activate() +{ + layout()->setPolicy(this); +} + +bool DuiAbstractLayoutPolicy::isActive() const +{ + return layout()->policy() == this; +} + +void DuiAbstractLayoutPolicy::invalidate() +{ +} + +void DuiAbstractLayoutPolicy::invalidatePolicyAndLayout() +{ + Q_D(DuiAbstractLayoutPolicy); + if (d->layout && d->layout->policy() == this) + d->layout->QGraphicsLayout::invalidate(); //Invalidate the layout only, and not the policy again + invalidate(); +} + +void DuiAbstractLayoutPolicy::updateGeometry() +{ + Q_D(DuiAbstractLayoutPolicy); + if (d->layout && d->layout->policy() == this) + d->layout->updateGeometry(); +} + +QRectF DuiAbstractLayoutPolicy::contentsArea() const +{ + Q_D(const DuiAbstractLayoutPolicy); + qreal left, top, right, bottom; + d->layout->getContentsMargins(&left, &top, &right, &bottom); + return d->layout->geometry().adjusted(left, top, -right, -bottom); +} + +void DuiAbstractLayoutPolicy::setContentsMargins(qreal left, qreal top, + qreal right, qreal bottom) +{ + Q_D(DuiAbstractLayoutPolicy); + + d->marginLeft = left; + d->marginTop = top; + d->marginRight = right; + d->marginBottom = bottom; + + d->userSetContentsMargins = true; + + invalidatePolicyAndLayout(); +} + +void DuiAbstractLayoutPolicy::getContentsMargins(qreal *left, qreal *top, + qreal *right, qreal *bottom) const +{ + Q_D(const DuiAbstractLayoutPolicy); + + if (!d->userSetContentsMargins) + (void) style(); //Make sure the style is loaded + + if (0 != left) + *left = d->marginLeft; + if (0 != top) + *top = d->marginTop; + if (0 != right) + *right = d->marginRight; + if (0 != bottom) + *bottom = d->marginBottom; +} + +void DuiAbstractLayoutPolicy::updateStyle() +{ + Q_D(DuiAbstractLayoutPolicy); + + Dui::Orientation orientation = Dui::Landscape; + if (DuiApplication::activeWindow()) { + orientation = DuiApplication::activeWindow()->orientation(); + } + + const DuiAbstractLayoutPolicyStyle *style = + static_cast(DuiTheme::style( + "DuiAbstractLayoutPolicyStyle", d->objectName, "", "", + orientation)); + + if (d->style != style) { + DuiTheme::releaseStyle(d->style); + d->style = style; + applyStyle(); + } else { + DuiTheme::releaseStyle(style); + } +} + +void DuiAbstractLayoutPolicy::unsetContentsMargins() +{ + Q_D(DuiAbstractLayoutPolicy); + if (!d->userSetContentsMargins) + return; //already unset + d->userSetContentsMargins = false; + (void)style(); //Force the style to be loaded + applyStyle(); +} +void DuiAbstractLayoutPolicy::applyStyle() +{ + Q_D(DuiAbstractLayoutPolicy); + //Do not change the margins if the user manually set them or the margins + //have not changed + if (!d->userSetContentsMargins && + (d->marginLeft != (int)d->style->marginLeft() || + d->marginTop != (int)d->style->marginTop() || + d->marginRight != (int)d->style->marginRight() || + d->marginBottom != (int)d->style->marginBottom())) { + d->marginLeft = (int)d->style->marginLeft(); + d->marginTop = (int)d->style->marginTop(); + d->marginRight = (int)d->style->marginRight(); + d->marginBottom = (int)d->style->marginBottom(); + invalidatePolicyAndLayout(); + } + + if (!d->userSetHorizontalSpacing) { + setHorizontalSpacing(d->style->horizontalSpacing()); //This is a virtual function so we have to call it so that subclasses receive this + d->userSetHorizontalSpacing = false; + } + + if (!d->userSetVerticalSpacing) { + setVerticalSpacing(d->style->verticalSpacing()); //This is a virtual function so we have to call it so that subclasses receive this + d->userSetVerticalSpacing = false; + } +} + +void DuiAbstractLayoutPolicy::setObjectName(const QString &name) +{ + Q_D(DuiAbstractLayoutPolicy); + if (name == d->objectName) + return; + d->objectName = name; + updateStyle(); +} +QString DuiAbstractLayoutPolicy::objectName() const +{ + Q_D(const DuiAbstractLayoutPolicy); + return d->objectName; +} + +const DuiAbstractLayoutPolicyStyle *DuiAbstractLayoutPolicy::style() const +{ + Q_D(const DuiAbstractLayoutPolicy); + if (!d->style) + const_cast(this)->updateStyle(); + return d->style; +} + +void DuiAbstractLayoutPolicy::setHorizontalSpacing(qreal spacing) +{ + Q_D(DuiAbstractLayoutPolicy); + d->userSetHorizontalSpacing = true; + if (spacing == d->horizontalSpacing) + return; + d->horizontalSpacing = spacing; + invalidatePolicyAndLayout(); +} + +qreal DuiAbstractLayoutPolicy::horizontalSpacing() const +{ + Q_D(const DuiAbstractLayoutPolicy); + if (!d->userSetHorizontalSpacing) + (void) style(); //Make sure the style is loaded + return d->horizontalSpacing; +} + +void DuiAbstractLayoutPolicy::setVerticalSpacing(qreal spacing) +{ + Q_D(DuiAbstractLayoutPolicy); + d->userSetVerticalSpacing = true; + if (spacing == d->verticalSpacing) + return; + d->verticalSpacing = spacing; + invalidatePolicyAndLayout(); +} + +qreal DuiAbstractLayoutPolicy::verticalSpacing() const +{ + Q_D(const DuiAbstractLayoutPolicy); + if (!d->userSetVerticalSpacing) + (void) style(); //Make sure the style is loaded + return d->verticalSpacing; +} + +void DuiAbstractLayoutPolicy::setSpacing(qreal spacing) +{ + setHorizontalSpacing(spacing); + setVerticalSpacing(spacing); +} + +int DuiAbstractLayoutPolicy::count() const +{ + Q_D(const DuiAbstractLayoutPolicy); + return d->items.count(); +} + +void DuiAbstractLayoutPolicy::addItem(QGraphicsLayoutItem *item) +{ + DuiAbstractLayoutPolicy::insertItem(count(), item); +} +void DuiAbstractLayoutPolicy::insertItem(int index, QGraphicsLayoutItem *item) +{ + Q_D(DuiAbstractLayoutPolicy); + if (!item) + return; + + //Note that we do not show the item, since for most policies we do not know where to place it + //until we have called relayout(). So instead we invalidate the policy, which we trigger a relayout, which will set + //the item's positions + + int layoutIndex = d->layout->addItem(item); + d->items.insert(index, layoutIndex); + //Invalidate the policy to trigger a relayout to place the new item. + //FIXME: For some policies, this is not optimal, since we might know the position of the new item without having to layout everything + invalidatePolicyAndLayout(); +} + +QGraphicsLayoutItem *DuiAbstractLayoutPolicy::itemAt(int index) const +{ + Q_D(const DuiAbstractLayoutPolicy); + if (index >= d->items.count() || index < 0) + return NULL; + return layout()->itemAt(d->items.at(index)); +} + +void DuiAbstractLayoutPolicy::setItemGeometry(int index, const QRectF &geometry) +{ + Q_D(DuiAbstractLayoutPolicy); + if (isActive()) + d->layout->d_ptr->setItemGeometry(d->items.at(index), geometry); +} + +QRectF DuiAbstractLayoutPolicy::itemGeometry(int index) const +{ + Q_D(const DuiAbstractLayoutPolicy); + return d->layout->d_ptr->itemGeometry(d->items.at(index)); +} +void DuiAbstractLayoutPolicy::hideItem(int index) +{ + Q_D(DuiAbstractLayoutPolicy); + d->layout->d_ptr->hideItem(d->items.at(index)); +} +void DuiAbstractLayoutPolicy::removeAt(int index) +{ + Q_D(DuiAbstractLayoutPolicy); + + if (isActive() && !d->removingFromLayout) //Do not hide the item if it's going to be removed from the layout totally + hideItem(index); + d->items.removeAt(index); + //This is an overkill - not all policies require laying out all the items again when one is removed + //(e.g. freestyle) + updateGeometry(); + invalidatePolicyAndLayout(); +} + +void DuiAbstractLayoutPolicy::removeItem(const QGraphicsLayoutItem *item) +{ + int index = indexOf(item); + if (index >= 0) + removeAt(index); +} + +int DuiAbstractLayoutPolicy::indexOf(const QGraphicsLayoutItem *item) const +{ + const int theCount = count(); + for (int i = 0; i < theCount; ++i) { + if (itemAt(i) == item) + return i; + } + return -1; +} + +void DuiAbstractLayoutPolicy::activated() +{ + Q_D(DuiAbstractLayoutPolicy); + const int count = d->layout->count(); + for (int i = 0; i < count; ++i) { + if (indexOf(d->layout->itemAt(i)) == -1) + d->layout->d_ptr->hideItem(i); //Item is not the policy so hide it + //if the item is currently hidden but is in the new layout, it will be shown when relayout() calls setTargetGeometry() + } + //Note that this is called from the constructor, so we can't do anything here that + //would update the style since this class is not fully constructed yet +} + +void DuiAbstractLayoutPolicy::aboutToBeRemovedFromLayout(const QGraphicsLayoutItem *item) +{ + Q_D(DuiAbstractLayoutPolicy); + d->aboutToBeRemovedFromLayout(item); +} + diff --git a/src/layout/duiabstractlayoutpolicy.h b/src/layout/duiabstractlayoutpolicy.h new file mode 100644 index 000000000..81d8e05e4 --- /dev/null +++ b/src/layout/duiabstractlayoutpolicy.h @@ -0,0 +1,530 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIABSTRACTLAYOUTPOLICY_H +#define DUIABSTRACTLAYOUTPOLICY_H + +#include "duiexport.h" + +#include +#include + +class DuiAbstractLayoutPolicyStyle; +class DuiAbstractLayoutPolicyPrivate; +class DuiLayout; + +class QGraphicsLayoutItem; +/*! + * \class DuiAbstractLayoutPolicy + * \brief The DuiAbstractLayoutPolicy class provides the base class for all DuiLayout policies. + * \ingroup layouts + * + * DuiAbstractLayoutPolicy is an abstract class that defines an API for + * arranging QGraphicsWidget, DuiWidget and other QGraphicsLayoutItem objects + * in the associated DuiLayout. + * + * A DuiLayout can have many different policies, with one of the policies being + * active at any moment. Changing a DuiLayout's active policy causes the items + * to move into a new position. + * + * \section visibility Visibility + * + * Items added to a layout will be automatically hidden and shown, depending on whether + * they are in the currently active policy. If your widget inherits DuiWidget then you can still + * manually hide an item by calling DuiWidget::hide(). + + * \section multiple_policies Multiple Policies + * + * A layout can have multiple policies associated with it. See the DuiLayout documentation for more information and examples. + * + * \sa DuiLayout, \ref layout-multiplepolicies, \ref layout-inside-layout + * + * \section styling_policy CSS Styling of Policies + * + * Policies can be styled in the CSS stylesheet files, however the class name is always + * DuiAbstractLayoutPolicy. Their object name can be set with setObjectName() and they + * can be styled different depending on the current device orientation. + * + * For example: + * + * \code + * DuiLinearLayoutPolicy mypolicy(mylayout); + * mypolicy.setObjectName("address"); + * \endcode + * could then be styled in the .css file with + * \code + * DuiAbstractLayoutPolicyStyle#address { + * vertical-spacing: 5; + * landscape-spacing: 5; + * margin-left: 10.0; + * margin-right: 10.0; + * margin-top: 10.0; + * margin-bottom: 10.0; + * } + * DuiAbstractLayoutPolicyStyle#address.Landscape { + * vertical-spacing: 0; + * } + * \endcode + * This sets the vertical spacing to be 0 pixels in landscape mode, and 5 pixels in portrait mode. + * + * \section custom_policy Writing a Custom Policy + * + * Implementing new layout policies is a straight forward process. This + * abstract base class handles registration and deregistration with + * the layout it is associated with, and by default handles the adding and + * removing of items from the policy. + * + *
+ * + * Examples for ICU format locale ID strings + * + *
Locale IDLanguageScriptCountryVariantKeywordsComment
fi_FIfiFIFinnish language in Finland, default sorting order
fi_FI@collation=phonebookfiFIcollation=phonebookFinnish language in Finland, phonebook sorting order
zh_CN@collation=stroke;calendar=chinesezhCNcollation=stroke;calendar=chineseSimplified Chinese with sorting via stroke-count and Chinese calendar
+ * + * + * + * + * + * + * + * + * + * + * + *
FunctionDescription
DuiAbstractLayoutPolicy::addItem()Add an item to the layout. The default implementation is usually sufficient (adds the item to the internal list of items, and invalidates the policy and layout). You may want to implement custom addItem functions that additionally take position, alignment etc parameters. You must call DuiAbstractLayoutPolicy::addItem() from any addItem implementation to maintain the internal state.
DuiAbstractLayoutPolicy::relayout()Triggers a relayout of items. This does the main task of laying out the items.
DuiAbstractLayoutPolicy::sizeHint()Returns the policy's size hints. This must enclose all of the items inside
+ *

+ * + * Additionally it may be useful to implement the following functions if the default behaviour is not sufficient: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
FunctionDescription
DuiAbstractLayoutPolicy::setHorizontalSpacing()Sets the horizontal spacing between items.
DuiAbstractLayoutPolicy::setVerticalSpacing()Sets the vertical spacing between items.
DuiAbstractLayoutPolicy::sizeHint()Returns the policy's size hints.
DuiAbstractLayoutPolicy::count() Returns the number of items in your layout.
DuiAbstractLayoutPolicy::itemAt() Returns a pointer to an item in your layout.
DuiAbstractLayoutPolicy::removeAt() Removes an item from your layout without destroying it.
DuiAbstractLayoutPolicy::invalidate()Notifies that an item has been added/removed or some other property has changed, requiring items to be laid out. You may want to override this to invalidate an internal model.
+ * + * For more details on how to implement each function, refer to the individual + * function documentation. + * + * Each layout defines its own API for arranging widgets and layout items. For + * example, with a grid layout, you require a row and a column index with optional + * row and column spans, alignment, spacing, and more. A linear layout, however, + * requires a single row or column index to position its items. For a grid layout, + * the order of insertion does not affect the layout in any way, but for a linear + * layout, the order is essential. When writing your own layout subclass, you are + * free to choose the API that best suits your layout. + * + * \section laying_out_item_in_custom_policy Laying out items in a custom policy + * + * For each item in a policy, the policy should at least call the + * QGraphicsLayoutItem::preferredSize() function to get the item's preferred size. + * A well-behaved policy will also respect the QGraphicsLayoutItem::sizePolicy() so + * that items can expand to take up all available space. + * + */ + +class DUI_EXPORT DuiAbstractLayoutPolicy +{ +public: + /** \brief Create a policy and associate it with the given layout + * + * The layout must not be NULL. + * The layout takes ownership of the policy, deleting the policy when the layout is deleted. If the policy + * is explicitly deleted, it will automatically be removed from the layout. + */ + explicit DuiAbstractLayoutPolicy(DuiLayout *layout); + + /*! + * \brief Destroys an abstract layout policy. + * + * If the policy was currently active, the next policy in the layout + * is automatically \link activate() activated\endlink, if available. Items in this + * policy continue to be owned by the associated DuiLayout and are + * \link QGraphicsItem::hide() hidden\endlink if not in the new policy. + * + * \sa activate() + */ + virtual ~DuiAbstractLayoutPolicy(); + + /*! + * \brief Set the content margins for this policy. + * + * This method sets the contents margins for the policy, overriding the values set in the CSS. + * + * By default, these are all -1, meaning that the DuiLayout::getContentsMargins() + * will be used. Any that are changed to be a non-negative number will override the + * value returned by DuiLayout::getContentsMargins() + * + * @param left Left margin. Set to -1 indicate to use DuiLayout's left margin + * @param top Top margin. Set to -1 indicate to use DuiLayout's top margin + * @param right Right margin. Set to -1 indicate to use DuiLayout's right margin + * @param bottom Bottom margin. Set to -1 indicate to use DuiLayout's bottom margin + * + * To use the values set in the CSS again, call unsetContentsMargins(); + * + * \sa DuiLayout::getContentsMargins() + * \sa DuiLayout::setContentsMargins() + * \sa unsetContentsMargins() + * \sa getContentsMargins() + */ + void setContentsMargins(qreal left, qreal top, qreal right, qreal bottom); + + /*! \brief Unset the contents margins for this policy, reading the values set in the CSS instead. + */ + void unsetContentsMargins(); + + /*! + * \brief Get the content margins override for this policy. + * + * This method gets the contents margins override for the policy. + * + * By default, these are all -1, meaning that the DuiLayout's getContentsMargins + * will be used. Any that are changed to be a non-negative number will override the + * value returned by DuiLayout's getContentsMargins + * + * @param left Left margin. -1 indicates to use DuiLayout's left margin + * @param top Top margin. -1 indicates to use DuiLayout's top margin + * @param right Right margin. -1 indicates to use DuiLayout's right margin + * @param bottom Bottom margin. -1 indicates to use DuiLayout's bottom margin + */ + void getContentsMargins(qreal *left, qreal *top, qreal *right, qreal *bottom) const; + + /*! + * \brief Get the layout this policy is associated with. + */ + DuiLayout *layout() const; + + /*! + * \brief Make this policy the active one. + * + * This method sets the policy as the one used by the layout to do + * all the work. + */ + void activate(); + + /*! + * \brief Whether this is the active policy. + * + * Checks whether this policy is the one currently used by the + * associated layout. + */ + bool isActive() const; + + /*! + * \brief Return the sizeHint for this policy. + * + * Implementations must ensure that the sizeHint returned encompasses all of + * the items inside, including taking into account contents margins returned from + * getContentsMargins() + * + * External classes, except for DuiLayout, should not call this directly, + * but should use DuiLayout::effectiveSizeHint() + */ + virtual QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const = 0; + + /*! + * \brief Called when the style has been changed. + * + * \sa applyStyle() + */ + void updateStyle(); + + /*! \brief Sets the name of this policy, for CSS styling. + * + * This is similar to QObject::setObjectName() and is used as + * the object name for the DuiStyle object name. + * For example: + * \code + * DuiLinearLayoutPolicy mypolicy(mylayout); + * mypolicy.setObjectName("address"); + * \endcode + * could then be styled in the .css file with + * \code + * DuiAbstractLayoutPolicy#address { + * vertical-spacing: 5; + * } + * \endcode + * + * By default the object's name is the empty string. + * + * \param name object name + */ + void setObjectName(const QString &name); + + /*! \brief Return the name of this policy, for CSS styling + * + * This is similar in functionality and usage to QObject::objectName() + * + * \sa setObjectName(const QString &) + */ + QString objectName() const; + + /*! + * \brief Set the horizontal spacing. + * + * The base implementation sets the horizontal spacing and invalidates the + * policy, triggering a relayout(). This overrides the value set in the CSS. + * + * @param spacing The spacing to use. + */ + virtual void setHorizontalSpacing(qreal spacing); + + /*! + * \brief Get the horizontal spacing. + * + * @return The spacing to use. + */ + virtual qreal horizontalSpacing() const; + + /*! + * \brief Set the vertical spacing. + * + * The base implementation sets the horizontal spacing and invalidates the + * policy, triggering a relayout(). This overrides the value set in the CSS. + * + * @param spacing The spacing to use. + */ + virtual void setVerticalSpacing(qreal spacing); + + /*! + * \brief Get the vertical spacing. + * + * @return The spacing to use. + */ + virtual qreal verticalSpacing() const; + + /*! + * \brief Convenience function to set both the horizontal and vertical spacing. + */ + virtual void setSpacing(qreal spacing); + + /*! + * \brief Returns the number of items in the policy. + */ + virtual int count() const; + + /*! + * \brief Get the item stored in the policy. + * + * Get the item found at the given index. + * + * @param index The index to check. + * @return The item at the given index or NULL if the index is invalid. + */ + virtual QGraphicsLayoutItem *itemAt(int index) const; + + /*! + * \brief Index of the given item. + * + * This function uses the virtual functions count() and itemAt() to find + * the index of the given item. + * + * Note that this takes linear, O(N), time. + * + * @param item The item to return the index of + * @return Index of the item + */ + int indexOf(const QGraphicsLayoutItem *item) const; + + /*! + * \brief Remove an item from the policy only. + * + * Remove an item from the policy, leaving it in layout. If the policy is active + * and the item is a QGraphicsWidget (or DuiWidget) then the item will be hidden + * via QGraphicsWidget::hide(). + * + * Note that layouts themselves are not a QGraphicsWidget and so will not be hidden + * when removed from another layout. So if you remove another layout from a policy, + * it will stay on the screen. You can solve this by placing the layout inside of a + * widget, and put that widget in the policy. + * + * @param index The policy index of the item to remove. + */ + virtual void removeAt(int index); + + /*! + * \brief Remove an item from the policy only. + * + * Convienence function + * + * @param item The item to remove. + */ + void removeItem(const QGraphicsLayoutItem *item); + + /*! + * \brief Return whether this policy's height depends on its width. + * + * By default this returns false. Override in custom policies to return true if the sizeHint() + * changes depending on the width. + */ + virtual bool hasHeightForWidth() const { + return false; + } + +protected: + /*! + * \brief Shared d_ptr setup constructor. + */ + explicit DuiAbstractLayoutPolicy(DuiAbstractLayoutPolicyPrivate &); + + /*! + * \brief Insert an item in the policy at the given index. + * + * Inserts @p item into the layout at @p index, or before any item that is currently at @p index. + * + * The base class function is protected since this does not make sense for all policies. Policies can + * make this function public where it is suitable, or create their own API. + * + * @param item The item to insert. + * @param index The index to place the item + */ + virtual void insertItem(int index, QGraphicsLayoutItem *item); + + /*! + * \brief Add an item to the policy. + * + * If the item is a QGraphicsWidget, it will be shown or hidden depending + * on whether it is in the active policy. + * + * Note that the order of the items in the policy is independent of the order of the items + * in the DuiLayout. + * + * @param item The item to add. + * + * \sa \ref layout-inside-layout + */ + virtual void addItem(QGraphicsLayoutItem *item); + + /*! \brief Set the target geometry of the given item to the given geometry + * + * To be used by inherited policies to set the geometry of the item. Typically called from + * relayout() and addItem(). This does nothing if the policy is not the currently active + * policy in the layout. + * + * Note that this causes the item to be shown, if it's being hidden. + */ + void setItemGeometry(int index, const QRectF &geometry); + + /*! \brief Return the target geometry of the item at the given index + */ + QRectF itemGeometry(int index) const; + + /*! \brief Hide the given item. + * + * When a policy is made active, any items not in the policy are automatically + * hidden. The rest of the items in the policy are not changed. To hide + * any items that are in the policy, call this function. + * + * To show the item again call the setItemGeometry() function. + * + * To hide items as a user of DuiLayout, see \ref visibility + */ + void hideItem(int index); + + /*! \brief Called when the style has changed (e.g the CSS file has been loaded). + * + * Inheriting policies reimplementing this should call this base class function. + * This function can be reimplemented to be read specific attributes in the CSS file. + * The pointer to the style, containing the updated values, can be accessed via the style() function + * \sa style() + */ + virtual void applyStyle(); + + /** Return the style for this policy */ + const DuiAbstractLayoutPolicyStyle *style() const; + + /*! + * \brief Callback triggered when a relayout is required. + * + * This method is triggered whenever complete relayout is required + * (e.g. when the layout itself is resized). + * + * All affected items are computed and the layout is triggered to update + * the information. + * + * You must override this method in your custom policies. + */ + virtual void relayout() = 0; + + /*! \deprecated Use removeAt() instead. There shouldn't be any need for this function. Since 0.19 + */ + virtual void Q_DECL_DEPRECATED aboutToBeRemovedFromLayout(const QGraphicsLayoutItem *item); + + /*! + * \brief Invalidate any cached size and geometry information here and invalidate layout + * If this policy is the current policy (aka activated) then it invalidates the layout. + * It then calls invalidate() which can be overridden by base classes to invalidate internal models + */ + void invalidatePolicyAndLayout(); + + /*! + * \brief Invalidate any cached size and geometry information here. + * This is called whenever the layout itself is invalidated by DuiLayout, and also called by + * invalidatePolicyAndLayout() + */ + virtual void invalidate(); + + /*! This virtual function discards any cached size hint information. + * You should always call this function if you change the return value of the + * sizeHint() function. Subclasses must always call the base implementation + * when reimplementing this function. + */ + virtual void updateGeometry(); + + /*! + * \brief Get the current content rectangle of the layout. + * + * Be aware that these coordinates are not local, this is different to + * contentsRect() + */ + QRectF contentsArea() const; + + /*! + * \brief Called by the layout when the policy is made active. + * + * The base class implementation hides all the items not in this policy, + * and shows all items that are in this policy. + */ + virtual void activated(); + + // shared d_ptr: + DuiAbstractLayoutPolicyPrivate *const d_ptr; + +private: + Q_DISABLE_COPY(DuiAbstractLayoutPolicy) + Q_DECLARE_PRIVATE(DuiAbstractLayoutPolicy) + + friend class DuiLayout; + friend class DuiLayoutPrivate; +}; + +#endif // Header Guard diff --git a/src/layout/duiabstractlayoutpolicy_p.cpp b/src/layout/duiabstractlayoutpolicy_p.cpp new file mode 100644 index 000000000..6d8b59aae --- /dev/null +++ b/src/layout/duiabstractlayoutpolicy_p.cpp @@ -0,0 +1,68 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiabstractlayoutpolicy_p.h" +#include + +DuiAbstractLayoutPolicyPrivate::DuiAbstractLayoutPolicyPrivate(DuiLayout *l) : + layout(l), + marginLeft(-1), //Negative number means to not override DuiLayout + marginTop(-1), + marginRight(-1), + marginBottom(-1), + horizontalSpacing(0), + verticalSpacing(0), + userSetVerticalSpacing(false), + userSetHorizontalSpacing(false), + userSetContentsMargins(false), + style(NULL), + removingFromLayout(false) +{ + Q_ASSERT(0 != layout); +} + +DuiAbstractLayoutPolicyPrivate::~DuiAbstractLayoutPolicyPrivate() +{ } + +void DuiAbstractLayoutPolicyPrivate::aboutToBeRemovedFromLayout(const QGraphicsLayoutItem *item) +{ + //The item is about to be removed from the layout, so we need to remove it from this policy too + //This gets called even if the item is not in this policy, so that we can update the items mapping + Q_Q(DuiAbstractLayoutPolicy); + + // First remove the item from this policy, if it is in this policy + int policyIndex = q->indexOf(item); + if (policyIndex > -1) { + removingFromLayout = true; + q->removeItem(item); + removingFromLayout = false; + } + + //Now update all of the indexes + int layoutIndex = layout->indexOf(item); //This should always succeed + Q_ASSERT(layoutIndex >= 0); + + const int count = items.count(); + for (int i = 0; i < count; ++i) { + int currentLayoutIndex = items.at(i); + if (currentLayoutIndex > layoutIndex) + items[i] = currentLayoutIndex - 1; + } +} + diff --git a/src/layout/duiabstractlayoutpolicy_p.h b/src/layout/duiabstractlayoutpolicy_p.h new file mode 100644 index 000000000..64ce2fdbb --- /dev/null +++ b/src/layout/duiabstractlayoutpolicy_p.h @@ -0,0 +1,89 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIABSTRACTLAYOUTPOLICY_P_H +#define DUIABSTRACTLAYOUTPOLICY_P_H + +#include "duiabstractlayoutpolicy.h" +#include +#include + +class DuiAbstractLayoutPolicyStyle; +class DuiLayout; +/** Private policy class. */ +class DuiAbstractLayoutPolicyPrivate +{ + Q_DECLARE_PUBLIC(DuiAbstractLayoutPolicy) + +public: + /** Constructor */ + explicit DuiAbstractLayoutPolicyPrivate(DuiLayout *); + /** Destructor */ + virtual ~DuiAbstractLayoutPolicyPrivate(); + + void aboutToBeRemovedFromLayout(const QGraphicsLayoutItem *item); + + /** The layout we are associated with. */ + DuiLayout *const layout; + + /** Left margin */ + qreal marginLeft; + + /** Top margin */ + qreal marginTop; + + /** Right margin */ + qreal marginRight; + + /** Bottom margin */ + qreal marginBottom; + + /** Horizontal spacing between items */ + qreal horizontalSpacing; + + /** Vertical spacing between items */ + qreal verticalSpacing; + + /** Whether the user has manually called setVerticalSpacing */ + bool userSetVerticalSpacing; + + /** Whether the user has manually called setHorizontalSpacing */ + bool userSetHorizontalSpacing; + + /** Whether the user has manually called setContentsMargins */ + bool userSetContentsMargins; + + /** Style for the abstract policy, but can be also used for inheriting policies */ + const DuiAbstractLayoutPolicyStyle *style; + + /** Name for this policy for DuiStyle. Similar to the QObject::objectName() property */ + QString objectName; + + /** List of items in this policy, as an index of layout */ + QList items; + + /** This is true if we are currently removing an item from the layout */ + bool removingFromLayout; + +protected: + // Shared d_ptr related code: + DuiAbstractLayoutPolicy *q_ptr; +}; + +#endif // Header Guard diff --git a/src/layout/duibasiclayoutanimation.cpp b/src/layout/duibasiclayoutanimation.cpp new file mode 100644 index 000000000..ad75032bc --- /dev/null +++ b/src/layout/duibasiclayoutanimation.cpp @@ -0,0 +1,192 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duibasiclayoutanimation.h" +#include "duibasiclayoutanimation_p.h" +#include "duibasiclayoutanimationstyle.h" +#include "duilayouthelper_p.h" + +#include +#include +#include +DuiBasicLayoutAnimation::DuiBasicLayoutAnimation(DuiLayout *layout) : + DuiLayoutAnimation(*(new DuiBasicLayoutAnimationPrivate()), layout) +{ + Q_D(DuiBasicLayoutAnimation); + d->q_ptr = this; + setLoopCount(-1); +} + +DuiBasicLayoutAnimation::~DuiBasicLayoutAnimation() { } + +void DuiBasicLayoutAnimation::animate(DuiItemState &item) +{ + Q_D(DuiBasicLayoutAnimation); + + QRectF target(item.targetGeometry()); + QRectF start(item.sourceGeometry()); + qreal delta_progress = d->recordedTimeSinceLastUpdate / style()->duration(); //Both times are in milliseconds + + //First animate the geometry if needed + if (item.geometryProgress() != 1) { + //animate the geometry + qreal new_geometry_progress = qMin(item.geometryProgress() + delta_progress, (qreal)1.0); //between 0 and 1 + item.setGeometryProgress(new_geometry_progress); + qreal geometry_animation_value = style()->geometryEasingCurve().valueForProgress(new_geometry_progress); + if (item.geometryProgress() == 1) { + item.item()->setGeometry(target); + } else { + QSizeF new_size = start.size() + (target.size() - start.size()) * geometry_animation_value; + new_size = new_size.boundedTo(item.item()->maximumSize()).expandedTo(item.item()->minimumSize()); + QPointF new_position = start.center() - QPointF(new_size.width() / 2, new_size.height() / 2) + (target.center() - start.center()) * geometry_animation_value; + QRectF new_geometry(new_position, new_size); + if (item.item()->geometry() != new_geometry) + item.item()->setGeometry(new_geometry); + } + } + + //Then animate the opacity if needed + if (item.opacityProgress() != 1 && item.targetOpacity() != -1) { //-1 target opacity means to not animate anyway + //animate the opacity + qreal new_opacity_progress = qMin(item.opacityProgress() + delta_progress, (qreal)1.0); //between 0 and 1 + item.setOpacityProgress(new_opacity_progress); + qreal opacity_animation_value = style()->opacityEasingCurve().valueForProgress(new_opacity_progress); + + qreal current_opacity = item.currentOpacity(); + if (current_opacity != -1) { + qreal new_opacity = item.sourceOpacity() + (item.targetOpacity() - item.sourceOpacity()) * opacity_animation_value; + new_opacity = qAbs(new_opacity); //make sure it is between 0 and 1 + if (new_opacity > 1) + new_opacity = qMax((float)qAbs(2 - new_opacity), 1.0f); + item.setCurrentOpacity(new_opacity); + } + } + + //Have we finished with this item now? + if (item.opacityProgress() == 1 && item.geometryProgress() == 1) { + if (item.isSet(DuiItemState::STATE_FLAG_TO_BE_HIDDEN)) { + if (item.targetOpacity() != -1) + item.setCurrentOpacity(1); //Restore the opacity to 1, since we are hiding it now anyway + hideItemNow(item.item()); + } + item.animationDone(); + } +} + +void DuiBasicLayoutAnimation::layoutAnimationFinished() +{ + stop(); +} + +void DuiBasicLayoutAnimation::doItemHiddenAnimation(DuiItemState *itemstate) +{ + Q_ASSERT(itemstate->item()); + // for item hiding it should deflate from its current size to final-hiding-scale-factor + qreal finalScaleFactor = style()->finalHidingScaleFactor(); + QRectF finalGeometry; + if (finalScaleFactor == 1.0) { + finalGeometry = itemstate->item()->geometry(); + } else { + QSizeF size = itemstate->item()->effectiveSizeHint(Qt::MinimumSize); + if (finalScaleFactor > 0) { + size = size.expandedTo(itemstate->item()->geometry().size() * finalScaleFactor) + .boundedTo(itemstate->item()->effectiveSizeHint(Qt::MaximumSize)); + } + finalGeometry = QRectF(QPointF(0, 0), size); + finalGeometry.moveCenter(itemstate->item()->geometry().center()); + } + + if (itemstate->targetGeometry().size() != finalGeometry.size()) + itemstate->setTargetGeometry(finalGeometry); + + QGraphicsItem *graphicsItem = itemstate->item()->graphicsItem(); + if (graphicsItem) { + qreal finalOpacity = style()->finalHidingOpacity(); + if (finalOpacity >= 0 && finalOpacity < 1) //If it ==1 there's no need to do anything + itemstate->setTargetOpacity(finalOpacity); + } +} +void DuiBasicLayoutAnimation::doItemShownAnimation(DuiItemState *itemstate) +{ + Q_ASSERT(itemstate->item()); + if (itemstate->isSet(DuiItemState::STATE_FLAG_SHOWING)) { + //If the item is already visible, this can be called because we were currently doing a hide animation. + //So just make sure that we make everything visible + showItemNow(itemstate->item()); + QGraphicsItem *graphicsItem = itemstate->item()->graphicsItem(); + if (graphicsItem) { + itemstate->setTargetOpacity(1); + graphicsItem->setOpacity(1); + } + return; + } + //If the item that started this animation is to be added/shown, set the initial geometry + qreal initialScaleFactor = style()->initialShowingScaleFactor(); + QRectF initialGeometry; + + if (initialScaleFactor == 1.0) { + initialGeometry = itemstate->targetGeometry(); + } else { + QSizeF size = itemstate->item()->effectiveSizeHint(Qt::MinimumSize); + if (initialScaleFactor != 0.0) { + size = size.expandedTo(itemstate->targetGeometry().size() * initialScaleFactor) + .boundedTo(itemstate->item()->effectiveSizeHint(Qt::MaximumSize)); + } + initialGeometry = QRectF(QPointF(0, 0), size); + initialGeometry.moveCenter(itemstate->targetGeometry().center()); + } + + itemstate->setGeometry(initialGeometry); + + showItemNow(itemstate->item()); + QGraphicsItem *graphicsItem = itemstate->item()->graphicsItem(); + if (graphicsItem) { + qreal initialOpacity = style()->initialShowingOpacity(); + if (initialOpacity != 1.0) { + graphicsItem->setOpacity(initialOpacity); + itemstate->setTargetOpacity(1); + } + } +} + +void DuiBasicLayoutAnimation::layoutAnimationStarted(DuiItemState *itemstate) +{ + if (!itemstate) + return; + + start(); + //Since start() calls updateCurrentTime immediately, which in turn can call stop() + //if the animation finishes immediately, which in turn can end up deleting the object, + //we cannot rely on itemstate.item() being valid after this point +} + +void DuiBasicLayoutAnimation::updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState) +{ + Q_D(DuiBasicLayoutAnimation); + Q_UNUSED(oldState); + if (newState == Running) + d->timeSinceLastUpdate.restart(); +} +void DuiBasicLayoutAnimation::updateCurrentTime(int msecs) +{ + Q_D(DuiBasicLayoutAnimation); + Q_UNUSED(msecs); + d->tick(); +} + diff --git a/src/layout/duibasiclayoutanimation.h b/src/layout/duibasiclayoutanimation.h new file mode 100644 index 000000000..b276e553e --- /dev/null +++ b/src/layout/duibasiclayoutanimation.h @@ -0,0 +1,90 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIBASICLAYOUTANIMATION_H +#define DUIBASICLAYOUTANIMATION_H + +#include "duilayoutanimation.h" +#include "duibasiclayoutanimationstyle.h" +#include "duianimation.h" + +class DuiBasicLayoutAnimationPrivate; + +/*! + * The DuiBasicLayoutAnimation provides a simple animation of items for a DuiLayout. + * It animates the items geometry and opacity in a linear way, with every animation + * taking the same amount of time. + */ +class DUI_EXPORT DuiBasicLayoutAnimation : public DuiLayoutAnimation +{ + DUI_ANIMATION(DuiBasicLayoutAnimationStyle) +public: + /** \brief Construct a basic layout animator. + */ + DuiBasicLayoutAnimation(DuiLayout *layout); + + /** \brief Destructor. */ + virtual ~DuiBasicLayoutAnimation(); + + /*! \brief This provides an animation to shown an item. + * + * This sets the item's current geometry to its minimum size, centering + * it on its DuiItemState::targetGeometry(). This provides an animation + * of the item 'growing' to its final size. + * */ + virtual void doItemShownAnimation(DuiItemState *itemstate); + + /*! \brief This provides an animation to hide an item. + * + * This sets the DuiItemState::targetGeometry() to the items minimum size, centering + * on its current position. This provides an animation of the item 'shrinking' before being + * removed. + */ + virtual void doItemHiddenAnimation(DuiItemState *itemstate); + +protected: + /*! + * \brief This method animates an item. + * + * This method is doing the actual animation of the objects + * in the layouts. + * + * @param layout The layout containing the item to animate. + * @param state The info about the layout item to animate. + */ + virtual void animate(DuiItemState &state); + + /*! \reimp */ + virtual void layoutAnimationStarted(DuiItemState *itemstate); + virtual void layoutAnimationFinished(); + + virtual void updateCurrentTime(int msecs); + virtual void updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState); + virtual int duration() const { + return -1; + } + /*! \reimp_end */ + +private: + Q_DISABLE_COPY(DuiBasicLayoutAnimation) + Q_DECLARE_PRIVATE_D(DuiLayoutAnimation::d_ptr, DuiBasicLayoutAnimation) + +}; + +#endif // Header Guard diff --git a/src/layout/duibasiclayoutanimation_p.cpp b/src/layout/duibasiclayoutanimation_p.cpp new file mode 100644 index 000000000..56cc0169a --- /dev/null +++ b/src/layout/duibasiclayoutanimation_p.cpp @@ -0,0 +1,52 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duibasiclayoutanimation_p.h" +#include "duilayout_p.h" + +DuiBasicLayoutAnimationPrivate::DuiBasicLayoutAnimationPrivate() +{ } + +DuiBasicLayoutAnimationPrivate::~DuiBasicLayoutAnimationPrivate() +{ } + +void DuiBasicLayoutAnimationPrivate::tick() +{ + Q_Q(DuiBasicLayoutAnimation); + recordedTimeSinceLastUpdate = timeSinceLastUpdate.elapsed(); + timeSinceLastUpdate.restart(); + + bool layout_is_done(true); + const int size = layout->d_ptr->states.size(); + for (int i = 0; i < size; ++i) { + if (layout->d_ptr->states.at(i).isAnimationDone()) + continue; + + DuiItemState state(layout->d_ptr->states.at(i)); + q->animate(state); + layout->d_ptr->states[i] = state; + + if (!layout->d_ptr->states.at(i).isAnimationDone()) + layout_is_done = false; + } + if (layout_is_done) { + // notify layout and derived animators + q->stopAnimation(); + } +} diff --git a/src/layout/duibasiclayoutanimation_p.h b/src/layout/duibasiclayoutanimation_p.h new file mode 100644 index 000000000..c6b6cd172 --- /dev/null +++ b/src/layout/duibasiclayoutanimation_p.h @@ -0,0 +1,54 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIBASICLAYOUTANIMATION_P_H +#define DUIBASICLAYOUTANIMATION_P_H + +#include "duibasiclayoutanimation.h" +#include "duilayoutanimation_p.h" + +#include +#include +#include +#include + +/** Private animator class. */ +class DuiBasicLayoutAnimationPrivate : public DuiLayoutAnimationPrivate +{ + Q_DECLARE_PUBLIC(DuiBasicLayoutAnimation) +public: + /** Constructor */ + DuiBasicLayoutAnimationPrivate(); + /** Destructor */ + virtual ~DuiBasicLayoutAnimationPrivate(); + + /** Keep track of the time elapsed since the last update. + * This is used because we may miss some timer events. + */ + QTime timeSinceLastUpdate; + /** The number of milliseconds elapsed since last update + * + * This records the value of timeSinceLastUpdate when an update happens + */ + qreal recordedTimeSinceLastUpdate; + /** Trigger animation step. */ + void tick(); +}; + +#endif // Header Guard diff --git a/src/layout/duiflowlayoutpolicy.cpp b/src/layout/duiflowlayoutpolicy.cpp new file mode 100644 index 000000000..e0e2f025d --- /dev/null +++ b/src/layout/duiflowlayoutpolicy.cpp @@ -0,0 +1,246 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiflowlayoutpolicy.h" +#include "duiflowlayoutpolicy_p.h" +#include "duilayout.h" + +#include +DuiFlowLayoutPolicy::DuiFlowLayoutPolicy(DuiLayout *layout) : + DuiAbstractLayoutPolicy(*(new DuiFlowLayoutPolicyPrivate(layout))) +{ } + +DuiFlowLayoutPolicy::~DuiFlowLayoutPolicy() +{ } + +void DuiFlowLayoutPolicy::addItem(QGraphicsLayoutItem *item) +{ + DuiAbstractLayoutPolicy::addItem(item); +} +void DuiFlowLayoutPolicy::insertItem(int index, QGraphicsLayoutItem *item) +{ + DuiAbstractLayoutPolicy::insertItem(index, item); +} +QSizeF DuiFlowLayoutPolicy::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const +{ + Q_D(const DuiFlowLayoutPolicy); + QSizeF new_size = constraint; + if (which == Qt::MaximumSize) { + if (new_size.width() < 0) + new_size.setWidth(QWIDGETSIZE_MAX); + if (new_size.height() < 0) + new_size.setHeight(QWIDGETSIZE_MAX); + return new_size; + } + //TODO - return (0,0) for PreferredSize? Since this will be rounded up to MinimumSize automatically + qreal left, top, right, bottom; + d->layout->getContentsMargins(&left, &top, &right, &bottom); + + // There is a Qt bug 257455 which means that we aren't always passed the width constraint + // To try to work around this, we use the current width as the constraint for finding the height, + // and return that as the preferred width. + // + // http://www.qtsoftware.com/developer/task-tracker/index_html?method=entry&id=257455 + // + // FIXME we should be able to remove this when/if Qt bug 257455 is fixed + qreal constraintWidth; //ideally this would just be same as new_size.width(), but it needs to be different to work around this bug.. + if (new_size.width() < 0) { + qreal width = 0; + const int theCount = count(); + for (int i = 0; i < theCount; ++i) { + QGraphicsLayoutItem *item = itemAt(i); + //The flow layout would become insanely more difficult if we want to find out the + //minimum size based on the minimum size of the widgets. Instead we use the + //preferred size as the minimum size + width = qMax(width, item->effectiveSizeHint(Qt::PreferredSize).width()); + } + if (which == Qt::MinimumSize) + new_size.setWidth(width); + // Set to the current width, expanded to the largest preferred width of the widgets + constraintWidth = qMax(d->layout->geometry().width() - (left + right), width); + if (which == Qt::PreferredSize) + new_size.setWidth(constraintWidth); + } else { + //subtract the margins from the given constraint + constraintWidth = qMax(new_size.width() - (left + right), (qreal)0.0); + new_size.setWidth(constraintWidth); + } + + + //We are now Qt::PreferredSize or Qt::MinimumSize, and we have a width constraint + QPointF current_position; + qreal current_rowheight = 0; + int rowCount = 0; + const int theCount = count(); + for (int i = 0; i < theCount; ++i) { + const QGraphicsLayoutItem *item = itemAt(i); + //We use the preferredsize for both the minimum and preferred sizeHints since + //doing otherwise would make this code a lot more complicated + QSizeF size = item->effectiveSizeHint(Qt::PreferredSize); + if (size.width() > constraintWidth) + size = item->effectiveSizeHint(Qt::PreferredSize, QSizeF(constraintWidth, -1)); + bool sameRow = d->roomForItemOnCurrentRow(size, constraintWidth, ¤t_position, ¤t_rowheight); + if (sameRow) { + //It fits on the same row + current_position.rx() += size.width(); + } else if ((uint)++rowCount >= (uint)d->rowLimit) { + break; //we have reached the maximum number of rows + } else { + //Place item on the next row + current_position.rx() = size.width(); + current_position.ry() += current_rowheight + d->verticalSpacing; + current_rowheight = size.height(); + } + } + + new_size.setHeight(current_position.y() + current_rowheight); + new_size += QSizeF(left + right, top + bottom); + return new_size; +} +int DuiFlowLayoutPolicy::rowCount() +{ + Q_D(DuiFlowLayoutPolicy); + if (d->numberOfRows == -1 && isActive()) //the layout is invalidated - we need to relayout first + layout()->activate(); + if (d->numberOfRows == -1) + return -1; + + return qMin((uint)d->numberOfRows, (uint)d->rowLimit); +} +void DuiFlowLayoutPolicy::invalidate() +{ + Q_D(DuiFlowLayoutPolicy); + d->numberOfRows = -1; +} + +void DuiFlowLayoutPolicy::relayout() +{ + Q_D(DuiFlowLayoutPolicy); + + /* The items are laid out in one or two passes. + * + * If the items are to be horizontally justified, then we want to expand all the items so that + * the right hand edge aligns with the side of the layout. + * This is done by making two passes over each row. The first pass determines what items + * can fit into the current row and how much space is left over. + * The second pass divides up the left over space among the items and actually sets their + * target positions + */ + QPointF origin = contentsArea().topLeft(); + qreal constraintWidth = contentsArea().width(); + QPointF current_position; + d->numberOfRows = 0; + int i = 0; + while (i < count() && (uint)d->numberOfRows < (uint)d->rowLimit) { + //for each row + //find the end of this row + qreal current_rowheight = 0; + int num_expandable = 0; + int row_start = i; //The item index at the start of a row + while (i < count()) { + QGraphicsLayoutItem *item = itemAt(i); + QSizeF size = item->effectiveSizeHint(Qt::PreferredSize); + if (size.width() > constraintWidth) { + //If the object's preferred size is too big to fit, try constraining it + size = item->effectiveSizeHint(Qt::PreferredSize, QSizeF(constraintWidth, -1)); + } + bool sameRow = d->roomForItemOnCurrentRow(size, constraintWidth, ¤t_position, ¤t_rowheight); + //check if we have finished with this row + if (sameRow) { + if (item->sizePolicy().expandingDirections().testFlag(Qt::Horizontal)) + num_expandable++; + current_position.rx() += size.width(); + i++; + } else + break; //we have finished with this row + } + qreal leftover_space = constraintWidth - current_position.x(); + + //Originally the code asserted if you try to add a big (minimum size) + //object into a small (maximum size) layout, but sometimes users do silly + //things and we need to handle that gracefully. +// Q_ASSERT(leftover_space >= -0.00001); //slight rounding errors can results in the number being just slightly less than 0 + //set the current position back to the start of the row + current_position.setX(0); + //we now know how wide this row would be, if we used preferred size. Allow stretching + //The row goes from "row_start" to "i-1", inclusive. + for (int j = row_start; j < i; ++j) { + QGraphicsLayoutItem *item = itemAt(j); + //get the size again + QSizeF size = item->effectiveSizeHint(Qt::PreferredSize); + if (size.width() > constraintWidth) + size = item->effectiveSizeHint(Qt::PreferredSize, QSizeF(constraintWidth, -1)); + d->roomForItemOnCurrentRow(size, constraintWidth, ¤t_position); +// Q_ASSERT(sameRow); + + Qt::Orientations expandable = item->sizePolicy().expandingDirections(); + QSizeF maxSize; + if (expandable) + maxSize = item->effectiveSizeHint(Qt::MaximumSize); + //let the items expand vertically if they want to + if (size.height() != current_rowheight && expandable.testFlag(Qt::Vertical)) { + //expand item to rowheight, making sure we don't exceed max size + size.setHeight(qMin(maxSize.height(), current_rowheight)); + } + + if (leftover_space > 0 && expandable.testFlag(Qt::Horizontal)) { + //distribute remaining leftover space to items left to process + //making sure that we don't exceed the maximum size + //Note that this isn't a great algorithm. It won't look very good if some items + //do have a maximum width + qreal expand_by = qMin(leftover_space / num_expandable, maxSize.width() - size.width()); + size.setWidth(size.width() + expand_by); + leftover_space -= expand_by; + Q_ASSERT(leftover_space >= -0.00001); //slight rounding errors can results in the number being just slightly less than 0 + --num_expandable; + } + + QRectF geometry = QRectF(origin, size); + if (layout()->layoutDirection() == Qt::LeftToRight) + geometry.translate(current_position); + else + geometry.translate(constraintWidth - current_position.x() - size.width() , current_position.y()); + + current_position.rx() += size.width(); + + //now position this item + setItemGeometry(j, geometry); + } + current_position.rx() = 0; + current_position.ry() += current_rowheight + d->verticalSpacing; + d->numberOfRows++; + } + //Hide any unplaced items - this can happen if we reached d->rowLimit + while (i < count()) { + hideItem(i++); + } +} + +void DuiFlowLayoutPolicy::setRowLimit(int rowLimit) +{ + Q_D(DuiFlowLayoutPolicy); + d->rowLimit = rowLimit; + invalidatePolicyAndLayout(); +} +int DuiFlowLayoutPolicy::rowLimit() const +{ + Q_D(const DuiFlowLayoutPolicy); + return d->rowLimit; +} + diff --git a/src/layout/duiflowlayoutpolicy.h b/src/layout/duiflowlayoutpolicy.h new file mode 100644 index 000000000..04385897b --- /dev/null +++ b/src/layout/duiflowlayoutpolicy.h @@ -0,0 +1,119 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIFLOWLAYOUTPOLICY_H +#define DUIFLOWLAYOUTPOLICY_H + +#include "duiabstractlayoutpolicy.h" +#include "duilayout.h" + +class DuiFlowLayoutPolicyPrivate; + +/*! + * \class DuiFlowLayoutPolicy + * + * \brief This policy implements a simple flow layout. + * \ingroup layouts + * + * The items in the policy are organised into rows, starting from the top left. + * The size of each item is initially determined by its + * \link QGraphicsLayoutItem::preferredSize() preferredSize()\endlink. + * Items with an expanding \link QGraphicsLayoutItem::sizePolicy() sizePolicy()\endlink + * are then expanded horizontally and vertically to fill any left over available space. + * + * The following example adds 10 labels to the flow layout policy: + * + * \dontinclude duiflowlayoutpolicy/duiflowlayoutpolicy.cpp + * \skip Create a DuiLayout + * \until } + * + * The result, with appropriate CSS styling, looks like: + * \image html duiflowlayoutpolicy.png + * + * \sa \ref layout-duiflowlayoutpolicy + * + * \section duibuttonsInFlowLayout Using DuiButton in a DuiFlowLayoutPolicy + * + * In the default CSS theme, a DuiButton has a fixed \link QGraphicsLayoutItem::preferredWidth() preferredWidth()\endlink, + * which does not depend on the text inside of it. This makes sense normally for buttons, + * but does not usually produce the desired behaviour in a flow layout. + * Every DuiButton in a DuiFlowLayoutPolicy will have the same width. + * + */ +class DUI_EXPORT DuiFlowLayoutPolicy : public DuiAbstractLayoutPolicy +{ +public: + /*! + * \brief Constructs a flow layout policy. + */ + explicit DuiFlowLayoutPolicy(DuiLayout *); + + /*! + * \brief Destroys a flow layout policy. + * + * \sa ~DuiAbstractLayoutPolicy() + */ + virtual ~DuiFlowLayoutPolicy(); + + /*! + * \brief Return the number of rows that the items in the flow layout occupy in its current geometry. + * + * The number of rows depends on the layout's current geometry, and the layout's geometry is not usually + * set until show() has been called. This will not be greater than rowLimit(), if set. + * + * If the policy is not currently active, and has since been \link invalidate() invalidated\endlink, this will return -1. + * If the policy is currently active and has been invalidated, this will trigger a relayout. + * + * @return The number of rows in the current geometry, or -1 if \link invalidate() invalidated\endlink and not active + */ + int rowCount(); + + /*! \brief Set the maximum number of rows to show. + * + * No more than @p rowLimit rows will be shown. The rest of the items will be hidden. + * + * The default is -1, indicating no row limit */ + void setRowLimit(int rowLimit); + + /*! \brief Return the maximum number of rows to show. + * + * No more than @p rowLimit rows will be shown. The rest of the items will be hidden. + * + * The default is -1, indicating no row limit */ + int rowLimit() const; + + /*! \reimp */ + virtual QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const; + virtual void addItem(QGraphicsLayoutItem *item); + virtual void insertItem(int index, QGraphicsLayoutItem *item); + + virtual void invalidate(); +protected: + virtual void relayout(); + virtual bool hasHeightForWidth() const { + return true; + } + /*! \reimp_end */ + +private: + Q_DISABLE_COPY(DuiFlowLayoutPolicy) + Q_DECLARE_PRIVATE(DuiFlowLayoutPolicy) +}; + +#endif // Header Guard diff --git a/src/layout/duiflowlayoutpolicy_p.cpp b/src/layout/duiflowlayoutpolicy_p.cpp new file mode 100644 index 000000000..0db6738c2 --- /dev/null +++ b/src/layout/duiflowlayoutpolicy_p.cpp @@ -0,0 +1,48 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiflowlayoutpolicy_p.h" + +DuiFlowLayoutPolicyPrivate::DuiFlowLayoutPolicyPrivate(DuiLayout *l) : + DuiAbstractLayoutPolicyPrivate(l) +{ + numberOfRows = -1; + rowLimit = -1; +} + +DuiFlowLayoutPolicyPrivate::~DuiFlowLayoutPolicyPrivate() +{ } + +bool DuiFlowLayoutPolicyPrivate::roomForItemOnCurrentRow(const QSizeF &item_size, const qreal &constraint_width, QPointF *position, qreal *row_height) const +{ + Q_ASSERT(position); + if (constraint_width != -1 //no width constraint, so everything will go on the first row + && (position->x() != 0) //Force the first item on a row to always fit in that row + && (position->x() + item_size.width() + horizontalSpacing > constraint_width)) // if the item doesn't fit into the current row, return false + return false; + + else if (position->x() != 0) { //the item fits into the current row and is not the first item + position->rx() += horizontalSpacing; + if (row_height) + *row_height = qMax(*row_height, item_size.height()); + } else if (row_height) //the item fits into the current row and is the first item + *row_height = item_size.height(); + return true; +} + diff --git a/src/layout/duiflowlayoutpolicy_p.h b/src/layout/duiflowlayoutpolicy_p.h new file mode 100644 index 000000000..26b470b46 --- /dev/null +++ b/src/layout/duiflowlayoutpolicy_p.h @@ -0,0 +1,57 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIFLOWLAYOUTPOLICY_P_H +#define DUIFLOWLAYOUTPOLICY_P_H + +#include "duiflowlayoutpolicy.h" +#include "duiabstractlayoutpolicy_p.h" + +/** Implementation class for DuiFlowLayoutPolicy. + * + * As the flow layout policy currently does not need any private data, this + * class does nothing and exists purely to keep the inheritance trees of + * private and public classes in sync. + */ +class DuiFlowLayoutPolicyPrivate : public DuiAbstractLayoutPolicyPrivate +{ + Q_DECLARE_PUBLIC(DuiFlowLayoutPolicy) + +public: + /** Constructor */ + explicit DuiFlowLayoutPolicyPrivate(DuiLayout *l); + /** Destructor */ + virtual ~DuiFlowLayoutPolicyPrivate(); + + /** Modify the position and row_height parameters accordingly to place the next item, with the given + * current position, item size and constraint size, as long as the item can fit on the current row. + * If the item does not fit on the current row, position and row_height are not changed. + * @p position must not be NULL. @row_height can be NULL + * @return True if the item fits on this row, False otherwise + */ + bool roomForItemOnCurrentRow(const QSizeF &item_size, const qreal &constraint_width, QPointF *position, qreal *row_height = NULL) const; + + /** Number of rows that the items occupy. -1 if not known (because we need to call relayout() first) */ + int numberOfRows; + + /** Maximum number of rows of items to show. -1 if no limit */ + int rowLimit; +}; + +#endif // Header Guard diff --git a/src/layout/duifreestylelayoutpolicy.cpp b/src/layout/duifreestylelayoutpolicy.cpp new file mode 100644 index 000000000..5d6aa4881 --- /dev/null +++ b/src/layout/duifreestylelayoutpolicy.cpp @@ -0,0 +1,148 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duifreestylelayoutpolicy.h" +#include "duifreestylelayoutpolicy_p.h" +#include +DuiFreestyleLayoutPolicy::DuiFreestyleLayoutPolicy(DuiLayout *layout) : + DuiAbstractLayoutPolicy(*(new DuiFreestyleLayoutPolicyPrivate(layout))) +{ } + +DuiFreestyleLayoutPolicy::~DuiFreestyleLayoutPolicy() +{ } + +void DuiFreestyleLayoutPolicy::addItem(QGraphicsLayoutItem *item) +{ + addItemAtGeometry(item, QRectF(contentsArea().topLeft(), item->effectiveSizeHint(Qt::PreferredSize))); +} + +void DuiFreestyleLayoutPolicy::addItemAtGeometry(QGraphicsLayoutItem *item, const QRectF &geom) +{ + Q_D(DuiFreestyleLayoutPolicy); + + DuiAbstractLayoutPolicy::addItem(item); + + QPointF topLeft = contentsArea().topLeft(); + + //set the item's geometry to geom, bounded by the item's minimum and maximum + //size. + QSizeF maximum = item->effectiveSizeHint(Qt::MaximumSize); + QSizeF minimum = item->effectiveSizeHint(Qt::MinimumSize); + QRectF new_geometry = QRectF(geom.topLeft(), geom.size().boundedTo(maximum).expandedTo(minimum)); + + QList new_geometries; + const int size = count(); + for (int i = 0; i < size - 1; ++i) + new_geometries << itemGeometry(i); + + //Add the new item to the list of geometries and place it + new_geometries << new_geometry; + d->placeItem(size - 1, new_geometries, topLeft, contentsArea().width()); + + for (int i = 0; i < size; ++i) + setItemGeometry(i, new_geometries.at(i)); + + updateGeometry(); +} + +void DuiFreestyleLayoutPolicy::moveItemTo(QGraphicsLayoutItem *item, const QRectF &geom) +{ + Q_D(DuiFreestyleLayoutPolicy); + + int index = indexOf(item); + if (index < 0) + return; //Item not found + + QPointF topLeft = contentsArea().topLeft(); + QList new_geometries; + + const int size = count(); + for (int i = 0; i < size; ++i) + new_geometries << itemGeometry(i); + + new_geometries[index] = geom; + + d->placeItem(index, new_geometries, topLeft, contentsArea().width()); + + for (int i = 0; i < size; ++i) + setItemGeometry(i, new_geometries.at(i)); + updateGeometry(); +} + +void DuiFreestyleLayoutPolicy::relayout() +{ + Q_D(DuiFreestyleLayoutPolicy); + + QPointF topLeft = contentsArea().topLeft(); + + QList new_geometries; + const int size = count(); + for (int i = 0; i < size; ++i) { + new_geometries << itemGeometry(i); + d->placeItem(i, new_geometries, topLeft, contentsArea().width()); + } + + QRectF area = contentsArea(); + for (int i = 0; i < size; ++i) { + area = area.united(new_geometries.at(i)); + setItemGeometry(i, new_geometries.at(i)); + } + + //if we have moved items outside of the bounding box, we need to invalidate the layout + //causing another relayout, but we have to be careful that we don't end up in an + //infinite loop because of this. + if (area.isValid() && !contentsArea().adjusted(-0.0000001, -0.0000001, 0.0000001, 0.0000001).contains(area)) //adjust for rounding errors + updateGeometry(); +} + +void DuiFreestyleLayoutPolicy::removeAt(int index) +{ + DuiAbstractLayoutPolicy::removeAt(index); + //since we've removed an item, our size hint would have changed. invalidate our preferred size etc + updateGeometry(); +} + +QSizeF DuiFreestyleLayoutPolicy::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const +{ + Q_D(const DuiFreestyleLayoutPolicy); + + if (which == Qt::MaximumSize) { + // maximum size is the QWIDGETSIZE_MAX + QSizeF new_size = constraint; + if (new_size.width() < 0) + new_size.setWidth(QWIDGETSIZE_MAX); + if (new_size.height() < 0) + new_size.setHeight(QWIDGETSIZE_MAX); + return new_size; + } + + // minimum and preferred size of a layout is the bounding box of the children + int i = count(); + QRectF boundingBox; + while (--i >= 0) { + // iterate through children + boundingBox = boundingBox.united(itemGeometry(i)); + } + + qreal right, bottom; + d->layout->getContentsMargins(NULL, NULL, &right, &bottom); + return QSizeF(boundingBox.right() + right - d->layout->geometry().left(), boundingBox.bottom() + bottom - d->layout->geometry().top()); +} + + diff --git a/src/layout/duifreestylelayoutpolicy.h b/src/layout/duifreestylelayoutpolicy.h new file mode 100644 index 000000000..fd17ceee7 --- /dev/null +++ b/src/layout/duifreestylelayoutpolicy.h @@ -0,0 +1,101 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIFREESTYLELAYOUTPOLICY_H +#define DUIFREESTYLELAYOUTPOLICY_H + +#include "duiabstractlayoutpolicy.h" +#include "duilayout.h" + +class DuiFreestyleLayoutPolicyPrivate; + +/*! + * \class DuiFreestyleLayoutPolicy + * \brief Freestyle layout policy. + * + * This policy arranges the items as much as possible according to the user's + * wishes but avoids any overlap. The height is computed as needed. + * + * The following example adds items to the freestyle layout policy in a circle shape: + * + * \dontinclude duifreestylelayoutpolicy/duifreestylelayoutpolicy.cpp + * \skip Create a DuiLayout + * \until } + * + * The result, with appropriate CSS styling, looks like: + * \image html duifreestylelayoutpolicy.png + * + * \sa \link layout-duifreestylelayoutpolicy DuiFreestyleLayoutPolicy Example \endlink + */ +class DUI_EXPORT DuiFreestyleLayoutPolicy : public DuiAbstractLayoutPolicy +{ +public: + /*! + * \brief Constructs a freestyle layout policy + */ + explicit DuiFreestyleLayoutPolicy(DuiLayout *layout); + + /*! + * \brief Destroys the freestyle layout policy. + */ + virtual ~DuiFreestyleLayoutPolicy(); + + /*! + * \brief Add an item to the top left hand corner in the freestyle layout. + * + * If the new item overlaps any existing items, the existing items will be + * moved out of the way. + * + * The item will be given its preferredSize. + * @param item The item to add. + */ + virtual void addItem(QGraphicsLayoutItem *item); + + /*! + * \brief Add an item at a specific geometry in the freestyle layout. + * + * If the new item overlaps any existing items, the existing items will be + * moved out of the way. + * + * @param item The item to add. + * @param geom The geometry where to add the item. + */ + void addItemAtGeometry(QGraphicsLayoutItem *item, const QRectF &geom); + + /*! \brief Move an item to the given geometry. + * + * The given @a item will be animated to the given geometry, if possible, + * moving any overlapping items out of the way, if possible. + */ + void moveItemTo(QGraphicsLayoutItem *item, const QRectF &geom); + + /*! \reimp */ + virtual QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const; + virtual void removeAt(int index); + /*! \reimp_end */ +protected: + + virtual void relayout(); + +private: + Q_DECLARE_PRIVATE(DuiFreestyleLayoutPolicy) + Q_DISABLE_COPY(DuiFreestyleLayoutPolicy) +}; + +#endif // Header Guard diff --git a/src/layout/duifreestylelayoutpolicy_p.cpp b/src/layout/duifreestylelayoutpolicy_p.cpp new file mode 100644 index 000000000..e6c1ff56c --- /dev/null +++ b/src/layout/duifreestylelayoutpolicy_p.cpp @@ -0,0 +1,113 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duifreestylelayoutpolicy_p.h" + +DuiFreestyleLayoutPolicyPrivate::DuiFreestyleLayoutPolicyPrivate(DuiLayout *l) : + DuiAbstractLayoutPolicyPrivate(l) +{ } + +DuiFreestyleLayoutPolicyPrivate::~DuiFreestyleLayoutPolicyPrivate() +{ } + +QRectF DuiFreestyleLayoutPolicyPrivate::moveAway(const QRectF &to_move, + const QRectF &blocked_area, + const QPointF &topLeft, + qreal width) const +{ + QRectF result(to_move); + QRectF intersection = to_move.intersect(blocked_area); + + bool moved = false; + if (qAbs(intersection.width()) < qAbs(intersection.height())) { + // move left or right first + if (to_move.center().x() < blocked_area.center().x() && topLeft.x() + to_move.width() <= blocked_area.left()) { + result.moveRight(blocked_area.left()); + moved = true; + } else if (blocked_area.right() + result.width() <= topLeft.x() + width) { + result.moveLeft(blocked_area.right()); + moved = true; + } + } + + if (!moved) { + // otherwise up or down first + if (to_move.center().y() < blocked_area.center().y() && topLeft.y() + to_move.height() <= blocked_area.top()) + result.moveBottom(blocked_area.top()); + else + result.moveTop(blocked_area.bottom()); + } + + return result; +} + +bool DuiFreestyleLayoutPolicyPrivate::placeItem(int indexToPlace, + QList & placed_items, + const QPointF &topLeft, + qreal width) const +{ + QRectF &target = placed_items[indexToPlace]; + if (target.right() > topLeft.x() + width) + target.moveRight(topLeft.x() + width); + if (target.x() < topLeft.x()) + target.moveLeft(topLeft.x()); + if (target.y() < topLeft.y()) + target.moveTop(topLeft.y()); + + const int size = placed_items.count(); + // check all placed items for overlaps + for (int i = 0; i < size; ++i) { + if (i != indexToPlace && placed_items.at(i).intersects(target)) { + // move other out of the way + QRectF otherTarget = moveAway(placed_items.at(i), target, topLeft, width); + + if (otherTarget == placed_items.at(i)) + break; //No change + placed_items[i] = otherTarget; + + // place other once more to allow for older items to make room + placeItem(i, placed_items, topLeft, width); + } + } + + // if something is still in the way to new item has to move + qreal bottom = topLeft.y(); + for (int i = 0; i < size; ++i) { + const QRectF &other = placed_items.at(i); + if (i != indexToPlace && other.intersects(target)) // move new item out of the way + target = moveAway(target, placed_items.at(i), topLeft, width); + bottom = qMax(other.bottom(), topLeft.y()); + } + + // if there is still some overlap, put new item at the bottom + for (int i = 0; i < size; ++i) { + if (i != indexToPlace && placed_items.at(i).intersects(target)) { + target.moveTop(bottom); + break; + } + } + + // now that everything is moved away, simply place the item + Q_ASSERT(target.top() + 0.00001 >= topLeft.y()); //add a small amount for rounding errors + Q_ASSERT(target.left() + 0.00001 >= topLeft.x()); + Q_ASSERT(target.right() - 0.00001 <= topLeft.x() + width || target.width() > width); //make sure it doesn't go outside the right hand side, unless + + return true; +} + diff --git a/src/layout/duifreestylelayoutpolicy_p.h b/src/layout/duifreestylelayoutpolicy_p.h new file mode 100644 index 000000000..1a2e3f715 --- /dev/null +++ b/src/layout/duifreestylelayoutpolicy_p.h @@ -0,0 +1,48 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIFREESTYLELAYOUTPOLICY_P_H +#define DUIFREESTYLELAYOUTPOLICY_P_H + +#include "duifreestylelayoutpolicy.h" +#include "duiabstractlayoutpolicy_p.h" + +/** Private policy class. */ +class DuiFreestyleLayoutPolicyPrivate : public DuiAbstractLayoutPolicyPrivate +{ +public: + /** Constructor */ + explicit DuiFreestyleLayoutPolicyPrivate(DuiLayout *); + /** Destructor */ + virtual ~DuiFreestyleLayoutPolicyPrivate(); + +protected: + /** Helper method to move a rectangle away from another one */ + QRectF moveAway(const QRectF &to_move, const QRectF &blocked, const QPointF &topLeft, qreal width) const; + /** Helper method to place items recursively */ + bool placeItem(int index, + QList & placed_items, + const QPointF &topLeft, + qreal width) const; + +private: + Q_DECLARE_PUBLIC(DuiFreestyleLayoutPolicy) +}; + +#endif // Header Guard diff --git a/src/layout/duigridlayoutpolicy.cpp b/src/layout/duigridlayoutpolicy.cpp new file mode 100644 index 000000000..b7a9b0a4d --- /dev/null +++ b/src/layout/duigridlayoutpolicy.cpp @@ -0,0 +1,331 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duigridlayoutpolicy.h" +#include "duigridlayoutpolicy_p.h" +#include "duiabstractlayoutpolicystyle.h" +#include "duidebug.h" + +#include "duilayouthelper_p.h" + +#include +#include +DuiGridLayoutPolicy::DuiGridLayoutPolicy(DuiLayout *layout) : + DuiAbstractLayoutPolicy(*(new DuiGridLayoutPolicyPrivate(layout))) +{ } + +DuiGridLayoutPolicy::~DuiGridLayoutPolicy() +{ } + +int DuiGridLayoutPolicy::rowCount() const +{ + Q_D(const DuiGridLayoutPolicy); + return d->engine->rowCount(); +} + +int DuiGridLayoutPolicy::columnCount() const +{ + Q_D(const DuiGridLayoutPolicy); + return d->engine->columnCount(); +} + + +QGraphicsLayoutItem *DuiGridLayoutPolicy::itemAt(int row, int col) const +{ + Q_D(const DuiGridLayoutPolicy); + ProxyItem *item = static_cast(d->engine->itemAt(row, col)); + if (!item) + return NULL; + + return item->proxiedItem(); +} + +void DuiGridLayoutPolicy::addItem(QGraphicsLayoutItem *item, int row, int column, + int rowSpan, int columnSpan, Qt::Alignment alignment) +{ + Q_D(DuiGridLayoutPolicy); + + if (row < 0 || column < 0) { + duiWarning("DuiGridLayoutPolicy") << Q_FUNC_INFO << "invalid row/column:" << (row < 0 ? row : column); + return; + } + if (columnSpan < 1 || rowSpan < 1) { + duiWarning("DuiGridLayoutPolicy") << Q_FUNC_INFO << "invalid row span/column span:" << (rowSpan < 1 ? rowSpan : columnSpan); + return; + } + if (!item) { + duiWarning("DuiGridLayoutPolicy") << Q_FUNC_INFO << "cannot set data for null item"; + return; + } + ProxyItem *proxyItem = new ProxyItem(item); + d->engine->addItem(proxyItem, row, column, rowSpan, columnSpan, alignment); + + // Register new item with the policy and layout + DuiAbstractLayoutPolicy::addItem(item); +} + +void DuiGridLayoutPolicy::setRowSpacing(int row, qreal spacing) +{ + Q_D(DuiGridLayoutPolicy); + d->engine->setRowSpacing(row, spacing); + invalidatePolicyAndLayout(); +} + +qreal DuiGridLayoutPolicy::rowSpacing(int row) const +{ + Q_D(const DuiGridLayoutPolicy); + return d->engine->rowSpacing(row); +} + +void DuiGridLayoutPolicy::setColumnSpacing(int column, qreal spacing) +{ + Q_D(DuiGridLayoutPolicy); + d->engine->setColumnSpacing(column, spacing); + invalidatePolicyAndLayout(); +} + +qreal DuiGridLayoutPolicy::columnSpacing(int column) const +{ + Q_D(const DuiGridLayoutPolicy); + return d->engine->columnSpacing(column); +} + +void DuiGridLayoutPolicy::setRowAlignment(int row, Qt::Alignment alignment) +{ + Q_D(DuiGridLayoutPolicy); + d->engine->setRowAlignment(row, alignment); + invalidatePolicyAndLayout(); +} + +Qt::Alignment DuiGridLayoutPolicy::rowAlignment(int row) const +{ + Q_D(const DuiGridLayoutPolicy); + return d->engine->rowAlignment(row); +} + +void DuiGridLayoutPolicy::setColumnAlignment(int column, Qt::Alignment alignment) +{ + Q_D(DuiGridLayoutPolicy); + d->engine->setColumnAlignment(column, alignment); + invalidatePolicyAndLayout(); +} + +Qt::Alignment DuiGridLayoutPolicy::columnAlignment(int column) const +{ + Q_D(const DuiGridLayoutPolicy); + return d->engine->columnAlignment(column); +} + +void DuiGridLayoutPolicy::setRowStretchFactor(int row, int stretch) +{ + Q_D(DuiGridLayoutPolicy); + d->engine->setRowStretchFactor(row, stretch); + invalidatePolicyAndLayout(); +} + +int DuiGridLayoutPolicy::rowStretchFactor(int row) const +{ + Q_D(const DuiGridLayoutPolicy); + return d->engine->rowStretchFactor(row); +} + +void DuiGridLayoutPolicy::setColumnStretchFactor(int column, int stretch) +{ + Q_D(DuiGridLayoutPolicy); + d->engine->setColumnStretchFactor(column, stretch); + invalidatePolicyAndLayout(); +} + +int DuiGridLayoutPolicy::columnStretchFactor(int column) const +{ + Q_D(const DuiGridLayoutPolicy); + return d->engine->columnStretchFactor(column); +} + +void DuiGridLayoutPolicy::setRowMinimumHeight(int row, qreal height) +{ + Q_D(DuiGridLayoutPolicy); + d->engine->setRowMinimumHeight(row, height); + invalidatePolicyAndLayout(); +} + +qreal DuiGridLayoutPolicy::rowMinimumHeight(int row) const +{ + Q_D(const DuiGridLayoutPolicy); + return d->engine->rowMinimumHeight(row); +} + +void DuiGridLayoutPolicy::setRowPreferredHeight(int row, qreal height) +{ + Q_D(DuiGridLayoutPolicy); + d->engine->setRowPreferredHeight(row, height); + invalidatePolicyAndLayout(); +} + +qreal DuiGridLayoutPolicy::rowPreferredHeight(int row) const +{ + Q_D(const DuiGridLayoutPolicy); + return d->engine->rowPreferredHeight(row); +} + +void DuiGridLayoutPolicy::setRowMaximumHeight(int row, qreal height) +{ + Q_D(DuiGridLayoutPolicy); + d->engine->setRowMaximumHeight(row, height); + invalidatePolicyAndLayout(); +} + +qreal DuiGridLayoutPolicy::rowMaximumHeight(int row) const +{ + Q_D(const DuiGridLayoutPolicy); + return d->engine->rowMaximumHeight(row); +} + +void DuiGridLayoutPolicy::setRowFixedHeight(int row, qreal height) +{ + Q_D(DuiGridLayoutPolicy); + d->engine->setRowFixedHeight(row, height); + invalidatePolicyAndLayout(); +} + +void DuiGridLayoutPolicy::setColumnMinimumWidth(int column, qreal width) +{ + Q_D(DuiGridLayoutPolicy); + d->engine->setColumnMinimumWidth(column, width); + invalidatePolicyAndLayout(); +} + +qreal DuiGridLayoutPolicy::columnMinimumWidth(int column) const +{ + Q_D(const DuiGridLayoutPolicy); + return d->engine->columnMinimumWidth(column); +} + +void DuiGridLayoutPolicy::setColumnPreferredWidth(int column, qreal width) +{ + Q_D(DuiGridLayoutPolicy); + d->engine->setColumnPreferredWidth(column, width); + invalidatePolicyAndLayout(); +} + +qreal DuiGridLayoutPolicy::columnPreferredWidth(int column) const +{ + Q_D(const DuiGridLayoutPolicy); + return d->engine->columnPreferredWidth(column); +} + +void DuiGridLayoutPolicy::setColumnMaximumWidth(int column, qreal width) +{ + Q_D(DuiGridLayoutPolicy); + d->engine->setColumnMaximumWidth(column, width); + invalidatePolicyAndLayout(); +} + +qreal DuiGridLayoutPolicy::columnMaximumWidth(int column) const +{ + Q_D(const DuiGridLayoutPolicy); + return d->engine->columnMaximumWidth(column); +} + +void DuiGridLayoutPolicy::setColumnFixedWidth(int column, qreal width) +{ + Q_D(DuiGridLayoutPolicy); + d->engine->setColumnFixedWidth(column, width); + invalidatePolicyAndLayout(); +} + +void DuiGridLayoutPolicy::removeAt(int index) +{ + Q_D(DuiGridLayoutPolicy); + if (index < 0 || index >= d->engine->count()) { + duiWarning("DuiGridLayoutPolicy") << Q_FUNC_INFO << "invalid index" << index; + return; + } + + QGraphicsLayoutItem *proxyItem = d->engine->itemAt(index); + d->engine->removeAt(index); + delete proxyItem; + + DuiAbstractLayoutPolicy::removeAt(index); +} +QSizeF DuiGridLayoutPolicy::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const +{ + Q_D(const DuiGridLayoutPolicy); + const_cast(d)->refreshEngine(); + return d->engine->sizeHint(which, constraint); +} + +void DuiGridLayoutPolicy::relayout() +{ + Q_D(DuiGridLayoutPolicy); + + d->engine->invalidate(); + d->refreshEngine(); + d->engine->activate(); + if (!isActive()) + return; + + for (int i = d->engine->count() - 1; i >= 0; --i) { + const QGraphicsLayoutItem *item = d->engine->itemAt(i); + setItemGeometry(i, item->geometry()); + } +} + +void DuiGridLayoutPolicy::invalidate() +{ + Q_D(DuiGridLayoutPolicy); + //We need to invalidate the geometry of all the proxy items + for (int i = d->engine->count() - 1; i >= 0; --i) { + ProxyItem *item = static_cast(d->engine->itemAt(i)); + item->updateGeometry(); + } + d->engine->invalidate(); + DuiAbstractLayoutPolicy::invalidate(); +} + +void DuiGridLayoutPolicy::setHorizontalSpacing(qreal spacing) +{ + Q_D(DuiGridLayoutPolicy); + DuiAbstractLayoutPolicy::setHorizontalSpacing(spacing); + d->engine->setHorizontalSpacing(spacing); +} + +void DuiGridLayoutPolicy::setVerticalSpacing(qreal spacing) +{ + Q_D(DuiGridLayoutPolicy); + DuiAbstractLayoutPolicy::setVerticalSpacing(spacing); + d->engine->setVerticalSpacing(spacing); +} + +void DuiGridLayoutPolicy::setAlignment(QGraphicsLayoutItem *item, Qt::Alignment alignment) +{ + Q_D(DuiGridLayoutPolicy); + //This will take O(N) time to find the index of the item + QGraphicsLayoutItem *proxyItem = d->engine->itemAt(indexOf(item)); + d->engine->setAlignment(proxyItem, alignment); + invalidatePolicyAndLayout(); +} + +Qt::Alignment DuiGridLayoutPolicy::alignment(QGraphicsLayoutItem *item) const +{ + Q_D(const DuiGridLayoutPolicy); + //This will take O(N) time to find the index of the item + QGraphicsLayoutItem *proxyItem = d->engine->itemAt(indexOf(item)); + return d->engine->alignment(proxyItem); +} diff --git a/src/layout/duigridlayoutpolicy.h b/src/layout/duigridlayoutpolicy.h new file mode 100644 index 000000000..973f4ce83 --- /dev/null +++ b/src/layout/duigridlayoutpolicy.h @@ -0,0 +1,286 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIGRIDLAYOUTPOLICY_H +#define DUIGRIDLAYOUTPOLICY_H + +#include "duiabstractlayoutpolicy.h" +class DuiGridLayoutPolicyPrivate; + +class QWidget; + +/*! + * \class DuiGridLayoutPolicy + * \brief Policy that uses the Qt grid layout engine to provide a grid layout. + * \ingroup layouts + * + * This class provides a policy which is similar to QGraphicsGridLayout, with the advantage + * of allowing multiple policies and animation. You can use QGraphicsGridLayout instead + * to slightly reduce memory overhead if these advantages are not required. + + * The following example adds items to the grid layout policy: + * + * \dontinclude duigridlayoutpolicy/duigridlayoutpolicy.cpp + * \skip Create a DuiLayout + * \until } + * + * The result, with appropriate CSS styling, looks like: + * \image html duigridlayoutpolicy.png + * + * \sa \ref layout-duigridlayoutpolicy + * + * \section gridLimitations Limitations - equally-sized columns + * + * It is difficult to create a grid layout with equally-sized columns, with both + * DuiGridLayoutPolicy and QGraphicsGridLayout. The current workaround is to + * manually set the preferred width of all the items inside the layout to the same width. + * + * As an example, to layout items in two columns with equal widths: + * + * \dontinclude two_columns/twocolumns.cpp + * \skip Create a DuiLayout that we set the policy for + * \until labelLayout->setPreferredWidth(1) + * + * We are working with Qt to try to find a better solution. + * + * \section qgraphicsgridlayout_instead Using QGraphicsGridLayout instead + * + * If you do not need animations or multiple policies, you can use QGraphicsGridLayout for same effect in less code. + * For example: + * + * \dontinclude qgraphicsgridlayout/qgraphicsgridlayout.cpp + * \skip Create a grid layout + * \until } + * + * \sa \ref layout-qgraphicsgridlayout + */ +class DUI_EXPORT DuiGridLayoutPolicy : public DuiAbstractLayoutPolicy +{ +public: + /*! + * \brief Constructs a grid layout policy. + * + * @param layout The layout to associate with. + */ + explicit DuiGridLayoutPolicy(DuiLayout *layout); + + /*! + * \brief Destructor to clean up engine. + */ + virtual ~DuiGridLayoutPolicy(); + + /*! + * \brief Get the number of rows. + * + * @return The number of rows. + */ + int rowCount() const; + + /*! + * \brief Get the number of columns. + * + * @return The number of columns. + */ + int columnCount() const; + + /*! + * \brief Set spacing for a single row. + * + * @param row The row to set the spacing for. + * @param spacing The spacing to use. + */ + void setRowSpacing(int row, qreal spacing); + + /*! + * \brief Get spacing for a single row. + * + * @param row The row to get the spacing for. + * + * @return The spacing. + */ + qreal rowSpacing(int row) const; + + /*! + * \brief Set spacing for a single column. + * + * @param column The column to set the spacing for. + * @param spacing The spacing to use. + */ + void setColumnSpacing(int column, qreal spacing); + + /*! + * \brief Get spacing for a single column. + * + * @param column The column to get the spacing for. + * + * @return The spacing. + */ + qreal columnSpacing(int column) const; + + /*! + * \brief Set the default alignment for a whole row. + * This value can be overridden on an item for item basis. + * + * @param row the row to set the default alignment for + * @param alignment the default alignment to use + */ + void setRowAlignment(int row, Qt::Alignment alignment); + + /*! + * \brief Get the default alignment for a whole row. + * + * @param row the row to get the alignment for + * @return the default alignment in use + */ + Qt::Alignment rowAlignment(int row) const; + + /*! + * \brief Set the default alignment for a whole column. + * This value can be overridden on an item for item basis. + * + * @param column the column to set the default alignment for + * @param alignment the default alignment to use + */ + void setColumnAlignment(int column, Qt::Alignment alignment); + + /*! + * \brief Get the default alignment for a whole column. + * + * @param column the row to get the alignment for + * @return the default alignment in use + */ + Qt::Alignment columnAlignment(int column) const; + + /*! + * \brief Get an item. + * + * Get the item found at the given position in the grid. + * + * @param row The row to query. + * @param col The column to query. + * + * @return The item at the position or 0 if invalid/unset. + */ + QGraphicsLayoutItem *itemAt(int row, int col) const; + + /*! + * \brief Add an item at a position in the grid. + * + * @param item The item to add. + * @param row The row to add the item to. + * @param column The column to add the item to. + * @param rowSpan The number of cells the item spans in the row + * @param columnSpan The number of cells the item spans in the column + * @param alignment The alignment to use. + */ + void addItem(QGraphicsLayoutItem *item, int row, int column, + int rowSpan, int columnSpan, Qt::Alignment alignment = 0); + + /*! + * \brief Add an item at a position in the grid. + * + * @param item The item to add. + * @param row The row to add the item to. + * @param column The column to add the item to. + * @param alignment The alignment to use. + */ + inline void addItem(QGraphicsLayoutItem *item, int row, int column, Qt::Alignment alignment = 0) { + addItem(item, row, column, 1, 1, alignment); + } + + /*! \reimp */ + virtual void removeAt(int index); + /*! \reimp_end */ + + /*! Sets the stretch factor for \a row. */ + void setRowStretchFactor(int row, int stretch); + /*! Returns the stretch factor for \a row. */ + int rowStretchFactor(int row) const; + /*! Sets the stretch factor for \a column. */ + void setColumnStretchFactor(int column, int stretch); + /*! Returns the stretch factor for \a column. */ + int columnStretchFactor(int column) const; + /*! Sets the minimum height for \a row to \a height. */ + void setRowMinimumHeight(int row, qreal height); + /*! Returns the minimum height for \a row. */ + qreal rowMinimumHeight(int row) const; + /*! Sets the preferred height for \a row. */ + void setRowPreferredHeight(int row, qreal height); + /*! Returns the preferred height for \a row. */ + qreal rowPreferredHeight(int row) const; + /*! Sets the maximum height for \a row to \a height. */ + void setRowMaximumHeight(int row, qreal height); + /*! Returns the maximum height for \a row. */ + qreal rowMaximumHeight(int row) const; + /*! Sets the fixed height for \a row to \a height. */ + void setRowFixedHeight(int row, qreal height); + /*! Sets the minimum width for \a column to \a width. */ + void setColumnMinimumWidth(int column, qreal width); + /*! Returns the minimum width for \a column. */ + qreal columnMinimumWidth(int column) const; + /*! Sets the preferred width for \a column to \a width. */ + void setColumnPreferredWidth(int column, qreal width); + /*! Returns the preferred width for \a column. */ + qreal columnPreferredWidth(int column) const; + /*! Sets the maximum width of \a column to \a width. */ + void setColumnMaximumWidth(int column, qreal width); + /*! Returns the maximum width for \a column. */ + qreal columnMaximumWidth(int column) const; + /*! Sets the fixed width of \a column to \a width. */ + void setColumnFixedWidth(int column, qreal width); + + /*! + Returns the alignment for \a item. The default alignment is + Qt::AlignCenter. + + The alignment decides how the item is positioned within its assigned space + in the case where there's more space available in the layout than the + widgets can occupy. + + \sa setAlignment() + */ + Qt::Alignment alignment(QGraphicsLayoutItem *item) const; + /*! + Sets the alignment of \a item to \a alignment. If \a item's alignment + changes, the layout is automatically invalidated. + + \sa alignment(), invalidate() + */ + void setAlignment(QGraphicsLayoutItem *item, Qt::Alignment alignment); + + + /*! \reimp */ + virtual QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const; + virtual void setHorizontalSpacing(qreal spacing); + virtual void setVerticalSpacing(qreal spacing); + /*! \reimp_end */ + + +protected: + /*! \reimp */ + virtual void relayout(); + virtual void invalidate(); + /*! \reimp_end */ + +private: + Q_DISABLE_COPY(DuiGridLayoutPolicy) + Q_DECLARE_PRIVATE(DuiGridLayoutPolicy) +}; + +#endif // Header Guard diff --git a/src/layout/duigridlayoutpolicy_p.cpp b/src/layout/duigridlayoutpolicy_p.cpp new file mode 100644 index 000000000..8ccec2f0d --- /dev/null +++ b/src/layout/duigridlayoutpolicy_p.cpp @@ -0,0 +1,64 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duigridlayoutpolicy_p.h" + +#include +#include +#include +#include "duilayout.h" +#include "duilayouthelper_p.h" +DuiGridLayoutPolicyPrivate::DuiGridLayoutPolicyPrivate(DuiLayout *l) : + DuiAbstractLayoutPolicyPrivate(l), engineWidget(new QGraphicsWidget), engine(new QGraphicsGridLayout(engineWidget)) +{ + engineWidget->setContentsMargins(0, 0, 0, 0); + engineWidget->setMinimumSize(0, 0); + engineWidget->setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); +} + +DuiGridLayoutPolicyPrivate::~DuiGridLayoutPolicyPrivate() +{ + delete engineWidget; //This deletes the engine, which in turn deletes all of its children +} + +void DuiGridLayoutPolicyPrivate::refreshEngine() +{ + engineWidget->setLayoutDirection(layout->layoutDirection()); //Make sure that we have our RTL/LTR correct + + //To properly relayout or get the size hint, we need to invalidate the size hints + //of all the proxy items and set the geometry of the proxy layout (d->engine) to be the same + engine->invalidate(); + for (int i = engine->count() - 1; i >= 0; --i) { + ProxyItem *item = static_cast(engine->itemAt(i)); + item->refresh(); + } + qreal left, top, right, bottom; + layout->getContentsMargins(&left, &top, &right, &bottom); + engine->setContentsMargins(left, top, right, bottom); + + engine->updateGeometry(); //Needed? + //We need to make engine->geometry() equal the layout->geometry() so that the items are in the right place + qreal topMargin = layout->geometry().top(); + qreal leftMargin = layout->geometry().left(); + qreal width = layout->geometry().right(); + qreal height = layout->geometry().bottom(); + engineWidget->setContentsMargins(leftMargin, topMargin, 0, 0); + engineWidget->resize(width, height); +} + diff --git a/src/layout/duigridlayoutpolicy_p.h b/src/layout/duigridlayoutpolicy_p.h new file mode 100644 index 000000000..a100cbee9 --- /dev/null +++ b/src/layout/duigridlayoutpolicy_p.h @@ -0,0 +1,50 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIGRIDLAYOUTPOLICY_P_H +#define DUIGRIDLAYOUTPOLICY_P_H + +#include "duiabstractlayoutpolicy_p.h" +#include "duigridlayoutpolicy.h" + +class DuiLayout; +class QGraphicsWidget; +class QGraphicsGridLayout; +/** + This is the private implementation class for the grid layout policy. + The real work is done in the QGraphicsGridLayout to which a pointer is + held here. +*/ +class DuiGridLayoutPolicyPrivate : public DuiAbstractLayoutPolicyPrivate +{ + Q_DECLARE_PUBLIC(DuiGridLayoutPolicy) + +public: + /** Constructor */ + explicit DuiGridLayoutPolicyPrivate(DuiLayout *l); + /** Destructor */ + virtual ~DuiGridLayoutPolicyPrivate(); + + void refreshEngine(); + + QGraphicsWidget *const engineWidget; + QGraphicsGridLayout *const engine; +}; + +#endif // Header Guard diff --git a/src/layout/duiitemstate.cpp b/src/layout/duiitemstate.cpp new file mode 100644 index 000000000..610e46775 --- /dev/null +++ b/src/layout/duiitemstate.cpp @@ -0,0 +1,275 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiitemstate.h" +#include "duiitemstate_p.h" +#include "duilayouthelper_p.h" + +DuiItemStatePrivate::DuiItemStatePrivate(QGraphicsLayoutItem *item) : + item(item), + sourceOpacity(-1), + targetOpacity(-1), + flags(DuiItemState::STATE_FLAG_NONE), + geometryProgress(1), + opacityProgress(1), + isAnimationDone(true) +{ +} + +DuiItemState::DuiItemState() + : d_ptr(new DuiItemStatePrivate(NULL)) +{ +} + +DuiItemState::DuiItemState(QGraphicsLayoutItem *i) + : d_ptr(new DuiItemStatePrivate(i)) +{ +} + +DuiItemState::DuiItemState(const DuiItemState &i) + : d_ptr(new DuiItemStatePrivate(*i.d_ptr)) +{ } + +DuiItemState *DuiItemState::operator =(const DuiItemState &i) +{ + Q_D(DuiItemState); + *d = *i.d_ptr; //do a shallow copy + return this; +} + +bool DuiItemState::operator ==(const DuiItemState &i) const +{ + Q_D(const DuiItemState); + // Identity is independent of positions... + return (d->item == i.d_ptr->item); +} + +DuiItemState::~DuiItemState() +{ + delete d_ptr; +} + +bool DuiItemState::isNull() const +{ + Q_D(const DuiItemState); + return (0 == d->item); +} + +QGraphicsLayoutItem *DuiItemState::item() const +{ + Q_D(const DuiItemState); + return d->item; +} + +QRectF DuiItemState::sourceGeometry() const +{ + Q_D(const DuiItemState); + return d->sourceGeometry; +} + +QRectF DuiItemState::targetGeometry() const +{ + Q_D(const DuiItemState); + return d->targetGeometry; +} + +DuiItemState::Flags DuiItemState::flags() const +{ + Q_D(const DuiItemState); + return d->flags; +} + +void DuiItemState::setGeometry(const QRectF &p) +{ + Q_D(DuiItemState); + d->item->setGeometry(p); + d->sourceGeometry = p; + d->isAnimationDone = false; + if (d->sourceGeometry != d->targetGeometry) + d->geometryProgress = 0; + else + d->geometryProgress = 1; +} +void DuiItemState::setTargetGeometry(const QRectF &p) +{ + Q_D(DuiItemState); + if (isNull()) { + return; + } + QSizeF maximum = d->item->effectiveSizeHint(Qt::MaximumSize, p.size()); + QSizeF minimum = d->item->effectiveSizeHint(Qt::MinimumSize, p.size()); + QRectF target = p; + target.setSize(target.size().boundedTo(maximum).expandedTo(minimum)); + if (target == d->targetGeometry && (isSet(STATE_FLAG_SHOWING) || isSet(STATE_FLAG_TO_BE_SHOWN)) && !isSet(STATE_FLAG_TO_BE_HIDDEN)) + return; //Nothing has changed and item is already being shown or is already showing. If the item is hiding, then we need to reset the source and show the item anyway + d->targetGeometry = target; + d->sourceGeometry = d->item->geometry(); + + if (!isSet(STATE_FLAG_SHOWING) || isSet(STATE_FLAG_TO_BE_HIDDEN)) //If it's not being shown or we are in the middle of a showing animation + setFlags(STATE_FLAG_TO_BE_SHOWN); + removeFlags(STATE_FLAG_TO_BE_HIDDEN); + + d->isAnimationDone = false; + if (d->sourceGeometry != d->targetGeometry) + d->geometryProgress = 0; +} + +void DuiItemState::setFlags(Flags new_flags) +{ + Q_D(DuiItemState); + if (isNull()) { + return; + } + const Flags old_flags(d->flags); + d->flags = new_flags; +} + +bool DuiItemState::isSet(Flag flag) const +{ + Q_D(const DuiItemState); + return (d->flags & flag) == flag; +} + +void DuiItemState::addFlags(Flags additional_flags) +{ + Q_D(DuiItemState); + if (isNull()) { + return; + } + const Flags old_flags(d->flags); + d->flags |= additional_flags; +} + +void DuiItemState::removeFlags(Flags flags_to_remove) +{ + Q_D(DuiItemState); + if (isNull()) { + return; + } + d->flags &= ~flags_to_remove; +} + +bool DuiItemState::hasIdenticalLayout(const DuiItemState &i) const +{ + Q_D(const DuiItemState); + return (i.d_ptr->targetGeometry == d->targetGeometry && + i.d_ptr->targetOpacity == d->targetOpacity && + i.d_ptr->opacityProgress == d->opacityProgress && + i.d_ptr->geometryProgress == d->geometryProgress && + i.d_ptr->flags == d->flags); +} + +bool DuiItemState::isAnimationDone() const +{ + Q_D(const DuiItemState); + return d->isAnimationDone; +} + +void DuiItemState::animationDone() +{ + Q_D(DuiItemState); + d->isAnimationDone = true; + d->opacityProgress = 1; + d->geometryProgress = 1; + d->sourceGeometry = d->targetGeometry; + d->sourceOpacity = d->targetOpacity = -1; + //Keep the deleted flag so that it can be deleted + if (d->flags & STATE_FLAG_TO_BE_SHOWN) { + d->flags &= ~STATE_FLAG_TO_BE_SHOWN; + d->flags |= STATE_FLAG_SHOWING; + } + if (d->flags & STATE_FLAG_TO_BE_HIDDEN) { + d->flags &= ~STATE_FLAG_TO_BE_HIDDEN; + d->flags &= ~STATE_FLAG_SHOWING; + } +} + +void DuiItemState::setGeometryProgress(qreal progress) +{ + Q_D(DuiItemState); + d->geometryProgress = progress; + if (progress != 1) + d->isAnimationDone = false; +} +void DuiItemState::setOpacityProgress(qreal progress) +{ + Q_D(DuiItemState); + d->opacityProgress = progress; + if (progress != 1) + d->isAnimationDone = false; +} +qreal DuiItemState::geometryProgress() const +{ + Q_D(const DuiItemState); + return d->geometryProgress; +} +qreal DuiItemState::opacityProgress() const +{ + Q_D(const DuiItemState); + return d->opacityProgress; +} + +void DuiItemState::setTargetOpacity(qreal opacity) +{ + Q_D(DuiItemState); + if (isNull()) + return; + d->targetOpacity = opacity; + if (d->targetOpacity == -1) + return; + + d->sourceOpacity = currentOpacity(); + if (d->targetOpacity != d->sourceOpacity) { + d->opacityProgress = 0; + d->isAnimationDone = false; + } +} +qreal DuiItemState::targetOpacity() const +{ + Q_D(const DuiItemState); + return d->targetOpacity; +} +qreal DuiItemState::sourceOpacity() const +{ + Q_D(const DuiItemState); + return d->sourceOpacity; +} +qreal DuiItemState::currentOpacity() const +{ + Q_D(const DuiItemState); + if (d->item) + return forAllGraphicsItems(d->item, GetOpacity()); //If this finds no visible QGraphicsItems it returns 0; + return 0; //Treat no items as being transparent +} +void DuiItemState::setCurrentOpacity(qreal opacity) +{ + Q_D(DuiItemState); + if (isNull() || opacity == -1) + return; + forAllGraphicsItems(d->item, SetOpacity(opacity)); +} + +void DuiItemState::hide() +{ + Q_D(DuiItemState); + removeFlags(STATE_FLAG_TO_BE_SHOWN); + d->isAnimationDone = false; + if (isSet(STATE_FLAG_SHOWING)) //if it's not already hiding + addFlags(STATE_FLAG_TO_BE_HIDDEN); +} diff --git a/src/layout/duiitemstate.h b/src/layout/duiitemstate.h new file mode 100644 index 000000000..66b29805d --- /dev/null +++ b/src/layout/duiitemstate.h @@ -0,0 +1,283 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIITEMSTATE_H +#define DUIITEMSTATE_H + +#include "duiexport.h" + +#include + +class DuiItemStatePrivate; + +/*! + * \brief Information on the items stored inside the layout. + * + * Class to hold additional information on the QGraphicsLayoutItems + * this layout is working on. + */ +class DUI_EXPORT DuiItemState +{ +public: + /*! + * \brief Flags + * + * These flags are giving details on the state of the item in + * the layout. + */ + enum Flag { + /* Nothing special. */ + STATE_FLAG_NONE = 0, //!< If none of the other flags are set, this indicates that the item is not being shown + /* The item is still doing its remove-animation. */ + STATE_FLAG_TO_BE_DELETED = 1, //!< Indicates that the item will be deleted as soon as its hidden/ + STATE_FLAG_TO_BE_SHOWN = 2, //!< Indicates that setTargetGeometry has been called for an item that wasn't SHOWING. The animator will move the item into its starting position and clear this flag. This is not set during any showing animation. + STATE_FLAG_TO_BE_HIDDEN = 4, //!< Indicates that hide() has been called for an item was SHOWING. The animator will set the hiding animation. Both this flag and the SHOWING flag will be left set during any hiding animation. One the animation is finished, the item will be hidden and both this flag and SHOWING will be cleared. If TO_BE_DELETED is set, the item is deleted. + STATE_FLAG_SHOWING = 8 //!< Whether the item is currently visible by the user + }; + Q_DECLARE_FLAGS(Flags, Flag) + + /*! + * \brief Constructs an item state. + * + * Returns a Null DuiItemState item. + */ + DuiItemState(); + /*! + * \brief Constructs an item state. + * + * Constructs an DuiItemState item from the values provided. The + * geometry settings are taken from the geometry of the item. + * + * @param item The QGraphicsLayoutItem. + */ + explicit DuiItemState(QGraphicsLayoutItem *item); + /* Copy constructor */ + DuiItemState(const DuiItemState &); + /* Assignment operator */ + DuiItemState *operator =(const DuiItemState &); + + /*! + * \brief Equality operator. + * + * This operator checks whether both items refer to the + * same QGraphicsLayoutItem. It does not check any additional + * information stored in the DuiItemState. + * + * @param other The item to compare with this one. + * + * @return true if both DuiItemStates refer to the same object and + * false otherwise. + */ + bool operator ==(const DuiItemState &other) const; + + /*! + * \brief Destructs an item state. + */ + ~DuiItemState(); + + /*! + * \brief Checks whether this is a null DuiItemState item? + * + * @return true if this DuiItemState item has a null QGraphicsLayoutItem + * and false otherwise. + */ + bool isNull() const; + + /*! + * \brief Getter for the QGraphicsLayoutItem. + */ + QGraphicsLayoutItem *item() const; + + /*! + * \brief Getter for the source position. + */ + QRectF sourceGeometry() const; + + /*! + * \brief Getter for the target position. + */ + QRectF targetGeometry() const; + + /*! + * \brief Getter for the state flags. + */ + Flags flags() const; + + /*! + * \brief Set a new target position. + * + * This will set the target geometry to the given rectangle, and set + * source geometry to be the current item geometry + */ + void setTargetGeometry(const QRectF &rect); + + /*! + * \brief Set the current position, restarting the animation + * + * This will set the item's geometry to the rectangle and set the source + * geometry, restarting the animation. + */ + void setGeometry(const QRectF &rect); + + /*! + * \brief set a new target opacity. + * + * This will set the target opacity, between 0 (invisible) to 1. If it + * is zero, the item will have its visibility set to false at the end + * of the animation. If it is not set to 0 or -1, the item will be set + * to visible at the start of the animation. + * + * Note that QGraphicLayoutItems do not have an opacity, so only their children + * that are QGraphicsItems will be changed. + * + * If this is set to -1, the opacity will not be changed. + */ + void setTargetOpacity(qreal opacity); + + /*! + * \brief Get the target opacity + * + * This is between 0 (invisible) to 1 (fully visible), or -1 to leave untouched. + * + * All child items, visible or not, will have their opacities changed to the + * target opacity if the target opacity is not -1. + */ + qreal targetOpacity() const; + + /*! + * \brief Get the source opacity + * + * This is set when setTargetOpacity is called. It is set to the item with + * the highest opacity (Each child item has its own opacity). Child items + * not visible are treated as having an opacity of 0. This returns 0 if + * there were no visible items and -1 if setTargetOpacity has not been called. + * + * @return -1 if setTargetOpacity has not been called, or between 0 and 1 + */ + qreal sourceOpacity() const; + + /*! + * \brief Get the current opacity + * + * This looks at the item() and iterates over all the children that are + * QGraphicsItems and returns the highest opacity of the children. Note + * that the children can have different opacities. + * + * The opacity of children that are not visible is not considered. + * + * An opacity of 0 is returned if no visible items are found + */ + qreal currentOpacity() const; + + /*! + * \brief Set the opacity for the item and all of its children + * + * This looks at the item() and iterates over all the children that are + * QGraphicsItem and sets their opacity. + * + * If this is set to 0, the items have their visibility set to false + * + * For convenience, if @p opacity = -1, nothing is done. + */ + void setCurrentOpacity(qreal opacity); + + /*! + * \brief Set new state flags. + */ + void setFlags(Flags new_flags); + + /*! + * \brief Is the flag set? + */ + bool isSet(Flag) const; + + /*! + * \brief Sets additional flags to the state, returns the updated state + */ + void addFlags(Flags); + + /*! + * \brief Removes flags from the state, returns the updated state + */ + void removeFlags(Flags); + + void hide(); + + /*! + * \brief Current geometry progress for this item + * + * The progress starts at 0 and finishes at 1 and indicates how + * far into the geometry animation we are + * If this is set to -1, the geometry will not be changed. + */ + qreal geometryProgress() const; + + /*! + * \brief Current opacity progress for this item + * + * The progress starts at 0 and finishes at 1 and indicates how + * far into the opacity animation we are + */ + qreal opacityProgress() const; + + /*! + * \brief Set the current geometry progress for this item + * + * The geometry progress starts at 0 and finishes at 1 and indicates how + * far into a geometry change animation we are. The animator will use the + * progress and the sourceGeometry and targetGeometry to set the item + * geometry. + * + * The animator will use this value to set the geometry + */ + void setGeometryProgress(qreal progress); + + /*! + * \brief Set the current opacity progress for this item + * + * The progress starts at 0 and finishes at 1 and indicates how + * far into an opacity change animation we are + * + * The animator will use this value to set the opacity + */ + void setOpacityProgress(qreal progress); + + /*! + * \brief Returns true if the all geometries and flags are identical. + */ + bool hasIdenticalLayout(const DuiItemState &) const; + + /** \brief Whether the animation is completed + * + * Equivalent to geometryProgress() == 1 && opacityProgress == 1 + */ + bool isAnimationDone() const; + void animationDone(); + +protected: + DuiItemStatePrivate *const d_ptr; + +private: + Q_DECLARE_PRIVATE(DuiItemState) +}; + + +Q_DECLARE_OPERATORS_FOR_FLAGS(DuiItemState::Flags) + +#endif diff --git a/src/layout/duiitemstate_p.h b/src/layout/duiitemstate_p.h new file mode 100644 index 000000000..5019d3a8f --- /dev/null +++ b/src/layout/duiitemstate_p.h @@ -0,0 +1,76 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIITEMSTATE_P_H +#define DUIITEMSTATE_P_H + +#include +#include "duiitemstate.h" + +class QGraphicsLayoutItem; + +class DuiItemStatePrivate +{ +public: + DuiItemStatePrivate(QGraphicsLayoutItem *item); + + /*! + * \brief The item to lay out. + */ + QGraphicsLayoutItem *item; + + /*! + * \brief The position of the item in the layout. + * + * This position is the one the item had before the currently + * active change was issued. + */ + QRectF sourceGeometry; + + /*! + * \brief The position of the item in the layout. + * + * This is the position the item should have once all in-flight + * operations are finished. + */ + QRectF targetGeometry; + + qreal sourceOpacity; + qreal targetOpacity; + + /*! + * \brief State of the item + */ + DuiItemState::Flags flags; + + /*! + * \brief Current progress of animation of the geometry + * Between 0 and 1. 1 indicating finished. + */ + qreal geometryProgress; + /*! + * \brief Current progress of animation of the opacity + * Between 0 and 1. 1 indicating finished. + */ + qreal opacityProgress; + /*! \brief True is the animation has completed */ + bool isAnimationDone; +}; +#endif // Header Guard + diff --git a/src/layout/duilayout.cpp b/src/layout/duilayout.cpp new file mode 100644 index 000000000..4ed68c77e --- /dev/null +++ b/src/layout/duilayout.cpp @@ -0,0 +1,379 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duilayout.h" +#include "duilayout_p.h" + +#include "duiapplication.h" +#include "duiabstractlayoutpolicy.h" +#include "duiabstractlayoutpolicy_p.h" +#include "duiitemstate.h" +#include "duibasiclayoutanimation.h" + +#include +#include +#include +#include + +DuiLayout::DuiLayout(QGraphicsLayoutItem *parent) : + QGraphicsLayout(parent), + d_ptr(new DuiLayoutPrivate(this)) +{ + Q_ASSERT(0 != d_ptr); + // some policies have height for width, so set it for the whole layout + QSizePolicy newSizePolicy(sizePolicy()); + newSizePolicy.setHeightForWidth(true); + setSizePolicy(newSizePolicy); + // Disabling layout animations by default. Unfortunately they are not working + // nicely. + //new DuiBasicLayoutAnimation(this); +} + +DuiLayout::~DuiLayout() +{ + Q_D(DuiLayout); + d->current_policy = NULL; //Make sure we have no policy before + + qDeleteAll(d->policies); + //Remove all the items from the layout and delete any layouts + //(which are ownedByLayout) inside this layout + //Because we don't have any policies, this should be pretty fast + for (int i = count() - 1; i >= 0; --i) { + bool deleteItem = (d->states.at(i).isSet(DuiItemState::STATE_FLAG_TO_BE_DELETED)); + QGraphicsLayoutItem *item = itemAt(i); + if (item) { + item->setParentLayoutItem(0); + if (item->ownedByLayout() || deleteItem) + delete item; + } + } + delete d->animation; + delete d_ptr; +} + +// Reimplemented from QGraphicsLayout +void DuiLayout::invalidate() +{ + Q_D(DuiLayout); + if (d->current_policy) + d->current_policy->invalidate(); + QGraphicsLayout::invalidate(); + //This following warning is useful, but too many false negatives :-/ +// if(!parentLayoutItem()) +// duiWarning("DuiLayout") << "DuiLayout does not have a parent - layouting will not be correct. Add the layout to a QGraphicsWidget"; +} + +void DuiLayout::invalidateLayoutOnly() +{ + QGraphicsLayout::invalidate(); +} + +int DuiLayout::count() const +{ + Q_D(const DuiLayout); + return d->states.count(); +} +bool DuiLayout::isEmpty() const +{ + Q_D(const DuiLayout); + return d->states.isEmpty(); +} +QGraphicsLayoutItem *DuiLayout::itemAt(int index) const +{ + Q_D(const DuiLayout); + if (0 > index || count() <= index) { + duiWarning("DuiLayout") << Q_FUNC_INFO << "Attempting to access item at index" << index << "when there are" << count() << "items"; + return NULL; + } + return d->states.at(index).item(); +} + +void DuiLayout::removeAt(int index) +{ + (void)takeAt(index); +} + +QGraphicsLayoutItem *DuiLayout::takeAt(int index) +{ + Q_D(DuiLayout); + if (0 > index || count() <= index) { + if (index != 0) //It's common to just try deleting the first item until there are none left, so suppress this warning for index=0 + duiWarning("DuiLayout") << Q_FUNC_INFO << "Attempting to remove item at index" << index << "when there are" << count() << "items"; + return NULL; + } + bool deleteItem = d->states.at(index).isSet(DuiItemState::STATE_FLAG_TO_BE_DELETED); + QGraphicsLayoutItem *item = d->states.at(index).item(); + Q_ASSERT(item); + foreach(DuiAbstractLayoutPolicy * policy, d->policies) { + Q_ASSERT(policy); + policy->d_ptr->aboutToBeRemovedFromLayout(item); + } + + d->states.removeAt(index); + item->setParentLayoutItem(NULL); + invalidate(); + if (deleteItem) { + delete item; + return NULL; + } + d->removeHiddenFlag(item); + return item; +} + +void DuiLayout::animatedDeleteItem(const QGraphicsLayoutItem *const item) +{ + animatedDeleteAt(indexOf(item)); +} + +void DuiLayout::animatedDeleteAt(int index) +{ + Q_D(DuiLayout); + if (0 > index || count() <= index) { + if (index != 0) + duiWarning("DuiLayout") << Q_FUNC_INFO << "Attempting to remove item at index" << index << "when there are" << count() << "items"; + return; + } + + DuiItemState &state = d->states[index]; + // Abort if already scheduled for deletion + // (this can happen because a graphics layout item removes itself from its + // layout upon destruction and would lead to an infinite recursion here) + if (state.isSet(DuiItemState::STATE_FLAG_TO_BE_DELETED)) + return; + + if (!d->animation || (!state.isSet(DuiItemState::STATE_FLAG_SHOWING))) { + delete takeAt(index); //Delete immediately if its not visible + } else { + if (state.isSet(DuiItemState::STATE_FLAG_TO_BE_DELETED)) + return; //Already set + state.addFlags(DuiItemState::STATE_FLAG_TO_BE_DELETED); + d->animation->doItemDeletingAnimation(&state); + d->animation->startAnimation(&state); + } +} + +// QGraphicsLayoutItem: + +QSizeF DuiLayout::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const +{ + Q_D(const DuiLayout); + if (d->current_policy) { + return d->current_policy->sizeHint(which, constraint); + } + return QSizeF(-1, -1); +} + +void DuiLayout::setGeometry(const QRectF &rect) +{ + Q_D(DuiLayout); + QRectF previousGeometry = geometry(); + //setGeometry is also called when the layout is activated after being invalidated + //so we should always setGeometry even if the rect has not changed + + //Note that setGeometry first adjusts rect to obey the sizehints, so our actual geometry + //afterwards is not necessarily equal to the parameter 'rect'. + QGraphicsLayout::setGeometry(rect); + if (d->current_policy) { + d->current_policy->relayout(); + //If the width really has changed and our height depends on the width, we need to recalculate + //the width. + if (d->current_policy->hasHeightForWidth() && previousGeometry.width() != geometry().width()) + updateGeometry(); //Since the height sizeHint has changed, we need to invalidate the current size hint + } + +} + +int DuiLayout::addItem(QGraphicsLayoutItem *item) +{ + Q_D(DuiLayout); + // do we know this item already? + if (!item) + return -1; //error + int index = indexOf(item); + if (index < 0) { + // If the item is a layout, we need to add all of its items + DuiItemState state(item); + addChildLayoutItem(item); + // Add item + index = d->states.size(); + d->states.append(state); + // Hide item for now since we do not know where to place it + d->hideItemNow(item); + } + return index; +} + +void DuiLayout::removeItem(const QGraphicsLayoutItem *const item) +{ + if (0 == item) { + return; + } + + int index = indexOf(item); + if (index == -1) + return; //Should we display a warning? + removeAt(index); +} + +int DuiLayout::indexOf(const QGraphicsItem *item) const +{ + Q_D(const DuiLayout); + if (0 == item) { + return -1; + } + + const int theCount = count(); + for (int i = 0; i < theCount; ++i) { + if (d->states.at(i).item()->graphicsItem() == item) { + return i; + } + } + + return -1; +} + +int DuiLayout::indexOf(const QGraphicsLayoutItem *item) const +{ + Q_D(const DuiLayout); + if (0 == item) { + return -1; + } + + const int theCount = count(); + for (int i = 0; i < theCount; ++i) { + if (d->states.at(i).item() == item) { + return i; + } + } + + return -1; +} + +void DuiLayout::setPolicy(DuiAbstractLayoutPolicy *policy) +{ + Q_D(DuiLayout); + if (d->current_policy == policy) + return; + + d->current_policy = policy; + if (d->current_policy) { + Q_ASSERT(d->policies.contains(policy)); + policy->activated(); + } + invalidate(); + //Note that the policy might not be fully constructed yet, since we might still be in the + //DuiAbstractLayoutPolicy constructor. So we cannot immediately do a re-layout - we have to + //invalidate, waiting until the next event loop to activate() +} +void DuiLayout::setLandscapePolicy(DuiAbstractLayoutPolicy *policy) +{ + Q_D(DuiLayout); + if (d->landscapePolicy == policy) + return; + d->landscapePolicy = policy; + Q_ASSERT(!policy || policy->layout() == this); + if (d->landscapePolicy && DuiApplication::activeWindow() + && DuiApplication::activeWindow()->orientation() == Dui::Landscape) { + policy->activate(); + } +} +DuiAbstractLayoutPolicy *DuiLayout::landscapePolicy() const +{ + Q_D(const DuiLayout); + return d->landscapePolicy; +} + +void DuiLayout::setPortraitPolicy(DuiAbstractLayoutPolicy *policy) +{ + Q_D(DuiLayout); + if (d->portraitPolicy == policy) + return; + d->portraitPolicy = policy; + Q_ASSERT(!policy || policy->layout() == this); + if (d->portraitPolicy && DuiApplication::activeWindow() + && DuiApplication::activeWindow()->orientation() == Dui::Portrait) { + policy->activate(); + } +} +DuiAbstractLayoutPolicy *DuiLayout::portraitPolicy() const +{ + Q_D(const DuiLayout); + return d->portraitPolicy; +} + +DuiAbstractLayoutPolicy *DuiLayout::policy() const +{ + Q_D(const DuiLayout); + return d->current_policy; +} + +QList DuiLayout::registeredPolicies() const +{ + Q_D(const DuiLayout); + return d->policies; +} + +void DuiLayout::setAnimation(DuiLayoutAnimation *animation) +{ + Q_D(DuiLayout); + delete d->animation; + d->animation = animation; +} + +DuiLayoutAnimation *DuiLayout::animation() const +{ + Q_D(const DuiLayout); + return d->animation; +} + +void DuiLayout::setContentsMargins(qreal left, qreal top, qreal right, qreal bottom) +{ + QGraphicsLayout::setContentsMargins(left, top, right, bottom); +} + +void DuiLayout::getContentsMargins(qreal *left, qreal *top, qreal *right, qreal *bottom) const +{ + Q_D(const DuiLayout); + //If there is a current policy, give it a chance to override current margins + if (d->current_policy) + d->current_policy->getContentsMargins(left, top, right, bottom); + + //if the policy returned negative values, use the QGraphicsLayout margins, otherwise do not change. + if (left && *left >= 0) + left = NULL; + if (top && *top >= 0) + top = NULL; + if (right && *right >= 0) + right = NULL; + if (bottom && *bottom >= 0) + bottom = NULL; + + QGraphicsLayout::getContentsMargins(left, top, right, bottom); +} + +/* This function was copied from Qt 4.5's qgraphicslayout_p.cpp's visualDirection*/ +Qt::LayoutDirection DuiLayout::layoutDirection() const +{ + Q_D(const DuiLayout); + if (QGraphicsItem *maybeWidget = d->parentItem()) { + if (maybeWidget->isWidget()) + return static_cast(maybeWidget)->layoutDirection(); + } + return QApplication::layoutDirection(); +} diff --git a/src/layout/duilayout.h b/src/layout/duilayout.h new file mode 100644 index 000000000..716f3818c --- /dev/null +++ b/src/layout/duilayout.h @@ -0,0 +1,578 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUILAYOUT_H +#define DUILAYOUT_H + +#include "duiexport.h" + +#include +#include + +class QGraphicsItem; +class DuiAbstractLayoutPolicy; +class DuiLayoutPrivate; +class DuiLayoutAnimation; +/*! + * \class DuiLayout + * \brief The magic layout class, extending QGraphicsLayout to add support for easily switching between + * multiple \link DuiAbstractLayoutPolicy layout policies \endlink . + * \ingroup layouts + * + * This layout class uses a policy to lay out its child \link QGraphicsLayoutItem QGraphicsLayoutItem's\endlink. + * A nice feature is that transitions may be animated by use of a + * DuiLayoutAnimation. + * + * The DuiLayout owns all its associated policies, deleting them when the layout is deleted. + * + * \section relation_to_qgraphicslayout Relation to QGraphicsLayout + * Use a DuiLayout if you want the ability to: + * + * \li Switch between multiple policies + * \li Animate the position and opacity of items + * \li Use one of the policies with no equivalent in QGraphicsLayout (e.g. DuiFlowLayoutPolicy, DuiFreestyleLayoutPolicy) + * + * Use a QGraphicsLayout if you want: + * + * \li A more lightweight layout + * \li A simple layout with no animation + * + * \sa \ref layout-qgraphicslayout + * + * \section policies Policies + * A layout can have multiple policies, with one active at any given time. With a normal Qt layout, + * items are added directly to the layout, however with DuiLayout items are added to the layout's + * associated policies. The policies all inherit from QAbstractLayoutPolicy and take care of + * geometry management for a set of widgets. To create more complex layouts you can nest DuiLayouts + * inside each other or a mix of DuiLayouts and other QGraphicsLayouts. + * + * The following code creates a DuiLayout with a linear and a flow policy, adding items to both policies. + * The first policy created will be the default policy. The other policies can be switched to by calling + * DuiAbstractLayoutPolicy::activate(). + * + * \dontinclude multiplepolicies/multiplepolicies.cpp + * \skip Create a DuiLayout + * \until layout->setPortraitPolicy + * + * \sa \ref layout-multiplepolicies + * + * \section layoutsInLayouts Layouts inside Layouts + * + * Another layout (DuiLayout or QGraphicsLayout) can be added to a policy to nest layouts to create + * more complex layouts. Items which are also layouts are not animated themselves, so prevent + * any problem of trying to animate a layout which is itself trying to animate the items inside of it. + * + * \section visibility Item Visibility + * + * Items added to a layout will be automatically hidden and shown, depending on whether + * they are in the currently active policy. If your widget inherits DuiWidget then you can still + * manually hide an item by calling DuiWidget::hide(). Usually it is sufficient to just call + * mywidget->hide(), but sometimes you have a QGraphicsItem or QGraphicsLayoutItem pointer + * that you must first cast to a DuiWidget. + * + * For \ref layout-hidden_widgets "example": + * + * \dontinclude hidden_widgets/hidden_widgets.cpp + * \skip Create a DuiLayout + * \until window.show + * + * \sa \ref layout-inside-layout + * + * \section main_policies Main Policies + * \li DuiLinearLayoutPolicy - For placing items horizontally or vertically + * + * \image html duilinearlayoutpolicy_small.png + * + * \li DuiGridLayoutPolicy - For placing items in a grid + * + * \image html duigridlayoutpolicy_small.png + * + * \li DuiFlowLayoutPolicy - For placing items in a horizontal line, overflowing onto the next line + * + * \image html duiflowlayoutpolicy_small.png + * + * \li DuiFreestyleLayoutPolicy - For placing items freely, but still preventing items from overlapping + * + * \image html duifreestylelayoutpolicy_small.png + * + * \section styling_layouts Styling + * + * CSS styling is done on the policies themselves - see DuiAbstractLayoutPolicy for more information. + * + * \sa \ref styling_policy + * + * \section custom_widgets Writing custom widgets + * + * For an item to be placed inside of a layout, the QGraphicsLayoutItem::sizeHint() and + * QGraphicsLayoutItem::sizePolicy() need to return sensible values. + * The minimum sizeHint should be the minimum size at which the item is usable. The + * preferred sizeHint should be the size at which it is usable, and the maximum sizeHint + * is typically QSizeF(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX). + * + * If you are implementing a custom DuiWidgetController and DuiWidgetView, then implement + * DuiWidgetView::sizeHint(), leaving the default DuiWidgetController::sizeHint() function + * which just calls the view's \link DuiWidgetView::sizeHint() sizeHint \endlink function. + * + * For an item in the layout, the QGraphicsLayoutItem::sizePolicy() function determines + * how the item should expand when there is space available. For example, a DuiButton cannot + * sensibly make use of more or less vertical space than its preferred height, so its vertical + * \link QGraphicsLayoutItem::sizePolicy() sizePolicy \endlink would be \link QSizePolicy QSizePolicy::Fixed. \endlink + * + * On the other hand, a text editing widget can use all the space that it can get, so its + * \link QGraphicsLayoutItem::sizePolicy() sizePolicy \endlink would be \link QSizePolicy QSizePolicy::Expanding \endlink + * in both directions. + * + * \sa \ref laying_out_item_in_custom_policy + * + * \section examples Examples + * There are many \ref layouts-example "provided examples" of using layouts to help you use layouts easily and effectively. + * + * \sa \ref layouts, \ref layout-inside-layout, \ref example-calculator + */ +class DUI_EXPORT DuiLayout : public QGraphicsLayout +{ +public: + + /*! + * \brief Constructs the layout. + */ + explicit DuiLayout(QGraphicsLayoutItem *parent = 0); + + /*! + * \brief Destructs the layout. + * + * This destructor deletes all policies associated with the layout. + */ + virtual ~DuiLayout(); + + // QGraphicsLayout: + /*! + * \brief The number of items handled by this layout. + * + * The count includes items currently being animatedly deleted. + */ + virtual int count() const; + + /*! \brief Returns if there are any items in this layout. + * + * This includes items currently being animatedly deleted. + */ + bool isEmpty() const; + + /** + * \brief Get the item at the given position. + * + * Note that the item may be marked for deletion if animatedDeleteAt() + * was called. + */ + virtual QGraphicsLayoutItem *itemAt(int index) const; + + /*! + * \brief Invalidate the current layout information. + * + * This is used to trigger invalidation in the policies. + */ + virtual void invalidate(); + + /*! + * \deprecate Policies should use DuiAbstractLayoutPolicy::invalidate instead. Since 0.19 + * \brief Invalidate the current layout information for the layout only - not the policy. + * + * This is used by policies to invalidate the layout without causing the layout to then invalidate the policy + * and causing an infinite recursion. + */ + void Q_DECL_DEPRECATED invalidateLayoutOnly(); + + // QGraphicsLayoutItem: + /*! + * \brief Get the size hints for this layout. + * + * This just calls the \link DuiAbstractLayoutPolicy::sizeHint() sizeHint function\endlink for the current policy. + */ + QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const; + + /*! + * \brief Remove an item handled by this layout. + * + * Removes the item immediately from the layout and all of its + * policies without destroying it, unless animatedDeleteAt() has + * been called previously for this item. + * Ownership of the item is transferred to the caller. + * + * Some policies allow items to be removed for only that policy. + * See the appropriate policy API documentation. + * + * Note that the item will remain on the scene, remaining visible. + * + * To remove the item from the layout immediately and delete it, simply do: + * + * \code + * delete item; + * \endcode + * + * and the item will be removed automatically from the layout. + * + * To remove the item from the layout and the scene, or to hide the item, + * see takeAt(). + * + * @param item The item to remove. + */ + void removeItem(const QGraphicsLayoutItem *const item); + + /*! + * \brief Remove the item at the given position. + * + * Removes the item immediately from the layout and all of its + * policies without destroying it, unless animatedDeleteAt() has + * been called previously for this item. + * Ownership of the item is transferred to the caller. + * + * Some policies allow items to be removed for only that policy. + * See the appropriate policy API documentation. + * + * Note that the item will remain on the scene, remaining visible. + * See the removeItem() and + * takeAt() functions for more information. + * + * \sa takeAt(), removeItem() + */ + virtual void removeAt(int index); + + /*! \brief Return and remove the item at the given position. + * + * Removes the item immediately from the layout and all of its + * policies without destroying it, unless animatedDeleteAt() has + * been called previously for this item. + * Ownership of the item is transferred to the caller. + * + * Note: + * If animatedDeleteAt() has been called previously for this item + * this will return NULL. + * + * Some policies allow items to be removed for only that policy. + * See the appropriate policy API documentation. + * + * This can be used to delete all items from the layout like so: + * + * \code + * while(!layout->isEmpty()) + * delete takeAt(0); + * \endcode + * + * And it can be used to remove an item from the layout and hide it: + * + * \code + * if( (QGraphicsItem *item = layout->takeAt(0)->graphicsItem()) ) + * item->hide; + * \endcode + * + * or to remove and hide all the items: + * + * \code + * while(!layout->isEmpty()) + * if( (QGraphicsItem *item = layout->takeAt(0)->graphicsItem()) ) + * item->hide; + * \endcode + * + * + * If you want to just remove and delete a single item, simply delete the item + * and it will be removed automatically from the layout. + * + * \sa removeItem(), removeAt() + */ + virtual QGraphicsLayoutItem *takeAt(int index); + + /*! + * \brief Remove and delete the item at the given position. + * + * The item is removed by the animation and then deleted. + * This allows for an animation when removing the item. + * The item is removed from the layout and all of its policies. + * + * Note that count() will still include this item until it is + * deleted, but this behavior may change in future revisions. + * Likewise the item can still be referenced with \link itemAt() itemAt(index) \endlink + * until the animation has finished. + * + * It is currently not possible to animatedly remove an item + * without deleting it. + * + * If the item is itself a layout, the layout will be deleted but + * the children inside will not be, and their ownership is transferred + * to the caller. + */ + virtual void animatedDeleteAt(int index); + + /*! + * \brief Remove and delete the item at the given position. + * + * Calls animatedDeleteAt() + */ + virtual void animatedDeleteItem(const QGraphicsLayoutItem *const item); + + /*! + * \brief Find the index of the given graphics item. + * + * @param item The graphics item to find. + * + * @return The index the item is stored at or -1 if it was not found. + */ + int indexOf(const QGraphicsItem *item) const; + + /*! + * \brief Find the index of the given graphics item. + * + * @param item The graphics item to find. + * + * @return The index the item is stored at or -1 if it was not found. + */ + inline int indexOf(const QGraphicsWidget *item) const { + return indexOf(static_cast(item)); + } + + /*! + * \brief Find the index of the given graphics layout item. + * + * @param item The graphics layout item to find. + * + * @return The index the item is stored at or -1 if it was not found. + */ + int indexOf(const QGraphicsLayoutItem *item) const; + + /*! + * \brief Set the active policy applied to this layout. + * + * This activates the given, already associated, policy in a layout with multiple + * policies. + * + * The policy encapsulates the actual layout logic. Switching a policy + * triggers a relayout() of all objects handled by the layout. The first + * policy created for a layout is automatically made active - there's no + * requirement to call this function if you only have one policy for a layout. + * + * Setting a policy that is not associated with this layout triggers an + * assertion. + * + * This does nothing if @p policy is NULL. + * + * This is equivalent to calling DuiAbstractLayoutPolicy::activate(). + * + * @param policy The policy to use for all layout operations. + */ + void setPolicy(DuiAbstractLayoutPolicy *policy); + + /*! \brief Convenience function to set the policy used in landscape mode. + * + * When the orientation of the device changes to landscape, the layout will + * set the given policy as active, if given. + * + * The default is NULL - the policy is not changed when the device is rotated. + * + * If the device is currently in landscape orientation and @p policy is not NULL, then the @p policy is immediately activated. + */ + void setLandscapePolicy(DuiAbstractLayoutPolicy *policy); + + /*! \brief The policy to be used in landscape mode. + * + * The default is NULL - the policy is not changed when the device is rotated. + */ + DuiAbstractLayoutPolicy *landscapePolicy() const; + + /*! \brief Convenience function to set the policy used in portrait mode. + * + * When the orientation of the device changes to portrait, the layout will + * set the given policy as active, if given. + * + * The default is NULL - the policy is not changed when the device is rotated. + * + * If the device is currently in portrait orientation and @p policy is not NULL, then the @p policy is immediately activated. + */ + void setPortraitPolicy(DuiAbstractLayoutPolicy *policy); + + /*! \brief The policy to be used in portrait mode. + * + * The default is NULL - the policy is not changed when the device is rotated. + */ + DuiAbstractLayoutPolicy *portraitPolicy() const; + + /*! + * \brief Get the currently active policy. + * + * @return The currently active policy, or NULL only if there are no associated policies. + */ + DuiAbstractLayoutPolicy *policy() const; + + /*! + * \brief Get a list of all policy objects associated with this layout. + * + * @return A list of all policies associated with this layout. None of the pointers will be NULL. + */ + QList registeredPolicies() const; + + /*! + * \brief Set the animation to be used for state transitions. + * + * If @p animation is NULL then no animations will occur - all items will jump into the new + * states without any transitions. + * + * Any previous animation is automatically deleted. + * + * @param animation The animation to be used for all state transitions. + * + * \sa animation() + */ + void setAnimation(DuiLayoutAnimation *animation); + + /*! + * \brief Get the current animation. + * + * If this is NULL then no animations will occur - all items will jump into the new + * states without any transitions. + * + * @return The currently set up animation. + * \sa setAnimation() + */ + DuiLayoutAnimation *animation() const; + + /*! + * \brief Set the default contents margins for the layout. + * + * This method sets the contents margins for the layout and can be overridden by the + * policies. + * + * If the current \link DuiAbstractLayoutPolicy::getContentsMargins() policy's getContentsMargins() \endlink + * returns -1 for any of the four parameters, the layout's content margins, set by this + * setContentsMargins() function, are used for those parameters instead. + * + * For example: + * \code + * DuiLayout *layout = new DuiLayout; + * DuiLinearLayoutPolicy *policy = new DuiLinearLayoutPolicy(layout, Qt::Horizontal); + * policy->setContentsMargins(-1, 0, -1, 0); + * layout->setContentsMargins(5, 5, 5, 5); + * qreal left, top, right, bottom; + * layout->getContentsMargins(left, top, right, bottom); + * // Now left = 5, top = 0, right = 5, bottom = 0 + * \endcode + * + * @param left Left margin. + * @param top Top margin. + * @param right Right margin. + * @param bottom Bottom margin. + * + * \sa getContentsMargins(), DuiAbstractLayoutPolicy::setContentsMargins(), DuiAbstractLayoutPolicy::getContentsMargins() + */ + virtual void setContentsMargins(qreal left, qreal top, qreal right, qreal bottom); + + /*! + * \brief Get the contents margins for the current layout and policy. + * + * For each of the parameters, this returns the value returned by the + * current \link DuiAbstractLayoutPolicy::getContentsMargins() policy's getContentsMargins()\endlink, unless that + * returns -1, in which case the value set by setContentsMargins() is used for that parameter. If + * neither have been set, the margins are set by the current QStyle. + * + * For example: + * \code + * DuiLayout *layout = new DuiLayout; + * DuiLinearLayoutPolicy *policy = new DuiLinearLayoutPolicy(layout, Qt::Horizontal); + * policy->setContentsMargins(-1, 0, -1, 0); + * layout->setContentsMargins(5, 5, 5, 5); + * qreal left, top, right, bottom; + * layout->getContentsMargins(left, top, right, bottom); + * // Now left = 5, top = 0, right = 5, bottom = 0 + * \endcode + * + * @param left Left margin. + * @param top Top margin. + * @param right Right margin. + * @param bottom Bottom margin. + * + * \sa setContentsMargins(), DuiAbstractLayoutPolicy::setContentsMargins(), DuiAbstractLayoutPolicy::getContentsMargins() + */ + virtual void getContentsMargins(qreal *left, qreal *top, qreal *right, qreal *bottom) const; + + /*! + * \brief Returns the direction the items will be laid out in. + * + * For example, layouts in a right-to-left language, + * such as Arabic or Hebrew, are usually laid out from right to left. + * + * If the layout is in a QGraphicsWidget, the layout direction is + * the QGraphicsWidget::layoutDirection(). Otherwise the QApplication::layoutDirection() + * is used. + * + * \sa QGraphicsWidget::layoutDirection(), QApplication::layoutDirection(), Qt::LayoutDirection + */ + Qt::LayoutDirection layoutDirection() const; + +protected: + /*! + * \brief Internal function to add a new item to this layout + * + * This is called by DuiAbstractLayoutPolicy when an item is added to the policy. + * + * For a user of DuiLayout, this function is protected. To add items to the layout, + * add them to the policy instead. + * + * The layout takes ownership of the item. If \link QGraphicsLayoutItem::ownedByLayout item->ownedByLayout()\endlink is true, + * the item will be deleted when the layout is deleted. + * + * The item will never be deleted by a removeAt() call and will always be deleted + * by an animatedDeleteAt() call. + * + * If the item was already added, this returns the index of its current position. + * + * @param item The item to add. + * @return Index of item whether it was added or not, or -1 if @p item is NULL + */ + virtual int addItem(QGraphicsLayoutItem *item); + + /** \internal + * This is a protected function since setGeometry() should not be called directly. The layout + * should be placed inside of another widget, and that widget's \link QGraphicsItem::setGeometry() geometry \endlink set. + * The idea is just to prevent some bugs that can be difficult to track down. + * + * This function can be called anyway, if really necessary, by: + * + * \code + * QGraphicsLayout *layout = someDuiLayout; + * layout->setGeometry(rect); + * \endcode + */ + virtual void setGeometry(const QRectF &rect); + /** \internal_end */ + + /** \internal + * Private pointer */ + DuiLayoutPrivate *const d_ptr; + /** \internal_end */ + +private: + Q_DISABLE_COPY(DuiLayout) + Q_DECLARE_PRIVATE(DuiLayout) + + + friend class DuiAbstractLayoutPolicy; + friend class DuiLayoutAnimation; + friend class DuiBasicLayoutAnimationPrivate; + friend class Ut_DuiLayout; +}; + +#endif // Header Guard diff --git a/src/layout/duilayout_p.cpp b/src/layout/duilayout_p.cpp new file mode 100644 index 000000000..203aafe7b --- /dev/null +++ b/src/layout/duilayout_p.cpp @@ -0,0 +1,227 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duilayout_p.h" + +#include "duiabstractlayoutpolicy.h" +#include "duibasiclayoutanimation.h" +#include "duilayouthelper_p.h" +#include "duiapplication.h" + +#include "duiwidget_p.h" + +#include "duidebug.h" + +DuiLayoutPrivate::DuiLayoutPrivate(DuiLayout *l) : + q_ptr(l), + portraitPolicy(NULL), + landscapePolicy(NULL), + current_policy(NULL), + animation(NULL) +{ + Q_ASSERT(0 != q_ptr); + DuiWindow *window = DuiApplication::activeWindow(); + if (window) { + connect(window, + SIGNAL(orientationChanged(Dui::Orientation)), + SLOT(orientationChanged(Dui::Orientation))); + } +} + +void DuiLayoutPrivate::registerPolicy(DuiAbstractLayoutPolicy *policy) +{ + Q_Q(DuiLayout); + Q_ASSERT(policy); + if (policies.contains(policy)) + return; + policies.append(policy); + + if (!current_policy) + q->setPolicy(policy); +} + +void DuiLayoutPrivate::unregisterPolicy(DuiAbstractLayoutPolicy *policy) +{ + Q_Q(DuiLayout); + Q_ASSERT(policy); + if (!policies.contains(policy)) + return; + + if (landscapePolicy == policy) + q->setLandscapePolicy(NULL); + if (portraitPolicy == policy) + q->setPortraitPolicy(NULL); + + policies.removeAll(policy); + if (current_policy == policy) { + if (policies.isEmpty()) + q->setPolicy(0); + else + q->setPolicy(policies.last()); + } +} + +void DuiLayoutPrivate::setItemGeometry(int index, const QRectF &geometry) +{ + Q_Q(DuiLayout); + if (0 > index || q->count() <= index) { + duiWarning("DuiLayout") << Q_FUNC_INFO << "Attempting to set the geometry of the item at index" << index << "when there are" << q->count() << "items"; + return; + } + + DuiItemState &state = states[index]; + state.setTargetGeometry(geometry); + + // If no animator or the item is a layout then do not animate + if (!animation || state.item()->isLayout()) { + //Show item + showItemNow(state.item()); + state.item()->setGeometry(state.targetGeometry()); + state.animationDone(); + itemAnimationFinished(index); + } else { + if (state.isSet(DuiItemState::STATE_FLAG_TO_BE_SHOWN)) { + animation->doItemShownAnimation(&state); + //we only want to call the item shown animation once, so clear the shown flags + state.removeFlags(DuiItemState::STATE_FLAG_TO_BE_SHOWN); + state.addFlags(DuiItemState::STATE_FLAG_SHOWING); + } + if (state.isAnimationDone()) //Set the geometry anyway, so that it can refresh + state.item()->setGeometry(state.targetGeometry()); + else + animation->startAnimation(&state); + } +} + +QRectF DuiLayoutPrivate::itemGeometry(int index) const +{ + Q_Q(const DuiLayout); + if (0 > index || q->count() <= index) { + duiWarning("DuiLayout") << Q_FUNC_INFO << "Attempting to set the geometry of the item at index" << index << "when there are" << q->count() << "items"; + return QRectF(); + } + + return states.at(index).targetGeometry(); +} +void DuiLayoutPrivate::itemAnimationFinished(int index) +{ + Q_Q(DuiLayout); + Q_ASSERT(states.at(index).isAnimationDone()); + if (states.at(index).isSet(DuiItemState::STATE_FLAG_TO_BE_DELETED)) + q->removeAt(index); //This will delete the item as well +} + +void DuiLayoutPrivate::animationFinished() +{ + // check whether any item is now really deleted + for (int i = states.size() - 1; i >= 0; --i) { + if (states.at(i).isAnimationDone()) + itemAnimationFinished(i); + } +} + +void DuiLayoutPrivate::hideItem(int index) +{ + DuiItemState &state = states[index]; + //Check if its being hidden or if it is hiding (i.e. not shown and not to-be-shown + if (state.isSet(DuiItemState::STATE_FLAG_TO_BE_HIDDEN) || + (!state.isSet(DuiItemState::STATE_FLAG_TO_BE_SHOWN) && + !state.isSet(DuiItemState::STATE_FLAG_SHOWING))) { + return; //It's already hiding/hidden. Nothing to do + } + state.hide(); + + QGraphicsItem *graphics_item = state.item()->graphicsItem(); + if (!animation || (graphics_item && !graphics_item->isVisibleTo(NULL))) { //If it isn't visible, do not bother to animate it + //Hide item directly + hideItemNow(state.item()); + //we can't do anything to hide something which isn't a QGraphicsItem + state.removeFlags( + DuiItemState::STATE_FLAG_TO_BE_HIDDEN | + DuiItemState::STATE_FLAG_TO_BE_SHOWN | + DuiItemState::STATE_FLAG_SHOWING); + } else { + animation->doItemHiddenAnimation(&state); + state.hide(); //setTargetGeometry clears TO_BE_HIDDEN, so re-add + animation->startAnimation(&state); + } + +} + +void DuiLayoutPrivate::orientationChanged(const Dui::Orientation &orientation) +{ + if (orientation == Dui::Portrait) { + if (portraitPolicy) + portraitPolicy->activate(); + } else if (landscapePolicy) + landscapePolicy->activate(); + //since the rotation has changed, reread the values from the CSS config + foreach(DuiAbstractLayoutPolicy * policy, policies) { + Q_ASSERT(policy); + policy->updateStyle(); + } +} +QGraphicsItem *DuiLayoutPrivate::parentItem() const +{ + Q_Q(const DuiLayout); + + const QGraphicsLayoutItem *parent = q; + while (parent && parent->isLayout()) { + parent = parent->parentLayoutItem(); + } + return parent ? parent->graphicsItem() : 0; +} + +void DuiLayoutPrivate::showItemNow(QGraphicsLayoutItem *layoutItem) +{ + QGraphicsItem *graphicsItem = layoutItem->graphicsItem(); + if (graphicsItem) { + DuiWidget *widget = dynamic_cast(graphicsItem); + if (widget) { + widget->d_ptr->layoutHidden = false; + if (!widget->d_ptr->explicitlyHidden) + graphicsItem->show(); //Show only if item was not set to invisible by the user + } else + graphicsItem->show(); //Show always for non-duiwidgets + } +} +void DuiLayoutPrivate::removeHiddenFlag(QGraphicsLayoutItem *layoutItem) +{ + DuiWidget *widget = dynamic_cast(layoutItem->graphicsItem()); + if (widget) + widget->d_ptr->layoutHidden = false; +} +void DuiLayoutPrivate::hideItemNow(QGraphicsLayoutItem *layoutItem) +{ + QGraphicsItem *graphicsItem = layoutItem->graphicsItem(); + if (graphicsItem) { + graphicsItem->hide(); + DuiWidget *widget = dynamic_cast(graphicsItem); + if (widget) + widget->d_ptr->layoutHidden = true; + } + //There's not really anything we can do to hide an item that isn't a QGraphicsItem + //DuiLayout, for example, is not a QGraphicsItem, but just a QGraphicsLayoutItem + //The following code moves the item out of the way, but in practice this doesn't + //really work since coordinates all relative +} + + +#include "moc_duilayout_p.cpp" + diff --git a/src/layout/duilayout_p.h b/src/layout/duilayout_p.h new file mode 100644 index 000000000..5edef6b63 --- /dev/null +++ b/src/layout/duilayout_p.h @@ -0,0 +1,129 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUILAYOUT_P_H +#define DUILAYOUT_P_H + +#include "duilayout.h" +#include "duilayoutanimation.h" + +#include +#include + +#include + +class QGraphicsLayoutItem; +class DuiLayoutAnimation; + +/** Private Layout class. + */ +class DuiLayoutPrivate : public QObject +{ + Q_OBJECT +public: + + /** Constructor */ + explicit DuiLayoutPrivate(DuiLayout *l); + + /*! + * \brief Method to register a policy with this layout. + * + * This is called by DuiAbstractLayoutPolicy when an instance is created. + * If there are no other registered policies, this will become the active (current) policy. + * + * @param policy The policy to register. + */ + void registerPolicy(DuiAbstractLayoutPolicy *policy); + + /*! + * \brief Method to unregister a policy with this layout. + * + * This is called by DuiAbstractLayoutPolicy when an instance is destroyed. + * + * If this policy was currently active, the most recently created policy will become automatically + * active. If there are no policies left, the current policy will become NULL. + * + * @param policy The policy to deregister. + */ + void unregisterPolicy(DuiAbstractLayoutPolicy *policy); + + /*! \brief Set the target geometry of the given item to the given geometry. + * + * This is called by DuiAbstractLayoutPolicy::setGeometry() to set the target + * geometry of the item. + * + * Note that this causes the item to be shown, if it's being hidden. + */ + void setItemGeometry(int index, const QRectF &geometry); + + /*! \brief Return the target geometry of the item at the given index. + */ + QRectF itemGeometry(int index) const; + + /*! \brief Hide the given item. + * + * Items can be hidden by the policies and are automatically hidden when + * switching to a policy not visible. Items become visible again with a + * subsequent call to setItemGeometry(). + * + * To hide items as a user of DuiLayout, see \ref visibility + */ + void hideItem(int index); + + /** This is called by the animator to trigger cleanup tasks. */ + void animationFinished(); + /** This is called when an item's animation has finished, to delete + * the item if it needs deleting */ + void itemAnimationFinished(int index); + + /** The list of defined ItemState items known to the layout. */ + QList states; + + /** Go up the parents and return the first parent that is not a layout */ + QGraphicsItem *parentItem() const; + + /** Hide the given item, setting a flag in DuiWidget to indicate that the layout hid it */ + void hideItemNow(QGraphicsLayoutItem *layoutItem); + /** Show the given item if it was hidden by the layout, clearing the flag in DuiWidget to indicate that the layout unhid it */ + void showItemNow(QGraphicsLayoutItem *layoutItem); + /** Only clear the flag in DuiWidget */ + void removeHiddenFlag(QGraphicsLayoutItem *layoutItem); +protected slots: + /** This is called when the device's orientation has changed */ + void orientationChanged(const Dui::Orientation &orientation); + + +protected: + Q_DECLARE_PUBLIC(DuiLayout) + // Shared d_ptr related code: + DuiLayout *q_ptr; + DuiAbstractLayoutPolicy *portraitPolicy; + DuiAbstractLayoutPolicy *landscapePolicy; + + /** The policy object governing layout. */ + DuiAbstractLayoutPolicy *current_policy; + + /** The layout animation for this policy */ + DuiLayoutAnimation *animation; + + /** Policies that are associated with this layout. */ + QList policies; +}; + +#endif // Header Guard diff --git a/src/layout/duilayoutanimation.cpp b/src/layout/duilayoutanimation.cpp new file mode 100644 index 000000000..7438af1cd --- /dev/null +++ b/src/layout/duilayoutanimation.cpp @@ -0,0 +1,83 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duilayoutanimation.h" +#include "duilayoutanimation_p.h" +#include "duilayout_p.h" +#include "duianimation.h" + +DuiLayoutAnimation::DuiLayoutAnimation(DuiLayout *layout) + : DuiAnimation(NULL), d_ptr(new DuiLayoutAnimationPrivate) +{ + Q_ASSERT(layout); + Q_D(DuiLayoutAnimation); + d->layout = layout; + layout->setAnimation(this); +} + +DuiLayoutAnimation::DuiLayoutAnimation(DuiLayoutAnimationPrivate &p, DuiLayout *layout) + : DuiAnimation(NULL), d_ptr(&p) +{ + Q_ASSERT(layout); + Q_ASSERT(0 != d_ptr); + Q_D(DuiLayoutAnimation); + d->layout = layout; + layout->setAnimation(this); +} + +DuiLayout *DuiLayoutAnimation::layout() const +{ + Q_D(const DuiLayoutAnimation); + return d->layout; +} + +DuiLayoutAnimation::~DuiLayoutAnimation() +{ + delete d_ptr; +} + +void DuiLayoutAnimation::startAnimation(DuiItemState *itemstate) +{ + layoutAnimationStarted(itemstate); +} +bool DuiLayoutAnimation::isAnimating() const +{ + return state() == QAbstractAnimation::Running; +} +void DuiLayoutAnimation::stopAnimation() +{ + Q_D(DuiLayoutAnimation); + if (!isAnimating()) + return; + d->layout->d_ptr->animationFinished(); + layoutAnimationFinished(); +} + +void DuiLayoutAnimation::showItemNow(QGraphicsLayoutItem *item) +{ + Q_D(DuiLayoutAnimation); + Q_ASSERT(item); + d->layout->d_ptr->showItemNow(item); +} +void DuiLayoutAnimation::hideItemNow(QGraphicsLayoutItem *item) +{ + Q_D(DuiLayoutAnimation); + Q_ASSERT(item); + d->layout->d_ptr->hideItemNow(item); +} diff --git a/src/layout/duilayoutanimation.h b/src/layout/duilayoutanimation.h new file mode 100644 index 000000000..8787acc8d --- /dev/null +++ b/src/layout/duilayoutanimation.h @@ -0,0 +1,187 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUILAYOUTANIMATION_H +#define DUILAYOUTANIMATION_H + +#include "duianimation.h" +#include "duiexport.h" +#include "duiitemstate.h" +#include "duilayout.h" +class DuiLayoutAnimationPrivate; + +/*! + * \class DuiLayoutAnimation + * \brief Animation interface for animating adding and removing of items and animating + * switching between policies in a DuiLayout. + * + * This class provides an base class to be used to animate changes + * in the DuiLayout. To reduce the memory footprint as well as + * CPU wakeups this class can be used by several layouts at the same + * time. + * + * The DuiLayout calls the public startAnimation() whenever it sees an item in need + * for animation. The layout is then added to a list of layouts to animate. + * This triggers a call to the virtual layoutAnimationStarted() function which is implemented + * by subclasses. + * + * Note that the item to animate will never itself be a layout, as layout items themselves are + * not animated. + * + * \section custom_animation How to write a custom animation + * + * The main method to implement for an animator is layoutAnimationStarted(DuiLayout * const layout, DuiItemState *itemstate). + * The implementing class would typically call DuiItemState::targetGeometry() and + * DuiItemState::targetOpacity() to determine the target state, then animate the + * DuiItemState::item() to that final geometry and opacity. + * + * The layoutAnimationFinished() is called when all the items in the given layout are + * flagged as DuiItemState::isAnimationDone() + * and may be reimplemented to turn off any timers etc. The default implementation does nothing. + * + * The doItemShownAnimation() must be implemented to provide an animation to show + * the items. At minimum this should set the item's geometry to something suitable and QGraphicsItem::show() the item. + * + * The doItemHiddenAnimation() may also be implemented to provide an animation to hide the item. + * + * The implementation must also decide whether the animation for the + * current item is finished. When the animation is completed it should call + * DuiItemState::animationDone(). + */ +class DUI_EXPORT DuiLayoutAnimation : public DuiAnimation +{ +public: + /*! + * \brief Construct the layout animator. + */ + explicit DuiLayoutAnimation(DuiLayout *layout); + /*! + * \brief Destroys the layout animator. + */ + virtual ~DuiLayoutAnimation(); + + /*! + * \brief Requests animation for an item. + * + * This requests animation for the given DuiItemState that is in the given layout. This in + * turns calls layoutAnimationStarted(). + * + * @param layout The layout that the itemstate is in + * @param itemstate The item that needs animating + */ + void startAnimation(DuiItemState *itemstate); + + /*! + * \brief Stop all the animations on this layout immediately. + */ + void stopAnimation(); + + /*! + * \brief Return whether the animator is currently animating any items. + */ + bool isAnimating() const; + + /*! + * \brief Called when an item is been shown. + * + * This function is called when an item has been added to the current policy + * or is being shown. It can be implemented to provide an animation. + */ + virtual void doItemShownAnimation(DuiItemState *itemstate) = 0; + + /*! + * \brief Called when an item is being hidden. + * + * This function is called when an item us being hidden (e.g. if the layout switches to a policy + * that doesn't contain this item or the item is removed from the policy). It can be + * implemented to provide an animation. + * + * The default implementation does nothing. + */ + virtual void doItemHiddenAnimation(DuiItemState *itemstate) { + Q_UNUSED(itemstate) + }; + + /*! + * \brief Called when an animatedDeleteAt has been called for an item. + * + * This function is called when DuiLayout::animatedDeleteAt() is called for an item, + * It can be implemented to provide an animation. + * + * The default implementation calls doItemHiddenAnimation(). + */ + virtual void doItemDeletingAnimation(DuiItemState *itemstate) { + doItemHiddenAnimation(itemstate); + } + + /*! + * \brief Return a pointer to the associated layout + */ + DuiLayout *layout() const; +protected: + /*! + * \brief Notifies derived animator classes whenever an animation is started. + * + * You can override this method to maintain internal state. + * + * This function will be called for every item in the layout that is animated, + * each time with a different itemstate. + * + * Any changes made to the itemstate will be saved to the layout. This allows + * for animating adding, removing, showing and hiding of items. + * + * @param layout The layout whose animation is started. + * @param itemstate A pointer to the item that has begun animating + */ + virtual void layoutAnimationStarted(DuiItemState *itemstate) = 0; + + /*! + * \brief Notifies derived animator classes whenever all the animations on a layout have finished. + * + * You can override this method to maintain internal state. The default implementation does nothing. + * + * @param layout the layout whose animation is complete. + */ + virtual void layoutAnimationFinished() {}; + + /*! \brief Hide the given item. + * + * Dervived classes should call this function to hide the given item, rather than + * calling QGraphicsItem::hide() on the item directly. */ + void hideItemNow(QGraphicsLayoutItem *item); + + /*! \brief Show the given item if it was hidden by the layout. + * + * Dervived classes should call this function to show the given item, rather than + * calling QGraphicsItem::show() on the item directly. */ + void showItemNow(QGraphicsLayoutItem *item); + + /** \internal + * Shared d_ptr setup constructor. */ + explicit DuiLayoutAnimation(DuiLayoutAnimationPrivate &, DuiLayout *layout); + /** \internal_end */ + + DuiLayoutAnimationPrivate *const d_ptr; + +private: + Q_DISABLE_COPY(DuiLayoutAnimation) + Q_DECLARE_PRIVATE(DuiLayoutAnimation) +}; + +#endif // Header Guard diff --git a/src/layout/duilayoutanimation_p.h b/src/layout/duilayoutanimation_p.h new file mode 100644 index 000000000..586ef0d79 --- /dev/null +++ b/src/layout/duilayoutanimation_p.h @@ -0,0 +1,47 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUILAYOUTANIMATION_P_H +#define DUILAYOUTANIMATION_P_H + +#include "duilayoutanimation.h" + +#include +#include +#include + +/** Private animator class. */ +class DuiLayoutAnimationPrivate +{ + Q_DECLARE_PUBLIC(DuiLayoutAnimation) + +public: + /** Constructor */ + DuiLayoutAnimationPrivate() {} + /** Destructor */ + virtual ~DuiLayoutAnimationPrivate() {} + + DuiLayout *layout; + +protected: + // Shared d_ptr related code: + DuiLayoutAnimation *q_ptr; +}; + +#endif // Header Guard diff --git a/src/layout/duilayouthelper_p.h b/src/layout/duilayouthelper_p.h new file mode 100644 index 000000000..17058e295 --- /dev/null +++ b/src/layout/duilayouthelper_p.h @@ -0,0 +1,145 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUILAYOUTHELPER_H +#define DUILAYOUTHELPER_H + +#include +#include + +//! \internal + +/*! + * \brief Helper function to operate on all graphics items in and below a layout item at once. + * + * This functions iterates over all layouts and sub-layouts to find all graphics items + * and uses the given function object on all those graphics items. + * The function object can return a collected value with the value() method. + * + * @param startItem the layout item to start the iteration at + * @param function the function object whose ()-operator is used on all graphics + * items + * + * @return the value returned by the value() method of the given function object + * + * @see SetOpacity, GetOpacity + */ +template typename F::return_type forAllGraphicsItems(QGraphicsLayoutItem *startItem, F function) +{ + QList items; + items.push_back(startItem); + + while (items.size() > 0) { + QGraphicsLayoutItem *item = items.front(); + items.pop_front(); + + if (0 == item) { + continue; + } + + if (item->graphicsItem()) { + // call the function on graphics item directly + function(item->graphicsItem()); + } else if (item->isLayout()) { + // for layouts, queue up all contained child items + QGraphicsLayout *layout = static_cast(item); + + const int count = layout->count(); + for (int j = 0; j < count; ++j) { + items.push_back(layout->itemAt(j)); + } + } + } + + // the functor might have collected a value, just return it + return function.value(); +} + +/*! + * \brief A base class that is useful to implement function objects for forAllGraphicsItems. + * + * It handles the internal value, so that this code does not have to be repeated in + * every class. If you need a value for the operation you have to specify a constructor + * that uses the base class constructor with the value given. + * + */ +template struct GraphicsItemFunction { + typedef VAL return_type; + + GraphicsItemFunction(VAL startValue = 0) : m_value(startValue) {} + return_type value() { + return m_value; + } + +protected: + return_type m_value; +}; + +/*! + * \brief Function object for forAllGraphicsItems to set the opacity + */ +struct SetOpacity : public GraphicsItemFunction { + SetOpacity(qreal value) : GraphicsItemFunction(value) {} + void operator()(QGraphicsItem *item) { + Q_ASSERT(item); + item->setOpacity(m_value); + } +}; + +/*! + * \brief Function object for forAllGraphicsItems to get the opacity. + * + * The collected opacity is the maximum of all opactities of the + * graphics items. + */ +struct GetOpacity : public GraphicsItemFunction { + void operator()(QGraphicsItem *item) { + Q_ASSERT(item); + if (item->isVisible()) + m_value = qMax(item->opacity(), m_value); + } +}; + +class ProxyItem : public QGraphicsLayoutItem +{ +public: + ProxyItem(QGraphicsLayoutItem *proxiedItem) { + item = proxiedItem; + setOwnedByLayout(true); + } + virtual QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const { + return item->effectiveSizeHint(which, constraint); + } + virtual void getContentsMargins(qreal *left, qreal *top, qreal *right, qreal *bottom) const { + item->getContentsMargins(left, top, right, bottom); + } + QGraphicsLayoutItem *proxiedItem() const { + return item; + } + void refresh() { + updateGeometry(); + setSizePolicy(item->sizePolicy()); + } +private: + QGraphicsLayoutItem *item; +}; + +//! \internal_end + +#endif // Header Guard diff --git a/src/layout/duilinearlayoutpolicy.cpp b/src/layout/duilinearlayoutpolicy.cpp new file mode 100644 index 000000000..7c3037c8e --- /dev/null +++ b/src/layout/duilinearlayoutpolicy.cpp @@ -0,0 +1,226 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duilinearlayoutpolicy.h" +#include "duilinearlayoutpolicy_p.h" + +#include "duilayout.h" +#include "duilayouthelper_p.h" +#include "duidebug.h" + +#include +#include +#include +DuiLinearLayoutPolicy::DuiLinearLayoutPolicy(DuiLayout *l, Qt::Orientation o) : + DuiAbstractLayoutPolicy(*(new DuiLinearLayoutPolicyPrivate(l, o))) +{ } + +DuiLinearLayoutPolicy::~DuiLinearLayoutPolicy() +{ } + +void DuiLinearLayoutPolicy::addItem(QGraphicsLayoutItem *item) +{ + insertItem(-1, item); +} +void DuiLinearLayoutPolicy::addItem(QGraphicsLayoutItem *item, Qt::Alignment alignment) +{ + insertItem(-1, item, alignment); +} + +void DuiLinearLayoutPolicy::insertItem(int index, QGraphicsLayoutItem *item) +{ + Q_D(DuiLinearLayoutPolicy); + if (!item) { + duiWarning("DuiLinearLayoutPolicy") << Q_FUNC_INFO << "cannot insert null item"; + return; + } + if (item == d->layout) { + duiWarning("DuiLinearLayoutPolicy") << Q_FUNC_INFO << "cannot insert self"; + return; + } + + d->fixIndex(&index); + d->rowCount++; + ProxyItem *proxyItem = new ProxyItem(item); + d->engine->insertItem(index, proxyItem); + DuiAbstractLayoutPolicy::insertItem(index, item); +} + +void DuiLinearLayoutPolicy::insertItem(int index, QGraphicsLayoutItem *item, Qt::Alignment alignment) +{ + insertItem(index, item); + setAlignment(item, alignment); +} + +qreal DuiLinearLayoutPolicy::spacing() const +{ + Q_D(const DuiLinearLayoutPolicy); + (void)style(); //Make sure the style is loaded + return d->engine->spacing(); +} + +void DuiLinearLayoutPolicy::setItemSpacing(int index, qreal spacing) +{ + Q_D(DuiLinearLayoutPolicy); + if (itemSpacing(index) == spacing) + return; + d->engine->setItemSpacing(index, spacing); + invalidatePolicyAndLayout(); +} + +qreal DuiLinearLayoutPolicy::itemSpacing(int index) const +{ + Q_D(const DuiLinearLayoutPolicy); + return d->engine->itemSpacing(index); +} + +void DuiLinearLayoutPolicy::insertStretch(int index, int stretch) +{ + Q_D(DuiLinearLayoutPolicy); + //FIXME This is going to screw everything up since we don't insert the item to the base class.. + d->fixIndex(&index); + d->rowCount++; + d->engine->insertStretch(index, stretch); + invalidatePolicyAndLayout(); +} +void DuiLinearLayoutPolicy::setStretchFactor(QGraphicsLayoutItem *item, int stretch) +{ + Q_D(DuiLinearLayoutPolicy); + if (!item) { + duiWarning("DuiLinearLayoutPolicy") << Q_FUNC_INFO << "cannot assign a stretch factor to a null item"; + return; + } + if (stretchFactor(item) == stretch) + return; + d->engine->setStretchFactor(item, stretch); + invalidatePolicyAndLayout(); +} +int DuiLinearLayoutPolicy::stretchFactor(QGraphicsLayoutItem *item) const +{ + Q_D(const DuiLinearLayoutPolicy); + if (!item) { + duiWarning("DuiLinearLayoutPolicy") << Q_FUNC_INFO << "cannot return a stretch factor for a null item"; + return 0; + } + return d->engine->stretchFactor(item); +} + +void DuiLinearLayoutPolicy::setOrientation(Qt::Orientation orientation) +{ + Q_D(DuiLinearLayoutPolicy); + if (orientation != d->engine->orientation()) { + d->engine->setOrientation(orientation); + if (orientation == Qt::Horizontal) + d->engine->setSpacing(horizontalSpacing()); + else + d->engine->setSpacing(verticalSpacing()); + invalidatePolicyAndLayout(); + } +} + +Qt::Orientation DuiLinearLayoutPolicy::orientation() const +{ + Q_D(const DuiLinearLayoutPolicy); + return d->engine->orientation(); +} + +void DuiLinearLayoutPolicy::removeAt(int index) +{ + Q_D(DuiLinearLayoutPolicy); + if (index < 0 || index >= d->engine->count()) { + duiWarning("DuiLinearLayoutPolicy") << Q_FUNC_INFO << "invalid index" << index; + return; + } + QGraphicsLayoutItem *proxyItem = d->engine->itemAt(index); + d->rowCount--; + d->engine->removeAt(index); + delete proxyItem; + DuiAbstractLayoutPolicy::removeAt(index); +} +QSizeF DuiLinearLayoutPolicy::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const +{ + Q_D(const DuiLinearLayoutPolicy); + + d->engine->setMinimumSize(QSizeF(-1, -1)); + d->engine->setMaximumSize(QSizeF(-1, -1)); + const_cast(d)->refreshEngine(); + return d->engine->sizeHint(which, constraint); +} + +void DuiLinearLayoutPolicy::relayout() +{ + Q_D(DuiLinearLayoutPolicy); + d->engine->setMinimumSize(layout()->minimumSize()); + d->engine->setMaximumSize(layout()->maximumSize()); + d->refreshEngine(); + d->engine->activate(); + + if (!isActive()) + return; + for (int i = d->engine->count() - 1; i >= 0; --i) { + const QGraphicsLayoutItem *item = d->engine->itemAt(i); + setItemGeometry(i, item->geometry()); + } +} + +void DuiLinearLayoutPolicy::invalidate() +{ + Q_D(DuiLinearLayoutPolicy); + d->engine->invalidate(); + DuiAbstractLayoutPolicy::invalidate(); +} + +void DuiLinearLayoutPolicy::setHorizontalSpacing(qreal spacing) +{ + Q_D(DuiLinearLayoutPolicy); + DuiAbstractLayoutPolicy::setHorizontalSpacing(spacing); + if (orientation() == Qt::Horizontal) + d->engine->setSpacing(spacing); +} + +void DuiLinearLayoutPolicy::setVerticalSpacing(qreal spacing) +{ + Q_D(DuiLinearLayoutPolicy); + DuiAbstractLayoutPolicy::setVerticalSpacing(spacing); + if (orientation() == Qt::Vertical) + d->engine->setSpacing(spacing); +} +void DuiLinearLayoutPolicy::setSpacing(qreal spacing) +{ + Q_D(DuiLinearLayoutPolicy); + DuiAbstractLayoutPolicy::setHorizontalSpacing(spacing); + DuiAbstractLayoutPolicy::setVerticalSpacing(spacing); + d->engine->setSpacing(spacing); +} + +void DuiLinearLayoutPolicy::setAlignment(QGraphicsLayoutItem *item, Qt::Alignment alignment) +{ + Q_D(DuiLinearLayoutPolicy); + QGraphicsLayoutItem *proxyItem = d->engine->itemAt(indexOf(item)); + d->engine->setAlignment(proxyItem, alignment); + invalidatePolicyAndLayout(); +} + +Qt::Alignment DuiLinearLayoutPolicy::alignment(QGraphicsLayoutItem *item) const +{ + Q_D(const DuiLinearLayoutPolicy); + QGraphicsLayoutItem *proxyItem = d->engine->itemAt(indexOf(item)); + return d->engine->alignment(proxyItem); +} + diff --git a/src/layout/duilinearlayoutpolicy.h b/src/layout/duilinearlayoutpolicy.h new file mode 100644 index 000000000..6d4a34268 --- /dev/null +++ b/src/layout/duilinearlayoutpolicy.h @@ -0,0 +1,275 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUILINEARLAYOUTPOLICY_H +#define DUILINEARLAYOUTPOLICY_H + +#include "duiabstractlayoutpolicy.h" + +class DuiLinearLayoutPolicyPrivate; +class QGraphicsLayoutItem; + +/*! + * \class DuiLinearLayoutPolicy + * \brief Policy that uses the Qt grid layout engine to provide a horizontal or vertical linear layout. + * \ingroup layouts + * + * This class provides a policy which is similar to QGraphicsLinearLayout, with the advantage + * of allowing multiple policies and animation. You can use QGraphicsLinearLayout instead + * to slightly reduce memory overhead if these advantages are not required. + * + * The following example adds items to the linear layout policy: + * + * \dontinclude duilinearlayoutpolicy/duilinearlayoutpolicy.cpp + * \skip Create a DuiLayout + * \until } + * + * The result, with appropriate CSS styling, looks like: + * \image html duilinearlayoutpolicy.png + * + * \sa \ref layout-duilinearlayoutpolicy + * + * \section using_qt_instead Using QGraphicsLinearLayout instead + * + * If you do not need animations or multiple policies, you can use QGraphicsLinearLayout for same effect in less code. + * For example: + * + * \dontinclude qgraphicslinearlayout/qgraphicslinearlayout.cpp + * \skip Create a linear layout + * \until } + * \sa \ref layout-qgraphicslinearlayout, \ref layout-qgraphicslayout + */ +class DUI_EXPORT DuiLinearLayoutPolicy : public DuiAbstractLayoutPolicy +{ +public: + /*! + * \brief Constructs a linear layout policy. + * + * The initial @p orientation is required by the constructor, but can be changed at any time + * with setOrientation(). + * + * @param layout The layout to associate with. + * @param orientation The orientation to use for this layout. + */ + explicit DuiLinearLayoutPolicy(DuiLayout *layout, Qt::Orientation orientation); + + /*! + * \brief Destroys the linear layout policy. + */ + virtual ~DuiLinearLayoutPolicy(); + + /*! + * \brief Get the spacing. The spacing is the distance between the items + * + * Note that in the CSS file, the attributes are horizontal-spacing and vertical-spacing. + * The appropriate spacing is used depending on whether the linear layout is horizontal + * or vertical. + * The horizontal and vertical spacing can also be set individually with + * setHorizontalSpacing() and setVerticalSpacing() + * + * @return The spacing to use. + * \sa QGraphicsLinearLayout::spacing() + */ + qreal spacing() const; + + /*! + * \brief Set the spacing. The spacing is the distance between the items + * + * \sa QGraphicsLinearLayout::setSpacing() + */ + virtual void setSpacing(qreal spacing); + + /*! + * \brief Set the spacing after the item at @p index. + * + * This overrides any spacing set by setSpacing(). + * + * @param index The position of the item to set the spacing after. + * @param spacing The spacing to use. + * + * \sa itemSpacing(), setSpacing(), spacing(), QGraphicsLinearLayout::setItemSpacing() + */ + void setItemSpacing(int index, qreal spacing); + + /*! + * \brief Get the spacing after the item at the given @p index. + * + * This overrides any spacing set by setSpacing(). + * + * @param index The position of the item to get the spacing after. + * @return The spacing to use. + * \sa QGraphicsLinearLayout::itemSpacing() + */ + qreal itemSpacing(int index) const; + + /*! + * \brief Returns the layout orientation. + * \sa setOrientation() + */ + Qt::Orientation orientation() const; + + /*! + * \brief Change the layout policy orientation to \a orientation. + * + * Changing the policy orientation will automatically invalidate the policy + * and invalidate the layout if this policy is the current layout policy. + * + * \sa orientation() + */ + void setOrientation(Qt::Orientation orientation); + + /*! \brief Add an item to the end of the linear layout policy. + * + * This adds the given item to the end of the linear layout policy, using the default + * alignment of 0. + * + * Equivalent to: + * \code + * insertItem(item, -1); + * \endcode + * + * Note that the order of the items in the policy is independent of the order of the items + * in the DuiLayout. + * + * @param item The item to add. + */ + virtual void addItem(QGraphicsLayoutItem *item); + + /*! \brief Add an item to the end of the linear layout policy with the given alignment + * + * This adds the given item to the end of the linear layout policy, using the given @p alignment + * + * Equivalent to: + * \code + * insertItem(item, -1, alignment); + * \endcode + * + * Note that the order of the items in the policy is independent of the order of the items + * in the DuiLayout. + * + * @param item The item to add. + */ + void addItem(QGraphicsLayoutItem *item, Qt::Alignment alignment); + + /*! + * \brief Insert an item in the policy at the given index. + * + * Inserts @p item into the @p layout at index, or before any item that is currently at @p index. + * + * Note that the order of the items in the policy is independent of the order of the items + * in the DuiLayout. + * + * @param item The item to insert. + * @param index The index to place the item + */ + virtual void insertItem(int index, QGraphicsLayoutItem *item); + + /*! \brief Insert an item in the policy at the given index with the given alignment. + * + * Inserts @p item into the @p layout at index, or before any item that is currently at @p index. + * + * Note that the order of the items in the policy is independent of the order of the items + * in the DuiLayout. + * + * @param item The item to insert. + * @param index The index to place the item + */ + void insertItem(int index, QGraphicsLayoutItem *item, Qt::Alignment alignment); + + /*! \brief Add a stretch with the given \a stretch factor + * + * This convenience function is equivalent to calling + * \code + * insertStretch(-1, stretch). + * \endcode + * + * Adding a stretch does not increase the count() of the policy, cannot be refderenced by itemAt(), + * and cannot be removed. + * + */ + inline void addStretch(int stretch = 1) { + insertStretch(-1, stretch); + } + + /** \brief Inserts a stretch of \a stretch at \a index, or before any item that is currently at \a index + * + * Adding a stretch does not increase the count() of the policy, cannot be refderenced by itemAt(), + * and cannot be removed. + * + * \sa addStretch(), setStretchFactor(), setItemSpacing(), insertItem() + */ + void insertStretch(int index, int stretch = 1); + + /*! \brief Returns the stretch factor for \a item. + * + * The default stretch factor is 0, meaning that the item has no assigned stretch factor. + * \sa setStretchFactor() + */ + int stretchFactor(QGraphicsLayoutItem *item) const; + + /*! \brief Sets the stretch factor for \a item to \a stretch. + * + * If an item's stretch factor changes, this function will invalidate the layout. + * Setting \a stretch to 0 removes the stretch factor from the item, and is + * effectively equivalent to setting \a stretch to 1. + * + * \sa stretchFactor() + */ + void setStretchFactor(QGraphicsLayoutItem *item, int stretch); + + /*! + Returns the alignment for \a item. The default alignment is + Qt::AlignCenter. + + The alignment decides how the item is positioned within its assigned space + in the case where there's more space available in the layout than the + widgets can occupy. + + \sa setAlignment() + */ + Qt::Alignment alignment(QGraphicsLayoutItem *item) const; + /*! + Sets the alignment of \a item to \a alignment. If \a item's alignment + changes, the layout is automatically invalidated. + + \sa alignment(), invalidate() + */ + void setAlignment(QGraphicsLayoutItem *item, Qt::Alignment alignment); + + + /*! \reimp */ + virtual QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const; + virtual void setHorizontalSpacing(qreal spacing); + virtual void setVerticalSpacing(qreal spacing); + virtual void removeAt(int index); + /*! \reimp_end */ + + +protected: + /*! \reimp */ + virtual void relayout(); + virtual void invalidate(); + /*! \reimp_end */ + +private: + Q_DISABLE_COPY(DuiLinearLayoutPolicy) + Q_DECLARE_PRIVATE(DuiLinearLayoutPolicy) +}; + +#endif // Header Guard diff --git a/src/layout/duilinearlayoutpolicy_p.cpp b/src/layout/duilinearlayoutpolicy_p.cpp new file mode 100644 index 000000000..10fccda30 --- /dev/null +++ b/src/layout/duilinearlayoutpolicy_p.cpp @@ -0,0 +1,71 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duilinearlayoutpolicy_p.h" + +#include +#include +#include + +#include "duilayout.h" +#include "duilayouthelper_p.h" +DuiLinearLayoutPolicyPrivate::DuiLinearLayoutPolicyPrivate(DuiLayout *layout, Qt::Orientation orientation) : + DuiAbstractLayoutPolicyPrivate(layout), engineWidget(new QGraphicsWidget), engine(new QGraphicsLinearLayout(orientation, engineWidget)) +{ + rowCount = 0; + engineWidget->setContentsMargins(0, 0, 0, 0); + engineWidget->setMinimumSize(0, 0); + engineWidget->setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); +} + +DuiLinearLayoutPolicyPrivate::~DuiLinearLayoutPolicyPrivate() +{ + delete engineWidget; //This deletes the engine, which in turn deletes all of its children +} + +void DuiLinearLayoutPolicyPrivate::fixIndex(int *index) const +{ + if (uint(*index) >= uint(rowCount)) + *index = rowCount; +} + +void DuiLinearLayoutPolicyPrivate::refreshEngine() +{ + engineWidget->setLayoutDirection(layout->layoutDirection()); //Make sure that we have our RTL/LTR correct + + engine->invalidate(); + for (int i = engine->count() - 1; i >= 0; --i) { + ProxyItem *item = static_cast(engine->itemAt(i)); + item->refresh(); + } + qreal left, top, right, bottom; + layout->getContentsMargins(&left, &top, &right, &bottom); + engine->setContentsMargins(left, top, right, bottom); + + engine->updateGeometry(); + + //We need to make engine->geometry() equal the layout->geometry() so that the items are in the right place + qreal topMargin = layout->geometry().top(); + qreal leftMargin = layout->geometry().left(); + qreal width = layout->geometry().right(); + qreal height = layout->geometry().bottom(); + engineWidget->setContentsMargins(leftMargin, topMargin, 0, 0); + engineWidget->resize(width, height); +} + diff --git a/src/layout/duilinearlayoutpolicy_p.h b/src/layout/duilinearlayoutpolicy_p.h new file mode 100644 index 000000000..a1843b40d --- /dev/null +++ b/src/layout/duilinearlayoutpolicy_p.h @@ -0,0 +1,56 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUILINEARLAYOUTPOLICY_P_H +#define DUILINEARLAYOUTPOLICY_P_H + +#include "duilinearlayoutpolicy.h" +#include "duiabstractlayoutpolicy_p.h" + +class QGraphicsLinearLayout; +class QGraphicsWidget; +class DuiLayout; + +/** + This is the private implementation class for the grid layout policy. + The real work is done in the QGridLayoutEngine to which a pointer is + held here. +*/ +class DuiLinearLayoutPolicyPrivate : public DuiAbstractLayoutPolicyPrivate +{ + Q_DECLARE_PUBLIC(DuiLinearLayoutPolicy) + +public: + /** Constructor */ + DuiLinearLayoutPolicyPrivate(DuiLayout *l, Qt::Orientation o); + /** Destructor */ + virtual ~DuiLinearLayoutPolicyPrivate(); + + void fixIndex(int *index) const; + void refreshEngine(); + + QGraphicsWidget *const engineWidget; + QGraphicsLinearLayout *const engine; + /** We need to keep track of the number of rows/columns in the layout, since + * QGraphicsLinearLayout does not expose this information to us. This is + * basically q->count() + the number of stretches added/inserted. */ + int rowCount; +}; + +#endif // Header Guard diff --git a/src/layout/layout state machine.txt b/src/layout/layout state machine.txt new file mode 100644 index 000000000..f84daaa86 --- /dev/null +++ b/src/layout/layout state machine.txt @@ -0,0 +1,60 @@ +This file describes the work flow of items being added, removed, shown, hidden and moved around. + + DuiLayout::animatedDeleteAt() + If the item was already TO_BE_DELETED, do nothing more + Item is marked as TO_BE_DELETED + Call DuiLayout::updateItemState + + DuiAbstractLayoutPolicy::addItem() + Invalidate policy and layout - this will trigger a DuiLayout::setGeometry() in the next event loop + Call DuiLayout::addItem() to make sure item is added to layout. + Add item internally to policy + + DuiLayout::addItem() + If item already exists and is marked as TO_BE_DELETED, give an error and return + If there is no policy, item should be set to TO_BE_HIDDEN and moved immediately + Call DuiLayout::updateItemState() + + DuiLayout::setGeometry() + The current policy will call DuiItemState::setTargetGeometry for all the items + Call DuiLayout::updateItemState() + + DuiItemState::setTargetGeometry() + set the target geometry + If the item was TO_BE_DELETED, do nothing more + If the item was not SHOWING, it should be set to TO_BE_SHOWN + If the item was TO_BE_HIDDEN and not TO_BE_DELETED, it should be to set to SHOWING + + DuiLayout::updateItemState() + If there's no animator or item is not TO_BE_SHOWN and is not SHOWING + If the item was TO_BE_SHOWN, the item is moved into position. State changed to SHOWING + If the item was TO_BE_HIDDEN, move offscreen. Remove TO_BE_HIDDEN and SHOWING states + Call animationDone() + If there's an animator: + If the item was TO_BE_HIDDEN, call DuiLayoutAnimation::doItemHiddenAnimation(). Readd TO_BE_HIDDEN and remove TO_BE_SHOWN flags. + If the item was TO_BE_SHOWN, call DuiLayoutAnimation::doItemShownAnimation(). Clear TO_BE_SHOWN flag + Call startAnimation() + + DuiBasicLayoutAnimation::doItemHiddenAnimation() + setTargetGeometry to current geometry resized to the minimum size. + At the end of the animation, it should be moved offscreen + + DuiBasicLayoutAnimation::doItemShownAnimation() + Set current geometry to target geometry resized to the minimum size + Call setTargetGeometry with target geometry + + DuiBasicLayoutAnimation::animationTick + Change geometry of item + If the item was TO_BE_HIDDEN, readd TO_BE_HIDDEN and remove TO_BE_SHOWN flags. + At end, call animationDone() + + DuiItemState::animationDone() + If the item was TO_BE_HIDDEN, remove TO_BE_HIDDEN and SHOWING flags + + DuiLayout::animationFinished() + If the item was TO_BE_DELETED, call DuiLayout::removeItem() + + DuiLayout::removeItem() + Remove item immediately + If item was marked as TO_BE_DELETED, delete + diff --git a/src/layout/layout.pri b/src/layout/layout.pri new file mode 100644 index 000000000..67bbfc2ed --- /dev/null +++ b/src/layout/layout.pri @@ -0,0 +1,39 @@ +############################################################################### +# DuiLayout module +# This module contains layout related code. +############################################################################### + +LAYOUT_SRC_DIR=./layout +INCLUDEPATH+=./layout + +HEADERS += \ + $$LAYOUT_SRC_DIR/duilayoutanimation.h \ + $$LAYOUT_SRC_DIR/duiabstractlayoutpolicy.h \ + $$LAYOUT_SRC_DIR/duibasiclayoutanimation.h \ + $$LAYOUT_SRC_DIR/duiflowlayoutpolicy.h \ + $$LAYOUT_SRC_DIR/duifreestylelayoutpolicy.h \ + $$LAYOUT_SRC_DIR/duigridlayoutpolicy.h \ + $$LAYOUT_SRC_DIR/duiitemstate.h \ + $$LAYOUT_SRC_DIR/duilayout.h \ + $$LAYOUT_SRC_DIR/duilayout_p.h \ + $$LAYOUT_SRC_DIR/duilayouthelper_p.h \ + $$LAYOUT_SRC_DIR/duilinearlayoutpolicy.h \ + + +SOURCES += \ + $$LAYOUT_SRC_DIR/duilayoutanimation.cpp \ + $$LAYOUT_SRC_DIR/duiabstractlayoutpolicy.cpp \ + $$LAYOUT_SRC_DIR/duiabstractlayoutpolicy_p.cpp \ + $$LAYOUT_SRC_DIR/duibasiclayoutanimation.cpp \ + $$LAYOUT_SRC_DIR/duibasiclayoutanimation_p.cpp \ + $$LAYOUT_SRC_DIR/duiflowlayoutpolicy.cpp \ + $$LAYOUT_SRC_DIR/duiflowlayoutpolicy_p.cpp \ + $$LAYOUT_SRC_DIR/duifreestylelayoutpolicy.cpp \ + $$LAYOUT_SRC_DIR/duifreestylelayoutpolicy_p.cpp \ + $$LAYOUT_SRC_DIR/duigridlayoutpolicy.cpp \ + $$LAYOUT_SRC_DIR/duigridlayoutpolicy_p.cpp \ + $$LAYOUT_SRC_DIR/duiitemstate.cpp \ + $$LAYOUT_SRC_DIR/duilayout.cpp \ + $$LAYOUT_SRC_DIR/duilayout_p.cpp \ + $$LAYOUT_SRC_DIR/duilinearlayoutpolicy.cpp \ + $$LAYOUT_SRC_DIR/duilinearlayoutpolicy_p.cpp diff --git a/src/mashup/appletcommunication/appletcommunication.pri b/src/mashup/appletcommunication/appletcommunication.pri new file mode 100644 index 000000000..1b32cc47b --- /dev/null +++ b/src/mashup/appletcommunication/appletcommunication.pri @@ -0,0 +1,49 @@ +include(../mashup.pri) + +MASHUP_APPLETCOMMUNICATION_SRC_DIR = $$MASHUP_SRC_DIR/appletcommunication +INCLUDEPATH += $$MASHUP_SRC_DIR/appletcommunication + +HEADERS += $$MASHUP_APPLETCOMMUNICATION_SRC_DIR/duiappletalivemessagerequest.h \ + $$MASHUP_APPLETCOMMUNICATION_SRC_DIR/duiappletalivemessageresponse.h \ + $$MASHUP_APPLETCOMMUNICATION_SRC_DIR/duiappletcommunicator.h \ + $$MASHUP_APPLETCOMMUNICATION_SRC_DIR/duiappletserver.h \ + $$MASHUP_APPLETCOMMUNICATION_SRC_DIR/duiappletclient.h \ + $$MASHUP_APPLETCOMMUNICATION_SRC_DIR/duiappletmessagefactory.h \ + $$MASHUP_APPLETCOMMUNICATION_SRC_DIR/duiappletmessage.h \ + $$MASHUP_APPLETCOMMUNICATION_SRC_DIR/duiappletmousemessage.h \ + $$MASHUP_APPLETCOMMUNICATION_SRC_DIR/duiappletorientationmessage.h \ + $$MASHUP_APPLETCOMMUNICATION_SRC_DIR/duiappletobjectmenurequestmessage.h \ + $$MASHUP_APPLETCOMMUNICATION_SRC_DIR/duiappletobjectmenumessage.h \ + $$MASHUP_APPLETCOMMUNICATION_SRC_DIR/duiappletobjectmenuactionselectedmessage.h \ + $$MASHUP_APPLETCOMMUNICATION_SRC_DIR/duiappletsetgeometrymessage.h \ + $$MASHUP_APPLETCOMMUNICATION_SRC_DIR/duiappletpixmaptakenintousemessage.h \ + $$MASHUP_APPLETCOMMUNICATION_SRC_DIR/duiappletvisibilitymessage.h \ + $$MASHUP_APPLETCOMMUNICATION_SRC_DIR/duiappleticonchangedmessage.h \ + $$MASHUP_APPLETCOMMUNICATION_SRC_DIR/duiapplettitlechangedmessage.h \ + $$MASHUP_APPLETCOMMUNICATION_SRC_DIR/duiapplettextchangedmessage.h \ + $$MASHUP_APPLETCOMMUNICATION_SRC_DIR/duiappletupdategeometrymessage.h \ + $$MASHUP_APPLETCOMMUNICATION_SRC_DIR/duiappletpixmapmodifiedmessage.h \ + $$MASHUP_APPLETCOMMUNICATION_SRC_DIR/duiappletcancelmessage.h \ + +SOURCES += $$MASHUP_APPLETCOMMUNICATION_SRC_DIR/duiappletalivemessagerequest.cpp \ + $$MASHUP_APPLETCOMMUNICATION_SRC_DIR/duiappletalivemessageresponse.cpp \ + $$MASHUP_APPLETCOMMUNICATION_SRC_DIR/duiappletcommunicator.cpp \ + $$MASHUP_APPLETCOMMUNICATION_SRC_DIR/duiappletserver.cpp \ + $$MASHUP_APPLETCOMMUNICATION_SRC_DIR/duiappletclient.cpp \ + $$MASHUP_APPLETCOMMUNICATION_SRC_DIR/duiappletmessage.cpp \ + $$MASHUP_APPLETCOMMUNICATION_SRC_DIR/duiappletmessagefactory.cpp \ + $$MASHUP_APPLETCOMMUNICATION_SRC_DIR/duiappletmousemessage.cpp \ + $$MASHUP_APPLETCOMMUNICATION_SRC_DIR/duiappletorientationmessage.cpp \ + $$MASHUP_APPLETCOMMUNICATION_SRC_DIR/duiappletobjectmenurequestmessage.cpp \ + $$MASHUP_APPLETCOMMUNICATION_SRC_DIR/duiappletobjectmenumessage.cpp \ + $$MASHUP_APPLETCOMMUNICATION_SRC_DIR/duiappletobjectmenuactionselectedmessage.cpp \ + $$MASHUP_APPLETCOMMUNICATION_SRC_DIR/duiappletsetgeometrymessage.cpp \ + $$MASHUP_APPLETCOMMUNICATION_SRC_DIR/duiappletpixmaptakenintousemessage.cpp \ + $$MASHUP_APPLETCOMMUNICATION_SRC_DIR/duiappletvisibilitymessage.cpp \ + $$MASHUP_APPLETCOMMUNICATION_SRC_DIR/duiappleticonchangedmessage.cpp \ + $$MASHUP_APPLETCOMMUNICATION_SRC_DIR/duiapplettitlechangedmessage.cpp \ + $$MASHUP_APPLETCOMMUNICATION_SRC_DIR/duiapplettextchangedmessage.cpp \ + $$MASHUP_APPLETCOMMUNICATION_SRC_DIR/duiappletupdategeometrymessage.cpp \ + $$MASHUP_APPLETCOMMUNICATION_SRC_DIR/duiappletpixmapmodifiedmessage.cpp \ + $$MASHUP_APPLETCOMMUNICATION_SRC_DIR/duiappletcancelmessage.cpp \ + diff --git a/src/mashup/appletcommunication/duiappletalivemessagerequest.cpp b/src/mashup/appletcommunication/duiappletalivemessagerequest.cpp new file mode 100644 index 000000000..b5b221332 --- /dev/null +++ b/src/mashup/appletcommunication/duiappletalivemessagerequest.cpp @@ -0,0 +1,29 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiappletalivemessagerequest.h" + +DuiAppletAliveMessageRequest::DuiAppletAliveMessageRequest() : + DuiAppletMessage(APPLET_ALIVE_MESSAGE_REQUEST) +{ +} + +DuiAppletAliveMessageRequest::~DuiAppletAliveMessageRequest() +{ +} diff --git a/src/mashup/appletcommunication/duiappletalivemessagerequest.h b/src/mashup/appletcommunication/duiappletalivemessagerequest.h new file mode 100644 index 000000000..bced948c3 --- /dev/null +++ b/src/mashup/appletcommunication/duiappletalivemessagerequest.h @@ -0,0 +1,44 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETALIVEMESSAGEREQUEST_H +#define DUIAPPLETALIVEMESSAGEREQUEST_H + +#include "duiappletmessage.h" + +/*! + * Applet alive message. + */ +class DUI_EXPORT DuiAppletAliveMessageRequest : public DuiAppletMessage +{ +public: + /*! + * Constructor. + * + */ + DuiAppletAliveMessageRequest(); + + /*! + * Destructor. + */ + virtual ~DuiAppletAliveMessageRequest(); + +}; + +#endif // DUIAPPLETALIVEMESSAGEREQUEST_H diff --git a/src/mashup/appletcommunication/duiappletalivemessageresponse.cpp b/src/mashup/appletcommunication/duiappletalivemessageresponse.cpp new file mode 100644 index 000000000..3b955ea4b --- /dev/null +++ b/src/mashup/appletcommunication/duiappletalivemessageresponse.cpp @@ -0,0 +1,29 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiappletalivemessageresponse.h" + +DuiAppletAliveMessageResponse::DuiAppletAliveMessageResponse() : + DuiAppletMessage(APPLET_ALIVE_MESSAGE_RESPONSE) +{ +} + +DuiAppletAliveMessageResponse::~DuiAppletAliveMessageResponse() +{ +} diff --git a/src/mashup/appletcommunication/duiappletalivemessageresponse.h b/src/mashup/appletcommunication/duiappletalivemessageresponse.h new file mode 100644 index 000000000..3c9fbc0f7 --- /dev/null +++ b/src/mashup/appletcommunication/duiappletalivemessageresponse.h @@ -0,0 +1,44 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETALIVEMESSAGERESPONSE_H +#define DUIAPPLETALIVEMESSAGERESPONSE_H + +#include "duiappletmessage.h" + +/*! + * Applet alive message. + */ +class DUI_EXPORT DuiAppletAliveMessageResponse : public DuiAppletMessage +{ +public: + /*! + * Constructor. + * + */ + DuiAppletAliveMessageResponse(); + + /*! + * Destructor. + */ + virtual ~DuiAppletAliveMessageResponse(); + +}; + +#endif // DUIAPPLETALIVEMESSAGERESPONSE_H diff --git a/src/mashup/appletcommunication/duiappletcancelmessage.cpp b/src/mashup/appletcommunication/duiappletcancelmessage.cpp new file mode 100644 index 000000000..0b8b000e4 --- /dev/null +++ b/src/mashup/appletcommunication/duiappletcancelmessage.cpp @@ -0,0 +1,30 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiappletcancelmessage.h" +#include "duiappletmessagefactory.h" + +DuiAppletCancelMessage::DuiAppletCancelMessage() : + DuiAppletMessage(CANCEL_MESSAGE) +{ +} + +DuiAppletCancelMessage::~DuiAppletCancelMessage() +{ +} diff --git a/src/mashup/appletcommunication/duiappletcancelmessage.h b/src/mashup/appletcommunication/duiappletcancelmessage.h new file mode 100644 index 000000000..b4029111f --- /dev/null +++ b/src/mashup/appletcommunication/duiappletcancelmessage.h @@ -0,0 +1,45 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETCANCELMESSAGE_H +#define DUIAPPLETCANCELMESSAGE_H + +#include "duiappletmessage.h" + +/*! + * Cancel message sent to the applet when the previously + * sent mouse press message needs to be cancelled. + */ +class DUI_EXPORT DuiAppletCancelMessage : public DuiAppletMessage +{ + +public: + /*! + * Cancel message constructor. The message does not contain + * any attributes, so no parameter is required. + */ + explicit DuiAppletCancelMessage(); + + /*! + * Destructor. + */ + virtual ~DuiAppletCancelMessage(); +}; + +#endif // DUIAPPLETCANCELMESSAGE_H diff --git a/src/mashup/appletcommunication/duiappletclient.cpp b/src/mashup/appletcommunication/duiappletclient.cpp new file mode 100644 index 000000000..c0d83ba36 --- /dev/null +++ b/src/mashup/appletcommunication/duiappletclient.cpp @@ -0,0 +1,95 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiappletclient.h" +#include + + +static const int MAX_CONNECTION_ATTEMPTS = 100; + +DuiAppletClient::DuiAppletClient() +{ +} + +DuiAppletClient::~DuiAppletClient() +{ + closeConnection(); +} + +bool DuiAppletClient::connectToServer(const QString &serverName) +{ + closeConnection(); + + // Connect to the specified server + socket = new QLocalSocket; + connect(socket, SIGNAL(connected()), this, SLOT(connected())); + connect(socket, SIGNAL(error(QLocalSocket::LocalSocketError)), this, SLOT(socketError(QLocalSocket::LocalSocketError))); + + socket->connectToServer(serverName); + + int attempt = 1; + while (socket->state() != QLocalSocket::ConnectedState) { + if (attempt >= MAX_CONNECTION_ATTEMPTS) break; +#ifndef Q_OS_WIN + usleep(100000); +#else +#include + Sleep(100); +#endif + ++attempt; + socket->connectToServer(serverName); + } + + if (attempt < MAX_CONNECTION_ATTEMPTS) { + duiDebug("DuiAppletClient") << "Connection took" << attempt << "attempts"; + return true; + } else { + duiDebug("DuiAppletClient") << "Couldn't establish connection to server"; + return false; + } +} + +void DuiAppletClient::closeConnection() +{ + if (socket) { + socket->disconnectFromServer(); + delete socket; + socket = NULL; + delete stream; + stream = NULL; + } +} + +void DuiAppletClient::connected() +{ + // Don't accept any additional connections + disconnect(socket, SIGNAL(connected()), this, SLOT(connected())); + + // Create a stream for the socket data + stream = new QDataStream(socket); + + connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead())); + + emit connectionEstablished(); +} + +void DuiAppletClient::socketError(QLocalSocket::LocalSocketError error) +{ + duiDebug("DuiAppletClient") << Q_FUNC_INFO << error << socket->errorString(); +} diff --git a/src/mashup/appletcommunication/duiappletclient.h b/src/mashup/appletcommunication/duiappletclient.h new file mode 100644 index 000000000..503afa3f0 --- /dev/null +++ b/src/mashup/appletcommunication/duiappletclient.h @@ -0,0 +1,72 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETCLIENT_H_ +#define DUIAPPLETCLIENT_H_ + +#include "duiexport.h" +#include "duiappletcommunicator.h" + + +/*! + * The DuiAppletClient implements a client for interprocess communication + * between two processes (a host application and an applet). + */ +class DUI_EXPORT DuiAppletClient : public DuiAppletCommunicator +{ + Q_OBJECT + +public: + /*! + * Constructs a DuiAppletClient. + */ + DuiAppletClient(); + + /*! + * Destroys the DuiAppletClient. + */ + virtual ~DuiAppletClient(); + + /*! + * Connects to the server. + * + * \param serverName the name of the server + * \return true if connection setup was successful, false otherwise + */ + bool connectToServer(const QString &serverName); + + /*! + * Closes the connection. + */ + virtual void closeConnection(); + +private slots: + /*! + * \brief A slot that gets called when a communication client manages to establish a connection. + */ + void connected(); + + /*! + * \brief A slot that gets called if the client side socket encounters an error. + * \param error the error type. + */ + void socketError(QLocalSocket::LocalSocketError error); +}; + +#endif /* DUIAPPLETCLIENT_H_ */ diff --git a/src/mashup/appletcommunication/duiappletcommunicator.cpp b/src/mashup/appletcommunication/duiappletcommunicator.cpp new file mode 100644 index 000000000..d751483a9 --- /dev/null +++ b/src/mashup/appletcommunication/duiappletcommunicator.cpp @@ -0,0 +1,210 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "duiappletcommunicator.h" +#include "duiappletmessage.h" +#include "duiappletmessagefactory.h" + +DuiAppletCommunicator::DuiAppletCommunicator() : + socket(NULL), + stream(NULL), + readState(NEEDS_TYPE), + receivedMessageType(DuiAppletMessage::INVALID), + pendingMessagePayloadSize(-1), + messagePayloadReceivingStream(&receivingBuffer) +{ + messagePayloadReceivingStream.device()->open(QIODevice::ReadWrite); +} + +DuiAppletCommunicator::~DuiAppletCommunicator() +{ +} + +bool DuiAppletCommunicator::sendMessage(const DuiAppletMessage &message) +{ + if (!isConnected()) { + return false; + } + + // Serialize the message to a temporary stream so that the size of the payload can be calculated + QByteArray tmpArray; + QDataStream tmpStream(&tmpArray, QIODevice::WriteOnly); + message.serialize(tmpStream); + + // Write the message type to the stream + *stream << (uint)message.type(); + + // Write the message payload size to the stream + *stream << tmpArray.size(); + + // Write the message payload to the stream + stream->writeRawData(tmpArray.data(), tmpArray.size()); + + // Flush the socket and calculate return value + bool result = (stream->status() == QDataStream::Ok) && socket->flush(); + if (!result) { + emit connectionLost(); + } + return result; +} + +bool DuiAppletCommunicator::isConnected() const +{ + // Check that the socket exists (the communicator is connected) + if (socket == NULL || socket->state() != QLocalSocket::ConnectedState) { + return false; + } + return true; +} + +void DuiAppletCommunicator::socketError(QLocalSocket::LocalSocketError error) +{ + duiDebug("DuiAppletCommunicator") << Q_FUNC_INFO << error + << socket->errorString(); + readState = NEEDS_TYPE; + emit connectionLost(); +} + +void DuiAppletCommunicator::readyRead() +{ + bool canProceed = true; + while (canProceed) { + if (readState == NEEDS_TYPE) { + canProceed = readMessageType(); + } + + if (readState == NEEDS_SIZE) { + canProceed = readMessageSize(); + } + + if (readState == NEEDS_DATA) { + canProceed = readMessageData(); + } + + if (readState == MESSAGE_RECEIVED) { + // Create a message from the type + QScopedPointer message(DuiAppletMessageFactory::create(receivedMessageType)); + + // Make sure the message exists (it won't if type is unknown) + if (!message.isNull()) { + // If the message had payload, unserialize it + if (messagePayloadReceivingStream.device()->size() > 0) { + messagePayloadReceivingStream.device()->seek(0); + message->unserialize(messagePayloadReceivingStream); + + // Clear the previous data buffer + messagePayloadReceivingStream.device()->seek(0); + receivingBuffer.buffer().clear(); + } + + emit messageReceived(*message); + } + + readState = NEEDS_TYPE; + } + } +} + +bool DuiAppletCommunicator::readMessageType() +{ + if (checkSocketError()) { + return false; + } + if (socket->bytesAvailable() >= (int)sizeof(uint)) { + uint tmp; + *stream >> tmp; + if (checkSocketError()) { + return false; + } + receivedMessageType = static_cast(tmp); + readState = NEEDS_SIZE; + return true; + } + return false; +} + +bool DuiAppletCommunicator::readMessageSize() +{ + pendingMessagePayloadSize = -1; + if (checkSocketError()) { + return false; + } + if (socket->bytesAvailable() >= (int)sizeof(int)) { + *stream >> pendingMessagePayloadSize; + if (checkSocketError()) { + return false; + } + if (pendingMessagePayloadSize > 0) { + readState = NEEDS_DATA; + + static_cast(messagePayloadReceivingStream.device())->buffer().reserve(pendingMessagePayloadSize); + } else { + readState = MESSAGE_RECEIVED; + } + return true; + } + return false; +} + +bool DuiAppletCommunicator::readMessageData() +{ + if (pendingMessagePayloadSize <= 0 && socket->bytesAvailable() <= 0) { + return false; + } + QByteArray byteArray; + byteArray.reserve(pendingMessagePayloadSize); + while (pendingMessagePayloadSize > 0 + && socket->bytesAvailable() > 0) { + int bytesRead = stream->readRawData(byteArray.data(), pendingMessagePayloadSize); + if (checkSocketError(bytesRead)) { + return false; + } + messagePayloadReceivingStream.writeRawData(byteArray.data(), bytesRead); + pendingMessagePayloadSize -= bytesRead; + } + if (checkSocketError()) { + return false; + } + if (pendingMessagePayloadSize == 0) { + readState = MESSAGE_RECEIVED; + return true; + } + return false; +} + +bool DuiAppletCommunicator::checkSocketError(qint64 bytesRead) +{ + if ((bytesRead < 0) + || (socket->bytesAvailable() < 0) + || (stream->status() != QDataStream::Ok)) { + readState = NEEDS_TYPE; + emit connectionLost(); + return true; + } + return false; +} diff --git a/src/mashup/appletcommunication/duiappletcommunicator.h b/src/mashup/appletcommunication/duiappletcommunicator.h new file mode 100644 index 000000000..d6917a639 --- /dev/null +++ b/src/mashup/appletcommunication/duiappletcommunicator.h @@ -0,0 +1,169 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETCOMMUNICATOR_H_ +#define DUIAPPLETCOMMUNICATOR_H_ + +#include "duiexport.h" +#include "duiappletmessage.h" + +#include +#include +class QDataStream; + +/*! + * The DuiAppletCommunicator is a base class for implementing interprocess + * communication between two processes (a host application and an applet). + */ +class DUI_EXPORT DuiAppletCommunicator : public QObject +{ + Q_OBJECT + +public: + /*! + * Constructs an DuiAppletCommunicator. + */ + DuiAppletCommunicator(); + + /*! + * Destroys the DuiAppletCommunicator. + */ + virtual ~DuiAppletCommunicator(); + + /*! + * Closes the connection. + */ + virtual void closeConnection() = 0; + + /*! + * Sends a DuiAppletMessage. + * + * \param message the DuiAppletMessage to send + * \return the result of the operation: \c true if sending was successful and \c false otherwise. + */ + bool sendMessage(const DuiAppletMessage &message); + + /*! + * Queries if this communicator is currently connected. + * \return \c true if connected, \c false if not. + */ + bool isConnected() const; + +protected: + //! The socket for IPC communication, created by subclasses + QLocalSocket *socket; + + //! Stream for reading and writing from the socket, created by subclasses + QDataStream *stream; + +private slots: + /*! + * \brief A slot that gets called if the client side socket encounters an error. + * \param error the error type. + */ + void socketError(QLocalSocket::LocalSocketError error); + + /*! + * \brief A slot that is called when there is new data available in the connection socket. + */ + void readyRead(); + +signals: + /*! + * \brief A signal that is emitted when this communicator has successfully established a connection. + */ + void connectionEstablished(); + + /*! + * A signal that is emitted when there's an error in communication. + * That usually means the reading of messages fails because the + * other end has crashed or otherwise closed the communication channel. + */ + void connectionLost(); + + /*! + * \brief A signal that is emitted when this communicator has received a new message. + * \param message the message that was received + */ + void messageReceived(const DuiAppletMessage &message); + +private: + /*! + * States for reading the data from the socket. + */ + enum ReadState { + NEEDS_TYPE, //!< The message type is expected to come next + NEEDS_SIZE, //!< The message size is expected to come next + NEEDS_DATA, //!< The message data is expected to come next or hasn't yet arrived completely + MESSAGE_RECEIVED //!< The message data has been received completely. Next the message should be constructed from the data and emitted + }; + + //! The reading state + ReadState readState; + + //! The type of the received message + DuiAppletMessage::DuiAppletMessageType receivedMessageType; + + //! The size of the payload that is still expected to be received for a message + int pendingMessagePayloadSize; + + //! The buffer used for the stream that receives the incoming message + // data + QBuffer receivingBuffer; + + //! A data stream for collecting the incoming message data + QDataStream messagePayloadReceivingStream; + + /*! + * Tries to read the message type from the socket. This method should be + * called when the state is \c NEEDS_TYPE. If there is enough data available + * in the socket and the type can be read, the state is set to \c NEEDS_SIZE + * and \c true is returned. + * \return \c true if the type could be read, \c false if not. + */ + bool readMessageType(); + + /*! + * Tries to read the message payload size from the socket. This method should be + * called when the state is \c NEEDS_SIZE. If there is enough data available + * in the socket and the payload size can be read, the state is set to \c NEEDS_DATA + * and \c true is returned. + * \return \c true if the payload size could be read, \c false if not. + */ + bool readMessageSize(); + + /*! + * Reads any data that is available in the socket, but at most \c pendingMessagePayloadSize + * bytes. This method should be called when the state is \c NEEDS_DATA. If \c pendingMessagePayloadSize + * bytes could be read this method sets the state to \c MESSAGE_RECEIVED and returns \c true. + * Otherwise this method returns \c false. + * \return \c true if no more message data is pendind, \c false otherwise. + */ + bool readMessageData(); + + /*! + * Checks for a socket error. Resets the state of the communicator + * if an error has occurred. + * \param bytesRead Optional count of read bytes. + * \return \c true if the socket or the stream are in an error state. + */ + bool checkSocketError(qint64 bytesRead = 0); +}; + +#endif /* DUIAPPLETCOMMUNICATOR_H_ */ diff --git a/src/mashup/appletcommunication/duiappleticonchangedmessage.cpp b/src/mashup/appletcommunication/duiappleticonchangedmessage.cpp new file mode 100644 index 000000000..0ad5f2441 --- /dev/null +++ b/src/mashup/appletcommunication/duiappleticonchangedmessage.cpp @@ -0,0 +1,49 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiappleticonchangedmessage.h" + +DuiAppletIconChangedMessage::DuiAppletIconChangedMessage() : + DuiAppletMessage(APPLET_ICON_MESSAGE) +{ +} + +DuiAppletIconChangedMessage::~DuiAppletIconChangedMessage() +{ +} + +void DuiAppletIconChangedMessage::serialize(QDataStream &stream) const +{ + stream << _icon; +} + +void DuiAppletIconChangedMessage::unserialize(QDataStream &stream) +{ + stream >> _icon; +} + +QString DuiAppletIconChangedMessage::icon() const +{ + return _icon; +} + +void DuiAppletIconChangedMessage::setIcon(const QString &newIcon) +{ + _icon = newIcon; +} diff --git a/src/mashup/appletcommunication/duiappleticonchangedmessage.h b/src/mashup/appletcommunication/duiappleticonchangedmessage.h new file mode 100644 index 000000000..48e3a1339 --- /dev/null +++ b/src/mashup/appletcommunication/duiappleticonchangedmessage.h @@ -0,0 +1,58 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETICONCHANGEDMESSAGE_H +#define DUIAPPLETICONCHANGEDMESSAGE_H + +#include +#include "duiappletmessage.h" + +/*! + * Applet icon changed message. + */ +class DUI_EXPORT DuiAppletIconChangedMessage : public DuiAppletMessage +{ +private: + QString _icon; + +public: + /*! + * Constructor. + * + */ + DuiAppletIconChangedMessage(); + + /*! + * Destructor. + */ + virtual ~DuiAppletIconChangedMessage(); + + //! \reimp + virtual void serialize(QDataStream &stream) const; + //! \reimp_end + + //! \reimp + virtual void unserialize(QDataStream &stream); + //! \reimp_end + + QString icon() const; + void setIcon(const QString &newIcon); +}; + +#endif // DUIAPPLETICONCHANGEDESSAGE_H diff --git a/src/mashup/appletcommunication/duiappletmessage.cpp b/src/mashup/appletcommunication/duiappletmessage.cpp new file mode 100644 index 000000000..f5994d74a --- /dev/null +++ b/src/mashup/appletcommunication/duiappletmessage.cpp @@ -0,0 +1,44 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiappletmessage.h" + +DuiAppletMessage::DuiAppletMessage(DuiAppletMessageType type) : + messageType(type) +{ +} + +DuiAppletMessage::~DuiAppletMessage() +{ +} + +DuiAppletMessage::DuiAppletMessageType DuiAppletMessage::type() const +{ + return messageType; +} + +void DuiAppletMessage::serialize(QDataStream &stream) const +{ + Q_UNUSED(stream); +} + +void DuiAppletMessage::unserialize(QDataStream &stream) +{ + Q_UNUSED(stream); +} diff --git a/src/mashup/appletcommunication/duiappletmessage.h b/src/mashup/appletcommunication/duiappletmessage.h new file mode 100644 index 000000000..d74699d48 --- /dev/null +++ b/src/mashup/appletcommunication/duiappletmessage.h @@ -0,0 +1,113 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETMESSAGE_H_ +#define DUIAPPLETMESSAGE_H_ + +#include "duiexport.h" + +#include + +/*! + * An abstract base class for messages that are used for communicating between + * applets and the host process. Messages can be serialized to a byte stream + * so they can be communicated to another processes. + */ +class DUI_EXPORT DuiAppletMessage +{ +public: + /*! + * A type for the message. + */ + enum DuiAppletMessageType { + INVALID = 0, + VISIBILITY_MESSAGE, + ORIENTATION_MESSAGE, + + MOUSE_PRESS_MESSAGE, + MOUSE_RELEASE_MESSAGE, + MOUSE_MOVE_MESSAGE, + CANCEL_MESSAGE, + + SET_GEOMETRY_MESSAGE, + + PIXMAP_TAKEN_INTO_USE_MESSAGE, + + APPLET_ALIVE_MESSAGE_REQUEST, + APPLET_ALIVE_MESSAGE_RESPONSE, + + APPLET_ICON_MESSAGE, + APPLET_TITLE_MESSAGE, + APPLET_TEXT_MESSAGE, + + UPDATE_GEOMETRY_MESSAGE, + + PIXMAP_MODIFIED_MESSAGE, + + OBJECT_MENU_REQUEST_MESSAGE, + OBJECT_MENU_MESSAGE, + OBJECT_MENU_ACTION_SELECTED_MESSAGE, + + NUM_TYPES + }; + +private: + /// The type of this message + DuiAppletMessageType messageType; + +protected: + /*! + * Constructor. + * + * Sets the type of the message. + * \param type the message type. + */ + DuiAppletMessage(DuiAppletMessageType type); + +public: + /*! + * Destructor. + */ + virtual ~DuiAppletMessage(); + + /*! + * Returns the type of the applet message. + * \return applet message type. + */ + DuiAppletMessageType type() const; + + /*! + * Serializes the contents of the message to a data stream. + * + * It doesn't matter what format the message uses for the serialization. + * It is only required that the \c unserialize() method knows how to read the data. + * \param stream the stream to serialize the message to. + */ + virtual void serialize(QDataStream &stream) const; + + /*! + * Unserializes the contents of the message from a data stream. + * + * \param stream the stream to serialize the message from. + */ + virtual void unserialize(QDataStream &stream); +}; + + +#endif /* DUIAPPLETMESSAGE_H_ */ diff --git a/src/mashup/appletcommunication/duiappletmessagefactory.cpp b/src/mashup/appletcommunication/duiappletmessagefactory.cpp new file mode 100644 index 000000000..dcb02e7c8 --- /dev/null +++ b/src/mashup/appletcommunication/duiappletmessagefactory.cpp @@ -0,0 +1,105 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include "duiappletmessagefactory.h" + +#include "duiappletvisibilitymessage.h" +#include "duiappletorientationmessage.h" +#include "duiappletmousemessage.h" +#include "duiappletsetgeometrymessage.h" +#include "duiappletpixmaptakenintousemessage.h" +#include "duiappletalivemessagerequest.h" +#include "duiappletalivemessageresponse.h" +#include "duiappleticonchangedmessage.h" +#include "duiapplettitlechangedmessage.h" +#include "duiapplettextchangedmessage.h" +#include "duiappletupdategeometrymessage.h" +#include "duiappletpixmapmodifiedmessage.h" +#include "duiappletcancelmessage.h" +#include "duiappletobjectmenurequestmessage.h" +#include "duiappletobjectmenumessage.h" +#include "duiappletobjectmenuactionselectedmessage.h" + +DuiAppletMessageFactory::DuiAppletMessageFactory() +{ +} + +DuiAppletMessage *DuiAppletMessageFactory::create(DuiAppletMessage::DuiAppletMessageType messageType) +{ + switch (messageType) { + case DuiAppletMessage::VISIBILITY_MESSAGE: + return new DuiAppletVisibilityMessage(); + + case DuiAppletMessage::ORIENTATION_MESSAGE: + return new DuiAppletOrientationMessage(); + + case DuiAppletMessage::MOUSE_PRESS_MESSAGE: + return new DuiAppletMouseMessage(DuiAppletMessage::MOUSE_PRESS_MESSAGE); + + case DuiAppletMessage::MOUSE_RELEASE_MESSAGE: + return new DuiAppletMouseMessage(DuiAppletMessage::MOUSE_RELEASE_MESSAGE); + + case DuiAppletMessage::MOUSE_MOVE_MESSAGE: + return new DuiAppletMouseMessage(DuiAppletMessage::MOUSE_MOVE_MESSAGE); + + case DuiAppletMessage::CANCEL_MESSAGE: + return new DuiAppletCancelMessage(); + + case DuiAppletMessage::SET_GEOMETRY_MESSAGE: + return new DuiAppletSetGeometryMessage(); + + case DuiAppletMessage::PIXMAP_TAKEN_INTO_USE_MESSAGE: + return new DuiAppletPixmapTakenIntoUseMessage(); + + case DuiAppletMessage::APPLET_ALIVE_MESSAGE_REQUEST: + return new DuiAppletAliveMessageRequest(); + + case DuiAppletMessage::APPLET_ALIVE_MESSAGE_RESPONSE: + return new DuiAppletAliveMessageResponse(); + + case DuiAppletMessage::APPLET_ICON_MESSAGE: + return new DuiAppletIconChangedMessage(); + + case DuiAppletMessage::APPLET_TITLE_MESSAGE: + return new DuiAppletTitleChangedMessage(); + + case DuiAppletMessage::APPLET_TEXT_MESSAGE: + return new DuiAppletTextChangedMessage(); + + case DuiAppletMessage::UPDATE_GEOMETRY_MESSAGE: + return new DuiAppletUpdateGeometryMessage(); + + case DuiAppletMessage::PIXMAP_MODIFIED_MESSAGE: + return new DuiAppletPixmapModifiedMessage(); + + case DuiAppletMessage::OBJECT_MENU_REQUEST_MESSAGE: + return new DuiAppletObjectMenuRequestMessage(); + + case DuiAppletMessage::OBJECT_MENU_MESSAGE: + return new DuiAppletObjectMenuMessage(); + + case DuiAppletMessage::OBJECT_MENU_ACTION_SELECTED_MESSAGE: + return new DuiAppletObjectMenuActionSelectedMessage(); + + default: + duiWarning("DuiAppletMessageFactory") << __func__ << "type" << messageType << "not registered"; + return NULL; + } +} diff --git a/src/mashup/appletcommunication/duiappletmessagefactory.h b/src/mashup/appletcommunication/duiappletmessagefactory.h new file mode 100644 index 000000000..410eeeb15 --- /dev/null +++ b/src/mashup/appletcommunication/duiappletmessagefactory.h @@ -0,0 +1,60 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETMESSAGEFACTORY_H_ +#define DUIAPPLETMESSAGEFACTORY_H_ + +#include "duiexport.h" + +#include + +/*! + * Factory class for creating applet messages. + * + * The factory class offers a service to create applet messages of the correct type. + * The applet message type is passed as a parameter to the \c create() function and + * the function constructs and returns a correct message object. If an invalid message + * type is requested, the factory returns \c NULL. + * + * \note The \c creator() function is \c static so you don't need an instance of the + * factory. Actually you can't even create instances of it since the constructor is + * hidden. + */ +class DUI_EXPORT DuiAppletMessageFactory +{ +private: + /// Hidden constructor to prevent instantiating. + DuiAppletMessageFactory(); + +public: + /*! + * Creates an applet message object of the requested type. + * + * The function constructs and returns a correct message object. If an invalid message + * type is requested, the factory returns \c NULL. + * + * \note The ownership of the returned object is transformed to the caller so the calling + * code is responsible of deleting the object. + * \param messageType the type of the requested message. + * \return An applet message or \c NULL on invalid request. + */ + static DuiAppletMessage *create(DuiAppletMessage::DuiAppletMessageType messageType); +}; + +#endif /* DUIAPPLETMESSAGEFACTORY_H_ */ diff --git a/src/mashup/appletcommunication/duiappletmousemessage.cpp b/src/mashup/appletcommunication/duiappletmousemessage.cpp new file mode 100644 index 000000000..2272fef60 --- /dev/null +++ b/src/mashup/appletcommunication/duiappletmousemessage.cpp @@ -0,0 +1,79 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiappletmousemessage.h" + +DuiAppletMouseMessage::DuiAppletMouseMessage(DuiAppletMessageType type, const QPointF &pos, Qt::MouseButton button, Qt::MouseButtons buttons) : + DuiAppletMessage(type), + _position(pos), + _button(button), + _buttons(buttons) +{ +} + +DuiAppletMouseMessage::~DuiAppletMouseMessage() +{ +} + +void DuiAppletMouseMessage::serialize(QDataStream &stream) const +{ + stream << _position; + stream << _button; + stream << _buttons; +} + +void DuiAppletMouseMessage::unserialize(QDataStream &stream) +{ + quint32 tmp; + stream >> _position; + stream >> tmp; + _button = (Qt::MouseButton)tmp; + stream >> tmp; + _buttons = (Qt::MouseButtons)tmp; +} + +QPointF DuiAppletMouseMessage::position() const +{ + return _position; +} + +void DuiAppletMouseMessage::setPosition(const QPointF &pos) +{ + _position = pos; +} + +Qt::MouseButton DuiAppletMouseMessage::button() const +{ + return _button; +} + +void DuiAppletMouseMessage::setButton(const Qt::MouseButton &button) +{ + _button = button; +} + +Qt::MouseButtons DuiAppletMouseMessage::buttons() const +{ + return _buttons; +} + +void DuiAppletMouseMessage::setButtons(const Qt::MouseButtons &buttons) +{ + _buttons = buttons; +} diff --git a/src/mashup/appletcommunication/duiappletmousemessage.h b/src/mashup/appletcommunication/duiappletmousemessage.h new file mode 100644 index 000000000..366ec3366 --- /dev/null +++ b/src/mashup/appletcommunication/duiappletmousemessage.h @@ -0,0 +1,106 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETMOUSEMESSAGE_H +#define DUIAPPLETMOUSEMESSAGE_H + +#include "duiappletmessage.h" + +#include + +/*! + * A base class for mouse event related applet messages. + * + * A mouse event contains the position of the mouse pointer when the event occurred. + */ +class DUI_EXPORT DuiAppletMouseMessage : public DuiAppletMessage +{ +private: + /// Location of the mouse pointer in the event. + QPointF _position; + + /// Mouse button that triggered the event. + Qt::MouseButton _button; + + /// State of mouse buttons when this event was triggered. + Qt::MouseButtons _buttons; + +public: + /*! + * Constructor for the inheriting classes. + * \param type the type of the applet message. + * \param pos the position of the mouse pointer in the event. + * \param button mouse button that triggered this event. + * \param buttons state of mouse buttons when triggering this event. + */ + DuiAppletMouseMessage(DuiAppletMessageType type, const QPointF &pos = QPointF(), Qt::MouseButton button = Qt::NoButton, Qt::MouseButtons buttons = Qt::NoButton); + + /*! + * Destructor. + */ + virtual ~DuiAppletMouseMessage(); + + //! \reimp + virtual void serialize(QDataStream &stream) const; + //! \reimp_end + + //! \reimp + virtual void unserialize(QDataStream &stream); + //! \reimp_end + + /*! + * Returns the mouse pointer position of the event. + * \return the mouse pointer position. + */ + QPointF position() const; + + /*! + * Sets the mouse pointer position of the event. + * \param pos the new position. + */ + void setPosition(const QPointF &pos); + + /*! + * Returns the enumerator of the mouse button of the event. + * \return the mouse button enumerator. + */ + Qt::MouseButton button() const; + + /*! + * Sets the mouse button enumerator that triggered this + * event. + * \param button triggering mouse button. + */ + void setButton(const Qt::MouseButton &button); + + /*! + * Returns the state of mouse buttons when this event + * was triggered. + * \return state of mouse buttons. + */ + Qt::MouseButtons buttons() const; + + /*! + * Sets the state of mouse buttons when this event was triggered. + * \param buttons state of mouse buttons. + */ + void setButtons(const Qt::MouseButtons &buttons); +}; + +#endif // DUIAPPLETMOUSEMESSAGE_H diff --git a/src/mashup/appletcommunication/duiappletobjectmenuactionselectedmessage.cpp b/src/mashup/appletcommunication/duiappletobjectmenuactionselectedmessage.cpp new file mode 100644 index 000000000..0a81fb0c8 --- /dev/null +++ b/src/mashup/appletcommunication/duiappletobjectmenuactionselectedmessage.cpp @@ -0,0 +1,46 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiappletobjectmenuactionselectedmessage.h" +#include "duiappletmessagefactory.h" + +DuiAppletObjectMenuActionSelectedMessage::DuiAppletObjectMenuActionSelectedMessage(uint index) : + DuiAppletMessage(OBJECT_MENU_ACTION_SELECTED_MESSAGE), + actionIndex(index) +{ +} + +DuiAppletObjectMenuActionSelectedMessage::~DuiAppletObjectMenuActionSelectedMessage() +{ +} + +void DuiAppletObjectMenuActionSelectedMessage::serialize(QDataStream &stream) const +{ + stream << actionIndex; +} + +void DuiAppletObjectMenuActionSelectedMessage::unserialize(QDataStream &stream) +{ + stream >> actionIndex; +} + +uint DuiAppletObjectMenuActionSelectedMessage::index() const +{ + return actionIndex; +} diff --git a/src/mashup/appletcommunication/duiappletobjectmenuactionselectedmessage.h b/src/mashup/appletcommunication/duiappletobjectmenuactionselectedmessage.h new file mode 100644 index 000000000..e6441c657 --- /dev/null +++ b/src/mashup/appletcommunication/duiappletobjectmenuactionselectedmessage.h @@ -0,0 +1,65 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETOBJECTMENUACTIONSELECTEDMESSAGE_H +#define DUIAPPLETOBJECTMENUACTIONSELECTEDMESSAGE_H + +#include "duiappletmessage.h" +#include + +/*! + * Send Response to applet with index of action selected from context menu actions displayed in host process + */ +class DUI_EXPORT DuiAppletObjectMenuActionSelectedMessage : public DuiAppletMessage +{ + +private: + /// index of action selected. + uint actionIndex; + +public: + /*! + * Constructor. + * + * The index can be set as a parameter. + * \param index the index of action selected. + */ + DuiAppletObjectMenuActionSelectedMessage(uint index = 0); + + /*! + * Destroys the DuiAppletObjectMenuActionSelectedMessage. + */ + + virtual ~DuiAppletObjectMenuActionSelectedMessage(); + //! \reimp + virtual void serialize(QDataStream &stream) const; + //! \reimp_end + + //! \reimp + virtual void unserialize(QDataStream &stream); + //! \reimp_end + + /*! + * Returns the index of action selected. + * \return the selected index. + */ + uint index() const; +}; + +#endif // DUIAPPLETOBJECTMENUACTIONSELECTEDMESSAGE_H diff --git a/src/mashup/appletcommunication/duiappletobjectmenumessage.cpp b/src/mashup/appletcommunication/duiappletobjectmenumessage.cpp new file mode 100644 index 000000000..11b9f61e9 --- /dev/null +++ b/src/mashup/appletcommunication/duiappletobjectmenumessage.cpp @@ -0,0 +1,49 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiappletobjectmenumessage.h" +#include + +DuiAppletObjectMenuMessage::DuiAppletObjectMenuMessage(const QList actions) : + DuiAppletMessage(OBJECT_MENU_MESSAGE) +{ + foreach(QAction * action, actions) { + actionNamesList.append(action->text()); + } +} + +DuiAppletObjectMenuMessage::~DuiAppletObjectMenuMessage() +{ +} + +void DuiAppletObjectMenuMessage::serialize(QDataStream &stream) const +{ + stream << actionNamesList; +} + +void DuiAppletObjectMenuMessage::unserialize(QDataStream &stream) +{ + actionNamesList.clear(); + stream >> actionNamesList; +} + +QList DuiAppletObjectMenuMessage::actionList() const +{ + return actionNamesList ; +} diff --git a/src/mashup/appletcommunication/duiappletobjectmenumessage.h b/src/mashup/appletcommunication/duiappletobjectmenumessage.h new file mode 100644 index 000000000..a8063a11e --- /dev/null +++ b/src/mashup/appletcommunication/duiappletobjectmenumessage.h @@ -0,0 +1,63 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETOBJECTMENUMESSAGE_H +#define DUIAPPLETOBJECTMENUMESSAGE_H + +#include "duiappletmessage.h" +#include + +class QAction; + +/*! + * Object menu message which provides list of actions from applet. + */ +class DUI_EXPORT DuiAppletObjectMenuMessage : public DuiAppletMessage +{ +private: + /// The list of action names. + QList actionNamesList; + +public: + /*! + * Constructor. + * + * List of QAction is given which are translated to list of QString and passed along. + * \param actions List of actions on widget. + */ + DuiAppletObjectMenuMessage(const QList actions = QList()); + + /*! + * Destructor. + */ + virtual ~DuiAppletObjectMenuMessage(); + + //! \reimp + virtual void serialize(QDataStream &stream) const; + //! \reimp_end + + //! \reimp + virtual void unserialize(QDataStream &stream); + //! \reimp_end + + //! Gives the list of names of the actions. + QList actionList() const; +}; + +#endif // DUIAPPLETORIENTATIONMESSAGE_H diff --git a/src/mashup/appletcommunication/duiappletobjectmenurequestmessage.cpp b/src/mashup/appletcommunication/duiappletobjectmenurequestmessage.cpp new file mode 100644 index 000000000..21910f57b --- /dev/null +++ b/src/mashup/appletcommunication/duiappletobjectmenurequestmessage.cpp @@ -0,0 +1,48 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include "duiappletobjectmenurequestmessage.h" +#include "duiappletmessagefactory.h" + +DuiAppletObjectMenuRequestMessage::DuiAppletObjectMenuRequestMessage(QPointF pos) : + DuiAppletMessage(OBJECT_MENU_REQUEST_MESSAGE), + _pos(pos) +{ +} + +DuiAppletObjectMenuRequestMessage::~DuiAppletObjectMenuRequestMessage() +{ +} + +void DuiAppletObjectMenuRequestMessage::serialize(QDataStream &stream) const +{ + stream << _pos; +} + +void DuiAppletObjectMenuRequestMessage::unserialize(QDataStream &stream) +{ + stream >> _pos; +} + +QPointF DuiAppletObjectMenuRequestMessage::pos() const +{ + return _pos; +} diff --git a/src/mashup/appletcommunication/duiappletobjectmenurequestmessage.h b/src/mashup/appletcommunication/duiappletobjectmenurequestmessage.h new file mode 100644 index 000000000..7295017e4 --- /dev/null +++ b/src/mashup/appletcommunication/duiappletobjectmenurequestmessage.h @@ -0,0 +1,64 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETOBJECTMENUREQUESTMESSAGE_H +#define DUIAPPLETOBJECTMENUREQUESTMESSAGE_H + +#include "duiappletmessage.h" +#include + +/*! + * Send Request to applet runner for a context menu. + */ +class DUI_EXPORT DuiAppletObjectMenuRequestMessage : public DuiAppletMessage +{ +private: + /// position where the event occured + QPointF _pos ; + +public: + /*! + * Constructor. + * + * The point of event is a parameter. + * \param pos point which was received by the host process in context menu event. + */ + DuiAppletObjectMenuRequestMessage(QPointF pos = QPointF(-1, -1)); + + /*! + * Destroys the DuiAppletObjectMenuRequestMessage + */ + virtual ~DuiAppletObjectMenuRequestMessage(); + + //! \reimp + virtual void serialize(QDataStream &stream) const; + //! \reimp_end + + //! \reimp + virtual void unserialize(QDataStream &stream); + //! \reimp_end + + /*! + * Returns the position of the context menu event. + * \return position of the event. + */ + QPointF pos() const; +}; + +#endif // DUIAPPLETOBJECTMENUREQUESTMESSAGE_H diff --git a/src/mashup/appletcommunication/duiappletorientationmessage.cpp b/src/mashup/appletcommunication/duiappletorientationmessage.cpp new file mode 100644 index 000000000..ffd7701bc --- /dev/null +++ b/src/mashup/appletcommunication/duiappletorientationmessage.cpp @@ -0,0 +1,54 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiappletorientationmessage.h" +#include "duiappletmessagefactory.h" + +DuiAppletOrientationMessage::DuiAppletOrientationMessage(Dui::Orientation orientation) : + DuiAppletMessage(ORIENTATION_MESSAGE), + _orientation(orientation) +{ +} + +DuiAppletOrientationMessage::~DuiAppletOrientationMessage() +{ + +} + +void DuiAppletOrientationMessage::serialize(QDataStream &stream) const +{ + stream << (uchar)_orientation; +} + +void DuiAppletOrientationMessage::unserialize(QDataStream &stream) +{ + uchar tmp; + stream >> tmp; + _orientation = (Dui::Orientation)tmp; +} + +Dui::Orientation DuiAppletOrientationMessage::orientation() const +{ + return _orientation; +} + +void DuiAppletOrientationMessage::setOrientation(Dui::Orientation orientation) +{ + _orientation = orientation; +} diff --git a/src/mashup/appletcommunication/duiappletorientationmessage.h b/src/mashup/appletcommunication/duiappletorientationmessage.h new file mode 100644 index 000000000..e58b7d403 --- /dev/null +++ b/src/mashup/appletcommunication/duiappletorientationmessage.h @@ -0,0 +1,70 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETORIENTATIONMESSAGE_H +#define DUIAPPLETORIENTATIONMESSAGE_H + +#include "duiappletmessage.h" +#include + +/*! + * Screen orientation change applet message. + */ +class DUI_EXPORT DuiAppletOrientationMessage : public DuiAppletMessage +{ +private: + /// The new orientation. + Dui::Orientation _orientation; + +public: + /*! + * Constructor. + * + * The orientation can be set as a parameter. The default is \c Dui::Landscape. + * \param orientation the orientation property of the message. + */ + DuiAppletOrientationMessage(Dui::Orientation orientation = Dui::Landscape); + + /*! + * Destructor. + */ + virtual ~DuiAppletOrientationMessage(); + + //! \reimp + virtual void serialize(QDataStream &stream) const; + //! \reimp_end + + //! \reimp + virtual void unserialize(QDataStream &stream); + //! \reimp_end + + /*! + * Returns the orientation property of the message. + * \return the orientation property. + */ + Dui::Orientation orientation() const; + + /*! + * Sets the orientation property of the message. + * \param orientation the new orientation. + */ + void setOrientation(Dui::Orientation orientation); +}; + +#endif // DUIAPPLETORIENTATIONMESSAGE_H diff --git a/src/mashup/appletcommunication/duiappletpixmapmodifiedmessage.cpp b/src/mashup/appletcommunication/duiappletpixmapmodifiedmessage.cpp new file mode 100644 index 000000000..c8c107c01 --- /dev/null +++ b/src/mashup/appletcommunication/duiappletpixmapmodifiedmessage.cpp @@ -0,0 +1,50 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiappletpixmapmodifiedmessage.h" + +DuiAppletPixmapModifiedMessage::DuiAppletPixmapModifiedMessage(const QRectF &geometry) : + DuiAppletMessage(PIXMAP_MODIFIED_MESSAGE), + _geometry(geometry) +{ +} + +DuiAppletPixmapModifiedMessage::~DuiAppletPixmapModifiedMessage() +{ +} + +void DuiAppletPixmapModifiedMessage::serialize(QDataStream &stream) const +{ + stream << _geometry; +} + +void DuiAppletPixmapModifiedMessage::unserialize(QDataStream &stream) +{ + stream >> _geometry; +} + +QRectF DuiAppletPixmapModifiedMessage::geometry() const +{ + return _geometry; +} + +void DuiAppletPixmapModifiedMessage::setGeometry(const QRectF &newGeometry) +{ + _geometry = newGeometry; +} diff --git a/src/mashup/appletcommunication/duiappletpixmapmodifiedmessage.h b/src/mashup/appletcommunication/duiappletpixmapmodifiedmessage.h new file mode 100644 index 000000000..f966d4c48 --- /dev/null +++ b/src/mashup/appletcommunication/duiappletpixmapmodifiedmessage.h @@ -0,0 +1,75 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETPIXMAPMODIFIEDMESSAGE_H +#define DUIAPPLETPIXMAPMODIFIEDMESSAGE_H + +#include "duiappletmessage.h" + +#include + +/*! + * An applet message for notifying the host that a part of the applet pixmap has been modified. + */ +class DUI_EXPORT DuiAppletPixmapModifiedMessage : public DuiAppletMessage +{ +private: + //! The geometry of the modified region. + QRectF _geometry; + +public: + /*! + * Constructs a DuiAppletPixmapModifiedMessage. + * + * The geometry of the modified region can be set as a parameter. + * The default is a null rectangle. + * + * \param geometry the geometry of the modified region. + */ + explicit DuiAppletPixmapModifiedMessage(const QRectF &geometry = QRectF()); + + /*! + * Destroys the DuiAppletPixmapModifiedMessage. + */ + virtual ~DuiAppletPixmapModifiedMessage(); + + //! \reimp + virtual void serialize(QDataStream &stream) const; + //! \reimp_end + + //! \reimp + virtual void unserialize(QDataStream &stream); + //! \reimp_end + + /*! + * Returns the geometry of the modified region. + * + * \return the geometry of the modified region + */ + QRectF geometry() const; + + /*! + * Sets the geometry of the modified region. + * + * \param newGeometry the new geometry of the modified region + */ + void setGeometry(const QRectF &newGeometry); +}; + +#endif // DUIAPPLETPIXMAPMODIFIEDMESSAGE_H diff --git a/src/mashup/appletcommunication/duiappletpixmaptakenintousemessage.cpp b/src/mashup/appletcommunication/duiappletpixmaptakenintousemessage.cpp new file mode 100644 index 000000000..95f62cb72 --- /dev/null +++ b/src/mashup/appletcommunication/duiappletpixmaptakenintousemessage.cpp @@ -0,0 +1,53 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiappletpixmaptakenintousemessage.h" +#include "duiappletmessagefactory.h" + +DuiAppletPixmapTakenIntoUseMessage::DuiAppletPixmapTakenIntoUseMessage(Qt::HANDLE handle) : + DuiAppletMessage(PIXMAP_TAKEN_INTO_USE_MESSAGE), + _handle(handle) +{ +} + +DuiAppletPixmapTakenIntoUseMessage::~DuiAppletPixmapTakenIntoUseMessage() +{ +} + +void DuiAppletPixmapTakenIntoUseMessage::serialize(QDataStream &stream) const +{ + stream << (quint64)_handle; +} + +void DuiAppletPixmapTakenIntoUseMessage::unserialize(QDataStream &stream) +{ + quint64 tmp; + stream >> tmp; + _handle = (Qt::HANDLE)tmp; +} + +Qt::HANDLE DuiAppletPixmapTakenIntoUseMessage::handle() const +{ + return _handle; +} + +void DuiAppletPixmapTakenIntoUseMessage::setHandle(Qt::HANDLE newHandle) +{ + _handle = newHandle; +} diff --git a/src/mashup/appletcommunication/duiappletpixmaptakenintousemessage.h b/src/mashup/appletcommunication/duiappletpixmaptakenintousemessage.h new file mode 100644 index 000000000..4695ca049 --- /dev/null +++ b/src/mashup/appletcommunication/duiappletpixmaptakenintousemessage.h @@ -0,0 +1,68 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETPIXMAPTAKENINTOUSEMESSAGE_H +#define DUIAPPLETPIXMAPTAKENINTOUSEMESSAGE_H + +#include "duiappletmessage.h" + +/*! + * An applet message for notifying that the pixmap has been taken into use. + */ +class DUI_EXPORT DuiAppletPixmapTakenIntoUseMessage : public DuiAppletMessage +{ +private: + //! The X pixmap handle. + Qt::HANDLE _handle; + +public: + /*! + * Constructs a DuiAppletPixmapTakenIntoUseMessage. + * + * \param handle the pixmap handle + */ + DuiAppletPixmapTakenIntoUseMessage(Qt::HANDLE handle = 0); + + /*! + * Destroys the DuiAppletPixmapTakenIntoUseMessage. + */ + virtual ~DuiAppletPixmapTakenIntoUseMessage(); + + //! \reimp + virtual void serialize(QDataStream &stream) const; + //! \reimp_end + + //! \reimp + virtual void unserialize(QDataStream &stream); + //! \reimp_end + + /*! + * Returns the X pixmap handle property of the message. + * \return the X pixmap handle. + */ + Qt::HANDLE handle() const; + + /*! + * Sets the X pixmap handle property of the message. + * \param newHandle the new X pixmap handle. + */ + void setHandle(Qt::HANDLE newHandle); +}; + +#endif // DUIAPPLETPIXMAPTAKENINTOUSEMESSAGE_H diff --git a/src/mashup/appletcommunication/duiappletserver.cpp b/src/mashup/appletcommunication/duiappletserver.cpp new file mode 100644 index 000000000..7c4c0f16c --- /dev/null +++ b/src/mashup/appletcommunication/duiappletserver.cpp @@ -0,0 +1,85 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include +#include "duiappletserver.h" + +DuiAppletServer::DuiAppletServer() : + server(NULL) +{ +} + +DuiAppletServer::~DuiAppletServer() +{ + closeConnection(); +} + +bool DuiAppletServer::startServer(const QString &serverName) +{ + closeConnection(); + + // Remove the socket file if it exists + QLocalServer::removeServer(serverName); + + // Create a server and start listening for connections + server = new QLocalServer; + connect(server, SIGNAL(newConnection()), this, SLOT(newConnection())); + + if (!server->listen(serverName)) { + duiWarning("DuiAppletServer") << "Could not init server." << server->errorString(); + return false; + } + + return true; +} + + +void DuiAppletServer::closeConnection() +{ + if (server) { + server->close(); + delete server; + server = NULL; + delete stream; + stream = NULL; + // socket is deleted by qlocalserver's destructor + socket = NULL; + } +} + +void DuiAppletServer::newConnection() +{ + // Disconnect the new connection signal since only one connection is supported + disconnect(server, SIGNAL(newConnection()), this, SLOT(newConnection())); + + // Get the socket for the connection + socket = server->nextPendingConnection(); + + if (socket != NULL) { + // Connect the readyRead() slot for the receiving data from the server + connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead())); + + // Create a stream for the socket data + stream = new QDataStream(socket); + + emit connectionEstablished(); + } +} diff --git a/src/mashup/appletcommunication/duiappletserver.h b/src/mashup/appletcommunication/duiappletserver.h new file mode 100644 index 000000000..9a3231fe3 --- /dev/null +++ b/src/mashup/appletcommunication/duiappletserver.h @@ -0,0 +1,71 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETSERVER_H_ +#define DUIAPPLETSERVER_H_ + +#include "duiexport.h" +#include "duiappletcommunicator.h" + +class QLocalServer; + +/*! + * The DuiAppletServer implements a server for interprocess communication + * between two processes (a host application and an applet). + */ +class DUI_EXPORT DuiAppletServer : public DuiAppletCommunicator +{ + Q_OBJECT + +public: + /*! + * Constructs a DuiAppletServer. + */ + DuiAppletServer(); + + /*! + * Destroys the DuiAppletServer. + */ + virtual ~DuiAppletServer(); + + /*! + * Starts the server. + * + * \param serverName the name of the server + * \return true if connection setup was successful, false otherwise + */ + bool startServer(const QString &serverName); + + /*! + * Closes the connection. + */ + virtual void closeConnection(); + +private: + //! The local server used for listening to connections + QLocalServer *server; + +private slots: + /*! + * \brief A slot that gets called when a new connection has been established by this communicator. + */ + void newConnection(); +}; + +#endif /* DUIAPPLETSERVER_H_ */ diff --git a/src/mashup/appletcommunication/duiappletsetgeometrymessage.cpp b/src/mashup/appletcommunication/duiappletsetgeometrymessage.cpp new file mode 100644 index 000000000..0a872d187 --- /dev/null +++ b/src/mashup/appletcommunication/duiappletsetgeometrymessage.cpp @@ -0,0 +1,66 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiappletsetgeometrymessage.h" +#include "duiappletmessagefactory.h" + +DuiAppletSetGeometryMessage::DuiAppletSetGeometryMessage(const QRectF &geometry, Qt::HANDLE handle) : + DuiAppletMessage(SET_GEOMETRY_MESSAGE), + _geometry(geometry), + _handle(handle) +{ +} + +DuiAppletSetGeometryMessage::~DuiAppletSetGeometryMessage() +{ +} + +void DuiAppletSetGeometryMessage::serialize(QDataStream &stream) const +{ + stream << _geometry; + stream << (quint64)_handle; +} + +void DuiAppletSetGeometryMessage::unserialize(QDataStream &stream) +{ + quint64 tmp; + stream >> _geometry; + stream >> tmp; + _handle = (Qt::HANDLE)tmp; +} + +QRectF DuiAppletSetGeometryMessage::geometry() const +{ + return _geometry; +} + +void DuiAppletSetGeometryMessage::setGeometry(const QRectF &newGeometry) +{ + _geometry = newGeometry; +} + +Qt::HANDLE DuiAppletSetGeometryMessage::handle() const +{ + return _handle; +} + +void DuiAppletSetGeometryMessage::setHandle(Qt::HANDLE newHandle) +{ + _handle = newHandle; +} diff --git a/src/mashup/appletcommunication/duiappletsetgeometrymessage.h b/src/mashup/appletcommunication/duiappletsetgeometrymessage.h new file mode 100644 index 000000000..b4969078a --- /dev/null +++ b/src/mashup/appletcommunication/duiappletsetgeometrymessage.h @@ -0,0 +1,87 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETSETGEOMETRYMESSAGE_H +#define DUIAPPLETSETGEOMETRYMESSAGE_H + +#include "duiappletmessage.h" + +#include + +/*! + * An applet message for setting the geometry of a \c QGraphicsLayoutItem. + */ +class DUI_EXPORT DuiAppletSetGeometryMessage : public DuiAppletMessage +{ +private: + //! The geometry property of the message. + QRectF _geometry; + + //! The X pixmap handle. + Qt::HANDLE _handle; + +public: + /*! + * Constructor. + * + * The geometry can be set as a parameter. The default is a null rectangle. + * \param geometry the geometry property of the message. + * \param handle the pixmap handle + */ + explicit DuiAppletSetGeometryMessage(const QRectF &geometry = QRectF(), Qt::HANDLE handle = 0); + + /*! + * Destructor. + */ + virtual ~DuiAppletSetGeometryMessage(); + + //! \reimp + virtual void serialize(QDataStream &stream) const; + //! \reimp_end + + //! \reimp + virtual void unserialize(QDataStream &stream); + //! \reimp_end + + /*! + * Returns the geometry property of the message. + * \return the geometry. + */ + QRectF geometry() const; + + /*! + * Sets the geometry property of the message. + * \param newGeometry the new geometry. + */ + void setGeometry(const QRectF &newGeometry); + + /*! + * Returns the X pixmap handle property of the message. + * \return the X pixmap handle. + */ + Qt::HANDLE handle() const; + + /*! + * Sets the X pixmap handle property of the message. + * \param newHandle the new X pixmap handle. + */ + void setHandle(Qt::HANDLE newHandle); +}; + +#endif // DUIAPPLETSETGEOMETRYMESSAGE_H diff --git a/src/mashup/appletcommunication/duiapplettextchangedmessage.cpp b/src/mashup/appletcommunication/duiapplettextchangedmessage.cpp new file mode 100644 index 000000000..2ff242c9c --- /dev/null +++ b/src/mashup/appletcommunication/duiapplettextchangedmessage.cpp @@ -0,0 +1,49 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiapplettextchangedmessage.h" + +DuiAppletTextChangedMessage::DuiAppletTextChangedMessage() : + DuiAppletMessage(APPLET_TEXT_MESSAGE) +{ +} + +DuiAppletTextChangedMessage::~DuiAppletTextChangedMessage() +{ +} + +void DuiAppletTextChangedMessage::serialize(QDataStream &stream) const +{ + stream << _text; +} + +void DuiAppletTextChangedMessage::unserialize(QDataStream &stream) +{ + stream >> _text; +} + +QString DuiAppletTextChangedMessage::text() const +{ + return _text; +} + +void DuiAppletTextChangedMessage::setText(const QString &newText) +{ + _text = newText; +} diff --git a/src/mashup/appletcommunication/duiapplettextchangedmessage.h b/src/mashup/appletcommunication/duiapplettextchangedmessage.h new file mode 100644 index 000000000..f0ea193e3 --- /dev/null +++ b/src/mashup/appletcommunication/duiapplettextchangedmessage.h @@ -0,0 +1,58 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETTEXTCHANGEDMESSAGE_H +#define DUIAPPLETTEXTCHANGEDMESSAGE_H + +#include +#include "duiappletmessage.h" + +/*! + * Applet text changed message. + */ +class DUI_EXPORT DuiAppletTextChangedMessage : public DuiAppletMessage +{ +private: + QString _text; + +public: + /*! + * Constructor. + * + */ + DuiAppletTextChangedMessage(); + + /*! + * Destructor. + */ + virtual ~DuiAppletTextChangedMessage(); + + //! \reimp + virtual void serialize(QDataStream &stream) const; + //! \reimp_end + + //! \reimp + virtual void unserialize(QDataStream &stream); + //! \reimp_end + + QString text() const; + void setText(const QString &newText); +}; + +#endif // DUIAPPLETTEXTCHANGEDESSAGE_H diff --git a/src/mashup/appletcommunication/duiapplettitlechangedmessage.cpp b/src/mashup/appletcommunication/duiapplettitlechangedmessage.cpp new file mode 100644 index 000000000..7c6e007bd --- /dev/null +++ b/src/mashup/appletcommunication/duiapplettitlechangedmessage.cpp @@ -0,0 +1,49 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiapplettitlechangedmessage.h" + +DuiAppletTitleChangedMessage::DuiAppletTitleChangedMessage() : + DuiAppletMessage(APPLET_TITLE_MESSAGE) +{ +} + +DuiAppletTitleChangedMessage::~DuiAppletTitleChangedMessage() +{ +} + +void DuiAppletTitleChangedMessage::serialize(QDataStream &stream) const +{ + stream << _title; +} + +void DuiAppletTitleChangedMessage::unserialize(QDataStream &stream) +{ + stream >> _title; +} + +QString DuiAppletTitleChangedMessage::title() const +{ + return _title; +} + +void DuiAppletTitleChangedMessage::setTitle(const QString &newTitle) +{ + _title = newTitle; +} diff --git a/src/mashup/appletcommunication/duiapplettitlechangedmessage.h b/src/mashup/appletcommunication/duiapplettitlechangedmessage.h new file mode 100644 index 000000000..c3150bf8e --- /dev/null +++ b/src/mashup/appletcommunication/duiapplettitlechangedmessage.h @@ -0,0 +1,58 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETTITLECHANGEDMESSAGE_H +#define DUIAPPLETTITLECHANGEDMESSAGE_H + +#include +#include "duiappletmessage.h" + +/*! + * Applet title changed message. + */ +class DUI_EXPORT DuiAppletTitleChangedMessage : public DuiAppletMessage +{ +private: + QString _title; + +public: + /*! + * Constructor. + * + */ + DuiAppletTitleChangedMessage(); + + /*! + * Destructor. + */ + virtual ~DuiAppletTitleChangedMessage(); + + //! \reimp + virtual void serialize(QDataStream &stream) const; + //! \reimp_end + + //! \reimp + virtual void unserialize(QDataStream &stream); + //! \reimp_end + + QString title() const; + void setTitle(const QString &newTitle); +}; + +#endif // DUIAPPLETTITLECHANGEDESSAGE_H diff --git a/src/mashup/appletcommunication/duiappletupdategeometrymessage.cpp b/src/mashup/appletcommunication/duiappletupdategeometrymessage.cpp new file mode 100644 index 000000000..79b651a1e --- /dev/null +++ b/src/mashup/appletcommunication/duiappletupdategeometrymessage.cpp @@ -0,0 +1,50 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiappletupdategeometrymessage.h" + +DuiAppletUpdateGeometryMessage::DuiAppletUpdateGeometryMessage(const QVector &sizeHints) : + DuiAppletMessage(UPDATE_GEOMETRY_MESSAGE), + _sizeHints(sizeHints) +{ +} + +DuiAppletUpdateGeometryMessage::~DuiAppletUpdateGeometryMessage() +{ +} + +void DuiAppletUpdateGeometryMessage::serialize(QDataStream &stream) const +{ + stream << _sizeHints; +} + +void DuiAppletUpdateGeometryMessage::unserialize(QDataStream &stream) +{ + stream >> _sizeHints; +} + +QVector DuiAppletUpdateGeometryMessage::sizeHints() const +{ + return _sizeHints; +} + +void DuiAppletUpdateGeometryMessage::setSizeHints(const QVector &sizeHints) +{ + _sizeHints = sizeHints; +} diff --git a/src/mashup/appletcommunication/duiappletupdategeometrymessage.h b/src/mashup/appletcommunication/duiappletupdategeometrymessage.h new file mode 100644 index 000000000..cdc9264f7 --- /dev/null +++ b/src/mashup/appletcommunication/duiappletupdategeometrymessage.h @@ -0,0 +1,70 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETUPDATEGEOMETRYMESSAGE_H +#define DUIAPPLETUPDATEGEOMETRYMESSAGE_H + +#include "duiappletmessage.h" +#include +#include + +/*! + * Update geometry message. + */ +class DUI_EXPORT DuiAppletUpdateGeometryMessage : public DuiAppletMessage +{ +private: + // Size hints + QVector _sizeHints; + +public: + /*! + * Constructs a DuiAppletUpdateGeometryMessage. + * + * \param sizeHints a vector containing size hints + */ + explicit DuiAppletUpdateGeometryMessage(const QVector &sizeHints = QVector(Qt::NSizeHints)); + + /*! + * Destroys the DuiAppletUpdateGeometryMessage. + */ + virtual ~DuiAppletUpdateGeometryMessage(); + + //! \reimp + virtual void serialize(QDataStream &stream) const; + //! \reimp_end + + //! \reimp + virtual void unserialize(QDataStream &stream); + //! \reimp_end + + /*! + * Returns the size hints of the message. + * \return a vector containing the size hints. + */ + QVector sizeHints() const; + + /*! + * Sets the size hints of the message. + * \param sizeHints the new size hints. + */ + void setSizeHints(const QVector &sizeHints); +}; + +#endif // DUIAPPLETUPDATEGEOMETRYMESSAGE_H diff --git a/src/mashup/appletcommunication/duiappletvisibilitymessage.cpp b/src/mashup/appletcommunication/duiappletvisibilitymessage.cpp new file mode 100644 index 000000000..25a171049 --- /dev/null +++ b/src/mashup/appletcommunication/duiappletvisibilitymessage.cpp @@ -0,0 +1,52 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiappletvisibilitymessage.h" +#include "duiappletmessagefactory.h" + +DuiAppletVisibilityMessage::DuiAppletVisibilityMessage(bool visible) : + DuiAppletMessage(VISIBILITY_MESSAGE), + _visible(visible) +{ +} + +DuiAppletVisibilityMessage::~DuiAppletVisibilityMessage() +{ +} + +void DuiAppletVisibilityMessage::serialize(QDataStream &stream) const +{ + stream << _visible; +} + +void DuiAppletVisibilityMessage::unserialize(QDataStream &stream) +{ + stream >> _visible; +} + +bool DuiAppletVisibilityMessage::visible() const +{ + return _visible; +} + +void DuiAppletVisibilityMessage::setVisible(bool visible) +{ + _visible = visible; +} + diff --git a/src/mashup/appletcommunication/duiappletvisibilitymessage.h b/src/mashup/appletcommunication/duiappletvisibilitymessage.h new file mode 100644 index 000000000..c64886292 --- /dev/null +++ b/src/mashup/appletcommunication/duiappletvisibilitymessage.h @@ -0,0 +1,72 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETVISIBILITYMESSAGE_H +#define DUIAPPLETVISIBILITYMESSAGE_H + +#include "duiappletmessage.h" + +/*! + * An applet message for telling an applet when it gets visible/invisible. + */ +class DUI_EXPORT DuiAppletVisibilityMessage : public DuiAppletMessage +{ +private: + //! Visible or invisible + bool _visible; + +public: + /*! + * Constructor. + * + * The visibility property can be set as a parameter. + * The default is \c true (visible). + * \param visible the visibility. + */ + DuiAppletVisibilityMessage(bool visible = true); + + /*! + * Destructor. + */ + virtual ~DuiAppletVisibilityMessage(); + + //! \reimp + virtual void serialize(QDataStream &stream) const; + //! \reimp_end + + //! \reimp + virtual void unserialize(QDataStream &stream); + //! \reimp_end + + /*! + * Returns the visibility value of the message. Visible is \c true, invisible + * is \c false. + * \return the visibility. + */ + bool visible() const; + + /*! + * Sets the visibility value of the message. Visible is \c true, invisible + * is \c false. + * \param visible the visibility. + */ + void setVisible(bool visible = true); +}; + +#endif // DUIAPPLETVISIBILITYMESSAGE_H diff --git a/src/mashup/appletinstallation/appletinstallation.pri b/src/mashup/appletinstallation/appletinstallation.pri new file mode 100644 index 000000000..0272f543c --- /dev/null +++ b/src/mashup/appletinstallation/appletinstallation.pri @@ -0,0 +1,10 @@ +include(../mashup.pri) + +MASHUP_APPLETINSTALLATION_SRC_DIR = $$MASHUP_SRC_DIR/appletinstallation +INCLUDEPATH += $$MASHUP_SRC_DIR/appletinstallation + +HEADERS += $$MASHUP_APPLETINSTALLATION_SRC_DIR/duiappletinstallationsourceinterface.h \ + $$MASHUP_APPLETINSTALLATION_SRC_DIR/duiappletinstantiator.h \ + $$MASHUP_APPLETINSTALLATION_SRC_DIR/duiappletinstantiator_p.h + +SOURCES += $$MASHUP_APPLETINSTALLATION_SRC_DIR/duiappletinstantiator.cpp diff --git a/src/mashup/appletinstallation/duiappletinstallationsourceinterface.h b/src/mashup/appletinstallation/duiappletinstallationsourceinterface.h new file mode 100644 index 000000000..9d65f0831 --- /dev/null +++ b/src/mashup/appletinstallation/duiappletinstallationsourceinterface.h @@ -0,0 +1,57 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETINSTALLATIONSOURCEINTERFACE_H +#define DUIAPPLETINSTALLATIONSOURCEINTERFACE_H + +#include +#include "duiexport.h" + +class DuiWidget; +class DuiAppletInstantiator; + +/** + * DuiAppletInstallationSourceInterface is the base class for applet installation source classes. + * + * Applet installation source developers need to implement this interface in a plugin library + * and export their implementation from the library. The applet inventory will instantiate + * the available installation sources when needed. + * + * \see \ref appletdevelopment + */ +class DUI_EXPORT DuiAppletInstallationSourceInterface +{ +public: + /*! + * Destructor. + */ + virtual ~DuiAppletInstallationSourceInterface() {} + + /** + * This method is called to construct a new applet installation source. + * Caller will maintain the ownership of the constructed widget and + * will destroy it when it is no longer needed. + * \return New DuiWidget class instance that visualizes this installation source. + */ + virtual DuiWidget *constructWidget() = 0; +}; + +Q_DECLARE_INTERFACE(DuiAppletInstallationSourceInterface, "com.nokia.dui.core.AppletInstallationSourceInterface/1.0") + +#endif // DUIAPPLETINSTALLATIONSOURCEINTERFACE_H diff --git a/src/mashup/appletinstallation/duiappletinstantiator.cpp b/src/mashup/appletinstallation/duiappletinstantiator.cpp new file mode 100644 index 000000000..0ae81ffb2 --- /dev/null +++ b/src/mashup/appletinstallation/duiappletinstantiator.cpp @@ -0,0 +1,121 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include +#include +#include +#include "duiappletinstantiator.h" +#include "duiappletinstantiator_p.h" + +const QString DuiAppletInstantiatorPrivate::PACKAGE_MANAGER_DBUS_SERVICE = "com.nokia.package_manager"; +const QString DuiAppletInstantiatorPrivate::PACKAGE_MANAGER_DBUS_PATH = "/com/nokia/package_manager"; +const QString DuiAppletInstantiatorPrivate::PACKAGE_MANAGER_DBUS_INTERFACE = "com.nokia.package_manager"; +const QString DuiAppletInstantiatorPrivate::APPLET_INSTANCE_MANAGER_DBUS_INTERFACE = "org.maemo.dui.DuiAppletInstanceManager"; + +DuiAppletInstantiatorPrivate::DuiAppletInstantiatorPrivate() +{ +} + +DuiAppletInstantiatorPrivate::~DuiAppletInstantiatorPrivate() +{ +} + +DuiAppletInstantiator::DuiAppletInstantiator() : d_ptr(new DuiAppletInstantiatorPrivate) +{ +} + +DuiAppletInstantiator::~DuiAppletInstantiator() +{ + delete d_ptr; +} + +DuiAppletInstantiator *DuiAppletInstantiator::instance() +{ + static DuiAppletInstantiator appletInstantiatorInstance; + return &appletInstantiatorInstance; +} + +void DuiAppletInstantiator::instantiateAppletsInPackage(const QString &packageName, const QString &canvasDBusAddress) +{ + // Make sure the canvas D-Bus address is valid (the format is service/path) + if (canvasDBusAddress.contains('/')) { + Q_D(DuiAppletInstantiator); + + // Query the meta data of the package + QDBusInterface interface(DuiAppletInstantiatorPrivate::PACKAGE_MANAGER_DBUS_SERVICE, DuiAppletInstantiatorPrivate::PACKAGE_MANAGER_DBUS_PATH, DuiAppletInstantiatorPrivate::PACKAGE_MANAGER_DBUS_INTERFACE, QDBusConnection::systemBus()); + QDBusPendingCallWatcher *watcher; + if (packageName.contains('/')) { + // Get metadata for a local file + QDBusPendingCall call = interface.asyncCall("FetchPackageDataFile", packageName); + watcher = new QDBusPendingCallWatcher(call, this); + } else { + // Get metadata for a remote file + QString packageBaseName = QFileInfo(packageName).baseName().split('_').at(0); + QDBusPendingCall call = interface.asyncCall("FetchPackageData", packageBaseName, QString()); + watcher = new QDBusPendingCallWatcher(call, this); + } + watcher->setProperty("packageName", packageName); + watcher->setProperty("canvasDBusAddress", canvasDBusAddress); + connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher *)), d, SLOT(receivePackageData(QDBusPendingCallWatcher *))); + } +} + +void DuiAppletInstantiatorPrivate::receivePackageData(QDBusPendingCallWatcher *watcher) +{ + if (watcher != NULL) { + // Get the package name + QString packageName = watcher->property("packageName").toString(); + QString canvasDBusAddress = watcher->property("canvasDBusAddress").toString(); + + QDBusPendingReply > reply = *watcher; + if (!reply.isError()) { + // Get the meta data from the reply and inform the canvas about the installation + informCanvasAboutPackageInstallation(packageName, reply.argumentAt<0>(), canvasDBusAddress); + + // Start the installation of the package + QDBusInterface interface(PACKAGE_MANAGER_DBUS_SERVICE, PACKAGE_MANAGER_DBUS_PATH, PACKAGE_MANAGER_DBUS_INTERFACE, QDBusConnection::systemBus()); + if (packageName.contains('/')) { + // Install from a local file + interface.call(QDBus::NoBlock, "InstallFile", packageName); + } else { + // Install from a remote file + interface.call(QDBus::NoBlock, "Install", packageName); + } + } else { + // An error occurred so don't start installation but inform the canvas anyway without metadata in order to display the error + informCanvasAboutPackageInstallation(packageName, QMap(), canvasDBusAddress); + } + } +} + +void DuiAppletInstantiatorPrivate::informCanvasAboutPackageInstallation(const QString &packageName, const QMap &metaData, const QString &canvasDBusAddress) +{ + // Split the D-Bus path of the target canvas to service and path from the first slash; the validity of the address has already been checked + int pathSeparatorIndex = canvasDBusAddress.indexOf('/'); + QString service = canvasDBusAddress.left(pathSeparatorIndex); + QString path = canvasDBusAddress.mid(pathSeparatorIndex); + + // Call the instantiateApplet method of the target mashup canvas + QDBusInterface interface(service, path, APPLET_INSTANCE_MANAGER_DBUS_INTERFACE); + interface.call(QDBus::NoBlock, "instantiateAppletFromPackage", packageName, metaData); +} + +#include "moc_duiappletinstantiator.cpp" diff --git a/src/mashup/appletinstallation/duiappletinstantiator.h b/src/mashup/appletinstallation/duiappletinstantiator.h new file mode 100644 index 000000000..0c4ef139a --- /dev/null +++ b/src/mashup/appletinstallation/duiappletinstantiator.h @@ -0,0 +1,72 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETINSTANTIATOR_H_ +#define DUIAPPLETINSTANTIATOR_H_ + +#include +#include +#include + +class DuiAppletInstantiatorPrivate; +class QDBusPendingCallWatcher; + +/*! + * Instantiates applets from a given package to the given mashup canvas. + */ +class DuiAppletInstantiator : public QObject +{ + Q_OBJECT + +private: + /*! + * Constructs a new DuiAppletInstantiator. + */ + DuiAppletInstantiator(); + + /*! + * Destroys the DuiAppletInstantiator. + */ + virtual ~DuiAppletInstantiator(); + +public: + /*! + * Returns an instance of the applet instantiator. + * + * \return an instance of the applet instantiator + */ + static DuiAppletInstantiator *instance(); + + /*! + * Instantiates applets in a package to the given mashup canvas. + * + * \param packageName the name of the package to instantiate applets from + * \param canvasDBusAddress the D-Bus address of the canvas to instantiate to in service/path format + */ + void instantiateAppletsInPackage(const QString &packageName, const QString &canvasDBusAddress); + +private: + // The private class + DuiAppletInstantiatorPrivate *const d_ptr; + + Q_DECLARE_PRIVATE(DuiAppletInstantiator) + Q_PRIVATE_SLOT(d_func(), void receivePackageData(QDBusPendingCallWatcher *)) +}; + +#endif /* DUIAPPLETINSTANTIATOR_H_ */ diff --git a/src/mashup/appletinstallation/duiappletinstantiator_p.h b/src/mashup/appletinstallation/duiappletinstantiator_p.h new file mode 100644 index 000000000..5f8966831 --- /dev/null +++ b/src/mashup/appletinstallation/duiappletinstantiator_p.h @@ -0,0 +1,76 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETINSTANTIATOR_P_H_ +#define DUIAPPLETINSTANTIATOR_P_H_ + +#include +#include + +class QDBusPendingCallWatcher; + +/*! + * Private class for DuiAppletInstantiator. + */ +class DuiAppletInstantiatorPrivate : public QObject +{ + Q_OBJECT + +public: + /*! + * Creates a new private class for DuiAppletInstantiator. + */ + DuiAppletInstantiatorPrivate(); + + /*! + * Destroys the DuiAppletInstantiatorPrivate. + */ + virtual ~DuiAppletInstantiatorPrivate(); + + //! D-Bus service of the Package Manager + static const QString PACKAGE_MANAGER_DBUS_SERVICE; + + //! D-Bus path of the Package Manager + static const QString PACKAGE_MANAGER_DBUS_PATH; + + //! D-Bus interface of the Package Manager + static const QString PACKAGE_MANAGER_DBUS_INTERFACE; + + //! Name of the DuiAppletInstanceManager D-Bus Interface + static const QString APPLET_INSTANCE_MANAGER_DBUS_INTERFACE; + + /*! + * Informs the canvas about the installation of a package. + * + * \param packageName the name of the package to be installed + * \param metaData relevant meta data for the package + * \param canvasDBusAddress the D-Bus address of the canvas to instantiate to in service/path format + */ + void informCanvasAboutPackageInstallation(const QString &packageName, const QMap &metaData, const QString &canvasDBusAddress); + +public slots: + /*! + * Slot for receiving package data from the Package Manager + * + * \param watcher the QDBusPendingCallWatcher for the D-Bus call + */ + void receivePackageData(QDBusPendingCallWatcher *watcher); +}; + +#endif /* DUIAPPLETINSTANTIATOR_P_H_ */ diff --git a/src/mashup/appletinterface/appletinterface.pri b/src/mashup/appletinterface/appletinterface.pri new file mode 100644 index 000000000..dc6135914 --- /dev/null +++ b/src/mashup/appletinterface/appletinterface.pri @@ -0,0 +1,9 @@ +include(../mashup.pri) + +MASHUP_APPLETINTERFACE_SRC_DIR = $$MASHUP_SRC_DIR/appletinterface +INCLUDEPATH += $$MASHUP_SRC_DIR/appletinterface + +HEADERS += $$MASHUP_APPLETINTERFACE_SRC_DIR/duiappletinterface.h \ + $$MASHUP_APPLETINTERFACE_SRC_DIR/duiappletmetadata.h + +SOURCES += $$MASHUP_APPLETINTERFACE_SRC_DIR/duiappletmetadata.cpp diff --git a/src/mashup/appletinterface/duiappletinterface.h b/src/mashup/appletinterface/duiappletinterface.h new file mode 100644 index 000000000..4de9cb336 --- /dev/null +++ b/src/mashup/appletinterface/duiappletinterface.h @@ -0,0 +1,65 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETINTERFACE_H +#define DUIAPPLETINTERFACE_H + +#include +#include "duiexport.h" + +class DuiWidget; +class DuiAppletMetaData; +class DuiDataStore; +class DuiDataAccess; + +/** + * DuiAppletInterface is the base class for desktop applet + * entry-point classes. + * + * Applet developers need to implement this interface in their applet binary + * and export their implementation from the binary. The host application will maintain + * an inventory of available applets and instantiate them using this interface + * when needed. + * + * \see \ref appletdevelopment + */ +class DUI_EXPORT DuiAppletInterface +{ +public: + /*! + * Destructor. + */ + virtual ~DuiAppletInterface() {} + + /** + * This method is called to construct a new applet widget instance. + * Caller will maintain the ownership of the constructed widget and + * will destroy it when it is no longer needed. + * \param metadata Is const reference to metadata of the applet. + * \param instanceData A data store object that should be used to store permanent data of the constructed applet instance. + * \param settings A data store object that bundles applet settings to the applet. Contains both the + * instance settings and the global settings. + * \return New DuiWidget class instance that visualizes this applet. + */ + virtual DuiWidget *constructWidget(const DuiAppletMetaData &metadata, DuiDataStore &instanceData, DuiDataAccess &settings) = 0; +}; + +Q_DECLARE_INTERFACE(DuiAppletInterface, "com.nokia.dui.core.AppletInterface/1.0") + +#endif // DUIAPPLETINTERFACE_H diff --git a/src/mashup/appletinterface/duiappletmetadata.cpp b/src/mashup/appletinterface/duiappletmetadata.cpp new file mode 100644 index 000000000..27e31d5d1 --- /dev/null +++ b/src/mashup/appletinterface/duiappletmetadata.cpp @@ -0,0 +1,126 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiappletmetadata.h" +#include +#include + + +const QString AppletBinaryKey("DUI/X-DUIApplet-Applet"); +const QString IdentifierKey("DUI/X-DUIApplet-Identifier"); +const QString IconKey("Desktop Entry/Icon"); + +// Required desktop entry keys in an applet metadata file +QList RequiredKeys; + +DuiAppletMetaData::DuiAppletMetaData(const QString &fileName) : DuiDesktopEntry(fileName) +{ + if (RequiredKeys.isEmpty()) { + RequiredKeys << AppletBinaryKey << IconKey; + } +} + +DuiAppletMetaData::~DuiAppletMetaData() +{ +} + +bool DuiAppletMetaData::isValid() const +{ + // Make sure that applet metadata file is a valid desktop file. + if (!DuiDesktopEntry::isValid()) + return false; + + // Loop through keys and check that all are found + const int length = RequiredKeys.length(); + for (int i = 0; i < length; ++i) { + if (!contains(RequiredKeys[i])) { + return false; + } + } + + // If metadata contains runner binary, check that the binary exists. + if (exec().length() > 0 && runnerBinary() == NULL) { + return false; + } + + // Check that applet binary exists in filesystem. + if (appletBinary() == NULL) { + return false; + } + + return true; +} + +QString DuiAppletMetaData::runnerBinary() const +{ + // If runner binary is specified, return absolute file path. + QString s = exec(); + if (s.length() > 0) { + QFileInfo runner(QString(APPLET_LIBS), s); + if (runner.exists() && runner.isFile() && runner.isExecutable()) { + return runner.absoluteFilePath(); + } else { + duiDebug("DuiAppletMetaData") << "runner" << runner.absoluteFilePath() << "does not exist!"; + } + } + return NULL; +} + +QString DuiAppletMetaData::appletBinary() const +{ + // Fetch the absolute file path and return it. + QFileInfo applet(QString(APPLET_LIBS), value(AppletBinaryKey)); + if (applet.exists() && applet.isFile()) { + return applet.absoluteFilePath(); + } else { + duiDebug("DuiAppletMetaData") << "applet" << applet.absoluteFilePath() << "does not exist!"; + } + return NULL; +} + +QString DuiAppletMetaData::extractLibraryName(const QString &libFileName) +{ + QRegExp regExp(".*lib([^/]*)[.]so"); + + if (regExp.exactMatch(libFileName)) { + // The given argument can be treated as valid + QString tmp(libFileName); + tmp.replace(regExp, "\\1"); + return tmp; + } else { + // Invalid input - return empty string + return QString(); + } +} + +QString DuiAppletMetaData::resourceIdentifier() const +{ + QString resourceId; + QString binary = appletBinary(); + + if (contains(IdentifierKey)) { + resourceId = value(IdentifierKey); + } else if (!binary.isNull()) { + resourceId = extractLibraryName(binary); + } else { + return NULL; + } + + return resourceId; +} diff --git a/src/mashup/appletinterface/duiappletmetadata.h b/src/mashup/appletinterface/duiappletmetadata.h new file mode 100644 index 000000000..6ba8a0971 --- /dev/null +++ b/src/mashup/appletinterface/duiappletmetadata.h @@ -0,0 +1,115 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETMETADATA_H +#define DUIAPPLETMETADATA_H + +#include + +/*! + * This class provides dui applet metadata such as applet binary, appletrunner binary, + * icon and description. + * + * Applet metadata is stored in a .desktop file. The metadata file may also contain applet + * specific metadata such as script or markup source. Applet-specific information can also be accessed + * through this interface. + * + * Applet is ran using applet runner binary. Each applet has to define an applet binary which is + * compiled as a shared library. Both applet binaries and applet runner binaries are searched + * from a centralized place in the file system. The location for applet binaries and applet runner binaries + * is determined by APPLET_LIBS compile-time definition. All applet binaries and applet runner binaries + * are searched from this location. + * + * \code + * // Instantiate metadata from an applet file relative to binary path. + * DuiAppletMetaData data("filename.desktop"); + * + * // Make sure that applet metadata is valid before using it. + * if(data.isValid()) + * { + * // Access metadata.. + * } + * \endcode + * + * \see \ref appletdevelopment + */ +class DUI_EXPORT DuiAppletMetaData : public DuiDesktopEntry +{ +public: + /*! + * Constructs a new instance of DuiAppletMetaData by reading the .desktop + * file in that is given as a construction parameter. + * \param filename Location of .desktop file to be read by constructed DuiAppletMetaData instance. + */ + DuiAppletMetaData(const QString &filename); + + /*! + * Destructor + */ + virtual ~DuiAppletMetaData(); + + /*! + * Checks if the given metadata file contains all necessary data for an applet. + * At least applet binary needs to be specified. + * + * Note that applet metadata file needs to be valid desktop file before applet metadata-specific + * keys are investigated. + * \see DuiDesktopEntry::isValid() + */ + bool isValid() const; + + /*! + * Returns absolute path of the applet runner binary. The applet runner absolute path is + * effectively the APPLET_LIBS compile-time path definition appended by the applet runner binary + * defined in the applet metadata. + * + * If runner binary is not specified the applet described by this metadata should be ran + * in the host process. + * + * \return Path to the applet runner binary to be used for launching the applet. + */ + QString runnerBinary() const; + + /*! + * Get absolute path of the applet binary. The applet binary absolute path is + * effectively the APPLET_LIBS compile-time path definition appended by the applet binary + * defined in the applet metadata. + */ + QString appletBinary() const; + + /*! + * Get a resource identifier for the applet, used for specifying the + * directory of applet resources. + */ + QString resourceIdentifier() const; + +private: + /** + * Extracts a library name from a library file name. E.g. "libfoo.so" + * and "/usr/lib/libfoo.so" both produce "foo" as the name. If the + * given argument doesn't represent a valid library file name an empty + * string is returned. + * \param libFileName the file name of the library. + */ + static QString extractLibraryName(const QString &libFileName); + + Q_DISABLE_COPY(DuiAppletMetaData) +}; + +#endif // DUIAPPLETMETADATA_H diff --git a/src/mashup/mashup.pri b/src/mashup/mashup.pri new file mode 100644 index 000000000..4ce01d55f --- /dev/null +++ b/src/mashup/mashup.pri @@ -0,0 +1 @@ +MASHUP_SRC_DIR=./mashup diff --git a/src/mashup/mashup/duiaggregatedataaccess.cpp b/src/mashup/mashup/duiaggregatedataaccess.cpp new file mode 100644 index 000000000..17c7e4b0f --- /dev/null +++ b/src/mashup/mashup/duiaggregatedataaccess.cpp @@ -0,0 +1,101 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiaggregatedataaccess.h" +#include "duiaggregatedataaccess_p.h" + +DuiAggregateDataAccessPrivate::DuiAggregateDataAccessPrivate(DuiDataAccess &primaryAccess, DuiDataAccess &secondaryAccess) : + primaryAccess(primaryAccess), secondaryAccess(secondaryAccess) +{ +} + +DuiAggregateDataAccessPrivate::~DuiAggregateDataAccessPrivate() +{ +} + +DuiAggregateDataAccess::DuiAggregateDataAccess(DuiDataAccess &primaryAccess, DuiDataAccess &secondaryAccess) : + d_ptr(new DuiAggregateDataAccessPrivate(primaryAccess, secondaryAccess)) +{ + init(); +} + +DuiAggregateDataAccess::DuiAggregateDataAccess(DuiAggregateDataAccessPrivate &dd) : + d_ptr(&dd) +{ + init(); +} + +void DuiAggregateDataAccess::init() +{ + Q_D(DuiAggregateDataAccess); + d->q_ptr = this; + connect(&d->primaryAccess, SIGNAL(valueChanged(QString, QVariant)), this, SIGNAL(valueChanged(QString, QVariant))); + connect(&d->secondaryAccess, SIGNAL(valueChanged(QString, QVariant)), this, SLOT(secondaryAccessValueChanged(QString, QVariant))); +} + +DuiAggregateDataAccess::~DuiAggregateDataAccess() +{ + delete d_ptr; +} + +bool DuiAggregateDataAccess::setValue(const QString &key, const QVariant &value) +{ + Q_D(DuiAggregateDataAccess); + + bool ret = false; + ret = d->primaryAccess.setValue(key, value); + if (!ret) { + ret = d->secondaryAccess.setValue(key, value); + } + return ret; +} + +QVariant DuiAggregateDataAccess::value(const QString &key) const +{ + Q_D(const DuiAggregateDataAccess); + + if (d->primaryAccess.contains(key)) { + return d->primaryAccess.value(key); + } + return d->secondaryAccess.value(key); +} + +QStringList DuiAggregateDataAccess::allKeys() const +{ + Q_D(const DuiAggregateDataAccess); + + QStringList ret = d->primaryAccess.allKeys() + d->secondaryAccess.allKeys(); + ret.removeDuplicates(); + return ret; +} + +bool DuiAggregateDataAccess::contains(const QString &key) const +{ + Q_D(const DuiAggregateDataAccess); + + return d->primaryAccess.contains(key) || d->secondaryAccess.contains(key); +} + +void DuiAggregateDataAccess::secondaryAccessValueChanged(const QString &key, const QVariant &value) +{ + Q_D(const DuiAggregateDataAccess); + if (!d->primaryAccess.contains(key)) { + emit valueChanged(key, value); + } +} diff --git a/src/mashup/mashup/duiaggregatedataaccess.h b/src/mashup/mashup/duiaggregatedataaccess.h new file mode 100644 index 000000000..fea1c2f84 --- /dev/null +++ b/src/mashup/mashup/duiaggregatedataaccess.h @@ -0,0 +1,107 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAGGREGATEDATAACCESS_H +#define DUIAGGREGATEDATAACCESS_H + +#include +#include "duiexport.h" + +class DuiAggregateDataAccessPrivate; + +/*! + * \brief DuiAggregateDataAccess can be used to combine two or several objects implementing DuiDataAccess interface behind common + * DuiDataAccess interface. + * + * Keys are primarily set and acquired from primary access. If the particular key is not defined in primary access then its + * set or acquired from the secondary access. DuiDataAccess interfaces can be chained so that DuiAggregateDataAccess is defined + * as the secondary DuiDataAccess in the constructor of this object. + * \code + * // DuiAggregateDataAccess with two DuiDataAccesses: + * DuiDataAccess& primaryAccess; + * DuiDataAccess& secondaryAccess; + * DuiAggregateDataAccess* aggregate = new DuiAggregateDataAccess(primaryAccess, secondaryAccess); + * + * // DuiAggregateDataAccess with three DuiDataAccesses: + * DuiDataAccess& primaryAccess; + * DuiDataAccess& secondaryAccess; + * DuiDataAccess& tertiaryAccess; + * DuiAggregateDataAccess* secondaryAggregate = new DuiAggregateDataAccess(secondaryAccess, tertiaryAccess); + * DuiAggregateDataAccess* aggregate = new DuiAggregateDataAccess(primaryAccess, *secondaryAggregate); + * \endcode + * + * Ownership of the primary and secondary data access are maintained on the caller. Caller needs to make sure that primary and secondary data access objects + * exist whenever DuiAggregateDataAccess exists. For instance, DuiAggregateDataAccess object has to be destroyed before associated primary and secondary + * data access objects are destroyed. + */ +class DUI_EXPORT DuiAggregateDataAccess : public DuiDataAccess +{ + Q_OBJECT + +public: + /*! + * Default constructor. + * \param primaryAccess Primary DuiDataAccess object. Values are set and accessed from this data access primarily. + * \param secondaryAccess Secondary DuiDataAccess object. Values are set and accessed from this data access only if values cannot be set or accessed from the primary access. + */ + DuiAggregateDataAccess(DuiDataAccess &primaryAccess, DuiDataAccess &secondaryAccess); + + /*! + * Destructor. + */ + virtual ~DuiAggregateDataAccess(); + + //! \reimp + virtual bool setValue(const QString &key, const QVariant &value); + virtual QVariant value(const QString &key) const; + /*! + * Returns the combined key list of both primary and secondary data access objects. All duplicate keys are removed. + * \return Keys from both primary and secondary data access objects with duplicates removed. + */ + virtual QStringList allKeys() const; + virtual bool contains(const QString &key) const; + //! \reimp_end + +protected: + //! Pointer to private implementation object. + DuiAggregateDataAccessPrivate *const d_ptr; + + /*! + * Constructor for derived classes that allows injection of private implementation object of a derived class. + */ + DuiAggregateDataAccess(DuiAggregateDataAccessPrivate &dd); + +private slots: + /*! + * Slot called when values are changed in secondary DuiDataAccess object. + * If value is unique in this DuiAggregateDataAccess the valueChanged signal is emitted onwards. + */ + void secondaryAccessValueChanged(const QString &key, const QVariant &value); + +private: + /*! + * Initializes this object + */ + void init(); + +private: + Q_DECLARE_PRIVATE(DuiAggregateDataAccess) +}; + +#endif // DUIAGGREGATEDATAACCESS_H diff --git a/src/mashup/mashup/duiaggregatedataaccess_p.h b/src/mashup/mashup/duiaggregatedataaccess_p.h new file mode 100644 index 000000000..8c94b772e --- /dev/null +++ b/src/mashup/mashup/duiaggregatedataaccess_p.h @@ -0,0 +1,53 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAGGREGATEDATAACCESS_P_H +#define DUIAGGREGATEDATAACCESS_P_H + +#include + +/*! + * A private data class for DuiAggregateDataAccess. + */ +class DuiAggregateDataAccessPrivate +{ + Q_DECLARE_PUBLIC(DuiAggregateDataAccess) + +public: + /*! + * Constructor. + */ + DuiAggregateDataAccessPrivate(DuiDataAccess &primaryAccess, DuiDataAccess &secondaryAccess); + + /*! + * Destructor. + */ + virtual ~DuiAggregateDataAccessPrivate(); + + //! The primary data access object + DuiDataAccess &primaryAccess; + + //! The secondary data access object + DuiDataAccess &secondaryAccess; + +protected: + DuiAggregateDataAccess *q_ptr; +}; + +#endif diff --git a/src/mashup/mashup/duiappletbutton.cpp b/src/mashup/mashup/duiappletbutton.cpp new file mode 100644 index 000000000..f7bb04444 --- /dev/null +++ b/src/mashup/mashup/duiappletbutton.cpp @@ -0,0 +1,50 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiappletbutton.h" + +#include "duiwidgetcreator.h" +DUI_REGISTER_WIDGET(DuiAppletButton) + +DuiAppletButton::DuiAppletButton(QGraphicsItem *parent, const QString &type) : DuiButton(parent) +{ + setViewType(type); + this->setObjectName("DuiAppletButton"); +} + +DuiAppletButton::~DuiAppletButton() +{ +} + +bool DuiAppletButton::initialize(const DuiAppletMetaData &data) +{ + if (!data.isValid()) { + return false; + } + + metadataFile = data.fileName(); + setText(data.name()); + setIconID(data.icon()); + return true; +} + +QString DuiAppletButton::metadataFilename() const +{ + return metadataFile; +} diff --git a/src/mashup/mashup/duiappletbutton.h b/src/mashup/mashup/duiappletbutton.h new file mode 100644 index 000000000..8b94e726f --- /dev/null +++ b/src/mashup/mashup/duiappletbutton.h @@ -0,0 +1,90 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETBUTTON_H +#define DUIAPPLETBUTTON_H + +#include + +#include + +//! \internal + +/*! + * DuiAppletButton widget presents an available applet + * in the applet inventory. + * + * The icon, name and other data of the DuiAppletButton + * is retrieved from applet metadata, that is read from + * an applet metadata file given as a parameter to the + * initialize() - method. + * + * \code + * // Create a new duiappletbutton + * DuiAppletButton* button = new DuiAppletButton(); + * + * // Initialize the applet button from a given metadata file. + * if(button->initialize(appletMetaDataFile)) { + * // ... Use applet button here. + * } + * \endcode + */ +class DuiAppletButton : public DuiButton +{ + Q_OBJECT + +public: + /*! + * Constructs an DuiAppletButton. + */ + DuiAppletButton(QGraphicsItem *parent = 0, const QString &type = ""); + + /*! + * Destroys the DuiAppletButton. + */ + virtual ~DuiAppletButton(); + + /*! + * Initializes the applet button. Absolute path to an applet + * metadata file is given as a parameter. + * + * This method will read the applet metadata and verify that + * the data is valid. If the data is valid, this applet can + * be instantiated and used. + * + * \param data the applet metadata + * \return true if metadata is valid and applet can be used. False otherwise. + */ + bool initialize(const DuiAppletMetaData &data); + + /*! + * Get file name for the metadata of the applet that this button represents + * + * \return file name for the metadata of the applet that this button represents + */ + QString metadataFilename() const; + +private: + //! Applet metadata file name + QString metadataFile; +}; + +//! \internal_end + +#endif // DUIAPPLETBUTTON_H diff --git a/src/mashup/mashup/duiapplethandle.cpp b/src/mashup/mashup/duiapplethandle.cpp new file mode 100644 index 000000000..dac826a13 --- /dev/null +++ b/src/mashup/mashup/duiapplethandle.cpp @@ -0,0 +1,645 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiapplethandle.h" +#include "duiapplethandle_p.h" +#include "duiapplethandlestyle.h" +#include "duiappletsharedmutex.h" +#include +#include +#include +#include "duiscenemanager.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "duiwidgetcreator.h" +DUI_REGISTER_WIDGET(DuiAppletHandle) + +//! D-Bus path of the Package Manager +const QString DuiAppletHandlePrivate::PACKAGE_MANAGER_DBUS_PATH = "/com/nokia/package_manager"; + +//! D-Bus interface of the Package Manager +const QString DuiAppletHandlePrivate::PACKAGE_MANAGER_DBUS_INTERFACE = "com.nokia.package_manager"; + +DuiAppletHandlePrivate::DuiAppletHandlePrivate() : + restartCount(0), + appletResponseTimeout(3000), + runnerConnectionTimeout(20000), + applicationVisible(true), + widgetVisible(true), + appletSpecificActions() +{ + communicationTimer.setSingleShot(true); + + // Connect to the system bus to receive the Package Manager signals + QDBusConnection::systemBus().connect(QString(), PACKAGE_MANAGER_DBUS_PATH, PACKAGE_MANAGER_DBUS_INTERFACE, "OperationProgress", this, SLOT(operationProgress(QString, QString, int))); + QDBusConnection::systemBus().connect(QString(), PACKAGE_MANAGER_DBUS_PATH, PACKAGE_MANAGER_DBUS_INTERFACE, "OperationComplete", this, SLOT(operationComplete(QString, QString, QString))); +} + +DuiAppletHandlePrivate::~DuiAppletHandlePrivate() +{ +} + +void DuiAppletHandlePrivate::visibilityChanged() +{ + communicator.sendMessage(DuiAppletVisibilityMessage(applicationVisible && widgetVisible)); +} + +void DuiAppletHandlePrivate::operationComplete(const QString &operation, const QString &pkg, const QString &error) +{ + Q_Q(DuiAppletHandle); + + if (operation == "Install" && q->model()->packageName() == pkg && !error.isEmpty()) { + // If the installation of a package being installed fails go to the broken state + q->model()->setInstallationError(error); + q->model()->setState(DuiAppletHandleModel::BROKEN); + } +} + +void DuiAppletHandlePrivate::operationProgress(const QString &operation, const QString &pkg, int percentage) +{ + Q_Q(DuiAppletHandle); + + // Applet Instance Manager handles the situation when installation compeletes + if (operation == "Install" && q->model()->packageName() == pkg) { + q->model()->setInstallationProgress(percentage); + } +} + +DuiAppletHandle::DuiAppletHandle() : + DuiWidgetController(new DuiAppletHandlePrivate, new DuiAppletHandleModel, NULL) +{ + Q_D(DuiAppletHandle); + +#ifdef QT_OPENGL_ES_2 + if (!DuiApplication::softwareRendering()) { + setViewType("gles"); + } +#endif + + // TODO: FIXME - this needs to have the scene specified, + // temporarily uses currently active DuiWindow's scene. + connect(DuiApplication::activeWindow(), + SIGNAL(orientationChanged(Dui::Orientation)), + this, SLOT(orientationEvent(Dui::Orientation))); + + connect(this, SIGNAL(visibilityChanged(bool)), this, SLOT(visibilityEvent(bool))); + + // Configure the timers + connect(&d->aliveTimer, SIGNAL(timeout()), this, SLOT(sendAliveMessageRequest())); + connect(&d->communicationTimer, SIGNAL(timeout()), this, SLOT(communicationTimerTimeout())); +} + +DuiAppletHandle::~DuiAppletHandle() +{ + kill(); +} + +void DuiAppletHandle::initPlaceHolder(const DuiAppletId &appletId, const QString &packageName, const QString &installationError) +{ + model()->setAppletId(appletId); + model()->setPackageName(packageName); + if (installationError.isEmpty()) { + model()->setState(DuiAppletHandleModel::INSTALLING); + } else { + model()->setState(DuiAppletHandleModel::BROKEN); + model()->setInstallationError(installationError); + } +} + +void DuiAppletHandle::init(const QString &runnerBinary, const QString &appletInstanceFileDataPath, const QString &metaDataFileName, const DuiAppletId &appletId) +{ + Q_D(DuiAppletHandle); + + // Construct a server name + // Hash this object's pointer so we don't reveal the real address. This + // is a security protection mechanism against any kind of + // hacks revealing the address might make possible. + QByteArray const digest = QCryptographicHash::hash(QByteArray::number((quintptr)this), QCryptographicHash::Md5); + d->serverName = QString::number(QCoreApplication::applicationPid()) + '_' + QString::fromLatin1(digest.toHex()); + + // Store the arguments and the binary + d->arguments.clear(); + d->arguments << appletId.toString() << appletInstanceFileDataPath << metaDataFileName << d->serverName; + d->runnerBinary = runnerBinary; + + // Set the applet ID and applet base name + DuiAppletMetaData metaData(metaDataFileName); + model()->setAppletId(appletId); + model()->setAppletBaseName(QFileInfo(metaDataFileName).baseName()); + + // Create a new applet settings object and put it into the model + model()->setAppletSettings(new DuiAppletSettings(metaDataFileName, appletId)); + + // Start the applet process + run(); +} + +void DuiAppletHandle::run() +{ + Q_D(DuiAppletHandle); + + // Create a shared pixmap mutex after destroying any previous mutex + delete model()->pixmapMutex(); + DuiAppletSharedMutex *mutex = new DuiAppletSharedMutex; + if (!mutex->init(d->serverName)) { + model()->setState(DuiAppletHandleModel::BROKEN); + return; + } + + // Put it in the model so the view can use it + model()->setPixmapMutex(mutex); + + // Set the state to applet starting + model()->setState(DuiAppletHandleModel::STARTING); + + // Listen for connections from the runner + connect(&d->communicator, SIGNAL(connectionEstablished()), this, SLOT(connectionEstablished())); + + // Initialize socket server + if (!d->communicator.startServer(d->serverName)) { + model()->setState(DuiAppletHandleModel::BROKEN); + return; + } + + // Connect a signal to recognize termination of the process + connect(&d->process, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(processFinished(int, QProcess::ExitStatus))); + // Connect a signal to recognize errors of the process + connect(&d->process, SIGNAL(error(QProcess::ProcessError)), this, SLOT(processError(QProcess::ProcessError))); + + // Connect signals for receiving stdout and stderr data from the process + connect(&d->process, SIGNAL(readyReadStandardOutput()), this, SLOT(processStdOutputReady())); + connect(&d->process, SIGNAL(readyReadStandardError()), this, SLOT(processStdErrorReady())); + + d->process.start(d->runnerBinary, d->arguments); + d->processStartTime.start(); + +#ifdef Q_OS_UNIX + // Store the process pid as a property + setProperty("pid", d->process.pid()); +#endif + + // Create a timeout for establishing connection from runner to applet handle + d->communicationTimer.start(d->runnerConnectionTimeout); +} + +void DuiAppletHandle::processError(QProcess::ProcessError error) +{ + if (error == QProcess::FailedToStart) { + setAppletBrokenState(); + } +} + +void DuiAppletHandle::processFinished(int exitCode, QProcess::ExitStatus exitStatus) +{ + Q_UNUSED(exitCode); + Q_UNUSED(exitStatus); + + setAppletBrokenState(); +} + +void DuiAppletHandle::connectionEstablished() +{ + Q_D(DuiAppletHandle); + + if (state() != DuiAppletHandleModel::STARTING) { + qWarning() << "DuiAppletHandle::connectionEstablished() - Internal error, DuiAppletHandle state differs from DuiAppletHandleModel::STARTING"; + return; + } + + // Stop runner connection timeout timer + d->communicationTimer.stop(); + + // Don't accept any more connections + disconnect(&d->communicator, SIGNAL(connectionEstablished()), this, SLOT(connectionEstablished())); + // Listen for received messages + connect(&d->communicator, SIGNAL(messageReceived(DuiAppletMessage)), this, SLOT(messageReceived(DuiAppletMessage))); + + // Set the state to running + model()->setState(DuiAppletHandleModel::RUNNING); + + // Send applet alive request every 5 seconds. Send the first alive request immediately. + d->aliveTimer.start(5000); + sendAliveMessageRequest(); + + if (d->oldGeometry.isValid()) { + // Restore the applet geometry + setGeometry(d->oldGeometry); + } + + // Ask the applet for the size hints + updateGeometry(); + + update(); +} + +void DuiAppletHandle::kill() +{ + Q_D(DuiAppletHandle); + + // Stop communication with the runner + stopCommunication(); + + // Stop the applet process + d->process.disconnect(); + d->process.terminate(); + d->process.waitForFinished(); + + // Set the state to stopped + model()->setState(DuiAppletHandleModel::STOPPED); + + // Destroy the shared mutex + delete model()->pixmapMutex(); + model()->setPixmapMutex(NULL); + + // Remove the applet settings + delete model()->appletSettings(); + model()->setAppletSettings(NULL); +} + +void DuiAppletHandle::reinit() +{ + Q_D(DuiAppletHandle); + + // Get the applet geometry + d->oldGeometry = geometry(); + + // Stop the current instance + kill(); + + // Restart the applet + run(); +} + +void DuiAppletHandle::removeApplet() +{ + emit appletRemovalRequested(model()->appletId()); +} + +void DuiAppletHandle::setAliveResponseTimeout(uint timeout) +{ + Q_D(DuiAppletHandle); + + d->appletResponseTimeout = timeout; +} + +void DuiAppletHandle::setAppletIcon(const QString &newIcon) +{ + model()->setAppletIcon(newIcon); + emit appletIconChanged(newIcon); +} + +void DuiAppletHandle::setAppletTitle(const QString &newTitle) +{ + model()->setAppletTitle(newTitle); + emit appletTitleChanged(newTitle); +} + +void DuiAppletHandle::setAppletText(const QString &newText) +{ + model()->setAppletText(newText); + emit appletTextChanged(newText); +} + +QString DuiAppletHandle::appletIcon() const +{ + return model()->appletIcon(); +} + +QString DuiAppletHandle::appletTitle() const +{ + return model()->appletTitle(); +} + +QString DuiAppletHandle::appletText() const +{ + return model()->appletText(); +} + +void DuiAppletHandle::messageReceived(const DuiAppletMessage &message) +{ + Q_D(DuiAppletHandle); + + switch (message.type()) { + case DuiAppletMessage::PIXMAP_TAKEN_INTO_USE_MESSAGE: { + const DuiAppletPixmapTakenIntoUseMessage *m = dynamic_cast(&message); + + if (m != NULL) { + emit pixmapTakenIntoUse(m->handle()); + } + break; + } + + case DuiAppletMessage::APPLET_ALIVE_MESSAGE_RESPONSE: { + const DuiAppletAliveMessageResponse *m = dynamic_cast(&message); + if (m != NULL) { + d->communicationTimer.stop(); + } + break; + } + + case DuiAppletMessage::APPLET_ICON_MESSAGE: { + const DuiAppletIconChangedMessage *m = dynamic_cast(&message); + if (m != NULL) { + setAppletIcon(m->icon()); + } + break; + } + + case DuiAppletMessage::APPLET_TITLE_MESSAGE: { + const DuiAppletTitleChangedMessage *m = dynamic_cast(&message); + if (m != NULL) { + setAppletTitle(m->title()); + } + break; + } + + case DuiAppletMessage::APPLET_TEXT_MESSAGE: { + const DuiAppletTextChangedMessage *m = dynamic_cast(&message); + if (m != NULL) { + setAppletText(m->text()); + } + break; + } + + case DuiAppletMessage::UPDATE_GEOMETRY_MESSAGE: { + const DuiAppletUpdateGeometryMessage *m = dynamic_cast(&message); + if (m != NULL) { + // Put the size hints in the model and update the geometry + model()->setSizeHints(m->sizeHints()); + updateGeometry(); + } + break; + } + + case DuiAppletMessage::PIXMAP_MODIFIED_MESSAGE: { + const DuiAppletPixmapModifiedMessage *m = dynamic_cast(&message); + if (m != NULL) { + emit appletPixmapModified(m->geometry()); + } + break; + } + + case DuiAppletMessage::OBJECT_MENU_MESSAGE: { + //Got the actions from the message. Now draw them. + const DuiAppletObjectMenuMessage *m = dynamic_cast(&message); + if (m != NULL) { + displayContextMenu(m->actionList()); + } + break; + } + default: + qWarning() << "IPC protocol error! Got message type:" << message.type(); + break; + } +} + +void DuiAppletHandle::displayContextMenu(QList actions) +{ + setAppletSpecificActions(actions); + DuiObjectMenu *menu = new DuiObjectMenu(this); + sceneManager()->showWindow(menu, DuiSceneWindow::DestroyWhenDone); +} + +void DuiAppletHandle::stopCommunication() +{ + Q_D(DuiAppletHandle); + + disconnect(&d->communicator, SIGNAL(messageReceived(DuiAppletMessage)), this, SLOT(messageReceived(DuiAppletMessage))); + disconnect(&d->communicator, SIGNAL(connectionEstablished()), this, SLOT(connectionEstablished())); + d->aliveTimer.stop(); + d->communicationTimer.stop(); + + d->communicator.closeConnection(); +} + +void DuiAppletHandle::setAppletBrokenState() +{ + Q_D(DuiAppletHandle); + + model()->setState(DuiAppletHandleModel::BROKEN); + stopCommunication(); + setAppletSpecificActions(); + + if (d->processStartTime.elapsed() >= 30000) { + d->restartCount = 0; + } + + if (d->restartCount < 1) { + d->restartCount++; + reinit(); + } +} + +void DuiAppletHandle::communicationTimerTimeout() +{ + setAppletBrokenState(); +} + +void DuiAppletHandle::sendAliveMessageRequest() +{ + Q_D(DuiAppletHandle); + + d->communicator.sendMessage(DuiAppletAliveMessageRequest()); + d->communicationTimer.start(d->appletResponseTimeout); +} + +void DuiAppletHandle::visibilityEvent(bool visible) +{ + Q_D(DuiAppletHandle); + + d->widgetVisible = visible; + d->visibilityChanged(); +} + +void DuiAppletHandle::enterDisplayEvent() +{ + Q_D(DuiAppletHandle); + + d->applicationVisible = true; + d->visibilityChanged(); +} + +void DuiAppletHandle::exitDisplayEvent() +{ + Q_D(DuiAppletHandle); + + d->applicationVisible = false; + d->visibilityChanged(); +} + +void DuiAppletHandle::orientationEvent(const Dui::Orientation &orientation) +{ + Q_D(DuiAppletHandle); + + d->communicator.sendMessage(DuiAppletOrientationMessage(orientation)); +} + +void DuiAppletHandle::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + Q_D(DuiAppletHandle); + + // Scale the mouse events based on the current applet pixmap scaling factor + d->communicator.sendMessage(DuiAppletMouseMessage(DuiAppletMessage::MOUSE_PRESS_MESSAGE, event->pos() / model()->appletScale(), event->button(), event->buttons())); +} + +void DuiAppletHandle::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) +{ + if (state() == DuiAppletHandleModel::RUNNING) { + Q_D(DuiAppletHandle); + QPointF scaledPos = event->pos() / model()->appletScale(); + d->communicator.sendMessage(DuiAppletObjectMenuRequestMessage(scaledPos)); + } else { + DuiWidgetController::contextMenuEvent(event); + } +} + +void DuiAppletHandle::cancelEvent(DuiCancelEvent *event) +{ + Q_UNUSED(event); + Q_D(DuiAppletHandle); + + d->communicator.sendMessage(DuiAppletCancelMessage()); +} + +void DuiAppletHandle::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + if (state() == DuiAppletHandleModel::BROKEN) { + DuiWidgetController::mouseReleaseEvent(event); + } else { + Q_D(DuiAppletHandle); + + // Scale the mouse events based on the current applet pixmap scaling factor + d->communicator.sendMessage(DuiAppletMouseMessage(DuiAppletMessage::MOUSE_RELEASE_MESSAGE, event->pos() / model()->appletScale(), event->button(), event->buttons())); + } +} + +void DuiAppletHandle::mouseMoveEvent(QGraphicsSceneMouseEvent *event) +{ + Q_D(DuiAppletHandle); + + // Scale the mouse events based on the current applet pixmap scaling factor + d->communicator.sendMessage(DuiAppletMouseMessage(DuiAppletMessage::MOUSE_MOVE_MESSAGE, event->pos() / model()->appletScale(), event->button(), event->buttons())); +} + +void DuiAppletHandle::sendGeometryMessage(QRectF appletRect, Qt::HANDLE pixmapHandle) +{ +#ifndef Q_WS_X11 + Q_UNUSED(appletRect); + Q_UNUSED(pixmapHandle); +#else + Q_D(DuiAppletHandle); + + // Send the size the applet should know about and the X Pixmap handle to the applet + d->communicator.sendMessage(DuiAppletSetGeometryMessage(appletRect, pixmapHandle)); +#endif +} + +void DuiAppletHandle::processStdOutputReady() +{ + Q_D(DuiAppletHandle); + duiDebug("DuiAppletHandle") << "processStdOutputReady()\n -------------->"; + duiDebug("") << qPrintable(QString(d->process.readAllStandardOutput())); + duiDebug("") << " <--------------\n"; +} + +void DuiAppletHandle::processStdErrorReady() +{ + Q_D(DuiAppletHandle); + duiDebug("DuiAppletHandle") << "processStdErrorReady()\n -------------->"; + duiDebug("") << qPrintable(QString(d->process.readAllStandardError())); + duiDebug("") << " <--------------\n"; +} + +void DuiAppletHandle::setAppletSpecificActions(QList items) +{ + Q_D(DuiAppletHandle); + + // Remove previous applet specific actions + foreach(DuiAction * action, d->appletSpecificActions) { + removeAction(action); + delete action; + } + d->appletSpecificActions.clear(); + + foreach(const QString & item, items) { + DuiAction *action = new DuiAction(item, this); + d->appletSpecificActions.append(action); + connect(action, SIGNAL(triggered()), this, SLOT(appletSpecificActionTriggered())); + addAction(action); + } +} + +void DuiAppletHandle::appletSpecificActionTriggered() +{ + Q_D(DuiAppletHandle); + + DuiAction *action = qobject_cast(sender()); + if (action != NULL) { + int index = d->appletSpecificActions.indexOf(action); + if (index >= 0) { + d->communicator.sendMessage(DuiAppletObjectMenuActionSelectedMessage(index)); + } + } +} + +DuiAppletHandleModel::AppletState DuiAppletHandle::state() const +{ + return model()->state(); +} + +void DuiAppletHandle::setSizeHints(const QVector &sizeHints) +{ + model()->setSizeHints(sizeHints); +} + +#include "moc_duiapplethandle.cpp" diff --git a/src/mashup/mashup/duiapplethandle.h b/src/mashup/mashup/duiapplethandle.h new file mode 100644 index 000000000..b825f2a60 --- /dev/null +++ b/src/mashup/mashup/duiapplethandle.h @@ -0,0 +1,318 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETHANDLE_H +#define DUIAPPLETHANDLE_H + +#include +#include "duiappletinstancemanager.h" + +#include +#include +#include +#include +#include +#include +#include "duiapplethandlemodel.h" +#include "duiappletid.h" + +class DuiAppletCommunicator; +class DuiAppletMessage; +class DuiAppletHandlePrivate; +class QTimer; + +//! \internal + +/*! + * @class DuiAppletHandle + * + * Interfaces with the actual applet that resides in another process. Handle starts the + * 'runner' process that opens the actual .so applet and knows how to deal with it internally. + * + * If the applet insists that its minimum and preferred size hints are larger + * than the width of the screen DuiAppletHandle will draw the applet pixmap + * downscaled so that it fits the screen. + */ +class DuiAppletHandle : public DuiWidgetController +{ + Q_OBJECT + DUI_CONTROLLER(DuiAppletHandle) + Q_PROPERTY(QString appletIcon READ appletIcon WRITE setAppletIcon NOTIFY appletIconChanged) + Q_PROPERTY(QString appletTitle READ appletTitle WRITE setAppletTitle NOTIFY appletTitleChanged) + Q_PROPERTY(QString appletText READ appletText WRITE setAppletText NOTIFY appletTextChanged) + + Q_PROPERTY(DuiAppletHandleModel::AppletState state READ state) + +public: + /*! + * Constructs an DuiAppletHandle. + */ + DuiAppletHandle(); + + /*! + * Destroys the DuiAppletHandle. + */ + virtual ~DuiAppletHandle(); + + /*! + * Initializes the handle and launches runner process. + * + * \param runnerBinary the runner binary to be used + * \param appletInstanceFileDataPath path to data file used to store instance specific data about this applet. + * \param metaDataFileName applet metadata file name + * \param appletId Applet global identifier + */ + void init(const QString &runnerBinary, const QString &appletInstanceFileDataPath, const QString &metaDataFileName, const DuiAppletId &appletId); + + /*! + * Initializes the place holder handle. Sets the applet handle to INSTALLING state if no error has occurred or to BROKEN state if an error has occurred. + * + * \param appletId Applet global identifier + * \param packageName Package of which installation progress should be tracked by the handle + * \param installationError An empty string if no error has occurred or the reason for the error if an error has occurred + */ + void initPlaceHolder(const DuiAppletId &appletId, const QString &packageName, const QString &installationError = QString()); + + /*! + * Stops the handle's runner process. + */ + void kill(); + + /*! + * Reinitializes the handle by first stopping the current process and then + * restarting it. + */ + void reinit(); + + /*! + * Sets the timeout that applet handle waits for applet instance to respond to applet alive requests. + * If the applet instance fails to respond to the request in time, DuiAppletHandle assumes that the applet instance + * has become unresponsive and will emit the appletNotResponding - signal \see appletNotResponding. + * The timeout defaults to 3000 milliseconds. + * + * \param timeout Timeout in milliseconds to wait for applet instance to respond to an applet alive request. + */ + void setAliveResponseTimeout(uint timeout); + + /*! + * Sends the applet a message of type \c DuiAppletSetGeometryMessage about changed geometry. + * \param appletRect the new size of the applet + * \param pixmapHandle the X pixmap handle the applet should use + */ + void sendGeometryMessage(QRectF appletRect, Qt::HANDLE pixmapHandle); + + /*! + * Sends a signal to the instance manager to remove this applet + */ + void removeApplet(); + + /*! + * Stops the communication to the applet runner. + */ + void stopCommunication(); + + /*! + * Sets the applet specific actions to \p items. Any previous applet + * specific actions are removed. Initially the applet specific actions + * list is empty. + * \param items a list of the names of the applet specific actions. + */ + void setAppletSpecificActions(QList items = QList()); + + /*! + * Returns the state of the applet handle. + */ + DuiAppletHandleModel::AppletState state() const; + + /*! + * Sets the icon ID of the applet. + * + * \param newIcon the new icon ID + */ + void setAppletIcon(const QString &newIcon); + + /*! + * Sets the title of the applet. + * + * \param newTitle the new title + */ + void setAppletTitle(const QString &newTitle); + + /*! + * Sets the text of the applet. + * + * \param newText the new text + */ + void setAppletText(const QString &newText); + + /*! + * Returns the icon ID of the applet. + * + * \return the icon ID of the applet + */ + QString appletIcon() const; + + /*! + * Returns the title of the applet. + * + * \return the title of the applet + */ + QString appletTitle() const; + + /*! + * Returns the text of the applet. + * + * \return the text of the applet + */ + QString appletText() const; + + /*! + * Sets the size hints of the applet. The purpose of this is to set the + * size hints while the applet is not yet running. + * + * \param sizeHints the size hints for the applet + */ + void setSizeHints(const QVector &sizeHints); + +protected: + //! \reimp + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event); + virtual void cancelEvent(DuiCancelEvent *event); + virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent *event); + virtual void enterDisplayEvent(); + virtual void exitDisplayEvent(); + //! \reimp_end + +protected slots: + /*! + * \brief A slot that gets called when the communication channel to the applet + * runner binary has been established. + */ + void connectionEstablished(); + + /*! + * \brief A slot for running the applet process + */ + void run(); + + /*! + * \brief A slot for notifying that a message has been received from the applet + */ + void messageReceived(const DuiAppletMessage &message); + + /*! + * \brief A slot for notifying that communication between applet handle and applet runner has dropped. + * This slot can be called if establishing of communication between applet handle and applet runner failed + * or if communication is dropped during the lifetime of the applet. + */ + void communicationTimerTimeout(); + + /*! + * \brief A slot for notifying that an alive request should be sent to the applet + */ + void sendAliveMessageRequest(); + + /*! + * \brief A slot for notifying that the visibility of the applet has changed due to hide()/show() + */ + void visibilityEvent(bool visible); + + /*! + * \brief A slot for notifying that the orientation has changed + */ + void orientationEvent(const Dui::Orientation &); + + /*! + * \brief A slot for notifying that there is data to be read from the applet's standard error stream + */ + void processStdErrorReady(); + + /*! + * \brief A slot for notifying that there is data to be read from the applet's standard output stream + */ + void processStdOutputReady(); + + /*! + * \brief A slot for handling errors in the applet runner process. + * \param error the error code. + */ + void processError(QProcess::ProcessError error); + + /*! + * \brief A slot for notifying that the applet process has finished + */ + void processFinished(int exitCode, QProcess::ExitStatus exitStatus); + + /*! + * A slot to be called when an applet specific action gets triggered. + * Sends a message to the applet to notify about the action triggering. + */ + void appletSpecificActionTriggered(); + +signals: + /*! + * Signal that is emitted to indicate that the applet removal is requested + * \param appletId The appletId object + */ + void appletRemovalRequested(DuiAppletId appletId); + + /*! + * \brief Applet changed its icon, part of container communication API + */ + void appletIconChanged(const QString &newIcon); + + /*! + * \brief Applet changed its title, part of container communication API + */ + void appletTitleChanged(const QString &newTitle); + + /*! + * \brief Applet changed its additional text, part of container communication API + */ + void appletTextChanged(const QString &newText); + + /*! + * \brief Signals that a pixmap has been taken into use by the applet + */ + void pixmapTakenIntoUse(Qt::HANDLE pixmapHandle); + + /*! + * \brief Content's of the applet's pixmap have changed + */ + void appletPixmapModified(const QRectF &rect); + +private: + Q_DECLARE_PRIVATE(DuiAppletHandle) + + //! Sets the applet state to BROKEN and restarts it if this is the first time the applet broke + void setAppletBrokenState(); + + //! Displays the list of actions on the host process + void displayContextMenu(QList actions); + +#ifdef UNIT_TEST + friend class Ut_DuiAppletHandle; +#endif +}; + +//! \internal_end + +#endif // DUIAPPLETHANDLE_H diff --git a/src/mashup/mashup/duiapplethandle_p.h b/src/mashup/mashup/duiapplethandle_p.h new file mode 100644 index 000000000..519cffa64 --- /dev/null +++ b/src/mashup/mashup/duiapplethandle_p.h @@ -0,0 +1,141 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETHANDLE_P_H +#define DUIAPPLETHANDLE_P_H + +#include "duiapplethandle.h" +#include "private/duiwidgetcontroller_p.h" +#include "duiappletinstancemanager.h" +#include "duiappletid.h" +#include "duiappletserver.h" + +#include +#include +#include + +class DuiSettingsLanguageBinary; +class DuiAction; + +/*! + * A private data class for DuiAppletHandle. + */ +class DuiAppletHandlePrivate : public virtual QObject, public DuiWidgetControllerPrivate +{ + Q_DECLARE_PUBLIC(DuiAppletHandle) + Q_OBJECT + +public: + /*! + * Constructor. + */ + DuiAppletHandlePrivate(); + + /*! + * Destructor. + */ + virtual ~DuiAppletHandlePrivate(); + + //! The name for the applet communication server + QString serverName; + + //! The arguments that were given to init() + QStringList arguments; + + //! The name of the applet runner binary + QString runnerBinary; + + //! The applet process + QProcess process; + + //! The number of times this process has been restarted due to applet malfunction + int restartCount; + + //! Time since the process was started, for checking how long the applet could run before breaking + QTime processStartTime; + + //! A server for IPC communication between the processes + DuiAppletServer communicator; + + //! Timer to send alive message requests to runner at constant intervals + QTimer aliveTimer; + + //! Timer to verify that communication between runner process and applet handle is working + QTimer communicationTimer; + + //! Timeout for applet instance to respond to applet alive request. + uint appletResponseTimeout; + + //! Timeout for applet runner process to connect to applet handle + uint runnerConnectionTimeout; + + //! Stored geometry of the applet + QRectF oldGeometry; + + //! A list of applet instance settings binaries read during initialization + QList instanceSettingsBinaries; + + //! A list of applet global settings binaries read during initialization + QList globalSettingsBinaries; + + //! Application level visibility + bool applicationVisible; + + //! Widget level visibility + bool widgetVisible; + + //! A list of applet specific actions + QList appletSpecificActions; + + //! D-Bus service of the Package Manager + static const QString PACKAGE_MANAGER_DBUS_SERVICE; + + //! D-Bus path of the Package Manager + static const QString PACKAGE_MANAGER_DBUS_PATH; + + //! D-Bus interface of the Package Manager + static const QString PACKAGE_MANAGER_DBUS_INTERFACE; + + /*! + * Sends the necessary visibility change message when the application or + * widget level visibility has changed + */ + void visibilityChanged(); + +public slots: + /*! + * Slot for listening to operation complete signals from the Package Manager + * + * \param operation Name of the operation. Possible names are: Install, Uninstall and Upgrade + * \param pkg Name of the package that operation is performed on + * \param error Empty if operation was successful, DBus error name otherwise + */ + void operationComplete(const QString &operation, const QString &pkg, const QString &error); + + /*! + * Receives information about the progress of a Package Manager operation. + * + * \param operation Name of the operation. Possible names are: Install, Uninstall and Upgrade + * \param pkg Name of the package that operation is performed on. + * \param percentage Current progress percentage + */ + void operationProgress(const QString &operation, const QString &pkg, int percentage); +}; + +#endif diff --git a/src/mashup/mashup/duiapplethandleglesview.cpp b/src/mashup/mashup/duiapplethandleglesview.cpp new file mode 100644 index 000000000..603ab5d46 --- /dev/null +++ b/src/mashup/mashup/duiapplethandleglesview.cpp @@ -0,0 +1,148 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include "duiviewcreator.h" +#include +#include "duiapplethandle.h" +#include "duiapplethandleglesview.h" +#include "duiapplethandleglesview_p.h" +#include + +DuiAppletHandleGLESViewPrivate::DuiAppletHandleGLESViewPrivate(DuiAppletHandle *appletHandle) : + DuiAppletHandleViewPrivate(appletHandle), + textureID(-1), + brokenAppletPixmap(QPixmap()) +{ + if (DuiGLRenderer::instance()->getProgram("DuiAppletHandleViewShader") == NULL) { + // Create a fragment shader for blurring an image + static const char *fragmentShader = "\ + varying mediump vec2 fragTexCoord;\ + uniform sampler2D texture0;\ + uniform mediump float width;\ + uniform mediump float height;\ + void main(void)\ + {\ + const int n = 3;\ + const mediump float l = float(n * 2 + 1);\ + const mediump float mult = 1.0 / (l * l);\ + gl_FragColor = vec4(0);\ + mediump vec2 coord = fragTexCoord + vec2(-float(n) * width, -float(n) * height);\ + for(int y = -n; y <= n; ++y) {\ + for(int x = -n; x <= n; ++x) {\ + gl_FragColor += texture2D(texture0, coord);\ + coord.x += width;\ + }\ + coord += vec2(width * -l, height);\ + }\ + gl_FragColor *= mult;\ + lowp float c = (gl_FragColor.r * 0.3 + gl_FragColor.g * 0.59 + gl_FragColor.b * 0.11);\ + gl_FragColor.rgb = vec3(c, c, c);\ + }"; + + DuiGLRenderer::instance()->createShader("DuiAppletHandleViewFragmentShader", fragmentShader, DuiGLRenderer::DuiShaderFragment); + DuiGLRenderer::instance()->createProgram("DuiAppletHandleViewShader", "", "DuiAppletHandleViewFragmentShader"); + } +} + +DuiAppletHandleGLESViewPrivate::~DuiAppletHandleGLESViewPrivate() +{ + destroyPixmaps(); +} + +void DuiAppletHandleGLESViewPrivate::destroyPixmaps() +{ + // Delete texture if there is one + if (textureID >= 0) { + DuiGLRenderer::instance()->viewport()->deleteTexture(textureID); + textureID = -1; + } + + brokenAppletPixmap = QPixmap(); + + DuiAppletHandleViewPrivate::destroyPixmaps(); +} + +void DuiAppletHandleGLESViewPrivate::drawAppletBrokenState() +{ + Q_Q(const DuiAppletHandleGLESView); + + if (!DuiApplication::softwareRendering() && brokenAppletPixmap.isNull() && !localPixmap.isNull()) { + textureID = DuiGLRenderer::instance()->viewport()->bindTexture(localPixmap); + + DuiAppletHandleViewUniformProvider uniforms(localPixmap.width(), localPixmap.height()); + + QSize newSize = localPixmap.size() * q->model()->appletScale(); + QGLFramebufferObject fbo(newSize); + fbo.bind(); + DuiGLRenderer::instance()->setViewportSize(newSize); + DuiGLRenderer::instance()->drawTexture("DuiAppletHandleViewShader", + QTransform(), + textureID, + newSize, + &uniforms); + brokenAppletPixmap = QPixmap::fromImage(fbo.toImage()); + fbo.release(); + } + + DuiAppletHandleViewPrivate::drawAppletBrokenState(); +} + +void DuiAppletHandleGLESViewPrivate::drawAppletPixmap(QPainter *painter, const QRectF &sourceGeometry, const QRectF &targetGeometry, bool brokenState) const +{ + // Draw the applet pixmap scaled so that it fits the screen + if (brokenState && !brokenAppletPixmap.isNull()) { + painter->drawPixmap(0, 0, brokenAppletPixmap); + } else { + painter->drawPixmap(targetGeometry, localPixmap, sourceGeometry); + } +} + +DuiAppletHandleGLESView::DuiAppletHandleGLESView(DuiAppletHandle *appletHandle) : + DuiAppletHandleView(* new DuiAppletHandleGLESViewPrivate(appletHandle), appletHandle) +{ +} + +DuiAppletHandleGLESView::~DuiAppletHandleGLESView() +{ +} + +DuiAppletHandleViewUniformProvider::DuiAppletHandleViewUniformProvider(float width, float height) : + width(qMax(width, 1.0f)), height(qMax(height, 1.0f)) +{ +} + +DuiAppletHandleViewUniformProvider::~DuiAppletHandleViewUniformProvider() +{ +} + +bool DuiAppletHandleViewUniformProvider::setUniformValue(const QString &name, const DuiGLShaderUniform &uniform) +{ + if (name == "width") { + uniform = 1.0f / width; + return true; + } else if (name == "height") { + uniform = 1.0f / height; + return true; + } + + return false; +} + +DUI_REGISTER_VIEW_NEW(DuiAppletHandleGLESView, DuiAppletHandle) diff --git a/src/mashup/mashup/duiapplethandleglesview.h b/src/mashup/mashup/duiapplethandleglesview.h new file mode 100644 index 000000000..343211185 --- /dev/null +++ b/src/mashup/mashup/duiapplethandleglesview.h @@ -0,0 +1,93 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETHANDLEGLESVIEW_H +#define DUIAPPLETHANDLEGLESVIEW_H + +#include +#include "duiapplethandle.h" +#include "duiapplethandlemodel.h" +#include "duiapplethandlestyle.h" +#include "duiapplethandleview.h" +#include +#include + +class DuiAppletHandleGLESViewPrivate; + +//! \internal +/*! + * DuiAppletHandleGLESView is a view for the DuiAppletHandle that + * renders graphics using OpenGL where possible. + */ +class DuiAppletHandleGLESView : public DuiAppletHandleView +{ + Q_OBJECT + DUI_VIEW(DuiAppletHandleModel, DuiAppletHandleStyle) + +public: + /*! + * Constructs a DuiAppletHandleGLESView. + * + * \param appletHandle the DuiAppletHandle controller to be used + */ + DuiAppletHandleGLESView(DuiAppletHandle *appletHandle); + + /*! + * Destroys the DuiAppletHandleGLESView. + */ + virtual ~DuiAppletHandleGLESView(); + +private: + Q_DISABLE_COPY(DuiAppletHandleGLESView) + Q_DECLARE_PRIVATE(DuiAppletHandleGLESView) +}; + + +/*! + * Provides the uniforms required by DuiAppletHandleGLESView. + */ +class DUI_EXPORT DuiAppletHandleViewUniformProvider : public IDuiGLUniformProvider +{ +public: + /*! + * \brief Constructs a new DuiAppletHandleViewUniformProvider. + * + * \param width the width of the applet view, must be more than 0 + * \param height the height of the applet view, must be more than 0 + */ + DuiAppletHandleViewUniformProvider(float width, float height); + + /*! + * \brief Destroys the DuiAppletHandleViewUniformProvider. + */ + virtual ~DuiAppletHandleViewUniformProvider(); + + //! \reimp + virtual bool setUniformValue(const QString &name, const DuiGLShaderUniform &uniform); + //! \reimp_end + +private: + //! The width of the applet view + float width; + //! The height of the applet view + float height; +}; +//! \internal_end + +#endif // DUIAPPLETHANDLEGLESVIEW_H diff --git a/src/mashup/mashup/duiapplethandleglesview_p.h b/src/mashup/mashup/duiapplethandleglesview_p.h new file mode 100644 index 000000000..091f13641 --- /dev/null +++ b/src/mashup/mashup/duiapplethandleglesview_p.h @@ -0,0 +1,53 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETHANDLEGLESVIEW_P_H_ +#define DUIAPPLETHANDLEGLESVIEW_P_H_ + +#include "duiapplethandleview_p.h" + +class DuiAppletHandleGLESView; +class DuiAppletHandle; + +class DuiAppletHandleGLESViewPrivate : public DuiAppletHandleViewPrivate +{ + Q_DECLARE_PUBLIC(DuiAppletHandleGLESView) + +public: + DuiAppletHandleGLESViewPrivate(DuiAppletHandle *appletHandle); + virtual ~DuiAppletHandleGLESViewPrivate(); + + //! OpenGL texture id for the applet view + qint32 textureID; + + //! The applet pixmap with the broken state visuals applied + QPixmap brokenAppletPixmap; + + //! Deletes the pixmaps + virtual void destroyPixmaps(); + + //! Draws graphics on top of the applet to show the broken state. + virtual void drawAppletBrokenState(); + + //! \reimp + virtual void drawAppletPixmap(QPainter *painter, const QRectF &sourceGeometry, const QRectF &targetGeometry, bool brokenState) const; + //! \reimp_end +}; + +#endif /* DUIAPPLETHANDLEGLESVIEW_P_H_ */ diff --git a/src/mashup/mashup/duiapplethandlemodel.h b/src/mashup/mashup/duiapplethandlemodel.h new file mode 100644 index 000000000..5133cacf3 --- /dev/null +++ b/src/mashup/mashup/duiapplethandlemodel.h @@ -0,0 +1,90 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETHANDLEMODEL_H +#define DUIAPPLETHANDLEMODEL_H + +#include +#include + +class DuiAppletSharedMutex; +class DuiAppletSettings; + +//! \internal +class DuiAppletHandleModel : public DuiWidgetModel +{ + Q_OBJECT + DUI_MODEL_INTERNAL(DuiAppletHandleModel) + Q_ENUMS(AppletState) + +public: + /*! + * Different states where the applet life cycle can be. + */ + enum AppletState { + STOPPED, //!< The applet is stopped. This is the initial state for an installed applet + RUNNING, //!< The applet client has connected and the applet is fully functional + STARTING, //!< The applet process is starting + BROKEN, //!< The applet is broken + INSTALLING //!< The applet is currently being installed, so the handle is placeholder. + }; + +private: + /*! The state of the applet*/ + DUI_MODEL_PROPERTY(DuiAppletHandleModel::AppletState, state, State, true, STOPPED) + + /*! Current scaling factor of the applet, used for the view and event handling */ + DUI_MODEL_PROPERTY(qreal, appletScale, AppletScale, true, 1) + + /*! The icon ID of the applet */ + DUI_MODEL_PROPERTY(QString, appletIcon, AppletIcon, true, QString()) + + /*! The title of the applet */ + DUI_MODEL_PROPERTY(QString, appletTitle, AppletTitle, true, QString()) + + /*! The container text of the applet */ + DUI_MODEL_PROPERTY(QString, appletText, AppletText, true, QString()) + + //! DuiAppletSettings of the applet + DUI_MODEL_PTR_PROPERTY(DuiAppletSettings *, appletSettings, AppletSettings, true, NULL) + + //! The applet instance identifier given to the init() + DUI_MODEL_PROPERTY(DuiAppletId, appletId, AppletId, true, DuiAppletId()) + + //! The applet base name + DUI_MODEL_PROPERTY(QString, appletBaseName, AppletBaseName, true, QString()) + + //! A mutex for locking the pixmap + DUI_MODEL_PTR_PROPERTY(DuiAppletSharedMutex *, pixmapMutex, PixmapMutex, true, NULL) + + //! Size hints returned by the applet + DUI_MODEL_PROPERTY(QVector, sizeHints, SizeHints, true, QVector(Qt::NSizeHints, QSizeF(128, 128))) + + //! Applet installation progress status (percentage) + DUI_MODEL_PROPERTY(int, installationProgress, InstallationProgress, true, 0) + + //! Applet's package name to install from + DUI_MODEL_PROPERTY(QString, packageName, PackageName, true, QString()) + + //! Applet's installation error + DUI_MODEL_PROPERTY(QString, installationError, InstallationError, true, QString()) +}; +//! \internal_end + +#endif // DUIAPPLETHANDLEMODEL_H diff --git a/src/mashup/mashup/duiapplethandleswview.cpp b/src/mashup/mashup/duiapplethandleswview.cpp new file mode 100644 index 000000000..6c3765826 --- /dev/null +++ b/src/mashup/mashup/duiapplethandleswview.cpp @@ -0,0 +1,51 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include "duiviewcreator.h" +#include "duiapplethandle.h" +#include "duiapplethandleswview.h" +#include "duiapplethandleswview_p.h" + + +DuiAppletHandleSWViewPrivate::DuiAppletHandleSWViewPrivate(DuiAppletHandle *appletHandle) : + DuiAppletHandleViewPrivate(appletHandle) +{ +} + +DuiAppletHandleSWViewPrivate::~DuiAppletHandleSWViewPrivate() +{ +} + +void DuiAppletHandleSWViewPrivate::drawAppletPixmap(QPainter *painter, const QRectF &sourceGeometry, const QRectF &targetGeometry, bool) const +{ + // Draw the applet pixmap scaled so that it fits the screen + painter->drawPixmap(targetGeometry, localPixmap, sourceGeometry); +} + +DuiAppletHandleSWView::DuiAppletHandleSWView(DuiAppletHandle *appletHandle) : + DuiAppletHandleView(* new DuiAppletHandleSWViewPrivate(appletHandle), appletHandle) +{ +} + +DuiAppletHandleSWView::~DuiAppletHandleSWView() +{ +} + +DUI_REGISTER_VIEW_NEW(DuiAppletHandleSWView, DuiAppletHandle) diff --git a/src/mashup/mashup/duiapplethandleswview.h b/src/mashup/mashup/duiapplethandleswview.h new file mode 100644 index 000000000..942409598 --- /dev/null +++ b/src/mashup/mashup/duiapplethandleswview.h @@ -0,0 +1,59 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETHANDLESWVIEW_H +#define DUIAPPLETHANDLESWVIEW_H + +#include +#include "duiapplethandle.h" +#include "duiapplethandlemodel.h" +#include "duiapplethandleview.h" + +//! \internal +class DuiAppletHandleSWViewPrivate; + +/*! + * DuiAppletHandleSWView is a view for the DuiAppletHandle that + * renders graphics without OpenGL. + */ +class DuiAppletHandleSWView : public DuiAppletHandleView +{ + Q_OBJECT + DUI_VIEW(DuiAppletHandleModel, DuiAppletHandleStyle) + +public: + /*! + * Constructs a DuiAppletHandleSWView. + * + * \param appletHandle the DuiAppletHandle controller to be used + */ + DuiAppletHandleSWView(DuiAppletHandle *appletHandle); + + /*! + * Destroys the DuiAppletHandleSWView. + */ + virtual ~DuiAppletHandleSWView(); + +private : + Q_DISABLE_COPY(DuiAppletHandleSWView) + Q_DECLARE_PRIVATE(DuiAppletHandleSWView) +}; +//! \internal_end + +#endif // DUIAPPLETHANDLESWVIEW_H diff --git a/src/mashup/mashup/duiapplethandleswview_p.h b/src/mashup/mashup/duiapplethandleswview_p.h new file mode 100644 index 000000000..d4fb06ef6 --- /dev/null +++ b/src/mashup/mashup/duiapplethandleswview_p.h @@ -0,0 +1,41 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETHANDLESWVIEW_P_H_ +#define DUIAPPLETHANDLESWVIEW_P_H_ + +#include "duiapplethandleview_p.h" + +class DuiAppletHandleSWView; +class DuiAppletHandle; + +class DuiAppletHandleSWViewPrivate : public DuiAppletHandleViewPrivate +{ + Q_DECLARE_PUBLIC(DuiAppletHandleSWView) + +public: + DuiAppletHandleSWViewPrivate(DuiAppletHandle *appletHandle); + virtual ~DuiAppletHandleSWViewPrivate(); + + //! \reimp + virtual void drawAppletPixmap(QPainter *painter, const QRectF &sourceGeometry, const QRectF &targetGeometry, bool brokenState) const; + //! \reimp_end +}; + +#endif /* DUIAPPLETHANDLESWVIEW_P_H_ */ diff --git a/src/mashup/mashup/duiapplethandleview.cpp b/src/mashup/mashup/duiapplethandleview.cpp new file mode 100644 index 000000000..a861e41c4 --- /dev/null +++ b/src/mashup/mashup/duiapplethandleview.cpp @@ -0,0 +1,487 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiapplethandleview.h" +#include "duiapplethandleview_p.h" + +#include "duiaction.h" +#include "duiappletsharedmutex.h" +#include "duiprogressindicator.h" +#include "duimessagebox.h" +#include "duilocale.h" +#include "duibutton.h" +#include "duiappletsettingsdialog.h" +#include "duiappletsettings.h" +#include "duiscenemanager.h" + +#include +#include + +#ifdef Q_WS_X11 +#include +#endif + +DuiAppletHandleViewPrivate::DuiAppletHandleViewPrivate(DuiAppletHandle *appletHandle) : + appletHandle(appletHandle), + pixmapTakenIntoUse(NULL), + pixmapToBeTakenIntoUse(NULL), + pixmapSizeToBeTakenIntoUse(NULL), + progressIndicator(new DuiProgressIndicator(appletHandle)) +{ + // The progress indicator is not visible by default + progressIndicator->setVisible(false); +} + +DuiAppletHandleViewPrivate::~DuiAppletHandleViewPrivate() +{ + destroyPixmaps(); +} + +void DuiAppletHandleViewPrivate::connectSignals() +{ + Q_Q(DuiAppletHandleView); + + // Listen for pixmap taken into use signals + QObject::connect(appletHandle, SIGNAL(pixmapTakenIntoUse(Qt::HANDLE)), q, SLOT(pixmapTakenIntoUse(Qt::HANDLE))); + + // Listen for scene changed signals + QObject::connect(appletHandle, SIGNAL(appletPixmapModified(QRectF)), q, SLOT(appletPixmapModified(QRectF))); +} + +void DuiAppletHandleViewPrivate::destroyPixmaps() +{ + if (pixmapTakenIntoUse != NULL) { + delete pixmapTakenIntoUse; + pixmapTakenIntoUse = NULL; + } + if (pixmapToBeTakenIntoUse != NULL) { + delete pixmapToBeTakenIntoUse; + pixmapToBeTakenIntoUse = NULL; + } +} + +void DuiAppletHandleViewPrivate::showAppletBrokenDialog() +{ + Q_Q(DuiAppletHandleView); + + // the following use of translatable strings is not good. + // Splitting sentences like this makes it hard to translate them + // into language where the structure of the sentence is very + // different from English. + QString s; + QTextStream(&s) << + "" << + //~ uispec-document ??? FIXME + //% "The applet" + qtTrId("duiapplethandle_brokendialog_messagestart") << + " " << + q->model()->appletTitle() << + " " << + //~ uispec-document ??? FIXME + //% "is not functioning properly.
" + //% "Please select whether to restart or remove the applet." + qtTrId("duiapplethandle_brokendialog_messageend") << "
"; + + DuiMessageBox mb(s, Dui::NoStandardButton); + //~ uispec-document ??? FIXME + //% "Restart" + DuiButtonModel *restartButton = mb.addButton(qtTrId("duiapplethandle_brokendialog_restart")); + //~ uispec-document ??? FIXME + //% "Remove" + DuiButtonModel *removeButton = mb.addButton(qtTrId("duiapplethandle_brokendialog_remove")); + + controller->sceneManager()->execDialog(&mb); + + if (mb.clickedButton() == restartButton) { + appletHandle->reinit(); + } else if (mb.clickedButton() == removeButton) { + appletHandle->removeApplet(); + } +} + +void DuiAppletHandleViewPrivate::showAppletInstallationFailedDialog(const QString &error) +{ + Q_Q(DuiAppletHandleView); + + // the following use of translatable strings is not good. + // Splitting sentences like this makes it hard to translate them + // into language where the structure of the sentence is very + // different from English. + QString s; + QTextStream(&s) << + "" << + //~ uispec-document ??? FIXME + //% "The applet" + qtTrId("duiapplethandle_installationfaileddialog_messagestart") << + " " << + q->model()->appletTitle() << + " " << + //~ uispec-document ??? FIXME + //% "failed to install properly with the following error message:
" + qtTrId("duiapplethandle_installationfaileddialog_messagemiddle") << + error << + "
" << + //% "Please remove the applet." + qtTrId("duiapplethandle_installationfaileddialog_messageend") << "
"; + + DuiMessageBox mb(s, Dui::NoStandardButton); + //~ uispec-document ??? FIXME + //% "Remove" + DuiButtonModel *removeButton = mb.addButton(qtTrId("duiapplethandle_brokendialog_remove")); + + controller->sceneManager()->execDialog(&mb); + if (mb.clickedButton() == removeButton) { + appletHandle->removeApplet(); + } +} + +void DuiAppletHandleViewPrivate::resetView() +{ + destroyPixmaps(); + + // Reset the old geometry to force the applet pixmap ID to be sent to the applet + oldGeometry = QRectF(); +} + +void DuiAppletHandleViewPrivate::drawAppletBrokenState() +{ + Q_Q(DuiAppletHandleView); + + q->update(); +} + +void DuiAppletHandleViewPrivate::drawAppletPixmap(QPainter *, const QRectF &, const QRectF &, bool) const +{ +} + +QSizeF DuiAppletHandleViewPrivate::hostToAppletCoordinates(const QSizeF &size) const +{ + Q_Q(const DuiAppletHandleView); + + return size / q->model()->appletScale(); +} + +QSizeF DuiAppletHandleViewPrivate::appletToHostCoordinates(const QSizeF &size) const +{ + Q_Q(const DuiAppletHandleView); + + return size * q->model()->appletScale(); +} + +void DuiAppletHandleViewPrivate::calculateAppletScale() +{ + Q_Q(DuiAppletHandleView); + + // Set a scaling factor if the applet's minimum width is larger than the available width + const DuiAppletHandleStyleContainer *handleStyle = dynamic_cast(&q->style()); + if (handleStyle != NULL) { + qreal minimumWidth = q->model()->sizeHints().at(Qt::MinimumSize).width(); + qreal availableWidth = (*handleStyle)->maximumAppletSize().width(); + q->model()->setAppletScale(minimumWidth > availableWidth ? availableWidth / minimumWidth : 1); + } +} + +void DuiAppletHandleViewPrivate::appletSizeChanged(QSizeF size) +{ + if (pixmapToBeTakenIntoUse == NULL) { + // The pixmap to be taken into use has been taken into use. A new one can be allocated + allocatePixmapToBeTakenIntoUse(size); + } else { + // The pixmap to be taken into use has not been taken into use. + // The new size should be taken into use when the pixmap has been taken into use. + delete pixmapSizeToBeTakenIntoUse; + pixmapSizeToBeTakenIntoUse = new QSizeF(size); + } +} + +void DuiAppletHandleViewPrivate::allocatePixmapToBeTakenIntoUse(QSizeF size) +{ + // Allocate a new pixmap to be taken into use + QSizeF pixmapSize = size.expandedTo(QSizeF(1, 1)); + pixmapToBeTakenIntoUse = new QPixmap(pixmapSize.width(), pixmapSize.height()); + pixmapToBeTakenIntoUse->setAlphaChannel(*pixmapToBeTakenIntoUse); + + // Clear the pixmap + QPainter painter(pixmapToBeTakenIntoUse); + painter.setCompositionMode(QPainter::CompositionMode_Clear); + painter.fillRect(pixmapToBeTakenIntoUse->rect(), QColor(0, 0, 0, 0)); + + // Synchronize X to make sure the pixmap handle is now valid + QApplication::syncX(); + +// handle() is X11 specific +#ifdef Q_WS_X11 + // Communicate the new geometry and pixmap handle to be taken into use to the applet + appletHandle->sendGeometryMessage(QRectF(QPointF(), pixmapSize), pixmapToBeTakenIntoUse->handle()); +#endif +} + +void DuiAppletHandleViewPrivate::updateLocalPixmap() +{ + if (!pixmapModifiedRect.isEmpty() && pixmapTakenIntoUse != NULL && !pixmapTakenIntoUse->isNull()) { + Q_Q(DuiAppletHandleView); + + // Get the address of the pixmap mutex in shared memory and lock the mutex + DuiAppletSharedMutex *mutex = q->model()->pixmapMutex(); + if (mutex != NULL && mutex->tryLock()) { + // Mutex locked: copy the changed pixmap area to the local pixmap + if (!localPixmap.isNull()) { + QPainter painter(&localPixmap); + painter.setCompositionMode(QPainter::CompositionMode_Source); + painter.drawPixmap(pixmapModifiedRect, *pixmapTakenIntoUse, pixmapModifiedRect); + } + + // Unlock the pixmap mutex + mutex->unlock(); + + // Update the changed region + q->update(pixmapModifiedRect); + + // No modifications pending anymore + pixmapModifiedRect = QRectF(); + } + } +} + + + +DuiAppletHandleView::DuiAppletHandleView(DuiAppletHandle *appletHandle) : + DuiWidgetView(* new DuiAppletHandleViewPrivate(appletHandle), appletHandle) +{ + Q_D(DuiAppletHandleView); + + d->connectSignals(); +} + +DuiAppletHandleView::DuiAppletHandleView(DuiAppletHandleViewPrivate &dd, DuiAppletHandle *appletHandle) : + DuiWidgetView(dd, appletHandle) +{ + Q_D(DuiAppletHandleView); + + d->connectSignals(); +} + +DuiAppletHandleView::~DuiAppletHandleView() +{ +} + +void DuiAppletHandleView::setupModel() +{ + DuiWidgetView::setupModel(); + + // Let the view know what's the state of the model + QList m; + m << DuiAppletHandleModel::AppletScale; + m << DuiAppletHandleModel::State; + m << DuiAppletHandleModel::AppletSettings; + m << DuiAppletHandleModel::InstallationProgress; + updateData(m); +} + +void DuiAppletHandleView::openAppletSettings() +{ + if (model()->appletSettings() != NULL) { + DuiAppletSettingsDialog settingsDialog(*model()->appletSettings()); + settingsDialog.exec(); + } +} + +void DuiAppletHandleView::updateData(const QList& modifications) +{ + Q_D(DuiAppletHandleView); + + DuiWidgetView::updateData(modifications); + const char *member; + foreach(member, modifications) { + if (member == DuiAppletHandleModel::State) { + switch (model()->state()) { + case DuiAppletHandleModel::INSTALLING: + d->progressIndicator->setViewType(DuiProgressIndicator::barType); + d->progressIndicator->setRange(0, 100); + d->progressIndicator->setVisible(true); + d->progressIndicator->setUnknownDuration(false); + d->progressIndicator->setValue(model()->installationProgress()); + break; + case DuiAppletHandleModel::BROKEN: + d->progressIndicator->setVisible(false); + d->progressIndicator->setUnknownDuration(false); + d->drawAppletBrokenState(); + break; + case DuiAppletHandleModel::STARTING: + d->progressIndicator->setVisible(true); + d->progressIndicator->setUnknownDuration(true); + break; + case DuiAppletHandleModel::STOPPED: + d->progressIndicator->setVisible(false); + d->progressIndicator->setUnknownDuration(false); + break; + case DuiAppletHandleModel::RUNNING: + d->progressIndicator->setVisible(false); + d->progressIndicator->setUnknownDuration(false); + d->resetView(); + break; + } + } else if (member == DuiAppletHandleModel::AppletSettings) { + // If there's already an action for showing the applet settings, remove it + foreach(QAction * action, d->controller->actions()) { + //~ uispec-document ??? FIXME + //% "Settings" + if (action->text() == qtTrId("duiapplethandle_applet_settings")) { + d->controller->removeAction(action); + delete action; + } + } + if (model()->appletSettings() != NULL && model()->appletSettings()->hasSettings()) { + //~ uispec-document ??? FIXME + // Add an action for showing the applet settings + //% "Settings" + DuiAction *action = new DuiAction(qtTrId("duiapplethandle_applet_settings"), d->controller); + connect(action, SIGNAL(triggered(bool)), this, SLOT(openAppletSettings()), Qt::QueuedConnection); + d->controller->addAction(action); + } + } else if (member == DuiAppletHandleModel::InstallationProgress) { + d->progressIndicator->setValue(model()->installationProgress()); + } + } +} + +void DuiAppletHandleView::drawContents(QPainter *painter, const QStyleOptionGraphicsItem *) const +{ + Q_D(const DuiAppletHandleView); + + if (!d->localPixmap.isNull()) { + // If there are modifications to be copied to the local pixmap try to copy them + if (!d->pixmapModifiedRect.isEmpty()) { + const_cast(d)->updateLocalPixmap(); + } + + bool brokenState = model()->state() == DuiAppletHandleModel::BROKEN || model()->state() == DuiAppletHandleModel::STARTING; + if (brokenState) { + // In broken state use a specific opacity + painter->setOpacity(style()->brokenAppletOpacity()); + } + + // Draw the applet pixmap + QRectF source(d->localPixmap.rect()); + QRectF destination(QPointF(), d->appletToHostCoordinates(d->localPixmap.size())); + d->drawAppletPixmap(painter, source, destination, brokenState); + } + + if (model()->state() == DuiAppletHandleModel::BROKEN) { + const QPixmap *brokenAppletImage = style()->brokenAppletImage(); + if (brokenAppletImage != NULL) { + QPoint p(size().width() - brokenAppletImage->width(), 0); + p += style()->brokenAppletImageOffset(); + painter->setOpacity(1.0f); + painter->drawPixmap(p, *brokenAppletImage); + } + } +} + +void DuiAppletHandleView::setGeometry(const QRectF &rect) +{ + Q_D(DuiAppletHandleView); + + // rect is always between minimum and maximum applet size because the size hints have been + // bounded to these limits; calculate scaling factor if even the minimum size won't fit + d->calculateAppletScale(); + + // Get the old size and the new size + QSizeF oldSize = d->hostToAppletCoordinates(d->oldGeometry.size()); + QSizeF newSize = d->hostToAppletCoordinates(rect.size()); + + // Apply the geometry locally immediately + DuiWidgetView::setGeometry(rect); + d->oldGeometry = rect; + + // Check whether the new size differs from the old size + if (newSize != oldSize) { + d->appletSizeChanged(newSize); + } + + // Set the progress indicator position + QRectF progressIndicatorRect; + progressIndicatorRect.setSize(rect.size() * 0.5f); + progressIndicatorRect.moveCenter(rect.center() - rect.topLeft()); + d->progressIndicator->setGeometry(progressIndicatorRect); +} + +QRectF DuiAppletHandleView::boundingRect() const +{ + Q_D(const DuiAppletHandleView); + + // Use the (downscaled) applet size as the bounding rectangle + return QRectF(QPointF(), d->appletToHostCoordinates(d->localPixmap.size()).expandedTo(style()->minimumAppletSize()).boundedTo(style()->maximumAppletSize())); +} + +void DuiAppletHandleView::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + Q_D(DuiAppletHandleView); + + // TODO: this should actually be handled by a mouse click, but at the + // moment the base class doesn't contain such method... + if (event->button() == Qt::LeftButton) { + if (model()->state() == DuiAppletHandleModel::BROKEN && model()->installationError().isEmpty()) { + d->showAppletBrokenDialog(); + } else if (model()->state() == DuiAppletHandleModel::BROKEN && !model()->installationError().isEmpty()) { + d->showAppletInstallationFailedDialog(model()->installationError()); + } + } +} + +void DuiAppletHandleView::pixmapTakenIntoUse(Qt::HANDLE) +{ + Q_D(DuiAppletHandleView); + + // Delete the pixmap that was in use, mark the new one as taken into use + delete d->pixmapTakenIntoUse; + d->pixmapTakenIntoUse = d->pixmapToBeTakenIntoUse; + d->pixmapToBeTakenIntoUse = NULL; + d->localPixmap = d->pixmapTakenIntoUse->copy(); + + if (d->pixmapSizeToBeTakenIntoUse != NULL) { + // The applet pixmap has not been resized to the latest requested size so do it now + d->appletSizeChanged(*d->pixmapSizeToBeTakenIntoUse); + + // Size taken into use + delete d->pixmapSizeToBeTakenIntoUse; + d->pixmapSizeToBeTakenIntoUse = NULL; + } +} + +QSizeF DuiAppletHandleView::sizeHint(Qt::SizeHint which, const QSizeF &) const +{ + Q_D(const DuiAppletHandleView); + + // Return the requested size hint bounded to minimum and maximum applet sizes defined in the style + return d->appletToHostCoordinates(model()->sizeHints().at(which)).expandedTo(style()->minimumAppletSize()).boundedTo(style()->maximumAppletSize()); +} + +void DuiAppletHandleView::appletPixmapModified(const QRectF &rect) +{ + Q_D(DuiAppletHandleView); + + // Unite the changed rectangle with the previous changed rectangle + d->pixmapModifiedRect = rect.united(d->pixmapModifiedRect); + + // Update the local pixmap + d->updateLocalPixmap(); +} + +DUI_REGISTER_VIEW_NEW(DuiAppletHandleView, DuiAppletHandle) diff --git a/src/mashup/mashup/duiapplethandleview.h b/src/mashup/mashup/duiapplethandleview.h new file mode 100644 index 000000000..834761b5b --- /dev/null +++ b/src/mashup/mashup/duiapplethandleview.h @@ -0,0 +1,105 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETHANDLEVIEW_H +#define DUIAPPLETHANDLEVIEW_H + +#include +#include "duiapplethandle.h" +#include "duiapplethandlemodel.h" +#include "duiapplethandlestyle.h" + +class DuiAppletHandleViewPrivate; + +//! \internal +/*! + * DuiAppletHandleView is a view for the DuiAppletHandle that + * renders the applet's pixmap, shows whether the applet is in + * a broken state or not and displays a dialog if the applet + * is broken and the user taps it. + */ +class DuiAppletHandleView : public DuiWidgetView +{ + Q_OBJECT + DUI_VIEW(DuiAppletHandleModel, DuiAppletHandleStyle) + +public: + /*! + * Constructs a DuiAppletHandleView. + * + * \param appletHandle the DuiAppletHandle controller to be used + */ + DuiAppletHandleView(DuiAppletHandle *appletHandle); + + /*! + * Destroyes the DuiAppletHandleView. + */ + virtual ~DuiAppletHandleView(); + + //! \reimp + virtual void setGeometry(const QRectF &rect); + virtual QRectF boundingRect() const; + //! \reimp_end + +protected: + //! \reimp + virtual void drawContents(QPainter *painter, const QStyleOptionGraphicsItem *option) const; + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint) const; + //! \reimp_end + + /*! + * Constructs a DuiAppletHandleView. Should be used from derived classes. + * + * \param dd the private class + * \param appletHandle the DuiAppletHandle controller to be used + */ + DuiAppletHandleView(DuiAppletHandleViewPrivate &dd, DuiAppletHandle *appletHandle); + +protected slots: + //! \reimp + virtual void updateData(const QList& modifications); + //! \reimp_end + + //! \reimp + virtual void setupModel(); + //! \reimp_end + + /*! + * \brief A slot for receiving information about pixmaps that have been taken into use + */ + void pixmapTakenIntoUse(Qt::HANDLE pixmapHandle); + + /*! + * \brief A slot for processing the applet pixmap modifications + */ + void appletPixmapModified(const QRectF &rect); + + /*! + * \brief A slot for opening applet settings + */ + void openAppletSettings(); + +private : + Q_DISABLE_COPY(DuiAppletHandleView) + Q_DECLARE_PRIVATE(DuiAppletHandleView) +}; +//! \internal_end + +#endif // DUIAPPLETHANDLEVIEW_H diff --git a/src/mashup/mashup/duiapplethandleview_p.h b/src/mashup/mashup/duiapplethandleview_p.h new file mode 100644 index 000000000..c7ebe2176 --- /dev/null +++ b/src/mashup/mashup/duiapplethandleview_p.h @@ -0,0 +1,112 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETHANDLEVIEW_P_H_ +#define DUIAPPLETHANDLEVIEW_P_H_ + +#include "private/duiwidgetview_p.h" + +class DuiAppletHandleView; +class DuiAppletHandle; +class QPixmap; +class DuiProgressIndicator; + +class DuiAppletHandleViewPrivate : public DuiWidgetViewPrivate +{ + Q_DECLARE_PUBLIC(DuiAppletHandleView) + +public: + DuiAppletHandleViewPrivate(DuiAppletHandle *appletHandle); + virtual ~DuiAppletHandleViewPrivate(); + + //! The controller + DuiAppletHandle *appletHandle; + + //! A local copy of the latest applet pixmap + QPixmap localPixmap; + + //! The applet pixmap that has been taken into use + QPixmap *pixmapTakenIntoUse; + + //! The applet pixmap to be taken into use + QPixmap *pixmapToBeTakenIntoUse; + + //! The size for the pixmap not taken into use yet + QSizeF *pixmapSizeToBeTakenIntoUse; + + //! Progress indicator for showing feedback about various applet handle states + DuiProgressIndicator *progressIndicator; + + //! Unprocessed changed rectangle + QRectF pixmapModifiedRect; + + //! Previous geometry + QRectF oldGeometry; + + //! Connects the signals + void connectSignals(); + + //! Clears the view state for a newly initialized applet + void resetView(); + + //! Draws graphics on top of the applet to show the broken state. + virtual void drawAppletBrokenState(); + + //! Handles changes in the applet size + void appletSizeChanged(QSizeF size); + + //! Allocates a new applet pixmap to be taken into use + void allocatePixmapToBeTakenIntoUse(QSizeF size); + + //! Updates the local applet pixmap if necessary + void updateLocalPixmap(); + + /*! Shows a dialog for deciding what to do with a broken applet. */ + void showAppletBrokenDialog(); + + /*! Shows a dialog for deciding what to do with an installation failed applet. */ + void showAppletInstallationFailedDialog(const QString &error); + + /*! Deletes the pixmaps */ + virtual void destroyPixmaps(); + + //! Sends the geometry of the applet handle to the applet + void sendGeometryMessage(); + + /*! + * \brief Draw the contents of the applet pixmap + * + * \param painter the painter to draw with + * \param sourceGeometry the part of the applet pixmap to use + * \param targetGeometry the part of the target pixmap to draw to + * \param brokenState \c true if the applet pixmap should be drawn in a broken state, \c false otherwise + */ + virtual void drawAppletPixmap(QPainter *painter, const QRectF &sourceGeometry, const QRectF &targetGeometry, bool brokenState) const; + + //! Converts a size from host coordinates to applet coordinates + QSizeF hostToAppletCoordinates(const QSizeF &size) const; + + //! Converts a size from applet coordinates to host coordinates + QSizeF appletToHostCoordinates(const QSizeF &size) const; + + //! Calculates the applet scale based on the size hints and available size + void calculateAppletScale(); +}; + +#endif /* DUIAPPLETHANDLEVIEW_P_H_ */ diff --git a/src/mashup/mashup/duiappletid.cpp b/src/mashup/mashup/duiappletid.cpp new file mode 100644 index 000000000..7186c57ac --- /dev/null +++ b/src/mashup/mashup/duiappletid.cpp @@ -0,0 +1,74 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include "duiappletid.h" + +DuiAppletId::DuiAppletId() : + applicationName_(), + mashupCanvasName_(), + appletInstanceId(0) +{ +} + +DuiAppletId::DuiAppletId(const QString &applicationName, const QString &mashupCanvasName, const AppletInstanceID &instanceId) : + applicationName_(applicationName), + mashupCanvasName_(mashupCanvasName), + appletInstanceId(instanceId) +{ +} + +DuiAppletId::DuiAppletId(const QString &appletId) +{ + QStringList list = appletId.split('/'); + if (list.length() > 0) { + applicationName_ = list.at(0); + if (list.length() > 1) { + mashupCanvasName_ = list.at(1); + if (list.length() > 2) { + appletInstanceId = list.at(2).toUInt(); + } + } + } +} + +DuiAppletId::~DuiAppletId() +{ +} + +QString DuiAppletId::toString() const +{ + QString ret = applicationName_ + '/' + mashupCanvasName_ + '/' + QString::number(appletInstanceId); + return ret; +} + +QString DuiAppletId::applicationName() const +{ + return applicationName_; +} + +QString DuiAppletId::mashupCanvasName() const +{ + return mashupCanvasName_; +} + +DuiAppletId::AppletInstanceID DuiAppletId::instanceId() const +{ + return appletInstanceId; +} diff --git a/src/mashup/mashup/duiappletid.h b/src/mashup/mashup/duiappletid.h new file mode 100644 index 000000000..772a07b1b --- /dev/null +++ b/src/mashup/mashup/duiappletid.h @@ -0,0 +1,111 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETID_H +#define DUIAPPLETID_H + +#include + +//! \internal + +/*! + * \class DuiAppletId + * \brief DuiAppletId implements the applet instance identifier. + * It consists of application name, mashup canvas name and applet instance id. + * This class is used to uniquely identify an applet instance in the system. + * + */ +class DuiAppletId +{ +public: + //! Type for the applet instance ids. + typedef uint AppletInstanceID; + + /*! + * \brief Constructs DuiAppletId with empty application name, empty mashup canvas name and applet instance id 0 + */ + DuiAppletId(); + + /*! + * \brief Creates the DuiAppletId object with the given parameters + * \param applicationName Name of application that applet instance belongs to + * \param mashupCanvasName Applet mashup canvas name + * \param instanceId Applet instance id + */ + DuiAppletId(const QString &applicationName, const QString &mashupCanvasName, const AppletInstanceID &instanceId); + + /*! + * \brief Creates the DuiAppletId object from a string in + * <application name>/<mashup name>/<applet instance id> format. + * + * \param appletId the string to create a DuiAppletId from + */ + explicit DuiAppletId(const QString &appletId); + + /*! + * \brief Destructor + */ + virtual ~DuiAppletId(); + + /*! + * \brief Return the applet global identifier. + * The returned string will be of the format + * <application name>/<mashup name>/<applet instance id> + */ + QString toString() const; + + /*! + * \brief Returns the application name. + */ + QString applicationName() const; + + /*! + * \brief Returns the mashup canvas name. + */ + QString mashupCanvasName() const; + + /*! + * \brief Returns the applet instance id. + */ + AppletInstanceID instanceId() const; + + /*! + * Compares a DuiAppletId with another DuiAppletId + * + * \param other the DuiAppletId to compare to + * \return true if the DuiAppletIds differ, false otherwise + */ + inline bool operator!=(const DuiAppletId &other) const { + return other.applicationName_ != applicationName_ || other.mashupCanvasName_ != mashupCanvasName_ || other.appletInstanceId != appletInstanceId; + } + +private: + //! Name of the application + QString applicationName_; + + //! Mashup canvas for the applet instances + QString mashupCanvasName_; + + //! Applet instance id + AppletInstanceID appletInstanceId; +}; + +//! \internal_end + +#endif // DUIAPPLETID_H diff --git a/src/mashup/mashup/duiappletinstancedata.cpp b/src/mashup/mashup/duiappletinstancedata.cpp new file mode 100644 index 000000000..b4b749a44 --- /dev/null +++ b/src/mashup/mashup/duiappletinstancedata.cpp @@ -0,0 +1,43 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include "duiappletinstancedata.h" +#include "duiappletpackagemetadata.h" +#include "duiwidget.h" +#include "duifiledatastore.h" +#include "duisubdatastore.h" + +DuiAppletInstanceData::DuiAppletInstanceData() : + widget(NULL), + instanceDataStore(NULL), + mashupCanvasDataStore(NULL), + settingsDataAccess(NULL), + installationStatus(Unknown) +{ +} + +DuiAppletInstanceData::~DuiAppletInstanceData() +{ + delete widget; + delete instanceDataStore; + delete mashupCanvasDataStore; + delete settingsDataAccess; +} diff --git a/src/mashup/mashup/duiappletinstancedata.h b/src/mashup/mashup/duiappletinstancedata.h new file mode 100644 index 000000000..9f38cd845 --- /dev/null +++ b/src/mashup/mashup/duiappletinstancedata.h @@ -0,0 +1,86 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETINSTANCEDATA_H_ +#define DUIAPPLETINSTANCEDATA_H_ + +#include +#include "duiappletid.h" + +class DuiWidget; +class DuiFileDataStore; +class DuiSubDataStore; +class DuiDataAccess; +class DuiDataStore; +class DuiAppletHandle; + +//! \internal + +/*! + * A helper class for storing data about the applet instances. + */ +class DuiAppletInstanceData +{ +public: + enum InstallationStatus { + Unknown, + PlaceHolderRequired, + Installing, + Installed + }; + + /*! + * Constructs a new data object. + */ + DuiAppletInstanceData(); + + /*! + * Destructor. + */ + virtual ~DuiAppletInstanceData(); + + //! The id of the applet instance. + DuiAppletId appletId; + //! The desktop file of the applet. + QString desktopFile; + //! The name of the package the applet is being installed from. + QString packageName; + //! The title of the applet + QString title; + //! The size of the applet in landscape + QString sizeLandscape; + //! The size of the applet in portrait + QString sizePortrait; + //! The applet widget. + DuiWidget *widget; + //! The path where applet instances can store their instance data. + QString instanceDataFilePath; + //! The data store where applet instances can store their instance data. + DuiFileDataStore *instanceDataStore; + //! A data store that the mashup canvas can use to store layout etc. data about this applet instance. + DuiSubDataStore *mashupCanvasDataStore; + //! An interface for the applets to access their settings. + DuiDataAccess *settingsDataAccess; + //! Applet installation status + InstallationStatus installationStatus; +}; + +//! \internal_end + +#endif /* DUIAPPLETINSTANCEDATA_H_ */ diff --git a/src/mashup/mashup/duiappletinstancemanager.cpp b/src/mashup/mashup/duiappletinstancemanager.cpp new file mode 100644 index 000000000..497ea8cbf --- /dev/null +++ b/src/mashup/mashup/duiappletinstancemanager.cpp @@ -0,0 +1,608 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiappletinstancemanager.h" +#include "duiappletinstancemanagerdbusadaptor.h" +#include "duiappletinstancedata.h" +#include "duidatastore.h" +#include "duiappletmetadata.h" +#include "duiapplethandle.h" +#include "duifiledatastore.h" +#include "duigconfdatastore.h" +#include "duisubdatastore.h" +#include "duiappletloader.h" +#include "duiappletsettings.h" +#include "duiappletpackagemetadata.h" +#include "duiapplication.h" +#include "duiscenemanager.h" +#include "duiaction.h" + +const QString DuiAppletInstanceManager::PACKAGE_MANAGER_DBUS_SERVICE = "com.nokia.package_manager"; +const QString DuiAppletInstanceManager::PACKAGE_MANAGER_DBUS_PATH = "/com/nokia/package_manager"; +const QString DuiAppletInstanceManager::PACKAGE_MANAGER_DBUS_INTERFACE = "com.nokia.package_manager"; + +DuiAppletInstanceManager::DuiAppletInstanceManager(const QString &mashupCanvasName, DuiDataStore *dataStore) : + dataStore(NULL), + fileDataStore(NULL), + lastAppletInstanceID(1) +{ + init(mashupCanvasName, dataStore); +} + +DuiAppletInstanceManager::~DuiAppletInstanceManager() +{ + qDeleteAll(applets.values()); + delete fileDataStore; +} + +void DuiAppletInstanceManager::init(const QString &mashupCanvasName, DuiDataStore *dataStore) +{ + this->applicationName = QFileInfo(QCoreApplication::applicationFilePath()).fileName(); + this->mashupCanvasName = mashupCanvasName; + this->dataStore = dataStore; + + if (dataStore == NULL) { + // Create a file datastore if a data store was not provided + createDataStore(); + this->dataStore = fileDataStore; + } + + // Read applet data + readAppletData(); + + // Create a D-Bus service for this applet instance manager + new DuiAppletInstanceManagerDBusAdaptor(this); + + // Connect to D-Bus and register the DBus source as an object + QDBusConnection::sessionBus().registerObject("/DuiAppletInstanceManager/" + mashupCanvasName, this); + + // Connect to the system bus to receive the Package Manager signals + QDBusConnection::systemBus().connect(QString(), PACKAGE_MANAGER_DBUS_PATH, PACKAGE_MANAGER_DBUS_INTERFACE, "OperationComplete", this, SLOT(operationComplete(QString, QString, QString))); +} + +bool DuiAppletInstanceManager::restoreApplets() +{ + // Instantiate the applets + bool result = true; + foreach(DuiAppletInstanceData * data, applets) { + result &= instantiateApplet(data->appletId); + } + + return result; +} + +bool DuiAppletInstanceManager::instantiateApplet(const QString &desktopFile) +{ + // Create applet instance data from a .desktop file + DuiAppletId appletId = getUnusedAppletID(); + QMap appletInstantiationData; + appletInstantiationData.insert("desktopFile", desktopFile); + DuiAppletInstanceData *data = createAppletInstanceDataFromInstantiationData(appletId, appletInstantiationData); + applets.insert(appletId.instanceId(), data); + storeData(data); + + return instantiateApplet(appletId); +} + +void DuiAppletInstanceManager::instantiateAppletFromPackage(const QString &packageName, const QMap &metaData) +{ + // Create applet instance data from a package meta data + DuiAppletId appletId = getUnusedAppletID(); + QMap appletPackageMetaData(metaData); + appletPackageMetaData.insert(DuiAppletPackageMetaData::PACKAGE_KEY, packageName); + DuiAppletInstanceData *data = createAppletInstanceDataFromPackageMetaData(appletId, appletPackageMetaData); + applets.insert(appletId.instanceId(), data); + storeData(data); + + instantiateApplet(appletId); +} + +bool DuiAppletInstanceManager::removeApplet(DuiAppletId appletId) +{ + // Make sure the applet instance exists in this particular applet instance manager + if (appletId.applicationName() == applicationName && + appletId.mashupCanvasName() == mashupCanvasName && applets.contains(appletId.instanceId())) { + // Get the data for the applet + DuiAppletInstanceData *data = applets.value(appletId.instanceId()); + + // Let interested parties know that the applet's widget should be removed + emit appletRemoved(data->widget); + + // Remove the applet instance data + removeAppletInstanceData(appletId); + return true; + } + + return false; +} + +void DuiAppletInstanceManager::removeActionTriggered(bool) +{ + // Check which DuiAction has generated the event + DuiAction *action = qobject_cast(sender()); + if (action != NULL) { + // Go through the associated graphics widgets + foreach(QGraphicsWidget * w, action->associatedGraphicsWidgets()) { + // They're expected to be DUIWidgets + DuiWidget *widget = qobject_cast(w); + if (widget != NULL) { + // If an applet is found for the widget, remove it + DuiAppletId id = appletIDForWidget(widget); + + if (id != DuiAppletId()) { + removeApplet(id); + break; + } + } + } + } +} + +void DuiAppletInstanceManager::appletUninstalled(const QString &desktopFile) +{ + // Remove all instances of the applet that was uninstalled + foreach(const DuiAppletInstanceData * data, applets.values()) { + if (data->desktopFile == desktopFile) { + removeApplet(data->appletId); + } + } +} + +bool DuiAppletInstanceManager::instantiateApplet(DuiAppletId appletId) +{ + DuiAppletInstanceData *data = applets.value(appletId.instanceId()); + if (data != NULL) { + // There is no applet handle for the applet yet + QFile desktopFile(data->desktopFile); + if ((!data->desktopFile.isEmpty() && desktopFile.exists()) || data->installationStatus == DuiAppletInstanceData::Installing) { + // The desktop file exists, so the applet is installed or the applet was being installed: instantiate the applet + DuiAppletMetaData metadata(data->desktopFile); + if (metadata.isValid()) { + // Check whether a runner is defined + bool success; + if (metadata.runnerBinary().isEmpty()) { + // Runner not defined: create an in-process applet + success = instantiateInProcessApplet(data, metadata); + } else { + // Runner is defined: create an out-of-process applet + success = instantiateOutOfProcessApplet(data, metadata); + } + + if (success) { + // Notify that the applet placeholder instantiation is done + emit appletInstantiated(data->widget, *data->mashupCanvasDataStore); + return true; + } + } + } else if (!data->packageName.isEmpty()) { + // The package name is known + if (data->installationStatus == DuiAppletInstanceData::Unknown) { + // Installation status is not known: query installation status + queryInstallationStatus(data); + return true; + } else if (data->installationStatus == DuiAppletInstanceData::PlaceHolderRequired) { + // Placeholder is required: instantiate one and notify about it + instantiateAppletPlaceHolder(data); + emit appletInstantiated(data->widget, *data->mashupCanvasDataStore); + return true; + } + } + + // Instantiation failed: Remove related data + removeAppletInstanceData(appletId); + } + + return false; +} + +bool DuiAppletInstanceManager::instantiateOutOfProcessApplet(DuiAppletInstanceData *data, const DuiAppletMetaData &metadata) +{ + // Create an applet handle if one doesn't exist already + DuiAppletHandle *handle = dynamic_cast(data->widget); + if (handle == NULL) { + handle = new DuiAppletHandle; + data->widget = handle; + } else if (data->installationStatus != DuiAppletInstanceData::Installing) { + // Applet already instantiated + return true; + } + + // The applet is now installed + data->installationStatus = DuiAppletInstanceData::Installed; + + // Initialize the applet handle + handle->init(metadata.runnerBinary(), createAppletInstanceDataFileName(data->appletId), data->desktopFile, data->appletId); + handle->setAppletTitle(data->title); + setAppletHandleSizeHints(*handle, *data); + + // Clean up if the applet ended up in a broken state + if (handle->state() == DuiAppletHandleModel::BROKEN) { + delete handle; + data->widget = NULL; + return false; + } + + + // Listen to changes in the applet's title + connect(handle, SIGNAL(appletTitleChanged(QString)), SLOT(setAppletTitle(QString))); + + // Listen for removal requests + connect(handle, SIGNAL(appletRemovalRequested(DuiAppletId)), this, SLOT(removeApplet(DuiAppletId))); + + return true; +} + +bool DuiAppletInstanceManager::instantiateInProcessApplet(DuiAppletInstanceData *data, const DuiAppletMetaData &metadata) +{ + DuiFileDataStore *instanceDataStore = new DuiFileDataStore(data->instanceDataFilePath); + if (instanceDataStore->isReadable() && instanceDataStore->isWritable()) { + data->settingsDataAccess = new DuiGConfDataStore(QString()); + data->widget = DuiAppletLoader::loadApplet(metadata, *instanceDataStore, *data->settingsDataAccess); + data->instanceDataStore = instanceDataStore; + } else { + qWarning() << "Couldn't create applet instance data store"; + delete instanceDataStore; + return false; + } + + return true; +} + +void DuiAppletInstanceManager::instantiateAppletPlaceHolder(DuiAppletInstanceData *data) +{ + // Create and initialize a placeholder applet handle + DuiAppletHandle *handle = new DuiAppletHandle; + if (data->desktopFile.isEmpty()) { + //~ uispec-document ??? FIXME + //% "Could not get package meta data" + handle->initPlaceHolder(data->appletId, data->packageName, qtTrId("duiappletinstancedata_nopackagemetadata")); + } else { + handle->initPlaceHolder(data->appletId, data->packageName); + } + handle->setAppletTitle(data->title); + setAppletHandleSizeHints(*handle, *data); + + data->widget = handle; + data->installationStatus = DuiAppletInstanceData::Installing; + + // Listen for removal requests + connect(handle, SIGNAL(appletRemovalRequested(DuiAppletId)), this, SLOT(removeApplet(DuiAppletId))); +} + +void DuiAppletInstanceManager::queryInstallationStatus(DuiAppletInstanceData *data) +{ + QDBusInterface interface(DuiAppletInstanceManager::PACKAGE_MANAGER_DBUS_SERVICE, DuiAppletInstanceManager::PACKAGE_MANAGER_DBUS_PATH, DuiAppletInstanceManager::PACKAGE_MANAGER_DBUS_INTERFACE, QDBusConnection::systemBus()); + QDBusPendingCall call = interface.asyncCall("Operation", data->packageName); + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this); + watcher->setProperty("appletId", data->appletId.toString()); + connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher *)), this, SLOT(receiveOperation(QDBusPendingCallWatcher *))); +} + +void DuiAppletInstanceManager::createDataStore() +{ + QString dataPath = this->dataPath(); + QString dataStoreFileName = dataPath + mashupCanvasName + ".data"; + + if (!QFile::exists(dataStoreFileName)) { + // Copy the default datastore file as the user's datastore file if one doesn't exist yet + QString defaultDataStoreFileName = DUI_XDG_DIR "/" + applicationName + '/' + mashupCanvasName + ".data"; + + // Copy the default datastore only if it exists + if (QFile::exists(defaultDataStoreFileName)) { + // Create the user data directory if it doesn't exist yet + if (!QDir::root().exists(dataPath)) { + QDir::root().mkpath(dataPath); + } + + QFile::copy(defaultDataStoreFileName, dataStoreFileName); + } + } + + fileDataStore = new DuiFileDataStore(dataStoreFileName); +} + +void DuiAppletInstanceManager::readAppletData() +{ + // Gather all data related to each instance ID into a key-value map + QMap * > appletInstantiationDataForAppletId; + foreach(const QString & key, dataStore->allKeys()) { + if (isValidKey(key)) { + // Gather data only from valid keys + DuiAppletId::AppletInstanceID instanceId = appletInstanceIDFromKey(key); + + if (instanceId > 0) { + // Check if the key is supported + const static QStringList supportedParameters = (QStringList() << "desktopFile" << "packageName" << "title" << "sizeLandscape" << "sizePortrait"); + QString parameterName = getParameterName(key); + if (!supportedParameters.contains(parameterName)) { + qWarning() << "Invalid key" << key; + continue; + } + + // Find out whether there is already some data for this instance ID + QMap *appletInstantiationData = appletInstantiationDataForAppletId.value(instanceId); + if (appletInstantiationData == NULL) { + appletInstantiationData = new QMap; + appletInstantiationDataForAppletId.insert(instanceId, appletInstantiationData); + } + + // Update the data + appletInstantiationData->insert(getParameterName(key), dataStore->value(key).toString()); + } + } + } + + foreach(DuiAppletId::AppletInstanceID appletId, appletInstantiationDataForAppletId.keys()) { + // Create DuiAppletInstanceData objects from the key-value maps + DuiAppletInstanceData *data = createAppletInstanceDataFromInstantiationData(createAppletId(appletId), *appletInstantiationDataForAppletId.value(appletId)); + applets.insert(appletId, data); + } +} + +DuiAppletInstanceData *DuiAppletInstanceManager::createAppletInstanceDataFromInstantiationData(const DuiAppletId &appletId, const QMap &appletInstantiationData) +{ + DuiAppletInstanceData *data = new DuiAppletInstanceData; + data->appletId = appletId; + data->installationStatus = DuiAppletInstanceData::Unknown; + data->mashupCanvasDataStore = new DuiSubDataStore(createKey(appletId, PrivateDomain), *dataStore); + data->instanceDataFilePath = createAppletInstanceDataFileName(appletId); + data->packageName = appletInstantiationData.value("packageName").toString(); + data->desktopFile = appletInstantiationData.value("desktopFile").toString(); + data->title = appletInstantiationData.value("title").toString(); + data->sizeLandscape = appletInstantiationData.value("sizeLandscape").toString(); + data->sizePortrait = appletInstantiationData.value("sizePortrait").toString(); + return data; +} + +DuiAppletInstanceData *DuiAppletInstanceManager::createAppletInstanceDataFromPackageMetaData(const DuiAppletId &appletId, const QMap &packageMetaData) +{ + DuiAppletInstanceData *data = new DuiAppletInstanceData; + data->appletId = appletId; + data->installationStatus = DuiAppletInstanceData::PlaceHolderRequired; + data->mashupCanvasDataStore = new DuiSubDataStore(createKey(appletId, PrivateDomain), *dataStore); + data->instanceDataFilePath = createAppletInstanceDataFileName(appletId); + data->packageName = packageMetaData.value(DuiAppletPackageMetaData::PACKAGE_KEY).toString(); + data->desktopFile = packageMetaData.value(DuiAppletPackageMetaData::DESKTOP_FILE_KEY).toString(); + data->title = packageMetaData.value(DuiAppletPackageMetaData::APPLET_TITLE_KEY).toString(); + data->sizeLandscape = packageMetaData.value(DuiAppletPackageMetaData::APPLET_SIZE_LANDSCAPE_KEY).toString(); + data->sizePortrait = packageMetaData.value(DuiAppletPackageMetaData::APPLET_SIZE_PORTRAIT_KEY).toString(); + return data; +} + +void DuiAppletInstanceManager::setAppletHandleSizeHints(DuiAppletHandle &handle, DuiAppletInstanceData &data) +{ + // Set the size hints of the applet + DuiWindow *window = DuiApplication::activeWindow(); + if (window != NULL) { + DuiSceneManager *sceneManager = window->sceneManager(); + if (sceneManager != NULL) { + // Convert the size string to a QSizeF; it should be a non-zero size + QSizeF size = qStringToQSizeF(sceneManager->orientation() == Dui::Landscape ? data.sizeLandscape : data.sizePortrait); + if (!size.isEmpty()) { + // Set all size hints to the given size in the current orientation + QVector sizeHints; + sizeHints.append(size); + sizeHints.append(size); + sizeHints.append(size); + sizeHints.append(size); + handle.setSizeHints(sizeHints); + } + } + } +} + +QSizeF DuiAppletInstanceManager::qStringToQSizeF(const QString &string) +{ + // Use any non-digits as the separator + QStringList list = string.split(QRegExp("\\D+"), QString::SkipEmptyParts); + if (list.length() == 2) { + // There should be a valid width and a valid height + bool widthOk, heightOk; + qreal width = list.at(0).toFloat(&widthOk); + qreal height = list.at(1).toFloat(&heightOk); + if (widthOk && heightOk) { + return QSizeF(width, height); + } + } + + // Return an empty size on failure + return QSizeF(); +} + +QString DuiAppletInstanceManager::dataPath() const +{ + return QDir::homePath() + "/.config/" + applicationName + '/'; +} + +QString DuiAppletInstanceManager::createAppletInstanceDataFileName(DuiAppletId id) const +{ + return dataPath() + mashupCanvasName + '/' + QString::number(id.instanceId()) + ".data"; +} + +void DuiAppletInstanceManager::freeAppletInstanceID(DuiAppletId id) +{ + if (id.instanceId() < lastAppletInstanceID) { + lastAppletInstanceID = id.instanceId(); + } +} + +DuiAppletId DuiAppletInstanceManager::appletIDForWidget(DuiWidget *widget) const +{ + foreach(DuiAppletInstanceData * data, applets.values()) { + if (data->widget == widget) { + return data->appletId; + } + } + return DuiAppletId(); +} + +DuiAppletId DuiAppletInstanceManager::appletIDForPackageName(const QString &packageName) const +{ + foreach(DuiAppletInstanceData * data, applets.values()) { + if (data->packageName == packageName) { + return data->appletId; + } + } + return DuiAppletId(); +} + +DuiAppletId::AppletInstanceID DuiAppletInstanceManager::appletInstanceIDFromKey(const QString &key) +{ + // Convert the instance ID string to an integer + return key.left(key.indexOf('/')).toUInt(); +} + +void DuiAppletInstanceManager::removeAppletInstanceData(DuiAppletId appletId) +{ + // Make sure the applet instance exists + if (applets.contains(appletId.instanceId())) { + // Remove the applet instance from the applets map + DuiAppletInstanceData *data = applets.take(appletId.instanceId()); + + // Remove all keys from the data store that are related to the instance we are removing + QStringList keys(dataStore->allKeys()); + foreach(const QString & key, keys) { + if (appletInstanceIDFromKey(key) == appletId.instanceId()) { + dataStore->remove(key); + } + } + + // Remove the instance data file + QFile::remove(data->instanceDataFilePath); + + // Remove applet instance related settings + DuiAppletSettings settings(data->desktopFile, appletId); + settings.removeInstanceSettingValues(); + + // Destroy instance data + delete data; + + // Free the applet instance ID + freeAppletInstanceID(appletId); + } +} + +DuiAppletId DuiAppletInstanceManager::getUnusedAppletID() +{ + // Search for an unused applet ID + while (applets.contains(lastAppletInstanceID)) { + lastAppletInstanceID++; + } + + return createAppletId(lastAppletInstanceID); +} + +bool DuiAppletInstanceManager::isValidKey(const QString &key) +{ + // The key should be in instanceID/parameterName format + return key.count('/') == 1; +} + +QString DuiAppletInstanceManager::getParameterName(const QString &key) +{ + // Convert the parameter name + return key.mid(key.indexOf('/') + 1); +} + +QString DuiAppletInstanceManager::createKey(const DuiAppletId &appletId, KeyType type) +{ + QString ret; + + switch (type) { + case DesktopFile: + ret.sprintf("%d/desktopFile", appletId.instanceId()); + break; + case PackageName: + ret.sprintf("%d/packageName", appletId.instanceId()); + break; + case Title: + ret.sprintf("%d/title", appletId.instanceId()); + break; + case PrivateDomain: + ret.sprintf("%d/private/", appletId.instanceId()); + break; + } + + return ret; +} + +void DuiAppletInstanceManager::storeData(DuiAppletInstanceData *data) +{ + dataStore->createValue(createKey(data->appletId, DesktopFile), data->desktopFile); + dataStore->createValue(createKey(data->appletId, PackageName), data->packageName); + dataStore->createValue(createKey(data->appletId, Title), data->title); +} + +DuiAppletId DuiAppletInstanceManager::createAppletId(DuiAppletId::AppletInstanceID instanceId) const +{ + return DuiAppletId(applicationName, mashupCanvasName, instanceId); +} + +void DuiAppletInstanceManager::setAppletTitle(const QString &title) +{ + // Find the widget whose title has changed + DuiWidget *widget = dynamic_cast(sender()); + if (widget != NULL) { + foreach(DuiAppletInstanceData * data, applets.values()) { + if (data->widget == widget) { + // Set the title to the data and store the data + data->title = title; + storeData(data); + } + } + } +} + +void DuiAppletInstanceManager::operationComplete(const QString &operation, const QString &pkg, const QString &error) +{ + // If the installation of a package being installed succeeds instantiate it; errors are shown by the applet handle itself + if (operation == "Install" && error.isEmpty()) { + DuiAppletId appletId = appletIDForPackageName(pkg); + + if (appletId != DuiAppletId()) { + // Instantiate the applet based on the applet ID of the package + instantiateApplet(appletId); + } + } +} + +void DuiAppletInstanceManager::receiveOperation(QDBusPendingCallWatcher *watcher) +{ + if (watcher != NULL) { + DuiAppletId appletId(watcher->property("appletId").toString()); + DuiAppletInstanceData *data = applets.value(appletId.instanceId()); + if (data != NULL) { + // Figure out whether installation is in progress + bool installationInProgress = false; + QDBusPendingReply reply = *watcher; + if (!reply.isError()) { + installationInProgress = reply.argumentAt<0>() == "Install"; + } + + if (!installationInProgress) { + // Installation is not in progress: cause the placeholder to go to BROKEN state + data->desktopFile = QString(); + } + + // Instantiate the applet + data->installationStatus = DuiAppletInstanceData::PlaceHolderRequired; + instantiateApplet(appletId); + } + } +} diff --git a/src/mashup/mashup/duiappletinstancemanager.h b/src/mashup/mashup/duiappletinstancemanager.h new file mode 100644 index 000000000..b4521a7b3 --- /dev/null +++ b/src/mashup/mashup/duiappletinstancemanager.h @@ -0,0 +1,404 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETINSTANCEMANAGER_H_ +#define DUIAPPLETINSTANCEMANAGER_H_ + +#include "duiappletid.h" +#include +#include +#include + +class DuiWidget; +class DuiDataStore; +class DuiAppletInstanceData; +class DuiAppletMetaData; +class DuiAppletHandle; +class DuiFileDataStore; +class QDBusPendingCallWatcher; + +//! \internal + +/*! + * DuiAppletInstanceManager maintains currently running applets. + * + * DuiAppletInstanceManager ensures that data about running applet instances is stored in a permanent storage. + * DuiAppletInstanceManager can be used to instantiate new applets and remove existing applet instances. + * DuiAppletInstanceManager also monitors if out-of-process applets die or become unresponsive. If this occurs + * DuiAppletInstanceManager tries to first restart them but if that fails the applet instance is removed + * permanently from the manager. + * + * Other objects can observe state of the applet instance manager by subscribing to appletInstantiated + * and appletRemoved signals. + * + * DuiAppletInstanceManager uses a data store to store the information about instantiated applets and their data. + * The data store object is either given to the DuiAppletInstanceManager in the constructor or then the + * DuiAppletInstanceManager creates its own file-based data storing mechanism. User needs to provide a unique + * identifier to identify a DuiAppletInstanceManager object in application's context. + * + * \see \ref appletdevelopment + */ +class DuiAppletInstanceManager : public QObject +{ + Q_OBJECT + +public: + //! Type for the container that holds the applet data + typedef QHash AppletContainer; + //! An iterator type for the container that holds the applet data + typedef QHashIterator AppletContainerIterator; + + /*! + * Constructs a DuiAppletInstanceManager. + * + * \param identifier An identifier to identify this DuiAppletInstanceManager in this applications context. + * \param dataStore Instance of DuiDataStore class that is to be used as an interface + * to store information about applet instance data to and restore the data from. + * The ownership of dataStore is maintained by the caller. If no data store is provided, the + * DuiAppletInstanceManager will create a default file-system based data store. + */ + explicit DuiAppletInstanceManager(const QString &identifier, DuiDataStore *dataStore = NULL); + + /*! + * Destroys the DuiAppletInstanceManager. + */ + virtual ~DuiAppletInstanceManager(); + + /*! + * Restores applets from the permanent data store provided in the constructor. + * \return true if restoration succeeded, false otherwise. + */ + bool restoreApplets(); + + /*! + * Creates a new applet instance from the given applet metadata. + * \param metadataFile Metadata file which specificies the applet that is to be instantiated. + * \return true if the applet instantiation succeeded, false otherwise. + */ + bool instantiateApplet(const QString &metadataFile); + + /*! + * Installs an applet on the canvas from a software package. If the package + * is not yet installed, the mashup canvas starts monitoring the installation + * progress (but this method call returns). After the package installation is + * done an applet instantiation takes place. + * \param packageName the name of the package that contains the applet. + * \param metaData meta data for the applet package. + */ + void instantiateAppletFromPackage(const QString &packageName, const QMap &metaData); + +signals: + /*! + * Signals about a new instance of an applet. + * \param widget Pointer to DuiWidget that represents the new widget. + * \param store Reference to a DuiDataStore object given to clients listening to this signal. Through this DuiDataStore object + * clients can store their own data into permanent store that will be bound with the instantiated applet instance. + */ + void appletInstantiated(DuiWidget *widget, DuiDataStore &store) const; + + /*! + * Signals about a removal of an applet instance. + * \param widget Pointer to DuiWidget representation about the removed applet instance. + */ + void appletRemoved(DuiWidget *widget); + +public slots: + /*! + * removeActionTriggered is invoked when the user selects "Remove Applet" + * from the object menu of an applet. This will remove the applet. + * + * \param checked Not used. (true if the action is checked, false if the action is unchecked) + */ + void removeActionTriggered(bool checked); + + /*! + * \brief Called when a .desktop file that used to be present is removed + */ + void appletUninstalled(const QString &desktopFile); + + /*! + * Removes applet instance with the given instance ID. Does nothing if applet instance with the specified instance ID is not found. + * \param instanceId The ID of the instance to be removed. + */ + bool removeApplet(DuiAppletId appletId); + +private slots: + /*! + * Slot for listening to operation complete signals from the Package Manager + * + * \param operation Name of the operation. Possible names are: Install, Uninstall and Upgrade + * \param pkg Name of the package that operation is performed on + * \param error Empty if operation was successful, DBus error name otherwise + */ + void operationComplete(const QString &operation, const QString &pkg, const QString &error); + + /*! + * Sets the applet's title to a new value in the sending widget's applet data + * + * \param title the new title + */ + void setAppletTitle(const QString &title); + + /*! + * Figures out whether installation is in progress from the received + * Operation and instantiate the applet placeholder with relevant + * data accordingly + * + * \param watcher the call watcher + */ + void receiveOperation(QDBusPendingCallWatcher *watcher); + +private: + /*! + * Initializes the instance manager. + * + * \param mashupCanvasName the name of the mashup canvas that this manager is part of. + * \param dataStore the data store to be used for storing the applet instance related data. + */ + void init(const QString &mashupCanvasName, DuiDataStore *dataStore); + + /*! + * Instantiates the applet with the given ID. + * + * \param appletId the ID of the applet to be instantiated + * \return true if the applet instantiation succeeded, false otherwise. + */ + bool instantiateApplet(DuiAppletId appletId); + + /*! + * Instantiates an out of process applet from the given data. + * + * \param data applet instance data to instantiate applet from + * \param metadata meta data for the applet + * \return true if the applet instantiation succeeded, false otherwise. + */ + bool instantiateOutOfProcessApplet(DuiAppletInstanceData *data, const DuiAppletMetaData &metadata); + + /*! + * Instantiates an in process applet from the given data. + * + * \param data applet instance data to instantiate applet from + * \param metadata meta data for the applet + * \return true if the applet instantiation succeeded, false otherwise. + */ + bool instantiateInProcessApplet(DuiAppletInstanceData *data, const DuiAppletMetaData &metadata); + + /*! + * Instantiates a placeholder for the applet with the given data. + * + * \param data applet instance data to instantiate applet placeholder from + */ + void instantiateAppletPlaceHolder(DuiAppletInstanceData *data); + + /*! + * Queries installation status of an applet with the given data. + * This calls the Package Manager method "Operation" with the + * package name of the applet. The result is expected to be + * returned to the receiveOperation() function. + * + * \param data applet instance data of the applet whose installation status is to be queried + */ + void queryInstallationStatus(DuiAppletInstanceData *data); + + /*! + * Creates a data store for the instance manager. If the data store does + * not already exist on disk a default data store is copied if one exists. + */ + void createDataStore(); + + /*! + * Reads applet data from the instance manager's data store. + */ + void readAppletData(); + + /*! + * Creates DuiAppletInstanceData objects from applet instantiation data + * read from the data file. + * + * \param appletId the ID of the applet instance + * \param appletInstantiationData key-value pairs read from a data file for an applet instance + * \return DuiAppletInstanceData object for the data + */ + DuiAppletInstanceData *createAppletInstanceDataFromInstantiationData(const DuiAppletId &appletId, const QMap &appletInstantiationData); + + /*! + * Creates DuiAppletInstanceData objects from package metadata. + * + * \param appletId the ID of the applet instance + * \param packageMetaData package metadata for the applet package + * \return DuiAppletInstanceData object for the data + */ + DuiAppletInstanceData *createAppletInstanceDataFromPackageMetaData(const DuiAppletId &appletId, const QMap &packageMetaData); + + /*! + * Sets the size hints of the given applet handle as defined in the given data. + * + * \param handle the DuiAppletHandle whose size hints should be set + * \param data the DuiAppletInstanceData to get the size hints from + */ + static void setAppletHandleSizeHints(DuiAppletHandle &handle, DuiAppletInstanceData &data); + + /*! + * Converts a size string to a QSizeF. Any non-digits are used as separators between a width and a height. + * + * \param string the string to be converted + * \return the given string as a QSizeF or an empty QSizeF() if the operation fails + */ + static QSizeF qStringToQSizeF(const QString &string); + + /*! + * Returns a common data file path that the applet instance manager should use + * for storing data files. + * + * \return data file path used by the applet instance manager + */ + QString dataPath() const; + + /*! + * Returns a file name for an applet instance data file. Every applet instance + * has an own data file so the applet instance id is used to separate these. + * + * \param id the ID of the applet to get instance data file name for + * \return instance data file name for the applet with the given ID + */ + QString createAppletInstanceDataFileName(DuiAppletId id) const; + + /*! + * Frees an applet instance ID for later use. + * + * \param the applet instance ID to mark unused + */ + void freeAppletInstanceID(DuiAppletId id); + + /*! + * Returns the Applet ID for a widget + * + * \return the Applet ID of the widget or an empty ID if the widget does not belong to an applet + */ + DuiAppletId appletIDForWidget(DuiWidget *widget) const; + + /*! + * Returns the Applet ID for a package name + * + * \return the Applet ID for a package name or an empty ID if the package name does not match an applet + */ + DuiAppletId appletIDForPackageName(const QString &packageName) const; + + /*! + * Gets the applet instance ID from a settings file key + * + * \param key the key to get the applet instance ID from + * \return the applet instance ID or 0 if it is not valid + */ + static DuiAppletId::AppletInstanceID appletInstanceIDFromKey(const QString &key); + + /*! + * Removes all temporary data related to an applet instance. + * This includes applet instance data and applet instance related settings. + * After a call to this method the applet instance can't basically be restored + * any more. + * \param appletId the ID of the applet instance which data is to be removed. + */ + void removeAppletInstanceData(DuiAppletId appletId); + + /*! + * Returns an unused applet ID + * + * \return an unused applet ID + */ + DuiAppletId getUnusedAppletID(); + + /*! + * Checks whether a settings file key is valid (is in instanceID/parameterName format) + * + * \param key the key to check for validity + * \return true if the settings file key is in instanceID/parameterName format + */ + static bool isValidKey(const QString &key); + + /*! + * Gets the parameter name from a settings file key + * + * \param key the key to get the parameter name from + * \return the parameter name + */ + static QString getParameterName(const QString &key); + + /*! + * Key types for the data stored about applet instances by the applet instance manager. + */ + enum KeyType { + DesktopFile, //!< The desktop file of the applet. + PackageName, //!< The name of the package the applet is being installed from. + Title, //!< The title of the applet. + PrivateDomain //!< Key prefix for applet instance namespece. + }; + + /*! + * Generates a data store key from instance id and type of the key. + */ + static QString createKey(const DuiAppletId &appletId, KeyType type); + + /*! + * Stores the data in the given DuiAppletInstanceData object to a permanent store. + * This will store only the data that is permanent. + * + * \param data the DuiAppletInstanceData to be stored to permanent data storage. + */ + void storeData(DuiAppletInstanceData *data); + + /*! + * \brief Creates the DuiAppetId for the applet instance + * \param instanceId Applet instance id + */ + DuiAppletId createAppletId(DuiAppletId::AppletInstanceID instanceId) const; + + //! The name of the application this applet instance manager belongs to + QString applicationName; + + //! The unique name of the mashup canvas this applet instance manager is associated to in the application's context + QString mashupCanvasName; + + //! DuiDataStore object used to store and restore applet instance data + DuiDataStore *dataStore; + + //! Default file data store used, if user provides no DuiDataStore. + DuiFileDataStore *fileDataStore; + + //! A map for keeping track of running applets + AppletContainer applets; + + //! The last applet ID that used to be free + DuiAppletId::AppletInstanceID lastAppletInstanceID; + + //! D-Bus service of the Package Manager + static const QString PACKAGE_MANAGER_DBUS_SERVICE; + + //! D-Bus path of the Package Manager + static const QString PACKAGE_MANAGER_DBUS_PATH; + + //! D-Bus interface of the Package Manager + static const QString PACKAGE_MANAGER_DBUS_INTERFACE; + + Q_DISABLE_COPY(DuiAppletInstanceManager) +}; + +//! \internal_end + +#endif /* DUIAPPLETINSTANCEMANAGER_H_ */ diff --git a/src/mashup/mashup/duiappletinstancemanagerdbusadaptor.cpp b/src/mashup/mashup/duiappletinstancemanagerdbusadaptor.cpp new file mode 100644 index 000000000..b29b76f78 --- /dev/null +++ b/src/mashup/mashup/duiappletinstancemanagerdbusadaptor.cpp @@ -0,0 +1,41 @@ +/* + * This file was generated by qdbusxml2cpp version 0.7 + * Command line was: qdbusxml2cpp duiappletinstancemanagerdbusinterface.xml -a duiappletinstancemanagerdbusadaptor -c DuiAppletInstanceManagerDBusAdaptor -l DuiAppletInstanceManager -i duiappletinstancemanager.h + * + * qdbusxml2cpp is Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#include "duiappletinstancemanagerdbusadaptor.h" +#include +#include +#include +#include +#include +#include +#include + +/* + * Implementation of adaptor class DuiAppletInstanceManagerDBusAdaptor + */ + +DuiAppletInstanceManagerDBusAdaptor::DuiAppletInstanceManagerDBusAdaptor(DuiAppletInstanceManager *parent) + : QDBusAbstractAdaptor(parent) +{ + // constructor + setAutoRelaySignals(true); +} + +DuiAppletInstanceManagerDBusAdaptor::~DuiAppletInstanceManagerDBusAdaptor() +{ + // destructor +} + +void DuiAppletInstanceManagerDBusAdaptor::instantiateAppletFromPackage(const QString &packageName, const QMap &metaData) +{ + // handle method call org.maemo.dui.DuiAppletInstanceManager.instantiateAppletFromPackage + parent()->instantiateAppletFromPackage(packageName, metaData); +} + diff --git a/src/mashup/mashup/duiappletinstancemanagerdbusadaptor.h b/src/mashup/mashup/duiappletinstancemanagerdbusadaptor.h new file mode 100644 index 000000000..986d50315 --- /dev/null +++ b/src/mashup/mashup/duiappletinstancemanagerdbusadaptor.h @@ -0,0 +1,55 @@ +/* + * This file was generated by qdbusxml2cpp version 0.7 + * Command line was: qdbusxml2cpp duiappletinstancemanagerdbusinterface.xml -a duiappletinstancemanagerdbusadaptor -c DuiAppletInstanceManagerDBusAdaptor -l DuiAppletInstanceManager -i duiappletinstancemanager.h + * + * qdbusxml2cpp is Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#ifndef DUIAPPLETINSTANCEMANAGERDBUSADAPTOR_H_1265801264 +#define DUIAPPLETINSTANCEMANAGERDBUSADAPTOR_H_1265801264 + +#include +#include +#include "duiappletinstancemanager.h" +class QByteArray; +template class QList; +template class QMap; +class QString; +class QStringList; +class QVariant; + +/* + * Adaptor class for interface org.maemo.dui.DuiAppletInstanceManager + */ +class DuiAppletInstanceManagerDBusAdaptor: public QDBusAbstractAdaptor +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "org.maemo.dui.DuiAppletInstanceManager") + Q_CLASSINFO("D-Bus Introspection", "" + " \n" + " \n" + " \" name=\"com.trolltech.QtDBus.QtTypeName.In1\"/>\n" + " \n" + " \n" + " \n" + " \n" + "") +public: + DuiAppletInstanceManagerDBusAdaptor(DuiAppletInstanceManager *parent); + virtual ~DuiAppletInstanceManagerDBusAdaptor(); + + inline DuiAppletInstanceManager *parent() const { + return static_cast(QObject::parent()); + } + +public: // PROPERTIES +public Q_SLOTS: // METHODS + void instantiateAppletFromPackage(const QString &packageName, const QMap &metaData); +Q_SIGNALS: // SIGNALS +}; + +#endif diff --git a/src/mashup/mashup/duiappletinstancemanagerdbusinterface.xml b/src/mashup/mashup/duiappletinstancemanagerdbusinterface.xml new file mode 100644 index 000000000..2944b691d --- /dev/null +++ b/src/mashup/mashup/duiappletinstancemanagerdbusinterface.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/mashup/mashup/duiappletinventory.cpp b/src/mashup/mashup/duiappletinventory.cpp new file mode 100644 index 000000000..b0b9f6e49 --- /dev/null +++ b/src/mashup/mashup/duiappletinventory.cpp @@ -0,0 +1,276 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include +#include "duiappletinventory.h" +#include "duiappletinventorymodel.h" +#include "duiappletinstancemanager.h" +#include "duiappletbutton.h" +#include "duimashupcanvas.h" +#include "duiappletinstallationsourceinterface.h" +#include "private/duiwidgetcontroller_p.h" +#include "duiappletinstantiator.h" + +#include "duiwidgetcreator.h" +DUI_REGISTER_WIDGET_NO_CREATE(DuiAppletInventory) + +DuiAppletInventory::DuiAppletInventory(QGraphicsItem *parent) : + DuiWidgetController(new DuiWidgetControllerPrivate, new DuiAppletInventoryModel, parent), + mashupCanvas(NULL), + watcher(new QFileSystemWatcher()), + appletPath(APPLET_DATA), + initialized(false) +{ +} + +DuiAppletInventory::~DuiAppletInventory() +{ + // Destroy the installation sources + foreach(DuiWidget * w, model()->installationSources()) { + delete w; + } + + // Destroy the remaining applet buttons + foreach(DuiWidget * w, model()->widgets()) { + delete w; + } + + delete watcher; +} + +void DuiAppletInventory::initializeIfNecessary() +{ + if (!initialized) { + // Create installation source widgets + createInstallationSourceWidgets(); + + // Verify that the applet .desktop file path exists and is readable + if (appletPath.exists() && appletPath.isReadable()) { + // Start monitoring the applet desktop file path + watcher->addPath(appletPath.absolutePath()); + + if (watcher->directories().contains(appletPath.absolutePath())) { + connect(watcher, SIGNAL(directoryChanged(QString)), this, SLOT(appletPathChanged(QString))); + + // Trigger the first applet path refresh manually + appletPathChanged(appletPath.absolutePath()); + } + } + + // The applet inventory has now been initialized + initialized = true; + } +} + +void DuiAppletInventory::setMashupCanvas(DuiMashupCanvas &mashupCanvas) +{ + this->mashupCanvas = &mashupCanvas; +} + +void DuiAppletInventory::setCategories(const QStringList &categories) +{ + if (appletCategories != categories) { + appletCategories = categories; + + // If the applet inventory has already been initialized re-read the installation path + if (initialized && appletPath.exists() && appletPath.isReadable()) { + appletPathChanged(appletPath.absolutePath()); + } + } +} + +QStringList DuiAppletInventory::categories() const +{ + return appletCategories; +} + +void DuiAppletInventory::appletButtonClicked() +{ + DuiAppletButton *button = dynamic_cast(sender()); + Q_ASSERT(button != NULL); + + mashupCanvas->appletInstanceManager()->instantiateApplet(button->metadataFilename()); + emit hideAppletInventory(); +} + +void DuiAppletInventory::appletPathChanged(const QString &path) +{ + Q_UNUSED(path); + Q_ASSERT(appletPath.absolutePath() == path); + + // Move all widgets from the model to the old widgets list + QList oldWidgets(model()->widgets()); + + // Go through the applets and create applet buttons of them in this container + QList widgets; + QStringList filter; + filter << "*.desktop"; + foreach(const QString & fileName, appletPath.entryList(filter, QDir::Files)) { + const QString metadataFilename = QFileInfo(appletPath, fileName).absoluteFilePath(); + DuiAppletMetaData metadata(metadataFilename); + + // If no categories have been defined all applet buttons should be shown + bool appletShouldBeShown = appletCategories.empty(); + + if (!appletCategories.empty()) { + // If categories have been defined only applets belonging in any of the defined categories should be shown + foreach(const QString & category, metadata.categories()) { + appletShouldBeShown = appletCategories.contains(category); + if (appletShouldBeShown) { + break; + } + } + } + + // Check if there was already a button for the applet + bool alreadyAdded = false; + foreach(DuiWidget * w, oldWidgets) { + DuiAppletButton *b = dynamic_cast(w); + if (b != NULL && b->metadataFilename() == metadataFilename && appletShouldBeShown) { + // Applet button already created - put it back in the widget list + widgets.append(w); + + // Remove from the old widgets list + oldWidgets.removeOne(w); + + // Don't create a new button + alreadyAdded = true; + break; + } + } + + if (!alreadyAdded && appletShouldBeShown) { + // No button for this applet found in the model + DuiAppletButton *appletButton = new DuiAppletButton(NULL); + appletButton->setViewType("icon"); + if (appletButton->initialize(metadata)) { + connect(appletButton, SIGNAL(clicked()), this, SLOT(appletButtonClicked())); + widgets.append(appletButton); + } else { + delete appletButton; + } + } + } + + // Let the view know about the new widget list + model()->setWidgets(widgets); + + // Send a signal about each applet that is no longer installed + foreach(DuiWidget * w, oldWidgets) { + DuiAppletButton *b = dynamic_cast(w); + if (b != NULL) { + emit appletUninstalled(b->metadataFilename()); + } + + // Destroy the applet button. This MUST be done AFTER the widget has been removed from the layout. + delete w; + } +} + +void DuiAppletInventory::setEnabled(bool enabled) +{ + if (enabled) { + // Initialize the applet inventory if necessary + initializeIfNecessary(); + } + + DuiWidgetController::setEnabled(enabled); + + // Show or hide the button + model()->setCloseButtonVisible(enabled); +} + +void DuiAppletInventory::createInstallationSourceWidgets() +{ + // Destroy the existing installation sources + foreach(DuiWidget * w, model()->installationSources()) { + delete w; + } + + QList sourceWidgets; + + // Load the installation sources + QStringList sourcePaths = installationSourceBinaryPaths(); + foreach(const QString & path, sourcePaths) { + DuiWidget *widget = loadAppletInstallationSource(path); + if (widget) { + sourceWidgets.append(widget); + } + } + + model()->setInstallationSources(sourceWidgets); +} + +void DuiAppletInventory::setInstallationSources(const QStringList &installationSources) +{ + if (this->installationSources != installationSources) { + this->installationSources = installationSources; + + if (initialized) { + // If the applet inventory has already been initialized, create installation source widgets + createInstallationSourceWidgets(); + } + } +} + +QStringList DuiAppletInventory::installationSourceBinaryPaths() const +{ + QStringList sourcePaths; + + foreach(const QString & sourceName, installationSources) { + QFileInfo source(QString(APPLET_INSTALLATION_SOURCES), sourceName); + if (source.exists() && source.isFile()) { + sourcePaths.append(source.absoluteFilePath()); + } else { + duiDebug("DuiAppletInventory") << "applet source" << source.absoluteFilePath() << "does not exist!"; + } + } + + return sourcePaths; +} + +DuiWidget *DuiAppletInventory::loadAppletInstallationSource(const QString &path) +{ + QPluginLoader loader(path); + QObject *object = loader.instance(); + + DuiAppletInstallationSourceInterface *source = qobject_cast(object); + DuiWidget *widget = NULL; + if (source != NULL) { + widget = source->constructWidget(); + if (widget) { + const QMetaObject *mob = widget->metaObject(); + + // connect signals from widget to the applet inventory + if (mob->indexOfSignal("packageSelectedForInstallation(QString)") != -1) { + QObject::connect(widget, SIGNAL(packageSelectedForInstallation(QString)), this, SLOT(instantiateAppletsFromPackage(QString))); + } + } + } + delete object; + return widget; +} + +void DuiAppletInventory::instantiateAppletsFromPackage(const QString &packageName) +{ + DuiAppletInstantiator::instance()->instantiateAppletsInPackage(packageName, mashupCanvas->serviceAddress()); + emit hideAppletInventory(); +} diff --git a/src/mashup/mashup/duiappletinventory.h b/src/mashup/mashup/duiappletinventory.h new file mode 100644 index 000000000..cf34e944b --- /dev/null +++ b/src/mashup/mashup/duiappletinventory.h @@ -0,0 +1,191 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETINVENTORY_H +#define DUIAPPLETINVENTORY_H + +#include +#include +#include "duiappletinventorymodel.h" + +class QFileSystemWatcher; +class DuiWidget; +class DuiMashupCanvas; + +//! \internal + +/*! + * DuiAppletInventory is a widget that maintains collection of available + * applets and instantiates new instances of those applets. + * + * DuiAppletInventory will start to monitor an applet path after + * setEnabled(true) is called. When active, all applets that are available in + * the inventory are visualised as instantiable options in this inventory + * widget. + * + * User can instantiate applets from an DuiAppletInventory by selecting them. + * When an applet is instantiated from DuiAppletInventory the widget + * of the applet is added to the DuiMashupCanvas container that is specified in + * the call to the setMashupCanvas() method. + * + * Available applets are defined as .desktop metadata files in + * /usr/share/applications/dui/applets. The files conform to the + * freedesktop.org desktop file format. + */ + +class DuiAppletInventory : public DuiWidgetController +{ + Q_OBJECT + DUI_CONTROLLER(DuiAppletInventory) + +public: + /*! + * Constructs an DuiAppletInventory widget. + * + * \param parent the parent widget of the DuiAppletInventory, defaults to NULL + */ + DuiAppletInventory(QGraphicsItem *parent = NULL); + + /*! + * Destroys the DuiAppletInventory. + */ + virtual ~DuiAppletInventory(); + + /*! + * Sets the mashup canvas to add instantiated applet widgets to. + * + * \param mashupCanvas The mashup canvas to add instantiated applet widgets to. + */ + void setMashupCanvas(DuiMashupCanvas &mashupCanvas); + + /*! + * Sets the applet categories available in this applet inventory. + * The default value for the categories is an empty list. This + * means filtering by categories is disabled and all applets are + * shown in the applet inventory. + * + * \param categories a list of names of the applet categories to show in this applet inventory. + */ + void setCategories(const QStringList &categories); + + /*! + * Gets the applet categories available in this applet inventory. + * + * \return a list of names of the applet categories to show in this applet inventory. + */ + QStringList categories() const; + + /*! + * If enabled is true, the applet inventory is enabled (items can be clicked, button is visible); otherwise, it is disabled. + * + * The applet inventory is disabled by default. + * + * \param enabled if true, the applet inventory is enabled; otherwise, it is disabled + */ + void setEnabled(bool enabled); + + /*! + * Sets the names of the installation sources to show in the inventory + * \param installationSources a list of the source names + */ + void setInstallationSources(const QStringList &installationSources); + +signals: + /*! + * \brief Called when a .desktop file that used to be present is removed + */ + void appletUninstalled(const QString &desktopFile); + + /*! + * \brief Emitted when the applet inventory should be hidden + */ + void hideAppletInventory(); + +private slots: + /*! + * Called when the applet binary path has changed. + * + * \param path Path that has changed (should be the applet binary path) + */ + void appletPathChanged(const QString &path); + + /*! + * Called when the user clicks an applet button + */ + void appletButtonClicked(); + + /*! + * Called to instantiate applets from a package + * + * \param packageName the name of the applet package to be instantiated + */ + void instantiateAppletsFromPackage(const QString &packageName); + +private: + /*! + * Initalizes the applet inventory if necessary. + * Connects applet inventory to a DuiMashupCanvas widget set using + * setMashupCanvas and starts monitoring the applet metadata files. + */ + void initializeIfNecessary(); + + /*! + * Loads and instantiates an applet installation source from the given library + * \param path the path to the library + * \return the installation source widget + */ + DuiWidget *loadAppletInstallationSource(const QString &path); + + /*! + * Creates the applet installation source widgets and stores them into the model + */ + void createInstallationSourceWidgets(); + + /*! + * Returns a list of paths to the available installation source binaries + * \return a list of absolute file paths + */ + QStringList installationSourceBinaryPaths() const; + + //! Mashup canvas for the applet instances + DuiMashupCanvas *mashupCanvas; + + //! File system watcher to monitor changes in the applet binary directory + QFileSystemWatcher *watcher; + + //! Plugin binary path + QDir appletPath; + + //! A list of names of the applet categories to show in this applet inventory. An empty list will show all applets. + QStringList appletCategories; + + //! A list of installation source names + QStringList installationSources; + + //! Whether the applet inventory has been initialized or not + bool initialized; + +#ifdef UNIT_TEST + friend class Ut_DuiAppletInventory; +#endif +}; + +//! \internal_end + +#endif // DUIAPPLETINVENTORY_H diff --git a/src/mashup/mashup/duiappletinventorymodel.h b/src/mashup/mashup/duiappletinventorymodel.h new file mode 100644 index 000000000..074c965bd --- /dev/null +++ b/src/mashup/mashup/duiappletinventorymodel.h @@ -0,0 +1,47 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETINVENTORYMODEL_H_ +#define DUIAPPLETINVENTORYMODEL_H_ + +#include "duiwidgetmodel.h" + +class DuiWidget; + +//! \internal +typedef QList WidgetList; + +class DuiAppletInventoryModel : public DuiWidgetModel +{ + Q_OBJECT + DUI_MODEL_INTERNAL(DuiAppletInventoryModel) + +private: + //! The list of widgets in the applet inventory + DUI_MODEL_PROPERTY(WidgetList, widgets, Widgets, true, WidgetList()) + + //! The list of installation source widgets + DUI_MODEL_PROPERTY(WidgetList, installationSources, InstallationSources, true, WidgetList()) + + //! Whether the close button should be visible or not + DUI_MODEL_PROPERTY(bool, closeButtonVisible, CloseButtonVisible, true, false) +}; +//! \internal_end + +#endif /* DUIAPPLETINVENTORYMODEL_H_ */ diff --git a/src/mashup/mashup/duiappletinventoryview.cpp b/src/mashup/mashup/duiappletinventoryview.cpp new file mode 100644 index 000000000..08b38c6e1 --- /dev/null +++ b/src/mashup/mashup/duiappletinventoryview.cpp @@ -0,0 +1,171 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "duiappletinventory.h" +#include "duiappletinventoryview.h" +#include "duiappletinventoryview_p.h" + +DuiAppletInventoryViewPrivate::DuiAppletInventoryViewPrivate() : + controller(NULL), + layout(new DuiLayout), + layoutPolicy(new DuiLinearLayoutPolicy(layout, Qt::Vertical)), + appletLayout(new DuiLayout), + appletLayoutPolicy(new DuiFlowLayoutPolicy(appletLayout)), + appletContainer(NULL), + closeButtonOverlay(new DuiOverlay), + closeButton(new DuiButton(closeButtonOverlay)) +{ +} + +DuiAppletInventoryViewPrivate::~DuiAppletInventoryViewPrivate() +{ + delete closeButtonOverlay; +} + +void DuiAppletInventoryViewPrivate::init(DuiAppletInventory *controller) +{ + this->controller = controller; + + // Create a container for the applets + //~ uispec-document ??? FIXME + //% "Applets" + appletContainer = new DuiContainer(qtTrId("duiappletinventoryview_appletcontainer"), controller); + appletContainer->setObjectName("DuiAppletInventoryAppletContainer"); + appletContainer->centralWidget()->setLayout(appletLayout); + appletLayout->setContentsMargins(0, 0, 0, 0); + appletLayoutPolicy->setObjectName("DuiAppletInventoryFlowLayoutPolicy"); + + // Define layout properties + controller->setLayout(layout); + layout->setContentsMargins(0, 0, 0, 0); + layoutPolicy->setObjectName("DuiAppletInventoryLinearLayoutPolicy"); + layoutPolicy->addItem(appletContainer); + + // Set close button properties + closeButton->setViewType("icon"); + closeButton->setObjectName("DuiAppletInventoryCloseButton"); + closeButton->setIconID("Icon-close"); + QObject::connect(closeButton, SIGNAL(clicked()), controller, SIGNAL(hideAppletInventory())); + + closeButtonOverlay->setObjectName("DuiAppletInventoryCloseButtonOverlay"); +} + +DuiAppletInventoryView::DuiAppletInventoryView(DuiAppletInventory *container) : + DuiExtendingBackgroundView(* new DuiAppletInventoryViewPrivate, container) +{ + Q_D(DuiAppletInventoryView); + d->init(container); +} + +DuiAppletInventoryView::~DuiAppletInventoryView() +{ +} + +void DuiAppletInventoryView::updateData(const QList& modifications) +{ + Q_D(const DuiAppletInventoryView); + + DuiExtendingBackgroundView::updateData(modifications); + const char *member; + foreach(member, modifications) { + if (member == DuiAppletInventoryModel::Widgets) { + // Remove all widgets from the layout (do not destroy them) + while (d->appletLayout->count() > 0) { + d->appletLayout->removeAt(0); + } + + // Add widgets from the model to the layout + foreach(DuiWidget * widget, model()->widgets()) { + d->appletLayoutPolicy->addItem(widget); + } + } else if (member == DuiAppletInventoryModel::CloseButtonVisible) { + // Set the visibility of the button + if (model()->closeButtonVisible()) { + d->controller->sceneManager()->showWindow(d->closeButtonOverlay); + } else { + d->controller->sceneManager()->hideWindow(d->closeButtonOverlay); + } + } else if (member == DuiAppletInventoryModel::InstallationSources) { + // Remove any existing source containers + foreach(DuiContainer * container, installationSourceContainers) { + d->layoutPolicy->removeItem(container); + delete container; + } + + // Create containers for the source widgets + installationSourceContainers.clear(); + foreach(DuiWidget * widget, model()->installationSources()) { + DuiContainer *sourceContainer = new DuiContainer(d->controller); + installationSourceContainers.append(sourceContainer); + sourceContainer->setObjectName("DuiAppletInventorySourceContainer"); + sourceContainer->setCentralWidget(widget); + connectContainerToInstallationSource(sourceContainer, widget); + d->layoutPolicy->addItem(sourceContainer); + } + } + } +} + +void DuiAppletInventoryView::connectContainerToInstallationSource(DuiContainer *container, DuiWidget *sourceWidget) const +{ + const QMetaObject *mob = sourceWidget->metaObject(); + + // use properties to fill header of the container + int iconProperty = mob->indexOfProperty("installationSourceIcon"); + int titleProperty = mob->indexOfProperty("installationSourceTitle"); + int textProperty = mob->indexOfProperty("installationSourceText"); + + if (iconProperty != -1) { + container->setIconID((mob->property(iconProperty).read(sourceWidget)).toString()); + } + + if (titleProperty != -1) { + container->setTitle((mob->property(titleProperty).read(sourceWidget)).toString()); + container->setHeaderVisible(true); + } + + if (textProperty != -1) { + container->setText((mob->property(textProperty).read(sourceWidget)).toString()); + } + + // connect signals from source to the container + if (mob->indexOfSignal("installationSourceIconChanged(QString)") != -1) { + QObject::connect(sourceWidget, SIGNAL(installationSourceIconChanged(QString)), container, SLOT(setIconID(QString))); + } + + if (mob->indexOfSignal("installationSourceTitleChanged(QString)") != -1) { + QObject::connect(sourceWidget, SIGNAL(installationSourceTitleChanged(QString)), container, SLOT(setTitle(QString))); + } + + if (mob->indexOfSignal("installationSourceTextChanged(QString)") != -1) { + QObject::connect(sourceWidget, SIGNAL(installationSourceTextChanged(QString)), container, SLOT(setText(QString))); + } +} + + +DUI_REGISTER_VIEW_NEW(DuiAppletInventoryView, DuiAppletInventory) diff --git a/src/mashup/mashup/duiappletinventoryview.h b/src/mashup/mashup/duiappletinventoryview.h new file mode 100644 index 000000000..4f00514d9 --- /dev/null +++ b/src/mashup/mashup/duiappletinventoryview.h @@ -0,0 +1,76 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETINVENTORYVIEW_H +#define DUIAPPLETINVENTORYVIEW_H + +#include +#include "duiappletinventorystyle.h" +#include "duiappletinventorymodel.h" + +class DuiAppletInventory; +class DuiAppletInventoryViewPrivate; +class DuiContainer; + +//! \internal +/*! + * The applet inventory view manages a layout related to the applet inventory. + * The widgets are inside a flow layout. The view also contains a close button + * for closing the container. + */ +class DuiAppletInventoryView : public DuiExtendingBackgroundView +{ + Q_OBJECT + DUI_VIEW(DuiAppletInventoryModel, DuiAppletInventoryStyle) + +public: + /*! + * Constructs a DuiAppletInventoryView. + * + * \param controller the DuiAppletInventory controller to be used + */ + DuiAppletInventoryView(DuiAppletInventory *controller); + + /*! + * Destroys the DuiAppletInventoryView. + */ + virtual ~DuiAppletInventoryView(); + +private slots: + //! \reimp + virtual void updateData(const QList& modifications); + //! \reimp_end + +private: + Q_DISABLE_COPY(DuiAppletInventoryView) + Q_DECLARE_PRIVATE(DuiAppletInventoryView) + + /*! + * Configures various attributes of a container according to properties in a installation source widget + * \param container the container to configure + * \param sourceWidget the installation source widget + */ + void connectContainerToInstallationSource(DuiContainer *container, DuiWidget *sourceWidget) const; + + //! List of applet installation source container widgets displayed on the inventory + QList installationSourceContainers; +}; +//! \internal_end + +#endif // DUIAPPLETINVENTORYVIEW_H diff --git a/src/mashup/mashup/duiappletinventoryview_p.h b/src/mashup/mashup/duiappletinventoryview_p.h new file mode 100644 index 000000000..cb4107bc8 --- /dev/null +++ b/src/mashup/mashup/duiappletinventoryview_p.h @@ -0,0 +1,83 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETINVENTORYVIEW_P_H_ +#define DUIAPPLETINVENTORYVIEW_P_H_ + +#include "private/duiextendingbackgroundview_p.h" + +class DuiAppletInventory; +class DuiLayout; +class DuiFlowLayoutPolicy; +class DuiLinearLayoutPolicy; +class DuiButton; +class DuiOverlay; +class DuiContainer; + +/*! + * The private class for DuiAppletInventoryView. + */ +class DuiAppletInventoryViewPrivate : public DuiExtendingBackgroundViewPrivate +{ + Q_DECLARE_PUBLIC(DuiAppletInventoryView) + +public: + /*! + * Creates an instance of DuiAppletInventoryViewPrivate. + */ + DuiAppletInventoryViewPrivate(); + + /*! + * Destroys the DuiAppletInventoryViewPrivate. + */ + virtual ~DuiAppletInventoryViewPrivate(); + + /*! + * Initializes the private class. + * + * \param controller the DuiAppletInventory for the view + */ + void init(DuiAppletInventory *controller); + + //! The DuiAppletInventory controller + DuiAppletInventory *controller; + + //! A layout for the inventory + DuiLayout *layout; + + //! A linear layout policy for the inventory + DuiLinearLayoutPolicy *layoutPolicy; + + //! A layout for the applet widgets + DuiLayout *appletLayout; + + //! A flow layout policy for the widgets + DuiFlowLayoutPolicy *appletLayoutPolicy; + + //! A container for the applet widgets + DuiContainer *appletContainer; + + //! An overlay for the close button + DuiOverlay *closeButtonOverlay; + + //! A close button + DuiButton *closeButton; +}; + +#endif /* DUIAPPLETINVENTORYVIEW_P_H_ */ diff --git a/src/mashup/mashup/duiappletloader.cpp b/src/mashup/mashup/duiappletloader.cpp new file mode 100644 index 000000000..69ddb69d2 --- /dev/null +++ b/src/mashup/mashup/duiappletloader.cpp @@ -0,0 +1,46 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiappletloader.h" + +#include "duiappletinterface.h" +#include "duiwidget.h" +#include "duiappletmetadata.h" +#include "duidataaccess.h" + +#include + +DuiAppletLoader::DuiAppletLoader() +{ +} + +DuiWidget *DuiAppletLoader::loadApplet(const DuiAppletMetaData &metadata, DuiDataStore &dataStore, DuiDataAccess &settings) +{ + QPluginLoader loader(metadata.appletBinary()); + QObject *object = loader.instance(); + + DuiAppletInterface *applet = qobject_cast(object); + DuiWidget *widget = NULL; + if (applet != NULL) { + widget = applet->constructWidget(metadata, dataStore, settings); + } + delete object; + return widget; +} + diff --git a/src/mashup/mashup/duiappletloader.h b/src/mashup/mashup/duiappletloader.h new file mode 100644 index 000000000..dfe0b7e28 --- /dev/null +++ b/src/mashup/mashup/duiappletloader.h @@ -0,0 +1,54 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETLOADER_H +#define DUIAPPLETLOADER_H + +#include "duiexport.h" + +class DuiAppletMetaData; +class DuiWidget; +class DuiDataStore; +class DuiDataAccess; + +/*! + * \brief A class that loads Dui applets. + */ +class DUI_EXPORT DuiAppletLoader +{ +public: + /*! + * Loads an applet according to an applet metadata object. + * The ownership of the returned applet widget is transfered to the caller. + * \param metadata the metadata that is used to load the applet. + * \param dataStore a data store object where applet instances can store their instance specific data. + * \param settings a data store object that bundles applet settings to the applet. + * \return the applet widget or \c NULL in an error. + */ + static DuiWidget *loadApplet(const DuiAppletMetaData &metadata, DuiDataStore &dataStore, DuiDataAccess &settings); + +private: + /*! + * A private default constructor so no objects of this class can be created. + */ + DuiAppletLoader(); + +}; + +#endif // DUIAPPLETLOADER_H diff --git a/src/mashup/mashup/duiappletpackagemetadata.h b/src/mashup/mashup/duiappletpackagemetadata.h new file mode 100644 index 000000000..e2a463e44 --- /dev/null +++ b/src/mashup/mashup/duiappletpackagemetadata.h @@ -0,0 +1,43 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETPACKAGEMETADATA_H_ +#define DUIAPPLETPACKAGEMETADATA_H_ + +#include + +//! \internal +namespace DuiAppletPackageMetaData +{ + //! Name of the package name key + const QString PACKAGE_KEY = "Package"; + //! Name of the .desktop file name key + const QString DESKTOP_FILE_KEY = "Maemo-Desktop-File"; + //! Name of the applet title key + const QString APPLET_TITLE_KEY = "Maemo-Applet-Title"; + //! Name of the applet size in portrait key + const QString APPLET_SIZE_PORTRAIT_KEY = "Maemo-Applet-Size-Portrait"; + //! Name of the applet size in landscape key + const QString APPLET_SIZE_LANDSCAPE_KEY = "Maemo-Applet-Size-Landscape"; + //! Name of the icon key + const QString ICON_KEY = "Maemo-Icon"; +} +//! \internal_end + +#endif /* DUIAPPLETPACKAGEMETADATA_H_ */ diff --git a/src/mashup/mashup/duiappletsettings.cpp b/src/mashup/mashup/duiappletsettings.cpp new file mode 100644 index 000000000..fd424435d --- /dev/null +++ b/src/mashup/mashup/duiappletsettings.cpp @@ -0,0 +1,179 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiappletsettings.h" +#include "duisettingslanguageparser.h" +#include "duiaggregatedataaccess.h" +#include +#include + +#include +#include +#include +#include + + +/* +Implementation note: + +This class's implementation uses lazy evaluation. The returned +values/objects from the query methods of the class are only constructed when they +are needed for the first time. That's why most of the private member variables of +this class are marked as mutable - they are changed inside const methods. There are +flags (...Uptodate) that track the validity of the objects. Those flags should be +used to mark when changes to some objects are needed. +*/ + +DuiAppletSettings::DuiAppletSettings(const QString &metaDataFileName, const DuiAppletId &appletId) : + instanceSettingsBinaryObject(NULL), + instanceSettingsBinaryUptodate(false), + globalSettingsBinaryObject(NULL), + globalSettingsBinaryUptodate(false), + settingsAggregate(NULL), + instanceGConfDataStore(NULL), + globalGConfDataStore(NULL) +{ + init(metaDataFileName, appletId.toString()); +} + +DuiAppletSettings::DuiAppletSettings(const QString &metaDataFileName, const QString &appletId) : + instanceSettingsBinaryObject(NULL), + instanceSettingsBinaryUptodate(false), + globalSettingsBinaryObject(NULL), + globalSettingsBinaryUptodate(false), + settingsAggregate(NULL), + instanceGConfDataStore(NULL), + globalGConfDataStore(NULL) +{ + init(metaDataFileName, appletId); +} + +void DuiAppletSettings::init(const QString &metaDataFileName, const QString &appletId) +{ + QString appletBaseName = QFileInfo(metaDataFileName).baseName(); + QFileInfo fileInfo(QDir(QString(APPLET_SETTINGS_DIR)), appletBaseName); + QString settingsFileStub = fileInfo.absoluteFilePath(); + + instanceSettingsFileName = settingsFileStub + "-instance.xml"; + globalSettingsFileName = settingsFileStub + "-global.xml"; + + instanceGConfPrefix = QString("/apps/") + appletId; + globalGConfPrefix = QString("/apps/") + appletBaseName; + + // Load the applet's translation catalog for translating settings titles + DuiAppletMetaData metaData(metaDataFileName); + DuiLocale locale; + locale.installTrCatalog(metaData.resourceIdentifier()); + DuiLocale::setDefault(locale); +} + +DuiAppletSettings::~DuiAppletSettings() +{ + delete globalSettingsBinaryObject; + delete instanceSettingsBinaryObject; + deleteDataStores(); +} + +const DuiSettingsLanguageBinary *DuiAppletSettings::instanceSettingsBinary() const +{ + ensureSettingsBinaryObjectUptodate(instanceSettingsBinaryUptodate, &instanceSettingsBinaryObject, instanceSettingsFileName); + return instanceSettingsBinaryObject; +} + +const DuiSettingsLanguageBinary *DuiAppletSettings::globalSettingsBinary() const +{ + ensureSettingsBinaryObjectUptodate(globalSettingsBinaryUptodate, &globalSettingsBinaryObject, globalSettingsFileName); + return globalSettingsBinaryObject; +} + +bool DuiAppletSettings::hasSettings() const +{ + return instanceSettingsBinary() != NULL || globalSettingsBinary() != NULL; +} + +void DuiAppletSettings::deleteDataStores() const +{ + delete settingsAggregate; + delete instanceGConfDataStore; + delete globalGConfDataStore; + settingsAggregate = NULL; + instanceGConfDataStore = NULL; + globalGConfDataStore = NULL; +} + +void DuiAppletSettings::createDataStoresIfNeeded() const +{ + if (instanceGConfDataStore == NULL || globalGConfDataStore == NULL || settingsAggregate == NULL) { + // Delete any previous data store + deleteDataStores(); + + instanceGConfDataStore = new DuiGConfDataStore(instanceGConfPrefix); + globalGConfDataStore = new DuiGConfDataStore(globalGConfPrefix); + settingsAggregate = new DuiAggregateDataAccess(*instanceGConfDataStore, *globalGConfDataStore); + } +} + +DuiDataStore *DuiAppletSettings::instanceDataStore() const +{ + createDataStoresIfNeeded(); + + return instanceGConfDataStore; +} + +DuiDataStore *DuiAppletSettings::globalDataStore() const +{ + createDataStoresIfNeeded(); + + return globalGConfDataStore; +} + +DuiDataAccess *DuiAppletSettings::dataAccess() const +{ + createDataStoresIfNeeded(); + + return settingsAggregate; +} + +void DuiAppletSettings::removeInstanceSettingValues() const +{ + createDataStoresIfNeeded(); + + if (instanceGConfDataStore) { + instanceGConfDataStore->clear(); + } +} + +void DuiAppletSettings::ensureSettingsBinaryObjectUptodate(bool &settingsBinaryUptodate, + DuiSettingsLanguageBinary **settingsBinaryObjectPointer, + const QString &settingsFileName) +{ + if (!settingsBinaryUptodate) { + // Delete any previous object + delete *settingsBinaryObjectPointer; + *settingsBinaryObjectPointer = NULL; + + // Convert the settings XML to a settings binary + QFile xmlFile(settingsFileName); + DuiSettingsLanguageParser parser; + if (parser.readFrom(xmlFile)) { + *settingsBinaryObjectPointer = parser.createSettingsBinary(); + } + settingsBinaryUptodate = true; + } +} diff --git a/src/mashup/mashup/duiappletsettings.h b/src/mashup/mashup/duiappletsettings.h new file mode 100644 index 000000000..61caa4d72 --- /dev/null +++ b/src/mashup/mashup/duiappletsettings.h @@ -0,0 +1,161 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETSETTINGS_H +#define DUIAPPLETSETTINGS_H + +#include +#include "duiexport.h" + +class DuiSettingsLanguageBinary; +class DuiGConfDataStore; +class DuiAppletId; +class DuiAggregateDataAccess; +class DuiDataAccess; +class DuiDataStore; + +/*! + * \class DuiAppletSettings + * This class handles parsing of the applet instance and global settings files + * and creation of settings binaries. + */ +class DUI_EXPORT DuiAppletSettings +{ +public: + /*! + * Constructs a DuiAppletSettings object. + * \param metaDataFileName Name of the applet metadata file + * \param appletId The applet's id + */ + DuiAppletSettings(const QString &metaDataFileName, const DuiAppletId &appletId); + + /*! + * Constructs a DuiAppletSettings object. + * \param metaDataFileName Name of the applet metadata file + * \param appletId The applet's id as a string with the form + * applicationName/mashupCanvasName/instanceid, for example: + * myapp/canvas1/1 + */ + DuiAppletSettings(const QString &metaDataFileName, const QString &appletId); + + /*! + * \brief Destructor + */ + virtual ~DuiAppletSettings(); + + /*! + * Gets the DuiSettingsLanguageBinary object for the instance + * settings. Returns \c NULL if the applet has no instance settings. + * \return the applet instance settings binary. + */ + const DuiSettingsLanguageBinary *instanceSettingsBinary() const; + + /*! + * Gets the DuiSettingsLanguageBinary object for the global + * settings. Returns \c NULL if the applet has no global settings. + * \return the applet global settings binary. + */ + const DuiSettingsLanguageBinary *globalSettingsBinary() const; + + /*! + * Returns \c true if applet has settings (either instance or global or both), \c false otherwise. + * \return a boolean telling whether applet has settings or not. + */ + bool hasSettings() const; + + /*! + * Returns the datastore for the applet instance settings. + * Returns \c NULL if the applet has no settings. + */ + DuiDataStore *instanceDataStore() const; + + /*! + * Returns the datastore for the applet global settings. + * Returns \c NULL if the applet has no settings. + */ + DuiDataStore *globalDataStore() const; + + /*! + * Returns a data access for the applet global and instance settings. + * Returns \c NULL if the applet has no settings. + */ + DuiDataAccess *dataAccess() const; + + /*! + * Removes all applet instance settings from the storage backend. The handles + * to the instance settings still remain in this object though. For example + * \c instanceSettingsBinary() still returns a binary object that contains all + * the instance settings. + */ + void removeInstanceSettingValues() const; + +private: + //! Applet instance settings file name + QString instanceSettingsFileName; + + //! Applet global settings file name + QString globalSettingsFileName; + + //! The prefix that is used for instance specific gconf settings + QString instanceGConfPrefix; + + //! The prefix that is used for global gconf settings + QString globalGConfPrefix; + + //! The instance settings binary representation + mutable DuiSettingsLanguageBinary *instanceSettingsBinaryObject; + //! A flag to tell if the instance settings binary has been created and is uptodate + mutable bool instanceSettingsBinaryUptodate; + + //! The global settings binary representation + mutable DuiSettingsLanguageBinary *globalSettingsBinaryObject; + //! A flag to tell if the global settings binary has been created and is uptodate + mutable bool globalSettingsBinaryUptodate; + + //! Aggregate datastore of the instance and global settings datastores + mutable DuiAggregateDataAccess *settingsAggregate; + + //! Instance specific gconf datastore + mutable DuiGConfDataStore *instanceGConfDataStore; + //! Global gconf datastore + mutable DuiGConfDataStore *globalGConfDataStore; + + //! Called by the constructors to initialize the object. See the constructors for the parameter descriptions. + void init(const QString &metaDataFileName, const QString &appletId); + + //! Creates the datastores if they are not created yet + void createDataStoresIfNeeded() const; + //! Deletes all the datastore instances + void deleteDataStores() const; + + /*! + * A helper method to ensure that a settings binary object is uptodate. + * The "uptodateness" is determined by the \a settingsBinaryUptodate parameter. + * If the binary needs updating, it is updated by reading the settings file determined + * by the \a settingsFileName parameter. + * \param settingsBinaryUptodate determines if the settings binary is uptodate or not. + * This parameter will be \c true after this method returns. + * \param settingsBinaryObjectPointer a pointer to the pointer variable of the binary to be manipulated. + * \param settingsFileName the file name of the settings file. + */ + static void ensureSettingsBinaryObjectUptodate(bool &settingsBinaryUptodate, DuiSettingsLanguageBinary **settingsBinaryObjectPointer, + const QString &settingsFileName); +}; + +#endif // DUIAPPLETSETTINGS_H diff --git a/src/mashup/mashup/duiappletsettingsdialog.cpp b/src/mashup/mashup/duiappletsettingsdialog.cpp new file mode 100644 index 000000000..4c1924ded --- /dev/null +++ b/src/mashup/mashup/duiappletsettingsdialog.cpp @@ -0,0 +1,93 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiappletsettingsdialog.h" + +#include "duidialog.h" +#include "duiwidgetcontroller.h" +#include "duiwidgetview.h" +#include "duisettingslanguagewidgetfactory.h" +#include "duisettingslanguagewidget.h" +#include "duilocale.h" +#include "duicontainer.h" +#include "duiappletsettings.h" +#include "duigconfdatastore.h" +#include + +DuiAppletSettingsDialog::DuiAppletSettingsDialog(const DuiAppletSettings &appletSettings) : + appletSettings(appletSettings) +{ +} + +DuiAppletSettingsDialog::~DuiAppletSettingsDialog() +{ +} + +void DuiAppletSettingsDialog::exec() const +{ + if (!appletSettings.hasSettings()) { + return; + } + + // Create a central widget for the settings dialog + DuiWidgetController *widget = new DuiWidgetController; + widget->setView(new DuiWidgetView(widget)); + widget->setObjectName("DuiAppletHandleSettingsWidget"); + QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(Qt::Vertical); + layout->setContentsMargins(0, 0, 0, 0); + layout->setSpacing(0); + widget->setLayout(layout); + + const DuiSettingsLanguageBinary *instanceSettingsBinary = appletSettings.instanceSettingsBinary(); + if (instanceSettingsBinary != NULL) { + //~ uispec-document ??? FIXME + //% "Applet Instance Settings" + layout->addItem(createAppletSettingsWidgets(widget, qtTrId("duiappletsettingsdialog_applet_instance_settings_title"), *instanceSettingsBinary, appletSettings.instanceDataStore())); + } + + const DuiSettingsLanguageBinary *globalSettingsBinary = appletSettings.globalSettingsBinary(); + if (globalSettingsBinary != NULL) { + //~ uispec-document ??? FIXME + //% "Applet Global Settings" + layout->addItem(createAppletSettingsWidgets(widget, qtTrId("duiappletsettingsdialog_applet_global_settings_title"), *globalSettingsBinary, appletSettings.globalDataStore())); + } + + // Create a dialog to show the applet instance and global settings + //~ uispec-document ??? FIXME + //% "Applet Settings" + DuiDialog dialog(qtTrId("duiapplethandle_applet_settings_title"), widget, + Dui::NoStandardButton); + dialog.setObjectName("AppletSettingsDialog"); + dialog.exec(); +} + +QGraphicsLayoutItem *DuiAppletSettingsDialog::createAppletSettingsWidgets(QGraphicsItem *parent, const QString &title, const DuiSettingsLanguageBinary &settingsBinary, DuiDataStore *settingsDataStore) +{ + DuiContainer *container = new DuiContainer(parent); + container->setTitle(title); + DuiWidgetController *centralWidget = new DuiWidgetController(container); + container->setCentralWidget(centralWidget); + QGraphicsLinearLayout *containerLayout = new QGraphicsLinearLayout(Qt::Vertical); + centralWidget->setLayout(containerLayout); + + // Create and add settings widgets to container + containerLayout->addItem(DuiSettingsLanguageWidgetFactory::createWidget(settingsBinary, settingsDataStore)); + + return container; +} diff --git a/src/mashup/mashup/duiappletsettingsdialog.h b/src/mashup/mashup/duiappletsettingsdialog.h new file mode 100644 index 000000000..5680f1e68 --- /dev/null +++ b/src/mashup/mashup/duiappletsettingsdialog.h @@ -0,0 +1,71 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETSETTINGSDIALOG_H +#define DUIAPPLETSETTINGSDIALOG_H + +#include "duiexport.h" +#include "duiappletsettings.h" + +class QGraphicsLayoutItem; +class QGraphicsItem; +class DuiSettingsLanguageBinary; +class DuiDataStore; + +/*! + * \class DuiAppletSettingsDialog + * \brief DuiAppletSettingsDialog implements the applet settings dialog. + * A dialog is constructed if an applet has any settings to show. + */ +class DUI_EXPORT DuiAppletSettingsDialog +{ +public: + /*! + * \brief Default constructor. Constructs DuiAppletSettingsDialog. + * \param appletSettings the settings object that is used for the dialog + */ + DuiAppletSettingsDialog(const DuiAppletSettings &appletSettings); + + /*! + * \brief Destructor + */ + virtual ~DuiAppletSettingsDialog(); + + /*! + * Creates the applet settings dialog showing applet instance and global settings. + */ + void exec() const; + +private: + /*! + * Creates a container for showing applet instance/global settings + * Also places the widgets into the container + * + * \param parent The parent of the container + * \param title The title of the container + * \param settingsBinaryList a list of applet settings binaries + * \param settingsDataStore the settings data store for the settings + */ + static QGraphicsLayoutItem *createAppletSettingsWidgets(QGraphicsItem *parent, const QString &title, const DuiSettingsLanguageBinary &settingsBinary, DuiDataStore *settingsDataStore); + + //! The applet settings object that is used to construct the dialog + DuiAppletSettings appletSettings; +}; + +#endif // DUIAPPLETSETTINGSDIALOG_H diff --git a/src/mashup/mashup/duiappletsharedmutex.cpp b/src/mashup/mashup/duiappletsharedmutex.cpp new file mode 100644 index 000000000..b3f63217e --- /dev/null +++ b/src/mashup/mashup/duiappletsharedmutex.cpp @@ -0,0 +1,202 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiappletsharedmutex.h" +#include "duiappletsharedmutex_p.h" + +#include +#include +#include + +DuiAppletSharedMutexPrivate::DuiAppletSharedMutexPrivate() : + sharedMemory(NULL), + sharedMemoryId(-1) +{ +} + +DuiAppletSharedMutexPrivate::~DuiAppletSharedMutexPrivate() +{ + destroySharedMemory(keyString); +} + +QString DuiAppletSharedMutexPrivate::createSharedMemoryKeyFileName(const QString &keyString) +{ + return QDir::tempPath() + "/dui_sharedmemory_" + keyString; +} + +key_t DuiAppletSharedMutexPrivate::createSharedMemoryKey(const QString &fileName) +{ + // Create a file for ftok + if (!QFile::exists(fileName)) { + QFile file(fileName); + file.open(QIODevice::WriteOnly); + file.close(); + } + + return ftok(QFile::encodeName(fileName).constData(), 'D'); +} + +bool DuiAppletSharedMutexPrivate::initSharedMemory(const QString &keyString) +{ + // Store the key string + this->keyString = keyString; + + // Empty keystrings are not supported + if (keyString.isEmpty()) { + return false; + } + + // Get a shared memory segment + bool newSegment = true; + QString keyFileName = createSharedMemoryKeyFileName(keyString); + key_t shmKey = createSharedMemoryKey(keyFileName); + sharedMemoryId = shmget(shmKey, sizeof(pthread_mutex_t), IPC_CREAT | IPC_EXCL | 00600); + if (sharedMemoryId == -1 && errno == EEXIST) { + // The shared memory segment already exists + newSegment = false; + + // Try to take the existing segment into use + sharedMemoryId = shmget(shmKey, sizeof(pthread_mutex_t), 00600); + + if (sharedMemoryId != -1) { + // Mark the segment to be destroyed after the attach count reaches zero + struct shmid_ds sds; + shmctl(sharedMemoryId, IPC_RMID, &sds); + + // Remove the file created for ftok + QFile::remove(keyFileName); + } + } + + if (sharedMemoryId != -1) { + // Attach to the shared memory segment + sharedMemory = shmat(sharedMemoryId, NULL, 0); + + if (sharedMemory != (void *) - 1) { + // Initialize shared mutex + if (newSegment && !initMutex((pthread_mutex_t *)sharedMemory)) { + // Initialization of mutex failed: destroy shared memory + destroySharedMemory(keyString); + } + } else { + // Attaching failed: the shared memory address and ID are not valid + sharedMemory = NULL; + sharedMemoryId = -1; + } + } + + return sharedMemory != NULL; +} + +void DuiAppletSharedMutexPrivate::destroySharedMemory(const QString &keyString) +{ + if (sharedMemory != NULL) { + // Get the attach count and mark the memory to be deleted + struct shmid_ds sds; + shmctl(sharedMemoryId, IPC_STAT, &sds); + shmctl(sharedMemoryId, IPC_RMID, &sds); + + if (sds.shm_nattch == 1) { + // Destroy the mutex and remove the file created for ftok if the detach count was 1 + destroyMutex((pthread_mutex_t *)sharedMemory); + QFile::remove(createSharedMemoryKeyFileName(keyString)); + } + + // Detach + shmdt(sharedMemory); + sharedMemory = NULL; + sharedMemoryId = -1; + } +} + +bool DuiAppletSharedMutexPrivate::initMutex(pthread_mutex_t *mutex) +{ + if (mutex != NULL) { + // Initialize a mutex in the shared memory with the "shared between processes" attribute + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + if (pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED) == 0 && + pthread_mutex_init(mutex, &attr) == 0) { + return true; + } + } + + return false; +} + +void DuiAppletSharedMutexPrivate::destroyMutex(pthread_mutex_t *mutex) +{ + if (mutex != NULL) { + // If the mutex is locked the result of destroying is undefined but since the memory segment is about to be destroyed anyway this won't matter + pthread_mutex_destroy(mutex); + } +} + +DuiAppletSharedMutex::DuiAppletSharedMutex() : d_ptr(new DuiAppletSharedMutexPrivate) +{ +} + +DuiAppletSharedMutex::~DuiAppletSharedMutex() +{ + delete d_ptr; +} + +bool DuiAppletSharedMutex::init(const QString &key) +{ + Q_D(DuiAppletSharedMutex); + + // Destroy any previously shared memory + d->destroySharedMemory(d->keyString); + + // Initialize shared memory + return d->initSharedMemory(key); +} + +bool DuiAppletSharedMutex::lock() +{ + Q_D(DuiAppletSharedMutex); + + if (d->sharedMemory != NULL) { + return pthread_mutex_lock((pthread_mutex_t *)d->sharedMemory) == 0; + } else { + return false; + } +} + +bool DuiAppletSharedMutex::unlock() +{ + Q_D(DuiAppletSharedMutex); + + if (d->sharedMemory != NULL) { + return pthread_mutex_unlock((pthread_mutex_t *)d->sharedMemory) == 0; + } else { + return false; + } +} + +bool DuiAppletSharedMutex::tryLock() +{ + Q_D(DuiAppletSharedMutex); + + if (d->sharedMemory != NULL) { + return pthread_mutex_trylock((pthread_mutex_t *)d->sharedMemory) == 0; + } else { + return false; + } +} diff --git a/src/mashup/mashup/duiappletsharedmutex.h b/src/mashup/mashup/duiappletsharedmutex.h new file mode 100644 index 000000000..6300e4694 --- /dev/null +++ b/src/mashup/mashup/duiappletsharedmutex.h @@ -0,0 +1,87 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETSHAREDMUTEX_H_ +#define DUIAPPLETSHAREDMUTEX_H_ + +#include + +class DuiAppletSharedMutexPrivate; + +/*! + * DuiAppletSharedMutex provides a POSIX mutex that is located in shared + * memory. Initializing the shared mutex will create a shared memory segment + * if one is not created yet. Otherwise the already existing shared memory + * segment is attached. Destroying the mutex will detach from the shared + * memory so that when all parties have detached the segment will be freed. + */ +class DUI_EXPORT DuiAppletSharedMutex +{ + Q_DECLARE_PRIVATE(DuiAppletSharedMutex) + +public: + /*! + * Creates a new shared mutex. The mutex must be initialized using + * init() before it can be used. + */ + DuiAppletSharedMutex(); + + /*! + * Destroys the shared mutex. Detaches the shared memory so that + * when all parties have detached the segment will be freed. + */ + virtual ~DuiAppletSharedMutex(); + + /*! + * Initializes the shared mutex. Creates a shared memory segment + * if one is not created yet. Otherwise the already existing shared memory + * segment is attached and the mutex is marked to be destroyed when all + * parties have detached. + */ + bool init(const QString &key); + + /*! + * Locks the mutex. If the mutex is already locked the calling thread + * shall block until the mutex becomes available. + * + * \return true if the mutex could be locked, false otherwise + */ + bool lock(); + + /*! + * Unlocks the mutex. + * + * \return true if the mutex could be unlocked, false otherwise + */ + bool unlock(); + + /*! + * Locks the mutex. If the mutex is already locked the function + * will return false immediately. + * + * \return true if the mutex could be locked, false otherwise + */ + bool tryLock(); + +private: + //! A pointer to the private class + DuiAppletSharedMutexPrivate *d_ptr; +}; + +#endif /* DUIAPPLETSHAREDMUTEX_H_ */ diff --git a/src/mashup/mashup/duiappletsharedmutex_p.h b/src/mashup/mashup/duiappletsharedmutex_p.h new file mode 100644 index 000000000..d92e1aa15 --- /dev/null +++ b/src/mashup/mashup/duiappletsharedmutex_p.h @@ -0,0 +1,94 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETSHAREDMUTEXPRIVATE_H_ +#define DUIAPPLETSHAREDMUTEXPRIVATE_H_ + +#include +#include +#include + +class DuiAppletSharedMutexPrivate +{ + Q_DECLARE_PUBLIC(DuiAppletSharedMutex) + +public: + DuiAppletSharedMutexPrivate(); + virtual ~DuiAppletSharedMutexPrivate(); + + //! Public class + DuiAppletSharedMutex *q_ptr; + + //! Shared memory key string + QString keyString; + + //! Memory segment shared between the host process and the applet process, used to store a mutex to control access to the shared X pixmap + void *sharedMemory; + + //! ID for the shared memory segment + int sharedMemoryId; + + /*! + * Creates a shared memory key file name from a string. + * + * \param keyString the string to use as the shared memory key + * \return the shared memory key file name for the string + */ + QString createSharedMemoryKeyFileName(const QString &keyString); + + /*! + * Creates a shared memory key from a string. + * + * \param keyString the string to use as the shared memory key + * \return the shared memory key for the string + */ + key_t createSharedMemoryKey(const QString &keyString); + + /*! + * Initializes a shared memory segment by either allocating a new shared memory segment or attaching to an existing one. + * + * \param keyString the string to use as the shared memory key + * \return true if creation succeeded, false otherwise + */ + bool initSharedMemory(const QString &keyString); + + /*! + * Destroys the shared memory segment if it exists. + * + * \param keyString the string to use as the shared memory key + */ + void destroySharedMemory(const QString &keyString); + + /*! + * Initializes a mutex. + * + * \param pointer to the mutex to be initialized + * \return true if initialization succeeded, false otherwise + */ + bool initMutex(pthread_mutex_t *mutex); + + /*! + * Destroys the mutex if it exists. + * + * \param mutex the mutex to be destroyed + */ + void destroyMutex(pthread_mutex_t *mutex); +}; + +#endif /* DUIAPPLETSHAREDMUTEXPRIVATE_H_ */ diff --git a/src/mashup/mashup/duidataaccess.h b/src/mashup/mashup/duidataaccess.h new file mode 100644 index 000000000..d9b271f0c --- /dev/null +++ b/src/mashup/mashup/duidataaccess.h @@ -0,0 +1,85 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIDATAACCESS_H +#define DUIDATAACCESS_H + +#include "duiexport.h" +#include +#include +#include +#include + +/*! + * \brief Interface for reading and storing key values. + * + * Users can read and write key values using this interface. The user + * also get notified when changes happen in the key values. + */ +class DUI_EXPORT DuiDataAccess : public QObject +{ + Q_OBJECT + +public: + /*! + * Destroys the DuiDataAccess. + */ + virtual ~DuiDataAccess() {} + + /*! + * Returns a value for a key. + * If the key doesn't exist, an invalid (QVariant::Invalid) value is returned. + * \param key the key. + * \return the requested value. + */ + virtual QVariant value(const QString &key) const = 0; + + /*! + * Sets a new value for a key. If the key isn't found, nothing + * happens and \c false is returned. + * \param key the key to be changed. + * \param value the new value. + * \return \c true if setting was succesful, \c false otherwise + */ + virtual bool setValue(const QString &key, const QVariant &value) = 0; + + /*! + * Returns a list of all specified keys. + */ + virtual QStringList allKeys() const = 0; + + /*! + * Returns \c true if there exists a key called \a key and \c false otherwise. + * + * \param key the key to test + * \return a boolean value telling if the key exists or not + * \sa value() and setValue(). + */ + virtual bool contains(const QString &key) const = 0; + +Q_SIGNALS: + /*! + * A signal that is emitted when a key value changes. + * \param key the key that changed. + * \param value the new value. + */ + void valueChanged(const QString &key, const QVariant &value); +}; + +#endif // DUIDATAACCESS_H diff --git a/src/mashup/mashup/duidatastore.h b/src/mashup/mashup/duidatastore.h new file mode 100644 index 000000000..94b190529 --- /dev/null +++ b/src/mashup/mashup/duidatastore.h @@ -0,0 +1,71 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIDATASTORE_H +#define DUIDATASTORE_H + +#include "duidataaccess.h" +#include "duiexport.h" + +/*! + * Interface for reading and storing data. + * + * The difference between this class and \c DuiDataAccess is that this interface + * can also be used to create and remove keys. + */ +class DUI_EXPORT DuiDataStore : public DuiDataAccess +{ + Q_OBJECT + +public: + /*! + * Destroys the DuiDataStore. + */ + virtual ~DuiDataStore() {} + + /*! + * This will add a new key with the given value or change the value of an + * existing key if the key already exists. + * + * Concrete implementations of DuiDataStore have to ensure that the data + * is being synchronized with the backend when this is called. + * + * \param key the key to set the value for + * \param value the value for the key + * \return \c true if the key was changed or added, \c false otherwise + */ + virtual bool createValue(const QString &key, const QVariant &value) = 0; + + /*! + * Removes the data of the given key from the datastore. + * Concrete implementations of DuiDataStore have to ensure that the data is being synchronized + * with the backend when this is called. + */ + virtual void remove(const QString &key) = 0; + + /*! + * Removes all entries in this datastore. + * Concrete implementations of DuiDataStore have to ensure that the data is being synchronized + * with the backend when this is called. + */ + virtual void clear() = 0; + +}; + +#endif // DUIDATASTORE_H diff --git a/src/mashup/mashup/duifiledatastore.cpp b/src/mashup/mashup/duifiledatastore.cpp new file mode 100644 index 000000000..c1e3db922 --- /dev/null +++ b/src/mashup/mashup/duifiledatastore.cpp @@ -0,0 +1,295 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duifiledatastore.h" +#include +#include + +/*! + * Creates a temporary file in the directory of an original file. + * \param originalPath Absolute path that is used as a base for generating + * the temporary file. + * \return Path of the created file, or an empty string if creating the + * file fails. The returned value is a copy, so for uses where it's assigned + * to a variable, it need not be const. For cases where it's passed as a + * parameter, it need not be const because references to non-const will + * not bind to function return values, because they are rvalues. When + * C++0x brings rvalue references, the value should not be const in order + * to allow rvalue references to bind to it and thus enable moving from it. + */ +static QString createTempFile(const QString &originalPath) +{ + QString returnValue; + QTemporaryFile tempFile(originalPath); + if (tempFile.open()) { + tempFile.setAutoRemove(false); + returnValue = tempFile.fileName(); + } + return returnValue; +} + +/*! + * Copies settings from a QSettings object to another QSettings object. + * \param originalSettings Settings to copy. + * \param newSettings Target of the copy. + * \return true if copying succeeds, false if it fails. + */ +static bool copySettings(const QSettings &originalSettings, + QSettings &newSettings) +{ + QStringList keys = originalSettings.allKeys(); + foreach(const QString & key, originalSettings.allKeys()) { + newSettings.setValue(key, originalSettings.value(key)); + if (newSettings.status() != QSettings::NoError) { + return false; + } + } + return true; +} + +/*! + * Renames a file. Ensures that a file with the new name + * doesn't exist. + * \param oldname Name of the file to rename. + * \param newName New name. + */ +static void renameSettingFile(const QString &oldName, + const QString &newName) +{ + QFile::remove(newName); + QFile::rename(oldName, newName); +} + +/*! + * Adds the necessary paths to the file system watcher + * \param filePath Path (including name) of the file to watch. + * \param watcher The file system watcher. + */ +static void addPathsToWatcher(const QString &filePath, + QScopedPointer& watcher) +{ + // Watch the directory if it's not being watched yet + QString canonicalPath(QFileInfo(filePath).canonicalPath()); + if (!watcher->directories().contains(canonicalPath)) { + watcher->addPath(canonicalPath); + } + + // Watch the file itself if it's not being watched yet + if (!watcher->files().contains(filePath)) { + watcher->addPath(filePath); + } +} + +/*! + * Saves the settings to a file. The settings are first + * saved to a temporary file, and then that file is copied + * over the original settings. This avoids clearing settings + * when there's no disk space. + * \param originalSettings Settings to save. + */ +static bool doSync(QSettings &originalSettings, QScopedPointer& watcher) +{ + bool returnValue = false; + QString tempFileName = createTempFile(originalSettings.fileName()); + if (!tempFileName.isEmpty()) { + QSettings copiedSettings(tempFileName, QSettings::IniFormat); + if (copySettings(originalSettings, copiedSettings)) { + copiedSettings.sync(); + if (copiedSettings.status() == QSettings::NoError) { + renameSettingFile(tempFileName, originalSettings.fileName()); + returnValue = true; + } + } + } + addPathsToWatcher(originalSettings.fileName(), watcher); + return returnValue; +} + +DuiFileDataStore::DuiFileDataStore(const QString &filePath) : + settings(QString(filePath), QSettings::IniFormat), + watcher(new QFileSystemWatcher()) +{ + settings.sync(); + takeSnapshot(); + addPathsToWatcher(filePath, watcher); + connect(watcher.data(), SIGNAL(fileChanged(QString)), + this, SLOT(fileChanged(QString))); + connect(watcher.data(), SIGNAL(directoryChanged(QString)), + this, SLOT(directoryChanged(QString))); +} + +bool DuiFileDataStore::createValue(const QString &key, const QVariant &value) +{ + bool returnValue = false; + // QSettings has some kind of a cache so we'll prevent any temporary writes + // by checking if the data can be actually stored before doing anything + if (isWritable()) { + bool originalValueSet = settings.contains(key); + QVariant originalValue = settings.value(key); + settings.setValue(key, value); + bool syncOk = doSync(settings, watcher); + if (syncOk) { + returnValue = true; + // Emit valueChanged signal when value is changed or a new key is added + if ((originalValueSet && originalValue != value) + || !originalValueSet) { + settingsSnapshot[key] = value; + emit valueChanged(key, value); + } + } else if (originalValueSet) { + // if sync fails, make sure the value in memory is the original + settings.setValue(key, originalValue); + } else { + settings.remove(key); + } + + } + return returnValue; +} + +bool DuiFileDataStore::setValue(const QString &key, const QVariant &value) +{ + bool returnValue = false; + // QSettings has some kind of a cache so we'll prevent any temporary writes + // by checking if the data can be actually stored before doing anything + if (isWritable() && settings.contains(key)) { + bool originalValueSet = settings.contains(key); + QVariant originalValue = settings.value(key); + settings.setValue(key, value); + bool syncOk = doSync(settings, watcher); + if (syncOk) { + returnValue = true; + // Emit valueChanged signal when value is changed + if (originalValue != value) { + settingsSnapshot[key] = value; + emit valueChanged(key, value); + } + } else if (originalValueSet) { + // if sync fails, make sure the value in memory is the original + settings.setValue(key, originalValue); + } else { + settings.remove(key); + } + } + return returnValue; +} + +QVariant DuiFileDataStore::value(const QString &key) const +{ + return settings.value(key); +} + +QStringList DuiFileDataStore::allKeys() const +{ + return settings.allKeys(); +} + +void DuiFileDataStore::remove(const QString &key) +{ + // QSettings has some kind of a cache so we'll prevent any temporary writes + // by checking if the data can be actually stored before doing anything + if (isWritable()) { + bool originalValueSet = settings.contains(key); + if (!originalValueSet) { + return; + } + QVariant originalValue = settings.value(key); + settings.remove(key); + bool syncOk = doSync(settings, watcher); + if (!syncOk) { + if (originalValueSet) { + // if sync fails, make sure the value in memory is the original + settings.setValue(key, originalValue); + } + } else { + settingsSnapshot.remove(key); + emit valueChanged(key, QVariant()); + } + } +} + +void DuiFileDataStore::clear() +{ + // QSettings has some kind of a cache so we'll prevent any temporary writes + // by checking if the data can be actually stored before doing anything + if (isWritable()) { + settings.clear(); + settings.sync(); + takeSnapshot(); + } +} + +bool DuiFileDataStore::contains(const QString &key) const +{ + return settings.contains(key); +} + +bool DuiFileDataStore::isReadable() const +{ + return settings.status() == QSettings::NoError; +} + +bool DuiFileDataStore::isWritable() const +{ + return settings.isWritable() && settings.status() == QSettings::NoError; +} + +void DuiFileDataStore::takeSnapshot() +{ + settingsSnapshot.clear(); + foreach(const QString & key, settings.allKeys()) { + settingsSnapshot.insert(key, settings.value(key)); + } +} + +void DuiFileDataStore::fileChanged(const QString &fileName) +{ + // sync the settings and add the path, for observing + // the file even if it was deleted + settings.sync(); + addPathsToWatcher(settings.fileName(), watcher); + if (settings.fileName() == fileName && isWritable()) { + // Check whether the values for existing keys have changed or + // if keys have been deleted + foreach(const QString & key, settingsSnapshot.keys()) { + if ((settings.contains(key) + && settings.value(key) != settingsSnapshot.value(key)) + || (!settings.contains(key))) { + emit valueChanged(key, settings.value(key)); + } + } + // Check whether new keys have been added + foreach(const QString & key, settings.allKeys()) { + if (!settingsSnapshot.contains(key)) { + emit valueChanged(key, settings.value(key)); + } + } + takeSnapshot(); + } +} + +void DuiFileDataStore::directoryChanged(const QString &fileName) +{ + if (fileName == QFileInfo(settings.fileName()).canonicalPath()) { + // we can't know which file changed, so we'll sync at this + // point. This is not very optimal, but it at least works. + fileChanged(settings.fileName()); + } +} + diff --git a/src/mashup/mashup/duifiledatastore.h b/src/mashup/mashup/duifiledatastore.h new file mode 100644 index 000000000..440ab3285 --- /dev/null +++ b/src/mashup/mashup/duifiledatastore.h @@ -0,0 +1,124 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIFILEDATASTORE_H +#define DUIFILEDATASTORE_H + +#include "duidatastore.h" +#include +#include +#include +#include + +/*! + * Concrete implementation of \c DuiDataStore interface. This class stores the data to the + * filesystem. The file name is given as a constructor parameter. + */ +class DUI_EXPORT DuiFileDataStore : public DuiDataStore +{ + Q_OBJECT +public: + /*! + * Constructor. + * \param filePath Absolute path to the file that the settings will be written to and read from. + */ + explicit DuiFileDataStore(const QString &filePath); + //! \reimp + /*! + * If \c isWritable returns \c false, this method returns \c false. + */ + virtual bool createValue(const QString &key, const QVariant &value); + /*! + * If \c isWritable returns \c false, this method returns \c false. + */ + virtual bool setValue(const QString &key, const QVariant &value); + /*! + * If \c isReadable returns \c false, this method returns an empty QVariant. + */ + virtual QVariant value(const QString &key) const; + /*! + * If \c isReadable returns \c false, this method returns an empty list. + */ + virtual QStringList allKeys() const; + /*! + * If \c isWritable returns \c false, this method does nothing. + */ + virtual void remove(const QString &key); + /*! + * If \c isWritable returns \c false, this method does nothing. + */ + virtual void clear(); + /*! + * If \c isReadable returns \c false, this method returns \c false. + */ + virtual bool contains(const QString &key) const; + //! \reimp_end + + /*! + * Queries if this data store is readable. If this method returns \c true you + * can use the reading methods of this class (\c value, \c allKeys, \c contains). + * If this method returns \c false, the reading methods don't provide the real data. + * \sa value, allKeys, contains + * \return \c true if the data store can be read. + */ + bool isReadable() const; + + /*! + * Queries if this data store is writable. If this method returns \c true you + * can use the writing methods of this class (\c setValue, \c remove, \c clear). + * If this method returns \c false, the writing methods don't modify the data store. + * \sa setValue, remove, clear + * \return \c true if the data store can be written. + */ + bool isWritable() const; + +private: + /*! + * Takes a snapshot of keys and values in the underlying QSettings. + * This allows us to check for external modifications. QSettings seems + * to pick up such modifications automatically, so we compare the settings + * to the snapshot when we notice a file change. + */ + void takeSnapshot(); + +private slots: + /*! + * Notifies that the settings file has been changed in the filesystem externally + * \param fileName The name of the file modified + */ + void fileChanged(const QString &fileName); + + /*! + * Notifies that the directory of the settings file has been changed in the filesystem externally + * \param fileName The name of the file modified + */ + void directoryChanged(const QString &fileName); + +private: + //! The used data storing backend + QSettings settings; + + //! Snapshot of the settings, used for observing external file changes + QMap settingsSnapshot; + + //! File system watcher wrapped with QScopedPointer to monitor changes in the settings file + QScopedPointer watcher; +}; + +#endif // DUIFILEDATASTORE_H diff --git a/src/mashup/mashup/duigconfdatastore.cpp b/src/mashup/mashup/duigconfdatastore.cpp new file mode 100644 index 000000000..005078d2a --- /dev/null +++ b/src/mashup/mashup/duigconfdatastore.cpp @@ -0,0 +1,127 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duigconfdatastore.h" +#include "duigconfitem.h" + +DuiGConfDataStore::DuiGConfDataStore(const QString &keyPath) : + keyContainer(), + keyPath(keyPath) +{ + DuiGConfItem rootKey(keyPath, this); + this->keyPath += keyPath.endsWith('/') ? "" : "/"; + + QList entries = rootKey.listEntries(); + foreach(const QString & entry, entries) { + DuiGConfItem *item = new DuiGConfItem(entry, this); + keyContainer.insert(entry.mid(this->keyPath.length()), item); + connect(item, SIGNAL(valueChanged()), this, SLOT(gconfValueChanged())); + } +} + +DuiGConfDataStore::~DuiGConfDataStore() +{ +} + +bool DuiGConfDataStore::setValue(const QString &key, const QVariant &value) +{ + // Don't allow setting keys below the key path of the datastore + if (key.indexOf('/') != -1) { + return false; + } + + // Use an iterator and find() in order to avoid double search in the container + KeyContainer::const_iterator it = keyContainer.constFind(key); + if (it != keyContainer.constEnd()) { + it.value()->set(value); + return true; + } else { + return false; + } +} + +bool DuiGConfDataStore::createValue(const QString &key, const QVariant &value) +{ + // Use an iterator and find() in order to avoid double search in the container + KeyContainer::const_iterator it = keyContainer.constFind(key); + if (it != keyContainer.constEnd()) { + it.value()->set(value); + return true; + } else { + // Don't allow creating keys below the key path of the datastore + if (key.indexOf('/') != -1) { + return false; + } + DuiGConfItem *item = new DuiGConfItem(keyPath + key, this); + keyContainer.insert(key, item); + item->set(value); + return true; + } +} + +QVariant DuiGConfDataStore::value(const QString &key) const +{ + // Use an iterator and find() in order to avoid double search in the container + KeyContainer::const_iterator it = keyContainer.find(key); + if (it != keyContainer.end()) { + return it.value()->value(); + } else { + return QVariant(QVariant::Invalid); + } +} + +QStringList DuiGConfDataStore::allKeys() const +{ + return keyContainer.keys(); +} + +void DuiGConfDataStore::remove(const QString &key) +{ + DuiGConfItem *item = keyContainer.take(key); + if (item != NULL) { + item->unset(); + delete item; + } +} + +void DuiGConfDataStore::clear() +{ + foreach(DuiGConfItem * item, keyContainer.values()) { + if (item != NULL) { + item->unset(); + delete item; + } + } + keyContainer.clear(); +} + +bool DuiGConfDataStore::contains(const QString &key) const +{ + return keyContainer.contains(key); +} + +void DuiGConfDataStore::gconfValueChanged() +{ + DuiGConfItem *item = qobject_cast(sender()); + if (item != NULL) { + QString key = item->key().mid(keyPath.length()); + QVariant value = item->value(); + emit valueChanged(key, value); + } +} diff --git a/src/mashup/mashup/duigconfdatastore.h b/src/mashup/mashup/duigconfdatastore.h new file mode 100644 index 000000000..27f953716 --- /dev/null +++ b/src/mashup/mashup/duigconfdatastore.h @@ -0,0 +1,93 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIGCONFDATASTORE_H +#define DUIGCONFDATASTORE_H + +#include +#include "duidatastore.h" + +class DuiGConfItem; + +/*! + * A data store class that uses GConf as the backend. + * + * This datastore can access all keys inside a GConf path given in the constructor. + * The access is limited to a single level of hierarchy, you can't access keys + * of any subdirectories of the path. For example, the following code will + * create the datastore with the GConf path /example and set a + * value of the key called userKey under that path: + * + * \code + * DuiGConfDataStore dataStore("/example"); + * dataStore.setValue("userKey", 123); + * \endcode + * + */ +class DUI_EXPORT DuiGConfDataStore : public DuiDataStore +{ + Q_OBJECT + +public: + /*! + * Constructor. + * \param keyPath The gconf path in which the datastore operates. + */ + DuiGConfDataStore(const QString &keyPath); + + /*! + * Destructor. + */ + virtual ~DuiGConfDataStore(); + + //! \reimp + virtual bool setValue(const QString &key, const QVariant &value); + virtual bool createValue(const QString &key, const QVariant &value); + virtual QVariant value(const QString &key) const; + virtual QStringList allKeys() const; + virtual void remove(const QString &key); + virtual void clear(); + + /*! + * Note that this function returns \c true if a GConf key mapping for the + * key has been set even if the key wouldn't have a value. + */ + virtual bool contains(const QString &key) const; + //! \reimp_end + +private slots: + /*! + * Notifies the object that a GConf value has changed. + * If the caller of this slot is valid this causes the valueChanged() + * signal to be emitted. + */ + void gconfValueChanged(); + +private: + //! Type for a container that maps strings to GConf items. + typedef QHash KeyContainer; + + //! A container for the GConf items. + KeyContainer keyContainer; + + //! The gconf path of this datastore + QString keyPath; +}; + +#endif /* DUIGCONFDATASTORE_H */ diff --git a/src/mashup/mashup/duimashupcanvas.cpp b/src/mashup/mashup/duimashupcanvas.cpp new file mode 100644 index 000000000..a2e80a461 --- /dev/null +++ b/src/mashup/mashup/duimashupcanvas.cpp @@ -0,0 +1,193 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duimashupcanvas.h" +#include "duimashupcanvas_p.h" +#include "duicomponentdata.h" +#include "duiappletinstancemanager.h" +#include "duidatastore.h" +#include "duimashupcanvasstyle.h" +#include "duilocale.h" +#include +#include + +#include "duiwidgetcreator.h" +DUI_REGISTER_WIDGET_NO_CREATE(DuiMashupCanvas) + +/////////////////// +// PRIVATE CLASS // +/////////////////// + +QSet DuiMashupCanvasPrivate::allMashupCanvasIdentifiers; + +DuiMashupCanvasPrivate::DuiMashupCanvasPrivate() : instanceManager(NULL) +{ +} + +DuiMashupCanvasPrivate::~DuiMashupCanvasPrivate() +{ + delete instanceManager; +} + +void DuiMashupCanvasPrivate::init(const QString &identifier) +{ + Q_Q(DuiMashupCanvas); + + this->identifier = provideUniqueIdentifier(identifier); + this->serviceAddress = DuiComponentData::serviceName() + "/DuiAppletInstanceManager/" + this->identifier; + instanceManager = new DuiAppletInstanceManager(this->identifier); + + // Connect applet instance manager signals and restore applet instances + q->connect(instanceManager, SIGNAL(appletInstantiated(DuiWidget *, DuiDataStore &)), SLOT(addWidget(DuiWidget *, DuiDataStore &))); + q->connect(instanceManager, SIGNAL(appletRemoved(DuiWidget *)), SLOT(removeWidget(DuiWidget *))); + instanceManager->restoreApplets(); + + // Put the data stores into the model + q->model()->setDataStores(&dataStores); +} + +QString DuiMashupCanvasPrivate::provideUniqueIdentifier(const QString &identifier) +{ + QString result = identifier; + if (identifier.isEmpty() || allMashupCanvasIdentifiers.contains(identifier)) { + uint number = 1; + QString tmpIdentifier = identifier + '_' + QString::number(number); + while (allMashupCanvasIdentifiers.contains(tmpIdentifier)) { + ++number; + tmpIdentifier = identifier + '_' + QString::number(number); + } + + result = tmpIdentifier; + } + + allMashupCanvasIdentifiers.insert(result); + return result; +} + +void DuiMashupCanvasPrivate::addWidget(DuiWidget *widget, DuiDataStore &store) +{ + Q_Q(DuiMashupCanvas); + + // TODO: when the current ABI freeze ends: + // - make DuiMashupCanvas inherit DuiExtensionArea + // - remove dataStore handling in this function and call DuiExtensionAreaPrivate's addWidget instead + // (leave the DuiAction things here) + if (!dataStores.contains(widget)) { + // Add the remove action into the object menu of the applet widget + //: Object menu command. Removes e.g. applet from canvas. + //~ uispec-document DirectUI_Common_Strings_UI_Specification_0.7.pdf + //% "Remove Applet" + DuiAction *action = new DuiAction(qtTrId("qtn_comm_removewidget"), q); + instanceManager->connect(action, SIGNAL(triggered(bool)), SLOT(removeActionTriggered(bool))); + widget->addAction(action); + + // Add data store to data stores map + dataStores[widget] = &store; + + // Let the view know about the data store modification + q->model()->dataStoresModified(); + } else { + // Widget is already added to the mashup canvas. Bail out. + duiWarning("DuiMashupCanvas") << "DuiMashupCanvas::addWidget() - Widget was already added to mashup canvas."; + } +} + +void DuiMashupCanvasPrivate::removeWidget(DuiWidget *widget) +{ + Q_Q(DuiMashupCanvas); + + // TODO: when the current ABI freeze ends: + // - make DuiMashupCanvas inherit DuiExtensionArea + // - remove this function (removeWidget in the base class works then) + if (dataStores.contains(widget)) { + // Remove data store from the data stores map + dataStores.remove(widget); + q->model()->dataStoresModified(); + } +} + + +////////////////// +// PUBLIC CLASS // +////////////////// +DuiMashupCanvas::DuiMashupCanvas(const QString &identifier, QGraphicsItem *parent) : + DuiWidgetController(new DuiMashupCanvasPrivate, new DuiMashupCanvasModel, parent) +{ + // Initialize the private implementation + Q_D(DuiMashupCanvas); + d->q_ptr = this; + d->init(identifier); +} + +DuiMashupCanvas::DuiMashupCanvas(DuiMashupCanvasPrivate *dd, DuiMashupCanvasModel *model, QGraphicsItem *parent, const QString &identifier) : + DuiWidgetController(dd, model, parent) +{ + Q_D(DuiMashupCanvas); + + // Initialize the private implementation + d->init(identifier); +} + +DuiMashupCanvas::~DuiMashupCanvas() +{ +} + +void DuiMashupCanvas::setCategories(const QStringList &categories) +{ + model()->setCategories(categories); +} + +QStringList DuiMashupCanvas::categories() const +{ + return model()->categories(); +} + +QString DuiMashupCanvas::identifier() const +{ + Q_D(const DuiMashupCanvas); + + return d->identifier; +} + +QString DuiMashupCanvas::serviceAddress() const +{ + Q_D(const DuiMashupCanvas); + + return d->serviceAddress; +} + +void DuiMashupCanvas::addWidget(DuiWidget *widget, DuiDataStore &store) +{ + Q_D(DuiMashupCanvas); + + d->addWidget(widget, store); +} + +void DuiMashupCanvas::removeWidget(DuiWidget *widget) +{ + Q_D(DuiMashupCanvas); + + d->removeWidget(widget); +} + +DuiAppletInstanceManager *DuiMashupCanvas::appletInstanceManager() const +{ + Q_D(const DuiMashupCanvas); + return d->instanceManager; +} diff --git a/src/mashup/mashup/duimashupcanvas.h b/src/mashup/mashup/duimashupcanvas.h new file mode 100644 index 000000000..388a36c43 --- /dev/null +++ b/src/mashup/mashup/duimashupcanvas.h @@ -0,0 +1,138 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIMASHUPCANVAS_H +#define DUIMASHUPCANVAS_H + +#include +#include "duimashupcanvasmodel.h" + +class DuiDataStore; +class DuiAppletInstanceManager; +class DuiMashupCanvasPrivate; + +/*! + * DuiMashupCanvas is a widget which can be populated with applet instances. DuiMashupCanvas + * can be placed on any view that wants to leverage applet support. + * + * Every DuiMashupCanvas has to be identified by a unique identifier that is passed in through + * the constructor. The user of this class should ensure that they use unique identifiers for the + * mashup canvases they construct. If the user of this class fails to provide unique identifiers, + * unpredictable side effects may occur because the implementation ensures that every mashup canvas has a + * unique identifier. The unexpected side effects may include, but isn't limited to: + * - mixing of the contents of the canvases + * - missing applets from the canvases upon restart of the application + * + * \see \ref appletdevelopment + */ +class DUI_EXPORT DuiMashupCanvas : public DuiWidgetController +{ + Q_OBJECT + DUI_CONTROLLER(DuiMashupCanvas) + +public: + /*! + * Constructor + * \param identifier A unique identifier of this mashup canvas. The data of the instantiated + * applets is stored and restored based on this identifier. + \param parent Optional Object's parent + */ + explicit DuiMashupCanvas(const QString &identifier, QGraphicsItem *parent = NULL); + + /*! + * Default destructor + */ + virtual ~DuiMashupCanvas(); + + /*! + * Gets the applet instance manager for managing applet instances. + * + * \return an instance of DuiAppletInstanceManager + */ + DuiAppletInstanceManager *appletInstanceManager() const; + + /*! + * Sets the applet categories available in this mashup canvas. + * The default value for the categories is an empty list. This + * means filtering by categories is disabled and all applets are + * shown in the applet inventory. + * + * \param categories a list of names of the applet categories to show in this mashup canvas. + */ + void setCategories(const QStringList &categories); + + /*! + * Gets the applet categories available in this mashup canvas. + * + * \return a list of names of the applet categories to show in this mashup canvas. + */ + QStringList categories() const; + + /*! + * Returns the unique identifier of this canvas + * \return the identifier + */ + QString identifier() const; + + /*! + * Returns the D-Bus service address of this canvas + * \return the D-Bus address + */ + QString serviceAddress() const; + +protected: + /*! + * Protected constructor to be called by derived classes to set up the private implementation + * hierarchy. + */ + DuiMashupCanvas(DuiMashupCanvasPrivate *dd, DuiMashupCanvasModel *model, QGraphicsItem *parent, const QString &identifier); + +protected Q_SLOTS: + /*! + * addWidget is invoked whenever a new applet is instantiated in the AppletInstanceManager + * associated with this DuiMashupCanvas. The DuiWidget that is passed in the argument is + * the graphical presentation of the instantiated applet. DuiMashupCanvas inserts the + * widget to the layout using the given layout data. The ownership of the widget remains + * on the AppletInstanceManager object that called this slot. + * This slot can be overridden in specialised mashup canvases to provide tailored functionality. + * \param widget Widget to be added onto the DuiMashupCanvas. + * \param store This DuiDataStore object can be used to store permanent mashup canvas data related + * to this particular applet instance. When the same applet instance is reinstantiated, this + * API will be called with the data that was stored to the permanent storage the last time around. + * This can be used to store for instance layout data of an applet instance or any other mashup + * canvas specific data. + */ + virtual void addWidget(DuiWidget *widget, DuiDataStore &store); + + /*! + * removeWidget is invoked whenever an existing applet instance is removed from the system. + * DuiMashupCanvas will remove the associated presentation from the canvas, but should not + * remove the DuiWidget object, since the ownership is maintained on whoever called the addWidget + * on the associated DuiWidget. + * + * \param widget The widget to be removed from the system. + */ + virtual void removeWidget(DuiWidget *widget); + +private: + Q_DECLARE_PRIVATE(DuiMashupCanvas) + Q_DISABLE_COPY(DuiMashupCanvas) +}; + +#endif // DUIMASHUPCANVAS_H diff --git a/src/mashup/mashup/duimashupcanvas_p.h b/src/mashup/mashup/duimashupcanvas_p.h new file mode 100644 index 000000000..76214951e --- /dev/null +++ b/src/mashup/mashup/duimashupcanvas_p.h @@ -0,0 +1,92 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIMASHUPCANVAS_P_H +#define DUIMASHUPCANVAS_P_H + +#include "private/duiwidgetcontroller_p.h" +#include "applicationextension/duiextensionarea_p.h" + +class DuiDataStore; +class DuiAppletInstanceManager; + +/*! + * Private class for DuiMashupCanvas. + */ +class DuiMashupCanvasPrivate : public DuiExtensionAreaPrivate +{ + Q_DECLARE_PUBLIC(DuiMashupCanvas) + +public: + /*! + * Constructor. + */ + DuiMashupCanvasPrivate(); + + /*! + * Destructor. + */ + virtual ~DuiMashupCanvasPrivate(); + + /*! + * Initializes this class. This method should be called before this class + * is used for anything else. + * + * \param identifier the identifier for the mashup canvas. + */ + void init(const QString &identifier); + + /*! + * Adds a widget to the canvas. + * \see DuiMashupCanvas::addWidget() + */ + virtual void addWidget(DuiWidget *widget, DuiDataStore &store); + + /*! + * Removes a widget from the canvas. + * \see DuiMashupCanvas::removeWidget() + */ + virtual void removeWidget(DuiWidget *widget); + + //! Applet instance manager + DuiAppletInstanceManager *instanceManager; + + //! The identifier of this canvas + QString identifier; + + //! The D-Bus service address of this canvas + QString serviceAddress; + + /*! + * Provides a unique identifier in this process. + * If the provided identifier is not previously used, the same identifier + * is returned as is. If the identifier is previously used, some additional + * characters are appended to the identifier to make it unique. + * Also empty string is not accepted as an identifier but some characters are + * provided as an identifier if an empty identifier is requested. + * \param identifier the identifier. + * \return a unique identifier. + */ + static QString provideUniqueIdentifier(const QString &identifier); + + //! A list of used mashup canvas identifiers in this process + static QSet allMashupCanvasIdentifiers; +}; + +#endif // DUIMASHUPCANVAS_P_H diff --git a/src/mashup/mashup/duimashupcanvasmodel.cpp b/src/mashup/mashup/duimashupcanvasmodel.cpp new file mode 100644 index 000000000..3e2dc604e --- /dev/null +++ b/src/mashup/mashup/duimashupcanvasmodel.cpp @@ -0,0 +1,26 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duimashupcanvasmodel.h" +#include "gen_duimashupcanvasmodeldata.h" + +void DuiMashupCanvasModel::dataStoresModified() +{ + memberModified(DataStores); +} diff --git a/src/mashup/mashup/duimashupcanvasmodel.h b/src/mashup/mashup/duimashupcanvasmodel.h new file mode 100644 index 000000000..a4b9ab852 --- /dev/null +++ b/src/mashup/mashup/duimashupcanvasmodel.h @@ -0,0 +1,54 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIMASHUPCANVASMODEL_H_ +#define DUIMASHUPCANVASMODEL_H_ + +#include +#include + +class DuiWidget; +class DuiDataStore; + +typedef QMap DataStoreMap; + +/*! + * DuiMashupCanvasModel is the model class for DuiMashupCanvas. + */ +class DUI_EXPORT DuiMashupCanvasModel : public DuiWidgetModel +{ + Q_OBJECT + DUI_MODEL_INTERNAL(DuiMashupCanvasModel) + +public: + //! A list of widgets + DUI_MODEL_PTR_PROPERTY(DataStoreMap *, dataStores, DataStores, true, NULL) + + //! A list of names of the applet categories to show in this mashup canvas + DUI_MODEL_PROPERTY(QStringList, categories, Categories, true, QStringList()) + +public: + /*! + * Emits the memberModified() signal for dataStores. Can be used + * when the data pointed to by dataStores has changed. + */ + void dataStoresModified(); +}; + +#endif /* DUIMASHUPCANVASMODEL_H_ */ diff --git a/src/mashup/mashup/duimashupcanvasview.cpp b/src/mashup/mashup/duimashupcanvasview.cpp new file mode 100644 index 000000000..43af656b4 --- /dev/null +++ b/src/mashup/mashup/duimashupcanvasview.cpp @@ -0,0 +1,232 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiviewcreator.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "duimashupcanvasview.h" +#include "duimashupcanvasview_p.h" +#include "duimashupcanvas.h" +#include "duiappletinventory.h" +#include "duiappletinstancemanager.h" +#include "duidatastore.h" +#include "duilocale.h" + +DuiMashupCanvasViewPrivate::DuiMashupCanvasViewPrivate() : + controller(NULL), + mainLayout(new QGraphicsLinearLayout(Qt::Vertical)), + appletInventoryWindow(NULL) +{ +} + +DuiMashupCanvasViewPrivate::~DuiMashupCanvasViewPrivate() +{ + // Destroying the window destroys it's children (the viewport, layouts, button...) + delete appletInventoryWindow; +} + +void DuiMashupCanvasViewPrivate::init() +{ + DuiLayout *dl = new DuiLayout; + dl->setAnimation(NULL); + layout = dl; + mainLayout->addItem(layout); + layoutPolicy = new DuiFlowLayoutPolicy(dl); + appletInventoryButton = new DuiButton; + appletInventory = new DuiAppletInventory; + appletInventoryWindow = new DuiModalSceneWindow; + appletInventoryViewport = new DuiPannableViewport(appletInventoryWindow); + + // Put the applet inventory inside a viewport + appletInventoryViewport->setWidget(appletInventory); + + // Set the applet installation source libraries for the applet inventory. + // TODO: this is currently a fake installation source to provide some demo functionality. + // Once the real installation sources are known, they will be added here. + appletInventory->setInstallationSources(QStringList("libfakeinstallationsource.so")); + + // TODO: FIXME - this needs to have the scene specified, + // temporarily uses currently active DuiWindow's scene. + QSize sceneSize = DuiApplication::activeWindow()->visibleSceneSize(); + + appletInventoryViewport->setMinimumSize(sceneSize); + appletInventoryViewport->setMaximumSize(sceneSize); + + // Create a dialog layout + QGraphicsLinearLayout *dialogLayout = new QGraphicsLinearLayout(); + dialogLayout->setContentsMargins(0, 0, 0, 0); + dialogLayout->addItem(appletInventoryViewport); + appletInventoryWindow->setLayout(dialogLayout); + appletInventoryWindow->setObjectName("DuiAppletInventoryWindow"); + + // Create an applet inventory button + appletInventoryButton->setObjectName("DuiAppletInventoryButton"); + //~ uispec-document ??? FIXME + //% "Applet Library" + appletInventoryButton->setText(qtTrId("qtn_appl_inventory")); + + // Add the applet inventory button to a horizontal layout for centering + QGraphicsLinearLayout *l = new QGraphicsLinearLayout(Qt::Horizontal); + l->setContentsMargins(0, 0, 0, 0); + l->addStretch(); + l->addItem(appletInventoryButton); + l->addStretch(); + + // Add the horizontal layout to the main layout + mainLayout->addItem(l); +} + +void DuiMashupCanvasViewPrivate::addToLayout(DuiWidget *widget, int index) +{ + if (index >= 0) { + layoutPolicy->insertItem(index, widget); + } else { + layoutPolicy->addItem(widget); + } +} + +DuiMashupCanvasView::DuiMashupCanvasView(DuiMashupCanvas *controller) : + DuiWidgetView(* new DuiMashupCanvasViewPrivate, controller) +{ + Q_D(DuiMashupCanvasView); + d->q_ptr = this; + d->init(); + + init(controller); +} + +DuiMashupCanvasView::DuiMashupCanvasView(DuiMashupCanvasViewPrivate &dd, DuiMashupCanvas *controller) : + DuiWidgetView(dd, controller) +{ + init(controller); +} + +DuiMashupCanvasView::~DuiMashupCanvasView() +{ +} + +void DuiMashupCanvasView::init(DuiMashupCanvas *controller) +{ + Q_D(DuiMashupCanvasView); + d->controller = controller; + d->controller->setLayout(d->mainLayout); + + // Set up the applet inventory + d->appletInventory->setMashupCanvas(*controller); + connect(d->appletInventory, SIGNAL(hideAppletInventory()), this, SLOT(hideAppletInventory())); + connect(d->appletInventory, SIGNAL(appletUninstalled(QString)), controller->appletInstanceManager(), SLOT(appletUninstalled(QString))); + + // Connect the applet inventory button clicking signal + QObject::connect(d->appletInventoryButton, SIGNAL(clicked()), this, SLOT(showAppletInventory())); + + // Get informed about orientation changes + // TODO: FIXME - this needs to have the scene specified, + // temporarily uses currently active DuiWindow's scene. + connect(DuiApplication::activeWindow(), SIGNAL(orientationChanged(Dui::Orientation)), this, SLOT(orientationChanged(Dui::Orientation))); +} + +void DuiMashupCanvasView::orientationChanged(const Dui::Orientation &) +{ + Q_D(DuiMashupCanvasView); + + // TODO: FIXME - this needs to have the scene specified, + // temporarily uses currently active DuiWindow's scene. + QSize sceneSize = DuiApplication::activeWindow()->visibleSceneSize(); + + // Set the applet inventory viewport to the size of the display + d->appletInventoryViewport->setMinimumSize(sceneSize); + d->appletInventoryViewport->setMaximumSize(sceneSize); +} + +void DuiMashupCanvasView::showAppletInventory() +{ + Q_D(DuiMashupCanvasView); + + d->controller->sceneManager()->showWindow(d->appletInventoryWindow); + d->appletInventory->setEnabled(true); +} + +void DuiMashupCanvasView::hideAppletInventory() +{ + Q_D(DuiMashupCanvasView); + + // Disable the applet inventory, so that during the disappear animation of + // the dialog it's not possible to launch another applet + d->appletInventory->setEnabled(false); + + d->controller->sceneManager()->hideWindow(d->appletInventoryWindow); +} + +void DuiMashupCanvasView::setupModel() +{ + Q_D(DuiMashupCanvasView); + + DuiWidgetView::setupModel(); + + d->updateLayout(); + d->appletInventory->setCategories(model()->categories()); +} + +void DuiMashupCanvasView::applyStyle() +{ + Q_D(DuiMashupCanvasView); + d->setupContainers(style()->containerMode()); +} + +void DuiMashupCanvasView::updateData(const QList& modifications) +{ + Q_D(DuiMashupCanvasView); + + bool appletLayoutUpdateNeeded = false; + DuiWidgetView::updateData(modifications); + foreach(const char * member, modifications) { + if (member == DuiMashupCanvasModel::DataStores) { + appletLayoutUpdateNeeded = true; + } else if (member == DuiMashupCanvasModel::Categories) { + d->appletInventory->setCategories(model()->categories()); + } + } + + if (appletLayoutUpdateNeeded) { + d->updateLayout(); + } +} + +void DuiMashupCanvasView::setGeometry(const QRectF &rect) +{ + Q_D(DuiMashupCanvasView); + + // Set new geometry to the widget and to the layout + DuiWidgetView::setGeometry(rect); + + // Geometry change might have affected the geometry of applets. Update all applets data stores. + d->updateData(); +} + +DUI_REGISTER_VIEW_NEW(DuiMashupCanvasView, DuiMashupCanvas) diff --git a/src/mashup/mashup/duimashupcanvasview.h b/src/mashup/mashup/duimashupcanvasview.h new file mode 100644 index 000000000..ed0ad20a1 --- /dev/null +++ b/src/mashup/mashup/duimashupcanvasview.h @@ -0,0 +1,98 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIMASHUPCANVASVIEW_H_ +#define DUIMASHUPCANVASVIEW_H_ + +#include +#include +#include "duimashupcanvasmodel.h" +#include "duimashupcanvasstyle.h" + +class DuiMashupCanvasViewPrivate; +class DuiMashupCanvas; +class DuiContainer; + +/*! + * A view class for the DuiMashupCanvas. + */ +class DUI_EXPORT DuiMashupCanvasView : public DuiWidgetView +{ + Q_OBJECT + DUI_VIEW(DuiMashupCanvasModel, DuiMashupCanvasStyle) + +public: + /*! + * Constructs a new view for DuiMashupCanvas. + * + * \param controller the DuiMashupCanvas controller for the view. + */ + DuiMashupCanvasView(DuiMashupCanvas *controller); + + /*! + * Destroys the DuiMashupCanvasView. + */ + virtual ~DuiMashupCanvasView(); + +protected: + /*! + * Initializes the DuiMashupCanvasView. + */ + void init(DuiMashupCanvas *controller); + + //! \reimp + virtual void setGeometry(const QRectF &rect); + virtual void setupModel(); + virtual void applyStyle(); + //! \reimp_end + + /*! + * Constructs a new view for DuiMashupCanvas. + * + * \param dd the DuiMashupCanvasViewPrivate private class instance to be used. + * \param controller the DuiMashupCanvas controller for the view. + */ + DuiMashupCanvasView(DuiMashupCanvasViewPrivate &dd, DuiMashupCanvas *controller); + +protected slots: + /*! + * \brief A slot for notifying that the applet inventory should be shown + */ + void showAppletInventory(); + + /*! + * \brief A slot for notifying that the applet inventory should be hidden + */ + void hideAppletInventory(); + + /*! + * \brief A slot for getting information about orientation changes + */ + void orientationChanged(const Dui::Orientation &); + + //! \reimp + virtual void updateData(const QList& modifications); + //! \reimp_end + +private: + Q_DISABLE_COPY(DuiMashupCanvasView) + Q_DECLARE_PRIVATE(DuiMashupCanvasView) +}; + +#endif /* DUIMASHUPCANVASVIEW_H_ */ diff --git a/src/mashup/mashup/duimashupcanvasview_p.h b/src/mashup/mashup/duimashupcanvasview_p.h new file mode 100644 index 000000000..598d10cf2 --- /dev/null +++ b/src/mashup/mashup/duimashupcanvasview_p.h @@ -0,0 +1,89 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIMASHUPCANVASVIEW_P_H_ +#define DUIMASHUPCANVASVIEW_P_H_ + +#include "private/duiwidgetview_p.h" +#include "applicationextension/duiextensionareaview_p.h" +#include "duimashupcanvasview.h" + +class DuiLayout; +class DuiFlowLayoutPolicy; +class QGraphicsLinearLayout; +class DuiButton; +class DuiAppletInventory; +class DuiPannableViewport; +class DuiSceneWindow; +class DuiMashupCanvas; + +/*! + * DuiMashupCanvasViewPrivate is the private class for DuiMashupCanvasView. + */ +class DuiMashupCanvasViewPrivate : public DuiExtensionAreaViewPrivate +{ + Q_DECLARE_PUBLIC(DuiMashupCanvasView) + +public: + /*! + * Constructs a DuiMashupCanvasViewPrivate private class for + * DuiMashupCanvasView. + */ + DuiMashupCanvasViewPrivate(); + + /*! + * Destroys the DuiMashupCanvasViewPrivate. + */ + virtual ~DuiMashupCanvasViewPrivate(); + + /*! + * Initializes the class + */ + void init(); + + /*! + * Adds a widget to the layout + * \param widget the widget + * \param index the index to insert or -1 to add to the end + */ + virtual void addToLayout(DuiWidget *widget, int index = -1); + + //! The DuiMashupCanvas controller. + DuiMashupCanvas *controller; + + //! The main layout of the mashup canvas. + QGraphicsLinearLayout *mainLayout; + + //! Layout policy used to layout the applet instances on this canvas. + DuiFlowLayoutPolicy *layoutPolicy; + + //! Applet inventory button + DuiButton *appletInventoryButton; + + //! Applet inventory for this mashup + DuiAppletInventory *appletInventory; + + //! DuiSceneWindow for the applet inventory + DuiSceneWindow *appletInventoryWindow; + + //! Pannable viewport in which the applet inventory is displayed + DuiPannableViewport *appletInventoryViewport; +}; + +#endif /* DUIMASHUPCANVASVIEW_P_H_ */ diff --git a/src/mashup/mashup/duisubdatastore.cpp b/src/mashup/mashup/duisubdatastore.cpp new file mode 100644 index 000000000..45c0f504d --- /dev/null +++ b/src/mashup/mashup/duisubdatastore.cpp @@ -0,0 +1,94 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duisubdatastore.h" + +DuiSubDataStore::DuiSubDataStore(const QString &prefix, DuiDataStore &baseStore) : + _prefix(prefix), + _prefixLength(prefix.size()), + _baseStore(baseStore) +{ + connect(&baseStore, SIGNAL(valueChanged(QString, QVariant)), this, SLOT(baseStoreValueChanged(QString, QVariant))); +} + +DuiSubDataStore::~DuiSubDataStore() +{ +} + +QString DuiSubDataStore::prefix() const +{ + return _prefix; +} + +bool DuiSubDataStore::createValue(const QString &key, const QVariant &value) +{ + return _baseStore.createValue(_prefix + key, value); +} + + +bool DuiSubDataStore::setValue(const QString &key, const QVariant &value) +{ + return _baseStore.setValue(_prefix + key, value); +} + + +QVariant DuiSubDataStore::value(const QString &key) const +{ + return _baseStore.value(_prefix + key); +} + +QStringList DuiSubDataStore::allKeys() const +{ + QStringList keys = _baseStore.allKeys(); + QStringList result; + foreach(QString aKey, keys) { + if (aKey.startsWith(_prefix)) { + result.append(aKey.remove(0, _prefixLength)); + } + } + return result; +} + +void DuiSubDataStore::remove(const QString &key) +{ + _baseStore.remove(_prefix + key); +} + +void DuiSubDataStore::clear() +{ + QStringList keys = _baseStore.allKeys(); + + foreach(const QString & aKey, keys) { + if (aKey.startsWith(_prefix)) { + _baseStore.remove(aKey); + } + } +} + +bool DuiSubDataStore::contains(const QString &key) const +{ + return _baseStore.contains(_prefix + key); +} + +void DuiSubDataStore::baseStoreValueChanged(const QString &key, const QVariant &value) +{ + if (key.startsWith(_prefix)) { + emit valueChanged(key.mid(_prefixLength), value); + } +} diff --git a/src/mashup/mashup/duisubdatastore.h b/src/mashup/mashup/duisubdatastore.h new file mode 100644 index 000000000..82fb55fcc --- /dev/null +++ b/src/mashup/mashup/duisubdatastore.h @@ -0,0 +1,82 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISUBDATASTORE_H +#define DUISUBDATASTORE_H + +#include "duidatastore.h" + +/*! + * DuiSubDataStore takes another DataStore object and gives a limited view to it. + * + * DuiSubDataStore doesn't store any data by itself but instead it uses another DataStore + * object for this. DuiSubDataStore offers a limited view to the keys of the underlying DataStore. + * It only allows access to keys with a given prefix. This can be seen as a namespace limitation. + * The prefix or namespace as well as the underlying DataStore object are given at + * construction time and they can't be changed after that. + */ +class DUI_EXPORT DuiSubDataStore : public DuiDataStore +{ + Q_OBJECT + + //! The prefix of the sub data store. + QString _prefix; + //! The length of the prefix string. Calculated only once for efficiency. + int _prefixLength; + //! The base data store object this object uses. + DuiDataStore &_baseStore; + +public: + /*! + * Constructs a new DuiSubDataStore view to another DataStore object. + * \param prefix the namespace for the DuiSubDataStore. + * \param baseStore the underlying base DataStore object. + */ + DuiSubDataStore(const QString &prefix, DuiDataStore &baseStore); + + /*! + * Destructs the DuiSubDataStore. + */ + virtual ~DuiSubDataStore(); + + /*! + * Gets the prefix or namespace that was given to the class at construction time. + * \return the prefix. + */ + QString prefix() const; + + //! \reimp + virtual bool createValue(const QString &key, const QVariant &value); + virtual bool setValue(const QString &key, const QVariant &value); + virtual QVariant value(const QString &key) const; + virtual QStringList allKeys() const; + virtual void remove(const QString &key); + virtual void clear(); + virtual bool contains(const QString &key) const; + //! \reimp_end + +private slots: + /*! + * A slot for getting information about changes in the basestore. + * If the key has the prefix of this subdatastore, the valueChanged signal is emitted. + */ + void baseStoreValueChanged(const QString &key, const QVariant &value); +}; + +#endif // DUISUBDATASTORE_H diff --git a/src/mashup/mashup/mashup.pri b/src/mashup/mashup/mashup.pri new file mode 100644 index 000000000..af6cd13fa --- /dev/null +++ b/src/mashup/mashup/mashup.pri @@ -0,0 +1,78 @@ +include(../mashup.pri) +MASHUP_MASHUP_SRC_DIR = $$MASHUP_SRC_DIR/mashup +INCLUDEPATH += $$MASHUP_SRC_DIR/mashup \ + $$GEN_DIR + +duigen_model_mashup.name = duigenerator \ + model +duigen_model_mashup.input = MASHUP_WIDGET_MODEL_HEADERS +duigen_model_mashup.output = $$GEN_DIR/gen_${QMAKE_FILE_BASE}data.cpp +duigen_model_mashup.depends = ../duigen/duigen +duigen_model_mashup.commands += ../duigen/duigen --model ${QMAKE_FILE_NAME} $$GEN_DIR +duigen_model_mashup.clean += $$GEN_DIR/gen_* +duigen_model_mashup.CONFIG = target_predeps no_link +duigen_model_mashup.variable_out = GENERATED_SOURCES + +QMAKE_EXTRA_COMPILERS += duigen_model_mashup +HEADERS += $$MASHUP_MASHUP_SRC_DIR/duiappletbutton.h \ + $$MASHUP_MASHUP_SRC_DIR/duiappletsharedmutex.h \ + $$MASHUP_MASHUP_SRC_DIR/duiappletsharedmutex_p.h \ + $$MASHUP_MASHUP_SRC_DIR/duiapplethandle.h \ + $$MASHUP_MASHUP_SRC_DIR/duiapplethandle_p.h \ + $$MASHUP_MASHUP_SRC_DIR/duiapplethandleview.h \ + $$MASHUP_MASHUP_SRC_DIR/duiapplethandleview_p.h \ + $$MASHUP_MASHUP_SRC_DIR/duiapplethandleswview.h \ + $$MASHUP_MASHUP_SRC_DIR/duiapplethandleswview_p.h \ + $$MASHUP_MASHUP_SRC_DIR/duiapplethandleglesview.h \ + $$MASHUP_MASHUP_SRC_DIR/duiapplethandleglesview_p.h \ + $$MASHUP_MASHUP_SRC_DIR/duiappletinstancemanager.h \ + $$MASHUP_MASHUP_SRC_DIR/duiappletinstancedata.h \ + $$MASHUP_MASHUP_SRC_DIR/duiappletinventory.h \ + $$MASHUP_MASHUP_SRC_DIR/duiappletinventoryview.h \ + $$MASHUP_MASHUP_SRC_DIR/duiappletinventoryview_p.h \ + $$MASHUP_MASHUP_SRC_DIR/duiappletinventorymodel.h \ + $$MASHUP_MASHUP_SRC_DIR/duidatastore.h \ + $$MASHUP_MASHUP_SRC_DIR/duidataaccess.h \ + $$MASHUP_MASHUP_SRC_DIR/duiaggregatedataaccess.h \ + $$MASHUP_MASHUP_SRC_DIR/duiaggregatedataaccess_p.h \ + $$MASHUP_MASHUP_SRC_DIR/duifiledatastore.h \ + $$MASHUP_MASHUP_SRC_DIR/duimashupcanvas.h \ + $$MASHUP_MASHUP_SRC_DIR/duimashupcanvas_p.h \ + $$MASHUP_MASHUP_SRC_DIR/duimashupcanvasmodel.h \ + $$MASHUP_MASHUP_SRC_DIR/duimashupcanvasview.h \ + $$MASHUP_MASHUP_SRC_DIR/duimashupcanvasview_p.h \ + $$MASHUP_MASHUP_SRC_DIR/duisubdatastore.h \ + $$MASHUP_MASHUP_SRC_DIR/duiapplethandlemodel.h \ + $$MASHUP_MASHUP_SRC_DIR/duiappletloader.h \ + $$MASHUP_MASHUP_SRC_DIR/duiappletid.h \ + $$MASHUP_MASHUP_SRC_DIR/duiappletsettings.h \ + $$MASHUP_MASHUP_SRC_DIR/duiappletsettingsdialog.h \ + $$MASHUP_MASHUP_SRC_DIR/duigconfdatastore.h \ + $$MASHUP_MASHUP_SRC_DIR/duiappletinstancemanagerdbusadaptor.h + +SOURCES += $$MASHUP_MASHUP_SRC_DIR/duiappletbutton.cpp \ + $$MASHUP_MASHUP_SRC_DIR/duiappletsharedmutex.cpp \ + $$MASHUP_MASHUP_SRC_DIR/duiapplethandle.cpp \ + $$MASHUP_MASHUP_SRC_DIR/duiapplethandleview.cpp \ + $$MASHUP_MASHUP_SRC_DIR/duiapplethandleswview.cpp \ + $$MASHUP_MASHUP_SRC_DIR/duiapplethandleglesview.cpp \ + $$MASHUP_MASHUP_SRC_DIR/duiappletinstancemanager.cpp \ + $$MASHUP_MASHUP_SRC_DIR/duiappletinstancedata.cpp \ + $$MASHUP_MASHUP_SRC_DIR/duiappletinventory.cpp \ + $$MASHUP_MASHUP_SRC_DIR/duiappletinventoryview.cpp \ + $$MASHUP_MASHUP_SRC_DIR/duiaggregatedataaccess.cpp \ + $$MASHUP_MASHUP_SRC_DIR/duifiledatastore.cpp \ + $$MASHUP_MASHUP_SRC_DIR/duimashupcanvas.cpp \ + $$MASHUP_MASHUP_SRC_DIR/duimashupcanvasmodel.cpp \ + $$MASHUP_MASHUP_SRC_DIR/duimashupcanvasview.cpp \ + $$MASHUP_MASHUP_SRC_DIR/duisubdatastore.cpp \ + $$MASHUP_MASHUP_SRC_DIR/duiappletloader.cpp \ + $$MASHUP_MASHUP_SRC_DIR/duiappletid.cpp \ + $$MASHUP_MASHUP_SRC_DIR/duiappletsettings.cpp \ + $$MASHUP_MASHUP_SRC_DIR/duiappletsettingsdialog.cpp \ + $$MASHUP_MASHUP_SRC_DIR/duigconfdatastore.cpp \ + $$MASHUP_MASHUP_SRC_DIR/duiappletinstancemanagerdbusadaptor.cpp + +MASHUP_WIDGET_MODEL_HEADERS += $$MASHUP_MASHUP_SRC_DIR/duiapplethandlemodel.h \ + $$MASHUP_MASHUP_SRC_DIR/duimashupcanvasmodel.h \ + $$MASHUP_MASHUP_SRC_DIR/duiappletinventorymodel.h diff --git a/src/notification/duinotification.cpp b/src/notification/duinotification.cpp new file mode 100644 index 000000000..f8153779b --- /dev/null +++ b/src/notification/duinotification.cpp @@ -0,0 +1,114 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duinotification.h" +#include "duinotification_p.h" +#include "duinotificationmanager.h" +#include "duiremoteaction.h" + +DuiNotificationPrivate::DuiNotificationPrivate() : + _id(0) +{ +} + +DuiNotificationPrivate::~DuiNotificationPrivate() +{ +} + + +DuiNotification::DuiNotification(DuiNotificationPrivate &dd) : + d_ptr(&dd) +{ +} + +DuiNotification::DuiNotification(const QString &eventType, const QString &summary, const QString &body, const QString &imageURI, const DuiRemoteAction &action, uint count, bool persistent) : + d_ptr(new DuiNotificationPrivate) +{ + Q_D(DuiNotification); + if (!summary.isNull() || !body.isNull() || !imageURI.isNull() || !action.toString().isNull()) + d->_id = DuiNotificationManager::instance()->addNotification(0, eventType, summary, body, action.toString(), imageURI, count, persistent); + else + d->_id = DuiNotificationManager::instance()->addNotification(0, eventType, persistent); +} + +DuiNotification::DuiNotification(const DuiNotificationGroup &group, const QString &eventType, const QString &summary, const QString &body, const QString &imageURI, const DuiRemoteAction &action) : + d_ptr(new DuiNotificationPrivate) +{ + Q_D(DuiNotification); + if (!summary.isNull() || !body.isNull() || !imageURI.isNull() || !action.toString().isNull()) + d->_id = DuiNotificationManager::instance()->addNotification(group.id(), eventType, summary, body, action.toString(), imageURI); + else + d->_id = DuiNotificationManager::instance()->addNotification(group.id(), eventType); +} + +DuiNotification::DuiNotification(uint id) : + d_ptr(new DuiNotificationPrivate) +{ + Q_D(DuiNotification); + d->_id = id; +} + +DuiNotification::~DuiNotification() +{ + delete d_ptr; +} + +uint DuiNotification::id() const +{ + Q_D(const DuiNotification); + return d->_id; +} + +bool DuiNotification::update(const QString &eventType, const QString &summary, const QString &body, const QString &imageURI, uint count, const DuiRemoteAction &action) +{ + Q_D(DuiNotification); + if (!summary.isNull() || !body.isNull() || !imageURI.isNull() || !action.toString().isNull()) + return DuiNotificationManager::instance()->updateNotification(d->_id, eventType, summary, body, action.toString(), imageURI, count); + else + return DuiNotificationManager::instance()->updateNotification(d->_id, eventType); +} + +bool DuiNotification::remove() +{ + if (!isValid()) { + return false; + } else { + Q_D(DuiNotification); + uint id = d->_id; + d->_id = 0; + return DuiNotificationManager::instance()->removeNotification(id); + } +} + +bool DuiNotification::isValid() const +{ + Q_D(const DuiNotification); + return d->_id != 0; +} + +QList DuiNotification::notifications() +{ + QList idList = DuiNotificationManager::instance()->notificationIdList(); + QList notifications; + foreach(uint i, idList) { + DuiNotification *notification = new DuiNotification(i); + notifications.append(notification); + } + return notifications; +} diff --git a/src/notification/duinotification.h b/src/notification/duinotification.h new file mode 100644 index 000000000..4c936c8f1 --- /dev/null +++ b/src/notification/duinotification.h @@ -0,0 +1,204 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUINOTIFICATION_H_ +#define DUINOTIFICATION_H_ + +#include "duinotificationgroup.h" + +#include +#include +#include + +class DuiNotificationPrivate; +class QString; + +/*! + \class DuiNotification + \brief A class that represents a system notification. + + \ingroup widgets + + \section DuiNotificationOverview Overview + Notifications provide means to communicate system information and status updates to the user, + without blocking the UI or requiring the user to switch to another view. Notifications can be + done through visual, audio or haptic means. + + Dialogs and notifications are related to each other, but separate components. All Dialogs are modal, + i.e. elements that do not go away from the screen without requiring user interactions, whereas all + notifications are temporal elements (i.e. modeless) that do not require interactions from the user + (although they can sometimes also provide them). + + Certain notifications are related to the communication activities (like SMS, email, feed updates etc.), + and notifications relating to application and system behaviour (like connection lost, battery low etc.). + Communication activities display incoming event notifications. + + When an instance of this class is created a notification is created unless the instance represents an + already existing notification and is created using a known notification ID. + + A list of notifications already created can be requested, but in this case a DuiApplication + instance must have been created before any notifications were created and before the request + itself. + + \sa \ref notifications + + \section DuiNotificationInteractions Interactions + Notifications can be non-interactive (for information only) or interactive: the interactive + notifications provide information, but they also provide a way for interacting with the notification, + for example to fix a connectivity problem. Notifications are always modeless components - modal + "notifications" are specified with Dialogs. Images on this page are for illustrational purposes only. + In case that images and text conflict each other, the text should be followed. + + \section DuiNotificationUsageGuidelines Usage guidelines + \li Notifications are intended to communicate information when the foreground application UI is not + able to do this. If the foreground application UI can already communicate the information, a + separate Notification shouldn't be shown anymore. + \li Notifications are temporal elements, i.e. they are dismissed from screen after a certain time + (or timeout). + \li Incoming events aim to provide a centralized method for applications to provide persistent + notifications to the users. + \li Use non-interactive notifications (status banners) to display feedback/progress/notifications for + successful actions, if other parts of the foreground UI cannot be directly utilized. + \li Consider using interactive status banners for notifications in error cases, exceptions etc. that + can either be dismissed or then reacted upon. The interactive elements are essentially shortcut + functions, intended to save time from the users. No use case should fail because the user fails to + press the interactive status banner. + \li DuiInfoBanner class can be used to show in-process notifications directly without having to use the + notification framework. + + \section DuiNotificationPersistence Persistence + Notifications created as persistent are stored by the notification system and are returned by the + DuiNotification::notifications() even after a reboot. + + \note A DuiApplication instance must be created before creating any persistent notifications. + + \section DuiNotificationVariants Variants + The notification component has the following variants: + - \link DuiInfoBannerEventView Event banner \endlink + - \link DuiInfoBannerInformationView Information banner \endlink (for status, progress and errors) + + \section ExampleWidgetOpenIssues Open issues + \li Rules about system modal notifications to be added. + \li Now there is no separation between foreground application status banners vs. background and system + status banners. +*/ + +class DUI_EXPORT DuiNotification +{ +public: + /*! + * Creates a new representation of a notification. A notification is + * automatically created and is given an ID by the notification manager. + * + * \param eventType the event type of the notification + * \param summary the summary text to be used in the notification. Defaults to no summary text. + * \param body the body text to be used in the notification. Defaults to no body text. + * \param imageURI the ID of the icon to be used in the notification. Defaults to no image URI. + * \param action the action to be executed when the notification is activated. Defaults to no action. + * \param count the number of items inside this notification + * \param persistent \c true if the notification should be persistent, \c false otherwise + */ + explicit DuiNotification(const QString &eventType, const QString &summary = QString(), const QString &body = QString(), const QString &imageURI = QString(), const DuiRemoteAction &action = DuiRemoteAction(), uint count = 1, bool persistent = false); + + /*! + * Creates a new representation of a notification. A notification is + * automatically created into the given notification group and is given + * an ID by the notification manager. + * + * \param group the notification group to put the notification in + * \param eventType the event type of the notification + * \param summary the summary text to be used in the notification. Defaults to no summary text. + * \param body the body text to be used in the notification. Defaults to no body text. + * \param imageURI the ID of the icon to be used in the notification. Defaults to no image URI. + * \param action the action to be executed when the notification is activated. Defaults to no action. + */ + explicit DuiNotification(const DuiNotificationGroup &group, const QString &eventType, const QString &summary = QString(), const QString &body = QString(), const QString &imageURI = QString(), const DuiRemoteAction &action = DuiRemoteAction()); + + /*! + * Creates a representation of an existing notification. + * Should be used to get a handle to an existing notification + * with a known ID. + * + * \param id the ID of the existing notification + */ + explicit DuiNotification(unsigned int id); + + /*! + * Destroys the class that represents a notification. + */ + virtual ~DuiNotification(); + + /*! + * Returns the ID of the notification. + * + * \return the ID of the notification + */ + unsigned int id() const; + + /*! + * Updates the notification. + * + * \param eventType the event type of the notification + * \param summary the summary text to be used in the notification. Defaults to no summary text. + * \param body the body text to be used in the notification. Defaults to no body text. + * \param imageURI the ID of the icon to be used in the notification. Defaults to no image URI. + * \param count the number of items inside this notification + * \param action the action to be executed when the notification is activated. Defaults to no action. + * \return true if the update succeeded, false otherwise + */ + bool update(const QString &eventType, const QString &summary = QString(), const QString &body = QString(), const QString &imageURI = QString(), uint count = 1, const DuiRemoteAction &action = DuiRemoteAction()); + + /*! + * Removes a notification. + * + * \return true if the removal succeeded, false otherwise + */ + bool remove(); + + /*! + * Returns whether the notification is valid + * + * \return true if the notification is valid, false otherwise + */ + bool isValid() const; + + /*! + * Returns a list of notifications created by this application but which + * have not been dismissed by the user yet. Caller of this function gets + * the ownership of the notifications, and is responsible for freeing them. + * + * \return list of notifications + */ + static QList notifications(); + +protected: + /*! + * A constructor to be called by the derived classes. + * \param dd a derived private class object. + */ + DuiNotification(DuiNotificationPrivate &dd); + + //! A pointer to the private implementation class + DuiNotificationPrivate *d_ptr; + + Q_DECLARE_PRIVATE(DuiNotification) + +}; + +#endif /* DUINOTIFICATION_H_ */ diff --git a/src/notification/duinotification_p.h b/src/notification/duinotification_p.h new file mode 100644 index 000000000..2b0337e16 --- /dev/null +++ b/src/notification/duinotification_p.h @@ -0,0 +1,43 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUINOTIFICATION_P_H +#define DUINOTIFICATION_P_H + +/*! + * A private class for DuiNotification + */ +class DuiNotificationPrivate +{ +public: + /*! + * Constructor + */ + DuiNotificationPrivate(); + + /*! + * Destructor + */ + virtual ~DuiNotificationPrivate(); + + //! The ID of the notification + unsigned int _id; +}; + +#endif // DUINOTIFICATION_P_H diff --git a/src/notification/duinotificationgroup.cpp b/src/notification/duinotificationgroup.cpp new file mode 100644 index 000000000..9d619bb4c --- /dev/null +++ b/src/notification/duinotificationgroup.cpp @@ -0,0 +1,92 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duinotificationgroup.h" +#include "duinotificationgroup_p.h" +#include "duinotificationmanager.h" +#include "duiremoteaction.h" + +DuiNotificationGroupPrivate::DuiNotificationGroupPrivate() : + _id(0) +{ +} + +DuiNotificationGroupPrivate::~DuiNotificationGroupPrivate() +{ +} + +DuiNotificationGroup::DuiNotificationGroup(DuiNotificationGroupPrivate &dd) : + d_ptr(&dd) +{ +} + +DuiNotificationGroup::DuiNotificationGroup(const QString &eventType, const QString &summary, const QString &body, const QString &imageURI, const DuiRemoteAction &action, uint count, bool persistent) : + d_ptr(new DuiNotificationGroupPrivate) +{ + Q_D(DuiNotificationGroup); + if (!summary.isNull() || !body.isNull() || !imageURI.isNull() || !action.toString().isNull()) + d->_id = DuiNotificationManager::instance()->addGroup(eventType, summary, body, action.toString(), imageURI, count, persistent); + else + d->_id = DuiNotificationManager::instance()->addGroup(eventType, persistent); +} + +DuiNotificationGroup::DuiNotificationGroup(unsigned int id) : + d_ptr(new DuiNotificationGroupPrivate) +{ + Q_D(DuiNotificationGroup); + d->_id = id; +} + +DuiNotificationGroup::~DuiNotificationGroup() +{ + delete d_ptr; +} + +uint DuiNotificationGroup::id() const +{ + Q_D(const DuiNotificationGroup); + return d->_id; +} + +bool DuiNotificationGroup::update(const QString &eventType, const QString &summary, const QString &body, const QString &imageURI, uint count, const DuiRemoteAction &action) +{ + Q_D(DuiNotificationGroup); + if (!summary.isNull() || !body.isNull() || !imageURI.isNull() || !action.toString().isNull()) + return DuiNotificationManager::instance()->updateGroup(d->_id, eventType, summary, body, action.toString(), imageURI, count); + else + return DuiNotificationManager::instance()->updateGroup(d->_id, eventType); +} + +bool DuiNotificationGroup::remove() +{ + if (!isValid()) { + return false; + } else { + Q_D(DuiNotificationGroup); + uint id = d->_id; + d->_id = 0; + return DuiNotificationManager::instance()->removeGroup(id); + } +} + +bool DuiNotificationGroup::isValid() const +{ + Q_D(const DuiNotificationGroup); + return d->_id != 0; +} diff --git a/src/notification/duinotificationgroup.h b/src/notification/duinotificationgroup.h new file mode 100644 index 000000000..a01403e49 --- /dev/null +++ b/src/notification/duinotificationgroup.h @@ -0,0 +1,118 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUINOTIFICATIONGROUP_H_ +#define DUINOTIFICATIONGROUP_H_ + +#include +#include +#include +#include + +class DuiNotificationGroupPrivate; + +/*! + * A class that represents a notification group. When an instance of this + * class is created a notification group is created unless the instance + * represents an already existing notification group and is created using a + * known notification group ID. + * + * \sa \ref notifications + */ +class DUI_EXPORT DuiNotificationGroup +{ +public: + /*! + * Creates a new representation of a notification group. A notification + * group is automatically created and is given an ID by the notification + * manager. + * + * \param eventType the event type of the notification group + * \param summary the summary text to be used in the notification group. Defaults to no summary text. + * \param body the body text to be used in the notification group. Defaults to no body text. + * \param imageURI the ID of the icon to be used in the notification group. Defaults to no image URI. + * \param action the action to be executed when the notification group is activated. Defaults to no action. + * \param count the number of notifications in this group + * \param persistent \c true if the notifications in this group should be persistent, \c false otherwise + */ + explicit DuiNotificationGroup(const QString &eventType, const QString &summary = QString(), const QString &body = QString(), const QString &imageURI = QString(), const DuiRemoteAction &action = DuiRemoteAction(), uint count = 1, bool persistent = false); + + /*! + * Creates a representation of an existing notification group. + * Should be used to get a handle to an existing notification group + * with a known ID. + * + * \param id the ID of the existing notification group + */ + explicit DuiNotificationGroup(unsigned int id); + + /*! + * Destroys the class that represents a notification group. + */ + virtual ~DuiNotificationGroup(); + + /*! + * Returns the ID of the notification group. + * + * \return the ID of the notification group + */ + unsigned int id() const; + + /*! + * Updates the notification group. + * + * \param eventType the event type of the notification group + * \param summary the summary text to be used in the notification group. Defaults to no summary text. + * \param body the body text to be used in the notification group. Defaults to no body text. + * \param imageURI the ID of the icon to be used in the notification group. Defaults to no image URI. + * \param count the number of notifications in this group + * \param action the action to be executed when the notification group is activated. Defaults to no action. + * \return true if the update succeeded, false otherwise + */ + bool update(const QString &eventType, const QString &summary = QString(), const QString &body = QString(), const QString &imageURI = QString(), uint count = 1, const DuiRemoteAction &action = DuiRemoteAction()); + + /*! + * Removes the notification group and all notifications in the group. + * + * \return true if the removal succeeded, false otherwise + */ + bool remove(); + + /*! + * Returns whether the notification group is valid + * + * \return true if the notification group is valid, false otherwise + */ + bool isValid() const; + +protected: + /*! + * A constructor to be called by the derived classes. + * \param dd a derived private class object. + */ + DuiNotificationGroup(DuiNotificationGroupPrivate &dd); + + //! A pointer to the private implementation class + DuiNotificationGroupPrivate *d_ptr; + + Q_DECLARE_PRIVATE(DuiNotificationGroup) + +}; + +#endif /* DUINOTIFICATIONGROUP_H_ */ diff --git a/src/notification/duinotificationgroup_p.h b/src/notification/duinotificationgroup_p.h new file mode 100644 index 000000000..94a89b825 --- /dev/null +++ b/src/notification/duinotificationgroup_p.h @@ -0,0 +1,43 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUI_NOTIFICATION_GROUP_P_H +#define DUI_NOTIFICATION_GROUP_P_H + +/*! + * A private class for DuiNotificationGroup + */ +class DuiNotificationGroupPrivate +{ +public: + /*! + * Constructor + */ + DuiNotificationGroupPrivate(); + + /*! + * Destructor + */ + virtual ~DuiNotificationGroupPrivate(); + + //! The ID of the notification group + unsigned int _id; +}; + +#endif // DUI_NOTIFICATION_GROUP_P_H diff --git a/src/notification/duinotificationmanager.cpp b/src/notification/duinotificationmanager.cpp new file mode 100644 index 000000000..743b1e68d --- /dev/null +++ b/src/notification/duinotificationmanager.cpp @@ -0,0 +1,122 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duinotificationmanager.h" +#include "duifiledatastore.h" +#include +#include + +static const QString DATA_PATH = QDir::homePath() + QString("/.config/libdui/notifications/"); + +DuiNotificationManager::DuiNotificationManager() : + proxy("org.maemo.dui.NotificationManager", "/", QDBusConnection::sessionBus()), + userId(0) +{ + if (!DuiApplication::instance()) { + qWarning("DuiApplication instance should be created before creating persistent notifications"); + return; + } + + + if (!QDir::root().exists(DATA_PATH) && !QDir::root().mkpath(DATA_PATH)) + return; + + DuiFileDataStore userIdStore(DATA_PATH + DuiApplication::appName() + ".data"); + + if (!userIdStore.isReadable()) + return; + + QString appId = QString("id/") + DuiApplication::appName(); + + // Check if a userId for an application with this name already exists + if (userIdStore.contains(appId)) { + userId = userIdStore.value(appId).toUInt(); + } else { + if (!userIdStore.isWritable()) + return; + // Fetch a new id from the notification manager over DBus + userId = proxy.notificationUserId(); + userIdStore.createValue(appId, userId); + } +} + +DuiNotificationManager::~DuiNotificationManager() +{ +} + +DuiNotificationManager *DuiNotificationManager::instance() +{ + static DuiNotificationManager notificationManagerInstance; + return ¬ificationManagerInstance; +} + +uint DuiNotificationManager::addGroup(const QString &eventType, const QString &summary, const QString &body, const QString &action, const QString &imageURI, uint count, bool persistent) +{ + return proxy.addGroup(userId, eventType, summary, body, action, imageURI, count, persistent); +} + +uint DuiNotificationManager::addGroup(const QString &eventType, bool persistent) +{ + return proxy.addGroup(userId, eventType, persistent); +} + +uint DuiNotificationManager::addNotification(uint groupId, const QString &eventType, const QString &summary, const QString &body, const QString &action, const QString &imageURI, uint count, bool persistent) +{ + return proxy.addNotification(userId, groupId, eventType, summary, body, action, imageURI, count, persistent); +} + +uint DuiNotificationManager::addNotification(uint groupId, const QString &eventType, bool persistent) +{ + return proxy.addNotification(userId, groupId, eventType, persistent); +} + +bool DuiNotificationManager::removeGroup(uint groupId) +{ + return proxy.removeGroup(userId, groupId); +} + +bool DuiNotificationManager::removeNotification(uint notificationId) +{ + return proxy.removeNotification(userId, notificationId); +} + +bool DuiNotificationManager::updateGroup(uint groupId, const QString &eventType, const QString &summary, const QString &body, const QString &action, const QString &imageURI, uint count) +{ + return proxy.updateGroup(userId, groupId, eventType, summary, body, action, imageURI, count); +} + +bool DuiNotificationManager::updateGroup(uint groupId, const QString &eventType) +{ + return proxy.updateGroup(userId, groupId, eventType); +} + +bool DuiNotificationManager::updateNotification(uint notificationId, const QString &eventType, const QString &summary, const QString &body, const QString &action, const QString &imageURI, uint count) +{ + return proxy.updateNotification(userId, notificationId, eventType, summary, body, action, imageURI, count); +} + +bool DuiNotificationManager::updateNotification(uint notificationId, const QString &eventType) +{ + return proxy.updateNotification(userId, notificationId, eventType); +} + +QList DuiNotificationManager::notificationIdList() +{ + return proxy.notificationIdList(userId); +} diff --git a/src/notification/duinotificationmanager.h b/src/notification/duinotificationmanager.h new file mode 100644 index 000000000..6272fba61 --- /dev/null +++ b/src/notification/duinotificationmanager.h @@ -0,0 +1,178 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +// Make doxygen skip this internal class +//! \cond +#ifndef DUINOTIFICATIONMANAGER_H_ +#define DUINOTIFICATIONMANAGER_H_ + +#include "duinotificationmanagerproxy.h" + +/*! + * An interface to the notification manager. + * Uses the org.maemo.dui.NotificationManager D-Bus interface with which + * application developers can create and manage notifications. + */ +class DuiNotificationManager +{ +private: + /*! + * Constructs an interface for the notification manager. + */ + DuiNotificationManager(); + + /*! + * Destroys an interface for the notification manager. + */ + virtual ~DuiNotificationManager(); + + //! The D-Bus proxy object for the notification manager interface. + DuiNotificationManagerProxy proxy; + + //! The notification user ID + uint userId; + +public: + /*! + * Returns an instance of the notification manager interface. + * + * \return an instance of the notification manager interface + */ + static DuiNotificationManager *instance(); + + /*! + * Adds a new notification group. + * + * \param eventType the event type of the notification + * \param summary the summary text to be used in the notification + * \param body the body text to be used in the notification + * \param action the ID of the content to be used in the notification + * \param imageURI the ID of the icon to be used in the notification + * \param count the number of items inside this group + * \param persistent \c true if the notification group should be persistent, \c false otherwise + * \return the ID of the new notification group + */ + uint addGroup(const QString &eventType, const QString &summary, const QString &body, const QString &action, const QString &imageURI, uint count, bool persistent); + + /*! + * Adds a new notification group. + * + * \param eventType the event type of the notification + * \param persistent \c true if the notification group should be persistent, \c false otherwise + * \return the ID of the new notification group + */ + uint addGroup(const QString &eventType, bool persistent = false); + + /*! + * Adds a new notification. + * + * \param groupId the ID of the notification group to put the notification in + * \param eventType the event type of the notification + * \param summary the summary text to be used in the notification + * \param body the body text to be used in the notification + * \param action the ID of the content to be used in the notification + * \param imageURI the ID of the icon to be used in the notification + * \param count the number of items inside this notification + * \param persistent \c true if the notification group should be persistent, \c false otherwise + * \return the ID of the new notification + */ + uint addNotification(uint groupId, const QString &eventType, const QString &summary, const QString &body, const QString &action, const QString &imageURI, uint count = 1, bool persistent = false); + + /*! + * Adds a new notification. + * + * \param groupId the ID of the notification group to put the notification in + * \param eventType the event type of the notification + * \param persistent \c true if the notification group should be persistent, \c false otherwise + * \return the ID of the new notification + */ + uint addNotification(uint groupId, const QString &eventType, bool persistent = false); + + /*! + * Removes a notification group and all notifications in the group. + * + * \param groupId the ID of the notification group to be removed + * \return true if the removal succeeded, false otherwise + */ + bool removeGroup(uint groupId); + + /*! + * Removes a notification. + * + * \param notificationId the ID of the notification to be removed + * \return true if the removal succeeded, false otherwise + */ + bool removeNotification(uint notificationId); + + /*! + * Updates an existing notification group. + * + * \param groupId the ID of the notification group to be updated + * \param eventType the event type of the notification + * \param summary the summary text to be used in the notification + * \param body the body text to be used in the notification + * \param action the ID of the content to be used in the notification + * \param imageURI the ID of the icon to be used in the notification + * \param count the number of items inside this group + * \return true if the update succeeded, false otherwise + */ + bool updateGroup(uint groupId, const QString &eventType, const QString &summary, const QString &body, const QString &action, const QString &imageURI, uint count); + + /*! + * Updates an existing notification group. + * + * \param groupId the ID of the notification group to be updated + * \param eventType the event type of the notification + * \return true if the update succeeded, false otherwise + */ + bool updateGroup(uint groupId, const QString &eventType); + + /*! + * Updates an existing notification. + * + * \param notificationId the ID of the notification to be updated + * \param eventType the event type of the notification + * \param summary the summary text to be used in the notification + * \param body the body text to be used in the notification + * \param action the ID of the content to be used in the notification + * \param imageURI the ID of the icon to be used in the notification + * \param count the number of items inside this notification + * \return true if the update succeeded, false otherwise + */ + bool updateNotification(uint notificationId, const QString &eventType, const QString &summary, const QString &body, const QString &action, const QString &imageURI, uint count = 1); + + /*! + * Updates an existing notification. + * + * \param notificationId the ID of the notification to be updated + * \param eventType the event type of the notification + * \return true if the update succeeded, false otherwise + */ + bool updateNotification(uint notificationId, const QString &eventType); + + /*! + * Returns a list of IDs for notifications owned by this application + * + * \return list of notification IDs + */ + QList notificationIdList(); +}; + +#endif /* DUINOTIFICATIONMANAGER_H_ */ +//! \endcond diff --git a/src/notification/duinotificationmanagerproxy.cpp b/src/notification/duinotificationmanagerproxy.cpp new file mode 100644 index 000000000..cd3b4d4dc --- /dev/null +++ b/src/notification/duinotificationmanagerproxy.cpp @@ -0,0 +1,26 @@ +/* + * This file was generated by qdbusxml2cpp version 0.7 + * Command line was: qdbusxml2cpp notificationmanager.xml -p duinotificationmanagerproxy -c DuiNotificationManagerProxy -v -i metatypedeclarations.h + * + * qdbusxml2cpp is Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#include "duinotificationmanagerproxy.h" + +/* + * Implementation of interface class DuiNotificationManagerProxy + */ + +DuiNotificationManagerProxy::DuiNotificationManagerProxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) + : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) +{ +} + +DuiNotificationManagerProxy::~DuiNotificationManagerProxy() +{ +} + diff --git a/src/notification/duinotificationmanagerproxy.h b/src/notification/duinotificationmanagerproxy.h new file mode 100644 index 000000000..cb9b7414f --- /dev/null +++ b/src/notification/duinotificationmanagerproxy.h @@ -0,0 +1,128 @@ +/* + * This file was generated by qdbusxml2cpp version 0.7 + * Command line was: qdbusxml2cpp notificationmanager.xml -p duinotificationmanagerproxy -c DuiNotificationManagerProxy -v -i metatypedeclarations.h + * + * qdbusxml2cpp is Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +// Make doxygen skip this internal class +//! \cond +#ifndef DUINOTIFICATIONMANAGERPROXY_H_1259674559 +#define DUINOTIFICATIONMANAGERPROXY_H_1259674559 + +#include +#include +#include +#include +#include +#include +#include +#include +#include "metatypedeclarations.h" + +/* + * Proxy class for interface org.maemo.dui.NotificationManager + */ +class DuiNotificationManagerProxy: public QDBusAbstractInterface +{ + Q_OBJECT +public: + static inline const char *staticInterfaceName() { + return "org.maemo.dui.NotificationManager"; + } + +public: + DuiNotificationManagerProxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0); + + ~DuiNotificationManagerProxy(); + +public Q_SLOTS: // METHODS + inline QDBusPendingReply addGroup(uint notificationUserId, const QString &eventType, const QString &summary, const QString &body, const QString &action, const QString &imageURI, uint count, bool persistent) { + QList argumentList; + argumentList << qVariantFromValue(notificationUserId) << qVariantFromValue(eventType) << qVariantFromValue(summary) << qVariantFromValue(body) << qVariantFromValue(action) << qVariantFromValue(imageURI) << qVariantFromValue(count) << qVariantFromValue(persistent); + return asyncCallWithArgumentList(QLatin1String("addGroup"), argumentList); + } + + inline QDBusPendingReply addGroup(uint notificationUserId, const QString &eventType, bool persistent) { + QList argumentList; + argumentList << qVariantFromValue(notificationUserId) << qVariantFromValue(eventType) << qVariantFromValue(persistent); + return asyncCallWithArgumentList(QLatin1String("addGroup"), argumentList); + } + + inline QDBusPendingReply addNotification(uint notificationUserId, uint groupId, const QString &eventType, const QString &summary, const QString &body, const QString &action, const QString &imageURI, uint count, bool persistent) { + QList argumentList; + argumentList << qVariantFromValue(notificationUserId) << qVariantFromValue(groupId) << qVariantFromValue(eventType) << qVariantFromValue(summary) << qVariantFromValue(body) << qVariantFromValue(action) << qVariantFromValue(imageURI) << qVariantFromValue(count) << qVariantFromValue(persistent); + return asyncCallWithArgumentList(QLatin1String("addNotification"), argumentList); + } + + inline QDBusPendingReply addNotification(uint notificationUserId, uint groupId, const QString &eventType, bool persistent) { + QList argumentList; + argumentList << qVariantFromValue(notificationUserId) << qVariantFromValue(groupId) << qVariantFromValue(eventType) << qVariantFromValue(persistent); + return asyncCallWithArgumentList(QLatin1String("addNotification"), argumentList); + } + + inline QDBusPendingReply > notificationIdList(uint notificationUserId) { + QList argumentList; + argumentList << qVariantFromValue(notificationUserId); + return asyncCallWithArgumentList(QLatin1String("notificationIdList"), argumentList); + } + + inline QDBusPendingReply notificationUserId() { + QList argumentList; + return asyncCallWithArgumentList(QLatin1String("notificationUserId"), argumentList); + } + + inline QDBusPendingReply removeGroup(uint notificationUserId, uint groupId) { + QList argumentList; + argumentList << qVariantFromValue(notificationUserId) << qVariantFromValue(groupId); + return asyncCallWithArgumentList(QLatin1String("removeGroup"), argumentList); + } + + inline QDBusPendingReply removeNotification(uint notificationUserId, uint notificationId) { + QList argumentList; + argumentList << qVariantFromValue(notificationUserId) << qVariantFromValue(notificationId); + return asyncCallWithArgumentList(QLatin1String("removeNotification"), argumentList); + } + + inline QDBusPendingReply updateGroup(uint notificationUserId, uint groupId, const QString &eventType, const QString &summary, const QString &body, const QString &action, const QString &imageURI, uint count) { + QList argumentList; + argumentList << qVariantFromValue(notificationUserId) << qVariantFromValue(groupId) << qVariantFromValue(eventType) << qVariantFromValue(summary) << qVariantFromValue(body) << qVariantFromValue(action) << qVariantFromValue(imageURI) << qVariantFromValue(count); + return asyncCallWithArgumentList(QLatin1String("updateGroup"), argumentList); + } + + inline QDBusPendingReply updateGroup(uint notificationUserId, uint groupId, const QString &eventType) { + QList argumentList; + argumentList << qVariantFromValue(notificationUserId) << qVariantFromValue(groupId) << qVariantFromValue(eventType); + return asyncCallWithArgumentList(QLatin1String("updateGroup"), argumentList); + } + + inline QDBusPendingReply updateNotification(uint notificationUserId, uint notificationId, const QString &eventType, const QString &summary, const QString &body, const QString &action, const QString &imageURI, uint count) { + QList argumentList; + argumentList << qVariantFromValue(notificationUserId) << qVariantFromValue(notificationId) << qVariantFromValue(eventType) << qVariantFromValue(summary) << qVariantFromValue(body) << qVariantFromValue(action) << qVariantFromValue(imageURI) << qVariantFromValue(count); + return asyncCallWithArgumentList(QLatin1String("updateNotification"), argumentList); + } + + inline QDBusPendingReply updateNotification(uint notificationUserId, uint notificationId, const QString &eventType) { + QList argumentList; + argumentList << qVariantFromValue(notificationUserId) << qVariantFromValue(notificationId) << qVariantFromValue(eventType); + return asyncCallWithArgumentList(QLatin1String("updateNotification"), argumentList); + } + +Q_SIGNALS: // SIGNALS +}; + +namespace org +{ + namespace maemo + { + namespace dui + { + typedef ::DuiNotificationManagerProxy NotificationManager; + } + } +} +#endif +//! \endcond diff --git a/src/notification/metatypedeclarations.h b/src/notification/metatypedeclarations.h new file mode 100644 index 000000000..fe6dccc64 --- /dev/null +++ b/src/notification/metatypedeclarations.h @@ -0,0 +1,25 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef METATYPEDECLARATIONS_H +#define METATYPEDECLARATIONS_H + +Q_DECLARE_METATYPE(QList) + +#endif // METATYPEDECLARATIONS_H diff --git a/src/notification/notification.pri b/src/notification/notification.pri new file mode 100644 index 000000000..4fbbe837d --- /dev/null +++ b/src/notification/notification.pri @@ -0,0 +1,25 @@ +# ############################################################################## +# DuiNotification module +# This module contains a convenience API for handling notifications in a system +# ############################################################################## +NOTIFICATION_SRC_DIR = ./notification +INCLUDEPATH += $$NOTIFICATION_SRC_DIR + +HEADERS += \ + $$NOTIFICATION_SRC_DIR/duinotification_p.h \ + $$NOTIFICATION_SRC_DIR/duinotificationgroup_p.h + +# These headers should get installed +HEADERS += \ + $$NOTIFICATION_SRC_DIR/duinotification.h \ + $$NOTIFICATION_SRC_DIR/duinotificationgroup.h + +# These headers should not get installed +HEADERS += $$NOTIFICATION_SRC_DIR/duinotificationmanager.h \ + $$NOTIFICATION_SRC_DIR/duinotificationmanagerproxy.h \ + +SOURCES += \ + $$NOTIFICATION_SRC_DIR/duinotification.cpp \ + $$NOTIFICATION_SRC_DIR/duinotificationgroup.cpp \ + $$NOTIFICATION_SRC_DIR/duinotificationmanager.cpp \ + $$NOTIFICATION_SRC_DIR/duinotificationmanagerproxy.cpp diff --git a/src/notification/notificationmanager.xml b/src/notification/notificationmanager.xml new file mode 100644 index 000000000..5bc9f38ef --- /dev/null +++ b/src/notification/notificationmanager.xml @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/painting/duigles2renderer.cpp b/src/painting/duigles2renderer.cpp new file mode 100644 index 000000000..e0138a3e1 --- /dev/null +++ b/src/painting/duigles2renderer.cpp @@ -0,0 +1,773 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duigles2renderer.h" + +#ifdef DUI_USE_OPENGL +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "duidebug.h" + +namespace +{ + + typedef QPair DuiGLProgramKey; + typedef QHash DuiGLProgramCache; + + static const EGLint pixmapAttribs[] = { + EGL_TEXTURE_TARGET, EGL_TEXTURE_2D, + EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGB, + EGL_NONE + }; + +//DUI specific attribute array indices + static const GLuint DUI_ATTR_VERTEX = 0; + static const GLuint DUI_ATTR_TCOORD = 1; + static const GLuint DUI_ATTR_VCOLOR = 2; + + struct TexturePixmap { + TexturePixmap(): eglpixmap(0), texture(0) {} + EGLSurface eglpixmap; + quint32 texture; + }; + + typedef QHash PixmapHash; + + static QString defaultVertexShader() + { + return QString::fromLatin1(DUI_SHADER_SOURCE_DIR "/default.vert"); + } + + static QString defaultFragmentShader() + { + return QString::fromLatin1(DUI_SHADER_SOURCE_DIR "/default.frag"); + } + + static QString canonicalFilename(const QString &filename) + { + if (filename.isEmpty()) + return QString(); + else + return QFileInfo(filename).canonicalFilePath(); + } + +} // anonymous namespace + +class DuiGLES2RendererPrivate +{ +public: + DuiGLES2RendererPrivate(); + virtual ~DuiGLES2RendererPrivate(); + + GLuint setupVertices(const QSizeF &texSize, const QList& sourceRects, const QList& targetRects); + void resizeAttrArrays(int numQuads); + QGLShaderProgram *requestBinaryProgram(const QString &frag, const QString &vert); + + GLfloat m_matProj[4][4]; + GLfloat m_matWorld[4][4]; + + QVector m_vertices; + QVector m_texCoords; + QVector m_color; + QVector m_indices; + + QGLWidget *m_glWidget; + + DuiGLProgramCache m_programCache; + QGLShaderProgram *m_defaultProgram; + + QSize m_viewportSize; + + EGLConfig config; + EGLDisplay dpy; + PixmapHash bound_pixmaps; + + static QMap glRenderers; + static DuiGLES2Renderer *activeRenderer; + + QPainter *m_activePainter; + QGLShaderProgram *m_activeProgram; + QSize m_boundTexSize; + bool m_invertTexture; +}; + +QMap DuiGLES2RendererPrivate::glRenderers; +DuiGLES2Renderer *DuiGLES2RendererPrivate::activeRenderer = NULL; + +DuiGLES2RendererPrivate::DuiGLES2RendererPrivate() + : m_glWidget(NULL), m_viewportSize(-1, -1) +{ + //init world matrix for the known parts + //parts that are changeable by the transformation + //are set when rendering in the textures + m_matWorld[0][2] = 0.0; + m_matWorld[1][2] = 0.0; + m_matWorld[2][0] = 0.0; + m_matWorld[2][1] = 0.0; + m_matWorld[2][2] = 1.0; + m_matWorld[2][3] = 0.0; + m_matWorld[3][2] = 0.0; + + //init vertex and texcoord arrays, 4 first vertices are used to draw standard + //pixmaps and all the remaining vertices can be used to draw dynamic geometries + //like scalable images and other patched stuff, the vertices are packed into same + //array so that we don't need to switch the used array on fly. + m_vertices.resize(8 + (9 * 4 * 2)); + m_texCoords.resize(8 + (9 * 4 * 2)); + GLfloat *tc = m_texCoords.data(); + tc[0] = 0.0; tc[1] = 1.0; + tc[2] = 0.0; tc[3] = 0.0; + tc[4] = 1.0; tc[5] = 0.0; + tc[6] = 1.0; tc[7] = 1.0; + + //init index array that is used to draw dynamic geometries + //the indices are offset by 4 because the 4 vertices that + //are used to draw normal pixmaps are in the beginning of + //the array + m_indices.resize(9 * 6); + GLushort *indices = m_indices.data(); + for (GLuint i = 0; i < 9; i++) { + indices[i*6+0] = 4 + (i * 4 + 0); //x1 y1 TL + indices[i*6+1] = 4 + (i * 4 + 1); //x1 y2 BL + indices[i*6+2] = 4 + (i * 4 + 2); //x2 y2 BR + indices[i*6+3] = 4 + (i * 4 + 0); //x1 y1 TL + indices[i*6+4] = 4 + (i * 4 + 2); //x2 y2 BR + indices[i*6+5] = 4 + (i * 4 + 3); //x2 y1 TR + } + + dpy = eglGetDisplay(EGLNativeDisplayType(QX11Info::display())); + + m_activePainter = NULL; + m_invertTexture = false; +} + +DuiGLES2RendererPrivate::~DuiGLES2RendererPrivate() +{ + qDeleteAll(m_programCache); + + const PixmapHash::const_iterator bound_pixmaps_end = bound_pixmaps.constEnd(); + for (PixmapHash::const_iterator i = bound_pixmaps.constBegin(); i != bound_pixmaps_end; ++i) { + eglDestroySurface(dpy, i->eglpixmap); + glDeleteTextures(1, &i->texture); + } +} + +GLuint DuiGLES2RendererPrivate::setupVertices(const QSizeF &texSize, const QList& sourceRects, const QList& targetRects) +{ + const int numRects = qMin(sourceRects.size(), targetRects.size()); + resizeAttrArrays(numRects); + + const GLfloat dx = 1.0f / texSize.width(); + const GLfloat dy = 1.0f / texSize.height(); + + const QVector::iterator vertices = m_vertices.begin() + 8; + const QVector::iterator texcoords = m_texCoords.begin() + 8; + + for (int i = 0; i < numRects; ++i) { + // setup vertices for the target rectangle + const QRect &target = targetRects[i]; + const GLfloat x1 = target.left(); + const GLfloat x2 = target.right(); + const GLfloat y1 = target.top(); + const GLfloat y2 = target.bottom(); + + vertices[8*i] = x1; vertices[8*i + 1] = y1; + vertices[8*i + 2] = x1; vertices[8*i + 3] = y2; + vertices[8*i + 4] = x2; vertices[8*i + 5] = y2; + vertices[8*i + 6] = x2; vertices[8*i + 7] = y1; + + // setup texture coords for the source rectangle + const QRect &source = sourceRects[i]; + const GLfloat u1 = dx * float(source.left()); + const GLfloat u2 = dx * float(source.right()); + GLfloat v1 = dy * float(source.top()); + GLfloat v2 = dy * float(source.bottom()); + if (m_invertTexture) { + v1 = 1.0f - v1; + v2 = 1.0f - v2; + } + texcoords[8*i] = u1; texcoords[8*i + 1] = v1; + texcoords[8*i + 2] = u1; texcoords[8*i + 3] = v2; + texcoords[8*i + 4] = u2; texcoords[8*i + 5] = v2; + texcoords[8*i + 6] = u2; texcoords[8*i + 7] = v1; + } + return numRects * 6; +} + +void DuiGLES2RendererPrivate::resizeAttrArrays(int numQuads) +{ + if (numQuads * 6 > m_indices.size()) { + //resize the vertex and texcoord arrays to needed size + m_vertices.resize(8 + (numQuads * 4 * 2)); + m_texCoords.resize(8 + (numQuads * 4 * 2)); + + //resize the index array and fill the new indices + GLuint oldcount = m_indices.size() / 6; + GLuint newcount = numQuads; + m_indices.resize(numQuads * 6); + GLushort *indices = m_indices.data(); + for (GLuint i = oldcount; i < newcount; i++) { + indices[i*6+0] = 4 + (i * 4 + 0); //x1 y1 TL + indices[i*6+1] = 4 + (i * 4 + 1); //x1 y2 BL + indices[i*6+2] = 4 + (i * 4 + 2); //x2 y2 BR + indices[i*6+3] = 4 + (i * 4 + 0); //x1 y1 TL + indices[i*6+4] = 4 + (i * 4 + 2); //x2 y2 BR + indices[i*6+5] = 4 + (i * 4 + 3); //x2 y1 TR + } + + //reinit the attribute array pointers because resizing might of + //changed pointer returned by the data() + glEnableVertexAttribArray(DUI_ATTR_VERTEX); + glVertexAttribPointer(DUI_ATTR_VERTEX, 2, GL_FLOAT, GL_FALSE, 0, m_vertices.data()); + glEnableVertexAttribArray(DUI_ATTR_TCOORD); + glVertexAttribPointer(DUI_ATTR_TCOORD, 2, GL_FLOAT, GL_FALSE, 0, m_texCoords.data()); + } +} + +QGLShaderProgram *DuiGLES2RendererPrivate::requestBinaryProgram(const QString &frag, const QString &vert) +{ + // not implemented yet + (void) frag; + (void) vert; + return 0; +} + +DuiGLES2Renderer::DuiGLES2Renderer() + : d_ptr(new DuiGLES2RendererPrivate()) +{ +} + +DuiGLES2Renderer::~DuiGLES2Renderer() +{ + delete d_ptr; +} + +DuiGLES2Renderer *DuiGLES2Renderer::instance() +{ + if (!DuiGLES2RendererPrivate::activeRenderer) + duiWarning("DuiGLES2Renderer::instance()") << "No active renderer."; + + return DuiGLES2RendererPrivate::activeRenderer; +} + +DuiGLES2Renderer *DuiGLES2Renderer::instance(QGLWidget *glWidget) +{ + DuiGLES2Renderer *renderer = DuiGLES2RendererPrivate::glRenderers.value(glWidget); + + if (!renderer) { + renderer = new DuiGLES2Renderer(); + renderer->init(glWidget); + DuiGLES2RendererPrivate::glRenderers.insert(glWidget, renderer); + } + return renderer; +} + +void DuiGLES2Renderer::activate(QGLWidget *glWidget) +{ + if (glWidget) + DuiGLES2RendererPrivate::activeRenderer = DuiGLES2Renderer::instance(glWidget); + else + DuiGLES2RendererPrivate::activeRenderer = NULL; +} + +void DuiGLES2Renderer::destroy(QGLWidget *glWidget) +{ + if (DuiGLES2Renderer *const renderer = DuiGLES2RendererPrivate::glRenderers.take(glWidget)) { + + if (renderer == DuiGLES2RendererPrivate::activeRenderer) { + duiWarning("DuiGLES2Renderer::destroy()") << "Destroying active renderer."; + DuiGLES2Renderer::activate(NULL); + } + delete renderer; + } +} + +void DuiGLES2Renderer::destroyAll() +{ + if (!DuiGLES2RendererPrivate::glRenderers.empty()) { + duiWarning("DuiGLES2Renderer::destroyAll()") << "Renderers still existing."; + DuiGLES2Renderer::activate(NULL); + qDeleteAll(DuiGLES2RendererPrivate::glRenderers); + DuiGLES2RendererPrivate::glRenderers.clear(); + } +} + +void DuiGLES2Renderer::init(QGLWidget *glWidget) +{ + d_ptr->dpy = eglGetDisplay(EGLNativeDisplayType(QX11Info::display())); + d_ptr->m_glWidget = glWidget; + d_ptr->m_glWidget->makeCurrent(); + + //init the orthogonal projection matrix + //glOrtho(0, w, h, 0, -1, 1): + //2.0/w, 0.0, 0.0, -1.0 + //0.0, -2.0/h, 0.0, 1.0 + //0.0, 0.0, -1.0, 0.0 + //0.0, 0.0, 0.0, 1.0 + GLfloat w = glWidget->width(); + GLfloat h = glWidget->height(); + d_ptr->m_matProj[0][0] = 2.0f / w; d_ptr->m_matProj[1][0] = 0.0; d_ptr->m_matProj[2][0] = 0.0; d_ptr->m_matProj[3][0] = -1.0; + d_ptr->m_matProj[0][1] = 0.0; d_ptr->m_matProj[1][1] = -2.0f / h; d_ptr->m_matProj[2][1] = 0.0; d_ptr->m_matProj[3][1] = 1.0; + d_ptr->m_matProj[0][2] = 0.0; d_ptr->m_matProj[1][2] = 0.0; d_ptr->m_matProj[2][2] = -1.0; d_ptr->m_matProj[3][2] = 0.0; + d_ptr->m_matProj[0][3] = 0.0; d_ptr->m_matProj[1][3] = 0.0; d_ptr->m_matProj[2][3] = 0.0; d_ptr->m_matProj[3][3] = 1.0; + + d_ptr->m_defaultProgram = getShaderProgram(QString(), QString()); +} + +QGLShaderProgram *DuiGLES2Renderer::getShaderProgram(const QString &frag, const QString &vert) +{ + // First try a direct lookup with the passed-in filenames. If they are + // already canonical and the program exists in the cache, the file system + // access can be skipped altogether. + QGLShaderProgram *program = d_ptr->m_programCache.value(DuiGLProgramKey(frag, vert)); + + if (!program) { + const DuiGLProgramKey key(canonicalFilename(frag), canonicalFilename(vert)); + program = d_ptr->m_programCache.value(key); + + if (!program) { + program = d_ptr->requestBinaryProgram(key.first, key.second); + if (!program) + program = compileShaderProgram(key.first, key.second); + if (program) + d_ptr->m_programCache.insert(key, program); + } + } + return program; +} + +QGLShaderProgram *DuiGLES2Renderer::compileShaderProgram(const QString &frag, const QString &vert) +{ + const QString fragFilename = (frag.isEmpty()) ? defaultFragmentShader() : frag; + QGLShader fragShader(QGLShader::Fragment, d_ptr->m_glWidget->context()); + if (!fragShader.compileSourceFile(fragFilename)) { + duiWarning("DuiGLES2Renderer") << "failed to compile fragment shader" << fragFilename + << '\n' << fragShader.log(); + return 0; + } + const QString vertFilename = (vert.isEmpty()) ? defaultVertexShader() : vert; + QGLShader vertShader(QGLShader::Vertex, d_ptr->m_glWidget->context()); + if (!vertShader.compileSourceFile(vertFilename)) { + duiWarning("DuiGLES2Renderer") << "failed to compile vertex shader" << vertFilename + << '\n' << vertShader.log(); + return 0; + } + QGLShaderProgram *const program = new QGLShaderProgram(d_ptr->m_glWidget->context()); + + if (program->addShader(&fragShader) && program->addShader(&vertShader)) { + // bind needed attribute arrays to specific indices -- TODO: What's this for exactly? + program->bindAttributeLocation("vertex", DUI_ATTR_VERTEX); + program->bindAttributeLocation("texCoord", DUI_ATTR_TCOORD); + program->bindAttributeLocation("color", DUI_ATTR_VCOLOR); + + // TODO: default context implicit here, but not above? + if (program->link() && program->bind()) { + // Setup default texturing uniforms here so we dont need setup them in runtime + const QByteArray prefix("texture"); + GLint maxTexUnits = 0; + glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxTexUnits); + + for (int i = 0; i < maxTexUnits; ++i) { + const int loc = program->uniformLocation(prefix + QByteArray::number(i)); + if (loc >= 0) + program->setUniformValue(loc, GLuint(i)); + } + } + return program; + } + duiWarning("DuiGLES2Renderer") << "failed to link shader program" + << (fragFilename + ':' + vertFilename); + delete program; + return 0; +} + +quint32 DuiGLES2Renderer::bindX11Pixmap(Qt::HANDLE pixmap) +{ + EGLSurface eglpixmap = 0; + + // If surface does not yet exist, initialize and find appropriates EGL surface + if (!d_ptr->config) { + EGLint ecfgs = 0; + EGLConfig configs[20]; + + static const EGLint pixmap_config[] = { + EGL_SURFACE_TYPE, EGL_PIXMAP_BIT, + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + EGL_DEPTH_SIZE, 0, + EGL_BIND_TO_TEXTURE_RGB, EGL_TRUE, + EGL_NONE + }; + + if (!eglChooseConfig(d_ptr->dpy, pixmap_config, configs, + 20, &ecfgs) || !ecfgs) { + duiWarning("DuiGLES2Renderer") << "No appropriate EGL configuration for texture from pixmap!"; + return 0; + } + for (EGLint i = 0; i < ecfgs; i++) { + eglpixmap = eglCreatePixmapSurface(d_ptr->dpy, configs[i], + (EGLNativePixmapType) pixmap, + pixmapAttribs); + if (eglpixmap == EGL_NO_SURFACE) + continue; + else { + d_ptr->config = configs[i]; + break; + } + } + } + + // Returns the cached texture if we have one already + TexturePixmap tp = d_ptr->bound_pixmaps.value(pixmap); + if (tp.texture > 0) + return tp.texture; + + // .. or create a new one + if (!eglpixmap) + eglpixmap = eglCreatePixmapSurface(d_ptr->dpy, d_ptr->config, + (EGLNativePixmapType) pixmap, + pixmapAttribs); + if (eglpixmap == EGL_NO_SURFACE) { + duiWarning("DuiGLES2Renderer") << "Cannot create EGL surface:" << eglGetError(); + return 0; + } + tp.eglpixmap = eglpixmap; + + glGenTextures(1, &tp.texture); + d_ptr->bound_pixmaps[pixmap] = tp; + glBindTexture(GL_TEXTURE_2D, tp.texture); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + glEnable(GL_TEXTURE_2D); + + return tp.texture; +} + +void DuiGLES2Renderer::unbindX11Pixmap(Qt::HANDLE pixmap) +{ + TexturePixmap tp = d_ptr->bound_pixmaps.value(pixmap); + if (!tp.texture) + return; + + // free the pixmap and texture cache + eglDestroySurface(d_ptr->dpy, tp.eglpixmap); + tp.eglpixmap = EGL_NO_SURFACE; + //XSync(QX11Info::display(), FALSE); + glDeleteTextures(1, &tp.texture); + d_ptr->bound_pixmaps.remove(pixmap); +} + +void DuiGLES2Renderer::updateX11Pixmap(Qt::HANDLE pixmap) +{ + // catch updates to the pixmap here when they happen + TexturePixmap tp = d_ptr->bound_pixmaps.value(pixmap); + if (!tp.texture) + return; + + glBindTexture(GL_TEXTURE_2D, tp.texture); + + if (eglReleaseTexImage(d_ptr->dpy, tp.eglpixmap, + EGL_BACK_BUFFER) == EGL_FALSE) + duiWarning("DuiGLES2Renderer: Update pixmap, cant release bound texture"); + if (eglBindTexImage(d_ptr->dpy, tp.eglpixmap, + EGL_BACK_BUFFER) == EGL_FALSE) { + duiWarning("DuiGLES2Renderer: Update pixmap, can't bind EGL texture to pixmap:") << eglGetError(); + } + glEnable(GL_TEXTURE_2D); +} + +void DuiGLES2Renderer::begin(QPainter *painter) +{ + begin(painter, d_ptr->m_defaultProgram); +} + +void DuiGLES2Renderer::begin(QPainter *painter, QGLShaderProgram *program) +{ + if (d_ptr->m_activePainter) + end(); + + if (painter) { + d_ptr->m_activePainter = painter; + d_ptr->m_activePainter->beginNativePainting(); + } + + //TODO: do this only when setting the viewport size manually? + // otherwise set this and the uniform only once when creating the program + //setup orthogonal projection matrix + GLfloat w = d_ptr->m_viewportSize.width() == -1 ? d_ptr->m_glWidget->width() : d_ptr->m_viewportSize.width(); + GLfloat h = d_ptr->m_viewportSize.height() == -1 ? d_ptr->m_glWidget->height() : d_ptr->m_viewportSize.height(); + glViewport(0, 0, w, h); + d_ptr->m_matProj[0][0] = 2.0 / w; + d_ptr->m_matProj[1][1] = -2.0 / h; + + //setup shader program + d_ptr->m_activeProgram = program; + if (d_ptr->m_activeProgram) { + d_ptr->m_activeProgram->bind(); + d_ptr->m_activeProgram->setUniformValue("matProj", d_ptr->m_matProj); + } + + glEnableVertexAttribArray(DUI_ATTR_VERTEX); + glVertexAttribPointer(DUI_ATTR_VERTEX, 2, GL_FLOAT, GL_FALSE, 0, d_ptr->m_vertices.data()); + glEnableVertexAttribArray(DUI_ATTR_TCOORD); + glVertexAttribPointer(DUI_ATTR_TCOORD, 2, GL_FLOAT, GL_FALSE, 0, d_ptr->m_texCoords.data()); + + glDisable(GL_DEPTH_TEST); + glEnable(GL_BLEND); +} + +void DuiGLES2Renderer::end() +{ + if (d_ptr->m_activePainter) { + d_ptr->m_activePainter->endNativePainting(); + d_ptr->m_activePainter = NULL; + } + if (d_ptr->m_activeProgram) { + d_ptr->m_activeProgram->release(); + d_ptr->m_activeProgram = NULL; + } + + d_ptr->m_boundTexSize = QSize(-1, -1); + d_ptr->m_viewportSize = QSize(-1, -1); + + //TODO: Refactor this to be more automatic, only x pixmaps need inverting. + d_ptr->m_invertTexture = false; + GLfloat *tc = d_ptr->m_texCoords.data(); + tc[0] = 0.0; tc[1] = 1.0; + tc[2] = 0.0; tc[3] = 0.0; + tc[4] = 1.0; tc[5] = 0.0; + tc[6] = 1.0; tc[7] = 1.0; +} + +void DuiGLES2Renderer::activateProgram(QGLShaderProgram *program) +{ + if (program) { + d_ptr->m_activeProgram = program; + d_ptr->m_activeProgram->bind(); + d_ptr->m_activeProgram->setUniformValue("matProj", d_ptr->m_matProj); + } else { + duiWarning("DuiGLES2Renderer") << "activateProgram() Invalid program."; + } +} + +void DuiGLES2Renderer::bindTexture(const QPixmap &pixmap, quint32 unit, const QString &uniformName) +{ + glActiveTexture(GL_TEXTURE0 + unit); + bindTexture(d_ptr->m_glWidget->bindTexture(pixmap, GL_TEXTURE_2D, GL_RGBA, QGLContext::PremultipliedAlphaBindOption), pixmap.size(), unit, uniformName); + //bindTexture(d_ptr->m_glWidget->bindTexture(pixmap, GL_TEXTURE_2D, GL_RGBA, QGLContext::NoBindOption), pixmap.size(), unit, uniformName); +} + +void DuiGLES2Renderer::bindTexture(quint32 texId, const QSize &texSize, quint32 unit, const QString &uniformName) +{ + //setup uniform only if some custom texture name has + //been defined, the default texture uniforms (texture0, + //texture1 etc.) was setup when creating the program + if (d_ptr->m_activeProgram && !uniformName.isEmpty()) { + duiWarning("DuiGLES2Renderer") << "bindTexture()" << uniformName << unit; + d_ptr->m_activeProgram->setUniformValue(uniformName.toStdString().c_str(), (GLuint)unit); + } + + //the unit 0 defines the texture size + //that is given to shaders who need it + if (unit == 0) + d_ptr->m_boundTexSize = texSize; + + //bind texture to wanted unit + glActiveTexture(GL_TEXTURE0 + unit); + glBindTexture(GL_TEXTURE_2D, texId); + + //setup texture filtering based on the active painter + if (d_ptr->m_activePainter) { + if (d_ptr->m_activePainter->renderHints() & QPainter::SmoothPixmapTransform) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + } else { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + } + } + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + glEnable(GL_TEXTURE_2D); +} + +void DuiGLES2Renderer::setInvertTexture(bool invert) +{ + /* Compensate for inverted textures + + Rendering done by the window system may be y-inverted compared +   to the standard OpenGL texture representation. More specifically: + the X Window system uses a coordinate system where the origin is in + the upper left; however, the GL uses a coordinate system where the + origin is in the lower left. + */ + + //TODO: Refactor this to be more automatic, only x pixmaps need inverting. + d_ptr->m_invertTexture = invert; + GLfloat *tc = d_ptr->m_texCoords.data(); + if (invert) { + tc[0] = 0.0; tc[1] = 0.0; + tc[2] = 0.0; tc[3] = 1.0; + tc[4] = 1.0; tc[5] = 1.0; + tc[6] = 1.0; tc[7] = 0.0; + } else { + tc[0] = 0.0; tc[1] = 1.0; + tc[2] = 0.0; tc[3] = 0.0; + tc[4] = 1.0; tc[5] = 0.0; + tc[6] = 1.0; tc[7] = 1.0; + } +} + +void DuiGLES2Renderer::draw(int x, int y, int width, int height) +{ + draw(QRect(x, y, width, height)); +} + +void DuiGLES2Renderer::draw(int x, int y) +{ + draw(x, y, d_ptr->m_boundTexSize.width(), d_ptr->m_boundTexSize.height()); +} + +void DuiGLES2Renderer::draw(const QRect &rectangle) +{ + GLfloat *vertices = d_ptr->m_vertices.data(); + vertices[0] = rectangle.left(); vertices[1] = rectangle.top(); + vertices[2] = rectangle.left(); vertices[3] = rectangle.bottom(); + vertices[4] = rectangle.right(); vertices[5] = rectangle.bottom(); + vertices[6] = rectangle.right(); vertices[7] = rectangle.top(); + + QTransform transform; + GLfloat o = 1.0; + if (d_ptr->m_activePainter) { + transform = d_ptr->m_activePainter->combinedTransform(); + o = d_ptr->m_activePainter->opacity(); + } + d_ptr->m_matWorld[0][0] = transform.m11(); + d_ptr->m_matWorld[0][1] = transform.m12(); + d_ptr->m_matWorld[0][3] = transform.m13(); + d_ptr->m_matWorld[1][0] = transform.m21(); + d_ptr->m_matWorld[1][1] = transform.m22(); + d_ptr->m_matWorld[1][3] = transform.m23(); + d_ptr->m_matWorld[3][0] = transform.dx(); + d_ptr->m_matWorld[3][1] = transform.dy(); + d_ptr->m_matWorld[3][3] = transform.m33(); + d_ptr->m_activeProgram->setUniformValue("matWorld", d_ptr->m_matWorld); + d_ptr->m_activeProgram->setUniformValue("opacity", o); + + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); +} + +void DuiGLES2Renderer::draw(const QList& targets, const QList& sources) +{ + GLuint num = d_ptr->setupVertices(d_ptr->m_boundTexSize, sources, targets); + + + QTransform transform; + GLfloat o = 1.0; + if (d_ptr->m_activePainter) { + transform = d_ptr->m_activePainter->combinedTransform(); + o = d_ptr->m_activePainter->opacity(); + } + + d_ptr->m_matWorld[0][0] = transform.m11(); + d_ptr->m_matWorld[0][1] = transform.m12(); + d_ptr->m_matWorld[0][3] = transform.m13(); + d_ptr->m_matWorld[1][0] = transform.m21(); + d_ptr->m_matWorld[1][1] = transform.m22(); + d_ptr->m_matWorld[1][3] = transform.m23(); + d_ptr->m_matWorld[3][0] = transform.dx(); + d_ptr->m_matWorld[3][1] = transform.dy(); + d_ptr->m_matWorld[3][3] = transform.m33(); + d_ptr->m_activeProgram->setUniformValue("matWorld", d_ptr->m_matWorld); + d_ptr->m_activeProgram->setUniformValue("opacity", o); + + glDrawElements(GL_TRIANGLES, num, GL_UNSIGNED_SHORT, d_ptr->m_indices.data()); +} + +void DuiGLES2Renderer::draw(const QRect &target, const QRect &source) +{ + QList targets; + QList sources; + targets.append(target); + sources.append(source); + draw(targets, sources); +} + +void DuiGLES2Renderer::setViewportSize(const QSize &size) +{ + d_ptr->m_viewportSize = size; +} + +#else +DuiGLES2Renderer *DuiGLES2Renderer::instance() +{ + return NULL; +} +DuiGLES2Renderer *DuiGLES2Renderer::instance(QGLWidget *) +{ + return NULL; +} +void DuiGLES2Renderer::activate(QGLWidget *) {} +void DuiGLES2Renderer::destroy(QGLWidget *) {} +void DuiGLES2Renderer::destroyAll() {} +QGLShaderProgram *DuiGLES2Renderer::getShaderProgram(const QString &, const QString &) +{ + return NULL; +} +QGLShaderProgram *DuiGLES2Renderer::compileShaderProgram(const QString &, const QString &) +{ + return NULL; +} +quint32 DuiGLES2Renderer::bindX11Pixmap(Qt::HANDLE) +{ + return 0; +} +void DuiGLES2Renderer::unbindX11Pixmap(Qt::HANDLE) {} +void DuiGLES2Renderer::updateX11Pixmap(Qt::HANDLE) {} +void DuiGLES2Renderer::begin(QPainter *) {} +void DuiGLES2Renderer::begin(QPainter *, QGLShaderProgram *) {} +void DuiGLES2Renderer::end() {} +void DuiGLES2Renderer::activateProgram(QGLShaderProgram *) {} +void DuiGLES2Renderer::bindTexture(const QPixmap &, quint32, const QString &) {} +void DuiGLES2Renderer::bindTexture(quint32, const QSize &, quint32, const QString &) {} +void DuiGLES2Renderer::setInvertTexture(bool) {} +void DuiGLES2Renderer::draw(int, int, int, int) {} +void DuiGLES2Renderer::draw(int, int) {} +void DuiGLES2Renderer::draw(const QRect &) {} +void DuiGLES2Renderer::draw(const QList&, const QList&) {} +void DuiGLES2Renderer::draw(const QRect &, const QRect &) {} +void DuiGLES2Renderer::setViewportSize(const QSize &) {} +#endif diff --git a/src/painting/duigles2renderer.h b/src/painting/duigles2renderer.h new file mode 100644 index 000000000..57c467bcf --- /dev/null +++ b/src/painting/duigles2renderer.h @@ -0,0 +1,335 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIGLES2RENDERER_H +#define DUIGLES2RENDERER_H + +#include +#include +#include "duiexport.h" + +class QGLWidget; +class DuiGLES2RendererPrivate; + +class QGLShader; +class QGLShaderProgram; + +class QSizeF; + +//some definitions to enable building without gles2 libraries +#ifdef QT_OPENGL_LIB +#include +#ifdef QT_OPENGL_ES_2 +#define DUI_USE_OPENGL +#endif +#endif + +/*! + \class DuiGLES2Renderer + \brief A singleton class for rendering textured quads with custom shaders. + + DuiGLES2Renderer class implements and provides an easy interface for + compiling and setuping glsl shaders. The class also provides functionality + for rendering textured quads directly with GLES2. Class caches the compiled + shaders so that they can used inside a process without always recompiling + them. Following uniforms and attributes are considered default and they are + initialized by the DuiGLES2Renderer class automatically: + + \code + //vertex shader variables + attribute highp vec4 vertex; //object space vertex coordinate + attribute lowp vec2 texCoord; //texture coordinates of the vertex + uniform highp mat4 matProj; //projection matrix + uniform highp mat4 matWorld; //world transformation matrix + uniform highp vec2 invSize; //inversed size of rendered quad + + //fragment shader variables + uniform sampler2D textureX; //textures for each texture unit (eg. texture0, texture1 ...) + \endcode +*/ +class DUI_EXPORT DuiGLES2Renderer +{ +public: + + /*! + \brief Destructor. + */ + virtual ~DuiGLES2Renderer(); + + /*! + \brief Returns instance of DuiGLES2Renderer object for the specified QGLWidget. + + If the renderer for the specified glWidget does not yet exist it + will be created and initialized. + + Renderer object is created automatically for each DuiWindow if SW + rendering is enabled. + + \return DuiGLES2Renderer object + */ + static DuiGLES2Renderer *instance(QGLWidget *glWidget); + + /*! + \brief Returns instance of DuiGLES2Renderer which was previously set active. + + Returns NULL if no renderer has been set active. + + In normal cases widgets should call this method when they need instance + of the renderer. DuiWindow is responsible for activating a renderer. + If the method returns NULL, it usually means that SW rendering has been + forcefully applied (or the current development environment does not + support GLES2). + + \return Active DuiGLES2Renderer object + */ + static DuiGLES2Renderer *instance(); + + /*! + \brief Activates a renderer for the specified QGLWidget. + + If the renderer for the specified glWidget does not yet exist it + will be created and initialized. + + DuiWindow is responsible for setting the active renderer automatically + when the framework is drawing into it. Widgets should not call this + method manually. + */ + static void activate(QGLWidget *glWidget); + + /*! + \brief Destroys a renderer of the specified QGLWidget. + + The \a glWidget is not destroyed by this method. + */ + static void destroy(QGLWidget *glWidget); + + /*! + \brief Destroys all the renderer instances. + */ + static void destroyAll(); + + /*! + \brief Fetch a shader program by its source file names. + + If the group of shaders does not include a vertex shader or fragment + shader a default one is added. + + \param frag Filename of the fragment shader source + \param vert Filename of the vertex shader source + \return The shader program, or NULL on failure + */ + QGLShaderProgram *getShaderProgram(const QString &frag = QString(), const QString &vert = QString()); + + /*! + \brief Compile and link a shader program. + + Compiles the specified shader source files and links the objects + to a shader program. No caching takes place at this point and + a new shader program is always created. Application code should + generally call getShaderProgram() instead of this method. + + \param frag Filename of the fragment shader source + \param vert Filename of the vertex shader source + \return The shader program, or NULL on failure + */ + QGLShaderProgram *compileShaderProgram(const QString &frag, const QString &vert); + + /*! + \brief Bind an X pixmap as a texture. + + Uses the Nokia texture from pixmap extension to ensure that same + pixmap in memory is used as a texture. Returns a texture id that + can be drawn with drawTexture() or in later glBindTexture() calls. + The texture that is generated is cached, so multiple calls to + bindPixmap() with the same X pixmap will return the same texture + id. Ideally, this function should be called once as soon as the + pixmap id is obtained. Before drawing the contents of the texture, + ensure updateX11Pixmap() is called to update its contents. + + \param pixmap specifies the X pixmap to be bound as a texture + */ + quint32 bindX11Pixmap(Qt::HANDLE pixmap); + + /*! + \brief Unbind the texture from an X pixmap. + + Deletes the texture cache as well. Call this to free the resources + of the pixmap bound as a texture + + \param pixmap specifies the X pixmap to be bound as a texture + */ + void unbindX11Pixmap(Qt::HANDLE pixmap); + + /*! + \brief Updates the contents of bound X pixmap. + Call this every time the contents of the pixmap changes i.e. from X + Damage events. + + \param pixmap specifies the X pixmap to be bound as a texture + */ + void updateX11Pixmap(Qt::HANDLE pixmap); + + /*! + \brief Begin painting with DuiGLES2Renderer using default program. + + If \a painter is not NULL, renderer will extract opacity and + transformation and use those when rendering pixmaps into screen. + The renderer will also cache the current state of the painter, the + state will be restored when calling the ::end() method. + + After calling this method you can still change the opacity and + transformation from the painter and they will be taken into account + when drawing pixmaps. + */ + void begin(QPainter *painter); + + /*! + \brief Begin painting with DuiGLES2Renderer using the specified program. + + If NULL is given as \a program, program needs to manually activated by + calling activateProgram(). + */ + void begin(QPainter *painter, QGLShaderProgram *program); + + /*! + \brief Restores to a state that was before calling ::begin(). + */ + void end(); + + /*! + \brief Activate a program and program specific data. + */ + void activateProgram(QGLShaderProgram *program); + + /*! + \brief Bind pixmap as texture. + + Bind \a pixmap to wanted texture unit and shader uniform. By default + the pixmaps are bound to shaders using "textureN" as the uniform name, + where N equals to \a unit. + + Size of pixmap bound to the unit 0, will be used when drawing textures + with drawing methods. + */ + void bindTexture(const QPixmap &pixmap, quint32 unit = 0, const QString &uniformName = QString()); + + /*! + \brief Bind texture. + + Bind \a texId to wanted texture unit and shader uniform. By default + the pixmaps are bound to shaders using "textureN" as the uniform name, + where N equals to \a unit. + + Optional texture size can be given as parameter, inversion of it will + be given to shaders if they want to use it (uniform name == "invSize"). + Only size given when binding unit 0 is used. The texture size is also + needed by some of the drawing methods. + */ + void bindTexture(quint32 texId, const QSize &texSize = QSize(-1, -1), quint32 unit = 0, const QString &uniformName = QString()); + + + //TODO: Refactor this to be more automatic, only x pixmaps need inverting. + //use inverted textures coords + void setInvertTexture(bool invert); + + /*! + \brief Draw texture. + + Draws the bound texture(s) into the rectangle at position (\a x, \a y) + with the given \a width and \a height. + */ + void draw(int x, int y, int width, int height); + + /*! + \brief Draw texture. + + Draws the bound texture(s) at position (\a x, \a y). The size that + was given as parameter to bindTexture() will be used as width and + height. + */ + void draw(int x, int y); + + /*! + \brief Draw texture. + + Draws the bound texture(s) into the given \a rectangle. + */ + void draw(const QRect &rectangle); + + /*! + \brief Draw texture. + + Draws multiple patches of texture(s) \a sources into the given + \a targets. + + The size that was given as parameter to bindTexture() will be used + for calculating the texture coordinates from the source rectangles. + */ + void draw(const QList& targets, const QList& sources); + + /*! + \brief Draw texture. + + Draws the rectangular portion \a source of the bound texture(s) + into the given \a target rectangle. + + The size that was given as parameter to bindTexture() will be used + for calculating the texture coordinates from the source rectangle. + */ + void draw(const QRect &target, const QRect &source); + + /*! + \brief Set the viewport size. + + By default the viewport size is defined by the viewport widget (screen + size), but for example when rendering into a texture using FBO the + viewport size must be set manually to match the FBO size. + + The viewport size will be reset to screen size when calling the end() + method. Viewport size can be reset manually by giving QSize(-1,-1) as + parameter. + + \param QSize Size of the viewport. + */ + void setViewportSize(const QSize &size); + +private: + + /*! + \brief Constructor. + */ + DuiGLES2Renderer(); + + /*! + \brief Initialization method for the class. + + Method initializes few default shaders and other GL specific data + needed for rendering. + */ + void init(QGLWidget *glWidget); + + //! Pointer to private implementation class object. + DuiGLES2RendererPrivate *const d_ptr; + + Q_DISABLE_COPY(DuiGLES2Renderer) + Q_DECLARE_PRIVATE(DuiGLES2Renderer) +}; + +#endif + diff --git a/src/painting/duiglrenderer.cpp b/src/painting/duiglrenderer.cpp new file mode 100644 index 000000000..9164f6738 --- /dev/null +++ b/src/painting/duiglrenderer.cpp @@ -0,0 +1,1267 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiglrenderer.h" +#include "duiglrenderer_p.h" + +#ifdef DUI_USE_OPENGL +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "duiglwidget.h" +#include "duiglshader.h" +#include "duiglshaderprogram.h" +#include "duiglshaderuniform.h" + +#include "duidebug.h" + +#include "duiparticleengine.h" + +static const char *DefaultVertSrc = "\n\ + attribute highp vec4 vertex;\n \ + attribute lowp vec2 texCoord;\n \ + uniform highp mat4 matProj;\n \ + uniform highp mat4 matWorld;\n \ + varying lowp vec2 fragTexCoord;\n \ + void main(void)\n \ + {\n\ + gl_Position = matProj * matWorld * vertex;\n\ + fragTexCoord = texCoord;\n \ + }\n"; + +static const char *DefaultFragSrc = "\n\ + varying lowp vec2 fragTexCoord;\n\ + uniform sampler2D texture0;\n\ + uniform lowp float opacity;\n\ + void main(void)\n\ + {\n\ + //gl_FragColor = vec4(0.0,0.0,1.0,1.0);\n\ + gl_FragColor = texture2D(texture0, fragTexCoord) * opacity;\n\ + }\n"; + +static const char *ParticleVertSrc = "\n\ + attribute highp vec4 vertex;\n \ + attribute lowp vec2 texCoord;\n \ + attribute lowp vec4 color;\n \ + uniform highp mat4 matProj;\n \ + uniform highp mat4 matWorld;\n \ + varying lowp vec2 fragTexCoord;\n \ + varying lowp vec4 fragColor;\n \ + void main(void)\n \ + {\n\ + gl_Position = matProj * matWorld * vertex;\n\ + fragTexCoord = texCoord;\n \ + fragColor = color;\n \ + }\n"; + +static const char *ParticleFragSrc = "\n\ + varying lowp vec2 fragTexCoord;\n\ + varying lowp vec4 fragColor;\n\ + uniform sampler2D texture0;\n\ + void main(void)\n\ + {\n\ + gl_FragColor = texture2D(texture0, fragTexCoord) * fragColor;\n\ + }\n"; + +/*static const char* PatchedVertSrc = "\n\ + attribute highp vec4 vertex;\n \ + uniform highp mat4 matProj;\n \ + uniform highp mat4 matWorld;\n \ + void main(void)\n \ + {\n\ + gl_Position = matProj * matWorld * vertex;\n\ + }\n"; +static const char* PatchedFragSrc = "\n\ + uniform lowp vec3 color;\n\ + void main(void)\n\ + {\n\ + gl_FragColor.rgb = color;\n\ + }\n";*/ + +static const EGLint pixmapAttribs[] = { + EGL_TEXTURE_TARGET, EGL_TEXTURE_2D, + EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGB, + EGL_NONE +}; + +static const GLuint DUI_ATTR_VERTEX = 0; +static const GLuint DUI_ATTR_TCOORD = 1; +static const GLuint DUI_ATTR_VCOLOR = 2; + +class DuiGLRendererPrivate +{ +public: + DuiGLRendererPrivate(); + virtual ~DuiGLRendererPrivate(); + + void setupGL(const QTransform &transform, GLuint texid, const QSizeF &size, bool inverted); + void setupMatrices(const QTransform &transform); + void setupTexturing(GLuint texid); + void setupVertices(const QSizeF &size, bool inverted); + GLuint setupVertices(const QSizeF &texSize, const QList& sourceRects, const QList& targetRects); + GLuint setupVertices(const DuiParticle *particles, int numParticles); + void restoreGL(); + void setupUniforms(const DuiGLShaderProgram *program, const QSizeF &size, IDuiGLUniformProvider *provider = NULL); + + GLfloat m_matProj[4][4]; + GLfloat m_matWorld[4][4]; + + //this are used when rendering scalableimages or particles (variable number of vertices) + QVector *m_vertices; + QVector *m_texCoords; + QVector *m_color; + QVector *m_indices; + + //this are used when rendering plain pixmap (constant number of vertices) + GLfloat m_pixmapVertices[8]; + GLfloat m_pixmapTexCoords[8]; + GLfloat m_pixmapTexCoordsInv[8]; + + QPointer m_glWidget; + + ShaderCache *m_shaderCache; + + ProgramCache *m_programCache; + + const DuiGLShaderProgram *m_defaultProgram; + + IDuiGLUniformProvider *m_uniformProvider; + + QSize *m_viewportSize; + + static EGLConfig config; + EGLDisplay dpy; + PixmapHash *bound_pixmaps; + + void *m_oldVert; + void *m_oldCoord; + void *m_oldColor; + //GLint m_oldTexture; + GLint *m_oldProgram; + GLboolean *m_oldDepthTest; + GLboolean *m_oldBlend; +}; + +// Don't touch this! This is independent of QGLWidget +EGLConfig DuiGLRendererPrivate::config = 0; + +DuiGLRendererPrivate::DuiGLRendererPrivate() + : m_glWidget(NULL), m_uniformProvider(NULL), m_viewportSize(0) +{ + dpy = eglGetDisplay(EGLNativeDisplayType(QX11Info::display())); +} + +DuiGLRendererPrivate::~DuiGLRendererPrivate() +{ +} + +void DuiGLRendererPrivate::setupMatrices(const QTransform &transform) +{ +// qDebug() << __FUNCTION__ << (quint32) QGLContext::currentContext(); + //TODO: don't recreate the matrix always when rendering a frame + // recreate matrix only when the gl widget size has actually changed + //setup/correct the projection matrix depending on the viewport size + GLfloat w = m_viewportSize->width() == -1 ? m_glWidget->width() : m_viewportSize->width(); + GLfloat h = m_viewportSize->height() == -1 ? m_glWidget->height() : m_viewportSize->height(); + glViewport(0, 0, w, h); + m_matProj[0][0] = 2.0 / w; + m_matProj[1][1] = -2.0 / h; + + //GLfloat matWorld[4][4] = + //{ + // {transform.m11(), transform.m12(), 0.0, transform.m13()}, + // {transform.m21(), transform.m22(), 0.0, transform.m23()}, + // { 0.0, 0.0, 1.0, 0.0}, + // {transform.dx() + 0.5, transform.dy() + 0.5, 0.0, transform.m33()} + //}; + //generate trasformation matrix to be given to opengl + //const QTransform& transform = painter->combinedTransform(); + m_matWorld[0][0] = transform.m11(); + m_matWorld[0][1] = transform.m12(); + m_matWorld[0][3] = transform.m13(); + m_matWorld[1][0] = transform.m21(); + m_matWorld[1][1] = transform.m22(); + m_matWorld[1][3] = transform.m23(); + m_matWorld[3][0] = transform.dx(); + m_matWorld[3][1] = transform.dy(); + m_matWorld[3][3] = transform.m33(); + + glGetBooleanv(GL_BLEND, m_oldBlend); + glEnable(GL_BLEND); + + glGetBooleanv(GL_DEPTH_TEST, m_oldDepthTest); + glDisable(GL_DEPTH_TEST); +} + +void DuiGLRendererPrivate::setupGL(const QTransform &transform, GLuint texid, const QSizeF &size, bool inverted) +{ + setupMatrices(transform); + setupTexturing(texid); + setupVertices(size, inverted); +} + +void DuiGLRendererPrivate::setupTexturing(GLuint texid) +{ +// qDebug() << __FUNCTION__ << (quint32) QGLContext::currentContext(); + //glGetIntegerv(GL_TEXTURE_BINDING_2D, &m_oldTexture); + + //setup texturing + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, texid); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); +} + + +void DuiGLRendererPrivate::setupVertices(const QSizeF &size, bool inverted) +{ + //setup vertices for the widget + m_pixmapVertices[3] = size.height(); + m_pixmapVertices[4] = size.width(); + m_pixmapVertices[5] = size.height(); + m_pixmapVertices[6] = size.width(); + + glGetVertexAttribPointerv(DUI_ATTR_VERTEX, GL_VERTEX_ATTRIB_ARRAY_POINTER, &m_oldVert); + glGetVertexAttribPointerv(DUI_ATTR_TCOORD, GL_VERTEX_ATTRIB_ARRAY_POINTER, &m_oldCoord); + + glEnableVertexAttribArray(DUI_ATTR_VERTEX); + glVertexAttribPointer(DUI_ATTR_VERTEX, 2, GL_FLOAT, GL_FALSE, 0, m_pixmapVertices); + glEnableVertexAttribArray(DUI_ATTR_TCOORD); + glVertexAttribPointer(DUI_ATTR_TCOORD, 2, GL_FLOAT, GL_FALSE, 0, inverted ? m_pixmapTexCoordsInv : m_pixmapTexCoords); +} + +GLuint DuiGLRendererPrivate::setupVertices(const QSizeF &texSize, const QList& sourceRects, const QList& targetRects) +{ + int numRects = sourceRects.size(); + if (sourceRects.size() != targetRects.size()) { + numRects = (sourceRects.size() < targetRects.size()) ? sourceRects.size() : targetRects.size(); + } + + //setup vertices for the target rects + GLfloat *vertices = m_vertices->data(); + GLfloat *texcoords = m_texCoords->data(); + GLuint numVert = 0; + for (int i = 0; i < numRects; ++i) { + const QRect &rc2 = targetRects.at(i); + QRectF rc = rc2; + GLfloat x1 = rc.left(); + GLfloat x2 = rc.right(); + GLfloat y1 = rc.top(); + GLfloat y2 = rc.bottom(); + + vertices[numVert++] = x1; vertices[numVert++] = y1; + vertices[numVert++] = x1; vertices[numVert++] = y2; + vertices[numVert++] = x2; vertices[numVert++] = y2; + vertices[numVert++] = x2; vertices[numVert++] = y1; + } + + + //setup texture coords for the target rects + GLfloat dx = 1.0 / texSize.width(); + GLfloat dy = 1.0 / texSize.height(); + GLuint numCoord = 0; + for (int i = 0; i < numRects; ++i) { + QRectF rc = sourceRects.at(i); + + GLfloat u1 = rc.left() * dx; + GLfloat u2 = rc.right() * dx; + GLfloat v1 = 1.0 - rc.top() * dy; + GLfloat v2 = 1.0 - rc.bottom() * dy; + + texcoords[numCoord++] = u1; texcoords[numCoord++] = v1; + texcoords[numCoord++] = u1; texcoords[numCoord++] = v2; + texcoords[numCoord++] = u2; texcoords[numCoord++] = v2; + texcoords[numCoord++] = u2; texcoords[numCoord++] = v1; + } + + glGetVertexAttribPointerv(DUI_ATTR_VERTEX, GL_VERTEX_ATTRIB_ARRAY_POINTER, &m_oldVert); + glGetVertexAttribPointerv(DUI_ATTR_TCOORD, GL_VERTEX_ATTRIB_ARRAY_POINTER, &m_oldCoord); + + glEnableVertexAttribArray(DUI_ATTR_VERTEX); + glVertexAttribPointer(DUI_ATTR_VERTEX, 2, GL_FLOAT, GL_FALSE, 0, vertices); + glEnableVertexAttribArray(DUI_ATTR_TCOORD); + glVertexAttribPointer(DUI_ATTR_TCOORD, 2, GL_FLOAT, GL_FALSE, 0, texcoords); + + return numRects * 6; +} + +GLuint DuiGLRendererPrivate::setupVertices(const DuiParticle *particles, int numParticles) +{ + //resize the vertex, texcoord and color arrays if needed + if (m_vertices->size() < numParticles * 4 * 2) + m_vertices->resize(numParticles * 4 * 2); + if (m_texCoords->size() < numParticles * 4 * 2) + m_texCoords->resize(numParticles * 4 * 2); + if (m_color->size() < numParticles * 4 * 4) + m_color->resize(numParticles * 4 * 4); + + //fill the vertex, textcoord and color arrays + GLfloat *vertices = m_vertices->data(); + GLfloat *texcoords = m_texCoords->data(); + GLfloat *colors = m_color->data(); + GLuint numVert = 0; + GLuint numCoord = 0; + GLuint numColor = 0; + GLuint numVisibleParticles = 0; + for (int i = 0; i < numParticles; ++i) { + const DuiParticle &particle = particles[i]; + if (particles[i].alive) { + ++numVisibleParticles; + GLfloat x1 = particle.px - ((particle.sx / 2.0) * particle.scale); + GLfloat x2 = particle.px + ((particle.sx / 2.0) * particle.scale); + GLfloat y1 = particle.py - ((particle.sx / 2.0) * particle.scale); + GLfloat y2 = particle.py + ((particle.sy / 2.0) * particle.scale); + vertices[numVert++] = (GLfloat)x1; vertices[numVert++] = (GLfloat)y1; + vertices[numVert++] = (GLfloat)x1; vertices[numVert++] = (GLfloat)y2; + vertices[numVert++] = (GLfloat)x2; vertices[numVert++] = (GLfloat)y2; + vertices[numVert++] = (GLfloat)x2; vertices[numVert++] = (GLfloat)y1; + + texcoords[numCoord++] = 0.0; texcoords[numCoord++] = 1.0; + texcoords[numCoord++] = 0.0; texcoords[numCoord++] = 0.0; + texcoords[numCoord++] = 1.0; texcoords[numCoord++] = 0.0; + texcoords[numCoord++] = 1.0; texcoords[numCoord++] = 1.0; + + colors[numColor++] = qRed(particle.color) / 255.0; colors[numColor++] = qGreen(particle.color) / 255.0; colors[numColor++] = qBlue(particle.color) / 255.0; colors[numColor++] = qAlpha(particle.color) / 255.0; + colors[numColor++] = qRed(particle.color) / 255.0; colors[numColor++] = qGreen(particle.color) / 255.0; colors[numColor++] = qBlue(particle.color) / 255.0; colors[numColor++] = qAlpha(particle.color) / 255.0; + colors[numColor++] = qRed(particle.color) / 255.0; colors[numColor++] = qGreen(particle.color) / 255.0; colors[numColor++] = qBlue(particle.color) / 255.0; colors[numColor++] = qAlpha(particle.color) / 255.0; + colors[numColor++] = qRed(particle.color) / 255.0; colors[numColor++] = qGreen(particle.color) / 255.0; colors[numColor++] = qBlue(particle.color) / 255.0; colors[numColor++] = qAlpha(particle.color) / 255.0; + } + } + + //reinitialize the index array if the particle count has increased over the current maximum limit + if (m_indices->size() < (int)numVisibleParticles * 6) { + m_indices->resize(numVisibleParticles * 6); + GLushort *indices = m_indices->data(); + for (GLuint i = 0; i < numVisibleParticles; i++) { + indices[i*6+0] = i * 4 + 0; //x1 y1 TL + indices[i*6+1] = i * 4 + 1; //x1 y2 BL + indices[i*6+2] = i * 4 + 2; //x2 y2 BR + indices[i*6+3] = i * 4 + 0; //x1 y1 TL + indices[i*6+4] = i * 4 + 2; //x2 y2 BR + indices[i*6+5] = i * 4 + 3; //x2 y1 TR + } + } + + glGetVertexAttribPointerv(DUI_ATTR_VERTEX, GL_VERTEX_ATTRIB_ARRAY_POINTER, &m_oldVert); + glGetVertexAttribPointerv(DUI_ATTR_TCOORD, GL_VERTEX_ATTRIB_ARRAY_POINTER, &m_oldCoord); + glGetVertexAttribPointerv(DUI_ATTR_VCOLOR, GL_VERTEX_ATTRIB_ARRAY_POINTER, &m_oldColor); + + glEnableVertexAttribArray(DUI_ATTR_VERTEX); + glVertexAttribPointer(DUI_ATTR_VERTEX, 2, GL_FLOAT, GL_FALSE, 0, vertices); + glEnableVertexAttribArray(DUI_ATTR_TCOORD); + glVertexAttribPointer(DUI_ATTR_TCOORD, 2, GL_FLOAT, GL_FALSE, 0, texcoords); + glEnableVertexAttribArray(DUI_ATTR_VCOLOR); + glVertexAttribPointer(DUI_ATTR_VCOLOR, 4, GL_FLOAT, GL_FALSE, 0, colors); + + return numVisibleParticles * 6; +} + +void DuiGLRendererPrivate::restoreGL() +{ +// qDebug() << __FUNCTION__ << (quint32) QGLContext::currentContext(); + if (m_glWidget) { + m_glWidget->paintEngine()->syncState(); + } + + //glDisable(GL_BLEND); + + //disable vertex and texture coord arrays + //glDisableVertexAttribArray(DUI_ATTR_VERTEX); + //glDisableVertexAttribArray(DUI_ATTR_TCOORD); + glDisableVertexAttribArray(DUI_ATTR_VCOLOR); + + glVertexAttribPointer(DUI_ATTR_VERTEX, 2, GL_FLOAT, GL_FALSE, 0, m_oldVert); + glVertexAttribPointer(DUI_ATTR_TCOORD, 2, GL_FLOAT, GL_FALSE, 0, m_oldCoord); + //glVertexAttribPointer(DUI_ATTR_VCOLOR, 4, GL_FLOAT, GL_FALSE, 0, m_oldColor); + + //activate the first texture unit so that qt still renders correctly + //for some reason they never activate the unit after initialization. + //glActiveTexture(GL_TEXTURE0); + //glBindTexture(GL_TEXTURE_2D, m_oldTexture); + + glUseProgram(*m_oldProgram); + + if (!(*m_oldBlend)) + glDisable(GL_BLEND); + + if ((*m_oldDepthTest)) + glEnable(GL_DEPTH_TEST); + + //reset the manually set viewport size after rendering + *m_viewportSize = QSize(-1, -1); + + //glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); +} + + +void DuiGLRendererPrivate::setupUniforms(const DuiGLShaderProgram *program, const QSizeF &size, IDuiGLUniformProvider *provider) +{ + //use provider given as parameter, if is is NULL then use global provider + //previously set with DuiGLRenderer::setUniformProvider method. + IDuiGLUniformProvider *usedProvider = provider ? provider : m_uniformProvider; + if (usedProvider) { + const DuiGLUniformList &uniforms = program->uniforms(); + DuiGLUniformList::const_iterator uniformsEnd = uniforms.constEnd(); + + for (DuiGLUniformList::const_iterator i = uniforms.begin(); i != uniformsEnd; ++i) { + //set the default values and give rest to the provider + QString uniformId = i.key(); + if (uniformId == "texture0") + i.value() = (GLuint)0; + else if (uniformId == "matWorld") + i.value() = m_matWorld; + else if (uniformId == "matProj") + i.value() = m_matProj; + else if (uniformId == "invSize") + i.value() = QSizeF(1.0f / size.width(), 1.0f / size.height()); + else { + usedProvider->setUniformValue(uniformId, *i); + } + } + } else { + //just set the default values if found + const DuiGLUniformList &uniforms = program->uniforms(); + const DuiGLUniformList::const_iterator end = uniforms.constEnd(); + DuiGLUniformList::const_iterator i = uniforms.constFind("texture0"); + if (i != end) + program->uniform("texture0") = (GLuint)0; + i = uniforms.constFind("matWorld"); + if (i != end) + program->uniform("matWorld") = m_matWorld; + i = uniforms.constFind("matProj"); + if (i != end) + program->uniform("matProj") = m_matProj; + i = uniforms.constFind("invSize"); + if (i != end) + program->uniform("invSize") = QSizeF(1.0f / size.width(), 1.0f / size.height()); + } +} + + +DuiGLRenderer::DuiGLRenderer() + : d_ptr(new DuiGLRendererPrivate()) +{ + qWarning("DuiGLRenderer is DEPRECATED. Use DuiGLES2Renderer instead."); +} + +DuiGLRenderer::~DuiGLRenderer() +{ + delete d_ptr; +} +#else + +DuiGLRenderer::DuiGLRenderer() + : d_ptr(NULL) +{ + qWarning("DuiGLRenderer is DEPRECATED. Use DuiGLES2Renderer instead."); +} + +DuiGLRenderer::~DuiGLRenderer() +{ +} + +#endif + +DuiGLRenderer *DuiGLRenderer::instance() +{ + //qWarning("DuiGLRenderer is DEPRECATED. Use DuiGLES2Renderer instead."); + + static DuiGLRenderer duiGLRenderer; + return &duiGLRenderer; +} + +#ifdef DUI_USE_OPENGL +void DuiGLRenderer::initGL(DuiGLWidget *glWidget) +{ +// qDebug() << __FUNCTION__ << (quint32) QGLContext::currentContext(); +// d_ptr->dpy = eglGetDisplay(EGLNativeDisplayType(QX11Info::display())); +// d_ptr->m_glWidget = glWidget; + + //init the orthogonal projection matrix + //glOrtho(0, w, h, 0, -1, 1): + //2.0/w, 0.0, 0.0, -1.0 + //0.0, -2.0/h, 0.0, 1.0 + //0.0, 0.0, -1.0, 0.0 + //0.0, 0.0, 0.0, 1.0 + GLfloat w = glWidget->width(); + GLfloat h = glWidget->height(); + d_ptr->m_matProj[0][0] = 2.0 / w; d_ptr->m_matProj[1][0] = 0.0; d_ptr->m_matProj[2][0] = 0.0; d_ptr->m_matProj[3][0] = -1.0; + d_ptr->m_matProj[0][1] = 0.0; d_ptr->m_matProj[1][1] = -2.0 / h; d_ptr->m_matProj[2][1] = 0.0; d_ptr->m_matProj[3][1] = 1.0; + d_ptr->m_matProj[0][2] = 0.0; d_ptr->m_matProj[1][2] = 0.0; d_ptr->m_matProj[2][2] = -1.0; d_ptr->m_matProj[3][2] = 0.0; + d_ptr->m_matProj[0][3] = 0.0; d_ptr->m_matProj[1][3] = 0.0; d_ptr->m_matProj[2][3] = 0.0; d_ptr->m_matProj[3][3] = 1.0; + + //TODO: Create some other default shaders here as well? + + //from file + //createShader("DefaultVert", DuiGLShader::VertexShader); + //createShader("DefaultFrag", DuiGLShader::FragmentShader); + + //from src + createShader("DefaultVert", DefaultVertSrc, DuiShaderVertex); + createShader("DefaultFrag", DefaultFragSrc, DuiShaderFragment); + + + createShader("ParticleVert", ParticleVertSrc, DuiShaderVertex); + createShader("ParticleFrag", ParticleFragSrc, DuiShaderFragment); + + d_ptr->m_defaultProgram = createProgram("Default", "DefaultVert", "DefaultFrag"); + createProgram("Particle", "ParticleVert", "ParticleFrag"); + + //TODO: Future optimizations, uncomment these if/when the center of the + // scalableimage is rendered with solid color. + /*createShader("PatchedVert", PatchedVertSrc, DuiShaderVertex); + createShader("PatchedFrag", PatchedFragSrc, DuiShaderFragment); + createProgram("Patched", "PatchedVert", "PatchedFrag");*/ +} + +DuiGLWidget *DuiGLRenderer::GLWidget() const +{ + return d_ptr->m_glWidget; +} + +void DuiGLRenderer::setGLWidget(DuiGLWidget *glWidget) +{ + if (d_ptr->m_glWidget != glWidget) { + if (glWidget) { + GLfloat **mp = glWidget->matProj(); + GLfloat **mw = glWidget->matWorld(); + for (int i = 0; i < 4; ++i) + for (int j = 0; j < 4; ++j) { + d_ptr->m_matProj[i][j] = mp[i][j]; + d_ptr->m_matWorld[i][j] = mw[i][j]; + } + GLfloat *pv = glWidget->pixmapVertices(); + GLfloat *ptc = glWidget->pixmapTexCoords(); + GLfloat *ptci = glWidget->pixmapTexCoordsInv(); + for (int i = 0; i < 8; ++i) { + d_ptr->m_pixmapVertices[i] = pv[i]; + d_ptr->m_pixmapTexCoords[i] = ptc[i]; + d_ptr->m_pixmapTexCoordsInv[i] = ptci[i]; + } + d_ptr->m_vertices = glWidget->vertices(); + d_ptr->m_texCoords = glWidget->texCoords(); + d_ptr->m_color = glWidget->color(); + d_ptr->m_indices = glWidget->indices(); + d_ptr->m_shaderCache = glWidget->shaderCache(); + d_ptr->m_programCache = glWidget->programCache(); + d_ptr->m_defaultProgram = glWidget->defaultProgram(); + d_ptr->m_uniformProvider = glWidget->uniformProvider(); + d_ptr->m_viewportSize = glWidget->viewportSize(); + d_ptr->bound_pixmaps = glWidget->boundPixmaps(); + d_ptr->m_oldVert = glWidget->oldVert(); + d_ptr->m_oldCoord = glWidget->oldCoord(); + d_ptr->m_oldColor = glWidget->oldColor(); + d_ptr->m_oldProgram = glWidget->oldProgram(); + d_ptr->m_oldDepthTest = glWidget->oldDepthTest(); + d_ptr->m_oldBlend = glWidget->oldBlend(); + glWidget->makeCurrent(); + } else { + for (int i = 0; i < 4; ++i) + for (int j = 0; j < 4; ++j) { + d_ptr->m_matProj[i][j] = 0; + d_ptr->m_matWorld[i][j] = 0; + } + d_ptr->m_vertices = 0; + d_ptr->m_texCoords = 0; + d_ptr->m_color = 0; + d_ptr->m_indices = 0; + d_ptr->m_shaderCache = 0; + d_ptr->m_programCache = 0; + d_ptr->m_defaultProgram = 0; + d_ptr->m_uniformProvider = 0; + d_ptr->m_viewportSize = 0; + d_ptr->bound_pixmaps = 0; + d_ptr->m_oldVert = 0; + d_ptr->m_oldCoord = 0; + d_ptr->m_oldColor = 0; + d_ptr->m_oldProgram = 0; + d_ptr->m_oldDepthTest = 0; + d_ptr->m_oldBlend = 0; + } + d_ptr->m_glWidget = glWidget; + } +// qDebug() << __FUNCTION__ << (quint32) QGLContext::currentContext(); +} + +const DuiGLShader *DuiGLRenderer::createShader(const QString &filename, DuiShaderType type) +{ + //open the shader file for reading + QFile shaderFile(filename); + if (!shaderFile.open(QIODevice::ReadOnly | QIODevice::Text)) { + duiWarning("DuiGLRenderer") << "createShader(" << filename << ") could not open file."; + return NULL; + } + + //read the source from the file + QTextStream stream(&shaderFile); + QString source = stream.readAll(); + if (source.length() == 0) { + duiWarning("DuiGLRenderer") << "createShader(" << filename << ") file does not contain data."; + return NULL; + } + + //try to create a shader from the source + QFileInfo fileInfo(shaderFile); + QString key = fileInfo.fileName(); + + const DuiGLShader *shader = createShader(key, source, type);; + if (!shader) { + //TODO Try to load shader binary here + } + + return shader; +} + +const DuiGLShader *DuiGLRenderer::createShader(const QString &key, const QString &source, DuiShaderType type) +{ + if (!d_ptr->m_glWidget) { + duiWarning("DuiGLRenderer") << "createShader()" << "DuiGLRenderer not initialized yet."; + return NULL; + } +// qDebug() << __FUNCTION__ << (quint32) QGLContext::currentContext(); + + QGLContext *ctx = (QGLContext *)d_ptr->m_glWidget->context(); + DuiGLShader *shader = NULL; + if (type == DuiShaderUndefined) { + //TODO: this kind of "autodetection" works only when linking programs with invalid shaders. + // Is this kind of automatic shader detection needed? It could be be achieved by detecting + // some special keywords from shader sources. + /*duiDebug("DuiGLRenderer") << "DuiGLRenderer::createShader() Auto detecting shader type."; + shader = new DuiGLShader(DuiGLShader::VertexShader, ctx); + shader->addSource(source.toLatin1()); + if( !shader->compile() ) + { + duiWarning("DuiGLRenderer) << "createShader(" << key << "):" << " shader failed to compile:" << shader->log(); + delete shader; + shader = new DuiGLShader(DuiGLShader::FragmentShader, ctx); + shader->addSource(source.toLatin1()); + if( !shader->compile() ) + { + duiWarning("DuiGLRenderer) << "createShader(" << key << "):" << " shader failed to compile:" << shader->log(); + delete shader; + return NULL; + } + }*/ + return NULL; + } else { + shader = new DuiGLShader((DuiGLShader::ShaderType)type, key, ctx); + if (shader->id() > 0) { + shader->addSource(source/*.toLatin1()*/); + if (!shader->compile()) { + duiWarning("DuiGLRenderer") << "createShader(" << key << "):" << " shader failed to compile:" << shader->log(); + delete shader; + return NULL; + } + } else { + duiWarning("DuiGLRenderer") << "Shader creation failed."; + delete shader; + return NULL; + } + } + d_ptr->m_shaderCache->insert(key, shader); + return shader; +} + +const DuiGLShader *DuiGLRenderer::getShader(const QString &key) +{ + if (d_ptr->m_shaderCache->contains(key)) { + return (*d_ptr->m_shaderCache)[key]; + } + return NULL; +} + +const DuiGLShaderProgram *DuiGLRenderer::createProgram(const QString &key, const QList& shaderKeyList) +{ + if (!d_ptr->m_glWidget) { + duiWarning("DuiGLRenderer") << "createProgram()" << "DuiGLRenderer not initialized yet."; + return NULL; + } +// qDebug() << __FUNCTION__ << (quint32) QGLContext::currentContext(); + + QGLContext *ctx = (QGLContext *)d_ptr->m_glWidget->context(); + + //create the shader program and add the wanted shaders into it + bool vert = false; + bool frag = false; + DuiGLShaderProgram *program = new DuiGLShaderProgram(ctx); + + QList::const_iterator shaderKeyListEnd = shaderKeyList.constEnd(); + + for (QList::const_iterator i = shaderKeyList.begin(); i != shaderKeyListEnd; ++i) { + //fetch precompiled shader from cache and add it to the program + const DuiGLShader *shader = getShader(*i); + if (shader) { + program->addShader(shader); + if (shader->type() == DuiGLShader::VertexShader) + vert = true; + else if (shader->type() == DuiGLShader::FragmentShader) + frag = true; + } else { + duiWarning("DuiGLRenderer") << "createProgram() Ignoring shader " << *i; + } + } + + //add default frag or vert shaders if missing from shader list + if (!vert) { + duiWarning("DuiGLRenderer") << "createProgram() Vertex shader missing, adding default one."; + if (!getShader("DefaultVert")) { + duiWarning("DuiGLRenderer") << "createProgram() Default shader does not exist."; + delete program; + return NULL; + } + program->addShader(getShader("DefaultVert")); + } + if (!frag) { + duiWarning("DuiGLRenderer") << "createProgram() Fragment shader missing, adding default one."; + if (!getShader("DefaultFrag")) { + duiWarning("DuiGLRenderer") << "createProgram() Default shader does not exist."; + delete program; + return NULL; + } + program->addShader(getShader("DefaultFrag")); + } + + glBindAttribLocation(program->id(), DUI_ATTR_VERTEX, "vertex"); + glBindAttribLocation(program->id(), DUI_ATTR_TCOORD, "texCoord"); + glBindAttribLocation(program->id(), DUI_ATTR_VCOLOR, "color"); + + //link program + if (!program->link()) { + duiWarning("DuiGLRenderer") << "createProgram(" << key << ", " << shaderKeyList << "):" << " failed to link:" << program->log(); + delete program; + return NULL; + } + + d_ptr->m_programCache->insert(key, program); + return program; +} + +const DuiGLShaderProgram *DuiGLRenderer::createProgram(const QString &key, const QString &vertShader, const QString &fragShader) +{ + QList shaders; + shaders.push_back(vertShader); + shaders.push_back(fragShader); + return createProgram(key, shaders); +} + +//DuiGLShaderProgram* DuiGLRenderer::createProgramFromFiles(const QString& key, const QList& shaderFileList) +//{ +//} + +const DuiGLShaderProgram *DuiGLRenderer::createProgramFromFiles(const QString &key, const QString &fragShaderFile, const QString &vertShaderFile) +{ + const DuiGLShader *frag = createShader(fragShaderFile, DuiShaderFragment); + if (!frag) { + frag = getShader("DefaultFrag"); + } + + const DuiGLShader *vert = createShader(vertShaderFile, DuiShaderVertex); + if (!vert) { + vert = getShader("DefaultVert"); + } + + return createProgram(key, frag->name(), vert->name()); +} + +const DuiGLShaderProgram *DuiGLRenderer::getProgram(const QString &key) +{ + if (d_ptr->m_programCache->contains(key)) { + return (*d_ptr->m_programCache)[key]; + } + + return NULL; +} + + +quint32 DuiGLRenderer::bindX11Pixmap(Qt::HANDLE pixmap) +{ + EGLSurface eglpixmap = 0; + + // If surface does not yet exist, initialize and find appropriates EGL surface + if (!d_ptr->config) { + EGLint ecfgs = 0; + EGLConfig configs[20]; + + static const EGLint pixmap_config[] = { + EGL_SURFACE_TYPE, EGL_PIXMAP_BIT, + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + EGL_DEPTH_SIZE, 0, + EGL_BIND_TO_TEXTURE_RGB, EGL_TRUE, + EGL_NONE + }; + + if (!eglChooseConfig(d_ptr->dpy, pixmap_config, configs, + 20, &ecfgs) || !ecfgs) { + duiWarning("DuiGLRenderer") << "No appropriate EGL configuration for texture from pixmap!"; + return 0; + } + for (EGLint i = 0; i < ecfgs; ++i) { + eglpixmap = eglCreatePixmapSurface(d_ptr->dpy, configs[i], + (EGLNativePixmapType) pixmap, + pixmapAttribs); + if (eglpixmap == EGL_NO_SURFACE) + continue; + else { + d_ptr->config = configs[i]; + break; + } + } + } + + // Returns the cached texture if we have one already + TexturePixmap tp = d_ptr->bound_pixmaps->value(pixmap); + if (tp.texture > 0) + return tp.texture; + + // .. or create a new one + if (!eglpixmap) + eglpixmap = eglCreatePixmapSurface(d_ptr->dpy, d_ptr->config, + (EGLNativePixmapType) pixmap, + pixmapAttribs); + if (eglpixmap == EGL_NO_SURFACE) { + // Guys! do not put duiWarning here, it can't understand HEX! + qWarning("Cannot create EGL surface: 0x%x", eglGetError()); + return 0; + } + tp.eglpixmap = eglpixmap; + + glGenTextures(1, &tp.texture); + (*d_ptr->bound_pixmaps)[pixmap] = tp; + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, tp.texture); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + return tp.texture; +} + +void DuiGLRenderer::unbindX11Pixmap(Qt::HANDLE pixmap) +{ + TexturePixmap tp = d_ptr->bound_pixmaps->value(pixmap); + if (!tp.texture) + return; + + // free the pixmap and texture cache + eglDestroySurface(d_ptr->dpy, tp.eglpixmap); + tp.eglpixmap = EGL_NO_SURFACE; + //XSync(QX11Info::display(), FALSE); + glDeleteTextures(1, &tp.texture); + d_ptr->bound_pixmaps->remove(pixmap); +} + +void DuiGLRenderer::updateX11Pixmap(Qt::HANDLE pixmap) +{ + // catch updates to the pixmap here when they happen + TexturePixmap tp = d_ptr->bound_pixmaps->value(pixmap); + if (!tp.texture) + return; + + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, tp.texture); + + if (eglReleaseTexImage(d_ptr->dpy, tp.eglpixmap, + EGL_BACK_BUFFER) == EGL_FALSE) + duiWarning("DuiGLRenderer: Update pixmap, cant release bound texture"); + if (eglBindTexImage(d_ptr->dpy, tp.eglpixmap, + EGL_BACK_BUFFER) == EGL_FALSE) + // Guys! do not put duiWarning here, it can't understand HEX! + qWarning("DuiGLRenderer: Update pixmap, can't bind EGL texture to pixmap: 0x%x", eglGetError()); +} + +void DuiGLRenderer::drawTexture(const QTransform &transform, quint32 texId, const QSizeF &size, qreal opacity, + bool inverted) +{ + if (!d_ptr->m_glWidget) { + duiWarning("DuiGLRenderer") << "DuiGLRenderer::drawTexture()" << "DuiGLRenderer not initialized yet."; + return; + } + glGetIntegerv(GL_CURRENT_PROGRAM, d_ptr->m_oldProgram); + + d_ptr->m_defaultProgram->use(); + + d_ptr->setupGL(transform, texId, size, inverted); + + d_ptr->m_defaultProgram->uniform("texture0") = (GLuint)0; + d_ptr->m_defaultProgram->uniform("matWorld") = d_ptr->m_matWorld; + d_ptr->m_defaultProgram->uniform("matProj") = d_ptr->m_matProj; + + GLfloat o = opacity; + d_ptr->m_defaultProgram->uniform("opacity") = o; + + //render + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + + d_ptr->restoreGL(); +} + +void DuiGLRenderer::drawTexture(const DuiGLShaderProgram *program, const QTransform &transform, quint32 texId, + const QSizeF &size, IDuiGLUniformProvider *provider, + bool inverted) +{ + if (!d_ptr->m_glWidget) { + duiWarning("DuiGLRenderer") << "drawTexture()" << "DuiGLRenderer not initialized yet."; + return; + } + + //program->use(); + d_ptr->setupGL(transform, texId, size, inverted); + + d_ptr->setupUniforms(program, size, provider); + + //render + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + + d_ptr->restoreGL(); +} + +void DuiGLRenderer::drawTexture(const QString &programId, const QTransform &transform, quint32 texId, + const QSizeF &size, IDuiGLUniformProvider *provider, + bool inverted) +{ + if (!d_ptr->m_glWidget) { + duiWarning("DuiGLRenderer") << "drawTexture()" << "DuiGLRenderer not initialized yet."; + return; + } + +// qDebug() << __FUNCTION__ << (quint32) QGLContext::currentContext(); + d_ptr->m_glWidget->makeCurrent(); + + const DuiGLShaderProgram *program = getProgram(programId); + if (!program) { + duiWarning("DuiGLRenderer") << "drawPixmap(): Invalid program" << programId; + return; + } + + glGetIntegerv(GL_CURRENT_PROGRAM, d_ptr->m_oldProgram); + + program->use(); + + d_ptr->setupGL(transform, texId, size, inverted); + d_ptr->setupUniforms(program, size, provider); + + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + + d_ptr->restoreGL(); +} + +void DuiGLRenderer::drawPixmap(const QTransform &transform, const QPixmap &pixmap, qreal opacity) +{ + if (!d_ptr->m_glWidget) { + duiWarning("DuiGLRenderer") << "drawPixmap()" << "DuiGLRenderer not initialized yet."; + return; + } +// qDebug() << __FUNCTION__ << (quint32) QGLContext::currentContext(); + + GLuint tex = d_ptr->m_glWidget->bindTexture(pixmap, GL_TEXTURE_2D, GL_RGBA, QGLContext::PremultipliedAlphaBindOption); + drawTexture(transform, tex, pixmap.size(), opacity); +} + +void DuiGLRenderer::drawPatchedPixmap(const QTransform &transform, const QPixmap &pixmap, qreal opacity, + const QList& sourceRects, const QList& targetRects) +{ + if (!d_ptr->m_glWidget) { + + duiWarning("DuiGLRenderer") << "drawPatchedPixmap()" << "DuiGLRenderer not initialized yet."; + return; + } + + d_ptr->m_glWidget->makeCurrent(); +// qDebug() << __FUNCTION__ << (quint32) QGLContext::currentContext(); + GLuint tex = d_ptr->m_glWidget->bindTexture(pixmap, GL_TEXTURE_2D, GL_RGBA, QGLContext::PremultipliedAlphaBindOption); + + glGetIntegerv(GL_CURRENT_PROGRAM, d_ptr->m_oldProgram); + d_ptr->m_defaultProgram->use(); + + d_ptr->setupMatrices(transform); + d_ptr->setupTexturing(tex); + GLuint num = d_ptr->setupVertices(pixmap.size(), sourceRects, targetRects); + + d_ptr->m_defaultProgram->uniform("texture0") = (GLuint)0; + d_ptr->m_defaultProgram->uniform("matWorld") = d_ptr->m_matWorld; + d_ptr->m_defaultProgram->uniform("matProj") = d_ptr->m_matProj; + + GLfloat o = opacity; + d_ptr->m_defaultProgram->uniform("opacity") = o; + + glDrawElements(GL_TRIANGLES, num, GL_UNSIGNED_SHORT, d_ptr->m_indices->data()); + + //TODO: Future optimizations, uncomment these when the graphics are updated + // to support solid center patch. + //draw corners and edges with blending and draw center without blending + /*glDrawElements(GL_TRIANGLES, num-6, GL_UNSIGNED_SHORT, d_ptr->m_indices.data()); + glDisable(GL_BLEND); + //glBlendFunc(GL_ONE, GL_ZERO); + + //draw center without texture lookups with single color + //DuiGLVec3 color2 = {0.5,0.5,0.5}; + //const DuiGLShaderProgram* prg2 = getProgram("Patched"); + //glDisableVertexAttribArray(1); + //prg2->use(); + //prg2->uniforms()["matWorld"] = d_ptr->m_matWorld; + //prg2->uniforms()["matProj"] = d_ptr->m_matProj; + //prg2->uniforms()["color"] = color2; + + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, &d_ptr->m_indices.data()[num-6]);*/ + + d_ptr->restoreGL(); +} + +void DuiGLRenderer::drawPixmap(const DuiGLShaderProgram *program, const QTransform &transform, + const QPixmap &pixmap, IDuiGLUniformProvider *provider) +{ + if (!d_ptr->m_glWidget) { + duiWarning("DuiGLRenderer") << "drawPixmap()" << "DuiGLRenderer not initialized yet."; + return; + } +// qDebug() << __FUNCTION__ << (quint32) QGLContext::currentContext(); + + GLuint tex = d_ptr->m_glWidget->bindTexture(pixmap, GL_TEXTURE_2D, GL_RGBA, QGLContext::PremultipliedAlphaBindOption); + drawTexture(program, transform, tex, pixmap.size(), provider); +} + +void DuiGLRenderer::drawPixmap(const QString &programId, const QTransform &transform, + const QPixmap &pixmap, IDuiGLUniformProvider *provider) +{ + if (!d_ptr->m_glWidget) { + duiWarning("DuiGLRenderer") << "drawPixmap()" << "DuiGLRenderer not initialized yet."; + return; + } +// qDebug() << __FUNCTION__ << (quint32) QGLContext::currentContext(); + + GLuint tex = d_ptr->m_glWidget->bindTexture(pixmap, GL_TEXTURE_2D, GL_RGBA, QGLContext::PremultipliedAlphaBindOption); + drawTexture(programId, transform, tex, pixmap.size(), provider); +} + +void DuiGLRenderer::drawParticles(const DuiParticle *particles, int numParticles, const QPixmap &pixmap, const QTransform &transform) +{ + if (!d_ptr->m_glWidget) { + duiWarning("DuiGLRenderer") << "renderParticles()" << "DuiGLRenderer not initialized yet."; + return; + } + + d_ptr->m_glWidget->makeCurrent(); + GLuint tex = d_ptr->m_glWidget->bindTexture(pixmap, GL_TEXTURE_2D, GL_RGBA, QGLContext::PremultipliedAlphaBindOption); + + glGetIntegerv(GL_CURRENT_PROGRAM, d_ptr->m_oldProgram); + const DuiGLShaderProgram *prg = getProgram("Particle"); + prg->use(); + + d_ptr->setupMatrices(transform); + d_ptr->setupTexturing(tex); + GLuint num = d_ptr->setupVertices(particles, numParticles); + + prg->uniform("texture0") = (GLuint)0; + prg->uniform("matWorld") = d_ptr->m_matWorld; + prg->uniform("matProj") = d_ptr->m_matProj; + + GLint srca; + GLint dsta; + glGetIntegerv(GL_BLEND_SRC_ALPHA, &srca); + glGetIntegerv(GL_BLEND_DST_ALPHA, &dsta); + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + + glDrawElements(GL_TRIANGLES, num, GL_UNSIGNED_SHORT, d_ptr->m_indices->data()); + + glBlendFunc(srca, dsta); + + d_ptr->restoreGL(); +} + +void DuiGLRenderer::setUniformProvider(IDuiGLUniformProvider *provider) +{ + d_ptr->m_uniformProvider = provider; +} + +QGLWidget *DuiGLRenderer::viewport() +{ + return d_ptr->m_glWidget; +} + +void DuiGLRenderer::setViewportSize(const QSize &size) +{ + *d_ptr->m_viewportSize = size; +} + +QPixmap DuiGLRenderer::composite(const DuiCompositionLayerList &layerList) +{ + if (!d_ptr->m_glWidget) { + duiWarning("DuiGLRenderer") << "composite()" << "DuiGLRenderer not initialized yet."; + return QPixmap(); + } +// qDebug() << __FUNCTION__ << (quint32) QGLContext::currentContext(); + + //resolve the destination pixmap size + QSize dstSize(0, 0); + const int layerListSize = layerList.size(); + for (int i = 0; i < layerListSize; i++) { + const QSize pmSize = layerList[i].pixmap().size(); + if (pmSize.width() > dstSize.width()) + dstSize.setWidth(pmSize.width()); + if (pmSize.height() > dstSize.height()) + dstSize.setHeight(pmSize.height()); + } + + d_ptr->m_glWidget->makeCurrent(); + + //QGLContext* ctx = (QGLContext*)d_ptr->m_glWidget->context(); + //ctx->makeCurrent(); + QGLFramebufferObject fbo(dstSize, QGLFramebufferObject::CombinedDepthStencil); + fbo.bind(); + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClear(GL_COLOR_BUFFER_BIT); + for (int i = 0; i < layerListSize; ++i) { + const DuiCompositionLayer::DuiCompositionMode mode = layerList[i].mode(); + if (mode == DuiCompositionLayer::Normal) { + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + } else if (mode == DuiCompositionLayer::Multiply) { + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + + setViewportSize(dstSize); + drawPixmap(QTransform(), layerList[i].pixmap(), layerList[i].opacity()); + } + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + fbo.release(); + return QPixmap::fromImage(fbo.toImage()); +} + +#else + +void DuiGLRenderer::initGL(DuiGLWidget *) +{ +} + +const DuiGLShader *DuiGLRenderer::createShader(const QString &, DuiShaderType) +{ + return NULL; +} + +const DuiGLShader *DuiGLRenderer::createShader(const QString &, const QString &, DuiShaderType) +{ + return NULL; +} + +const DuiGLShader *DuiGLRenderer::getShader(const QString &) +{ + return NULL; +} + +const DuiGLShaderProgram *DuiGLRenderer::createProgram(const QString &, const QList&) +{ + return NULL; +} + +const DuiGLShaderProgram *DuiGLRenderer::createProgram(const QString &, const QString &, const QString &) +{ + return NULL; +} + +const DuiGLShaderProgram *DuiGLRenderer::createProgramFromFiles(const QString &, const QString &, const QString &) +{ + return NULL; +} + +const DuiGLShaderProgram *DuiGLRenderer::getProgram(const QString &) +{ + return NULL; +} + +quint32 DuiGLRenderer::bindX11Pixmap(Qt::HANDLE) +{ + return 0; +} + +void DuiGLRenderer::unbindX11Pixmap(Qt::HANDLE) +{ +} + +void DuiGLRenderer::updateX11Pixmap(Qt::HANDLE) +{ +} + +void DuiGLRenderer::drawTexture(const QTransform &, quint32, const QSizeF &, qreal, bool) +{ +} + +void DuiGLRenderer::drawTexture(const DuiGLShaderProgram *, const QTransform &, quint32, + const QSizeF &, IDuiGLUniformProvider *, + bool) +{ +} + +void DuiGLRenderer::drawTexture(const QString &, const QTransform &, quint32, + const QSizeF &, IDuiGLUniformProvider *, + bool) +{ +} + +void DuiGLRenderer::drawPixmap(const QTransform &, const QPixmap &, qreal) +{ +} + +void DuiGLRenderer::drawPatchedPixmap(const QTransform &, const QPixmap &, qreal, + const QList&, const QList&) +{ +} + +void DuiGLRenderer::drawPixmap(const DuiGLShaderProgram *, const QTransform &, + const QPixmap &, IDuiGLUniformProvider *) +{ +} + +void DuiGLRenderer::drawPixmap(const QString &, const QTransform &, + const QPixmap &, IDuiGLUniformProvider *) +{ +} + +void DuiGLRenderer::setUniformProvider(IDuiGLUniformProvider *) +{ +} + +QGLWidget *DuiGLRenderer::viewport() +{ + return NULL; +} + +void DuiGLRenderer::setViewportSize(const QSize &) +{ +} + +QPixmap DuiGLRenderer::composite(const DuiCompositionLayerList &) +{ + return QPixmap(); +} + + + +#endif diff --git a/src/painting/duiglrenderer.h b/src/painting/duiglrenderer.h new file mode 100644 index 000000000..af3a73c34 --- /dev/null +++ b/src/painting/duiglrenderer.h @@ -0,0 +1,427 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIGLRENDERER_H +#define DUIGLRENDERER_H + +#include +#include +#include "duiexport.h" + +class QGLWidget; +class DuiGLWidget; +class DuiGLRendererPrivate; +class DuiGLShaderUniform; +class DuiGLShader; +class DuiGLShaderProgram; +class DuiParticle; +class QTransform; +class QSizeF; + +//some definitions to enable building without gles2 libraries +#ifdef QT_OPENGL_LIB +#include +#ifdef QT_OPENGL_ES_2 +#define DUI_USE_OPENGL +#endif +#endif + +class DuiCompositionLayer; +typedef QList DuiCompositionLayerList; + +/*! + * \class IDuiGLUniformProvider + * \brief Callback interface for setting uniform values for custom shaders. + */ +class DUI_EXPORT IDuiGLUniformProvider +{ +public: + virtual ~IDuiGLUniformProvider() {} + + /*! + * Initialize uniform \a name to wanted value. + * + * \param name Name of the uniform. + * \param uniform Uniform to be set. + * \return True if uniform was set by the method, false if uniform was not set + * by the method. + */ + virtual bool setUniformValue(const QString &name, const DuiGLShaderUniform &uniform) = 0; +}; + +/*! + * \class DuiGLRenderer + * \brief A singleton class for rendering textured quads with custom shaders. + * + * DuiGLRenderer class implements and provides an easy interface for + * compiling and setuping glsl shaders. The class also provides functionality + * for rendering textured quads directly with GLES2. Class caches the compiled + * shaders so that they can used inside a process without always recompiling + * them. Following uniforms and attributes are considered default and they are + * initialized by the DuiGLRenderer class automatically: + * + * \code + * //vertex shader variables + * attribute highp vec4 vertex; //object space vertex coordinate + * attribute lowp vec2 texCoord; //texture coordinates of the vertex + * uniform highp mat4 matProj; //projection matrix + * uniform highp mat4 matWorld; //world transformation matrix + * uniform highp vec2 invSize; //inversed size of rendered quad + * + * //fragment shader variables + * uniform sampler2D textureX; //textures for each texture unit (eg. texture0, texture1 ...) + * \endcode + * + * The DuiGLUniformProvider class can be used to automate setting of the custom + * uniforms found from the shaders. A user of the class can either set a global + * uniform provider callback by using the DuiGLRenderer::setUniformProvider() + * method or the user can give a separate provider interface for each draw call. User + * can also set the uniforms manually using the DuiGLShaderProgram class. The callback + * method will be called for each non-default uniform found from the used shader program. + * + * \deprecated Since 0.16 + */ +class DUI_EXPORT DuiGLRenderer +{ +public: + + //! Enumeration for supported shader types. + enum DuiShaderType { + DuiShaderVertex, + DuiShaderFragment, + //DuiShaderVertexBin, + //DuiShaderFragmentBin, + DuiShaderUndefined + }; + + /*! + * \brief Destructor. + */ + virtual ~DuiGLRenderer(); + + /*! + * Returns singleton DuiGLRenderer object + * + * \return DuiGLRenderer object + */ + static DuiGLRenderer *instance(); + + /*! + * Initialization method for the class. Method initializes few default + * shaders and other GL specific data needed for rendering. This should + * be called after the QGLWidget viewport has been created for the + * QGraphicsView. The class cannot be used without a valid QGLWidget + * object. + * + * \param glWidget Instance of QGLWidget that is needed to for executing GL commands. + */ + void initGL(DuiGLWidget *glWidget); + + /*! + * Returns a pointer to the currently used DuiGLWidget. + */ + DuiGLWidget *GLWidget() const; + + /*! + * Sets the \a glWidget as the currently used DuiGLWidget. + */ + void setGLWidget(DuiGLWidget *glWidget); + + /*! + * Create a shader from a file and push it into cache. + * + * \param filename Filename of the shader. This will be used as key as well. + * File can contain either precompiled shader binary or the ascii + * source of the shader. + * \param type Type of the shader, if the type is set to UndefinedShader the + * method will try to auto detect the type of the shader (frag or vert). + * \return Instance of the created shader, NULL if the creation fails. + */ + const DuiGLShader *createShader(const QString &filename, DuiShaderType type); + + /*! + * Compile a shader from a source and push it into cache. + * + * \param key Literal key for the shader. + * \param source Source code of the shader. + * \param type Type of the shader, if the type is set to UndefinedShader the + * method will try to auto detect the type of the shader (frag or vert). + * \return Instance of the created shader, NULL if the creation fails. + */ + const DuiGLShader *createShader(const QString &key, const QString &source, DuiShaderType type); + + /*! + * Get shader instance by key. + * + * \param key Literal key of the wanted shader. + * \return Instance of the shader, NULL if the shader does not exist. + */ + const DuiGLShader *getShader(const QString &key); + + /*! + * Create a shader program from a group of already compiled shaders. If + * the group of shaders does not include a vertex shader or fragment + * shader a default one is added. + * + * \param key Literal key for the created program. + * \param shaderKeyList List of shaders that will be linked into the + * program. If list contains a key that cannot be found from the + * shader cache it will be ignored. + * \return Instance of the program, NULL if the program creation fails. + */ + const DuiGLShaderProgram *createProgram(const QString &key, const QList& shaderKeyList); + + /*! + * Create a shader program from exactly one vertex shader and one + * fragment shader. + * + * \param key Literal key for the created program. + * \param vertShader Key of the vertex shader. By default the key is set to "" + * so that default vertex shader is used. + * \param fragShader Key of the fragment shader. + * \return Instance of the program, NULL if the program creation fails. + */ + const DuiGLShaderProgram *createProgram(const QString &key, const QString &vertShader, const QString &fragShader = QString()); + + /*! + * Create a shader program from a group of files. If the group of shaders + * does not include a vertex shader or fragment shader a default one is + * added. The shaders in the list are compiled and cached same way as if + * they are created with separate call to createShader() method. + * + * \param key Literal key for the created program. + * \param shaderFileList List of shaders files that will be compiled and + * linked into the program. If a list contains invalid shader + * (file doest not exist or shader compilation fails) it will be ignored. + * \return Instance of the program, NULL if the program creation fails. + */ + //DuiGLShaderProgram* createProgramFromFiles(const QString& key, const QList& shaderFileList); + + /*! + * Create a shader program from exactly one vertex shader and one + * fragment shader file. + * + * \param key Literal key for the created program. + * \param fragShaderFile Filename of the fragment shader. + * \param vertShaderFile Filename of the vertex shader. By default the filename is set to "" + * so that default vertex shader is used. + * \return Instance of the program, NULL if the program creation fails. + */ + const DuiGLShaderProgram *createProgramFromFiles(const QString &key, const QString &fragShaderFile, const QString &vertShaderFile = QString()); + + /*! + * Get program instance by key. + * + * \param key Literal key of the wanted program. + * \return Instance of the program, NULL if the program does not exist. + */ + const DuiGLShaderProgram *getProgram(const QString &key); + + /*! + * Bind an X pixmap as a texture. Uses the Nokia texture from pixmap + * extension to ensure that same pixmap in memory is used as a texture. + * Returns a texture id that can be drawn with drawTexture() or in later + * glBindTexture() calls. The texture that is generated is cached, + * so multiple calls to bindPixmap() with the same X pixmap will return + * the same texture id. Ideally, this function should be called once + * as soon as the pixmap id is obtained. Before drawing the contents + * of the texture, ensure updateX11Pixmap() is called to update its + * contents. + * + * \param pixmap specifies the X pixmap to be bound as a texture + */ + quint32 bindX11Pixmap(Qt::HANDLE pixmap); + + /*! + * Unbind the texture from an X pixmap. Deletes the texture cache as + * well. Call this to free the resources of the pixmap bound as a texture + * + * \param pixmap specifies the X pixmap to be bound as a texture + */ + void unbindX11Pixmap(Qt::HANDLE pixmap); + + /*! + * Updates the contents of bound X pixmap. Call this every time the + * contents of the pixmap changes i.e. from X Damage events + * + * \param pixmap specifies the X pixmap to be bound as a texture + */ + void updateX11Pixmap(Qt::HANDLE pixmap); + + /*! + * Draw textured quad using default shader. + * + * \param transform Transformation for the rendered quad. + * \param texId Id of the rendered texture. + * \param size Size of the rendered quad. + * \param opacity Transparency factor for the rendered quad. + * \param inverted Set to true if texture to be drawn is an inverted texture. False by default + */ + void drawTexture(const QTransform &transform, quint32 texId, const QSizeF &size, qreal opacity, + bool inverted = false); + + /*! + * Draw textured quad using a custom shader. + * + * \param program The used custom shader program. The program must have + * been set active prior to this method call. Also all the uniforms + * used by the program needs to be set before calling this method. + * \param transform Transformation for the rendered quad. + * \param texId Id of the rendered texture. + * \param size Size of the rendered quad. + * \param provider Callback interface for setting custom uniform values + * used by the shader program. + * \param inverted Set to true if texture to be drawn is an inverted texture. False by default + */ + void drawTexture(const DuiGLShaderProgram *program, const QTransform &transform, + quint32 texId, const QSizeF &size, IDuiGLUniformProvider *provider, + bool inverted = false); + + /*! + * Draw textured quad using a custom shader. + * + * \param programId Id of the used custom shader program. Method will + * fetch the precompiled program object from the cache and makes + * it active. + * \param transform Transformation for the rendered quad. + * \param texId Id of the rendered texture. + * \param size Size of the rendered quad. + * \param provider Callback interface for setting custom uniform values + * used by the shader program. + * \param inverted Set to true if texture to be drawn is an inverted texture. False by default + */ + void drawTexture(const QString &programId, const QTransform &transform, + quint32 texId, const QSizeF &size, IDuiGLUniformProvider *provider = NULL, + bool inverted = false); + + /*! + * Draw textured quad using default shader. + * + * \param transform Transformation for the rendered quad. + * \param pixmap Pixmap for the rendered quad. + * \param opacity Transparency factor for the rendered quad. + */ + void drawPixmap(const QTransform &transform, const QPixmap &pixmap, qreal opacity); + + + /*! + * \brief Draw several patches from a single pixmap to screen. + * + * \param transform Transformation for the patches. + * \param pixmap Source pixmap. + * \param opacity Transparency factor for the rendered patches. + * \param sourceRects List of source rectangles (pixmap). + * \param targetRects List of target rectangles (screen). + */ + void drawPatchedPixmap(const QTransform &transform, const QPixmap &pixmap, qreal opacity, + const QList& sourceRects, const QList& targetRects); + + /*! + * Draw textured quad using a custom shader. + * + * \param program The used custom shader program. The program must have + * been set active prior to this method call. Also all the uniforms + * used by the program needs to be set before calling this method. + * \param transform Transformation for the rendered quad. + * \param pixmap Pixmap for the rendered quad. + * \param provider Callback interface for setting custom uniform values + * used by the shader program. + */ + void drawPixmap(const DuiGLShaderProgram *program, const QTransform &transform, + const QPixmap &pixmap, IDuiGLUniformProvider *provider = NULL); + + /*! + * Draw textured quad using a custom shader. + * + * \param programId Id of the used custom shader program. Method will + * fetch the precompiled program object from the cache and makes + * it active. + * \param transform Transformation for the rendered quad. + * \param pixmap Pixmap for the rendered quad. + * \param provider Callback interface for setting custom uniform values + * used by the shader program. + */ + void drawPixmap(const QString &programId, const QTransform &transform, + const QPixmap &pixmap, IDuiGLUniformProvider *provider = NULL); + + /*! + * Draw particles. + * + * \param particles Array of particles. + * \param numParticles Particle count. + * \param pixmap Pixmap for the particles. + * \param transform Transformation for the particles. + */ + void drawParticles(const DuiParticle *particles, int numParticles, const QPixmap &pixmap, const QTransform &transform); + + /*! + * Set the global uniform provider interface. The global uniform provider + * will be always used unless another provider interface is given into + * the drawing methods. + * + * \param provider An interface for providing values for the non-default + * uniforms. + */ + void setUniformProvider(IDuiGLUniformProvider *provider); + + /*! + * Returns the viewport widget used for drawing. The widget is the same one + * that was previously set when initializing the renderer using the initGL() + * method. + * + * \return Viewport widget. + */ + QGLWidget *viewport(); + + /*! + * Set the viewport size. By default the viewport size is defined by the + * viewport widget (screen size), but for example when rendering into a + * texture using FBO the viewport size must be set manually to match the + * FBO size. After calling one of the rendering methods the viewport size + * is automatically reset to match the screen size. + * + * \param QSize Size of the viewport. + */ + void setViewportSize(const QSize &size); + + /*! + * Composite multiple pixmap layers into one pixmap. + * + * \param layerList List of the composited layers. + * \return Composited pixmap. + */ + QPixmap composite(const DuiCompositionLayerList &layerList); + +private: + + Q_DISABLE_COPY(DuiGLRenderer) + + /*! + * \brief Constructor. Initializes default shaders and data needed for rendering. + */ + DuiGLRenderer(); + + //! Pointer to private implementation class object. + DuiGLRendererPrivate *const d_ptr; + + Q_DECLARE_PRIVATE(DuiGLRenderer) +}; + +#endif + diff --git a/src/painting/duiglrenderer_p.h b/src/painting/duiglrenderer_p.h new file mode 100644 index 000000000..248dc9003 --- /dev/null +++ b/src/painting/duiglrenderer_p.h @@ -0,0 +1,98 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +// Make doxygen skip this internal class + +/* Internal classes for DuiGLRender*/ + +/*! + * \class DuiCompositionLayer + * \brief A class for defining a composition layer. +*/ +#ifndef DUIGLRENDERER_P_H +#define DUIGLRENDERER_P_H + +/* Internal implementation classes for DuiGLRenderer */ + +/*! + * \class DuiCompositionLayer + * \brief A class for defining a composition layer. +*/ +class DuiCompositionLayer +{ +public: + + //! Enumeration for supported composition modes + enum DuiCompositionMode { + Normal, + Multiply + }; + + /*! + * \brief Constructor. Initializes the class with wanted parameters. + */ + DuiCompositionLayer(const QPixmap &pixmap, float opacity, DuiCompositionMode mode) + : m_pixmap(pixmap), m_opacity(opacity), m_mode(mode) { + } + + /*! + * Returns pixmap associated with the layer. + * + * \return Layer pixmap. + */ + QPixmap pixmap() const { + return m_pixmap; + } + + /*! + * Returns opacity of the layer. + * + * \return Layer opacity. + */ + float opacity() const { + return m_opacity; + } + + /*! + * Returns composition mode of the layer. + * + * \return Layer composition mode. + */ + DuiCompositionMode mode() const { + return m_mode; + } + +private: + + /*! + * \brief Default constructor. + */ + DuiCompositionLayer(); + + //! Layer pixmap. + QPixmap m_pixmap; + + //! Opacity of the layer. + float m_opacity; + + //! Composition mode of the layer. + DuiCompositionMode m_mode; +}; + +#endif // DUIGLRENDERER_P_H diff --git a/src/painting/duiglshader.cpp b/src/painting/duiglshader.cpp new file mode 100644 index 000000000..715d70741 --- /dev/null +++ b/src/painting/duiglshader.cpp @@ -0,0 +1,164 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include + +#ifdef QT_OPENGL_LIB +#ifdef QT_OPENGL_ES_2 + +#include "duiglshader.h" +#include + + +class DuiGLShaderPrivate +{ +public: + DuiGLShaderPrivate() : shaderId(0), valid(false), ctx(0) {} + + GLuint shaderId; + QString source; + bool valid; + DuiGLShader::ShaderType type; + QGLContext *ctx; + QString name; +}; + + +DuiGLShader::DuiGLShader(DuiGLShader::ShaderType type, const QString &name, const QGLContext *ctx) + : d_ptr(new DuiGLShaderPrivate) +{ + qWarning("DuiGLShader is DEPRECATED. Use QGLShader instead."); + + Q_D(DuiGLShader); + + if (!ctx) + ctx = QGLContext::currentContext(); + + if (!ctx) { + qWarning("DuiGLShader being created without a context"); + return; + } + + d->ctx = const_cast(ctx); + d->ctx->makeCurrent(); + + if (type == DuiGLShader::FragmentShader) + d->shaderId = glCreateShader(GL_FRAGMENT_SHADER); + else + d->shaderId = glCreateShader(GL_VERTEX_SHADER); + + if (d->shaderId == 0) { + qWarning("Error creating shader object"); + return; + } + + d->type = type; + + d->name = name; +} + +quint32 DuiGLShader::id() const +{ + Q_D(const DuiGLShader); + return d->shaderId; +} + +DuiGLShader::ShaderType DuiGLShader::type() const +{ + Q_D(const DuiGLShader); + return d->type; +} + +QString DuiGLShader::name() const +{ + Q_D(const DuiGLShader); + + return d->name; +} + + +void DuiGLShader::clearSource() +{ + Q_D(DuiGLShader); + d->source.clear(); + d->valid = false; +} + +void DuiGLShader::addSource(const QString &newSource) +{ + Q_D(DuiGLShader); + d->source += newSource; + d->valid = false; +} + + +bool DuiGLShader::compile() +{ + Q_D(DuiGLShader); + + d->valid = false; + + if (d->source.size() == 0) + return false; + + const QByteArray src_ba = d->source.toAscii(); + const char *src = src_ba.constData(); + + glShaderSource(d->shaderId, 1, &src, 0); + + glCompileShader(d->shaderId); + + GLint shaderCompiled; + glGetShaderiv(d->shaderId, GL_COMPILE_STATUS, &shaderCompiled); + if (!shaderCompiled) + return false; + + d->valid = true; + return true; +} + +bool DuiGLShader::isValid() const +{ + Q_D(const DuiGLShader); + return d->valid; +} + +QString DuiGLShader::log() const +{ + Q_D(const DuiGLShader); + + char *logData; + GLint logSize; + GLint logLength; + + glGetShaderiv(d->shaderId, GL_INFO_LOG_LENGTH, &logSize); + + if (!logSize) + return QString(); + + logData = new char[logSize]; + glGetShaderInfoLog(d->shaderId, logSize, &logLength, logData); + QString result = QString::fromAscii(logData); + delete [] logData; + + return result; +} + +#endif +#endif diff --git a/src/painting/duiglshader.h b/src/painting/duiglshader.h new file mode 100644 index 000000000..cdd7fa11e --- /dev/null +++ b/src/painting/duiglshader.h @@ -0,0 +1,112 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIGLSHADER_H +#define DUIGLSHADER_H + +#include + +class DuiGLShaderPrivate; +class QGLContext; + +/*! + * \class DuiGLShader + * \brief Class for managing gl shaders. + * + * Class offers an interface for creating shaders. Binary shaders are not + * currently supported. + * + * \deprecated Since 0.16 + */ +class DuiGLShader : QObject +{ + Q_OBJECT + +public: + + //! Enumeration for shader type. + enum ShaderType {VertexShader, FragmentShader}; + + /*! + * \brief Constructor. + * \param type Type of the shader. + * \param name Name for the shader. + * \param ctx GL context. If NULL the currently active context is + * bound to this shader. + */ + DuiGLShader(ShaderType type, const QString &name, const QGLContext *ctx = 0); + + /*! + * Get the id of the shader. The id is used when linking shaders into programs. + * \return Id of the shader. + */ + quint32 id() const; + + /*! + * Get the type of the shader. + * \return Type of the shader; + */ + ShaderType type() const; + + /*! + * Clear all the code that has been added with addSource(): + */ + void clearSource(); + + /*! + * Add some source to shader. + * \param newSource Ascii source to be added. + */ + void addSource(const QString &newSource); + + /*! + * Compile the shader from source. + * \return True if the shader was compiled successfully, false if compiling fails. + */ + bool compile(); + + /* + * Get status of the shader. + * \return True if shader is valid and ready for linking, false if the + * shader is invalid (not compiled successfully or the source has + * changed after last compilation). + */ + bool isValid() const; + + /* + * Get link log. + * \return Link log. + */ + QString log() const; + + /* + * Get name of the shader. + * \return Name of the shader. + */ + QString name() const; + +private: + + //! Pointer to private implementation class object. + DuiGLShaderPrivate *const d_ptr; + + Q_DECLARE_PRIVATE(DuiGLShader) +}; + +#endif diff --git a/src/painting/duiglshaderprogram.cpp b/src/painting/duiglshaderprogram.cpp new file mode 100644 index 000000000..b8239b2f6 --- /dev/null +++ b/src/painting/duiglshaderprogram.cpp @@ -0,0 +1,299 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include + +#ifdef QT_OPENGL_LIB +#ifdef QT_OPENGL_ES_2 +#include "duiglshaderprogram.h" +#include "duiglshader.h" +#include "duiglshaderuniform.h" + +#include + + +class DuiGLShaderProgramPrivate +{ +public: + DuiGLShaderProgramPrivate() : valid(false), programId(0), ctx(0) {} + void populateVariableLists(); + DuiGLUniformType glUniformTypeToDuiUniformType(GLenum type); + + QVector shaders; + DuiGLUniformList uniforms; + bool valid; + GLuint programId; + QGLContext *ctx; +}; + + + +void DuiGLShaderProgramPrivate::populateVariableLists() +{ + uniforms.clear(); + + int count; + int sizeOfNameBuff; + char *name; + GLint nameLength; + GLenum type; + GLint size; + GLint location; + + glGetProgramiv(programId, GL_ACTIVE_UNIFORMS, &count); + glGetProgramiv(programId, GL_ACTIVE_UNIFORM_MAX_LENGTH, &sizeOfNameBuff); + + name = new char[sizeOfNameBuff]; + + for (int i = 0; i < count; ++i) { + nameLength = -1; + glGetActiveUniform(programId, i, sizeOfNameBuff, &nameLength, &size, &type, name); + if (nameLength == -1) + continue; + + location = glGetUniformLocation(programId, name); + uniforms.insert(QString::fromAscii(name), DuiGLShaderUniform(glUniformTypeToDuiUniformType(type), location)); + } + + delete[] name; +} + +DuiGLUniformType DuiGLShaderProgramPrivate::glUniformTypeToDuiUniformType(GLenum type) +{ + DuiGLUniformType duitype = DuiGLUniformInvalid; + switch (type) { + case GL_FLOAT: { + duitype = DuiGLUniformFloat; + } break; + case GL_FLOAT_VEC2: { + duitype = DuiGLUniformFloatVec2; + } break; + case GL_FLOAT_VEC3: { + duitype = DuiGLUniformFloatVec3; + } break; + case GL_FLOAT_VEC4: { + duitype = DuiGLUniformFloatVec4; + } break; + case GL_INT: { + duitype = DuiGLUniformInt; + } break; + case GL_INT_VEC2: { + duitype = DuiGLUniformIntVec2; + } break; + case GL_INT_VEC3: { + duitype = DuiGLUniformIntVec3; + } break; + case GL_INT_VEC4: { + duitype = DuiGLUniformIntVec4; + } break; + case GL_FLOAT_MAT2: { + duitype = DuiGLUniformMat2; + } break; + case GL_FLOAT_MAT3: { + duitype = DuiGLUniformMat3; + } break; + case GL_FLOAT_MAT4: { + duitype = DuiGLUniformMat4; + } break; + case GL_SAMPLER_2D: { + duitype = DuiGLUniformSampler2D; + } break; + + default: { + qWarning() << "DuiGLShaderProgramPrivate::glUniformTypeToDuiUniformType(): Unsupported uniform " << type; + } + } + + return duitype; +} + +DuiGLShaderProgram::DuiGLShaderProgram(const QGLContext *ctx) + : d_ptr(new DuiGLShaderProgramPrivate) +{ + //qWarning("DuiGLShaderProgram is DEPRECATED. Use QGLShaderProgram instead."); + + + Q_D(DuiGLShaderProgram); + if (!ctx) + ctx = QGLContext::currentContext(); + + if (!ctx) { + qWarning("DuiGLShaderProgram being created without a context"); + return; + } + + d->ctx = const_cast(ctx); + d->ctx->makeCurrent(); + + d->programId = glCreateProgram(); + + d->valid = false; +} + + +const DuiGLUniformList &DuiGLShaderProgram::uniforms() const +{ + Q_D(const DuiGLShaderProgram); + return const_cast(d->uniforms); +} + +const DuiGLShaderUniform &DuiGLShaderProgram::uniform(const QString &name) const +{ + Q_D(const DuiGLShaderProgram); + const DuiGLUniformList::const_iterator end = d->uniforms.constEnd(); + const DuiGLUniformList::const_iterator i = d->uniforms.constFind(name); + if (i != end) + return *i; + else { + qWarning("Unknown uniform \"%s\" Either the uniform doesn't exist or it was removed at shader link.", name.toStdString().c_str()); + const static DuiGLShaderUniform u; + return u; + } +} + + +bool DuiGLShaderProgram::addShader(const DuiGLShader *shader) +{ + Q_D(DuiGLShaderProgram); + if (!shader || !d->ctx) + return false; + + //if (newShader->context() != d->ctx) { + // qWarning("Shader object's context does not match program's context"); + // return false; + //} + + if (!shader->isValid()) + return false; + + QGLContext *ctx = d->ctx; + if (!ctx) + return false; + ctx->makeCurrent(); + + glAttachShader(d->programId, shader->id()); + + d->shaders.append(shader); + return true; +} + + +void DuiGLShaderProgram::removeShader(const DuiGLShader *shader) +{ + Q_D(DuiGLShaderProgram); + + int idx = d->shaders.indexOf(shader); + + if (idx == -1) + return; + + d->shaders.remove(idx); + + QGLContext *ctx = d->ctx; + if (!ctx) + return; + ctx->makeCurrent(); + + glDetachShader(d->programId, shader->id()); +} + + +bool DuiGLShaderProgram::removeAllShaders() +{ + Q_D(DuiGLShaderProgram); + + QGLContext *ctx = d->ctx; + if (!ctx) + return false; + ctx->makeCurrent(); + + foreach(const DuiGLShader * shader, d->shaders) { + glDetachShader(d->programId, shader->id()); + } + d->shaders.clear(); + return true; +} + +bool DuiGLShaderProgram::link() +{ + Q_D(DuiGLShaderProgram); + + QGLContext *ctx = d->ctx; + if (!ctx) + return false; + ctx->makeCurrent(); + + glLinkProgram(d->programId); + + + GLint linked; + glGetProgramiv(d->programId, GL_LINK_STATUS, &linked); + + if (!linked) + return false; + + d->populateVariableLists(); + + d->valid = true; + return true; +} + +void DuiGLShaderProgram::use() const +{ + qWarning("DuiGLShaderProgram is DEPRECATED. Use QGLShaderProgram instead."); + + Q_D(const DuiGLShaderProgram); + if (!d->valid) + return; + + glUseProgram(d->programId); +} + + +QString DuiGLShaderProgram::log() const +{ + Q_D(const DuiGLShaderProgram); + + QGLContext *ctx = d->ctx; + if (!ctx) + return QString(); + //ctx->makeCurrent(); + + GLint logSize = -666; + glGetProgramiv(d->programId, GL_INFO_LOG_LENGTH, &logSize); + + char *logData = new char[logSize]; + GLint logLength; + + glGetProgramInfoLog(d->programId, logSize, &logLength, logData); + + QString result = QString::fromAscii(logData); + delete [] logData; + + return result; +} + +quint32 DuiGLShaderProgram::id() const +{ + Q_D(const DuiGLShaderProgram); + return d->programId; +} + +#endif +#endif diff --git a/src/painting/duiglshaderprogram.h b/src/painting/duiglshaderprogram.h new file mode 100644 index 000000000..f40142e50 --- /dev/null +++ b/src/painting/duiglshaderprogram.h @@ -0,0 +1,132 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIGLSHADERPROGRAM_H +#define DUIGLSHADERPROGRAM_H + +#include +#include + +class QGLContext; +class DuiGLShader; +class DuiGLShaderUniform; +class DuiGLShaderProgramPrivate; + +//! Type definition for the uniform list. +typedef QMap DuiGLUniformList; + +/*! + * \class DuiGLShaderProgram + * \brief Class for managing gl shader programs. + * + * Class offers and interface for creating shader programs from vertex and + * fragment shaders. It also offers an interface for setting uniforms and + * activating the shader program. + * + * \deprecated Since 0.16 + */ +class DuiGLShaderProgram : QObject +{ + Q_OBJECT + +public: + + /*! + * \brief Constructor. + * \param ctx Pointer to the context where the program is bind to. If NULL, + * the program is bind to the currently active context. + */ + DuiGLShaderProgram(const QGLContext *ctx = 0); + + /*! + * Get uniform list. The program must be activated using the use() method + * before setting the uniforms. + * + * \return List of uniforms found from the program + */ + const DuiGLUniformList &uniforms() const; + + /*! + * Get single named uniform. The program must be activated using the use() method + * before setting the uniforms. + * + * \return Matching uniform, if the uniform does not exist an invalid uniform is returned. + */ + const DuiGLShaderUniform &uniform(const QString &name) const; + + /*! + * Add shader to program. Shader and program must be bound to same + * context otherwise the add fails. + * + * \param shader Shader object to be add. + * \return True if shader was added, false if add fails. + */ + bool addShader(const DuiGLShader *shader); + + /* + * Remove shader from program. + * \param shader Shader to be removed. + */ + void removeShader(const DuiGLShader *shader); + + /* + * Remove all shaders from program. + */ + bool removeAllShaders(); + + /* + * Link the program. + *\return True if the linking of the program succeeds, false if the linking fails. + */ + bool link(); + + /* + * Get link log. + * \return Link log. + */ + QString log() const; + + /* + * Get status of the program. + * \return True if program is valid and ready for activation, false if the + * program is invalid (not linked, link has failed.). + */ + bool isValid() const; + + /* + * Activate the program. Uniforms cannot be set before the program has been + * activated. The program must be linked before it can be activated. + */ + void use() const; + + /* + * Get the id of the program. + * \return id of the program. + */ + quint32 id() const; + +private: + + //! Pointer to private implementation class object. + DuiGLShaderProgramPrivate *const d_ptr; + + Q_DECLARE_PRIVATE(DuiGLShaderProgram) +}; + +#endif diff --git a/src/painting/duiglshaderuniform.cpp b/src/painting/duiglshaderuniform.cpp new file mode 100644 index 000000000..b48d9ed56 --- /dev/null +++ b/src/painting/duiglshaderuniform.cpp @@ -0,0 +1,319 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include "duiglshaderuniform.h" + +#ifdef QT_OPENGL_LIB +#ifdef QT_OPENGL_ES_2 +#define DUI_USE_OPENGL +#include +#endif +#endif + +#ifdef DUI_USE_OPENGL +class DuiGLShaderUniformPrivate +{ +public: + DuiGLShaderUniformPrivate() : m_id(0), m_type(DuiGLUniformInvalid) {} + + GLuint m_id; + DuiGLUniformType m_type; +}; + +DuiGLShaderUniform::DuiGLShaderUniform(DuiGLUniformType type, quint32 id) + : d_ptr(new DuiGLShaderUniformPrivate) +{ + //qWarning("DuiGLShaderUniform is DEPRECATED. Use QGLShaderProgram::setUniformValue() methods instead."); + + d_ptr->m_id = id; + d_ptr->m_type = type; +} + +DuiGLShaderUniform::DuiGLShaderUniform(const DuiGLShaderUniform &uniform) + : d_ptr(new DuiGLShaderUniformPrivate) +{ + //qWarning("DuiGLShaderUniform is DEPRECATED. Use QGLShaderProgram::setUniformValue() methods instead."); + + d_ptr->m_id = uniform.id(); + d_ptr->m_type = uniform.type(); +} + +DuiGLShaderUniform::DuiGLShaderUniform() + : d_ptr(new DuiGLShaderUniformPrivate) +{ + //qWarning("DuiGLShaderUniform is DEPRECATED. Use QGLShaderProgram::setUniformValue() methods instead."); + qWarning("Unknown uniform! Either the uniform doesn't exist or it was removed at shader link."); +} + +DuiGLShaderUniform::~DuiGLShaderUniform() +{ + if (d_ptr) + delete d_ptr; +} + +DuiGLUniformType DuiGLShaderUniform::type() const +{ + return d_ptr->m_type; +} + +quint32 DuiGLShaderUniform::id() const +{ + return d_ptr->m_id; +} + +const DuiGLShaderUniform &DuiGLShaderUniform::operator=(const GLfloat &rhs) const +{ + qWarning("DuiGLShaderUniform is DEPRECATED. Use QGLShaderProgram::setUniformValue() methods instead."); + if (d_ptr->m_type != DuiGLUniformFloat) + return *this; + + glUniform1f(d_ptr->m_id, rhs); + + return *this; +} + +const DuiGLShaderUniform &DuiGLShaderUniform::operator=(const DuiGLVec2 &rhs) const +{ + qWarning("DuiGLShaderUniform is DEPRECATED. Use QGLShaderProgram::setUniformValue() methods instead."); + if (d_ptr->m_type != DuiGLUniformFloatVec2) + return *this; + + glUniform2fv(d_ptr->m_id, 1, (const GLfloat *)&rhs); + + return *this; +} + +const DuiGLShaderUniform &DuiGLShaderUniform::operator=(const QSizeF &rhs) const +{ + qWarning("DuiGLShaderUniform is DEPRECATED. Use QGLShaderProgram::setUniformValue() methods instead."); + if (d_ptr->m_type != DuiGLUniformFloatVec2) + return *this; + + glUniform2f(d_ptr->m_id, rhs.width(), rhs.height()); + + return *this; +} + +const DuiGLShaderUniform &DuiGLShaderUniform::operator=(const QPointF &rhs) const +{ + qWarning("DuiGLShaderUniform is DEPRECATED. Use QGLShaderProgram::setUniformValue() methods instead."); + if (d_ptr->m_type != DuiGLUniformFloatVec2) + return *this; + + glUniform2f(d_ptr->m_id, rhs.x(), rhs.y()); + + return *this; +} + +const DuiGLShaderUniform &DuiGLShaderUniform::operator=(const DuiGLVec3 &rhs) const +{ + qWarning("DuiGLShaderUniform is DEPRECATED. Use QGLShaderProgram::setUniformValue() methods instead."); + if (d_ptr->m_type != DuiGLUniformFloatVec3) + return *this; + + glUniform3fv(d_ptr->m_id, 1, (const GLfloat *)&rhs); + + return *this; +} + +const DuiGLShaderUniform &DuiGLShaderUniform::operator=(const DuiGLVec4 &rhs) const +{ + qWarning("DuiGLShaderUniform is DEPRECATED. Use QGLShaderProgram::setUniformValue() methods instead."); + if (d_ptr->m_type != DuiGLUniformFloatVec4) + return *this; + + glUniform4fv(d_ptr->m_id, 1, (const GLfloat *)&rhs); + + return *this; +} + +const DuiGLShaderUniform &DuiGLShaderUniform::operator=(const QColor &rhs) const +{ + qWarning("DuiGLShaderUniform is DEPRECATED. Use QGLShaderProgram::setUniformValue() methods instead."); + if (d_ptr->m_type != DuiGLUniformFloatVec4) + return *this; + + glUniform4f(d_ptr->m_id, rhs.redF(), rhs.greenF(), rhs.blueF(), rhs.alphaF()); + + return *this; +} + +const DuiGLShaderUniform &DuiGLShaderUniform::operator=(const float rhs[2][2]) const +{ + qWarning("DuiGLShaderUniform is DEPRECATED. Use QGLShaderProgram::setUniformValue() methods instead."); + if (d_ptr->m_type != DuiGLUniformMat2) + return *this; + + glUniformMatrix2fv(d_ptr->m_id, 1, GL_FALSE, (GLfloat *)rhs); + + return *this; +} + +const DuiGLShaderUniform &DuiGLShaderUniform::operator=(const float rhs[3][3]) const +{ + qWarning("DuiGLShaderUniform is DEPRECATED. Use QGLShaderProgram::setUniformValue() methods instead."); + if (d_ptr->m_type != DuiGLUniformMat3) + return *this; + + glUniformMatrix3fv(d_ptr->m_id, 1, GL_FALSE, (GLfloat *)rhs); + + return *this; +} + +const DuiGLShaderUniform &DuiGLShaderUniform::operator=(const QTransform &rhs) const +{ + qWarning("DuiGLShaderUniform is DEPRECATED. Use QGLShaderProgram::setUniformValue() methods instead."); + if (d_ptr->m_type != DuiGLUniformMat3) + return *this; + + // Transposes ready for GL + GLfloat mat3[3][3] = { + {rhs.m11(), rhs.m12(), rhs.m13()}, + {rhs.m21(), rhs.m22(), rhs.m23()}, + {rhs.m31(), rhs.m32(), rhs.m33()} + }; + + glUniformMatrix3fv(d_ptr->m_id, 1, GL_FALSE, (GLfloat *)mat3); + + return *this; +} + +const DuiGLShaderUniform &DuiGLShaderUniform::operator=(const float rhs[4][4]) const +{ + qWarning("DuiGLShaderUniform is DEPRECATED. Use QGLShaderProgram::setUniformValue() methods instead."); + if (d_ptr->m_type != DuiGLUniformMat4) + return *this; + + glUniformMatrix4fv(d_ptr->m_id, 1, GL_FALSE, (GLfloat *)rhs); + + return *this; +} + +const DuiGLShaderUniform &DuiGLShaderUniform::operator=(const quint32 &rhs) const +{ + qWarning("DuiGLShaderUniform is DEPRECATED. Use QGLShaderProgram::setUniformValue() methods instead."); + if (d_ptr->m_type != DuiGLUniformSampler2D) + return *this; + + glUniform1i(d_ptr->m_id, rhs); + + return *this; +} + +const DuiGLShaderUniform &DuiGLShaderUniform::operator=(const DuiGLShaderUniform &uniform) +{ + d_ptr->m_id = uniform.id(); + d_ptr->m_type = uniform.type(); + return *this; +} + +#else + +DuiGLShaderUniform::DuiGLShaderUniform(DuiGLUniformType, quint32) + : d_ptr(NULL) +{ +} + +DuiGLShaderUniform::DuiGLShaderUniform() + : d_ptr(NULL) +{ +} + +DuiGLShaderUniform::~DuiGLShaderUniform() +{ +} + +DuiGLUniformType DuiGLShaderUniform::type() const +{ + return DuiGLUniformInvalid; +} + +quint32 DuiGLShaderUniform::id() const +{ + return 0; +} + +const DuiGLShaderUniform &DuiGLShaderUniform::operator=(const float &) const +{ + return *this; +} + +const DuiGLShaderUniform &DuiGLShaderUniform::operator=(const DuiGLVec2 &) const +{ + return *this; +} + +const DuiGLShaderUniform &DuiGLShaderUniform::operator=(const QSizeF &) const +{ + return *this; +} + +const DuiGLShaderUniform &DuiGLShaderUniform::operator=(const QPointF &) const +{ + return *this; +} + +const DuiGLShaderUniform &DuiGLShaderUniform::operator=(const DuiGLVec3 &) const +{ + return *this; +} + +const DuiGLShaderUniform &DuiGLShaderUniform::operator=(const DuiGLVec4 &) const +{ + return *this; +} + +const DuiGLShaderUniform &DuiGLShaderUniform::operator=(const QColor &) const +{ + return *this; +} + +const DuiGLShaderUniform &DuiGLShaderUniform::operator=(const float[2][2]) const +{ + return *this; +} + +const DuiGLShaderUniform &DuiGLShaderUniform::operator=(const float[3][3]) const +{ + return *this; +} + +const DuiGLShaderUniform &DuiGLShaderUniform::operator=(const QTransform &) const +{ + return *this; +} + +const DuiGLShaderUniform &DuiGLShaderUniform::operator=(const float[4][4]) const +{ + return *this; +} + +const DuiGLShaderUniform &DuiGLShaderUniform::operator=(const quint32 &) const +{ + return *this; +} + +const DuiGLShaderUniform &DuiGLShaderUniform::operator=(const DuiGLShaderUniform &) +{ + return *this; +} + + +#endif diff --git a/src/painting/duiglshaderuniform.h b/src/painting/duiglshaderuniform.h new file mode 100644 index 000000000..b4afd835b --- /dev/null +++ b/src/painting/duiglshaderuniform.h @@ -0,0 +1,178 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIGLSHADERUNIFORM_H +#define DUIGLSHADERUNIFORM_H + +#include +#include "duiexport.h" + +class QSizeF; +class QPointF; +class QTransform; +class QColor; +class DuiGLShaderUniformPrivate; + +//! Structure for vec2. +typedef struct { + float x; + float y; +} DuiGLVec2; + +//! Structure for vec3. +typedef struct { + float x; + float y; + float z; +} DuiGLVec3; + +//! Structure for vec4. +typedef struct { + float x; + float y; + float z; + float w; +} DuiGLVec4; + +//! Enumeration for the supported uniform types. +enum DuiGLUniformType { + DuiGLUniformInvalid, //! Invalid type + DuiGLUniformFloat, + DuiGLUniformFloatVec2, + DuiGLUniformFloatVec3, + DuiGLUniformFloatVec4, + DuiGLUniformInt, + DuiGLUniformIntVec2, + DuiGLUniformIntVec3, + DuiGLUniformIntVec4, + DuiGLUniformMat2, + DuiGLUniformMat3, + DuiGLUniformMat4, + DuiGLUniformSampler2D +}; + + +/*! + * \class DuiGLShaderUniform + * \brief Class for defining shader uniforms. + * + * Class offers and interface for defining and setting shader uniforms. + */ +class DUI_EXPORT DuiGLShaderUniform +{ + +public: + + /*! + * \brief Constructor. + * \param type Type for the uniform. + * \param id GL position id of the uniform. + */ + DuiGLShaderUniform(DuiGLUniformType type, quint32 id); + + /*! + * \brief Copy constructor. Used by QMap. + */ + DuiGLShaderUniform(const DuiGLShaderUniform &); + + + /*! + * \brief Default constructor. + */ + DuiGLShaderUniform(); + + /*! + * \brief Destructor. + */ + virtual ~DuiGLShaderUniform(); + + /*! + * Get the type of the uniform. + * \return Type of the uniform. + */ + DuiGLUniformType type() const; + + /*! + * Get the id of the uniform. + * \return Id of the uniform. + */ + quint32 id() const; + + /*! + * Overloaded assignment operator for float. + */ + const DuiGLShaderUniform &operator=(const float &) const; + /*! + * Overloaded assignment operator for DuiGLVec2. + */ + const DuiGLShaderUniform &operator=(const DuiGLVec2 &) const; + /*! + * Overloaded assignment operator for QSizeF. + */ + const DuiGLShaderUniform &operator=(const QSizeF &) const; + /*! + * Overloaded assignment operator for QPointF. + */ + const DuiGLShaderUniform &operator=(const QPointF &) const; + /*! + * Overloaded assignment operator for DuiGLVec3. + */ + const DuiGLShaderUniform &operator=(const DuiGLVec3 &) const; + /*! + * Overloaded assignment operator for DuiGLVec4. + */ + const DuiGLShaderUniform &operator=(const DuiGLVec4 &) const; + /*! + * Overloaded assignment operator for QColor. + */ + const DuiGLShaderUniform &operator=(const QColor &) const; + /*! + * Overloaded assignment operator for float[2][2]. + */ + const DuiGLShaderUniform &operator=(const float[2][2]) const; + /*! + * Overloaded assignment operator for float[3][3]. + */ + const DuiGLShaderUniform &operator=(const float[3][3]) const; + /*! + * Overloaded assignment operator for QTransform. + */ + const DuiGLShaderUniform &operator=(const QTransform &) const; + /*! + * Overloaded assignment operator for float[4][4]. + */ + const DuiGLShaderUniform &operator=(const float[4][4]) const; + /*! + * Overloaded assignment operator for quint32. + */ + const DuiGLShaderUniform &operator=(const quint32 &) const; + /*! + * Overloaded copy assigment operator. This used by QMap. + */ + const DuiGLShaderUniform &operator=(const DuiGLShaderUniform &); + +private: + + //! Pointer to private implementation class object. + DuiGLShaderUniformPrivate *const d_ptr; + Q_DECLARE_PRIVATE(DuiGLShaderUniform) + //Q_DISABLE_COPY(DuiGLShaderUniform) +}; + +#endif diff --git a/src/painting/duiglwidget.cpp b/src/painting/duiglwidget.cpp new file mode 100644 index 000000000..916072341 --- /dev/null +++ b/src/painting/duiglwidget.cpp @@ -0,0 +1,328 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiglwidget.h" + +#ifdef DUI_USE_OPENGL +#include "duiglshader.h" +#include "duiglshaderprogram.h" +#include + +class DuiGLWidgetPrivate +{ +public: + DuiGLWidgetPrivate(); + ~DuiGLWidgetPrivate(); + + GLfloat **m_matProj; + GLfloat **m_matWorld; + GLfloat *m_pixmapVertices; + GLfloat *m_pixmapTexCoords; + GLfloat *m_pixmapTexCoordsInv; + + void *m_oldVert; + void *m_oldCoord; + void *m_oldColor; + GLint m_oldProgram; + GLboolean m_oldDepthTest; + GLboolean m_oldBlend; + + QVector m_vertices; + QVector m_texCoords; + QVector m_color; + QVector m_indices; + + ShaderCache m_shaderCache; + ProgramCache m_programCache; + PixmapHash m_boundPixmaps; + + DuiGLShaderProgram *m_defaultProgram; + IDuiGLUniformProvider *m_uniformProvider; + + QSize m_viewportSize; + +protected: + DuiGLWidget *q_ptr; + +private: + Q_DECLARE_PUBLIC(DuiGLWidget) +}; + +DuiGLWidgetPrivate::DuiGLWidgetPrivate() : + m_uniformProvider(0) +{ + m_matProj = new GLfloat*[4]; + m_matWorld = new GLfloat*[4]; + for (int i = 0; i < 4; ++i) { + m_matProj[i] = new GLfloat[4]; + m_matWorld[i] = new GLfloat[4]; + } + m_pixmapVertices = new GLfloat[8]; + m_pixmapTexCoords = new GLfloat[8]; + m_pixmapTexCoordsInv = new GLfloat[8]; + + //init world matrix for the known parts + //parts that are changeable by the transformation + //are set when rendering in the setupGL() method + m_matWorld[0][2] = 0.0; + m_matWorld[1][2] = 0.0; + m_matWorld[2][0] = 0.0; + m_matWorld[2][1] = 0.0; + m_matWorld[2][2] = 1.0; + m_matWorld[2][3] = 0.0; + m_matWorld[3][2] = 0.0; + + //init constant vertex values + //other parts of the array are initialized when rendering + m_pixmapVertices[0] = 0.0; + m_pixmapVertices[1] = 0.0; + m_pixmapVertices[2] = 0.0; + m_pixmapVertices[7] = 0.0; + + //init texcoords for common pixmap rendering + m_pixmapTexCoords[0] = 0.0f; m_pixmapTexCoords[1] = 1.0f; + m_pixmapTexCoords[2] = 0.0f; m_pixmapTexCoords[3] = 0.0f; + m_pixmapTexCoords[4] = 1.0f; m_pixmapTexCoords[5] = 0.0f; + m_pixmapTexCoords[6] = 1.0f; m_pixmapTexCoords[7] = 1.0f; + + /* Compensate for inverted textures + + Rendering done by the window system may be y-inverted compared + to the standard OpenGL texture representation. More specifically: + the X Window system uses a coordinate system where the origin is in + the upper left; however, the GL uses a coordinate system where the + origin is in the lower left. + */ + m_pixmapTexCoordsInv[0] = 0.0f; m_pixmapTexCoordsInv[1] = 0.0f; + m_pixmapTexCoordsInv[2] = 0.0f; m_pixmapTexCoordsInv[3] = 1.0f; + m_pixmapTexCoordsInv[4] = 1.0f; m_pixmapTexCoordsInv[5] = 1.0f; + m_pixmapTexCoordsInv[6] = 1.0f; m_pixmapTexCoordsInv[7] = 0.0f; + + //init index, vertex and texcoord arrays by default with the number + //of elements needed for rendering scalableimage, particle rendering also + //uses these and it will resize the array on fly if needed + m_indices.resize(9 * 6); + GLushort *indices = m_indices.data(); + for (GLuint i = 0; i < 9; i++) { + indices[i*6+0] = i * 4 + 0; //x1 y1 TL + indices[i*6+1] = i * 4 + 1; //x1 y2 BL + indices[i*6+2] = i * 4 + 2; //x2 y2 BR + indices[i*6+3] = i * 4 + 0; //x1 y1 TL + indices[i*6+4] = i * 4 + 2; //x2 y2 BR + indices[i*6+5] = i * 4 + 3; //x2 y1 TR + } + m_vertices.resize(9 * 4 * 2); + m_texCoords.resize(9 * 4 * 2); + +} + +DuiGLWidgetPrivate::~DuiGLWidgetPrivate() +{ + for (int i = 0; i < 4; ++i) { + delete[] m_matProj[i]; + delete[] m_matWorld[i]; + } + delete[] m_matProj; + delete[] m_matWorld; + delete[] m_pixmapVertices; + delete[] m_pixmapTexCoords; + delete[] m_pixmapTexCoordsInv; + + ShaderCache::iterator shaderCacheEnd = m_shaderCache.end(); + for (ShaderCache::iterator i = m_shaderCache.begin(); i != shaderCacheEnd; ++i) { + delete *i; + } + + ProgramCache::iterator programCacheEnd = m_programCache.end(); + for (ProgramCache::iterator i = m_programCache.begin(); i != programCacheEnd; ++i) { + delete *i; + } +} + + +DuiGLWidget::DuiGLWidget(const QGLFormat &format, QWidget *parent, + const QGLWidget *shareWidget, Qt::WindowFlags f) : + QGLWidget(format, parent, shareWidget, f), + d_ptr(new DuiGLWidgetPrivate) +{ + qWarning("DuiGLWidget is DEPRECATED."); + + Q_D(DuiGLWidget); + + d->q_ptr = this; +} + +DuiGLWidget::~DuiGLWidget() +{ + delete d_ptr; +} + +ShaderCache *DuiGLWidget::shaderCache() +{ + Q_D(DuiGLWidget); + + return &d->m_shaderCache; +} + +ProgramCache *DuiGLWidget::programCache() +{ + Q_D(DuiGLWidget); + + return &d->m_programCache; +} + +PixmapHash *DuiGLWidget::boundPixmaps() +{ + Q_D(DuiGLWidget); + + return &d->m_boundPixmaps; +} + +DuiGLShaderProgram *DuiGLWidget::defaultProgram() +{ + Q_D(DuiGLWidget); + + return d->m_defaultProgram; +} + +QVector* DuiGLWidget::vertices() +{ + Q_D(DuiGLWidget); + + return &d->m_vertices; +} + +QVector* DuiGLWidget:: texCoords() +{ + Q_D(DuiGLWidget); + + return &d->m_texCoords; +} + +QVector* DuiGLWidget::color() +{ + Q_D(DuiGLWidget); + + return &d->m_color; +} + +QVector* DuiGLWidget::indices() +{ + Q_D(DuiGLWidget); + + return &d->m_indices; +} + +GLfloat **DuiGLWidget::matProj() +{ + Q_D(DuiGLWidget); + + return d->m_matProj; +} + +GLfloat **DuiGLWidget::matWorld() +{ + Q_D(DuiGLWidget); + + return d->m_matWorld; +} + +GLfloat *DuiGLWidget::pixmapVertices() +{ + Q_D(DuiGLWidget); + + return d->m_pixmapVertices; +} + +GLfloat *DuiGLWidget::pixmapTexCoords() +{ + Q_D(DuiGLWidget); + + return d->m_pixmapTexCoords; +} + +GLfloat *DuiGLWidget::pixmapTexCoordsInv() +{ + Q_D(DuiGLWidget); + + return d->m_pixmapTexCoordsInv; +} + +void *DuiGLWidget::oldVert() +{ + Q_D(DuiGLWidget); + + return d->m_oldVert; +} + +void *DuiGLWidget::oldCoord() +{ + Q_D(DuiGLWidget); + + return d->m_oldCoord; +} + +void *DuiGLWidget::oldColor() +{ + Q_D(DuiGLWidget); + + return d->m_oldColor; +} + +GLint *DuiGLWidget::oldProgram() +{ + Q_D(DuiGLWidget); + + return &d->m_oldProgram; +} + +GLboolean *DuiGLWidget::oldDepthTest() +{ + Q_D(DuiGLWidget); + + return &d->m_oldDepthTest; +} + +GLboolean *DuiGLWidget::oldBlend() +{ + Q_D(DuiGLWidget); + + return &d->m_oldBlend; +} + +IDuiGLUniformProvider *DuiGLWidget::uniformProvider() +{ + Q_D(DuiGLWidget); + + return d->m_uniformProvider; +} + +QSize *DuiGLWidget::viewportSize() +{ + Q_D(DuiGLWidget); + + return &d->m_viewportSize; +} +#else +DuiGLWidget::DuiGLWidget(const QGLFormat &format, QWidget *parent, + const QGLWidget *shareWidget, Qt::WindowFlags f) : + QGLWidget(format, parent, shareWidget, f) +{ +} +#endif diff --git a/src/painting/duiglwidget.h b/src/painting/duiglwidget.h new file mode 100644 index 000000000..75ca5ffb4 --- /dev/null +++ b/src/painting/duiglwidget.h @@ -0,0 +1,103 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIGLWIDGET_H +#define DUIGLWIDGET_H + +#include +#include "duiglrenderer.h" + +class QGLFormat; + +#ifdef DUI_USE_OPENGL +# include +# include + +class DuiGLWidgetPrivate; +class DuiGLShader; +class DuiGLShaderProgram; +class IDuiGLUniformProvider; + +struct TexturePixmap { + TexturePixmap(): eglpixmap(0), texture(0) {} + EGLSurface eglpixmap; + quint32 texture; +}; + +typedef QHash ShaderCache; +typedef QHash ProgramCache; +typedef QHash PixmapHash; +#endif // DUI_USE_OPENGL + +/* + * This class represents the painting surface of DuiWindow used by + * DuiGLRenderer. Apart from QGLWidget, it caches shaders, matrices, + * pixmaps, vertices and other data generated in DuiGLRenderer::initGL() + * method. When switching between painting, the cached data is loaded + * to DuiGLRenderer so it doesn't have to recreate it. + * + * \sa DuiGLRenderer + * + * \deprecated since 0.16 + */ +class DUI_EXPORT DuiGLWidget : public QGLWidget +{ +public: + DuiGLWidget(const QGLFormat &format, QWidget *parent = 0, + const QGLWidget *shareWidget = 0, Qt::WindowFlags f = 0); +#ifdef DUI_USE_OPENGL + ~DuiGLWidget(); + + ShaderCache *shaderCache(); + ProgramCache *programCache(); + PixmapHash *boundPixmaps(); + + DuiGLShaderProgram *defaultProgram(); + + QVector* vertices(); + QVector* texCoords(); + QVector* color(); + QVector* indices(); + + GLfloat **matProj(); + GLfloat **matWorld(); + GLfloat *pixmapVertices(); + GLfloat *pixmapTexCoords(); + GLfloat *pixmapTexCoordsInv(); + + void *oldVert(); + void *oldCoord(); + void *oldColor(); + GLint *oldProgram(); + GLboolean *oldDepthTest(); + GLboolean *oldBlend(); + + IDuiGLUniformProvider *uniformProvider(); + + QSize *viewportSize(); +protected: + DuiGLWidgetPrivate *const d_ptr; + +private: + Q_DISABLE_COPY(DuiGLWidget) + Q_DECLARE_PRIVATE(DuiGLWidget) +#endif // DUI_USE_OPENGL +}; + +#endif // DUIGLWIDGET_H diff --git a/src/painting/duiscalableimage.cpp b/src/painting/duiscalableimage.cpp new file mode 100644 index 000000000..25968062c --- /dev/null +++ b/src/painting/duiscalableimage.cpp @@ -0,0 +1,375 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiscalableimage.h" +#include "duiscalableimage_p.h" +#include "duigles2renderer.h" + +#include + +#include +#include + + +DuiScalableImagePrivate::DuiScalableImagePrivate() + : m_imageType(DuiScalable9), m_imageSize(-1, -1), m_image(NULL), + m_useGLRenderer(false), m_left(0), m_right(0), m_top(0), m_bottom(0) +{ +} + +DuiScalableImagePrivate::~DuiScalableImagePrivate() +{ + m_imageBlocks.clear(); + m_imageRects.clear(); +} + +void DuiScalableImagePrivate::validateSize(int &w, int &h) const +{ + if (w == -1) + w = m_image->width(); + if (h == -1) + h = m_image->height(); + + int cornerWidth = 0; + int cornerHeight = 0; + if (m_imageType == DuiScalable9) { + cornerWidth = m_imageRects[0].size().width() + m_imageRects[1].size().width(); + cornerHeight = m_imageRects[0].size().height() + m_imageRects[2].size().height(); + } + + if (w < cornerWidth) { + duiWarning("DuiScalableImage") << "Width of" << pixmapId << " image" << w << "is smaller than combined corner width " << cornerWidth << ". This might cause rendering artifacts."; + } + if (h < cornerHeight) { + duiWarning("DuiScalableImage") << "Height of " << pixmapId << " image" << h << "is smaller than combined corner height" << cornerHeight << ". This might cause rendering artifacts."; + } +} + +void DuiScalableImagePrivate::drawScalable9(int x, int y, int w, int h, QPainter *painter) const +{ + //make sure that the size is of the drawn image is + //bigger or equal as the 4 corner blocks + validateSize(w, h); + + //the image is used in it's native size + //no need to scale just draw it + if (m_image->size() == QSize(w, h)) { + painter->drawPixmap(x, y, *m_image); + } + //the image needs some scaling + else { + //calculate some common values + int cornerWidth = m_imageRects[0].size().width() + m_imageRects[1].size().width(); + int cornerHeight = m_imageRects[0].size().height() + m_imageRects[2].size().height(); + + int edgeWidth = w - cornerWidth; + int edgeHeight = h - cornerHeight; + int rightX = x + m_imageRects[0].size().width() + edgeWidth; + int bottomY = y + m_imageRects[0].size().height() + edgeHeight; + int horEdgeX = x + m_imageRects[0].size().width(); + int verEdgeY = y + m_imageRects[0].size().height(); + +#ifdef DUI_USE_OPENGL +#if QT_VERSION >= 0x040600 + if (m_useGLRenderer && painter->paintEngine()->type() == QPaintEngine::OpenGL2) { +#else + if (m_useGLRenderer && painter->paintEngine()->type() == QPaintEngine::OpenGL) { +#endif + QList targetRects; + + targetRects.append(QRect(QPoint(x, y), m_imageRects[0].size())); + targetRects.append(QRect(QPoint(rightX, y), m_imageRects[1].size())); + targetRects.append(QRect(QPoint(x, bottomY), m_imageRects[2].size())); + targetRects.append(QRect(QPoint(rightX, bottomY), m_imageRects[3].size())); + + targetRects.append(QRect(horEdgeX, y, edgeWidth, m_imageRects[0].size().height())); + targetRects.append(QRect(x, verEdgeY, m_imageRects[0].size().width(), edgeHeight)); + targetRects.append(QRect(horEdgeX, bottomY, edgeWidth, m_imageRects[2].size().height())); + targetRects.append(QRect(rightX, verEdgeY, m_imageRects[1].size().width(), edgeHeight)); + + targetRects.append(QRect(x + m_imageRects[0].size().width(), y + m_imageRects[0].size().height(), edgeWidth, edgeHeight)); + + DuiGLES2Renderer *r = DuiGLES2Renderer::instance(); + r->begin(painter); + r->bindTexture(*m_image); + r->draw(targetRects, m_imageRects); + r->end(); + } else { +#else + { +#endif + //draw corners + //tl + if (m_imageRects[0].width() && m_imageRects[0].height()) + painter->drawPixmap(QPoint(x, y), *m_image, m_imageRects[0]); + //tr + if (m_imageRects[1].width() && m_imageRects[1].height()) + painter->drawPixmap(QPoint(rightX, y), *m_image, m_imageRects[1]); + //bl + if (m_imageRects[2].width() && m_imageRects[2].height()) + painter->drawPixmap(QPoint(x, bottomY), *m_image, m_imageRects[2]); + //br + if (m_imageRects[3].width() && m_imageRects[3].height()) + painter->drawPixmap(QPoint(rightX, bottomY), *m_image, m_imageRects[3]); + + //draw edges + //top + if (m_imageRects[4].width() && m_imageRects[4].height()) + painter->drawPixmap(QRect(horEdgeX, y, edgeWidth, m_imageRects[0].size().height()), *m_image, m_imageRects[4]); + //left + if (m_imageRects[5].width() && m_imageRects[5].height()) + painter->drawPixmap(QRect(x, verEdgeY, m_imageRects[0].size().width(), edgeHeight), *m_image, m_imageRects[5]); + //bottom + if (m_imageRects[6].width() && m_imageRects[6].height()) + painter->drawPixmap(QRect(horEdgeX, bottomY, edgeWidth, m_imageRects[2].size().height()), *m_image, m_imageRects[6]); + //right + if (m_imageRects[7].width() && m_imageRects[7].height()) + painter->drawPixmap(QRect(rightX, verEdgeY, m_imageRects[1].size().width(), edgeHeight), *m_image, m_imageRects[7]); + + //TODO: Future optimizations, uncomment these when the graphics are updated + // to support solid center patch. + //draw center + //painter->setCompositionMode(QPainter::CompositionMode_Source); + if (m_imageRects[8].width() && m_imageRects[8].height()) { + painter->drawPixmap(QRect(x + m_imageRects[0].size().width(), y + m_imageRects[0].size().height(), edgeWidth, edgeHeight), *m_image, m_imageRects[8]); + //painter->fillRect(QRect(x+m_imageRects[0].size().width(),y+m_imageRects[0].size().height(), edgeWidth, edgeHeight), QColor(0, 255, 0)); + } + //painter->setCompositionMode(QPainter::CompositionMode_SourceOver); + } + } +} + +void DuiScalableImagePrivate::drawScalable1(int x, int y, int w, int h, QPainter *painter) const +{ + painter->drawPixmap(QRect(x, y, w, h), *m_image, m_image->rect()); +} + +/*void DuiScalableImagePrivate::drawScalable3H(int x, int y, int w, int h, QPainter* painter) const +{ +} + +void DuiScalableImagePrivate::drawScalable3V(int x, int y, int w, int h, QPainter* painter) const +{ +}*/ + +/* + 0 4 1 + *-----* + |xxxxx| + 5 |xx8xx| 7 + |xxxxx| + *-----* + 2 6 3 + + 0 2 1 + |xxxxx| + |xxxxx| + |xxxxx| + + 0 ----- + XXXXX + 1 XXXXX + XXXXX + 2 ----- +*/ +void DuiScalableImagePrivate::calcImageRects() const +{ + if (!m_image) + return; + + if (m_imageType == DuiScalableImagePrivate::DuiScalable9) { + m_imageSize = m_image->size(); + if (m_imageSize.width() < m_left + m_right) { + duiWarning("DuiScalableImagePrivate") << "DuiScalableImage - " << pixmapId << " : Width of horizontal borders" + << m_left + m_right << "is bigger than the width of the whole image" + << m_imageSize.width(); + } + if (m_imageSize.height() < m_top + m_bottom) { + duiWarning("DuiScalableImagePrivate") << "DuiScalableImage - " << pixmapId << " : Height of vertical borders" + << m_top + m_bottom << "is bigger than the height of the whole image" + << m_imageSize.height(); + } + + //corner sizes + QSize szTl(m_left, m_top); + QSize szTr(m_right, m_top); + QSize szBl(m_left, m_bottom); + QSize szBr(m_right, m_bottom); + + //edge widths + int h = m_imageSize.height() - m_top - m_bottom; + int w = m_imageSize.width() - m_left - m_right; + + //bottom and right edge positions + int b = m_imageSize.height() - m_bottom; + int r = m_imageSize.width() - m_right; + + //edge and center block sizes + QSize szL(m_left, h); + QSize szR(m_right, h); + QSize szT(w, m_top); + QSize szB(w, m_bottom); + QSize szC(w, h); + + //insert the block rects into array + m_imageRects.clear(); + m_imageRects.append(QRect(QPoint(0, 0), szTl)); + m_imageRects.append(QRect(QPoint(r, 0), szTr)); + m_imageRects.append(QRect(QPoint(0, b), szBl)); + m_imageRects.append(QRect(QPoint(r, b), szBr)); + m_imageRects.append(QRect(QPoint(m_left, 0), szT)); + m_imageRects.append(QRect(QPoint(0, m_top), szL)); + m_imageRects.append(QRect(QPoint(m_left, b), szB)); + m_imageRects.append(QRect(QPoint(r, m_top), szR)); + m_imageRects.append(QRect(QPoint(m_left, m_top), szC)); + } +} + + +DuiScalableImage::DuiScalableImage() + : d_ptr(new DuiScalableImagePrivate()) +{ + Q_D(DuiScalableImage); + d->q_ptr = this; +} + +DuiScalableImage::DuiScalableImage(const QPixmap *pixmap, int left, int right, int top, int bottom, const QString &pixmapId) + : d_ptr(new DuiScalableImagePrivate()) +{ + Q_D(DuiScalableImage); + d->q_ptr = this; + + setBorders(left, right, top, bottom); + setPixmap(pixmap); + d->pixmapId = pixmapId; +} + +DuiScalableImage::DuiScalableImage(DuiScalableImagePrivate *dd) + : d_ptr(dd) +{ + Q_D(DuiScalableImage); + d->q_ptr = this; +} + +DuiScalableImage::~DuiScalableImage() +{ + delete d_ptr; +} + +void DuiScalableImage::borders(int *left, int *right, int *top, int *bottom) const +{ + Q_D(const DuiScalableImage); + + if (left != NULL) { + *left = d->m_left; + } + if (right != NULL) { + *right = d->m_right; + } + if (top != NULL) { + *top = d->m_top; + } + if (bottom != NULL) { + *bottom = d->m_bottom; + } +} + +void DuiScalableImage::setBorders(int left, int right, int top, int bottom) +{ + Q_D(DuiScalableImage); + + d->m_left = left; + d->m_right = right; + d->m_top = top; + d->m_bottom = bottom; + + if (left == 0 && right == 0 && top == 0 && bottom == 0) { + d->m_imageType = DuiScalableImagePrivate::DuiScalable1; + } + /*else if( (top == 0 && bottom == 0) ) {//&& (right != 0 && left != 0 ) ) { + d->m_imageType = DuiScalableImagePrivate::DuiScalable3H; + duiDebug("DuiScalableImage) << "************** DuiScalable3H *************"; + } + else if( (right == 0 && left == 0) ) {//&& (top != 0 && bottom != 0 ) ) { + d->m_imageType = DuiScalableImagePrivate::DuiScalable3V; + duiDebug("DuiScalableImage) << "************** DuiScalable3V *************"; + }*/ + else { + d->m_imageType = DuiScalableImagePrivate::DuiScalable9; + } + + d->calcImageRects(); +} + +void DuiScalableImage::setPixmap(const QPixmap *pixmap) +{ + Q_D(DuiScalableImage); + + d->m_image = pixmap; + d->pixmapId = ""; + d->calcImageRects(); +} + +const QPixmap *DuiScalableImage::pixmap() const +{ + Q_D(const DuiScalableImage); + return d->m_image; +} + +void DuiScalableImage::draw(int x, int y, int w, int h, QPainter *painter) const +{ + Q_D(const DuiScalableImage); + + if (!d->m_image) { + duiWarning("DuiScalableImage") << "DuiScalableImage::draw() scalable image: " << d->pixmapId << " not properly initialized yet"; + painter->fillRect(QRect(x, y, w, h), QColor(255, 0, 0)); + return; + } + + if (d->m_imageSize != d->m_image->size()) + d->calcImageRects(); + + switch (d->m_imageType) { + case DuiScalableImagePrivate::DuiScalable1: + d->drawScalable1(x, y, w, h, painter); + break; + case DuiScalableImagePrivate::DuiScalable9: + d->drawScalable9(x, y, w, h, painter); + break; + default: + duiWarning("DuiScalableImage") << d->pixmapId << " draw() unsupported type " << d->m_imageType; + } +} + +void DuiScalableImage::draw(const QPoint &pos, const QSize &size, QPainter *painter) const +{ + draw(pos.x(), pos.y(), size.width(), size.height(), painter); +} + +void DuiScalableImage::draw(const QRect &rect, QPainter *painter) const +{ + draw(rect.x(), rect.y(), rect.width(), rect.height(), painter); +} + +void DuiScalableImage::enableOptimizedRendering(bool enable) +{ + Q_D(DuiScalableImage); + d->m_useGLRenderer = enable; +} + diff --git a/src/painting/duiscalableimage.h b/src/painting/duiscalableimage.h new file mode 100644 index 000000000..4abcd6f16 --- /dev/null +++ b/src/painting/duiscalableimage.h @@ -0,0 +1,158 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISCALABLEIMAGE_H +#define DUISCALABLEIMAGE_H + +#include +#include "duiexport.h" + +class DuiScalableImagePrivate; +class QPoint; +class QSize; +class QPainter; +class QPixmap; +class QRect; + + +/*! + \class DuiScalableImage + \brief DuiScalableImage is a class for drawing scaled pixmaps into screen + without breaking the boundaries of the image. + + The image is constructed from 9 blocks and it is scalable in every direction. + + <corner> <h_edge> <corner> + <v_edge> <center> <v_edge> + <corner> <h_edge> <corner> + + The scalable area of the image is defined using the left, right, top and bottom + border parameters. The borders are defined as pixels and they cannot be larger + the used source pixmap. + + The corner blocks are not scaled at all. The horizontal edges (h_edge) are + scaled only horizontally and the vertical edges (v_edge) only vertically. The + center block is scaled vertically and horizontally if needed. The size inputted + into one the draw() methods cannot be smaller than the defined borders. +*/ +class DUI_EXPORT DuiScalableImage : public QObject +{ + Q_OBJECT + +public: + + /*! + \brief Default constructor. Initiates pixmap and borders to 0. + */ + DuiScalableImage(); + + /*! + \brief Constructor. Initiates pixmap and borders to inputted values. + \param pixmapId - optional pixmapId associated with a scalable image which will be included into warnings + if DuiScalableImage happen to find those + */ + DuiScalableImage(const QPixmap *pixmap, int left, int right, int top, int bottom, const QString &pixmapId = ""); + + /*! + \brief Destructor. + */ + virtual ~DuiScalableImage(); + + /*! + \brief Get borders for the image. + + The borders are defined as pixels. See ::createScalable() for + description about how the borders affect to the image drawing/scaling. + */ + void borders(int *left, int *right, int *top, int *bottom) const; + + /*! + \brief Set borders for the image. + + The borders are defined as pixels. See ::createScalable() for + description about how the borders affect to the image drawing/scaling. + */ + void setBorders(int left, int right, int top, int bottom); + + /*! + \brief Set/change the drawn pixmap. + + The ownership of \a pixmap is not changed by this method, the caller + of the method is still responsible for releasing the pixmap after + done using it. + */ + void setPixmap(const QPixmap *pixmap); + + //init pixmap from theme, and release it in the destructor or when + //another pixmap is set. + //void setPixmap(const QString& pixmapId); + + /*! + \brief Returns the pixmap that was given as parameter into the ::createScalable() + or ::setPixmap() methods. + */ + const QPixmap *pixmap() const; + + /*! + \brief Draws scalable image. + + The image is drawn starting from the topleft corner defined by the + \a x and \a y coordinates. The image is scaled to fit the \a w and + \a h. Scaling follows the rules defined in the ::createScalable() method. + + If -1 is defined as \a w or \a h appropriate value from the image is + used so no scaling takes place. + */ + void draw(int x, int y, int w, int h, QPainter *painter) const; + + /*! + \brief Draws scalable image. + \overload + */ + void draw(const QPoint &pos, const QSize &size, QPainter *painter) const; + + /*! + \brief Draws scalable image. + \overload + */ + void draw(const QRect &rect, QPainter *painter) const; + + /*! + \brief Enable/disable optimized rendering. + + If \a enable is true, the image patches are packed into one vertex array + and it is rendered with one glDrawArray call. If \a enable is false, + the image patches are rendered separately. + + \note This method is only for benchmarking purposes and may be removed + in the future. + */ + void enableOptimizedRendering(bool enable); + +protected: + DuiScalableImagePrivate *const d_ptr; + DuiScalableImage(DuiScalableImagePrivate *dd); + +private: + Q_DECLARE_PRIVATE(DuiScalableImage) + Q_DISABLE_COPY(DuiScalableImage) +}; + +#endif + diff --git a/src/painting/duiscalableimage_p.h b/src/painting/duiscalableimage_p.h new file mode 100644 index 000000000..ff7c81ac7 --- /dev/null +++ b/src/painting/duiscalableimage_p.h @@ -0,0 +1,80 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISCALABLEIMAGE_P_H +#define DUISCALABLEIMAGE_P_H + +#include +#include +#include + +#include "duiscalableimage.h" + +class DuiScalableImagePrivate +{ + Q_DECLARE_PUBLIC(DuiScalableImage) +public: + + enum DuiScalableImageType { + DuiScalable9, + DuiScalable1 + //DuiScalable3H, + //DuiScalable3V, + }; + + DuiScalableImagePrivate(); + virtual ~DuiScalableImagePrivate(); + + void validateSize(int &w, int &h) const; + + void drawScalable9(int x, int y, int w, int h, QPainter *painter) const; + void drawScalable1(int x, int y, int w, int h, QPainter *painter) const; + void drawScalable3H(int x, int y, int w, int h, QPainter *painter) const; + void drawScalable3V(int x, int y, int w, int h, QPainter *painter) const; + + QList m_imageBlocks; + DuiScalableImageType m_imageType; + + //TODO: think some other solution for mutable: + //no precalculation, timer which is run until valid values are received, + //make m_imageRects and m_valid global variables. + + //mutables here are used because we are doing some precalculations in the + //draw methods, the recalculation is done in the paint method because + //the pixmap given in setPixmap() method might still be invalid because of + //asynchronous pixmap loading. + void calcImageRects() const; + mutable QList m_imageRects; + mutable QSize m_imageSize; + + const QPixmap *m_image; + + bool m_useGLRenderer; + + int m_left; + int m_right; + int m_top; + int m_bottom; + QString pixmapId; + +protected: + DuiScalableImage *q_ptr; +}; + +#endif // DUIWIDGET_P_H diff --git a/src/painting/painting.pri b/src/painting/painting.pri new file mode 100644 index 000000000..1ed8a1dd1 --- /dev/null +++ b/src/painting/painting.pri @@ -0,0 +1,30 @@ +############################################################################### +# DuiPainting module +# This module contains all classes that exclusively deal with painting. +############################################################################### +PAINTING_SRC_DIR=./painting +INCLUDEPATH+=./painting +HEADERS += \ + $$PAINTING_SRC_DIR/duiglwidget.h \ + $$PAINTING_SRC_DIR/duiglrenderer.h \ + $$PAINTING_SRC_DIR/duigles2renderer.h \ + $$PAINTING_SRC_DIR/duiglshader.h \ + $$PAINTING_SRC_DIR/duiglshaderprogram.h \ + $$PAINTING_SRC_DIR/duiglshaderuniform.h \ + $$PAINTING_SRC_DIR/duiscalableimage.h + +SOURCES += \ + $$PAINTING_SRC_DIR/duiglwidget.cpp \ + $$PAINTING_SRC_DIR/duiglrenderer.cpp \ + $$PAINTING_SRC_DIR/duigles2renderer.cpp \ + $$PAINTING_SRC_DIR/duiglshader.cpp \ + $$PAINTING_SRC_DIR/duiglshaderprogram.cpp \ + $$PAINTING_SRC_DIR/duiglshaderuniform.cpp \ + $$PAINTING_SRC_DIR/duiscalableimage.cpp + +install_shader_source.path = $$DUI_SHADER_SOURCE_DIR +install_shader_source.files = \ + $$PAINTING_SRC_DIR/shaders/default.frag \ + $$PAINTING_SRC_DIR/shaders/default.vert + +INSTALLS += install_shader_source diff --git a/src/painting/shaders/default.frag b/src/painting/shaders/default.frag new file mode 100644 index 000000000..b8c81f7fb --- /dev/null +++ b/src/painting/shaders/default.frag @@ -0,0 +1,8 @@ +varying lowp vec2 fragTexCoord; +uniform sampler2D texture0; +uniform lowp float opacity; + +void main(void) +{ + gl_FragColor = texture2D(texture0, fragTexCoord) * opacity; +} diff --git a/src/painting/shaders/default.vert b/src/painting/shaders/default.vert new file mode 100644 index 000000000..0abe12a0b --- /dev/null +++ b/src/painting/shaders/default.vert @@ -0,0 +1,11 @@ +attribute highp vec4 vertex; +attribute lowp vec2 texCoord; +uniform highp mat4 matProj; +uniform highp mat4 matWorld; +varying lowp vec2 fragTexCoord; + +void main(void) +{ + gl_Position = matProj * matWorld * vertex; + fragTexCoord = texCoord; +} diff --git a/src/predeps.pri b/src/predeps.pri new file mode 100644 index 000000000..a79c7d9ca --- /dev/null +++ b/src/predeps.pri @@ -0,0 +1,9 @@ +QMAKE_EXTRA_TARGETS += build_moc \ + build_gen \ + +build_moc.target = ../duimoc/duimoc +build_moc.commands = cd ../duimoc && qmake && make + +build_gen.target = ../duigen/duigen +build_gen.commands = cd ../duigen && qmake && make + diff --git a/src/scene/duiscene.cpp b/src/scene/duiscene.cpp new file mode 100644 index 000000000..0e9bed2ec --- /dev/null +++ b/src/scene/duiscene.cpp @@ -0,0 +1,318 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include +#include +#include + +#include +#include "duiapplication.h" +#include "duiapplicationwindow.h" +#include "duiscene.h" +#include "duiscenemanager.h" +#include "duiwidget.h" +#include "duiapplicationpage.h" +#include "duiscene_p.h" + +const QFont TextFont = QFont("Sans", 10); +const int MillisecsInSec = 1000; +const int FpsRefreshInterval = 1000; +const QSize FpsBoxSize = QSize(100, 40); +const QColor FpsTextColor = QColor(0xFFFF00); +const QFont FpsFont = QFont("Sans", 15); +const QString FpsBackgroundColor = "#000000"; +const qreal FpsBackgroundOpacity = 0.35; +const QString BoundingRectLineColor = "#00F000"; +const QString BoundingRectFillColor = "#00F000"; +const qreal BoundingRectOpacity = 0.1; +const qreal MarginBackgroundOpacity = 0.4; +const QColor MarginColor = QColor(Qt::red); +const int MarginBorderWidth = 2; + + + +// FIXME: Probably we should have a DuiScenePrivate class as a matter of policy +static QTime lastUpdate; +static int _frameCount = 0; +static int fps = 0; + + +DuiScenePrivate::~DuiScenePrivate() +{ +} + +void DuiScenePrivate::setSceneManager(DuiSceneManager *sceneManager) +{ + manager = sceneManager; +} + +void DuiScenePrivate::onDisplayChangeEvent(DuiOnDisplayChangeEvent *event) +{ + Q_Q(DuiScene); + + if (event->state() == DuiOnDisplayChangeEvent::FullyOnDisplay || + event->state() == DuiOnDisplayChangeEvent::FullyOffDisplay) { + // Simple cases. Just forward the event as it is. + sendEventToDuiWidgets(filterDuiWidgets(q->items()), event); + return; + } + + QList fullyOnWidgets; + QList partiallyOnWidgets; + QList fullyOffWidgets; + + QList intersectingWidgets = filterDuiWidgets(q->items(event->viewRect(), + Qt::IntersectsItemBoundingRect)); + + QList allWidgets = filterDuiWidgets(q->items()); + + // Find who is fully on, partially on and fully off + + QSet fullyOffWidgetsSet = allWidgets.toSet().subtract(intersectingWidgets.toSet()); + fullyOffWidgets = fullyOffWidgetsSet.toList(); + + int intersectingWidgetsCount = intersectingWidgets.count(); + DuiWidget *widget; + for (int i = 0; i < intersectingWidgetsCount; i++) { + widget = intersectingWidgets.at(i); + if (event->viewRect().contains(widget->sceneBoundingRect())) { + fullyOnWidgets << widget; + } else { + partiallyOnWidgets << widget; + } + } + + // Send the events to the corresponding DuiWidgets + + if (fullyOnWidgets.count() > 0) { + DuiOnDisplayChangeEvent fullyOnEvent(DuiOnDisplayChangeEvent::FullyOnDisplay, + event->viewRect()); + + sendEventToDuiWidgets(fullyOnWidgets, &fullyOnEvent); + } + + if (fullyOffWidgets.count() > 0) { + DuiOnDisplayChangeEvent fullyOffEvent(DuiOnDisplayChangeEvent::FullyOffDisplay, + event->viewRect()); + + sendEventToDuiWidgets(fullyOffWidgets, &fullyOffEvent); + } + + if (partiallyOnWidgets.count() > 0) { + DuiOnDisplayChangeEvent partiallyOnEvent(DuiOnDisplayChangeEvent::PartiallyOnDisplay, + event->viewRect()); + + sendEventToDuiWidgets(partiallyOnWidgets, &partiallyOnEvent); + } + +} + +QList DuiScenePrivate::filterDuiWidgets(QList itemsList) +{ + QGraphicsItem *item; + DuiWidget *duiWidget; + QList widgetsList; + + int itemsCount = itemsList.count(); + for (int i = 0; i < itemsCount; i++) { + item = itemsList.at(i); + if (item->isWidget()) { + duiWidget = qobject_cast(static_cast(item)); + if (duiWidget) { + widgetsList << duiWidget; + } + } + } + + return widgetsList; +} + +void DuiScenePrivate::sendEventToDuiWidgets(QList widgetsList, QEvent *event) +{ + Q_Q(DuiScene); + DuiWidget *widget; + + int widgetsCount = widgetsList.count(); + for (int i = 0; i < widgetsCount; i++) { + widget = widgetsList.at(i); + q->sendEvent(widget, event); + } +} + +DuiScene::DuiScene(QObject *parent) + : QGraphicsScene(parent), + d_ptr(new DuiScenePrivate) +{ + Q_D(DuiScene); + + d->q_ptr = this; + d->manager = 0; + QColor fpsBackgroundColor(FpsBackgroundColor); + fpsBackgroundColor.setAlphaF(FpsBackgroundOpacity); + d->fpsBackgroundBrush = QBrush(fpsBackgroundColor); + + QColor boundingRectLineColor(BoundingRectLineColor); + d->boundingRectLinePen = QPen(boundingRectLineColor); + + QColor boundingRectFillColor(BoundingRectFillColor); + d->boundingRectFillBrush = QBrush(boundingRectFillColor); + + setItemIndexMethod(QGraphicsScene::NoIndex); +} + +DuiScene::~DuiScene() +{ + delete d_ptr; +} + +DuiSceneManager *DuiScene::sceneManager() +{ + Q_D(DuiScene); + + return d->manager; +} + +void DuiScene::drawForeground(QPainter *painter, const QRectF &rect) +{ + Q_D(DuiScene); + + /* Overlay information on the widgets in development mode */ + if (DuiApplication::showBoundingRect() || DuiApplication::showSize() || DuiApplication::showPosition() || DuiApplication::showMargins() || DuiApplication::showObjectNames()) { + QList itemList = items(rect); + QList::iterator item; + + painter->setFont(TextFont); + QFontMetrics metrics(TextFont); + int fontHeight = metrics.height(); + + QTransform rotationMatrix; + painter->setTransform(rotationMatrix); + + QList::iterator end = itemList.end(); + for (item = itemList.begin(); item != end; ++item) { + QRectF br = (*item)->boundingRect(); + QPolygonF bp = (*item)->mapToScene(br); + + if (DuiApplication::showBoundingRect()) { + if (!dynamic_cast(*item)) { // filter out page for clarity + painter->setOpacity(BoundingRectOpacity); + painter->setPen(d->boundingRectLinePen); + painter->setBrush(d->boundingRectFillBrush); + painter->drawPolygon(bp); + } + } + + if (DuiApplication::showMargins()) { + // Draw content margins + QGraphicsLayoutItem *layoutItem = dynamic_cast(*item); + if (layoutItem) { + qreal left, top, right, bottom; + layoutItem->getContentsMargins(&left, &top, &right, &bottom); + if (left != 0 || top != 0 || right != 0 || bottom != 0) { + QPainterPath path; + path.addPolygon(bp); + path.addPolygon((*item)->mapToScene(br.adjusted(left, top, -right, -bottom))); + + painter->setOpacity(MarginBackgroundOpacity); + painter->fillPath(path, QBrush(MarginColor)); + painter->setOpacity(1.0); + painter->fillPath(path, QBrush(MarginColor, Qt::BDiagPattern)); + QPen pen(Qt::DashLine); + pen.setWidth(MarginBorderWidth); + pen.setColor(MarginColor); + painter->strokePath(path, pen); + } + } + + painter->setOpacity(1.0); + } + + if (DuiApplication::showPosition()) { + QPointF topLeft = ((*item)->mapToScene(br.topLeft())); + QString posStr = QString("(%1, %2)").arg(topLeft.x()).arg(topLeft.y()); + painter->setPen(Qt::black); + painter->drawText(topLeft += QPointF(5, fontHeight), posStr); + painter->setPen(Qt::white); + painter->drawText(topLeft -= QPointF(1, 1), posStr); + } + + if (DuiApplication::showSize()) { + QPointF bottomRight = ((*item)->mapToScene(br.bottomRight())); + QString sizeStr = QString("%1x%2").arg(br.width()).arg(br.height()); + painter->setPen(Qt::black); + painter->drawText(bottomRight -= QPointF(metrics.width(sizeStr), 2), sizeStr); + painter->setPen(Qt::white); + painter->drawText(bottomRight -= QPointF(1, 1), sizeStr); + } + + if (DuiApplication::showObjectNames()) { + QGraphicsWidget *widget = dynamic_cast(*item); + if (widget) { + QRectF boundingRect = bp.boundingRect(); + QString name = widget->objectName(); + QRect textBoundingRect = metrics.boundingRect(name); + QPointF center = boundingRect.topLeft(); + center += QPointF((boundingRect.width() - textBoundingRect.width()) / 2, (boundingRect.height() - fontHeight) / 2); + painter->fillRect(textBoundingRect.translated(center.toPoint()), d->fpsBackgroundBrush); + painter->setPen(FpsTextColor); + painter->drawText(center, name); + } + } + } + } + + /* Draw a simple FPS counter in the lower right corner */ + if (DuiApplication::showFps()) { + static QRectF fpsRect(0, 0, FpsBoxSize.width(), FpsBoxSize.height()); + if (!views().isEmpty()) { + DuiApplicationWindow *window = qobject_cast(views().at(0)); + if (window) { + if (d->manager && d->manager->orientation() == Dui::Portrait) + fpsRect.moveTo(QPointF(window->visibleSceneSize().height() - FpsBoxSize.width(), + window->visibleSceneSize().width() - FpsBoxSize.height())); + else + fpsRect.moveTo(QPointF(window->visibleSceneSize().width() - FpsBoxSize.width(), + window->visibleSceneSize().height() - FpsBoxSize.height())); + } + } + + painter->fillRect(fpsRect, d->fpsBackgroundBrush); + QTime now = QTime::currentTime(); + ++_frameCount; + + if (lastUpdate.msecsTo(now) > FpsRefreshInterval) { + fps = (MillisecsInSec * _frameCount) / (lastUpdate.msecsTo(now)); + _frameCount = 0; + lastUpdate = now; + } + + QString stringToDraw = QString("FPS: %1").arg(fps); + painter->setPen(FpsTextColor); + painter->setFont(FpsFont); + painter->drawText(fpsRect, + Qt::AlignCenter, + stringToDraw); + + // this update call makes repainting work as fast + // as possible, and by that prints useful fps numbers + QTimer::singleShot(0, this, SLOT(update())); + } +} diff --git a/src/scene/duiscene.h b/src/scene/duiscene.h new file mode 100644 index 000000000..a2e8fb84e --- /dev/null +++ b/src/scene/duiscene.h @@ -0,0 +1,71 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISCENE_H +#define DUISCENE_H + +#include "duiexport.h" +#include "duinamespace.h" + +#include + +class DuiSceneManager; +class DuiScenePrivate; +class DuiWindowPrivate; + +//! DUISCene stub +class DUI_EXPORT DuiScene : public QGraphicsScene +{ + Q_OBJECT + +public: + //! DuiScene constructor + /*! + * \param parent QObject* defaults to 0 + * \return DuiScene + * */ + explicit DuiScene(QObject *parent = 0); + virtual ~DuiScene(); + + /*! + * Returns a pointer to the scene manager that manages this scene. + * If no manager is assigned, a null pointer is returned. + */ + DuiSceneManager *sceneManager(); + +protected: + //! \reimp + void drawForeground(QPainter *painter, const QRectF &rect); + //! \reimp_end + + DuiScenePrivate *const d_ptr; + +private: + Q_DISABLE_COPY(DuiScene) + Q_DECLARE_PRIVATE(DuiScene) + +#ifdef UNIT_TEST + friend class Ut_DuiScene; +#endif // UNIT_TEST + + friend class DuiSceneManager; + friend class DuiWindowPrivate; +}; + +#endif diff --git a/src/scene/duiscene_p.h b/src/scene/duiscene_p.h new file mode 100644 index 000000000..c57e043b3 --- /dev/null +++ b/src/scene/duiscene_p.h @@ -0,0 +1,48 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISCENE_P_H +#define DUISCENE_P_H + +class DuiSceneManager; +class DuiOnDisplayChangeEvent; + +class DuiScenePrivate +{ + Q_DECLARE_PUBLIC(DuiScene) + +public: + void init(); + virtual ~DuiScenePrivate(); + void setSceneManager(DuiSceneManager *sceneManager); + + void onDisplayChangeEvent(DuiOnDisplayChangeEvent *event); + QList filterDuiWidgets(QList itemsList); + void sendEventToDuiWidgets(QList itemsList, QEvent *event); + + QBrush fpsBackgroundBrush; + QPen boundingRectLinePen; + QBrush boundingRectFillBrush; + +protected: + DuiScene *q_ptr; + DuiSceneManager *manager; +}; + +#endif // DUISCENE_P_H diff --git a/src/scene/duiscenelayereffect.cpp b/src/scene/duiscenelayereffect.cpp new file mode 100644 index 000000000..53227af3b --- /dev/null +++ b/src/scene/duiscenelayereffect.cpp @@ -0,0 +1,109 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include "duiscenelayereffect.h" +#include "duiscenelayereffect_p.h" +#include "duiscenelayereffectmodel.h" + +#include "duiwidgetcreator.h" +DUI_REGISTER_WIDGET_NO_CREATE(DuiSceneLayerEffect) + +DuiSceneLayerEffectPrivate::DuiSceneLayerEffectPrivate() +{ + layerPressedDirectly = false; +} + +DuiSceneLayerEffectPrivate::~DuiSceneLayerEffectPrivate() +{ +} + +DuiSceneLayerEffect::DuiSceneLayerEffect(const QString &effectType) + : DuiSceneWindow(new DuiSceneLayerEffectPrivate(), + new DuiSceneLayerEffectModel(), DuiSceneWindow::LayerEffect, + effectType) +{ +} + +DuiSceneLayerEffect::~DuiSceneLayerEffect() +{ +} + +void DuiSceneLayerEffect::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + Q_D(DuiSceneLayerEffect); + event->accept(); + + if (scene()->itemAt(event->scenePos()) == this) { + // The layer was pressed directly + d->layerPressedDirectly = true; + } else { + // The layer wasn't pressed. We got the event just because + // our child scene window didn't accept it. + d->layerPressedDirectly = false; + } +} + +void DuiSceneLayerEffect::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + Q_D(DuiSceneLayerEffect); + QList itemList = childItems(); + QGraphicsItem *item; + + event->accept(); + + if (d->layerPressedDirectly) { + // reset value + d->layerPressedDirectly = false; + if (scene()->itemAt(event->scenePos()) == this) { + // Mouse was released on top of the layer effect. That constitutes a + // proper click event. + // Let's dismiss our associated scene window. + foreach(item, itemList) { + if (item->isWidget()) { + QGraphicsWidget *widget = static_cast(item); + DuiSceneWindow *sceneWindow = qobject_cast(widget); + if (sceneWindow) { + sceneWindow->dismiss(); + } else { + widget->close(); + } + } + } + //By closing the associated scene window, this may in turn be delete this, + //so we can no longer rely on d_ptr from this point on. + } + } +} + +void DuiSceneLayerEffect::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) +{ + event->accept(); +} + +void DuiSceneLayerEffect::enableEffect() +{ + model()->setEnabled(true); +} + +void DuiSceneLayerEffect::disableEffect() +{ + model()->setEnabled(false); +} diff --git a/src/scene/duiscenelayereffect.h b/src/scene/duiscenelayereffect.h new file mode 100644 index 000000000..0e26444eb --- /dev/null +++ b/src/scene/duiscenelayereffect.h @@ -0,0 +1,57 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +// Make doxygen skip this internal class +//! \cond +#ifndef DUISCENELAYEREFFECT_H +#define DUISCENELAYEREFFECT_H + +#include "duiscenewindow.h" +#include "duiscenelayereffectmodel.h" + +class DuiSceneLayerEffectPrivate; + +class DuiSceneLayerEffect : public DuiSceneWindow +{ + Q_OBJECT + DUI_CONTROLLER(DuiSceneLayerEffect) + +public: + + DuiSceneLayerEffect(const QString &effectType); + virtual ~DuiSceneLayerEffect(); + +public Q_SLOTS: + void enableEffect(); + void disableEffect(); + +protected: + + //! \reimp + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent *event); + //! \reimp_end + +private: + Q_DECLARE_PRIVATE(DuiSceneLayerEffect) +}; + +#endif +//! \endcond diff --git a/src/scene/duiscenelayereffect_p.h b/src/scene/duiscenelayereffect_p.h new file mode 100644 index 000000000..faa5deef9 --- /dev/null +++ b/src/scene/duiscenelayereffect_p.h @@ -0,0 +1,38 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISCENELAYEREFFECT_P_H +#define DUISCENELAYEREFFECT_P_H + +#include "duiscenewindow_p.h" + +class DuiSceneLayerEffect; + +class DuiSceneLayerEffectPrivate : public DuiSceneWindowPrivate +{ + Q_DECLARE_PUBLIC(DuiSceneLayerEffect) + +public: + DuiSceneLayerEffectPrivate(); + ~DuiSceneLayerEffectPrivate(); + + bool layerPressedDirectly; +}; + +#endif diff --git a/src/scene/duiscenemanager.cpp b/src/scene/duiscenemanager.cpp new file mode 100644 index 000000000..52f562973 --- /dev/null +++ b/src/scene/duiscenemanager.cpp @@ -0,0 +1,1133 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiscenemanager.h" +#include "duiscenemanager_p.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "duiscenewindow.h" +#include "duiscenewindow_p.h" +#include "duideviceprofile.h" +#include "duidialog.h" +#include "duiscene.h" +#include "duiscene_p.h" +#include "duiscenelayereffect.h" +#include "duinavigationbar.h" +#include "duidockwidget.h" +#include "duiescapebuttonpanel.h" +#include "duiescapebuttonpanelmodel.h" +#include "duiapplication.h" +#include "duiwindow.h" +#include "duiapplicationwindow.h" +#include "duiapplicationwindow_p.h" + +#include "duiinputmethodstate.h" + +#include "duiapplicationpage.h" +#include "duiorientationtracker.h" + +#include "duibasicorientationanimation.h" +#include "duinotificationanimation.h" +#include "duiscenefadeanimation.h" +#include "duiabstractwidgetanimation.h" +#include "duipageswitchanimation.h" + +const int DuiSceneManagerPrivate::KeyboardSpacing = 20; + +namespace +{ + //! This is a guess for the SIP close timeout since there is no general way of getting it. + const int SoftwareInputPanelHideTimer = 500; +} + + +void DuiSceneManagerPrivate::init(DuiScene *scene) +{ + Q_Q(DuiSceneManager); + + this->scene = scene; + + navBar = 0; + escapeButtonPanel = 0; + currentPage = 0; + navBarHidden = false; + escapeButtonHidden = false; + + focusedInputWidget = 0; + alteredSceneWindow = 0; + sceneWindowTranslation = QPoint(); + + pendingSIPClose = false; + + // set the angle to that of the topmost window, if one exists + DuiWindow *activeWindow = DuiApplication::activeWindow(); + + DuiWindow *viewingWindow = 0; + if (scene->views().size() > 0) { + viewingWindow = qobject_cast(scene->views().at(0)); + Q_ASSERT(viewingWindow); + } + + if (activeWindow && activeWindow != viewingWindow) + angle = activeWindow->orientationAngle(); + else + angle = DuiOrientationTracker::instance()->orientationAngle(); + newAngle = angle; + + windows = new QList(); + pageHistory = new QList(); + + rootElement = new QGraphicsWidget(); + rootElement->setTransformOriginPoint(QPointF(q->visibleSceneSize().width() / 2.0, q->visibleSceneSize().height() / 2.0)); + scene->addItem(rootElement); + + //TODO: get this from theme + orientationAnimation = new DuiBasicOrientationAnimation(q->visibleSceneSize(Dui::Landscape)); + orientationAnimation->setRootElement(rootElement); + q->connect(orientationAnimation, SIGNAL(orientationChanged()), SLOT(_q_changeGlobalOrientation())); + q->connect(orientationAnimation, SIGNAL(finished()), SLOT(_q_emitOrientationChangeFinished())); + + pageSwitchAnimation = new DuiPageSwitchAnimation; + + setOrientationAngleWithoutAnimation(newAngle); +} + +DuiSceneManagerPrivate::~DuiSceneManagerPrivate() +{ + delete windows; + delete pageHistory; + delete orientationAnimation; + delete pageSwitchAnimation; +} + +int DuiSceneManagerPrivate::zForWindowType(DuiSceneWindow::WindowType windowType) +{ + int z = 0; + switch (windowType) { + case DuiSceneWindow::PlainSceneWindow: + z = DuiSceneManagerPrivate::PlainSceneWindow; + break; + case DuiSceneWindow::ApplicationPage: + z = DuiSceneManagerPrivate::ApplicationPage; + break; + case DuiSceneWindow::NavigationBar: + z = DuiSceneManagerPrivate::NavigationBar; + break; + case DuiSceneWindow::DockWidget: + z = DuiSceneManagerPrivate::DockWidget; + break; + case DuiSceneWindow::EscapeButtonPanel: + z = DuiSceneManagerPrivate::EscapeButtonPanel; + break; + case DuiSceneWindow::Dialog: + z = DuiSceneManagerPrivate::Dialog; + break; + case DuiSceneWindow::ModalSceneWindow: + z = DuiSceneManagerPrivate::ModalSceneWindow; + break; + case DuiSceneWindow::MessageBox: + z = DuiSceneManagerPrivate::MessageBox; + break; + case DuiSceneWindow::ApplicationMenu: + z = DuiSceneManagerPrivate::ApplicationMenu; + break; + case DuiSceneWindow::PopupList: + z = DuiSceneManagerPrivate::PopupList; + break; + case DuiSceneWindow::NotificationInformation: + z = DuiSceneManagerPrivate::NotificationInformation; + break; + case DuiSceneWindow::NotificationEvent: + z = DuiSceneManagerPrivate::NotificationEvent; + break; + case DuiSceneWindow::Overlay: + z = DuiSceneManagerPrivate::Overlay; + break; + case DuiSceneWindow::ObjectMenu: + z = DuiSceneManagerPrivate::ObjectMenu; + break; + case DuiSceneWindow::Completer: + z = DuiSceneManagerPrivate::Completer; + break; + case DuiSceneWindow::HomeButtonPanel: + z = DuiSceneManagerPrivate::HomeButtonPanel; + break; + default: + z = 0; + // Should not get here. Only scene layer effect does not have it's + // case statement and z is not asked for effect layer + break; + } + return z; +} + +void DuiSceneManagerPrivate::_q_setSenderGeometry() +{ + Q_Q(DuiSceneManager); + + DuiSceneWindow *window = qobject_cast(q->sender()); + if (window) + setSceneWindowGeometry(window); +} + +void DuiSceneManagerPrivate::_q_changeGlobalOrientation() +{ + Q_Q(DuiSceneManager); + + angle = newAngle; + + // Send a signal that the orientation is about to change + emit q->orientationAboutToChange(q->orientation()); + + // All scene windows are resized + setSceneWindowGeometries(); + + // Send a rotation event to the scene + emit q->orientationChanged(q->orientation()); +} + +void DuiSceneManagerPrivate::_q_emitOrientationChangeFinished() +{ + Q_Q(DuiSceneManager); + + emit q->orientationChangeFinished(q->orientation()); +} + +void DuiSceneManagerPrivate::_q_unFreezeUI() +{ + Q_Q(DuiSceneManager); + + rootElement->setEnabled(true); + + QAbstractAnimation *animation = dynamic_cast(q->sender()); + if (animation == 0) + return; + + QObject::disconnect(animation, SIGNAL(finished()), q, SLOT(_q_unFreezeUI())); +} + +void DuiSceneManagerPrivate::_q_windowShowAnimationFinished() +{ + Q_Q(DuiSceneManager); + DuiSceneWindow *window = dynamic_cast(q->sender()); + if (window == 0) + return; + + if (isOnDisplay()) { + produceMustBeResolvedDisplayEvent(window); + } + + QObject::disconnect(window, SIGNAL(windowShown()), q, SLOT(_q_windowShowAnimationFinished())); +} + +void DuiSceneManagerPrivate::_q_windowHideAnimationFinished() +{ + Q_Q(DuiSceneManager); + //TODO: There could be a mapping between windows and animations so that + // when a window is detached all its animations are deleted as well + // so this method would never got called for "invalid"/detached window. + DuiSceneWindow *window = dynamic_cast(q->sender()); + if (window == 0) + return; + + if (window->windowType() == DuiSceneWindow::NavigationBar && !navBarHidden) + navBar = 0; + + if (window->windowType() == DuiSceneWindow::EscapeButtonPanel && !escapeButtonHidden) + escapeButtonPanel = 0; + + if (isOnDisplay()) { + produceFullyOffDisplayEvents(window); + } + + window->hide(); + + QObject::disconnect(window, SIGNAL(windowHidden()), q, SLOT(_q_windowHideAnimationFinished())); + + //check if the window has not yet been detached + int i = windows->indexOf(window); + + if (i != -1) { + windows->removeAt(i); + QObject::disconnect(window, SIGNAL(repositionNeeded()), q, SLOT(_q_setSenderGeometry())); + + // If there is a layer effect it is deleted as well + if (window->d_func()->effect) { + window->setParentItem(0); + delete window->d_func()->effect; + window->d_func()->effect = 0; + } + + if ((window->deletionPolicy() == DuiSceneWindow::DestroyWhenDone) || + ((window->deletionPolicy() == DuiSceneWindow::DestroyWhenDismissed) + && window->d_func()->dismissed)) { + window->deleteLater(); + } + } +} + +void DuiSceneManagerPrivate::_q_relocateWindowByInputPanel(const QRect &inputPanelRect) +{ + if (focusedInputWidget) { + const QRect widgetRect( + focusedInputWidget->mapRectToItem(rootElement, focusedInputWidget->boundingRect()).toRect()); + const QRect mappedInputPanelRect(rootElement->mapRectFromScene(inputPanelRect).toRect()); + + if (widgetRect.intersects(mappedInputPanelRect)) { + const QRect intersection(widgetRect.intersected(mappedInputPanelRect)); + const InputPanelPlacement panelPlacement(inputPanelPlacement(mappedInputPanelRect)); + alteredSceneWindow = parentSceneWindow(focusedInputWidget); + if (alteredSceneWindow) { + QPoint newTranslation; + switch (panelPlacement) { + case North: + newTranslation.ry() += mappedInputPanelRect.bottomLeft().y() - + intersection.topLeft().y() + KeyboardSpacing; + break; + case South: + newTranslation.ry() += intersection.bottomLeft().y() - + mappedInputPanelRect.topLeft().y() + KeyboardSpacing; + newTranslation.ry() *= -1; + break; + default:; + } + moveSceneWindow(alteredSceneWindow, newTranslation); + } + } + } +} + +void DuiSceneManagerPrivate::_q_restoreSceneWindow() +{ + if (alteredSceneWindow && !focusedInputWidget) { + sceneWindowTranslation *= -1; + alteredSceneWindow->moveBy(sceneWindowTranslation.x(), sceneWindowTranslation.y()); + sceneWindowTranslation = QPoint(); + alteredSceneWindow = 0; + } +} + +Dui::Orientation DuiSceneManagerPrivate::orientation(Dui::OrientationAngle angle) const +{ + return (angle == Dui::Angle0 || angle == Dui::Angle180) ? Dui::Landscape : Dui::Portrait; +} + +void DuiSceneManagerPrivate::attachWindow(DuiSceneWindow *window) +{ + if (!windows->contains(window)) + windows->append(window); + + if (window->windowType() == DuiSceneWindow::ApplicationPage) + pageHistory->append(window); +} + +void DuiSceneManagerPrivate::detachWindow(DuiSceneWindow *window) +{ + windows->removeOne(window); + + // If there is a layer effect it is deleted as well + if (window->d_func()->effect) { + window->setParentItem(rootElement); + delete window->d_func()->effect; + window->d_func()->effect = 0; + } + + if (window->windowType() == DuiSceneWindow::ApplicationPage) { + pageHistory->removeOne(window); + } +} + +DuiSceneLayerEffect *DuiSceneManagerPrivate::createLayerEffectForWindow(DuiSceneWindow *window) +{ + DuiSceneLayerEffect *effect = 0; + + switch (window->windowType()) { + case DuiSceneWindow::PopupList: + case DuiSceneWindow::Dialog: + case DuiSceneWindow::MessageBox: + case DuiSceneWindow::ModalSceneWindow: + case DuiSceneWindow::ApplicationMenu: + effect = new DuiSceneLayerEffect("messagebox"); + break; + default: + return NULL; + } + + //resize the effect layer + setSceneWindowGeometry(effect); + + // Add effect to scene via rootElement + effect->setParentItem(rootElement); + effect->setZValue(zForWindowType(window->windowType())); + + // Add window as child of the effect + window->setParentItem(effect); + + window->d_func()->effect = effect; + + return effect; +} + +void DuiSceneManagerPrivate::setSceneWindowGeometries() +{ + _q_restoreSceneWindow(); + const int size = windows->size(); + for (int i = 0; i < size; ++i) + setSceneWindowGeometry(windows->at(i)); +} + +void DuiSceneManagerPrivate::setSceneWindowGeometry(DuiSceneWindow *window) +{ + if (window->isManagedManually()) + return; + + QPointF p = calculateSceneWindowPosition(window); + window->setPos(p); +} + + +QPointF DuiSceneManagerPrivate::calculateSceneWindowPosition(DuiSceneWindow *window) +{ + Q_Q(DuiSceneManager); + + QSizeF s = q->visibleSceneSize(orientation(angle)); + Qt::Alignment alignment = window->alignment(); + QSizeF windowSize = window->effectiveSizeHint(Qt::PreferredSize); + + qreal xpos = window->x(); + qreal ypos = window->y(); + bool valid = true; + + if (alignment.testFlag(Qt::AlignLeft)) + xpos = 0; + else if (alignment.testFlag(Qt::AlignHCenter)) + xpos = s.width() / 2 - windowSize.width() / 2; + else if (alignment.testFlag(Qt::AlignRight)) + xpos = s.width() - windowSize.width(); + + if (alignment.testFlag(Qt::AlignTop)) + ypos = 0; + else if (alignment.testFlag(Qt::AlignVCenter)) + ypos = s.height() / 2 - windowSize.height() / 2; + else if (alignment.testFlag(Qt::AlignBottom)) + ypos = s.height() - windowSize.height(); + + if (alignment.testFlag(Qt::AlignJustify)) + valid = false; + + if (valid) + return QPointF(xpos, ypos) + window->offset(); + + return QPointF(); +} + +void DuiSceneManagerPrivate::rotateToAngle(Dui::OrientationAngle newAngle) +{ + if (this->newAngle == newAngle) + return; + + orientationAnimation->stop(); + this->newAngle = newAngle; + orientationAnimation->setTargetRotationAngle(angle, newAngle); + orientationAnimation->start(); + freezeUIForAnimationDuration(orientationAnimation); +} + +void DuiSceneManagerPrivate::setOrientationAngleWithoutAnimation(Dui::OrientationAngle newAngle) +{ + Q_Q(DuiSceneManager); + + this->newAngle = newAngle; + _q_changeGlobalOrientation(); + + QSize landscapeScreenSize = q->visibleSceneSize(Dui::Landscape); + + rootElement->setRotation(newAngle); + if (orientation(angle) == Dui::Landscape) { + rootElement->setPos(0, 0); + rootElement->setTransformOriginPoint(landscapeScreenSize.width() / 2, + landscapeScreenSize.height() / 2); + } else { + rootElement->setPos((landscapeScreenSize.width() - landscapeScreenSize.height()) / 2, + (landscapeScreenSize.height() - landscapeScreenSize.width()) / 2); + rootElement->setTransformOriginPoint(landscapeScreenSize.height() / 2, + landscapeScreenSize.width() / 2); + } +} + +bool DuiSceneManagerPrivate::onApplicationPage(QGraphicsItem *item) +{ + QGraphicsItem *parent = item->parentItem(); + DuiApplicationPage *page = 0; + + if (parent) { + do { + page = dynamic_cast(parent); + if (page) + return true; + parent = parent->parentItem(); + } while (parent != 0); + } + return false; +} + +DuiSceneWindow *DuiSceneManagerPrivate::parentSceneWindow(QGraphicsItem *item) +{ + QGraphicsItem *parent = item->parentItem(); + DuiSceneWindow *parentSceneWindow = 0; + + if (parent) { + do { + parentSceneWindow = dynamic_cast(parent); + if (parentSceneWindow) + break; + parent = parent->parentItem(); + } while (parent != 0); + } + + return parentSceneWindow; +} + +DuiSceneManagerPrivate::InputPanelPlacement DuiSceneManagerPrivate::inputPanelPlacement( + const QRect &inputPanelRect) +{ + Q_Q(DuiSceneManager); + + InputPanelPlacement placement = Invalid; + QRect sceneRect(QPoint(), q->visibleSceneSize()); + + if (inputPanelRect.topLeft() == sceneRect.topLeft() && + inputPanelRect.topRight() == sceneRect.topRight()) { + placement = North; + } else if (inputPanelRect.bottomLeft() == sceneRect.bottomLeft() && + inputPanelRect.bottomRight() == sceneRect.bottomRight()) { + placement = South; + } + + return placement; +} + +void DuiSceneManagerPrivate::moveSceneWindow(DuiSceneWindow *window, const QPoint &translation) +{ + if (window) { + window->moveBy(translation.x(), translation.y()); + sceneWindowTranslation += translation; + } +} + +bool DuiSceneManagerPrivate::validateSceneWindowPreAppearanceStatus(DuiSceneWindow *sceneWindow) +{ + Q_Q(DuiSceneManager); + bool statusOk = true; + + if (sceneWindow->d_func()->shown) { + DuiSceneManager *otherSceneManager = sceneWindow->sceneManager(); + Q_ASSERT(otherSceneManager != 0); + + if (otherSceneManager != q) { + // Cannot be in two scenes simultaneously. + + DuiSceneWindow::DeletionPolicy currentPolicy = sceneWindow->deletionPolicy(); + + otherSceneManager->hideWindowNow(sceneWindow); + + if (currentPolicy == DuiSceneWindow::DestroyWhenDone) { + // Window is gone. + statusOk = false; + } + } else { + // Window is already being shown here. + statusOk = false; + } + } + + return statusOk; +} + +bool DuiSceneManagerPrivate::isOnDisplay() +{ + Q_Q(DuiSceneManager); + + QList viewsList = q->scene()->views(); + DuiWindow *window = 0; + bool result = false; + int i = 0; + + while (result == false && i < viewsList.count()) { + + window = qobject_cast(viewsList[i]); + if (window && window->isOnDisplay()) { + result = true; + } + + i++; + } + + return result; +} + +void DuiSceneManagerPrivate::produceMustBeResolvedDisplayEvent(DuiSceneWindow *sceneWindow) +{ + Q_Q(DuiSceneManager); + + QRectF viewRect(QPointF(0, 0), q->visibleSceneSize()); + DuiOnDisplayChangeEvent displayEvent(DuiOnDisplayChangeEvent::MustBeResolved, viewRect); + + q->scene()->sendEvent(sceneWindow, &displayEvent); +} + +void DuiSceneManagerPrivate::produceFullyOffDisplayEvents(QGraphicsItem *item) +{ + Q_Q(DuiSceneManager); + DuiWidget *duiWidget; + + if (item->isWidget()) { + duiWidget = qobject_cast(static_cast(item)); + if (duiWidget) { + QRectF visibleSceneRect(QPoint(0, 0), q->visibleSceneSize()); + DuiOnDisplayChangeEvent event(DuiOnDisplayChangeEvent::FullyOffDisplay, visibleSceneRect); + q->scene()->sendEvent(duiWidget, &event); + } + } + + QList childItemsList = item->childItems(); + int childItemsCount = childItemsList.count(); + + for (int i = 0; i < childItemsCount; i++) { + produceFullyOffDisplayEvents(childItemsList.at(i)); + } +} + +void DuiSceneManagerPrivate::produceSceneWindowEvent(QEvent::Type type, + DuiSceneWindow *sceneWindow, + bool animatedTransition) +{ + Q_Q(DuiSceneManager); + DuiSceneWindowEvent event(type, sceneWindow, animatedTransition); + QList viewsList = q->scene()->views(); + DuiApplicationWindow *window = 0; + int numberOfViews = viewsList.count(); + + // FIXME: + // Actually sending the event would require overriding customEvent() which + // would mess ABI compatibility. Calling the event handler directly for now + + if (type == DuiSceneWindowEvent::eventTypeAppear()) { + for (int i = 0; i < numberOfViews; i++) { + window = qobject_cast(viewsList[i]); + if (window) { + window->d_func()->sceneWindowAppearEvent(&event); + } + } + + } else if (type == DuiSceneWindowEvent::eventTypeDisappear()) { + for (int i = 0; i < numberOfViews; i++) { + window = qobject_cast(viewsList[i]); + if (window) { + window->d_func()->sceneWindowDisappearEvent(&event); + } + } + } else if (type == DuiSceneWindowEvent::eventTypeDismiss()) { + for (int i = 0; i < numberOfViews; i++) { + window = qobject_cast(viewsList[i]); + if (window) { + window->d_func()->sceneWindowDismissEvent(&event); + } + } + } else { + qFatal("Unknown event type in DuiSceneManagerPrivate::produceSceneWindowEvent"); + } +} + +void DuiSceneManagerPrivate::prepareWindowShow(DuiSceneWindow *window) +{ + Q_Q(DuiSceneManager); + + attachWindow(window); + + setSceneWindowGeometry(window); + DuiSceneLayerEffect *effect = createLayerEffectForWindow(window); + if (effect) { + effect->enableEffect(); + } else { + //add window to scene if not already there + if (scene->items().indexOf(window) == -1) { + window->setParentItem(rootElement); + window->setZValue(zForWindowType(window->windowType())); + } + } + + // Check whether we are trying to show a window while it is in the middle of + // a hide animation. If that's the case, we stop it. + if (window->hideAnimation() && + window->hideAnimation()->state() != QAbstractAnimation::Stopped) { + + window->hideAnimation()->stop(); + QObject::disconnect(window, SIGNAL(windowHidden()), + q, SLOT(_q_windowHideAnimationFinished())); + } + + if (window->windowType() == DuiSceneWindow::NavigationBar) + navBar = qobject_cast(window); + + if (window->windowType() == DuiSceneWindow::EscapeButtonPanel) + escapeButtonPanel = window; + + window->show(); + window->d_func()->shown = true; + + window->d_func()->dismissed = false; + + orientationAnimation->addSceneWindow(window); + + q->connect(window, SIGNAL(windowShown()), SLOT(_q_windowShowAnimationFinished())); + q->connect(window, SIGNAL(repositionNeeded()), SLOT(_q_setSenderGeometry())); +} + +void DuiSceneManagerPrivate::startPageSwitchAnimation(DuiSceneWindow *newPage, + DuiSceneWindow *oldPage, + DuiPageSwitchAnimation::PageTransitionDirection direction) +{ + pageSwitchAnimation->setNewPage(newPage); + pageSwitchAnimation->setOldPage(oldPage); + pageSwitchAnimation->setPageTransitionDirection(direction); + + pageSwitchAnimation->disconnect(SIGNAL(finished())); + QObject::connect(pageSwitchAnimation, SIGNAL(finished()), newPage, SIGNAL(windowShown())); + QObject::connect(pageSwitchAnimation, SIGNAL(finished()), oldPage, SIGNAL(windowHidden())); + + pageSwitchAnimation->start(); + freezeUIForAnimationDuration(pageSwitchAnimation); +} + +void DuiSceneManagerPrivate::appearWindow(DuiSceneWindow *window, + DuiSceneWindow::DeletionPolicy policy, + bool animatedTransition) +{ + if (!validateSceneWindowPreAppearanceStatus(window)) { + return; + } + + Q_ASSERT(window->d_func()->shown == false); + + produceSceneWindowEvent(DuiSceneWindowEvent::eventTypeAppear(), window, + animatedTransition); + prepareWindowShow(window); + + window->d_func()->policy = policy; + + // If the window was hidden using DuiSceneFadeAnimation it will be + // left with an opacity of 0. + // This might bite us back later if someone wants a window + // to appear straight away with, let's say, 0.5 opacity. If that happens + // we will have to think a better way of doing this DuiSceneFadeAnimation + // - Daniel d'Andrada + window->setOpacity(1.0); + + if (window->windowType() == DuiSceneWindow::ApplicationPage) { + + if (currentPage && currentPage != window) { + prepareWindowHide(currentPage); + produceSceneWindowEvent(DuiSceneWindowEvent::eventTypeDisappear(), currentPage, + animatedTransition); + } + + if (animatedTransition) { + startPageSwitchAnimation(window, currentPage, DuiPageSwitchAnimation::LeftToRight); + } else { + if (currentPage && currentPage != window) { + emit currentPage->windowHidden(); + } + emit window->windowShown(); + } + + } else { + if (animatedTransition && window->showAnimation()) { + window->showAnimation()->resetToInitialState(); + window->showAnimation()->start(); + } else { + emit window->windowShown(); + } + } + + if (window->windowType() == DuiSceneWindow::ApplicationPage) + currentPage = window; +} + +void DuiSceneManagerPrivate::prepareWindowHide(DuiSceneWindow *window) +{ + Q_Q(DuiSceneManager); + + QObject::disconnect(window, SIGNAL(repositionNeeded()), + q, SLOT(_q_setSenderGeometry())); + orientationAnimation->removeSceneWindow(window); + window->d_func()->shown = false; + + if (window->d_func()->effect) { + window->d_func()->effect->disableEffect(); + } + + // Check whether we are trying to hide a window while it is in the middle of + // a show animation. If that's the case, we stop it. + if (window->showAnimation() && + window->showAnimation()->state() != QAbstractAnimation::Stopped) { + + window->showAnimation()->stop(); + QObject::disconnect(window, SIGNAL(windowShown()), + q, SLOT(_q_windowShowAnimationFinished())); + } + + q->connect(window, SIGNAL(windowHidden()), SLOT(_q_windowHideAnimationFinished())); +} + +void DuiSceneManagerPrivate::disappearWindow(DuiSceneWindow *window, + bool animatedTransition) +{ + Q_Q(DuiSceneManager); + + produceSceneWindowEvent(DuiSceneWindowEvent::eventTypeDisappear(), window, + animatedTransition); + prepareWindowHide(window); + + if (animatedTransition && window->hideAnimation()) { + window->hideAnimation()->start(); + } else { + emit window->windowHidden(); + q->scene()->update(); // is this really needed? + } +} + +void DuiSceneManagerPrivate::freezeUIForAnimationDuration(QAbstractAnimation *animation) +{ + Q_Q(DuiSceneManager); + + if (animation->state() == QAbstractAnimation::Running) { + //rootElement->setEnabled(false); + QObject::connect(animation, SIGNAL(finished()), q, SLOT(_q_unFreezeUI())); + } +} + +void DuiSceneManagerPrivate::dismissWindow(DuiSceneWindow *window, + bool animatedTransition) +{ + Q_Q(DuiSceneManager); + + produceSceneWindowEvent(DuiSceneWindowEvent::eventTypeDismiss(), window, + animatedTransition); + prepareWindowHide(window); + + window->d_func()->dismissed = true; + + if (window->windowType() == DuiSceneWindow::ApplicationPage) { + pageHistory->removeLast(); + prepareWindowShow(pageHistory->last()); + produceSceneWindowEvent(DuiSceneWindowEvent::eventTypeAppear(), pageHistory->last(), + animatedTransition); + + if (animatedTransition) { + startPageSwitchAnimation(pageHistory->last(), window, DuiPageSwitchAnimation::RightToLeft); + } else { + emit window->windowHidden(); + emit pageHistory->last()->windowShown(); + } + + currentPage = pageHistory->last(); + + } else if (animatedTransition && window->hideAnimation()) { // Fallback to legacy hide anim. + window->hideAnimation()->start(); + } else { + emit window->windowHidden(); + q->scene()->update(); // is this really needed? + } +} + +void DuiSceneManagerPrivate::_q_inputPanelOpened() +{ + Q_Q(DuiSceneManager); + + Q_ASSERT(focusedInputWidget); + if (!focusedInputWidget) { + return; + } + + const bool widgetOnPage = onApplicationPage(focusedInputWidget); + if (navBar && widgetOnPage) { + navBarHidden = true; + q->hideWindow(navBar); + } + if (escapeButtonPanel && (widgetOnPage || (navBar && navBar->isAncestorOf(focusedInputWidget)))) { + escapeButtonHidden = true; + q->hideWindow(escapeButtonPanel); + } + + DuiInputMethodState *inputMethodState = DuiInputMethodState::instance(); + _q_relocateWindowByInputPanel(inputMethodState->inputMethodArea()); + QObject::connect(inputMethodState, SIGNAL(inputMethodAreaChanged(QRect)), + q, SLOT(_q_relocateWindowByInputPanel(QRect))); +} + +void DuiSceneManagerPrivate::_q_inputPanelClosed() +{ + Q_Q(DuiSceneManager); + + if (!pendingSIPClose) { + return; + } + + focusedInputWidget = 0; + + if (navBar && navBarHidden) { + q->showWindow(navBar); + navBarHidden = false; + } + if (escapeButtonPanel && escapeButtonHidden) { + q->showWindow(escapeButtonPanel); + escapeButtonHidden = false; + } + + QObject::disconnect(DuiInputMethodState::instance(), + SIGNAL(inputMethodAreaChanged(QRect)), + q, SLOT(_q_relocateWindowByInputPanel(QRect))); + _q_restoreSceneWindow(); +} + +DuiSceneManager::DuiSceneManager(DuiScene *scene, QObject *parent) : + QObject(parent), d_ptr(new DuiSceneManagerPrivate) +{ + Q_D(DuiSceneManager); + + if (scene == 0) + scene = new DuiScene(this); + + d->q_ptr = this; + d->init(scene); + d->scene->d_ptr->setSceneManager(this); +} + +DuiSceneManager::~DuiSceneManager() +{ + Q_D(DuiSceneManager); + + delete d; +} + +DuiScene *DuiSceneManager::scene() +{ + Q_D(DuiSceneManager); + + return d->scene; +} + +void DuiSceneManager::showWindow(DuiSceneWindow *window, DuiSceneWindow::DeletionPolicy policy) +{ + Q_D(DuiSceneManager); + + d->appearWindow(window, policy, true); +} + +void DuiSceneManager::showWindowNow(DuiSceneWindow *window, DuiSceneWindow::DeletionPolicy policy) +{ + Q_D(DuiSceneManager); + d->appearWindow(window, policy, false); +} + +int DuiSceneManager::execDialog(DuiDialog *dialog) +{ + QEventLoop eventLoop; + QPointer dialog_ptr = dialog; + connect(dialog, SIGNAL(finished(int)), &eventLoop, SLOT(quit())); + connect(dialog, SIGNAL(destroyed()), &eventLoop, SLOT(quit())); + + //TODO: Figure better workaround for this (or ask Qt to + // fix this for us). + // + //Launching of a modal scene window during mouse event handling + //(mouse press/release callbacks etc.) will block the mainloop and + //might break the event handling. + + //Release mouse focus from the current mousegrabber, so that the first + //mouse event wont be sent to wrong widget. This is needed if a + //modal scene window was executed during mouse release event. + QGraphicsItem *g = scene()->mouseGrabberItem(); + if (g) + g->ungrabMouse(); + + showWindow(dialog); + eventLoop.exec(); + + // use QPointer in case of the dialog being deleted in the meantime + if (dialog_ptr) + return dialog->standardButton(dialog->clickedButton()); + + return DuiDialog::Rejected; +} + +void DuiSceneManager::hideWindow(DuiSceneWindow *window) +{ + Q_D(DuiSceneManager); + d->disappearWindow(window, true); +} + +void DuiSceneManager::hideWindowNow(DuiSceneWindow *window) +{ + Q_D(DuiSceneManager); + d->disappearWindow(window, false); +} + +void DuiSceneManager::closeWindow(DuiSceneWindow *window) +{ + Q_D(DuiSceneManager); + d->dismissWindow(window, true); +} + +void DuiSceneManager::closeWindowNow(DuiSceneWindow *window) +{ + Q_D(DuiSceneManager); + d->dismissWindow(window, false); +} + +bool DuiSceneManager::eventFilter(QObject *watched, QEvent *event) +{ + Q_UNUSED(watched); + + event->ignore(); + return false; +} + +void DuiSceneManager::requestSoftwareInputPanel(QGraphicsWidget *inputWidget) +{ + Q_D(DuiSceneManager); + + if (inputWidget) { + + d->focusedInputWidget = inputWidget; + + QInputContext *inputContext = qApp->inputContext(); + if (!inputContext) { + return; + } + + // Calling _q_relocateWindowByInputPanel can change the scene window position and it is + // common that we got here with mousePressEvent in the backtrace. Moving the + // scene window now can cause mouse press to not hit its target (which causes focus lost). + // Because of this we shall visit event loop first. + // Also, it is just a mere assumption that SIP will be opened in the first place. + // Connecting a signal from DuiInputContext to DuiSceneManager is intentionally left out. + d->pendingSIPClose = false; + QTimer::singleShot(0, this, SLOT(_q_inputPanelOpened())); + + QWidget *focusWidget = QApplication::focusWidget(); + + if (focusWidget) { + // FIXME: this is a temporary workaround because of the + // QGraphicsView unable to correctly update the attribute. + // We're waiting for fixing this on Qt side. + focusWidget->setAttribute(Qt::WA_InputMethodEnabled, true); + //enforce update if focus is moved from one DuiTextEdit to other + //if attribute WA_InputMethodEnabled is not set then Qt will call + //setFocusWidget automatically + inputContext->setFocusWidget(focusWidget); + } + + //FIXME: verify if application style allows SIP usage + QEvent request(QEvent::RequestSoftwareInputPanel); + inputContext->filterEvent(&request); + } +} + +void DuiSceneManager::closeSoftwareInputPanel() +{ + Q_D(DuiSceneManager); + + QInputContext *inputContext = qApp->inputContext(); + + // Tell input context we want to close the SIP. + if (!inputContext) { + return; + } + + //FIXME: verify if application style allows SIP usage + QEvent close(QEvent::CloseSoftwareInputPanel); + inputContext->filterEvent(&close); + inputContext->reset(); + + // There is no general way of tracking when the SIP actually closes. It might not + // close at all, for example, in a situation where focus is changed between widgets + // that both wants a SIP. DuiInputContext has its own logic for this because it cannot + // rely that it's running on a DuiApplication. + // Our guess now is that SIP will be closed after some delay. + d->pendingSIPClose = true; + QTimer::singleShot(SoftwareInputPanelHideTimer, this, + SLOT(_q_inputPanelClosed())); +} + +void DuiSceneManager::setOrientationAngle(Dui::OrientationAngle angle, + Dui::OrientationChangeMode mode) +{ + Q_D(DuiSceneManager); + + if (mode == Dui::AnimatedOrientationChange) + d->rotateToAngle(angle); + else + d->setOrientationAngleWithoutAnimation(angle); +} + +Dui::Orientation DuiSceneManager::orientation() const +{ + Q_D(const DuiSceneManager); + + return d->orientation(d->newAngle); +} + +Dui::OrientationAngle DuiSceneManager::orientationAngle() const +{ + Q_D(const DuiSceneManager); + + return d->newAngle; +} + +QSize DuiSceneManager::visibleSceneSize(Dui::Orientation orientation) const +{ + QSize s; + + if (orientation == Dui::Landscape) { + s = DuiDeviceProfile::instance()->resolution(); + } else { + s = QSize(DuiDeviceProfile::instance()->resolution().height(), + DuiDeviceProfile::instance()->resolution().width()); + } + + return s; +} + +QSize DuiSceneManager::visibleSceneSize() const +{ + return visibleSceneSize(orientation()); +} + +#include "moc_duiscenemanager.cpp" diff --git a/src/scene/duiscenemanager.h b/src/scene/duiscenemanager.h new file mode 100644 index 000000000..a64113003 --- /dev/null +++ b/src/scene/duiscenemanager.h @@ -0,0 +1,250 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISCENEMANAGER_H +#define DUISCENEMANAGER_H + +#include "duiexport.h" + +#include +#include +#include +#include + +#include "duinamespace.h" + +class DuiSceneManagerPrivate; +class DuiScene; +class DuiSceneLayerEffect; +class DuiDialog; +class QGraphicsWidget; + +/*! + * \class DuiSceneManager + * \brief DuiSceneManager manages the DuiSceneWindows present in a DuiScene. + * + * DuiSceneManager ensures that the DuiSceneWindows of a DuiScene are correctly + * positioned and stacked, similarly to what a window manager does for top level + * windows in a tradicional windowing system. + * + * DuiSceneManager also orchestrates DuiSceneWindow's transitions such as + * appearance, disappearance and display orientation changes (e.g., from portrait + * to landscape). + * + * \sa DuiSceneWindow + */ +class DUI_EXPORT DuiSceneManager : public QObject +{ + Q_OBJECT + friend class DuiSceneWindow; +#ifdef UNIT_TEST + friend class Ut_DuiSceneManager; +#endif + +public: + + /*! + * Constructor of the DuiSceneManager class, constructs the manager for the given \a scene. + * + * \note You normally don't have to create an instance of this class, + * the DuiApplicationWindow class already provides the scene manager. + * + * \param scene Scene to be used. If 0, scene manager will automatically + * create his own DuiScene. + * + */ + DuiSceneManager(DuiScene *scene = 0, QObject *parent = 0); + + /*! + * Destructor of the DuiSceneManager class. + */ + virtual ~DuiSceneManager(); + + /*! + * Get scene instance that was created by this scene manager. + * \return Returns the scene that is managed by this scene manager. + */ + DuiScene *scene(); + + /*! + * Returns the current orientation. It's a convenience method with + * which you can get the orientation without querying the application window. + */ + Dui::Orientation orientation() const; + + /*! + * Returns the current orientation angle. It's a convenience method with + * which you can get the orientation angle without querying the application window. + */ + Dui::OrientationAngle orientationAngle() const; + + /*! + * Returns the visible scene size in \a orientation. It's a convenience method with + * which you can get the scene size without querying the application window. + */ + QSize visibleSceneSize(Dui::Orientation orientation) const; + + /*! + * Returns the visible scene size in current orientation. It's a convenience method with + * which you can get the scene size without querying the application window. + */ + QSize visibleSceneSize() const; + +public Q_SLOTS: + /*! + * Sets the orientation to \a angle. The \a mode can be set to Dui::ImmediateOrientationChange + * to disable orientation animation. + */ + void setOrientationAngle(Dui::OrientationAngle angle, + Dui::OrientationChangeMode mode = Dui::AnimatedOrientationChange); + + /*! + * Sends a request to the application's input context to open a software input + * panel (e.g. the virtual keyboard) for the given \a inputWidget. Depending on + * a placement of the \a inputWidget scene manager adjusts the scene by + * temporarily hiding the escape button and navigation bar. + * \param inputWidget A widget that requests the software input panel + * \sa closeSoftwareInputPanel + */ + void requestSoftwareInputPanel(QGraphicsWidget *inputWidget); + + /*! + * Sends a request to the application's input context to close a software input + * panel. Restores temporarily hidden escape button and navigation bar. + * \sa requestSoftwareInputPanel + */ + void closeSoftwareInputPanel(); + + /*! + * Attaches a \a window to the scene manager and shows it using associated animation. + * According to the given \a policy, a window can be kept or destroyed after hiding. + * + * \note Normally you don't have to call this method explicitly. DuiSceneWindow::appear() + * calls this method for you. + */ + void showWindow(DuiSceneWindow *window, DuiSceneWindow::DeletionPolicy policy = DuiSceneWindow::KeepWhenDone); + + /*! + * Attaches a \a window to the scene manager and shows it without animations (instantly). + * According to the given \a policy, a window can be kept or destroyed after hiding. + * + * \note Normally you don't have to call this method explicitly. DuiSceneWindow::appearNow() + * calls this method for you. + */ + void showWindowNow(DuiSceneWindow *window, DuiSceneWindow::DeletionPolicy policy = DuiSceneWindow::KeepWhenDone); + + /*! + * Shows a modal \a dialog using associated animation and returns its result code. + * + * \note Normally you don't have to call this method explicitly. + * DuiDialog::exec() calls this method for you. + */ + int execDialog(DuiDialog *dialog); + + /*! + * Hides a \a window using associated animation and detaches it from the scene manager. + * + * \note Normally you don't have to call this method explicitly. DuiSceneWindow::disappear() + * calls this method for you. + */ + void hideWindow(DuiSceneWindow *window); + + /*! + * Hides a \a window without animations (instantly) and detaches it from the scene manager. + * + * \note Normally you don't have to call this method explicitly. DuiSceneWindow::disappearNow() + * calls this method for you. + */ + void hideWindowNow(DuiSceneWindow *window); + + /*! + * Closes a \a window using associated animation and detaches it from the scene manager. + * + * \note Normally you don't have to call this method explicitly. DuiSceneWindow::dismiss() + * calls this method for you. + */ + void closeWindow(DuiSceneWindow *window); + + /*! + * Closes a \a window without animations (instantly) and detaches it from the scene manager. + * + * \note Normally you don't have to call this method explicitly. DuiSceneWindow::dismissNow() + * calls this method for you. + */ + void closeWindowNow(DuiSceneWindow *window); + +Q_SIGNALS: + /*! \brief Signal emitted before scene geometry is changed for a rotation + * + * This is for widgets that need to react when the orientation is about to change, + * and is emitted before the scene geometry is changed. + * + * This is the preferred way for the widgets to + * hook to orientation change. + * + * \param orientation New orientation of the viewport + */ + void orientationAboutToChange(const Dui::Orientation &orientation); + + /*! \brief Signal emitted after scene geometry has changed for a rotation + * + * This is for widgets that need to react when the orientation is about to change, + * and is emitted after the scene geometry has changed and the rotation animation + * is about to start. + * + * Note that this is emitted at the start of the rotation animation. + * + * This is the preferred way for the widgets to hook to orientation change. + * + * \param orientation New orientation of the viewport + */ + void orientationChanged(const Dui::Orientation &orientation); + + /*! + * This signal is emitted when the rotation animation has finished. + * + * \param orientation New orientation of the viewport + */ + void orientationChangeFinished(const Dui::Orientation &orientation); + +protected: + //! \internal + DuiSceneManagerPrivate *const d_ptr; + //! \internal_end + + //! \reimp + virtual bool eventFilter(QObject *watched, QEvent *event); + //! \reimp_end + +private: + Q_DECLARE_PRIVATE(DuiSceneManager) + + Q_PRIVATE_SLOT(d_func(), void _q_windowShowAnimationFinished()) + Q_PRIVATE_SLOT(d_func(), void _q_windowHideAnimationFinished()) + Q_PRIVATE_SLOT(d_func(), void _q_setSenderGeometry()) + Q_PRIVATE_SLOT(d_func(), void _q_changeGlobalOrientation()) + Q_PRIVATE_SLOT(d_func(), void _q_emitOrientationChangeFinished()) + Q_PRIVATE_SLOT(d_func(), void _q_restoreSceneWindow()) + Q_PRIVATE_SLOT(d_func(), void _q_relocateWindowByInputPanel(const QRect &inputPanelRect)) + Q_PRIVATE_SLOT(d_func(), void _q_inputPanelOpened()) + Q_PRIVATE_SLOT(d_func(), void _q_inputPanelClosed()) + Q_PRIVATE_SLOT(d_func(), void _q_unFreezeUI()) +}; + +#endif diff --git a/src/scene/duiscenemanager_p.h b/src/scene/duiscenemanager_p.h new file mode 100644 index 000000000..27860972e --- /dev/null +++ b/src/scene/duiscenemanager_p.h @@ -0,0 +1,172 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISCENEMANAGER_P_H +#define DUISCENEMANAGER_P_H + +#include + +#include "duinamespace.h" +#include "duiscenewindow.h" +#include +#include "duipageswitchanimation.h" + +class DuiScene; +class DuiSceneWindow; +class DuiSceneLayerEffect; +class DuiSceneManager; +class DuiNavigationBar; +class DuiBasicOrientationAnimation; +class DuiPageSwitchAnimation; +class DuiWindow; + +class QAbstractAnimation; +class QGraphicsWidget; +class QTimeLine; +class QPointF; + +class DuiSceneManagerPrivate +{ + Q_DECLARE_PUBLIC(DuiSceneManager) + +public: + + void init(DuiScene *scene); + virtual ~DuiSceneManagerPrivate(); + + enum WindowTypeZ { + PlainSceneWindow = 0, + ApplicationPage = PlainSceneWindow, // DuiApplicationPage + ApplicationMenu = 500, // DuiApplicationMenu + NavigationBar = 1000, // DuiNavigationBar + DockWidget = NavigationBar, // DuiDockWidget + EscapeButtonPanel = 2000, // DuiEscapeButtonPanel + Dialog = 3000, // DuiDialog + MessageBox = Dialog, // DuiMessageBox + ObjectMenu = Dialog, + ModalSceneWindow = Dialog, // DuiModalSceneWindow + PopupList = 4000, // DuiPopupList + NotificationInformation = 5000, // DuiNotification - Information + NotificationEvent = NotificationInformation, // DuiNotification - Event + Overlay = 6000, // DuiOverlay + Completer = Overlay, // DuiCompleter + HomeButtonPanel = 7000 // DuiHomeButtonPanel + }; + + enum InputPanelPlacement { + North, + South, + Invalid + }; + + int zForWindowType(DuiSceneWindow::WindowType windowType); + DuiSceneLayerEffect *createLayerEffectForWindow(DuiSceneWindow *window); + + Dui::Orientation orientation(Dui::OrientationAngle angle) const; + + QPointF calculateSceneWindowPosition(DuiSceneWindow *window); + void setSceneWindowGeometry(DuiSceneWindow *window); + void setSceneWindowGeometries(); + void rotateToAngle(Dui::OrientationAngle newAngle); + void setOrientationAngleWithoutAnimation(Dui::OrientationAngle newAngle); + + void attachWindow(DuiSceneWindow *window); + void detachWindow(DuiSceneWindow *window); + + bool onApplicationPage(QGraphicsItem *item); + DuiSceneWindow *parentSceneWindow(QGraphicsItem *item); + InputPanelPlacement inputPanelPlacement(const QRect &inputPanelRect); + void moveSceneWindow(DuiSceneWindow *window, const QPoint &translation); + + bool validateSceneWindowPreAppearanceStatus(DuiSceneWindow *sceneWindow); + + bool isOnDisplay(); + void produceMustBeResolvedDisplayEvent(DuiSceneWindow *sceneWindow); + void produceFullyOffDisplayEvents(QGraphicsItem *item); + void produceSceneWindowEvent(QEvent::Type type, DuiSceneWindow *sceneWindow, + bool animatedTransition); + + void freezeUIForAnimationDuration(QAbstractAnimation *animation); + + void prepareWindowShow(DuiSceneWindow *window); + + void appearWindow(DuiSceneWindow *window, + DuiSceneWindow::DeletionPolicy policy, + bool animatedTransition); + + void prepareWindowHide(DuiSceneWindow *window); + + void disappearWindow(DuiSceneWindow *window, + bool animatedTransition); + + void dismissWindow(DuiSceneWindow *window, + bool animatedTransition); + + void startPageSwitchAnimation(DuiSceneWindow *newPage, + DuiSceneWindow *oldPage, + DuiPageSwitchAnimation::PageTransitionDirection direction); + + void _q_setSenderGeometry(); + void _q_changeGlobalOrientation(); + void _q_emitOrientationChangeFinished(); + void _q_pageShowAnimationFinished(); + void _q_windowShowAnimationFinished(); + void _q_windowHideAnimationFinished(); + void _q_restoreSceneWindow(); + void _q_relocateWindowByInputPanel(const QRect &inputPanelRect); + + //! Prepares current window for SIP. + void _q_inputPanelOpened(); + + //! Restores the current window state after SIP is closed. + void _q_inputPanelClosed(); + + void _q_unFreezeUI(); + +public: + + DuiScene *scene; + + QGraphicsWidget *rootElement; + DuiBasicOrientationAnimation *orientationAnimation; + DuiPageSwitchAnimation *pageSwitchAnimation; + + QList *windows; + QList *pageHistory; + + Dui::OrientationAngle angle; + Dui::OrientationAngle newAngle; + + DuiNavigationBar *navBar; + DuiSceneWindow *escapeButtonPanel; + DuiSceneWindow *currentPage; + bool navBarHidden; + bool escapeButtonHidden; + + QGraphicsItem *focusedInputWidget; + DuiSceneWindow *alteredSceneWindow; + QPoint sceneWindowTranslation; + static const int KeyboardSpacing; + + bool pendingSIPClose; + + DuiSceneManager *q_ptr; +}; + +#endif diff --git a/src/scene/duiscenewindowanimator.cpp b/src/scene/duiscenewindowanimator.cpp new file mode 100644 index 000000000..38ef51736 --- /dev/null +++ b/src/scene/duiscenewindowanimator.cpp @@ -0,0 +1,313 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiscenewindowanimator.h" + +#include +#include "duiscenelayereffect.h" +#include "duiscenewindow.h" +#include "duiscenemanager.h" +#include "duiscene.h" +#include "duiscenewindowanimatorstyle.h" +#include "duitheme.h" + +class DuiSceneWindowAnimatorPrivate +{ + Q_DECLARE_PUBLIC(DuiSceneWindowAnimator) + +public: + void startTimeline(QTimeLine::Direction direction, int transitionDuration, bool transitionFade); + bool fade; + enum TransitionType { + None, + MoveUp, + MoveDown, + MoveLeft, + MoveRight, + MoveTo, + Expand, + Shrink + }; + TransitionType transition; + + void setupWindow(); + void setupEffect(bool forward, const QString &transitionType); +protected: + DuiSceneWindowAnimator *q_ptr; +private: // public for DuiSceneWindowAnimator + DuiSceneWindow *window; + DuiSceneLayerEffect *effect; + QTimeLine timeline; + const DuiSceneWindowAnimatorStyle *style; + QString effectType; + + QPointF startPosition; + QPointF endPosition; +}; + +void DuiSceneWindowAnimatorPrivate::startTimeline(QTimeLine::Direction direction, int transitionDuration, bool transitionFade) +{ + fade = transitionFade; + + timeline.setDirection(direction); + timeline.setDuration(transitionDuration); + timeline.setUpdateInterval(30); + timeline.start(); +} + +DuiSceneWindowAnimator::DuiSceneWindowAnimator(DuiSceneWindow *window, DuiSceneLayerEffect *effect) : + d_ptr(new DuiSceneWindowAnimatorPrivate) +{ + Q_D(DuiSceneWindowAnimator); + d->window = window; + d->effect = effect; + d->style = NULL; + d->q_ptr = this; + + DuiSceneWindow::WindowType windowType = window->windowType(); + switch (windowType) { + case DuiSceneWindow::Dialog: + d->effectType = "messagebox"; + break; + case DuiSceneWindow::Notification: + d->effectType = window->viewType(); + break; + case DuiSceneWindow::PopupList: + d->effectType = "popuplist"; + break; + default: + d->effectType = ""; + break; + } + + connect(&d->timeline, SIGNAL(valueChanged(qreal)), this, SLOT(windowAnimating(qreal))); + connect(&d->timeline, SIGNAL(finished()), this, SLOT(windowAnimationDone())); +} + +DuiSceneWindowAnimator::~DuiSceneWindowAnimator() +{ + Q_D(DuiSceneWindowAnimator); + DuiTheme::releaseStyle(d->style); + delete d_ptr; +} + +void DuiSceneWindowAnimator::updateStyle() +{ + Q_D(DuiSceneWindowAnimator); + const DuiSceneWindowAnimatorStyle *style = + dynamic_cast( + DuiTheme::style("DuiSceneWindowAnimatorStyle", QString(""), d->effectType, QString(""), Dui::Landscape)); + + if (d->style != style) { + DuiTheme::releaseStyle(d->style); + d->style = style; + styleUpdated(); + } else { + DuiTheme::releaseStyle(style); + } +} + +void DuiSceneWindowAnimator::styleUpdated() +{ + Q_D(DuiSceneWindowAnimator); + if (d->window) { + // TODO: check if these are needed, when orientation change is revisited + + QSizeF size = d->window->effectiveSizeHint(Qt::PreferredSize, QSizeF(-1, -1)); + d->window->resize(size); + } + if (d->effect) + d->effect->resize(DuiSceneManager::instance()->visibleSceneSize()); +} + +void DuiSceneWindowAnimator::windowAnimationDone() +{ + Q_D(DuiSceneWindowAnimator); + + if (d->timeline.direction() == QTimeLine::Forward) { + emit windowAnimationCompleted(this, true); + } else { + if (d->window) + d->window->hide(); + emit windowAnimationCompleted(this, false); + } +} + +void DuiSceneWindowAnimator::setWindow(DuiSceneWindow *window) +{ + Q_D(DuiSceneWindowAnimator); + d->window = window; +} + +DuiSceneWindow *DuiSceneWindowAnimator::window() const +{ + Q_D(const DuiSceneWindowAnimator); + return d->window; +} + +DuiSceneLayerEffect *DuiSceneWindowAnimator::effect() const +{ + Q_D(const DuiSceneWindowAnimator); + return d->effect; +} + +void DuiSceneWindowAnimator::forward() +{ + Q_D(DuiSceneWindowAnimator); + + d->setupWindow(); + d->setupEffect(true, d->style->transitionInType()); + + if (d->effect) + d->effect->setOpacity(0.0); + + d->startTimeline(QTimeLine::Forward, d->style->transitionInDuration(), d->style->transitionInFade()); +} + +void DuiSceneWindowAnimator::forwardNow() +{ + Q_D(DuiSceneWindowAnimator); + d->setupWindow(); + d->setupEffect(true, d->style->transitionInType()); + d->timeline.setDirection(QTimeLine::Forward); + windowAnimating(1.0); + windowAnimationDone(); +} + +void DuiSceneWindowAnimator::backward() +{ + Q_D(DuiSceneWindowAnimator); + + d->setupWindow(); + d->setupEffect(false, d->style->transitionOutType()); + + d->startTimeline(QTimeLine::Backward, d->style->transitionOutDuration(), d->style->transitionOutFade()); +} + +void DuiSceneWindowAnimator::backwardNow() +{ + Q_D(DuiSceneWindowAnimator); + d->setupWindow(); + d->setupEffect(false, d->style->transitionOutType()); + d->timeline.setDirection(QTimeLine::Backward); + windowAnimating(0.0); + windowAnimationDone(); +} + +void DuiSceneWindowAnimatorPrivate::setupWindow() +{ + if (window) { + QSizeF size = window->effectiveSizeHint(Qt::PreferredSize, QSizeF(-1, -1)); + window->resize(size); + } +} + +void DuiSceneWindowAnimatorPrivate::setupEffect(bool forward, const QString &transitionType) +{ + if (effect != NULL) { + DuiSceneManager::instance()->scene()->setActiveWindow(effect); + effect->resize(DuiSceneManager::instance()->visibleSceneSize()); + + if (transitionType == "move.up") { + transition = MoveUp; + if (forward) { + window->setPos(QPointF(window->pos().x(), DuiSceneManager::instance()->visibleSceneSize().height())); + } + endPosition = QPointF(window->pos().x(), window->pos().y() >= DuiSceneManager::instance()->visibleSceneSize().height() ? DuiSceneManager::instance()->visibleSceneSize().height() - window->size().height() : -window->size().height()); + } else if (transitionType == "move.down") { + transition = MoveDown; + if (forward) { + window->setPos(QPointF(window->pos().x(), -window->size().height())); + } + endPosition = QPointF(window->pos().x(), window->pos().y() < 0 ? 0 : DuiSceneManager::instance()->visibleSceneSize().height()); + } else if (transitionType == "move.left") { + transition = MoveLeft; + if (forward) { + window->setPos(QPointF(DuiSceneManager::instance()->visibleSceneSize().width(), window->pos().y())); + } + endPosition = QPointF(window->pos().x() >= DuiSceneManager::instance()->visibleSceneSize().width() ? DuiSceneManager::instance()->visibleSceneSize().width() - window->size().width() : -window->size().width(), window->pos().y()); + } else if (transitionType == "move.right") { + transition = MoveRight; + if (forward) { + window->setPos(QPointF(-window->size().width(), window->pos().y())); + } + endPosition = QPointF(window->pos().x() < 0 ? 0 : DuiSceneManager::instance()->visibleSceneSize().width(), window->pos().y()); + } else if (transitionType == "move.to") { + transition = MoveTo; + endPosition = forward ? style->transitionInDestination() : style->transitionOutDestination(); + } else if (transitionType == "expand") { + transition = Expand; + endPosition = window->pos(); + } else if (transitionType == "shrink") { + transition = Shrink; + endPosition = window->pos(); + } else { + transition = None; + endPosition = window->pos(); + } + + startPosition = window->pos(); + } +} + +void DuiSceneWindowAnimator::windowAnimating(qreal value) +{ + Q_D(DuiSceneWindowAnimator); + + if (d->effect) { + if (value == 0) + d->effect->setOpacity(0); + else if (value == 1 || !d->fade) + d->effect->setOpacity(1); + else + d->effect->setOpacity(value); + } + + if (!d->window) return; + + switch (d->transition) { + case DuiSceneWindowAnimatorPrivate::MoveUp: + case DuiSceneWindowAnimatorPrivate::MoveDown: + case DuiSceneWindowAnimatorPrivate::MoveLeft: + case DuiSceneWindowAnimatorPrivate::MoveRight: + case DuiSceneWindowAnimatorPrivate::MoveTo: + if (d->timeline.direction() == QTimeLine::Forward) { + d->window->setPos(d->startPosition.x() + (d->endPosition.x() - d->startPosition.x()) * value, + d->startPosition.y() + (d->endPosition.y() - d->startPosition.y()) * value); + } else { + d->window->setPos(d->startPosition.x() + (d->endPosition.x() - d->startPosition.x()) *(1 - value), + d->startPosition.y() + (d->endPosition.y() - d->startPosition.y()) *(1 - value)); + } + break; + case DuiSceneWindowAnimatorPrivate::Expand: + if (d->timeline.direction() == QTimeLine::Forward) { + QSizeF size = d->window->effectiveSizeHint(Qt::PreferredSize, QSizeF(-1, -1)); + d->window->resize(size.width(), size.height() * value); + } + break; + case DuiSceneWindowAnimatorPrivate::Shrink: + if (d->timeline.direction() == QTimeLine::Backward) { + QSizeF size = d->window->effectiveSizeHint(Qt::PreferredSize, QSizeF(-1, -1)); + d->window->resize(size.width(), size.height() * value); + } + break; + default: //Do nothing + break; + } +} diff --git a/src/scene/duiscenewindowanimator.h b/src/scene/duiscenewindowanimator.h new file mode 100644 index 000000000..03aa427de --- /dev/null +++ b/src/scene/duiscenewindowanimator.h @@ -0,0 +1,76 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +// Make doxygen skip this internal class +//! \cond +#ifndef DUISCENEWINDOWANIMATOR_H +#define DUISCENEWINDOWANIMATOR_H + +#include + +class DuiSceneWindow; +class DuiSceneLayerEffect; +class DuiSceneWindowAnimatorPrivate; + +class DuiSceneWindowAnimator : public QObject +{ + Q_OBJECT + +public: + + DuiSceneWindowAnimator(DuiSceneWindow *window, DuiSceneLayerEffect *effect); + virtual ~DuiSceneWindowAnimator(); + + void updateStyle(); + + /*! + * Set the SceneWindow pointer + */ + void setWindow(DuiSceneWindow *window); + + DuiSceneWindow *window() const; + + DuiSceneLayerEffect *effect() const; + + void forward(); + void backward(); + + void forwardNow(); + void backwardNow(); + +Q_SIGNALS: + void windowAnimationCompleted(DuiSceneWindowAnimator *, bool visible); + +protected: + virtual void styleUpdated(); + + DuiSceneWindowAnimatorPrivate *const d_ptr; + + +private Q_SLOTS: + void windowAnimationDone(); + void windowAnimating(qreal); + +private: + Q_DECLARE_PRIVATE(DuiSceneWindowAnimator) +}; + +#endif +//! \endcond + diff --git a/src/scene/scene.pri b/src/scene/scene.pri new file mode 100644 index 000000000..e16c672f0 --- /dev/null +++ b/src/scene/scene.pri @@ -0,0 +1,19 @@ +############################################################################### +# DuiTheme module +# This module contains all classes that handle style and CSS support. +############################################################################### +SCENE_SRC_DIR=./scene +INCLUDEPATH+=./scene +HEADERS += $$SCENE_SRC_DIR/duiscene.h \ + $$SCENE_SRC_DIR/duiscenelayereffect.h \ + $$SCENE_SRC_DIR/duiscenelayereffect_p.h \ + $$SCENE_SRC_DIR/duiscenemanager.h \ + $$SCENE_SRC_DIR/duiscenemanager_p.h \ +# $$SCENE_SRC_DIR/duiscenewindowanimator.h \ + $$SCENE_SRC_DIR/scenelayereffectviews/duiscenelayereffectdimview.h + +SOURCES += $$SCENE_SRC_DIR/duiscene.cpp \ + $$SCENE_SRC_DIR/duiscenelayereffect.cpp \ + $$SCENE_SRC_DIR/duiscenemanager.cpp \ +# $$SCENE_SRC_DIR/duiscenewindowanimator.cpp \ + $$SCENE_SRC_DIR/scenelayereffectviews/duiscenelayereffectdimview.cpp diff --git a/src/scene/scenelayereffectviews/duiscenelayereffectdimview.cpp b/src/scene/scenelayereffectviews/duiscenelayereffectdimview.cpp new file mode 100644 index 000000000..c99d25375 --- /dev/null +++ b/src/scene/scenelayereffectviews/duiscenelayereffectdimview.cpp @@ -0,0 +1,89 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include + +#include "duiscenelayereffectdimview.h" + +#include "duiscenewindowview_p.h" +#include "duiviewcreator.h" +#include "duiscenelayereffect.h" +#include "duiscenelayereffectmodel.h" + +//! \internal +class DuiSceneLayerEffectDimViewPrivate : public DuiSceneWindowViewPrivate +{ +public: + DuiSceneLayerEffect *controller; + QPropertyAnimation *animation; +}; +//! \internal_end + +DuiSceneLayerEffectDimView::DuiSceneLayerEffectDimView(DuiSceneLayerEffect *controller) : + DuiSceneWindowView(*new DuiSceneLayerEffectDimViewPrivate, controller) +{ + Q_D(DuiSceneLayerEffectDimView); + d->controller = controller; + d->controller->setFlag(QGraphicsItem::ItemDoesntPropagateOpacityToChildren, true); + + d->animation = new QPropertyAnimation(d->controller, "opacity", this); + d->animation->setStartValue(0.0f); +} + +DuiSceneLayerEffectDimView::~DuiSceneLayerEffectDimView() +{ +} + +void DuiSceneLayerEffectDimView::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + Q_UNUSED(widget); + Q_UNUSED(option); + + painter->fillRect(boundingRect(), QColor(0, 0, 0)); +} + +QRectF DuiSceneLayerEffectDimView::boundingRect() const +{ + Q_D(const DuiSceneLayerEffectDimView); + return QRectF(QPointF(0, 0), d->controller->size()); +} + +void DuiSceneLayerEffectDimView::updateData(const QList& modifications) +{ + Q_D(DuiSceneLayerEffectDimView); + + DuiSceneWindowView::updateData(modifications); + const char *member; + foreach(member, modifications) { + if (member == DuiSceneLayerEffectModel::Enabled) { + if (model()->enabled()) { + d->animation->setDuration(style()->fadeDuration()); + d->animation->setEasingCurve(style()->easingCurve()); + d->animation->setEndValue(style()->opacity()); + d->animation->start(); + } else { + d->animation->setStartValue(d->controller->opacity()); + d->animation->setEndValue(0.0f); + d->animation->start(); + } + } + } +} + +DUI_REGISTER_VIEW_NEW(DuiSceneLayerEffectDimView, DuiSceneLayerEffect) diff --git a/src/scene/scenelayereffectviews/duiscenelayereffectdimview.h b/src/scene/scenelayereffectviews/duiscenelayereffectdimview.h new file mode 100644 index 000000000..ebdc91226 --- /dev/null +++ b/src/scene/scenelayereffectviews/duiscenelayereffectdimview.h @@ -0,0 +1,54 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +// Make doxygen skip this internal class +//! \cond +#ifndef DUISCENELAYEREFFECTDIMVIEW_H +#define DUISCENELAYEREFFECTDIMVIEW_H + +#include +#include +#include + +class DuiSceneLayerEffect; +class DuiSceneLayerEffectDimViewPrivate; + +class DuiSceneLayerEffectDimView : public DuiSceneWindowView +{ + Q_OBJECT + DUI_VIEW(DuiSceneLayerEffectModel, DuiSceneLayerEffectDimStyle) + +public: + DuiSceneLayerEffectDimView(DuiSceneLayerEffect *controller); + virtual ~DuiSceneLayerEffectDimView(); + + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0); + virtual QRectF boundingRect() const; + +protected Q_SLOTS: + //! \reimp + virtual void updateData(const QList& modifications); + //! \reimp_end + +private: + Q_DECLARE_PRIVATE(DuiSceneLayerEffectDimView) +}; + +#endif +//! \endcond diff --git a/src/service/duiactionprovider.cpp b/src/service/duiactionprovider.cpp new file mode 100644 index 000000000..5594794e2 --- /dev/null +++ b/src/service/duiactionprovider.cpp @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiactionprovider.h" +#include "duiserviceaction.h" + +#include + +/***** TODO: remove test action when not needed any more ******/ +TestAction::TestAction(const QString &text) : + DuiServiceAction(NULL), + text(text) +{ +} + +TestAction::~TestAction() +{ +} + +void TestAction::executeService() +{ + duiDebug("TestAction") << text; +} +/***** TODO: test action ends here ******/ + + +DuiAction *DuiActionProvider::getDefaultAction(const QUrl &uri) +{ + if (uri.isValid()) { + if (uri.scheme() == "settings") { + return new TestAction(QString().sprintf("Action for opening the settings page %s triggered", uri.host().toUtf8().constData())); + } else if (uri.path().endsWith(QString(".png"), Qt::CaseInsensitive) || uri.path().endsWith(QString(".jpg"), Qt::CaseInsensitive)) { + return new TestAction(QString("Default action for Image triggered")); + } + } + + return NULL; +} + diff --git a/src/service/duiactionprovider.h b/src/service/duiactionprovider.h new file mode 100644 index 000000000..0ea841fda --- /dev/null +++ b/src/service/duiactionprovider.h @@ -0,0 +1,72 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIACTIONPROVIDER_H +#define DUIACTIONPROVIDER_H + +#include +#include + +#include "duiexport.h" + +/***** TODO: remove test action when not needed any more ******/ +#include "duiserviceaction.h" + +//! \internal +class TestAction : public DuiServiceAction +{ + Q_OBJECT + + QString text; + +public: + TestAction(const QString &text); + virtual ~TestAction(); + +public Q_SLOTS: + /*! + * Executes the service of this action. + */ + virtual void executeService(); + + +}; +//! \internal_end +/***** TODO: test action ends here ******/ + +/*! + * A mock action provider for testing. + */ +class DUI_EXPORT DuiActionProvider : public QObject +{ + Q_OBJECT +public: + /*! + * Provides a default action for a given URI. The ownership + * of the action is transformed to the caller (the caller must + * destroy the action when it's no longer needed). + * If no action can be provided, this method returns \c NULL. + * \param uri A URI for which an action is provided. + * \return The default action for the URI or \c NULL if no + * action can be provided. + */ + static DuiAction *getDefaultAction(const QUrl &uri); +}; + +#endif // DUIACTIONPROVIDER_H diff --git a/src/service/duiserviceaction.cpp b/src/service/duiserviceaction.cpp new file mode 100644 index 000000000..228af05fd --- /dev/null +++ b/src/service/duiserviceaction.cpp @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiserviceaction.h" +#include "duiserviceaction_p.h" +#include "duiserviceinvoker.h" + + + +DuiServiceActionPrivate::DuiServiceActionPrivate() +{ +} + +DuiServiceActionPrivate::~DuiServiceActionPrivate() +{ +} + + + +DuiServiceAction::DuiServiceAction(QObject *parent) : DuiAction(*new DuiServiceActionPrivate, parent) +{ + Q_D(DuiServiceAction); + + d->q_ptr = this; + + connect(this, SIGNAL(triggered()), DuiServiceInvoker::instance(), SLOT(invoke())); +} + + +DuiServiceAction::DuiServiceAction(DuiServiceActionPrivate &dd, QObject *parent) : + DuiAction(dd, parent) +{ + connect(this, SIGNAL(triggered()), DuiServiceInvoker::instance(), SLOT(invoke())); +} + +DuiServiceAction::~DuiServiceAction() +{ +} + +void DuiServiceAction::executeService() +{ +} diff --git a/src/service/duiserviceaction.h b/src/service/duiserviceaction.h new file mode 100644 index 000000000..6e29edf33 --- /dev/null +++ b/src/service/duiserviceaction.h @@ -0,0 +1,66 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISERVICEACTION_H +#define DUISERVICEACTION_H + +#include "duiaction.h" + +#include "duiexport.h" + +class DuiServiceActionPrivate; + +/*! + * Base class for actions that can be used to launch services. + */ +class DUI_EXPORT DuiServiceAction : public DuiAction +{ + Q_OBJECT + +public: + /*! + * Constructor. + */ + explicit DuiServiceAction(QObject *parent); + + /*! + * Destructor. + */ + virtual ~DuiServiceAction(); + +public slots: + /*! + * Executes the service of this action. + */ + virtual void executeService(); + +protected: + /*! + * Constructor to be used from inheriting classes. + */ + DuiServiceAction(DuiServiceActionPrivate &dd, QObject *parent); + +private: + Q_DECLARE_PRIVATE(DuiServiceAction) + Q_DISABLE_COPY(DuiServiceAction) + +}; + + +#endif // DUISERVICEACTION_H diff --git a/src/service/duiserviceaction_p.h b/src/service/duiserviceaction_p.h new file mode 100644 index 000000000..ba7dfdafa --- /dev/null +++ b/src/service/duiserviceaction_p.h @@ -0,0 +1,35 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISERVICEACTION_P_H +#define DUISERVICEACTION_P_H + +#include "duiaction_p.h" +#include "duiserviceaction.h" + +class DuiServiceActionPrivate : public DuiActionPrivate +{ + Q_DECLARE_PUBLIC(DuiServiceAction) + +public: + DuiServiceActionPrivate(); + virtual ~DuiServiceActionPrivate(); +}; + +#endif //DUISERVICEACTION_P_H diff --git a/src/service/duiserviceinvoker.cpp b/src/service/duiserviceinvoker.cpp new file mode 100644 index 000000000..6dcaf5cc2 --- /dev/null +++ b/src/service/duiserviceinvoker.cpp @@ -0,0 +1,46 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiserviceinvoker.h" +#include + +DuiServiceInvoker *DuiServiceInvoker::theInstance = NULL; + +DuiServiceInvoker::DuiServiceInvoker() +{ + +} + +DuiServiceInvoker *DuiServiceInvoker::instance() +{ + if (theInstance == NULL) { + theInstance = new DuiServiceInvoker(); + } + + return theInstance; +} + +void DuiServiceInvoker::invoke() +{ + DuiServiceAction *action = qobject_cast(sender()); + if (action != NULL) { + action->executeService(); + } +} + diff --git a/src/service/duiserviceinvoker.h b/src/service/duiserviceinvoker.h new file mode 100644 index 000000000..67866ac4a --- /dev/null +++ b/src/service/duiserviceinvoker.h @@ -0,0 +1,57 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISERVICEINVOKER_H +#define DUISERVICEINVOKER_H + +#include +#include + +/*! + * A helper service that invokes service actions. + */ +class DUI_EXPORT DuiServiceInvoker : public QObject +{ + Q_OBJECT + +private: + /*! + * Hidden default constructor + */ + DuiServiceInvoker(); + + Q_DISABLE_COPY(DuiServiceInvoker) + + //! Pointer to the singleton instance + static DuiServiceInvoker *theInstance; + +public: + /*! + * Returns a singleton instance of this class. + */ + static DuiServiceInvoker *instance(); + +public slots: + /*! + * Invokes a \c DuiServiceAction service. + */ + void invoke(); +}; + +#endif // DUISERVICEINVOKER_H diff --git a/src/service/service.pri b/src/service/service.pri new file mode 100644 index 000000000..b60cbf7c2 --- /dev/null +++ b/src/service/service.pri @@ -0,0 +1,10 @@ +SERVICE_SRC_DIR = ./service +INCLUDEPATH += ./service +HEADERS += $$SERVICE_SRC_DIR/duiactionprovider.h \ + $$SERVICE_SRC_DIR/duiserviceaction.h \ + $$SERVICE_SRC_DIR/duiserviceinvoker.h \ + $$SERVICE_SRC_DIR/duiserviceaction_p.h + +SOURCES += $$SERVICE_SRC_DIR/duiactionprovider.cpp \ + $$SERVICE_SRC_DIR/duiserviceaction.cpp \ + $$SERVICE_SRC_DIR/duiserviceinvoker.cpp diff --git a/src/servicefwif/com.nokia.DuiServiceFwIf.xml b/src/servicefwif/com.nokia.DuiServiceFwIf.xml new file mode 100644 index 000000000..5dd0053bb --- /dev/null +++ b/src/servicefwif/com.nokia.DuiServiceFwIf.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/servicefwif/duiservicefwbaseif.cpp b/src/servicefwif/duiservicefwbaseif.cpp new file mode 100644 index 000000000..3c7054539 --- /dev/null +++ b/src/servicefwif/duiservicefwbaseif.cpp @@ -0,0 +1,139 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiservicefwbaseif.h" + +#include +#include +#include + +DuiServiceFwBaseIf::DuiServiceFwBaseIf(const QString &iface, QObject *parent) : + QObject(parent), + interfaceProxy(0), + serviceFwProxyPtr(new DuiServiceFwProxy( + "com.nokia.DuiServiceFw", + "/", + QDBusConnection::sessionBus() + ) + ), + service(), + interface(iface) +{ + connect(serviceFwProxyPtr, SIGNAL(serviceAvailable(QString, QString)), + this, SLOT(handleServiceAvailable(QString, QString))); + + connect(serviceFwProxyPtr, SIGNAL(serviceUnavailable(QString)), + this, SLOT(handleServiceUnavailable(QString))); +} + +DuiServiceFwBaseIf::~DuiServiceFwBaseIf() +{ + if (interfaceProxy) { + delete interfaceProxy; + interfaceProxy = 0; + } + + if (serviceFwProxyPtr) { + delete serviceFwProxyPtr; + serviceFwProxyPtr = 0; + } +} + +bool DuiServiceFwBaseIf::isValid() const +{ + return (interfaceProxy != 0); +} + +QStringList DuiServiceFwBaseIf::serviceNames(const QString &interface) const +{ + return serviceFwProxyPtr->serviceNames(interface); +} + +QString DuiServiceFwBaseIf::serviceName() const +{ + return service; +} + +DuiServiceFwProxy *DuiServiceFwBaseIf::serviceFwProxy() +{ + return serviceFwProxyPtr; +} + +void DuiServiceFwBaseIf::handleServiceUnavailable(const QString &service) +{ + bool noCurrentService = this->service.isEmpty(); + bool currentServiceHasGone = (service == this->service); + + if (noCurrentService || currentServiceHasGone) { + // get new service for this interface + this->service = serviceFwProxyPtr->serviceName(this->interface); + + bool noMoreServicesForThisInterface = this->service.isEmpty(); + if (noMoreServicesForThisInterface) { + if (!noCurrentService) + emit serviceUnavailable(service); + } else { + setService(this->service); + emit serviceChanged(this->service); + } + } +} + +void DuiServiceFwBaseIf::handleServiceAvailable(const QString &service, const QString &interface) +{ + bool newServiceIsForThisInterface = (interface == this->interface); + if (newServiceIsForThisInterface) { + QString previousService = this->service; + + // let service mappper choose which service to use + this->service = serviceFwProxyPtr->serviceName(this->interface); + + bool interfaceWasDead = previousService.isEmpty(); + if (interfaceWasDead) { + emit serviceAvailable(service); + } + + bool serviceHasChanged = (previousService != this->service); + if (serviceHasChanged) { + setService(this->service); + emit serviceChanged(this->service); + } + } +} + +QString DuiServiceFwBaseIf::resolveServiceName(const QString &ifName, const QString &preferredService) +{ + duiDebug("DuiServiceFwBaseIf") << "DuiServiceFwBaseIf::resolveServiceName( ifName=" << ifName << ", preferredService=" << preferredService << " )"; + bool noPreferredSpecified = preferredService.isEmpty(); + if (noPreferredSpecified) { + // ask the service name from service mapper + if (serviceFwProxyPtr->connection().isConnected()) { + duiDebug("DuiServiceFwBaseIf") << "no preferred service and am connected to dbus so asking servicemapper"; + service = serviceFwProxyPtr->serviceName(ifName); + } else { + duiDebug("DuiServiceFwBaseIf") << "no preferred service and am not connected to dbus so making I/F invalid"; + service.clear(); + } + } else { + duiDebug("DuiServiceFwBaseIf") << "preferredService specified, so returning it"; + service = preferredService; + } + + return service; +} diff --git a/src/servicefwif/duiservicefwbaseif.h b/src/servicefwif/duiservicefwbaseif.h new file mode 100644 index 000000000..9433b8486 --- /dev/null +++ b/src/servicefwif/duiservicefwbaseif.h @@ -0,0 +1,168 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +// Make doxygen skip this internal class +//! \cond +#ifndef DUISERVICEFWBASEIF_H +#define DUISERVICEFWBASEIF_H + +#include "duiexport.h" + +#include +#include +#include "duiservicefwproxy.h" + +class QDBusAbstractInterface; + +/*! + * \class DuiServiceFwBaseIf + * \author Max Waterman + * \brief The base class from which all service interface classes are be derived. + * + * Service Interface classes are autogenerated and so there is no need + * for developers to directly reference this class. + * + * DuiServiceFwBaseIf hides the servicefw machanisms from the derived class, + * including service discovery and underlying IPC methods. + */ + +class DUI_EXPORT DuiServiceFwBaseIf : public QObject +{ + Q_OBJECT +public: + /*! + * \brief Constructs a base interface + * \param iface Interface to which to connect + * \param parent Parent object + */ + explicit DuiServiceFwBaseIf(const QString &iface, QObject *parent = 0); + + /*! + * \brief Destructor + */ + virtual ~DuiServiceFwBaseIf(); + + /*! + * \brief Returns true if the interface is connected and usable, otherwise false. + * \return Interface validity + */ + virtual bool isValid() const; + + /*! + * \brief Returns the name of the currently used service + * \return Name of currently used service + */ + virtual QString serviceName() const; + + /*! + * \brief Returns the address of the service framework proxy + * \return Address of service framework proxy + */ + virtual DuiServiceFwProxy *serviceFwProxy(); + + /*! + * \brief Set the service name + * \param service Name of the desired service + */ + virtual void setService(const QString &service) = 0; + +Q_SIGNALS: + /*! + * \brief A signal that is emitted when a service becomes available. + * \param service The name of the service that has become available + */ + void serviceAvailable(const QString &service); + + /*! + * \brief A signal that is emitted when the last service implementing + * the interface becomes unavailable. + * \param service The name of the service that has become unavailable + */ + void serviceUnavailable(const QString &service); + + /*! + * \brief A signal that is emitted when the service has changed + * \param service The name of the new service + */ + void serviceChanged(const QString &service); + +public Q_SLOTS: + /*! + * \brief Returns a list of available services + * \param interface Only list services that implement this interface; empty for all interfaces + * \return List of services + */ + QStringList serviceNames(const QString &interface = "") const; + +private Q_SLOTS: + /*! + * \brief Handles the ServicAvailable signal sent by the ServiceMapper + * \param service The name of the service that has become available + * \param interface The name of the interface implemented by the service + * + * Responsible for appropriately switching services and emitting signals + * to allow the app to know what has happened and what has changed as a + * result of a service becoming available. + * Emits serviceAvailable signal if there was previously none available. + * Emits serviceChanged signal if the service has changed. + */ + void handleServiceAvailable(const QString &service, const QString &interface); + + /*! + * \brief Handles the ServiceUnavailable signal sent by the ServiceMappper + * \param service The name of the service that has become unavailable + * + * Responsible for appropriately switching services and emitting signals + * to allow the app to know what has happened and what has changed as a + * result of a service becoming unavailable. + * Emits serviceUnavailable signal if there was previously none available. + * Emits serviceChanged signal if the service has changed. + */ + void handleServiceUnavailable(const QString &service); + +protected: + /*! + * \brief Resolves the service name for a specific interface + * \param ifName Interface name + * \param preferredService Name of a preferred service + * \return Name of selected service + */ + QString resolveServiceName(const QString &ifName, const QString &preferredService); + +protected: + // Pointer to the D-Bus interfaceProxy + // assigned in derived class, deleted in this class + QDBusAbstractInterface *interfaceProxy; + + // Interface to Service Framework, owned + DuiServiceFwProxy *serviceFwProxyPtr; + + // Name of the active service provider + QString service; + + // Name of the interface + const QString interface; + +#ifdef UNIT_TEST + friend class Ut_DuiServiceFwBaseIf; +#endif // UNIT_TEST +}; + +#endif +//! \endcond diff --git a/src/servicefwif/duiservicefwproxy.cpp b/src/servicefwif/duiservicefwproxy.cpp new file mode 100644 index 000000000..96df07e17 --- /dev/null +++ b/src/servicefwif/duiservicefwproxy.cpp @@ -0,0 +1,26 @@ +/* + * This file was generated by qdbusxml2cpp version 0.7 + * Command line was: qdbusxml2cpp -c ServiceFwProxy -p servicefwproxy.h:servicefwproxy.cpp servicefw.xml + * + * qdbusxml2cpp is Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#include + +/* + * Implementation of interface class ServiceFwProxy + */ + +DuiServiceFwProxy::DuiServiceFwProxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) + : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) +{ +} + +DuiServiceFwProxy::~DuiServiceFwProxy() +{ +} + diff --git a/src/servicefwif/include/duiservicefwproxy.h b/src/servicefwif/include/duiservicefwproxy.h new file mode 100644 index 000000000..a285a8877 --- /dev/null +++ b/src/servicefwif/include/duiservicefwproxy.h @@ -0,0 +1,80 @@ +/* + * This file was generated by qdbusxml2cpp version 0.7 + * Command line was: qdbusxml2cpp -c DuiServiceFwProxy -p duiservicefwproxy.h:duiservicefwproxy.cpp duiservicefw.xml + * + * qdbusxml2cpp is Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ +// Make doxygen skip this internal class +//! \cond + +#ifndef DUISERVICEFWPROXY_H_1235929249 +#define DUISERVICEFWPROXY_H_1235929249 + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Proxy class for interface com.nokia.ServiceFwIf + */ +class DuiServiceFwProxy: public QDBusAbstractInterface +{ + Q_OBJECT +public: + static inline const char *staticInterfaceName() { + return "com.nokia.DuiServiceFwIf"; + } + +public: + DuiServiceFwProxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0); + + virtual ~DuiServiceFwProxy(); + +public Q_SLOTS: // METHODS + inline QDBusPendingReply serviceName(const QString &interfaceName) { + QList argumentList; + argumentList << qVariantFromValue(interfaceName); + return asyncCallWithArgumentList(QLatin1String("serviceName"), argumentList); + } + + inline QDBusPendingReply serviceNames(const QString &interfaceName) { + QList argumentList; + argumentList << qVariantFromValue(interfaceName); + return asyncCallWithArgumentList(QLatin1String("serviceNames"), argumentList); + } + + inline QDBusPendingReply servicePath(const QString &interfaceName) { + QList argumentList; + argumentList << qVariantFromValue(interfaceName); + return asyncCallWithArgumentList(QLatin1String("servicePath"), argumentList); + } + + inline QDBusPendingReply interfaceName(const QString &serviceName) { + QList argumentList; + argumentList << qVariantFromValue(serviceName); + return asyncCallWithArgumentList(QLatin1String("interfaceName"), argumentList); + } + +Q_SIGNALS: // SIGNALS + void serviceAvailable(const QString &service, const QString &interface); + void serviceUnavailable(const QString &service); + +}; + +namespace com +{ + namespace nokia + { + typedef ::DuiServiceFwProxy DuiServiceFwIf; + } +} +#endif +//! \endcond diff --git a/src/servicefwif/servicefwif.pri b/src/servicefwif/servicefwif.pri new file mode 100644 index 000000000..cbe8652aa --- /dev/null +++ b/src/servicefwif/servicefwif.pri @@ -0,0 +1,15 @@ +############################################################################### +# DuiServiceFwIf module +# This module contains classes needed for applications to comminucate with +# the servicemapper +############################################################################### +SERVICEFWIF_SRC_DIR=./servicefwif +INCLUDEPATH+=./servicefwif/include +HEADERS += \ + $$SERVICEFWIF_SRC_DIR/duiservicefwbaseif.h \ + $$SERVICEFWIF_SRC_DIR/include/duiservicefwproxy.h \ + +SOURCES += \ + $$SERVICEFWIF_SRC_DIR/duiservicefwbaseif.cpp \ + $$SERVICEFWIF_SRC_DIR/duiservicefwproxy.cpp \ + diff --git a/src/settingslanguage/duisettingslanguagebinary.cpp b/src/settingslanguage/duisettingslanguagebinary.cpp new file mode 100644 index 000000000..dda33ecd1 --- /dev/null +++ b/src/settingslanguage/duisettingslanguagebinary.cpp @@ -0,0 +1,66 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include "duisettingslanguagebinary.h" +#include "duisettingslanguageselection.h" +#include "duisettingslanguageinteger.h" +#include "duisettingslanguagetext.h" +#include "duisettingslanguageboolean.h" + +DuiSettingsLanguageBinary::DuiSettingsLanguageBinary() +{ +} + +DuiSettingsLanguageBinary::~DuiSettingsLanguageBinary() +{ +} + +QStringList DuiSettingsLanguageBinary::keys() const +{ + QStringList keys; + QList nodes; + + for (nodes.append(const_cast(this)); !nodes.isEmpty();) { + // Process the first node in the node list + const DuiSettingsLanguageNode *node = nodes.takeFirst(); + + // Append all children of the node to the node list + nodes.append(node->children()); + + const DuiSettingsLanguageSelection *selectionNode; + const DuiSettingsLanguageInteger *intNode; + const DuiSettingsLanguageText *textNode; + const DuiSettingsLanguageBoolean *booleanNode; + + // Append the key of the node being processed (if any) to the key list + if ((selectionNode = dynamic_cast(node))) { + keys.append(selectionNode->key()); + } else if ((intNode = dynamic_cast(node))) { + keys.append(intNode->key()); + } else if ((textNode = dynamic_cast(node))) { + keys.append(textNode->key()); + } else if ((booleanNode = dynamic_cast(node))) { + keys.append(booleanNode->key()); + } + } + + return keys; +} + diff --git a/src/settingslanguage/duisettingslanguagebinary.h b/src/settingslanguage/duisettingslanguagebinary.h new file mode 100644 index 000000000..23f0ecfb2 --- /dev/null +++ b/src/settingslanguage/duisettingslanguagebinary.h @@ -0,0 +1,54 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISETTINGSLANGUAGEBINARY_H +#define DUISETTINGSLANGUAGEBINARY_H + +#include +#include "duiexport.h" +#include "duisettingslanguagesettings.h" + +/*! + * \brief The root class for the settings binary interface. + * + * This is the central access point class for the settings binary + * interface. + */ +class DUI_EXPORT DuiSettingsLanguageBinary : public DuiSettingsLanguageSettings +{ +public: + /*! + * Constructor. + */ + DuiSettingsLanguageBinary(); + + /*! + * Destructor. + */ + virtual ~DuiSettingsLanguageBinary(); + + /*! + * Returns the list of keys in this settings binary tree. + * + * \return a list of keys in this settings binary tree + */ + QStringList keys() const; +}; + +#endif // DUISETTINGSLANGUAGEBINARY_H diff --git a/src/settingslanguage/duisettingslanguageboolean.cpp b/src/settingslanguage/duisettingslanguageboolean.cpp new file mode 100644 index 000000000..17551480f --- /dev/null +++ b/src/settingslanguage/duisettingslanguageboolean.cpp @@ -0,0 +1,41 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duisettingslanguageboolean.h" + +DuiSettingsLanguageBoolean::DuiSettingsLanguageBoolean(const QString &key, + const QString &title) : + key_(key), + title_(title) +{ +} + +DuiSettingsLanguageBoolean::~DuiSettingsLanguageBoolean() +{ +} + +QString DuiSettingsLanguageBoolean::key() const +{ + return key_; +} + +QString DuiSettingsLanguageBoolean::title() const +{ + return qtTrId(title_.toUtf8()); +} diff --git a/src/settingslanguage/duisettingslanguageboolean.h b/src/settingslanguage/duisettingslanguageboolean.h new file mode 100644 index 000000000..e25e5d19b --- /dev/null +++ b/src/settingslanguage/duisettingslanguageboolean.h @@ -0,0 +1,63 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISETTINGSLANGUAGEBOOLEAN_H +#define DUISETTINGSLANGUAGEBOOLEAN_H + +#include +#include + +#include "duisettingslanguagenode.h" + +/*! + * \brief A settings node representing a boolean. + */ +class DuiSettingsLanguageBoolean : public DuiSettingsLanguageNode +{ +public: + /*! + * Constructs a new boolean with a given key. + * \param key the key (name) of the boolean. + */ + DuiSettingsLanguageBoolean(const QString &key, const QString &title); + + /*! + * Destructor. + */ + virtual ~DuiSettingsLanguageBoolean(); + + /*! + * Returns the key of this boolean. + */ + QString key() const; + + /*! + * Returns the localized title of this node. + */ + QString title() const; + +private: + //! The key (name) of this boolean. + QString key_; + + //! The title of this boolean. + QString title_; +}; + +#endif // DUISETTINGSLANGUAGEBOOLEAN_H diff --git a/src/settingslanguage/duisettingslanguagebooleancontroller.cpp b/src/settingslanguage/duisettingslanguagebooleancontroller.cpp new file mode 100644 index 000000000..59a9b24d5 --- /dev/null +++ b/src/settingslanguage/duisettingslanguagebooleancontroller.cpp @@ -0,0 +1,45 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duisettingslanguagebooleancontroller.h" + +#include +#include + +DuiSettingsLanguageBooleanController::DuiSettingsLanguageBooleanController(QObject *parent) : + QObject(parent) +{ +} + +DuiSettingsLanguageBooleanController::~DuiSettingsLanguageBooleanController() +{ +} + +void DuiSettingsLanguageBooleanController::buttonToggled(bool checked) +{ + // get button from signal sender + DuiButton *button = static_cast(sender()); + + if (button != NULL) { + DuiDataStore *dataStore = static_cast(button->property("dataStore").value()); + if (dataStore != NULL) { + dataStore->createValue(button->property("key").toString(), checked); + } + } +} diff --git a/src/settingslanguage/duisettingslanguagebooleancontroller.h b/src/settingslanguage/duisettingslanguagebooleancontroller.h new file mode 100644 index 000000000..fcf24b3a1 --- /dev/null +++ b/src/settingslanguage/duisettingslanguagebooleancontroller.h @@ -0,0 +1,58 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISETTINGSLANGUAGEBOOLEANCONTROLLER_H +#define DUISETTINGSLANGUAGEBOOLEANCONTROLLER_H + +#include + +class DuiButton; + +/*! + * An interaction controller for boolean items in settings language. + */ +class DuiSettingsLanguageBooleanController : public QObject +{ + Q_OBJECT + +public: + /*! + * Constructor. + * \param parent the parent object for this object. + */ + DuiSettingsLanguageBooleanController(QObject *parent = NULL); + + /*! + * Destructor. + */ + virtual ~DuiSettingsLanguageBooleanController(); + +public slots: + /*! + * Reacts to button toggles. Stores the selected buttons values to storage backend. + * The button should have the following properties set: + * - key: the name of the value + * - value: the value that should be set + * \param checked the checked value of button. + */ + void buttonToggled(bool checked); + +}; + +#endif // DUISETTINGSLANGUAGEBOOLEANCONTROLLER_H diff --git a/src/settingslanguage/duisettingslanguagebooleanfactory.cpp b/src/settingslanguage/duisettingslanguagebooleanfactory.cpp new file mode 100644 index 000000000..7787a0f31 --- /dev/null +++ b/src/settingslanguage/duisettingslanguagebooleanfactory.cpp @@ -0,0 +1,65 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duisettingslanguagebooleanfactory.h" +#include "duisettingslanguagebooleancontroller.h" +#include "duisettingslanguageboolean.h" + +#include +#include +#include +#include + +DuiWidgetController *DuiSettingsLanguageBooleanFactory::createWidget(const DuiSettingsLanguageBoolean &settingsBool, DuiSettingsLanguageWidget &rootWidget, DuiDataStore *dataStore) +{ + Q_UNUSED(rootWidget) + + DuiWidgetController *parentWidget = new DuiWidgetController; + parentWidget->setView(new DuiWidgetView(parentWidget)); + + // Make an interaction controller and make it a child of the widget object (so that it gets destroyed when appropriate) + DuiSettingsLanguageBooleanController *boolController = new DuiSettingsLanguageBooleanController(parentWidget); + + // Create a horizontal layout + QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(Qt::Horizontal); + layout->setContentsMargins(0, 0, 0, 0); + layout->setSpacing(0); + parentWidget->setLayout(layout); + + // Create a button + DuiButton *button = new DuiButton(parentWidget); + button->setCheckable(true); + button->setViewType(DuiButton::toggleType); + button->connect(button, SIGNAL(toggled(bool)), boolController, SLOT(buttonToggled(bool))); + + // Get the previously selected value if it exists + bool selectedValue = false; + if (dataStore != NULL) { + selectedValue = dataStore->value(settingsBool.key()).toBool(); + } + button->setChecked(selectedValue); + + button->setText(settingsBool.title()); + button->setObjectName("SettingsLanguageBooleanValueButton"); + button->setProperty("dataStore", qVariantFromValue(static_cast(dataStore))); + button->setProperty("key", settingsBool.key()); + layout->addItem(button); + + return parentWidget; +} diff --git a/src/settingslanguage/duisettingslanguagebooleanfactory.h b/src/settingslanguage/duisettingslanguagebooleanfactory.h new file mode 100644 index 000000000..8659c5f08 --- /dev/null +++ b/src/settingslanguage/duisettingslanguagebooleanfactory.h @@ -0,0 +1,54 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISETTINGSLANGUAGEBOOLEANFACTORY_H +#define DUISETTINGSLANGUAGEBOOLEANFACTORY_H + +#include + +class DuiWidgetController; +class DuiSettingsLanguageWidget; +class DuiDataStore; +class DuiSettingsLanguageBoolean; + +/*! + * A factory for translating settings binaries to widgets. + */ +class DuiSettingsLanguageBooleanFactory +{ + /*! + * Private constructor to prevent construction. + */ + DuiSettingsLanguageBooleanFactory() {} + Q_DISABLE_COPY(DuiSettingsLanguageBooleanFactory) + +public: + /*! + * \brief Creates a widget from a DuiSettingsLanguageBool representation. + * + * \param settingsBool the settings binary representation. + * \param rootWidget the root of the widget hierarchy where the new widget will be attached. + * \param dataStore the data store for the settings. + * \return a widget. + */ + static DuiWidgetController *createWidget(const DuiSettingsLanguageBoolean &settingsBool, DuiSettingsLanguageWidget &rootWidget, DuiDataStore *dataStore = NULL); + +}; + +#endif // DUISETTINGSLANGUAGEBOOLEANFACTORY_H diff --git a/src/settingslanguage/duisettingslanguagegroup.h b/src/settingslanguage/duisettingslanguagegroup.h new file mode 100644 index 000000000..957ec1aed --- /dev/null +++ b/src/settingslanguage/duisettingslanguagegroup.h @@ -0,0 +1,41 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISETTINGSLANGUAGEGROUP_H +#define DUISETTINGSLANGUAGEGROUP_H + +#include "duisettingslanguagenode.h" + +/*! + * \brief A settings node representing a group of setting items. + * + * A group can contain one or more setting items. + */ +class DuiSettingsLanguageGroup : public DuiSettingsLanguageNode +{ +public: + /*! + * Constructor. + */ + DuiSettingsLanguageGroup() {} + + virtual ~DuiSettingsLanguageGroup() {} +}; + +#endif // DUISETTINGSLANGUAGEGROUP_H diff --git a/src/settingslanguage/duisettingslanguagegroupfactory.cpp b/src/settingslanguage/duisettingslanguagegroupfactory.cpp new file mode 100644 index 000000000..06ffe8145 --- /dev/null +++ b/src/settingslanguage/duisettingslanguagegroupfactory.cpp @@ -0,0 +1,166 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duisettingslanguagesettingfactory.h" +#include "duisettingslanguagewidget.h" +#include "duisettingslanguagesettingcontroller.h" +#include "duisettingslanguagenode.h" +#include "duisettingslanguageselectionfactory.h" +#include "duisettingslanguageinfofactory.h" +#include "duisettingslanguagetextfactory.h" +#include "duisettingslanguageintegerfactory.h" +#include "duisettingslanguageinfo.h" +#include "duisettingslanguagetext.h" +#include "duisettingslanguagesetting.h" +#include "duisettingslanguageselection.h" +#include "duisettingslanguageinteger.h" +#include "duitheme.h" +#include "duisettingslanguagesettingfactorystyle.h" +#include "duisettingslanguagebooleanfactory.h" +#include "duisettingslanguageboolean.h" + +#include +#include +#include +#include +#include +#include +#include + +DuiWidgetController *DuiSettingsLanguageSettingFactory::createWidget(const DuiSettingsLanguageSetting &settingsItem, DuiSettingsLanguageWidget &rootWidget, DuiDataStore *dataStore) +{ + DuiWidgetController *widget = NULL; + DuiSettingsLanguageSettingController *settingsController = NULL; + + DuiAction *action = NULL; + // Try to get an action corresponding to the content attribute + if (!settingsItem.content().isEmpty()) { + action = DuiActionProvider::getDefaultAction(QUrl(settingsItem.content())); + if (action != NULL) { + action->setVisible(false); + action->connect(action, SIGNAL(triggered()), &rootWidget, SIGNAL(actionTriggered())); + } + } + + const DuiSettingsLanguageSettingFactoryStyle *style = + static_cast + (DuiTheme::style("DuiSettingsLanguageSettingFactoryStyle", "", "", "", Dui::Landscape, NULL)); + + // Create content layout to layout content items in + QGraphicsLinearLayout *contentLayout = new QGraphicsLinearLayout(Qt::Vertical); + contentLayout->setContentsMargins(0, 0, 0, 0); + + if (settingsItem.group()) { + // Create a container widget as a root widget + DuiContainer *container = new DuiContainer; + container->setObjectName("SettingsLanguageContainer"); + container->setTitle(settingsItem.title()); + + if (action != NULL) { + container->addAction(action); + // Trigger the action by clicking + container->connect(container, SIGNAL(headerClicked()), action, SLOT(trigger())); + + // Create content indicator + container->setIconID(style->contentIndicator()); + QGraphicsLayout *mainLayout = container->layout(); + // TODO: remove this when there's support from DuiContainer for the styling + if (mainLayout) { + QGraphicsWidget *header = dynamic_cast(mainLayout->itemAt(0)); + if (header) { + QGraphicsLayout *headerLayout = header->layout(); + if (headerLayout) { + headerLayout->setContentsMargins(style->contentIndicatorContainerMargin(), 0, 0, 0); + } + } + } + } + + // Create central widget as parent widget for content items + DuiWidget *centralWidget = new DuiWidget(container); + container->setCentralWidget(centralWidget, true); + centralWidget->setLayout(contentLayout); + widget = container; + } else { + // Create content indicator widget and put it into compound layout with the content layout + QGraphicsLinearLayout *itemLayout = new QGraphicsLinearLayout(Qt::Horizontal); + itemLayout->setContentsMargins(0, 0, 0, 0); + + if (action == NULL) { + widget = new DuiWidgetController; + widget->setView(new DuiWidgetView(widget)); + } else { + widget = new DuiButton; + // Make an interaction controller and make it a child of the widget object (so that it gets destroyed when appropriate) + settingsController = new DuiSettingsLanguageSettingController(widget); + // Handle activity by press/release events + widget->connect(widget, SIGNAL(pressed()), settingsController, SLOT(activate())); + widget->connect(widget, SIGNAL(released()), settingsController, SLOT(deactivate())); + + // Create a new layout for placing the content indicator icon + QGraphicsLinearLayout *indicatorLayout = new QGraphicsLinearLayout(Qt::Horizontal); + indicatorLayout->setContentsMargins(style->contentIndicatorLeftMargin(), style->contentIndicatorTopMargin(), style->contentIndicatorRightMargin(), style->contentIndicatorBottomMargin()); + DuiImage *indicator = new DuiImage(widget); + indicator->setImage(style->contentIndicator(), style->contentIndicatorSize()); + indicator->setObjectName("SettingsLanguageContentIndicator"); + indicatorLayout->addItem(indicator); + itemLayout->addItem(indicatorLayout); + // TODO: remove this when bug #133359 is fixed in duiimage + indicator->setZoomFactor(1.0, 1.0); + + widget->addAction(action); + // Trigger the action by clicking + widget->connect(widget, SIGNAL(clicked()), action, SLOT(trigger())); + } + + widget->setObjectName("DuiSettingsLanguage"); + itemLayout->addItem(contentLayout); + widget->setLayout(itemLayout); + } + + // Go through all children of the item + foreach(DuiSettingsLanguageNode * child, settingsItem.children()) { + DuiWidgetController *childWidget = NULL; + + if (child->nodeType() == Dui::DeclSettings::Selection) { + childWidget = DuiSettingsLanguageSelectionFactory::createWidget(*static_cast(child), rootWidget, dataStore); + } else if (child->nodeType() == Dui::DeclSettings::Info) { + childWidget = DuiSettingsLanguageInfoFactory::createWidget(*static_cast(child), rootWidget, dataStore); + // Monitor activity state changes of the parent widget + if (settingsController != NULL) { + childWidget->setActive(widget->isActive()); + settingsController->connect(settingsController, SIGNAL(activityChanged(bool)), childWidget, SLOT(setActive(bool))); + } + } else if (child->nodeType() == Dui::DeclSettings::Integer) { + childWidget = DuiSettingsLanguageIntegerFactory::createWidget(*static_cast(child), rootWidget, dataStore); + } else if (child->nodeType() == Dui::DeclSettings::Text) { + childWidget = DuiSettingsLanguageTextFactory::createWidget(*static_cast(child), rootWidget, dataStore); + } else if (child->nodeType() == Dui::DeclSettings::Boolean) { + childWidget = DuiSettingsLanguageBooleanFactory::createWidget(*static_cast(child), rootWidget, dataStore); + } + + if (childWidget != NULL) { + contentLayout->addItem(childWidget); + } + } + + DuiTheme::releaseStyle(style); + + return widget; +} diff --git a/src/settingslanguage/duisettingslanguagegroupfactory.h b/src/settingslanguage/duisettingslanguagegroupfactory.h new file mode 100644 index 000000000..b4c423bec --- /dev/null +++ b/src/settingslanguage/duisettingslanguagegroupfactory.h @@ -0,0 +1,54 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISETTINGSLANGUAGEITEMFACTORY_H_ +#define DUISETTINGSLANGUAGEITEMFACTORY_H_ + +#include + +class DuiWidgetController; +class DuiDataStore; +class DuiSettingsLanguageSetting; +class DuiSettingsLanguageWidget; + +/*! + * A factory for translating settings binaries to widgets. + */ +class DuiSettingsLanguageSettingFactory +{ + /*! + * Private constructor to prevent construction. + */ + DuiSettingsLanguageSettingFactory() {} + Q_DISABLE_COPY(DuiSettingsLanguageSettingFactory) + +public: + /*! + * \brief Creates a widget from a DuiSettingsLanguageSetting representation. + * + * \param settingsItem the settings binary representation. + * \param rootWidget the root of the widget hierarchy where the new widget will be attached. + * \param dataStore the data store for the settings. + * \return a widget. + */ + static DuiWidgetController *createWidget(const DuiSettingsLanguageSetting &settingsItem, DuiSettingsLanguageWidget &rootWidget, DuiDataStore *dataStore = NULL); + +}; + +#endif /* DUISETTINGSLANGUAGEITEMFACTORY_H_ */ diff --git a/src/settingslanguage/duisettingslanguageinteger.cpp b/src/settingslanguage/duisettingslanguageinteger.cpp new file mode 100644 index 000000000..3e2f1dcf5 --- /dev/null +++ b/src/settingslanguage/duisettingslanguageinteger.cpp @@ -0,0 +1,70 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duisettingslanguageinteger.h" + +DuiSettingsLanguageInteger::DuiSettingsLanguageInteger(const QString &key, const QString &title) : + key_(key), + title_(title), + minValue_(), + maxValue_() +{ +} + +DuiSettingsLanguageInteger::~DuiSettingsLanguageInteger() +{ +} + +QString DuiSettingsLanguageInteger::key() const +{ + return key_; +} + +QString DuiSettingsLanguageInteger::title() const +{ + return qtTrId(title_.toUtf8()); +} + +bool DuiSettingsLanguageInteger::minValue(int &value) const +{ + if (minValue_.isSet) { + value = minValue_.value; + } + return minValue_.isSet; +} + +bool DuiSettingsLanguageInteger::maxValue(int &value) const +{ + if (maxValue_.isSet) { + value = maxValue_.value; + } + return maxValue_.isSet; +} + +void DuiSettingsLanguageInteger::setMinValue(const int newMin) +{ + minValue_.isSet = true; + minValue_.value = newMin; +} +void DuiSettingsLanguageInteger::setMaxValue(const int newMax) +{ + maxValue_.isSet = true; + maxValue_.value = newMax; +} + diff --git a/src/settingslanguage/duisettingslanguageinteger.h b/src/settingslanguage/duisettingslanguageinteger.h new file mode 100644 index 000000000..0245ba1fe --- /dev/null +++ b/src/settingslanguage/duisettingslanguageinteger.h @@ -0,0 +1,105 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISETTINGSLANGUAGEINTEGER_H +#define DUISETTINGSLANGUAGEINTEGER_H + +#include +#include "duisettingslanguagenode.h" + +/*! + * \brief A settings node representing an integer within a given range. + */ +class DuiSettingsLanguageInteger : public DuiSettingsLanguageNode +{ +public: + struct MinMaxValue { + MinMaxValue() : isSet(false), value(0) {} + MinMaxValue(int v) : isSet(true), value(v) {} + MinMaxValue(bool s, int v) : isSet(s), value(v) {} + + bool isSet; + int value; + }; + + /*! + * Constructs a new integer settings node. + * + * If maxValue is smaller than or equal to minValue, the integer will be + * considered not to be constrained to any range. + * + * \param key the key (name) of the integer item. + * \param title the title of the integer item. + * \param min the minimum value for the item. Value can be set or unset. + * \param max the maximum value for the item. Value can be set or unset. + */ + DuiSettingsLanguageInteger(const QString &key, const QString &title); + + /*! + * Destructor + */ + virtual ~DuiSettingsLanguageInteger(); + + /*! + * Returns the key of this integer node. + * \return key + */ + QString key() const; + + /*! + * Returns the localized title of this integer node. + * \return title + */ + QString title() const; + + /*! + * Set parameter value to the minimum value, if minimum value is set. + * \param value return param to be set to minimum value + * \return true if minimum value is set + */ + bool minValue(int &value) const; + + /*! + * Set parameter value to the maximum value, if maximum value is set. + * \param value return param to be set to maximum value + * \return true if maximum value is set + */ + bool maxValue(int &value) const; + + + void setMinValue(int newMin); + + void setMaxValue(int newMax); + +private: + //! The key (name) of this object. + QString key_; + + //! The title of this object. + QString title_; + + //! The minimum value. + MinMaxValue minValue_; + + //! The maximum value. + MinMaxValue maxValue_; +}; + + +#endif // DUISETTINGSLANGUAGEINTEGER_H diff --git a/src/settingslanguage/duisettingslanguageintegercontroller.cpp b/src/settingslanguage/duisettingslanguageintegercontroller.cpp new file mode 100644 index 000000000..668b82156 --- /dev/null +++ b/src/settingslanguage/duisettingslanguageintegercontroller.cpp @@ -0,0 +1,39 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duisettingslanguageintegercontroller.h" + +#include + +DuiSettingsLanguageIntegerController::DuiSettingsLanguageIntegerController(QObject *parent) : + QObject(parent) +{ +} + +DuiSettingsLanguageIntegerController::~DuiSettingsLanguageIntegerController() +{ +} + +void DuiSettingsLanguageIntegerController::changeValue(int newValue) +{ + DuiDataStore *dataStore = static_cast(property("dataStore").value()); + if (dataStore != NULL) { + dataStore->createValue(property("key").toString(), newValue); + } +} diff --git a/src/settingslanguage/duisettingslanguageintegercontroller.h b/src/settingslanguage/duisettingslanguageintegercontroller.h new file mode 100644 index 000000000..d2ce6e1c5 --- /dev/null +++ b/src/settingslanguage/duisettingslanguageintegercontroller.h @@ -0,0 +1,56 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISETTINGSLANGUAGEINTEGERCONTROLLER_H_ +#define DUISETTINGSLANGUAGEINTEGERCONTROLLER_H_ + +#include + +/*! + * An interaction controller for integer items in settings language. + */ +class DuiSettingsLanguageIntegerController : public QObject +{ + Q_OBJECT + +public: + /*! + * Constructor. + * \param parent the parent object for this object. + */ + DuiSettingsLanguageIntegerController(QObject *parent = NULL); + + /*! + * Destructor. + */ + virtual ~DuiSettingsLanguageIntegerController(); + +public slots: + /*! + * Reacts to value changes. Stores the new value to the storage backend. + * + * The widget should have the following properties set: + * - key: the name of the value + * + * \param newValue the new value + */ + void changeValue(int newValue); +}; + +#endif /* DUISETTINGSLANGUAGEINTEGERCONTROLLER_H_ */ diff --git a/src/settingslanguage/duisettingslanguageintegerfactory.cpp b/src/settingslanguage/duisettingslanguageintegerfactory.cpp new file mode 100644 index 000000000..d22ae1e75 --- /dev/null +++ b/src/settingslanguage/duisettingslanguageintegerfactory.cpp @@ -0,0 +1,73 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duisettingslanguageinteger.h" +#include "duisettingslanguageintegerfactory.h" +#include "duisettingslanguageintegercontroller.h" + +#include +#include +#include +#include +#include + +DuiWidgetController *DuiSettingsLanguageIntegerFactory::createWidget(const DuiSettingsLanguageInteger &settingsInteger, DuiSettingsLanguageWidget &rootWidget, DuiDataStore *dataStore) +{ + Q_UNUSED(rootWidget); + + DuiWidgetController *parentWidget = new DuiWidgetController; + parentWidget->setView(new DuiWidgetView(parentWidget)); + + // Make an interaction controller and make it a child of the widget object (so that it gets destroyed when appropriate) + DuiSettingsLanguageIntegerController *intController = new DuiSettingsLanguageIntegerController(parentWidget); + intController->setProperty("dataStore", qVariantFromValue(static_cast(dataStore))); + intController->setProperty("key", settingsInteger.key()); + + // Create a horizontal layout + QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(Qt::Horizontal); + layout->setContentsMargins(0, 0, 0, 0); + layout->setSpacing(0); + parentWidget->setLayout(layout); + + // Create a label widget and put it into the layout + DuiLabel *label = new DuiLabel(settingsInteger.title()); + label->setObjectName("SettingsLanguageLabel"); + layout->addItem(label); + + DuiSlider *slider = new DuiSlider; + slider->setObjectName("SettingsLanguageSlider"); + int minVal; + if (settingsInteger.minValue(minVal)) { + slider->setMinimum(minVal); + } + int maxVal; + if (settingsInteger.maxValue(maxVal)) { + slider->setMaximum(maxVal); + } + + slider->connect(slider, SIGNAL(valueChanged(int)), intController, SLOT(changeValue(int))); + layout->addItem(slider); + + // Get the previously entered value if it exists + if (dataStore != NULL) { + slider->setValue(dataStore->value(settingsInteger.key()).toInt()); + } + + return parentWidget; +} diff --git a/src/settingslanguage/duisettingslanguageintegerfactory.h b/src/settingslanguage/duisettingslanguageintegerfactory.h new file mode 100644 index 000000000..514717bc0 --- /dev/null +++ b/src/settingslanguage/duisettingslanguageintegerfactory.h @@ -0,0 +1,51 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISETTINGSLANGUAGEINTEGERFACTORY_H_ +#define DUISETTINGSLANGUAGEINTEGERFACTORY_H_ + +class DuiWidgetController; +class DuiSettingsLanguageInteger; +class DuiSettingsLanguageWidget; +class DuiDataStore; + +/*! + * A factory for translating settings binaries to widgets. + */ +class DuiSettingsLanguageIntegerFactory +{ + /*! + * Private constructor to prevent construction. + */ + DuiSettingsLanguageIntegerFactory() {} + Q_DISABLE_COPY(DuiSettingsLanguageIntegerFactory) + +public: + /*! + * \brief Creates a widget from a DuiSettingsLanguageInteger representation. + * + * \param settingsInteger the settings binary representation. + * \param rootWidget the root of the widget hierarchy where the new widget will be attached. + * \param dataStore the data store for the settings. + * \return a widget. + */ + static DuiWidgetController *createWidget(const DuiSettingsLanguageInteger &settingsInteger, DuiSettingsLanguageWidget &rootWidget, DuiDataStore *dataStore = NULL); +}; + +#endif /* DUISETTINGSLANGUAGEINTEGERFACTORY_H_ */ diff --git a/src/settingslanguage/duisettingslanguagenode.cpp b/src/settingslanguage/duisettingslanguagenode.cpp new file mode 100644 index 000000000..7212c612b --- /dev/null +++ b/src/settingslanguage/duisettingslanguagenode.cpp @@ -0,0 +1,48 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duisettingslanguagenode.h" + +DuiSettingsLanguageNode::DuiSettingsLanguageNode() : + _children() +{ +} + +DuiSettingsLanguageNode::~DuiSettingsLanguageNode() +{ + // Delete the children to free memory + foreach(DuiSettingsLanguageNode * child, _children) { + delete child; + } +} + +void DuiSettingsLanguageNode::addChild(DuiSettingsLanguageNode *child) +{ + _children.append(child); +} + +uint DuiSettingsLanguageNode::numChildren() const +{ + return _children.count(); +} + +QList DuiSettingsLanguageNode::children() const +{ + return _children; +} diff --git a/src/settingslanguage/duisettingslanguagenode.h b/src/settingslanguage/duisettingslanguagenode.h new file mode 100644 index 000000000..b48b584a2 --- /dev/null +++ b/src/settingslanguage/duisettingslanguagenode.h @@ -0,0 +1,73 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISETTINGSLANGUAGENODE_H +#define DUISETTINGSLANGUAGENODE_H + +#include + +/*! + * \brief An abstract base class for the different settings binary nodes. + * + * This class provides support for constructing tree structures of the + * settings binary nodes. + */ +class DuiSettingsLanguageNode +{ +public: + /*! + * \brief Destructor. + * + * Also destroys all child nodes recursively so for the user it's enough + * to destroy the root node. + */ + virtual ~DuiSettingsLanguageNode() = 0; + + /*! + * Adds a child node to this node. + *\param child the child to be added. + */ + void addChild(DuiSettingsLanguageNode *child); + + /*! + * Gets the number of child nodes this node currently has. + * \return the number of child nodes. + */ + uint numChildren() const; + + /*! + * Gets the list of child nodes this node currently has. + * \return a list of child nodes. + */ + QList children() const; + +protected: + /*! + * \brief Constructor. + */ + DuiSettingsLanguageNode(); + +private: + /*! + * Container for the child nodes. + */ + QList _children; +}; + +#endif // DUISETTINGSLANGUAGENODE_H diff --git a/src/settingslanguage/duisettingslanguageoption.cpp b/src/settingslanguage/duisettingslanguageoption.cpp new file mode 100644 index 000000000..8184da45e --- /dev/null +++ b/src/settingslanguage/duisettingslanguageoption.cpp @@ -0,0 +1,41 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duisettingslanguageoption.h" + +DuiSettingsLanguageOption::DuiSettingsLanguageOption(const QString &title, int value) : + title_(title), + value_(value) +{ +} + +DuiSettingsLanguageOption::~DuiSettingsLanguageOption() +{ +} + +QString DuiSettingsLanguageOption::title() const +{ + return qtTrId(title_.toUtf8()); +} + +int DuiSettingsLanguageOption::value() const +{ + return value_; +} + diff --git a/src/settingslanguage/duisettingslanguageoption.h b/src/settingslanguage/duisettingslanguageoption.h new file mode 100644 index 000000000..d665b2933 --- /dev/null +++ b/src/settingslanguage/duisettingslanguageoption.h @@ -0,0 +1,65 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISETTINGSLANGUAGEOPTION_H +#define DUISETTINGSLANGUAGEOPTION_H + +#include "duisettingslanguagenode.h" +#include + +/*! + * \brief A settings node representing a selection option. + * + * A selection option has a title and a value. + */ +class DuiSettingsLanguageOption : public DuiSettingsLanguageNode +{ +public: + /*! + * Constructs a new selection option with a given title and value. + * \param title the title of the selection option. + * \param value the value of the selection option. + */ + DuiSettingsLanguageOption(const QString &title, int value); + + /*! + * Destructor. + */ + virtual ~DuiSettingsLanguageOption(); + + /*! + * Returns the localized title of this selection option. + */ + QString title() const; + + /*! + * Returns the value of this selection option. + */ + int value() const; + +private: + //! The title of this selection option. + QString title_; + + //! The value of this selection option. + int value_; + +}; + +#endif // DUISETTINGSLANGUAGEOPTION_H diff --git a/src/settingslanguage/duisettingslanguageparser.cpp b/src/settingslanguage/duisettingslanguageparser.cpp new file mode 100644 index 000000000..9989da2a8 --- /dev/null +++ b/src/settingslanguage/duisettingslanguageparser.cpp @@ -0,0 +1,263 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duisettingslanguageparser.h" +#include "duisettingslanguageparser_p.h" +#include "duisettingslanguagebinary.h" +#include "duisettingslanguagenode.h" +#include "duisettingslanguagetext.h" +#include "duisettingslanguageselection.h" +#include "duisettingslanguagesettings.h" +#include "duisettingslanguageboolean.h" +#include "duisettingslanguageinteger.h" +#include "duisettingslanguagegroup.h" + +#include +#include + +#define PARSER_WARNING duiWarning("DuiSettingsLanguageParser") + +DuiSettingsLanguageParserPrivate::DuiSettingsLanguageParserPrivate() : + document(NULL) +{ +} + +DuiSettingsLanguageParserPrivate::~DuiSettingsLanguageParserPrivate() +{ + delete document; +} + +DuiSettingsLanguageParser::DuiSettingsLanguageParser() : + d_ptr(new DuiSettingsLanguageParserPrivate) +{ + Q_D(DuiSettingsLanguageParser); + + d->q_ptr = this; +} + +DuiSettingsLanguageParser::~DuiSettingsLanguageParser() +{ + delete d_ptr; +} + +bool DuiSettingsLanguageParser::readFrom(QIODevice &device) +{ + Q_D(DuiSettingsLanguageParser); + delete d->document; + d->document = new QDomDocument(); + return d->document->setContent(&device, false); +} + +DuiSettingsLanguageBinary *DuiSettingsLanguageParser::createSettingsBinary() +{ + Q_D(DuiSettingsLanguageParser); + + if (d->document == NULL) { + return NULL; + } + + DuiSettingsLanguageBinary *sb = new DuiSettingsLanguageBinary; + QDomElement root = d->document->documentElement(); + if (root.nodeName() == "settings") { + if (d->parse(root, *sb)) { + return sb; + } + } + + // Return NULL on error + delete sb; + return NULL; +} + +bool DuiSettingsLanguageParserPrivate::parse(const QDomElement &item, DuiSettingsLanguageNode &settingsNode) +{ + QString elementName = item.nodeName(); + + if (elementName == "settings") { + return parseSettings(item, settingsNode); + } else if (elementName == "selection") { + return parseSelection(item, settingsNode); + } else if (elementName == "option") { + return parseOption(item, settingsNode); + } else if (elementName == "text") { + return parseText(item, settingsNode); + } else if (elementName == "boolean") { + return parseBoolean(item, settingsNode); + } else if (elementName == "integer") { + return parseInteger(item, settingsNode); + } else if (elementName == "group") { + return parseGroup(item, settingsNode); + } + + return false; +} + +bool DuiSettingsLanguageParserPrivate::parseSettings(const QDomElement &item, DuiSettingsLanguageNode &settingsNode) +{ + // Possible children elements of a 'settings' element + const static QStringList itemChildElements = (QStringList() << "text" << "boolean" << "integer" << "selection" << "group"); + + DuiSettingsLanguageSettings *si = new DuiSettingsLanguageSettings; + settingsNode.addChild(si); + + // Parse child elements + return parseChildElements(item, *si, itemChildElements); +} + +bool DuiSettingsLanguageParserPrivate::parseGroup(const QDomElement &item, DuiSettingsLanguageNode &settingsNode) +{ + // Possible children elements of a 'settings' element + const static QStringList itemChildElements = (QStringList() << "text" << "boolean" + << "integer" << "selection"); + + DuiSettingsLanguageNode *group = new DuiSettingsLanguageGroup(); + settingsNode.addChild(group); + + // Parse child elements + return parseChildElements(item, *group, itemChildElements); +} + +bool DuiSettingsLanguageParserPrivate::parseSelection(const QDomElement &item, DuiSettingsLanguageNode &settingsNode) +{ + // Possible children elements of a 'selection' element + const static QStringList selectionChildElements = (QStringList() << "option"); + const static QStringList requiredAttributes = (QStringList() << "key"); + + if (checkAttributes(item, requiredAttributes)) { + DuiSettingsLanguageSelection *se = new DuiSettingsLanguageSelection(item.attribute("key")); + settingsNode.addChild(se); + + // Parse child elements + return parseChildElements(item, *se, selectionChildElements); + } else { + return false; + } +} + +bool DuiSettingsLanguageParserPrivate::parseInteger(const QDomElement &item, DuiSettingsLanguageNode &settingsNode) +{ + bool result = false; + + const static QStringList requiredAttributes = (QStringList() << "key" << "title"); + if (checkAttributes(item, requiredAttributes)) { + bool minOk = true; + bool maxOk = true; + int min = item.attribute("min").toInt(&minOk); + int max = item.attribute("max").toInt(&maxOk); + if (minOk && maxOk && min > max) { + minOk = false; + maxOk = false; + } + + DuiSettingsLanguageInteger *si = new DuiSettingsLanguageInteger(item.attribute("key"), item.attribute("title")); + if (minOk) + si->setMinValue(min); + if (maxOk) + si->setMaxValue(max); + + settingsNode.addChild(si); + result = true; + } + + return result; +} + +bool DuiSettingsLanguageParserPrivate::parseOption(const QDomElement &item, DuiSettingsLanguageNode &settingsNode) +{ + bool result = false; + const static QStringList requiredAttributes = (QStringList() << "title"); + + if (checkAttributes(item, requiredAttributes)) { + if (dynamic_cast(&settingsNode)) { + bool ok; + int value = item.text().toInt(&ok); + if (ok) { + static_cast(settingsNode).addOption(item.attribute("title"), value); + result = true; + } else { + PARSER_WARNING << "Contents of an \"option\" element can't be converted to an integer"; + } + } else { + PARSER_WARNING << "An \"option\" element must be child element of \"selection\""; + } + } + + return result; +} + +bool DuiSettingsLanguageParserPrivate::parseText(const QDomElement &item, DuiSettingsLanguageNode &settingsNode) +{ + const static QStringList requiredAttributes = (QStringList() << "key" << "title"); + + bool result = true; + if (checkAttributes(item, requiredAttributes)) { + DuiSettingsLanguageText *si = new DuiSettingsLanguageText(item.attribute("key"), item.attribute("title")); + settingsNode.addChild(si); + } else { + result = false; + } + + return result; +} + +bool DuiSettingsLanguageParserPrivate::parseBoolean(const QDomElement &item, DuiSettingsLanguageNode &settingsNode) +{ + const static QStringList requiredAttributes = (QStringList() << "key" << "title"); + + bool result = true; + if (checkAttributes(item, requiredAttributes)) { + DuiSettingsLanguageBoolean *sb = new DuiSettingsLanguageBoolean(item.attribute("key"), item.attribute("title")); + settingsNode.addChild(sb); + } else { + result = false; + } + + return result; +} + +bool DuiSettingsLanguageParserPrivate::checkAttributes(const QDomElement &item, const QStringList &requiredAttributes) const +{ + bool result = true; + // Check that every required attribute is specified in the DOM element + foreach(const QString & attr, requiredAttributes) { + if (!item.hasAttribute(attr)) { + PARSER_WARNING << item.nodeName() << "element is missing a required attribute" << attr; + result = false; + } + } + + return result; +} + +bool DuiSettingsLanguageParserPrivate::parseChildElements(const QDomElement &item, DuiSettingsLanguageNode &settingsNode, const QStringList &acceptedChildren) +{ + for (QDomElement child = item.firstChildElement(); !child.isNull(); child = child.nextSiblingElement()) { + if (acceptedChildren.contains(child.nodeName())) { + if (!parse(child, settingsNode)) { + // If child parsing fails, stop and return false + return false; + } + } else { + PARSER_WARNING << "Invalid child element" << child.nodeName() << "for an" << item.nodeName() << "element"; + return false; + } + } + + return true; +} diff --git a/src/settingslanguage/duisettingslanguageparser.h b/src/settingslanguage/duisettingslanguageparser.h new file mode 100644 index 000000000..619ed2d15 --- /dev/null +++ b/src/settingslanguage/duisettingslanguageparser.h @@ -0,0 +1,75 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISETTINGSLANGUAGEPARSER_H +#define DUISETTINGSLANGUAGEPARSER_H + +#include +#include +#include +#include +#include "duisettingslanguagebinary.h" + +class DuiSettingsLanguageParserPrivate; + +/*! + * \brief Parser class for the settings language. + * + * This class can be used to read in a settings language description + * and transfer it into a binary representation. + */ +class DUI_EXPORT DuiSettingsLanguageParser +{ +public: + /*! + * Constructs a parser. + */ + DuiSettingsLanguageParser(); + + /*! + * Destructor. + */ + virtual ~DuiSettingsLanguageParser(); + + /*! + * Reads an XML file from the provided device. Returns \c true on + * success, \c false on failure. + * \param device the device to read from. + */ + bool readFrom(QIODevice &device); + + /*! + * Constructs and returns a settings binary representation from + * the parsed language source. Returns \c NULL on error. + * + * \note The ownership of the returned binary is transfered to the caller. + * \return a settigns binary representation. + */ + DuiSettingsLanguageBinary *createSettingsBinary(); + +protected: + //! A pointer to the private class + DuiSettingsLanguageParserPrivate *const d_ptr; + +private: + Q_DISABLE_COPY(DuiSettingsLanguageParser) + Q_DECLARE_PRIVATE(DuiSettingsLanguageParser) +}; + +#endif // DUISETTINGSLANGUAGEPARSER_H diff --git a/src/settingslanguage/duisettingslanguageparser_p.h b/src/settingslanguage/duisettingslanguageparser_p.h new file mode 100644 index 000000000..1172b745a --- /dev/null +++ b/src/settingslanguage/duisettingslanguageparser_p.h @@ -0,0 +1,138 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISETTINGSLANGUAGEPARSER_P_H_ +#define DUISETTINGSLANGUAGEPARSER_P_H_ + +class DuiSettingsLanguageParser; + +class DuiSettingsLanguageParserPrivate +{ + Q_DECLARE_PUBLIC(DuiSettingsLanguageParser) + +public: + /*! + * Constructs a private class for DuiSettingsLanguage. + */ + DuiSettingsLanguageParserPrivate(); + + /*! + * Destroys the DuiSettingsLanguagePrivate. + */ + virtual ~DuiSettingsLanguageParserPrivate(); + + //! The XML document to parse the information from + QDomDocument *document; + + /*! + * Parses an XML element. Basically just selects a parser subroutine. + * \param item the XML element to parse. + * \param settingsNode the binary node to which to add the binary nodes + * generated by the parsing. + * \return \c true on success, \false on failure. + */ + bool parse(const QDomElement &item, DuiSettingsLanguageNode &settingsNode); + + /*! + * Parses a 'settings' element. + * \param item the XML element to parse. + * \param settingsNode the binary node to which to add the binary nodes + * generated by the parsing. + * \return \c true on success, \false on failure. + */ + bool parseSettings(const QDomElement &item, DuiSettingsLanguageNode &settingsNode); + + /*! + * Parses a 'group' element. + * \param item the XML element to parse. + * \param settingsNode the binary node to which to add the binary nodes + * generated by the parsing. + * \return \c true on success, \false on failure. + */ + bool parseGroup(const QDomElement &item, DuiSettingsLanguageNode &settingsNode); + + /*! + * Parses a 'selection' element. + * \param item the XML element to parse. + * \param settingsNode the binary node to which to add the binary nodes + * generated by the parsing. + * \return \c true on success, \false on failure. + */ + bool parseSelection(const QDomElement &item, DuiSettingsLanguageNode &settingsNode); + + /*! + * Parses an 'integer' element. + * \param item the XML element to parse. + * \param settingsNode the binary node to which to add the binary nodes + * generated by the parsing. + * \return \c true on success, \false on failure. + */ + bool parseInteger(const QDomElement &item, DuiSettingsLanguageNode &settingsNode); + + /*! + * Parses an 'option' element. + * \param item the XML element to parse. + * \param settingsNode the binary node to which to add the binary nodes + * generated by the parsing. + * \return \c true on success, \false on failure. + */ + bool parseOption(const QDomElement &item, DuiSettingsLanguageNode &settingsNode); + + /*! + * Parses a 'text' element. + * \param item the XML element to parse. + * \param settingsNode the binary node to which to add the binary nodes + * generated by the parsing. + * \return \c true on success, \false on failure. + */ + bool parseText(const QDomElement &item, DuiSettingsLanguageNode &settingsNode); + + /*! + * Parses a 'boolean' element. + * \param item the XML element to parse. + * \param settingsNode the binary node to which to add the binary nodes + * generated by the parsing. + * \return \c true on success, \false on failure. + */ + bool parseBoolean(const QDomElement &item, DuiSettingsLanguageNode &settingsNode); + + /*! + * Checks existance of attributes in an XML element. Returns \c true + * if every required attribute is present and \c false otherwise. + * \param item the XML element to study. + * \param requiredAttributes a list attributes that are required to be present. + * \return \c true if attributes are OK, \c false otherwise. + */ + bool checkAttributes(const QDomElement &item, const QStringList &requiredAttributes) const; + + /*! + * A helper method for parsing child elements of a DOM element. + * \param item the parent node whose children will be parsed + * \param settingsNode the parent settings binary node where the parsed children will be added + * \param acceptedChildren a list of acceptable child element names + * \return \c true on success, \false on failure. + */ + bool parseChildElements(const QDomElement &item, DuiSettingsLanguageNode &settingsNode, const QStringList &acceptedChildren); + +protected: + //! A pointer to the public class + DuiSettingsLanguageParser *q_ptr; +}; + +#endif /* DUISETTINGSLANGUAGEPARSER_P_H_ */ diff --git a/src/settingslanguage/duisettingslanguageselection.cpp b/src/settingslanguage/duisettingslanguageselection.cpp new file mode 100644 index 000000000..33c2b4608 --- /dev/null +++ b/src/settingslanguage/duisettingslanguageselection.cpp @@ -0,0 +1,73 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duisettingslanguageselection.h" +#include "duisettingslanguageoption.h" + +DuiSettingsLanguageSelection::DuiSettingsLanguageSelection(const QString &key) : + _key(key) +{ +} + +DuiSettingsLanguageSelection::~DuiSettingsLanguageSelection() +{ +} + +QString DuiSettingsLanguageSelection::key() const +{ + return _key; +} + +DuiSettingsLanguageOption *DuiSettingsLanguageSelection::addOption(const QString &title, int value) +{ + DuiSettingsLanguageOption *v = new DuiSettingsLanguageOption(title, value); + addChild(v); + return v; +} + +DuiSettingsLanguageOption *DuiSettingsLanguageSelection::addOption(DuiSettingsLanguageOption *option) +{ + addChild(option); + return option; +} + +uint DuiSettingsLanguageSelection::numOptions() const +{ + uint n = 0; + foreach(const DuiSettingsLanguageNode * child, children()) { + if (dynamic_cast(child)) { + ++n; + } + } + + return n; +} + +QList DuiSettingsLanguageSelection::options() const +{ + QList vs; + foreach(const DuiSettingsLanguageNode * child, children()) { + const DuiSettingsLanguageOption *optionChild; + if ((optionChild = dynamic_cast(child))) { + vs.append(optionChild); + } + } + + return vs; +} diff --git a/src/settingslanguage/duisettingslanguageselection.h b/src/settingslanguage/duisettingslanguageselection.h new file mode 100644 index 000000000..8ba5abf25 --- /dev/null +++ b/src/settingslanguage/duisettingslanguageselection.h @@ -0,0 +1,92 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISETTINGSLANGUAGESELECTION_H +#define DUISETTINGSLANGUAGESELECTION_H + +#include +#include + +#include "duisettingslanguagenode.h" + +class DuiSettingsLanguageOption; + +/*! + * \brief A settings node representing a selection. + * + * A selection has a predefined set of options. + * + * A selection contains \link DuiSettingsLanguageOption \endlink nodes. + */ +class DuiSettingsLanguageSelection : public DuiSettingsLanguageNode +{ +public: + /*! + * Constructs a new selection with a given key. + * \param key the key (name) of the selection. + */ + DuiSettingsLanguageSelection(const QString &key); + + /*! + * Destructor. + */ + virtual ~DuiSettingsLanguageSelection(); + + /*! + * Returns the key of this selection. + */ + QString key() const; + + /*! + * Adds a new option to this selection. + * \param title the title for the new option. + * \param value the value for the new option. + * \return the newly constructed option object. + * \sa DuiSettingsLanguageOption + */ + DuiSettingsLanguageOption *addOption(const QString &title, int value); + + /*! + * Adds a new option to this selection. This version of the method + * can be used if the option object is already constructed by some + * other party. + * \param option the option to be added. + * \return the same pointer as was given as parameter if the addition + * was succesfull. Returns \c NULL if the addition couldn't be done. + * \sa DuiSettingsLanguageOption + */ + DuiSettingsLanguageOption *addOption(DuiSettingsLanguageOption *option); + + /*! + * Returns the number of child nodes of type DuiSettingsLanguageOption. + */ + uint numOptions() const; + + /*! + * Returns the DuiSettingsLanguageOption child nodes that this node has. + */ + QList options() const; + +private: + //! The key (name) of this object. + QString _key; + +}; + +#endif // DUISETTINGSLANGUAGESELECTION_H diff --git a/src/settingslanguage/duisettingslanguageselectioncontroller.cpp b/src/settingslanguage/duisettingslanguageselectioncontroller.cpp new file mode 100644 index 000000000..5778d5d40 --- /dev/null +++ b/src/settingslanguage/duisettingslanguageselectioncontroller.cpp @@ -0,0 +1,40 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duisettingslanguageselectioncontroller.h" + +#include +#include + +DuiSettingsLanguageSelectionController::DuiSettingsLanguageSelectionController(QObject *parent) : + QObject(parent) +{ +} + +DuiSettingsLanguageSelectionController::~DuiSettingsLanguageSelectionController() +{ +} + +void DuiSettingsLanguageSelectionController::buttonClicked(DuiButton *button) +{ + DuiDataStore *dataStore = static_cast(button->property("dataStore").value()); + if (dataStore != NULL) { + dataStore->createValue(button->property("key").toString(), button->property("value").toInt()); + } +} diff --git a/src/settingslanguage/duisettingslanguageselectioncontroller.h b/src/settingslanguage/duisettingslanguageselectioncontroller.h new file mode 100644 index 000000000..77b3537ba --- /dev/null +++ b/src/settingslanguage/duisettingslanguageselectioncontroller.h @@ -0,0 +1,58 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISETTINGSLANGUAGESELECTIONCONTROLLER_H_ +#define DUISETTINGSLANGUAGESELECTIONCONTROLLER_H_ + +#include + +class DuiButton; + +/*! + * An interaction controller for selection items in settings language. + */ +class DuiSettingsLanguageSelectionController : public QObject +{ + Q_OBJECT + +public: + /*! + * Constructor. + * \param parent the parent object for this object. + */ + DuiSettingsLanguageSelectionController(QObject *parent = NULL); + + /*! + * Destructor. + */ + virtual ~DuiSettingsLanguageSelectionController(); + +public slots: + /*! + * Reacts to button clicks. Stores the selected buttons values to storage backend. + * The button should have the following properties set: + * - key: the name of the value + * - value: the value that should be set + * \param button the button that was clicked + */ + void buttonClicked(DuiButton *button); + +}; + +#endif /* DUISETTINGSLANGUAGESELECTIONCONTROLLER_H_ */ diff --git a/src/settingslanguage/duisettingslanguageselectionfactory.cpp b/src/settingslanguage/duisettingslanguageselectionfactory.cpp new file mode 100644 index 000000000..c39c9b01f --- /dev/null +++ b/src/settingslanguage/duisettingslanguageselectionfactory.cpp @@ -0,0 +1,71 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duisettingslanguageselectionfactory.h" +#include "duisettingslanguageselectioncontroller.h" +#include "duisettingslanguageselection.h" +#include "duisettingslanguageoption.h" + +#include +#include +#include +#include +#include + +DuiWidgetController *DuiSettingsLanguageSelectionFactory::createWidget(const DuiSettingsLanguageSelection &settingsSelection, + DuiSettingsLanguageWidget &rootWidget, DuiDataStore *dataStore) +{ + Q_UNUSED(rootWidget) + + DuiWidgetController *parentWidget = new DuiWidgetController; + parentWidget->setView(new DuiWidgetView(parentWidget)); + + // Make an interaction controller and make it a child of the widget object (so that it gets destroyed when appropriate) + DuiSettingsLanguageSelectionController *selectionController = new DuiSettingsLanguageSelectionController(parentWidget); + + // Create a horizontal layout + QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(Qt::Horizontal); + layout->setContentsMargins(0, 0, 0, 0); + layout->setSpacing(0); + parentWidget->setLayout(layout); + + // Create a button group + DuiButtonGroup *buttonGroup = new DuiButtonGroup(parentWidget); + buttonGroup->connect(buttonGroup, SIGNAL(buttonClicked(DuiButton *)), selectionController, SLOT(buttonClicked(DuiButton *))); + + // Get the previously selected value or use 0 if it doesn't exist + int selectedValue = dataStore != NULL ? dataStore->value(settingsSelection.key()).toInt() : 0; + foreach(const DuiSettingsLanguageOption * value, settingsSelection.options()) { + // Create a radio button for the enum value + DuiButton *button = new DuiButton(parentWidget); + button->setText(value->title()); + button->setCheckable(true); + button->setObjectName("SettingsLanguageOptionButton"); + button->setChecked(value->value() == selectedValue); + button->setProperty("dataStore", qVariantFromValue(static_cast(dataStore))); + button->setProperty("key", settingsSelection.key()); + button->setProperty("value", value->value()); + layout->addItem(button); + + // Add the button to a button group + buttonGroup->addButton(button); + } + + return parentWidget; +} diff --git a/src/settingslanguage/duisettingslanguageselectionfactory.h b/src/settingslanguage/duisettingslanguageselectionfactory.h new file mode 100644 index 000000000..7571fe1e2 --- /dev/null +++ b/src/settingslanguage/duisettingslanguageselectionfactory.h @@ -0,0 +1,54 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISETTINGSLANGUAGESELECTIONFACTORY_H_ +#define DUISETTINGSLANGUAGESELECTIONFACTORY_H_ + +#include + +class DuiWidgetController; +class DuiSettingsLanguageWidget; +class DuiDataStore; +class DuiSettingsLanguageSelection; + +/*! + * A factory for translating settings binaries to widgets. + */ +class DuiSettingsLanguageSelectionFactory +{ + /*! + * Private constructor to prevent construction. + */ + DuiSettingsLanguageSelectionFactory() {} + Q_DISABLE_COPY(DuiSettingsLanguageSelectionFactory) + +public: + /*! + * \brief Creates a widget from a DuiSettingsLanguageSelection representation. + * + * \param selection the settings binary representation. + * \param rootWidget the root of the widget hierarchy where the new widget will be attached. + * \param dataStore the data store for the settings. + * \return a widget. + */ + static DuiWidgetController *createWidget(const DuiSettingsLanguageSelection &settingsSelection, DuiSettingsLanguageWidget &rootWidget, DuiDataStore *dataStore = NULL); + +}; + +#endif /* DUISETTINGSLANGUAGESELECTIONFACTORY_H_ */ diff --git a/src/settingslanguage/duisettingslanguagesettings.cpp b/src/settingslanguage/duisettingslanguagesettings.cpp new file mode 100644 index 000000000..c105df79d --- /dev/null +++ b/src/settingslanguage/duisettingslanguagesettings.cpp @@ -0,0 +1,28 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duisettingslanguagesettings.h" + +DuiSettingsLanguageSettings::DuiSettingsLanguageSettings() +{ +} + +DuiSettingsLanguageSettings::~DuiSettingsLanguageSettings() +{ +} diff --git a/src/settingslanguage/duisettingslanguagesettings.h b/src/settingslanguage/duisettingslanguagesettings.h new file mode 100644 index 000000000..504dda1db --- /dev/null +++ b/src/settingslanguage/duisettingslanguagesettings.h @@ -0,0 +1,53 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISETTINGSLANGUAGESETTINGS_H +#define DUISETTINGSLANGUAGESETTINGS_H + +#include +#include "duisettingslanguagenode.h" + +/*! + * \brief A settings node representing a "settings root node 'settings'". + */ +class DuiSettingsLanguageSettings : public DuiSettingsLanguageNode +{ +public: + /*! + * Constructs a DuiSettingsLanguageSettings node. + */ + DuiSettingsLanguageSettings(); + + /*! + * Destroys the DuiSettingsLanguageSettings node. + */ + virtual ~DuiSettingsLanguageSettings(); + +private: + //! The title of this settings. + QString _title; + + //! Whether this settings should be represented as a group. + bool _group; + + //! The IRI of the content this is linked to + QString _content; +}; + +#endif // DUISETTINGSLANGUAGESETTINGS_H diff --git a/src/settingslanguage/duisettingslanguagesettingsfactory.cpp b/src/settingslanguage/duisettingslanguagesettingsfactory.cpp new file mode 100644 index 000000000..d4594cbd4 --- /dev/null +++ b/src/settingslanguage/duisettingslanguagesettingsfactory.cpp @@ -0,0 +1,101 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duisettingslanguagesettingsfactory.h" +#include "duisettingslanguagewidget.h" +#include "duisettingslanguagenode.h" +#include "duisettingslanguageselectionfactory.h" +#include "duisettingslanguagetextfactory.h" +#include "duisettingslanguageintegerfactory.h" +#include "duisettingslanguagetext.h" +#include "duisettingslanguagesettings.h" +#include "duisettingslanguageselection.h" +#include "duisettingslanguageinteger.h" +#include "duitheme.h" +#include "duisettingslanguagesettingsfactorystyle.h" +#include "duisettingslanguagebooleanfactory.h" +#include "duisettingslanguageboolean.h" +#include "duisettingslanguagegroup.h" + +#include +#include +#include +#include +#include +#include +#include + +DuiWidgetController *DuiSettingsLanguageSettingsFactory::createWidget(const DuiSettingsLanguageSettings &settingsItem, DuiSettingsLanguageWidget &rootWidget, DuiDataStore *dataStore) +{ + const DuiSettingsLanguageSettingsFactoryStyle *style = + static_cast + (DuiTheme::style("DuiSettingsLanguageSettingsFactoryStyle", "", "", "", Dui::Landscape, NULL)); + + // Create content layout to layout content items in + QGraphicsLinearLayout *contentLayout = new QGraphicsLinearLayout(Qt::Vertical); + contentLayout->setContentsMargins(0, 0, 0, 0); + + DuiWidgetController *widget = new DuiWidgetController; + widget->setView(new DuiWidgetView(widget)); + widget->setObjectName("DuiSettingsLanguage"); + widget->setLayout(contentLayout); + + createChildren(*contentLayout, settingsItem, rootWidget, dataStore); + + DuiTheme::releaseStyle(style); + + return widget; +} + +void DuiSettingsLanguageSettingsFactory::createChildren(QGraphicsLinearLayout &layout, const DuiSettingsLanguageNode &node, + DuiSettingsLanguageWidget &rootWidget, DuiDataStore *dataStore) +{ + // Go through all children of the item + foreach(DuiSettingsLanguageNode * child, node.children()) { + DuiWidgetController *childWidget = NULL; + + const DuiSettingsLanguageSelection *selectionNode; + const DuiSettingsLanguageInteger *intNode; + const DuiSettingsLanguageText *textNode; + const DuiSettingsLanguageBoolean *booleanNode; + + if ((selectionNode = dynamic_cast(child))) { + childWidget = DuiSettingsLanguageSelectionFactory::createWidget(*selectionNode, rootWidget, dataStore); + } else if ((intNode = dynamic_cast(child))) { + childWidget = DuiSettingsLanguageIntegerFactory::createWidget(*intNode, rootWidget, dataStore); + } else if ((textNode = dynamic_cast(child))) { + childWidget = DuiSettingsLanguageTextFactory::createWidget(*textNode, rootWidget, dataStore); + } else if ((booleanNode = dynamic_cast(child))) { + childWidget = DuiSettingsLanguageBooleanFactory::createWidget(*booleanNode, rootWidget, dataStore); + } else if ((dynamic_cast(child))) { + DuiContainer *container = new DuiContainer; + container->setObjectName("SettingsLanguageGroupContainer"); + QGraphicsLinearLayout *groupContentLayout = new QGraphicsLinearLayout(Qt::Vertical); + groupContentLayout->setContentsMargins(0, 0, 0, 0); + container->setLayout(groupContentLayout); + + createChildren(*groupContentLayout, *child, rootWidget, dataStore); + childWidget = container; + } + + if (childWidget != NULL) { + layout.addItem(childWidget); + } + } +} diff --git a/src/settingslanguage/duisettingslanguagesettingsfactory.h b/src/settingslanguage/duisettingslanguagesettingsfactory.h new file mode 100644 index 000000000..3628a3801 --- /dev/null +++ b/src/settingslanguage/duisettingslanguagesettingsfactory.h @@ -0,0 +1,67 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISETTINGSLANGUAGESETTINGSFACTORY_H_ +#define DUISETTINGSLANGUAGESETTINGSFACTORY_H_ + +#include + +class QGraphicsLinearLayout; +class DuiWidgetController; +class DuiDataStore; +class DuiSettingsLanguageNode; +class DuiSettingsLanguageSettings; +class DuiSettingsLanguageWidget; + +/*! + * A factory for translating settings binaries to widgets. + */ +class DuiSettingsLanguageSettingsFactory +{ + /*! + * Private constructor to prevent construction. + */ + DuiSettingsLanguageSettingsFactory() {} + Q_DISABLE_COPY(DuiSettingsLanguageSettingsFactory) + +public: + /*! + * \brief Creates a widget from a DuiSettingsLanguageSettings representation. + * + * \param settingsItem the settings binary representation. + * \param rootWidget the root of the widget hierarchy where the new widget will be attached. + * \param dataStore the data store for the settings. + * \return a widget. + */ + static DuiWidgetController *createWidget(const DuiSettingsLanguageSettings &settingsItem, DuiSettingsLanguageWidget &rootWidget, DuiDataStore *dataStore = NULL); + +private: + + /*! + * Creates child widgets to a layout from a DuiSettingsLanguageNode representation. + * + * \param layout the layout where widgets are added. + * \param node the nodes binary representation. + * \param rootWidget the root of the widget hierarchy where the new widget will be attached. + * \param dataStore the data store for the settings. + */ + static void createChildren(QGraphicsLinearLayout &layout, const DuiSettingsLanguageNode &node, DuiSettingsLanguageWidget &rootWidget, DuiDataStore *dataStore); +}; + +#endif /* DUISETTINGSLANGUAGESETTINGSFACTORY_H_ */ diff --git a/src/settingslanguage/duisettingslanguagetext.cpp b/src/settingslanguage/duisettingslanguagetext.cpp new file mode 100644 index 000000000..e0394aa46 --- /dev/null +++ b/src/settingslanguage/duisettingslanguagetext.cpp @@ -0,0 +1,40 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duisettingslanguagetext.h" + +DuiSettingsLanguageText::DuiSettingsLanguageText(const QString &key, const QString &title) : + key_(key), + title_(title) +{ +} + +DuiSettingsLanguageText::~DuiSettingsLanguageText() +{ +} + +QString DuiSettingsLanguageText::key() const +{ + return key_; +} + +QString DuiSettingsLanguageText::title() const +{ + return qtTrId(title_.toUtf8());; +} diff --git a/src/settingslanguage/duisettingslanguagetext.h b/src/settingslanguage/duisettingslanguagetext.h new file mode 100644 index 000000000..292f73514 --- /dev/null +++ b/src/settingslanguage/duisettingslanguagetext.h @@ -0,0 +1,61 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISETTINGSLANGUAGETEXT_H +#define DUISETTINGSLANGUAGETEXT_H + +#include +#include "duisettingslanguagenode.h" +/*! + * \brief A settings node representing text. + */ +class DuiSettingsLanguageText : public DuiSettingsLanguageNode +{ +public: + /*! + * Constructs a new text settings node. + * \param key the key (name) of the text item. + * \param title the title of the text item. + */ + DuiSettingsLanguageText(const QString &key, const QString &title); + + /*! + * Destructor + */ + virtual ~DuiSettingsLanguageText(); + + /*! + * Returns the key of this text node. + */ + QString key() const; + + /*! + * Returns the localized title of this text node. + */ + QString title() const; + +private: + //! The key (name) of this object. + QString key_; + //! The title of this object. + QString title_; +}; + + +#endif // DUISETTINGSLANGUAGETEXT_H diff --git a/src/settingslanguage/duisettingslanguagetextcontroller.cpp b/src/settingslanguage/duisettingslanguagetextcontroller.cpp new file mode 100644 index 000000000..9c322b966 --- /dev/null +++ b/src/settingslanguage/duisettingslanguagetextcontroller.cpp @@ -0,0 +1,45 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duisettingslanguagetextcontroller.h" + +#include +#include + +DuiSettingsLanguageTextController::DuiSettingsLanguageTextController(QObject *parent) : + QObject(parent) +{ +} + +DuiSettingsLanguageTextController::~DuiSettingsLanguageTextController() +{ +} + +void DuiSettingsLanguageTextController::textEditLostFocus(Qt::FocusReason) +{ + // get text edit from signal sender + DuiTextEdit *textEdit = static_cast(sender()); + + if (textEdit != NULL) { + DuiDataStore *dataStore = static_cast(textEdit->property("dataStore").value()); + if (dataStore != NULL) { + dataStore->createValue(textEdit->property("key").toString(), textEdit->text()); + } + } +} diff --git a/src/settingslanguage/duisettingslanguagetextcontroller.h b/src/settingslanguage/duisettingslanguagetextcontroller.h new file mode 100644 index 000000000..c8e31f589 --- /dev/null +++ b/src/settingslanguage/duisettingslanguagetextcontroller.h @@ -0,0 +1,59 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISETTINGSLANGUAGETEXTCONTROLLER_H_ +#define DUISETTINGSLANGUAGETEXTCONTROLLER_H_ + +#include + +class DuiTextEdit; + +/*! + * An interaction controller for text items in settings language. + */ +class DuiSettingsLanguageTextController : public QObject +{ + Q_OBJECT + +public: + /*! + * Constructor. + * \param parent the parent object for this object. + */ + DuiSettingsLanguageTextController(QObject *parent = NULL); + + /*! + * Destructor. + */ + virtual ~DuiSettingsLanguageTextController(); + +public slots: + /*! + * Reacts to text changes. Stores the text in the sender DuiTextEdit + * widget to the storage backend. + * + * The widget should have the following properties set: + * - key: the name of the value + * + * \param reason the reason why the focus was lost + */ + void textEditLostFocus(Qt::FocusReason reason); +}; + +#endif /* DUISETTINGSLANGUAGETEXTCONTROLLER_H_ */ diff --git a/src/settingslanguage/duisettingslanguagetextfactory.cpp b/src/settingslanguage/duisettingslanguagetextfactory.cpp new file mode 100644 index 000000000..206cea8c5 --- /dev/null +++ b/src/settingslanguage/duisettingslanguagetextfactory.cpp @@ -0,0 +1,66 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duisettingslanguagetextfactory.h" +#include "duisettingslanguagetextcontroller.h" +#include "duisettingslanguagebinary.h" +#include "duisettingslanguagetext.h" + +#include +#include +#include +#include +#include + +DuiWidgetController *DuiSettingsLanguageTextFactory::createWidget(const DuiSettingsLanguageText &settingsText, DuiSettingsLanguageWidget &rootWidget, DuiDataStore *dataStore) +{ + Q_UNUSED(rootWidget); + + DuiWidgetController *parentWidget = new DuiWidgetController; + parentWidget->setView(new DuiWidgetView(parentWidget)); + + // Make an interaction controller and make it a child of the widget object (so that it gets destroyed when appropriate) + DuiSettingsLanguageTextController *textController = new DuiSettingsLanguageTextController(parentWidget); + + // Create a horizontal layout + QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(Qt::Horizontal); + layout->setContentsMargins(0, 0, 0, 0); + layout->setSpacing(0); + parentWidget->setLayout(layout); + + // Create a label widget and put it into the layout + DuiLabel *label = new DuiLabel(settingsText.title()); + label->setObjectName("SettingsLanguageLabel"); + layout->addItem(label); + + // Create a text edit widget and put it into the layout + DuiTextEdit *textEdit = new DuiTextEdit; + textEdit->setObjectName("SettingsLanguageTextTextEdit"); + textEdit->connect(textEdit, SIGNAL(lostFocus(Qt::FocusReason)), textController, SLOT(textEditLostFocus(Qt::FocusReason))); + textEdit->setProperty("dataStore", qVariantFromValue(static_cast(dataStore))); + textEdit->setProperty("key", settingsText.key()); + layout->addItem(textEdit); + + // Get the previously entered value if it exists + if (dataStore != NULL) { + textEdit->setText(dataStore->value(settingsText.key()).toString()); + } + + return parentWidget; +} diff --git a/src/settingslanguage/duisettingslanguagetextfactory.h b/src/settingslanguage/duisettingslanguagetextfactory.h new file mode 100644 index 000000000..859435b7b --- /dev/null +++ b/src/settingslanguage/duisettingslanguagetextfactory.h @@ -0,0 +1,53 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISETTINGSLANGUAGETEXTFACTORY_H_ +#define DUISETTINGSLANGUAGETEXTFACTORY_H_ + +#include + +class DuiWidgetController; +class DuiSettingsLanguageText; +class DuiSettingsLanguageWidget; +class DuiDataStore; + +/*! + * A factory for translating settings binaries to widgets. + */ +class DuiSettingsLanguageTextFactory +{ + /*! + * Private constructor to prevent construction. + */ + DuiSettingsLanguageTextFactory() {} + Q_DISABLE_COPY(DuiSettingsLanguageTextFactory) + +public: + /*! + * \brief Creates a widget from a DuiSettingsLanguageText representation. + * + * \param settingsText the settings binary representation. + * \param rootWidget the root of the widget hierarchy where the new widget will be attached. + * \param dataStore the data store for the settings. + * \return a widget. + */ + static DuiWidgetController *createWidget(const DuiSettingsLanguageText &settingsText, DuiSettingsLanguageWidget &rootWidget, DuiDataStore *dataStore = NULL); +}; + +#endif /* DUISETTINGSLANGUAGETEXTFACTORY_H_ */ diff --git a/src/settingslanguage/duisettingslanguagewidget.cpp b/src/settingslanguage/duisettingslanguagewidget.cpp new file mode 100644 index 000000000..1d975c253 --- /dev/null +++ b/src/settingslanguage/duisettingslanguagewidget.cpp @@ -0,0 +1,30 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duisettingslanguagewidget.h" +#include + +DuiSettingsLanguageWidget::DuiSettingsLanguageWidget(QGraphicsItem *parent) : + DuiWidgetController(new DuiSettingsLanguageWidgetModel, parent) +{ +} + +DuiSettingsLanguageWidget::~DuiSettingsLanguageWidget() +{ +} diff --git a/src/settingslanguage/duisettingslanguagewidget.h b/src/settingslanguage/duisettingslanguagewidget.h new file mode 100644 index 000000000..68cfda107 --- /dev/null +++ b/src/settingslanguage/duisettingslanguagewidget.h @@ -0,0 +1,56 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISETTINGSLANGUAGEWIDGET_H_ +#define DUISETTINGSLANGUAGEWIDGET_H_ + +#include +#include "duiexport.h" + +typedef DuiWidgetModel DuiSettingsLanguageWidgetModel; + +/*! + * DuiSettingsLanguageWidget is a UI component that represents a DuiSettingsLanguageBinary node. + */ +class DUI_EXPORT DuiSettingsLanguageWidget : public DuiWidgetController +{ + Q_OBJECT + DUI_CONTROLLER(DuiSettingsLanguageWidget) + +public: + /*! + * Constructs a new DuiSettingsLanguageWidget. + * + * \param parent the parent for the menu item + */ + DuiSettingsLanguageWidget(QGraphicsItem *parent = NULL); + + /*! + * Destroys the DuiSettingsLanguageWidget. + */ + virtual ~DuiSettingsLanguageWidget(); + +Q_SIGNALS: + /*! + * \brief Signal for informing that action is triggered by the widget. + */ + void actionTriggered(); +}; + +#endif /* DUISETTINGSLANGUAGEWIDGET_H_ */ diff --git a/src/settingslanguage/duisettingslanguagewidgetfactory.cpp b/src/settingslanguage/duisettingslanguagewidgetfactory.cpp new file mode 100644 index 000000000..367027ad2 --- /dev/null +++ b/src/settingslanguage/duisettingslanguagewidgetfactory.cpp @@ -0,0 +1,51 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duisettingslanguagewidgetfactory.h" +#include "duisettingslanguagebinary.h" +#include "duisettingslanguagewidget.h" +#include "duisettingslanguagesettings.h" + +#include "duisettingslanguagesettingsfactory.h" + +#include + +DuiSettingsLanguageWidget *DuiSettingsLanguageWidgetFactory::createWidget(const DuiSettingsLanguageBinary &settingsBinary, DuiDataStore *dataStore) +{ + DuiSettingsLanguageWidget *widget = new DuiSettingsLanguageWidget; + widget->setObjectName("DuiSettingsLanguage"); + + // Create a central layout + QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(Qt::Vertical); + // Set layout parameters + layout->setContentsMargins(0, 0, 0, 0); + layout->setSpacing(0); + widget->setLayout(layout); + + foreach(DuiSettingsLanguageNode * settingsNode, settingsBinary.children()) { + DuiSettingsLanguageSettings *settingsItem = dynamic_cast(settingsNode); + if (settingsItem != NULL) { + DuiWidget *itemWidget = DuiSettingsLanguageSettingsFactory::createWidget(*settingsItem, *widget, dataStore); + itemWidget->setParentItem(widget); + layout->addItem(itemWidget); + } + } + + return widget; +} diff --git a/src/settingslanguage/duisettingslanguagewidgetfactory.h b/src/settingslanguage/duisettingslanguagewidgetfactory.h new file mode 100644 index 000000000..ffdec17fb --- /dev/null +++ b/src/settingslanguage/duisettingslanguagewidgetfactory.h @@ -0,0 +1,53 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISETTINGSLANGUAGEFACTORY_H_ +#define DUISETTINGSLANGUAGEFACTORY_H_ + +#include +#include + +class DuiWidget; +class DuiSettingsLanguageWidget; +class DuiSettingsLanguageBinary; +class DuiDataStore; + +/*! + * A factory for translating settings binaries to widgets. + */ +class DUI_EXPORT DuiSettingsLanguageWidgetFactory +{ + /*! + * Private constructor to prevent construction. + */ + DuiSettingsLanguageWidgetFactory() {} + Q_DISABLE_COPY(DuiSettingsLanguageWidgetFactory) + +public: + /*! + * \brief Creates a widget from a DuiSettingsLanguageBinary representation. + * + * \param settingsBinary the settings binary representation. + * \param dataStore the data store for the settings. + * \return a widget. + */ + static DuiSettingsLanguageWidget *createWidget(const DuiSettingsLanguageBinary &settingsBinary, DuiDataStore *dataStore = NULL); +}; + +#endif /* DUISETTINGSLANGUAGEFACTORY_H_ */ diff --git a/src/settingslanguage/settingslanguage.pri b/src/settingslanguage/settingslanguage.pri new file mode 100644 index 000000000..b22a9b5af --- /dev/null +++ b/src/settingslanguage/settingslanguage.pri @@ -0,0 +1,71 @@ +# Input +SETTINGSLANGUAGE_SRC_DIR = ./settingslanguage +INCLUDEPATH += ./settingslanguage +QT += xml + +duigen_model_settingslanguage.name = duigenerator \ + model +duigen_model_settingslanguage.input = SETTINGSLANGUAGE_MODEL_HEADERS +duigen_model_settingslanguage.output = $$GEN_DIR/gen_${QMAKE_FILE_BASE}data.cpp +duigen_model_settingslanguage.depends = ../duigen/duigen +duigen_model_settingslanguage.commands += ../duigen/duigen --model \ + ${QMAKE_FILE_NAME} \ + $$GEN_DIR/ +duigen_model_settingslanguage.clean += $$GEN_DIR/gen_* +duigen_model_settingslanguage.CONFIG = target_predeps no_link +duigen_model_settingslanguage.variable_out = GENERATED_SOURCES +QMAKE_EXTRA_COMPILERS += duigen_model_settingslanguage + +duigen_style_settingslanguage.name = duigenerator style +duigen_style_settingslanguage.input = SETTINGSLANGUAGE_STYLE_HEADERS +duigen_style_settingslanguage.depends = ../duigen/duigen +duigen_style_settingslanguage.output = $$GEN_DIR/gen_${QMAKE_FILE_BASE}data.cpp +duigen_style_settingslanguage.commands += ../duigen/duigen --style ${QMAKE_FILE_NAME} $$GEN_DIR +duigen_style_settingslanguage.clean += $$GEN_DIR/gen_* +duigen_style_settingslanguage.CONFIG = target_predeps no_link +duigen_style_settingslanguage.variable_out = GENERATED_SOURCES + +QMAKE_EXTRA_COMPILERS += duigen_style_settingslanguage +HEADERS += $$SETTINGSLANGUAGE_MODEL_HEADERS \ + $$SETTINGSLANGUAGE_STYLE_HEADERS \ + $$SETTINGSLANGUAGE_SRC_DIR/duisettingslanguageparser.h \ + $$SETTINGSLANGUAGE_SRC_DIR/duisettingslanguagebinary.h \ + $$SETTINGSLANGUAGE_SRC_DIR/duisettingslanguagewidget.h \ + $$SETTINGSLANGUAGE_SRC_DIR/duisettingslanguagewidgetfactory.h \ + $$SETTINGSLANGUAGE_SRC_DIR/duisettingslanguagesettingsfactory.h \ + $$SETTINGSLANGUAGE_SRC_DIR/duisettingslanguageselectionfactory.h \ + $$SETTINGSLANGUAGE_SRC_DIR/duisettingslanguagetextfactory.h \ + $$SETTINGSLANGUAGE_SRC_DIR/duisettingslanguageintegerfactory.h \ + $$SETTINGSLANGUAGE_SRC_DIR/duisettingslanguageselectioncontroller.h \ + $$SETTINGSLANGUAGE_SRC_DIR/duisettingslanguagetextcontroller.h \ + $$SETTINGSLANGUAGE_SRC_DIR/duisettingslanguageintegercontroller.h \ + $$SETTINGSLANGUAGE_SRC_DIR/duisettingslanguagenode.h \ + $$SETTINGSLANGUAGE_SRC_DIR/duisettingslanguageoption.h \ + $$SETTINGSLANGUAGE_SRC_DIR/duisettingslanguageselection.h \ + $$SETTINGSLANGUAGE_SRC_DIR/duisettingslanguagesettings.h \ + $$SETTINGSLANGUAGE_SRC_DIR/duisettingslanguagetext.h \ + $$SETTINGSLANGUAGE_SRC_DIR/duisettingslanguagebooleancontroller.h \ + $$SETTINGSLANGUAGE_SRC_DIR/duisettingslanguagebooleanfactory.h \ + $$SETTINGSLANGUAGE_SRC_DIR/duisettingslanguageboolean.h \ + $$SETTINGSLANGUAGE_SRC_DIR/duisettingslanguageinteger.h \ + $$SETTINGSLANGUAGE_SRC_DIR/duisettingslanguagegroup.h +SOURCES += $$SETTINGSLANGUAGE_SRC_DIR/duisettingslanguageparser.cpp \ + $$SETTINGSLANGUAGE_SRC_DIR/duisettingslanguagebinary.cpp \ + $$SETTINGSLANGUAGE_SRC_DIR/duisettingslanguagewidget.cpp \ + $$SETTINGSLANGUAGE_SRC_DIR/duisettingslanguagewidgetfactory.cpp \ + $$SETTINGSLANGUAGE_SRC_DIR/duisettingslanguagesettingsfactory.cpp \ + $$SETTINGSLANGUAGE_SRC_DIR/duisettingslanguageselectionfactory.cpp \ + $$SETTINGSLANGUAGE_SRC_DIR/duisettingslanguagetextfactory.cpp \ + $$SETTINGSLANGUAGE_SRC_DIR/duisettingslanguageintegerfactory.cpp \ + $$SETTINGSLANGUAGE_SRC_DIR/duisettingslanguageselectioncontroller.cpp \ + $$SETTINGSLANGUAGE_SRC_DIR/duisettingslanguagetextcontroller.cpp \ + $$SETTINGSLANGUAGE_SRC_DIR/duisettingslanguageintegercontroller.cpp \ + $$SETTINGSLANGUAGE_SRC_DIR/duisettingslanguagenode.cpp \ + $$SETTINGSLANGUAGE_SRC_DIR/duisettingslanguageoption.cpp \ + $$SETTINGSLANGUAGE_SRC_DIR/duisettingslanguageselection.cpp \ + $$SETTINGSLANGUAGE_SRC_DIR/duisettingslanguagesettings.cpp \ + $$SETTINGSLANGUAGE_SRC_DIR/duisettingslanguagetext.cpp \ + $$SETTINGSLANGUAGE_SRC_DIR/duisettingslanguagebooleancontroller.cpp \ + $$SETTINGSLANGUAGE_SRC_DIR/duisettingslanguagebooleanfactory.cpp \ + $$SETTINGSLANGUAGE_SRC_DIR/duisettingslanguageboolean.cpp \ + $$SETTINGSLANGUAGE_SRC_DIR/duisettingslanguageinteger.cpp diff --git a/src/src.pro b/src/src.pro new file mode 100644 index 000000000..d1caa9563 --- /dev/null +++ b/src/src.pro @@ -0,0 +1,202 @@ +MOC_DIR = .moc +GEN_DIR = .gen +OBJECTS_DIR = .obj +DESTDIR = ../lib +TEMPLATE = lib +TARGET = dui + +include(../mkspecs/common.pri) +include(predeps.pri) + +include(animation/animation.pri) +include(core/core.pri) +include(events/events.pri) +include(feedback/feedback.pri) +include(layout/layout.pri) +include(settingslanguage/settingslanguage.pri) +include(painting/painting.pri) +include(scene/scene.pri) +include(service/service.pri) +include(style/style.pri) +include(theme/theme.pri) +include(i18n/i18n.pri) +include(widgets/widgets.pri) +include(workspace/workspace.pri) +# !macx:include(video/video.pri) DISABLED FOR NOW +contains(DEFINES, HAVE_DBUS) { + include(applicationextension/applicationextension.pri) + include(mashup/appletcommunication/appletcommunication.pri) + include(mashup/appletinterface/appletinterface.pri) + include(mashup/appletinstallation/appletinstallation.pri) + include(mashup/mashup/mashup.pri) + include(servicefwif/servicefwif.pri) + include(notification/notification.pri) +} + + +## Build configuration + +VERSION = $${DUI_VERSION} + +INCLUDEPATH += include +INCLUDEPATH += $${OUT_PWD}/.moc +INCLUDEPATH += $${OUT_PWD}/.gen + +QMAKE_STRIP = echo + +!win32 { + PRE_TARGETDEPS += ../duigen/duigen +} + +CONFIG += qt warn_on depend_includepath qmake_cache target_qt dll create_prl +!win32:CONFIG += link_pkgconfig +macx:CONFIG += lib_bundle + +win32 { + QMAKE_MOC = perl $${IN_PWD}\..\duimoc\duimoc + INCLUDEPATH += . +} else { + QMAKE_MOC = PATH=../duigen:$$(PATH) $${IN_PWD}/../duimoc/duimoc +} + +QMAKE_CFLAGS += -Werror + +QMAKE_CXXFLAGS += -DDUI_EXPORTS +!win32-msvc*:QMAKE_CXXFLAGS += -Wno-long-long -pedantic +!win32:QMAKE_CXXFLAGS += -Werror -Wno-variadic-macros -fvisibility=hidden + +!win32-msvc*:LIBS += -lm -lX11 +macx:LIBS -= -lX11 +win32:LIBS -= -lX11 + +# enable QString optimizations +DEFINES += QT_USE_FAST_CONCATENATION QT_USE_FAST_OPERATOR_PLUS + +# Check for mixing of const and non-const iterators, +# which can cause problems when built with some compilers: +DEFINES += QT_STRICT_ITERATORS + + +## Features + +contains(DUI_BUILD_FEATURES, coverage) { + QMAKE_CXXFLAGS += --coverage + QMAKE_LFLAGS += --coverage +} + +contains(DUI_BUILD_FEATURES, timestamps) { + DEFINES += DUI_TIMESTAMP +} + +contains(DUI_BUILD_FEATURES, testable) { + DEFINES += TESTABLE + HEADERS += ./core/testabilityinterface.h +} + +contains(DUI_PROFILE_PARTS, theme) { + DEFINES += DUI_THEMESYSTEM_PROFILING_SUPPORT +} + + +## Dependencies + +# list pkg-config dependencies here +!macx:PKGCONFIG += xdamage + +contains(DEFINES, HAVE_ICU) { + LIBS += -licui18n -licuuc -licudata + include(icu-extradata/extradata.pri) + EXTRADATA_SOURCE=icu-extradata/extradata.txt +} + +contains(DEFINES, HAVE_CONTEXTSUBSCRIBER) { + PKGCONFIG += contextsubscriber-1.0 +} + +contains(DEFINES, HAVE_GSTREAMER) { + PKGCONFIG += gstreamer-0.10 + # TODO: Is this necessary? + LIBS += -lgstbase-0.10 -lgstinterfaces-0.10 -lgstvideo-0.10 + + # On Mac, GStreamer can be also in /opt if installed via macports.org or /usr/local if installed from sources + macx:INCLUDEPATH += /opt/local/include/gstreamer-0.10 +} + +contains(DEFINES, HAVE_GCONF) { + PKGCONFIG += gconf-2.0 + # TODO: Why is this necessary? + # The PKGCONFIG call above usually causes qmake to link to the correct libraries + # automatically, but that does not happen if we remove these explicit mentions. + LIBS += -lgconf-2 +} + +contains(DEFINES, HAVE_DBUS) { + QT += dbus +} + +contains(DEFINES, HAVE_GLIB) { + LIBS += -lglib-2.0 +} + +QT += \ + svg \ + network \ + core \ + gui \ + opengl + + +## Files and paths + +macx { + FRAMEWORK_HEADERS.version = Versions + FRAMEWORK_HEADERS.files = $$system(find include/Dui*) $$HEADERS + FRAMEWORK_HEADERS.path = Headers + QMAKE_BUNDLE_DATA += FRAMEWORK_HEADERS +} + +target.path = $$DUI_INSTALL_LIBS + +HEADERS += $$PUBLIC_HEADERS $$PRIVATE_HEADERS + +win32 { + # for windows we can live with the broken pattern matching + FORWARDING_HEADERS = include/Dui* +} else { + # match only the camel case forwarding headers here + FORWARDING_HEADERS = $$system( find include/Dui* ) +} + +install_headers.path = $$DUI_INSTALL_HEADERS +install_headers.files = \ + $$FORWARDING_HEADERS \ + $$HEADERS # Remove this after all subdirs define PUBLIC_HEADERS + # $$PUBLIC_HEADERS + +install_pkgconfig.path = $$DUI_INSTALL_LIBS/pkgconfig +install_pkgconfig.files = Dui.pc + +install_prf.path = $$[QT_INSTALL_DATA]/mkspecs/features +install_prf.files = dui.prf dui_defines.prf translations.prf + +INSTALLS += \ + target \ + install_headers \ + install_pkgconfig + +# causes problems when installing on windows with INSTALL_ROOT +!win32 { + INSTALLS += install_prf +} + +QMAKE_EXTRA_TARGETS += check +check.depends = $$DESTDIR/lib$${TARGET}.so.$$VERSION +check.commands = $$system(true) + +QMAKE_EXTRA_TARGETS += check-xml +check-xml.depends = $$DESTDIR/lib$${TARGET}.so.$$VERSION +check-xml.commands = $$system(true) +QMAKE_CLEAN += \ + *.gcov \ + ./.obj/*.gcno \ + ./.obj/*.gcda \ diff --git a/src/style/.gitignore b/src/style/.gitignore new file mode 100644 index 000000000..b9ae69847 --- /dev/null +++ b/src/style/.gitignore @@ -0,0 +1 @@ +gen_* diff --git a/src/style/duiabstractlayoutpolicystyle.h b/src/style/duiabstractlayoutpolicystyle.h new file mode 100644 index 000000000..b05eb62fe --- /dev/null +++ b/src/style/duiabstractlayoutpolicystyle.h @@ -0,0 +1,55 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIABSTRACTLAYOUTPOLICYSTYLE_H +#define DUIABSTRACTLAYOUTPOLICYSTYLE_H + +#include + +/** \brief Defines a style for a DuiAbstractLayoutPolicy class and the policies that inherit from this + * This defines the attributes that are common to all DuiLayout policies + */ +class DUI_EXPORT DuiAbstractLayoutPolicyStyle : public DuiStyle +{ + Q_OBJECT + DUI_STYLE_INTERNAL(DuiAbstractLayoutPolicyStyle) + + ///Sets the horizontal distances between items, where applicable. + DUI_STYLE_ATTRIBUTE(qreal, horizontalSpacing, HorizontalSpacing) + ///Sets the vertical distances between items, where applicable. + DUI_STYLE_ATTRIBUTE(qreal, verticalSpacing, VerticalSpacing) + ///FIXME Convert these to int or, even better, QMargin + ///The left contents margin of the layout for this policy. If this is not set explicitly (in code or css) it returns -1, indicating to use the DuiLayout margin + DUI_STYLE_ATTRIBUTE(qreal, marginLeft, MarginLeft) + ///The top contents margin of the layout for this policy. If this is not set explicitly (in code or css) it returns -1, indicating to use the DuiLayout margin + DUI_STYLE_ATTRIBUTE(qreal, marginTop, MarginTop) + ///The right contents margin of the layout for this policy. If this is not set explicitly (in code or css) it returns -1, indicating to use the DuiLayout margin + DUI_STYLE_ATTRIBUTE(qreal, marginRight, MarginRight) + ///The bottom contents margin of the layout for this policy. If this is not set explicitly (in code or css) it returns -1, indicating to use the DuiLayout margin + DUI_STYLE_ATTRIBUTE(qreal, marginBottom, MarginBottom) + +}; + +class DUI_EXPORT DuiAbstractLayoutPolicyStyleContainer : public DuiStyleContainer +{ + DUI_STYLE_CONTAINER_INTERNAL(DuiAbstractLayoutPolicyStyle) +}; + +#endif + diff --git a/src/style/duiabstractwidgetanimationstyle.h b/src/style/duiabstractwidgetanimationstyle.h new file mode 100644 index 000000000..fc1dc1523 --- /dev/null +++ b/src/style/duiabstractwidgetanimationstyle.h @@ -0,0 +1,39 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIABSTRACTWIDGETANIMATIONSTYLE_H +#define DUIABSTRACTWIDGETANIMATIONSTYLE_H + +#include + +class DUI_EXPORT DuiAbstractWidgetAnimationStyle : public DuiAnimationStyle +{ + Q_OBJECT + DUI_STYLE_INTERNAL(DuiAbstractWidgetAnimationStyle) + + DUI_STYLE_ATTRIBUTE(int, duration, Duration) +}; + +class DUI_EXPORT DuiAbstractWidgetAnimationStyleContainer : public DuiAnimationStyleContainer +{ + DUI_STYLE_CONTAINER_INTERNAL(DuiAbstractWidgetAnimationStyle) +}; + +#endif + diff --git a/src/style/duianimationstyle.h b/src/style/duianimationstyle.h new file mode 100644 index 000000000..a0a182c4e --- /dev/null +++ b/src/style/duianimationstyle.h @@ -0,0 +1,36 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIANIMATIONSTYLE_H +#define DUIANIMATIONSTYLE_H + +#include + +class DUI_EXPORT DuiAnimationStyle : public DuiStyle +{ + Q_OBJECT + DUI_STYLE_INTERNAL(DuiAnimationStyle) +}; + +class DuiAnimationStyleContainer : public DuiStyleContainer +{ + DUI_STYLE_CONTAINER_INTERNAL(DuiAnimationStyle) +}; + +#endif diff --git a/src/style/duiapplethandlestyle.h b/src/style/duiapplethandlestyle.h new file mode 100644 index 000000000..38f043b2b --- /dev/null +++ b/src/style/duiapplethandlestyle.h @@ -0,0 +1,56 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETHANDLESTYLE_H +#define DUIAPPLETHANDLESTYLE_H + +#include +#include +#include + +class DUI_EXPORT DuiAppletHandleStyle : public DuiWidgetStyle +{ + Q_OBJECT + DUI_STYLE(DuiAppletHandleStyle) + + //! The image to be drawn on top of the applet when it is in a broken state + DUI_STYLE_PTR_ATTRIBUTE(QPixmap *, brokenAppletImage, BrokenAppletImage) + + //! Offset of the broken applet image relative to the top right corner of the applet + DUI_STYLE_ATTRIBUTE(QPoint, brokenAppletImageOffset, BrokenAppletImageOffset) + + //! The radius of the blur to be applied in a broken applet + DUI_STYLE_ATTRIBUTE(int, brokenAppletBlurRadius, BrokenAppletBlurRadius) + + //! The opacity of the applet when it is in a broken state + DUI_STYLE_ATTRIBUTE(qreal, brokenAppletOpacity, BrokenAppletOpacity) + + //! The minimum size of the applet even when the applet states it could be smaller + DUI_STYLE_ATTRIBUTE(QSizeF, minimumAppletSize, MinimumAppletSize) + + //! The maximum size of the applet even when the applet states it could be bigger + DUI_STYLE_ATTRIBUTE(QSizeF, maximumAppletSize, MaximumAppletSize) +}; + +class DUI_EXPORT DuiAppletHandleStyleContainer : public DuiWidgetStyleContainer +{ + DUI_STYLE_CONTAINER(DuiAppletHandleStyle) +}; + +#endif // DUIAPPLETHANDLESTYLE_H diff --git a/src/style/duiappletinventorystyle.h b/src/style/duiappletinventorystyle.h new file mode 100644 index 000000000..e72f975a3 --- /dev/null +++ b/src/style/duiappletinventorystyle.h @@ -0,0 +1,39 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETINVENTORYSTYLE_H +#define DUIAPPLETINVENTORYSTYLE_H + +#include +#include + +//! \internal +class DuiAppletInventoryStyle : public DuiExtendingBackgroundStyle +{ + Q_OBJECT + DUI_STYLE_INTERNAL(DuiAppletInventoryStyle) +}; + +class DuiAppletInventoryStyleContainer : public DuiExtendingBackgroundStyleContainer +{ + DUI_STYLE_CONTAINER_INTERNAL(DuiAppletInventoryStyle) +}; +//! \internal_end + +#endif diff --git a/src/style/duiapplicationextensionareastyle.h b/src/style/duiapplicationextensionareastyle.h new file mode 100644 index 000000000..7c864c721 --- /dev/null +++ b/src/style/duiapplicationextensionareastyle.h @@ -0,0 +1,42 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLICATIONEXTENSIONAREASTYLE_H_ +#define DUIAPPLICATIONEXTENSIONAREASTYLE_H_ + +#include "duiextensionareastyle.h" + +/*! + * DuiApplicationExtensionAreaStyle is the style class for DuiApplicationExtensionArea. + */ +class DUI_EXPORT DuiApplicationExtensionAreaStyle : public DuiExtensionAreaStyle +{ + Q_OBJECT + DUI_STYLE(DuiApplicationExtensionAreaStyle) +}; + +/*! + * DuiApplicationExtensionAreaStyleContainer is the style container class for DuiApplicationExtensionArea. + */ +class DUI_EXPORT DuiApplicationExtensionAreaStyleContainer : public DuiExtensionAreaStyleContainer +{ + DUI_STYLE_CONTAINER(DuiApplicationExtensionAreaStyle) +}; + +#endif /* DUIAPPLICATIONEXTENSIONAREASTYLE_H_ */ diff --git a/src/style/duiapplicationmenubuttonstyle.h b/src/style/duiapplicationmenubuttonstyle.h new file mode 100644 index 000000000..c3627f624 --- /dev/null +++ b/src/style/duiapplicationmenubuttonstyle.h @@ -0,0 +1,71 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLICATIONMENUBUTTONSTYLE_H +#define DUIAPPLICATIONMENUBUTTONSTYLE_H + +//! \internal +#include "duibuttonstyle.h" + +/*! + \class DuiApplicationMenuButtonStyle + \brief Style class for application menu title button + + \code + DuiApplicationMenuButtonStyle { + arrow-icon: "arrow-icon"; + } + \endcode + + \ingroup styles + \sa DuiApplicationMenuButtonStyleContainer DuiButtonStyle \ref styling DuiApplicationMenuButton DuiApplicationMenuButtonView +*/ +class DUI_EXPORT DuiApplicationMenuButtonStyle : public DuiButtonStyle +{ + Q_OBJECT + DUI_STYLE_INTERNAL(DuiApplicationMenuButtonStyle) + + /*! + \property DuiApplicationMenuButtonStyle::arrowIcon + \brief Id of arrow icon + */ + DUI_STYLE_ATTRIBUTE(QString, arrowIcon, ArrowIcon) + + /*! + \property DuiApplicationMenuButtonStyle::arrowIcon + \brief Size of arrow icon + */ + DUI_STYLE_ATTRIBUTE(QSize, arrowIconSize, ArrowIconSize) +}; + +/*! + \class DuiApplicationMenuButtonStyleContainer + \brief Style mode container class for DuiApplicationMenuButtonStyle. + + \ingroup styles + \sa DuiApplicationMenuButtonStyle +*/ +class DuiApplicationMenuButtonStyleContainer : public DuiButtonStyleContainer +{ + DUI_STYLE_CONTAINER_INTERNAL(DuiApplicationMenuButtonStyle) +}; +//! \internal_end + +#endif + diff --git a/src/style/duiapplicationmenustyle.h b/src/style/duiapplicationmenustyle.h new file mode 100644 index 000000000..dee29a58e --- /dev/null +++ b/src/style/duiapplicationmenustyle.h @@ -0,0 +1,146 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLICATIONMENUSTYLE_H +#define DUIAPPLICATIONMENUSTYLE_H + +#include +#include + +class DuiScalableImage; + +/*! + \class DuiApplicationMenuStyle + \brief Style class for application menu. + + \code + DuiApplicationMenuStyle { + canvas-image: "canvas-background" 3mm 3mm 3mm 3mm; + canvas-color: #000000; + canvas-opacity: 1.0; + canvas-margin: 12; + + divider-image:; + divider-color: #F9A427; + divider-opacity: 1.0; + divider-width: 1; + + item-height: 88; + gap-height: 1; + gap-color: #F9A427; + gap-opacity: 1.0; + } + \endcode + + \ingroup styles + \sa DuiApplicationMenuStyleContainer DuiSceneWindowStyle \ref styling DuiApplicationMenu DuiApplicationMenuView +*/ + +class DUI_EXPORT DuiApplicationMenuStyle : public DuiSceneWindowStyle +{ + Q_OBJECT + DUI_STYLE_INTERNAL(DuiApplicationMenuStyle) + + /*! + \property DuiApplicationMenuStyle::canvasImage + \brief Image for the menu canvas. + */ + DUI_STYLE_PTR_ATTRIBUTE(DuiScalableImage *, canvasImage, CanvasImage) + + /*! + \property DuiApplicationMenuStyle::canvasColor + \brief Color of the menu canvas. + */ + DUI_STYLE_ATTRIBUTE(QColor, canvasColor, CanvasColor) + + /*! + \property DuiApplicationMenuStyle::canvasOpacity + \brief Opacity of the menu canvas. + */ + DUI_STYLE_ATTRIBUTE(qreal, canvasOpacity, CanvasOpacity) + + /*! + \property DuiApplicationMenuStyle::canvasMargin + \brief Margin of the menu canvas. + */ + DUI_STYLE_ATTRIBUTE(int, canvasMargin, CanvasMargin) + + /*! + \property DuiApplicationMenuStyle::dividerImage + \brief Image for the menu divider. + */ + DUI_STYLE_PTR_ATTRIBUTE(DuiScalableImage *, dividerImage, DividerImage) + + /*! + \property DuiApplicationMenuStyle::dividerColor + \brief Color of the menu divider. + */ + DUI_STYLE_ATTRIBUTE(QColor, dividerColor, DividerColor) + + /*! + \property DuiApplicationMenuStyle::dividerOpacity + \brief Opacity of the menu divider. + */ + DUI_STYLE_ATTRIBUTE(qreal, dividerOpacity, DividerOpacity) + + /*! + \property DuiApplicationMenuStyle::dividerWidth + \brief Width of the menu divider. + */ + DUI_STYLE_ATTRIBUTE(int, dividerWidth, DividerWidth) + + /*! + \property DuiApplicationMenuStyle::itemHeight + \brief Height of the menu item. + */ + DUI_STYLE_ATTRIBUTE(int, itemHeight, ItemHeight) + + /*! + \property DuiApplicationMenuStyle::gapHeight + \brief Height of the menu gap. + */ + DUI_STYLE_ATTRIBUTE(int, gapHeight, GapHeight) + + /*! + \property DuiApplicationMenuStyle::gapColor + \brief Color of the menu gap. + */ + DUI_STYLE_ATTRIBUTE(QColor, gapColor, GapColor) + + /*! + \property DuiApplicationMenuStyle::gapOpacity + \brief Opacity of the menu gap. + */ + DUI_STYLE_ATTRIBUTE(qreal, gapOpacity, GapOpacity) +}; + +/*! + \class DuiApplicationMenuStyleContainer + \brief Style mode container class for DuiApplicationMenuStyle. + + \ingroup styles + \sa DuiApplicationMenuStyle +*/ +class DUI_EXPORT DuiApplicationMenuStyleContainer : public DuiSceneWindowStyleContainer +{ + DUI_STYLE_CONTAINER_INTERNAL(DuiApplicationMenuStyle) +}; + +#endif + diff --git a/src/style/duiapplicationpagestyle.h b/src/style/duiapplicationpagestyle.h new file mode 100644 index 000000000..9b80aadc5 --- /dev/null +++ b/src/style/duiapplicationpagestyle.h @@ -0,0 +1,39 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLICATIONPAGESTYLE_H +#define DUIAPPLICATIONPAGESTYLE_H + +#include + + +class DUI_EXPORT DuiApplicationPageStyle : public DuiSceneWindowStyle +{ + Q_OBJECT + DUI_STYLE_INTERNAL(DuiApplicationPageStyle) + +}; + +class DUI_EXPORT DuiApplicationPageStyleContainer : public DuiSceneWindowStyleContainer +{ + DUI_STYLE_CONTAINER_INTERNAL(DuiApplicationPageStyle) +}; + +#endif + diff --git a/src/style/duibasiclayoutanimationstyle.h b/src/style/duibasiclayoutanimationstyle.h new file mode 100644 index 000000000..f39be9a4e --- /dev/null +++ b/src/style/duibasiclayoutanimationstyle.h @@ -0,0 +1,48 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIBASICLAYOUTANIMATIONSTYLE_H +#define DUIBASICLAYOUTANIMATIONSTYLE_H + +#include + +#include +#include + +class DUI_EXPORT DuiBasicLayoutAnimationStyle : public DuiLayoutAnimationStyle +{ + Q_OBJECT + DUI_STYLE_INTERNAL(DuiBasicLayoutAnimationStyle) + + DUI_STYLE_ATTRIBUTE(int, duration, Duration) + DUI_STYLE_ATTRIBUTE(QEasingCurve, geometryEasingCurve, GeometryEasingCurve) + DUI_STYLE_ATTRIBUTE(QEasingCurve, opacityEasingCurve, OpacityEasingCurve) + DUI_STYLE_ATTRIBUTE(qreal, initialShowingOpacity, InitialShowingOpacity) + DUI_STYLE_ATTRIBUTE(qreal, initialShowingScaleFactor, InitialShowingScaleFactor) + DUI_STYLE_ATTRIBUTE(qreal, finalHidingOpacity, FinalHidingOpacity) + DUI_STYLE_ATTRIBUTE(qreal, finalHidingScaleFactor, FinalHidingScaleFactor) +}; + +// TODO: get rid of this container +class DUI_EXPORT DuiBasicLayoutAnimationStyleContainer : public DuiLayoutAnimationStyleContainer +{ + DUI_STYLE_CONTAINER_INTERNAL(DuiBasicLayoutAnimationStyle) +}; + +#endif diff --git a/src/style/duibasicorientationanimationstyle.h b/src/style/duibasicorientationanimationstyle.h new file mode 100644 index 000000000..3c17e5492 --- /dev/null +++ b/src/style/duibasicorientationanimationstyle.h @@ -0,0 +1,43 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIBASICORIENTATIONANIMATIONSTYLE_H +#define DUIBASICORIENTATIONANIMATIONSTYLE_H + +#include + +//! \internal +class DuiBasicOrientationAnimationStyle: public DuiAnimationStyle +{ + Q_OBJECT + DUI_STYLE_INTERNAL(DuiBasicOrientationAnimationStyle) + + DUI_STYLE_ATTRIBUTE(int, phaseZeroDuration, PhaseZeroDuration) + DUI_STYLE_ATTRIBUTE(int, phaseOneDuration, PhaseOneDuration) + DUI_STYLE_ATTRIBUTE(int, phaseTwoDuration, PhaseTwoDuration) +}; + +class DuiBasicOrientationAnimationStyleContainer : public DuiAnimationStyleContainer +{ + DUI_STYLE_CONTAINER_INTERNAL(DuiBasicOrientationAnimationStyle) +}; +//! \internal_end + +#endif + diff --git a/src/style/duibuttoniconstyle.h b/src/style/duibuttoniconstyle.h new file mode 100644 index 000000000..3a290ea70 --- /dev/null +++ b/src/style/duibuttoniconstyle.h @@ -0,0 +1,95 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIBUTTONICONSTYLE_H +#define DUIBUTTONICONSTYLE_H + +#include +#include + +/*! + \class DuiButtonIconStyle + \brief Style class for dui icon buttons. + + \code + DuiButtonStyle { + glow-color: #FFFF00; + glow-duration: 700; + glow-radius: 8; + + shrink-duration: 100; + shrink-factor: 0.2; + } + \endcode + + \ingroup styles + \sa DuiButtonIconStyleContainer DuiWidgetStyle DuiButtonStyle \ref styling DuiButton DuiButtonIconView +*/ +class DUI_EXPORT DuiButtonIconStyle : public DuiButtonStyle +{ + Q_OBJECT + DUI_STYLE_INTERNAL(DuiButtonIconStyle) + + /*! + \property DuiButtonIconStyle::glowColor + \brief Color of the glow effect. + */ + DUI_STYLE_ATTRIBUTE(QColor, glowColor, GlowColor) + + /*! + \property DuiButtonIconStyle::glowDuration + \brief Length of glow effect in ms. + */ + DUI_STYLE_ATTRIBUTE(int, glowDuration, GlowDuration) + + /*! + \property DuiButtonIconStyle::glowRadius + \brief Radius of the glow effect. + */ + DUI_STYLE_ATTRIBUTE(int, glowRadius, GlowRadius) + + /*! + \property DuiButtonIconStyle::shrinkDuration + \brief Length of the shrink animation in ms. + */ + DUI_STYLE_ATTRIBUTE(int, shrinkDuration, ShrinkDuration) + + /*! + \property DuiButtonIconStyle::shrinkFactor + \brief Scaling factor for the shrink animation. + + Defines the minimum size for the button. + */ + DUI_STYLE_ATTRIBUTE(qreal, shrinkFactor, ShrinkFactor) +}; + +/*! + \class DuiButtonIconStyleContainer + \brief Style mode container class for DuiButtonIconStyle. + + \ingroup styles + \sa DuiButtonIconStyle +*/ +class DUI_EXPORT DuiButtonIconStyleContainer : public DuiButtonStyleContainer +{ + DUI_STYLE_CONTAINER_INTERNAL(DuiButtonIconStyle) +}; + +#endif + diff --git a/src/style/duibuttonstyle.h b/src/style/duibuttonstyle.h new file mode 100644 index 000000000..0d8a67a95 --- /dev/null +++ b/src/style/duibuttonstyle.h @@ -0,0 +1,149 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIBUTTONSTYLE_H +#define DUIBUTTONSTYLE_H + +#include +#include +#include +#include + +/*! + \class DuiButtonStyle + \brief Style class for standard dui buttons. + + \code + DuiButtonStyle { + font: arial 12; + + icon-size: 32 32; + icon-align: left; + + text-color: white; + + vertical-text-align: vcenter; + horizontal-text-align: hcenter; + + text-margin-left: 5; + text-margin-top: 0; + text-margin-right: 5; + text-margin-bottom: 0; + } + \endcode + + \ingroup styles + \sa DuiButtonStyleContainer DuiWidgetStyle \ref styling DuiButton DuiButtonView +*/ +class DUI_EXPORT DuiButtonStyle : public DuiWidgetStyle +{ + Q_OBJECT + DUI_STYLE_INTERNAL(DuiButtonStyle) + + /*! + \property DuiButtonStyle::font + \brief Font for the button text. + */ + DUI_STYLE_ATTRIBUTE(QFont, font, Font) + + /*! + \property DuiButtonStyle::iconSize + \brief Size of the button icon. + */ + DUI_STYLE_ATTRIBUTE(QSize, iconSize, IconSize) + + /*! + \property DuiButtonStyle::iconAlign + \brief Alignmentation of the icon. + */ + DUI_STYLE_ATTRIBUTE(Qt::Alignment, iconAlign, IconAlign) + + /*! + \property DuiButtonStyle::textColor + \brief Text color. + */ + DUI_STYLE_ATTRIBUTE(QColor, textColor, TextColor) + + /*! + \property DuiButtonStyle::horizontalTextAlign + \brief Horizontal text alignment. + */ + DUI_STYLE_ATTRIBUTE(Qt::Alignment, horizontalTextAlign, HorizontalTextAlign) + + /*! + \property DuiButtonStyle::verticalTextAlign + \brief Vertical text alignment. + */ + DUI_STYLE_ATTRIBUTE(Qt::Alignment, verticalTextAlign, VerticalTextAlign) + + /*! + \property DuiButtonStyle::textMarginLeft + \brief Left text margin. + + Empty space after left text boundary. + */ + DUI_STYLE_ATTRIBUTE(int, textMarginLeft, TextMarginLeft) + + /*! + \property DuiButtonStyle::textMarginTop + \brief Top text margin. + + Empty space after top text boundary. + */ + DUI_STYLE_ATTRIBUTE(int, textMarginTop, TextMarginTop) + + /*! + \property DuiButtonStyle::textMarginRight + \brief Right text margin. + + Empty space after right text boundary. + */ + DUI_STYLE_ATTRIBUTE(int, textMarginRight, TextMarginRight) + + /*! + \property DuiButtonStyle::textMarginBottom + \brief Bottom text margin. + + Empty space after bottom text boundary. + */ + DUI_STYLE_ATTRIBUTE(int, textMarginBottom, TextMarginBottom) +}; + +/*! + \class DuiButtonStyleContainer + \brief Style mode container class for DuiButtonStyle. + + \ingroup styles + \sa DuiButtonStyle +*/ +class DUI_EXPORT DuiButtonStyleContainer : public DuiWidgetStyleContainer +{ + DUI_STYLE_CONTAINER_INTERNAL(DuiButtonStyle) + + /*! + \brief Style mode for a pressed button. + + Mode is activated when a button is pressed down and deactivated when + button is released. + */ + DUI_STYLE_MODE(Pressed) +}; + +#endif + diff --git a/src/style/duibuttonswitchstyle.h b/src/style/duibuttonswitchstyle.h new file mode 100644 index 000000000..ede76bee4 --- /dev/null +++ b/src/style/duibuttonswitchstyle.h @@ -0,0 +1,83 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIBUTTONSWITCHSTYLE_H +#define DUIBUTTONSWITCHSTYLE_H + +#include +#include + +/*! + \class DuiButtonSwitchStyle + \brief Style class for switch buttons. + + \code + DuiButtonSwitchStyle { + // slider is behind thumb, but above background + slider-image: "duibutton-switch-colorstripe"; + + // slider-mask defines the shape of the slider-image + slider-mask: "duibutton-switch-mask" 15px 15px 15px 15px; + + // thumb is the sliding part, should slide across the whole area + thumb-image: "duibutton-switch-thumb" 15px 15px 15px 15px; + } + \endcode + + \ingroup styles + \sa DuiButtonSwitchStyleContainer DuiWidgetStyle DuiButtonStyle \ref styling DuiButton DuiButtonSwitchView +*/ +class DUI_EXPORT DuiButtonSwitchStyle : public DuiButtonStyle +{ + Q_OBJECT + DUI_STYLE_INTERNAL(DuiButtonSwitchStyle) + + /*! + \property DuiButtonSwitchStyle::sliderImage + \brief Image for the sliding background of the switch. + */ + DUI_STYLE_PTR_ATTRIBUTE(DuiScalableImage *, sliderImage, SliderImage) + + /*! + \property DuiButtonSwitchStyle::sliderMask + \brief Image for masking the sliding background. + */ + DUI_STYLE_PTR_ATTRIBUTE(DuiScalableImage *, sliderMask, SliderMask) + + /*! + \property DuiButtonSwitchStyle::thumbImage + \brief Image for the thumb of the switch. + */ + DUI_STYLE_PTR_ATTRIBUTE(DuiScalableImage *, thumbImage, ThumbImage) +}; + +/*! + \class DuiButtonSwitchStyleContainer + \brief Style mode container class for DuiButtonSwitchStyle. + + \ingroup styles + \sa DuiButtonSwitchStyle +*/ +class DUI_EXPORT DuiButtonSwitchStyleContainer : public DuiButtonStyleContainer +{ + DUI_STYLE_CONTAINER_INTERNAL(DuiButtonSwitchStyle) +}; + +#endif + diff --git a/src/style/duicheckboxstyle.h b/src/style/duicheckboxstyle.h new file mode 100644 index 000000000..58033b32c --- /dev/null +++ b/src/style/duicheckboxstyle.h @@ -0,0 +1,65 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUICHECKBOXSTYLE_H +#define DUICHECKBOXSTYLE_H + +#include +#include + +/*! + \class DuiCheckboxStyle + \brief Style class for dui checkboxes. + + \code + DuiCheckboxStyle { + checkmark-image: duibutton-checkbox-checkmark 0 0 0 0; + } + \endcode + + \ingroup styles + \sa DuiCheckboxStyleContainer DuiWidgetStyle DuiButtonStyle \ref styling DuiButton DuiCheckboxView +*/ +class DUI_EXPORT DuiCheckboxStyle : public DuiButtonStyle +{ + Q_OBJECT + DUI_STYLE_INTERNAL(DuiCheckboxStyle) + + /*! + \property DuiButtonSwitchStyle::checkmarkImage + \brief Pixmap for the checkmark of the checkbox. + */ + DUI_STYLE_PTR_ATTRIBUTE(QPixmap *, checkmarkImage, CheckmarkImage) + +}; + +/*! + \class DuiCheckboxStyleContainer + \brief Style mode container class for DuiCheckboxStyle. + + \ingroup styles + \sa DuiCheckboxStyle +*/ +class DUI_EXPORT DuiCheckboxStyleContainer : public DuiButtonStyleContainer +{ + DUI_STYLE_CONTAINER_INTERNAL(DuiCheckboxStyle) +}; + +#endif + diff --git a/src/style/duicomboboxstyle.h b/src/style/duicomboboxstyle.h new file mode 100644 index 000000000..d1007d100 --- /dev/null +++ b/src/style/duicomboboxstyle.h @@ -0,0 +1,59 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUICOMBOBOXSTYLE_H +#define DUICOMBOBOXSTYLE_H + +#include + +/*! + \class DuiComboBoxStyle + \brief Style class for DuiComoBox. + + \ingroup styles + \sa DuiComboBoxStyleContainer DuiWidgetStyle \ref styling DuiComboBox DuiComboBoxView +*/ +class DUI_EXPORT DuiComboBoxStyle : public DuiWidgetStyle +{ + Q_OBJECT + DUI_STYLE_INTERNAL(DuiComboBoxStyle) +}; + +/*! + \class DuiComboBoxStyleContainer + \brief Style mode container class for DuiComboBoxStyle. + + \ingroup styles + \sa DuiComboBoxStyle +*/ +class DUI_EXPORT DuiComboBoxStyleContainer : public DuiWidgetStyleContainer +{ + DUI_STYLE_CONTAINER_INTERNAL(DuiComboBoxStyle) + + /*! + \brief Style mode for a pressed comboBox. + + Mode is activated when a comboBox is pressed down and deactivated when + comboBox is released. + */ + DUI_STYLE_MODE(Pressed) +}; + +#endif + diff --git a/src/style/duicompleterstyle.h b/src/style/duicompleterstyle.h new file mode 100644 index 000000000..3555f85a7 --- /dev/null +++ b/src/style/duicompleterstyle.h @@ -0,0 +1,46 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUICOMPLETERSTYLE_H +#define DUICOMPLETERSTYLE_H + +#include +#include +#include + +class DUI_EXPORT DuiCompleterStyle : public DuiSceneWindowStyle +{ + Q_OBJECT + DUI_STYLE_INTERNAL(DuiCompleterStyle) + + DUI_STYLE_ATTRIBUTE(QColor, highlightColor, HighlightColor) + DUI_STYLE_ATTRIBUTE(int, height, Height) + DUI_STYLE_ATTRIBUTE(int, displayBorder, DisplayBorder) + DUI_STYLE_ATTRIBUTE(int, labelMargin, LabelMargin) + DUI_STYLE_ATTRIBUTE(int, buttonMargin, ButtonMargin) + DUI_STYLE_ATTRIBUTE(int, buttonWidth, ButtonWidth) + DUI_STYLE_ATTRIBUTE(int, yPositionOffset, YPositionOffset) +}; + +class DUI_EXPORT DuiCompleterStyleContainer : public DuiSceneWindowStyleContainer +{ + DUI_STYLE_CONTAINER_INTERNAL(DuiCompleterStyle) +}; + +#endif diff --git a/src/style/duicontainerheaderstyle.h b/src/style/duicontainerheaderstyle.h new file mode 100644 index 000000000..dbd17a1b4 --- /dev/null +++ b/src/style/duicontainerheaderstyle.h @@ -0,0 +1,48 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUICONTAINERHEADERSTYLE_H +#define DUICONTAINERHEADERSTYLE_H + +#include + +#include + +/*! + * \internal + */ + +class DUI_EXPORT DuiContainerHeaderStyle : public DuiWidgetStyle +{ + Q_OBJECT + DUI_STYLE_INTERNAL(DuiContainerHeaderStyle) +}; + +/*! + * \internal + */ + +class DUI_EXPORT DuiContainerHeaderStyleContainer : public DuiWidgetStyleContainer +{ + DUI_STYLE_CONTAINER_INTERNAL(DuiContainerHeaderStyle) + DUI_STYLE_MODE(Pressed) +}; + + +#endif // DUICONTAINERHEADERSTYLE_H diff --git a/src/style/duicontainerstyle.h b/src/style/duicontainerstyle.h new file mode 100644 index 000000000..57121ae14 --- /dev/null +++ b/src/style/duicontainerstyle.h @@ -0,0 +1,42 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUICONTAINERSTYLE_H +#define DUICONTAINERSTYLE_H + +#include + +#include + +class DUI_EXPORT DuiContainerStyle : public DuiWidgetStyle +{ + Q_OBJECT + DUI_STYLE_INTERNAL(DuiContainerStyle) + + DUI_STYLE_ATTRIBUTE(QSize, iconSize, IconSize) + DUI_STYLE_ATTRIBUTE(int, internalMargins, InternalMargins) + DUI_STYLE_ATTRIBUTE(int, internalItemSpacing, InternalItemSpacing) +}; + +class DUI_EXPORT DuiContainerStyleContainer : public DuiWidgetStyleContainer +{ + DUI_STYLE_CONTAINER_INTERNAL(DuiContainerStyle) +}; + +#endif diff --git a/src/style/duicontentitemstyle.h b/src/style/duicontentitemstyle.h new file mode 100644 index 000000000..24079beae --- /dev/null +++ b/src/style/duicontentitemstyle.h @@ -0,0 +1,59 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUICONTENTITEMSTYLE_H +#define DUICONTENTITEMSTYLE_H + +#include + +class DUI_EXPORT DuiContentItemStyle : public DuiWidgetStyle +{ + Q_OBJECT + DUI_STYLE_INTERNAL(DuiContentItemStyle) + DUI_STYLE_PTR_ATTRIBUTE(DuiScalableImage *, backgroundImageTopLeft, BackgroundImageTopLeft) + DUI_STYLE_PTR_ATTRIBUTE(DuiScalableImage *, backgroundImageTop, BackgroundImageTop) + DUI_STYLE_PTR_ATTRIBUTE(DuiScalableImage *, backgroundImageTopRight, BackgroundImageTopRight) + DUI_STYLE_PTR_ATTRIBUTE(DuiScalableImage *, backgroundImageLeft, BackgroundImageLeft) + DUI_STYLE_PTR_ATTRIBUTE(DuiScalableImage *, backgroundImageCenter, BackgroundImageCenter) + DUI_STYLE_PTR_ATTRIBUTE(DuiScalableImage *, backgroundImageRight, BackgroundImageRight) + DUI_STYLE_PTR_ATTRIBUTE(DuiScalableImage *, backgroundImageBottomLeft, BackgroundImageBottomLeft) + DUI_STYLE_PTR_ATTRIBUTE(DuiScalableImage *, backgroundImageBottom, BackgroundImageBottom) + DUI_STYLE_PTR_ATTRIBUTE(DuiScalableImage *, backgroundImageBottomRight, BackgroundImageBottomRight) + + DUI_STYLE_PTR_ATTRIBUTE(DuiScalableImage *, backgroundImageSinglerowLeft, BackgroundImageSinglerowLeft) + DUI_STYLE_PTR_ATTRIBUTE(DuiScalableImage *, backgroundImageSinglerowCenter, BackgroundImageSinglerowCenter) + DUI_STYLE_PTR_ATTRIBUTE(DuiScalableImage *, backgroundImageSinglerowRight, BackgroundImageSinglerowRight) + + DUI_STYLE_PTR_ATTRIBUTE(DuiScalableImage *, backgroundImageSinglecolumnTop, BackgroundImageSinglecolumnTop) + DUI_STYLE_PTR_ATTRIBUTE(DuiScalableImage *, backgroundImageSinglecolumnCenter, BackgroundImageSinglecolumnCenter) + DUI_STYLE_PTR_ATTRIBUTE(DuiScalableImage *, backgroundImageSinglecolumnBottom, BackgroundImageSinglecolumnBottom) + + DUI_STYLE_PTR_ATTRIBUTE(DuiScalableImage *, backgroundImageSingle, BackgroundImageSingle) + + DUI_STYLE_ATTRIBUTE(QString, titleObjectName, TitleObjectName) + DUI_STYLE_ATTRIBUTE(QString, subtitleObjectName, SubtitleObjectName) + DUI_STYLE_ATTRIBUTE(QString, imageObjectName, ImageObjectName) +}; + +class DUI_EXPORT DuiContentItemStyleContainer : public DuiWidgetStyleContainer +{ + DUI_STYLE_CONTAINER_INTERNAL(DuiContentItemStyle) +}; + +#endif diff --git a/src/style/duidevicestyle.h b/src/style/duidevicestyle.h new file mode 100644 index 000000000..ea8da097d --- /dev/null +++ b/src/style/duidevicestyle.h @@ -0,0 +1,42 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIDEVICESTYLE_H +#define DUIDEVICESTYLE_H + +#include + +#include +#include + +class DUI_EXPORT DuiDeviceStyle : public DuiStyle +{ + Q_OBJECT + DUI_STYLE_INTERNAL(DuiDeviceStyle) + + DUI_STYLE_ATTRIBUTE(QSize, resolution, Resolution) + DUI_STYLE_ATTRIBUTE(QSize, pixelsPerInch, PixelsPerInch) +}; + +class DUI_EXPORT DuiDeviceStyleContainer : public DuiStyleContainer +{ + DUI_STYLE_CONTAINER_INTERNAL(DuiDeviceStyle) +}; + +#endif diff --git a/src/style/duidialogstyle.h b/src/style/duidialogstyle.h new file mode 100644 index 000000000..0efd21c08 --- /dev/null +++ b/src/style/duidialogstyle.h @@ -0,0 +1,148 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIDIALOGSTYLE_H +#define DUIDIALOGSTYLE_H + +#include + +/*! + \class DuiDialogStyle + \brief Style class for standard dui dialogs. + + \code + DuiDialogStyle { + vertical-spacing: 10; + button-spacing: 10; + + title-bar-height: 5.2mm; + + dialog-vertical-alignment: bottom; + + dialog-top-margin: 5; + dialog-bottom-margin: 0; + dialog-left-margin: 10; + dialog-right-margin: 10; + + dialog-minimum-size: 1mm 1mm; + dialog-preferred-size: 100% -1; + + button-box-orientation: horizontal; + } + \endcode + + \ingroup styles + \sa DuiWidgetStyle DuiDialog DuiDialogView +*/ +class DUI_EXPORT DuiDialogStyle : public DuiSceneWindowStyle +{ + Q_OBJECT + DUI_STYLE_INTERNAL(DuiDialogStyle) + + /*! + \property DuiDialogStyle::verticalSpacing + \brief Vertical spacing between dialog contents and button box. + */ + DUI_STYLE_ATTRIBUTE(qreal, verticalSpacing, VerticalSpacing) + + /*! + \property DuiDialogStyle::titleBarHeight + \brief Height of the titlebar. + */ + DUI_STYLE_ATTRIBUTE(qreal, titleBarHeight, TitleBarHeight) + + /*! + \property DuiDialogStyle::buttonSpacing + \brief Space between buttons. + */ + DUI_STYLE_ATTRIBUTE(qreal, buttonSpacing, ButtonSpacing) + + /*! + \property DuiDialogStyle::alignment + \brief Vertical alignment of the dialog. + + Only "bottom" or "center" is supported. + */ + DUI_STYLE_ATTRIBUTE(Qt::Alignment, dialogVerticalAlignment, DialogVerticalAlignment) + + /*! + \property DuiDialogStyle::dialogTopMargin + \brief Top margin of the dialog. + + Empty space above dialog contents. + */ + DUI_STYLE_ATTRIBUTE(qreal, dialogTopMargin, DialogTopMargin) + + /*! + \property DuiDialogStyle::dialogBottomMargin + \brief Bottom margin of the dialog. + + Empty space below dialog contents. + */ + DUI_STYLE_ATTRIBUTE(qreal, dialogBottomMargin, DialogBottomMargin) + + /*! + \property DuiDialogStyle::dialogLeftMargin + \brief Left margin of the dialog. + + Empty space on the left of dialog contents. + */ + DUI_STYLE_ATTRIBUTE(qreal, dialogLeftMargin, DialogLeftMargin) + + /*! + \property DuiDialogStyle::dialogRightMargin + \brief Right margin of the dialog. + + Empty space on the right of dialog contents. + */ + DUI_STYLE_ATTRIBUTE(qreal, dialogRightMargin, DialogRightMargin) + + /*! + \property DuiDialogStyle::dialogPreferredSize + \brief Dialog preffered size. + */ + DUI_STYLE_ATTRIBUTE(QSize, dialogPreferredSize, DialogPreferredSize) + + /*! + \property DuiDialogStyle::dialogMinimumSize + \brief Dialog minimum size. + */ + DUI_STYLE_ATTRIBUTE(QSize, dialogMinimumSize, DialogMinimumSize) + + /*! + \property DuiDialogStyle::buttonBoxOrientation + \brief Orientation of dialog button box. + */ + DUI_STYLE_ATTRIBUTE(Qt::Orientation, buttonBoxOrientation, ButtonBoxOrientation) +}; + +/*! + \class DuiDialogStyleContainer + \brief Style mode container class for DuiDialogStyle. + + \ingroup styles + \sa DuiDialogStyle +*/ +class DUI_EXPORT DuiDialogStyleContainer : public DuiSceneWindowStyleContainer +{ + DUI_STYLE_CONTAINER_INTERNAL(DuiDialogStyle) +}; + +#endif + diff --git a/src/style/duidockwidgetstyle.h b/src/style/duidockwidgetstyle.h new file mode 100644 index 000000000..960497f2d --- /dev/null +++ b/src/style/duidockwidgetstyle.h @@ -0,0 +1,39 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +// Make doxygen skip this internal class +//! \cond +#ifndef DUIDOCKWIDGETSTYLE_H +#define DUIDOCKWIDGETSTYLE_H + +#include + +class DuiDockWidgetStyle : public DuiSceneWindowStyle +{ + Q_OBJECT + DUI_STYLE_INTERNAL(DuiDockWidgetStyle) +}; + +class DuiDockWidgetStyleContainer : public DuiSceneWindowStyleContainer +{ + DUI_STYLE_CONTAINER_INTERNAL(DuiDockWidgetStyle) +}; + +#endif +//! \endcond diff --git a/src/style/duiescapebuttonpanelstyle.h b/src/style/duiescapebuttonpanelstyle.h new file mode 100644 index 000000000..734efe6bf --- /dev/null +++ b/src/style/duiescapebuttonpanelstyle.h @@ -0,0 +1,40 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIESCAPEBUTTONPANELSTYLE_H +#define DUIESCAPEBUTTONPANELSTYLE_H + +#include + +class DUI_EXPORT DuiEscapeButtonPanelStyle : public DuiSceneWindowStyle +{ + Q_OBJECT + DUI_STYLE_INTERNAL(DuiEscapeButtonPanelStyle) + + DUI_STYLE_ATTRIBUTE(int, buttonAnimationLength, ButtonAnimationLength) +}; + +class DUI_EXPORT DuiEscapeButtonPanelStyleContainer : public DuiSceneWindowStyleContainer +{ + DUI_STYLE_CONTAINER_INTERNAL(DuiEscapeButtonPanelStyle) + DUI_STYLE_MODE(Fullscreen) +}; + +#endif + diff --git a/src/style/duiextendingbackgroundstyle.h b/src/style/duiextendingbackgroundstyle.h new file mode 100644 index 000000000..71601e49a --- /dev/null +++ b/src/style/duiextendingbackgroundstyle.h @@ -0,0 +1,42 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIEXTENDINGBACKGROUNDSTYLE_H +#define DUIEXTENDINGBACKGROUNDSTYLE_H + +#include + +/*! + * Style class for DuiExtendingBackgroundView + */ +class DUI_EXPORT DuiExtendingBackgroundStyle : public DuiWidgetStyle +{ + Q_OBJECT + DUI_STYLE_INTERNAL(DuiExtendingBackgroundStyle) + + //! The direction where to extend the background beyond the screen edges (left/right/top/bottom) + DUI_STYLE_ATTRIBUTE(QString, extendDirection, ExtendDirection) +}; + +class DUI_EXPORT DuiExtendingBackgroundStyleContainer : public DuiWidgetStyleContainer +{ + DUI_STYLE_CONTAINER_INTERNAL(DuiExtendingBackgroundStyle) +}; + +#endif diff --git a/src/style/duiextensionareastyle.h b/src/style/duiextensionareastyle.h new file mode 100644 index 000000000..3caa3f231 --- /dev/null +++ b/src/style/duiextensionareastyle.h @@ -0,0 +1,45 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIEXTENSIONAREASTYLE_H_ +#define DUIEXTENSIONAREASTYLE_H_ + +#include + +/*! + * DuiExtensionAreaStyle is the style class for DuiExtensionArea. + */ +class DUI_EXPORT DuiExtensionAreaStyle : public DuiWidgetStyle +{ + Q_OBJECT + DUI_STYLE(DuiExtensionAreaStyle) + + //! Whether the applets on this mashup canvas should be inside containers or not + DUI_STYLE_ATTRIBUTE(bool, containerMode, ContainerMode) +}; + +/*! + * DuiExtensionAreaStyleContainer is the style container class for DuiExtensionArea. + */ +class DUI_EXPORT DuiExtensionAreaStyleContainer : public DuiWidgetStyleContainer +{ + DUI_STYLE_CONTAINER(DuiExtensionAreaStyle) +}; + +#endif /* DUIEXTENSIONAREASTYLE_H_ */ diff --git a/src/style/duigriditemstyle.h b/src/style/duigriditemstyle.h new file mode 100644 index 000000000..5fcf986b2 --- /dev/null +++ b/src/style/duigriditemstyle.h @@ -0,0 +1,71 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIGRIDITEMSTYLE_H +#define DUIGRIDITEMSTYLE_H + +#include + +/*! + \class DuiGridItemStyle + \brief Style class for DuiGridItem. + + \code + DuiGridItemStyle { + icon-align: left; + icon-size: 64px 64px; + } + \endcode + + \ingroup styles + \sa DuiGridItemStyleContainer DuiWidgetStyle \ref styling DuiGridItem DuiGridItemView +*/ + +class DUI_EXPORT DuiGridItemStyle : public DuiWidgetStyle +{ + Q_OBJECT + DUI_STYLE_INTERNAL(DuiGridItemStyle) + + /*! + \property DuiGridItemStyle::iconAlign + \brief Alignmentation of the icon. + */ + DUI_STYLE_ATTRIBUTE(Qt::Alignment, iconAlign, IconAlign) + + /*! + \property DuiGridItemStyle::iconSize + \brief Size of the icon. + */ + DUI_STYLE_ATTRIBUTE(QSize, iconSize, IconSize) +}; + +/*! + \class DuiGridItemStyleContainer + \brief Style mode container class for DuiGridItemStyle. + + \ingroup styles + \sa DuiGridItemStyle +*/ +class DUI_EXPORT DuiGridItemStyleContainer : public DuiWidgetStyleContainer +{ + DUI_STYLE_CONTAINER_INTERNAL(DuiGridItemStyle) +}; + +#endif + diff --git a/src/style/duigroupanimationstyle.h b/src/style/duigroupanimationstyle.h new file mode 100644 index 000000000..6f6bbbe2c --- /dev/null +++ b/src/style/duigroupanimationstyle.h @@ -0,0 +1,36 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIGROUPANIMATIONSTYLE_H +#define DUIGROUPANIMATIONSTYLE_H + +#include + +class DUI_EXPORT DuiGroupAnimationStyle : public DuiAnimationStyle +{ + Q_OBJECT + DUI_STYLE_INTERNAL(DuiGroupAnimationStyle) +}; + +class DuiGroupAnimationStyleContainer : public DuiAnimationStyleContainer +{ + DUI_STYLE_CONTAINER_INTERNAL(DuiGroupAnimationStyle) +}; + +#endif diff --git a/src/style/duiimagewidgetstyle.h b/src/style/duiimagewidgetstyle.h new file mode 100644 index 000000000..48fb0221b --- /dev/null +++ b/src/style/duiimagewidgetstyle.h @@ -0,0 +1,100 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIIMAGEWIDGETSTYLE_H +#define DUIIMAGEWIDGETSTYLE_H + +#include +#include + +/*! + \class DuiImageWidgetStyle + \brief Style class for standard dui images. + + \code + DuiImageWidgetStyle { + border-top: 0; + border-left: 0; + border-bottom: 0; + border-right: 0; + border-color: #FFFFFF; + border-opacity: 1.0; + } + \endcode + + \ingroup styles + \sa DuiImageWidgetStyleContainer DuiWidgetStyle \ref styling DuiImageWidget DuiImageWidgetView +*/ + +class DUI_EXPORT DuiImageWidgetStyle : public DuiWidgetStyle +{ + Q_OBJECT + DUI_STYLE_INTERNAL(DuiImageWidgetStyle) + + /*! + \property DuiImageWidgetStyle::borderTop + \brief top border of DuiImageWidget. + */ + DUI_STYLE_ATTRIBUTE(int, borderTop, BorderTop) + + /*! + \property DuiImageWidgetStyle::borderLeft + \brief left border of DuiImageWidget. + */ + DUI_STYLE_ATTRIBUTE(int, borderLeft, BorderLeft) + + /*! + \property DuiImageWidgetStyle::borderBottom + \brief bottom border of DuiImageWidget. + */ + DUI_STYLE_ATTRIBUTE(int, borderBottom, BorderBottom) + + /*! + \property DuiImageWidgetStyle::borderRight + \brief right border of DuiImageWidget. + */ + DUI_STYLE_ATTRIBUTE(int, borderRight, BorderRight) + + /*! + \property DuiImageWidgetStyle::borderColor + \brief border color of DuiImageWidget. + */ + DUI_STYLE_ATTRIBUTE(QColor, borderColor, BorderColor) + + /*! + \property DuiImageWidgetStyle::borderOpacity + \brief border opacity of DuiImageWidget. + */ + DUI_STYLE_ATTRIBUTE(qreal, borderOpacity, BorderOpacity) +}; + +/*! + \class DuiImageWidgetStyleContainer + \brief Style mode container class for DuiImageWidgetStyle. + + \ingroup styles + \sa DuiImageWidgetStyle +*/ +class DUI_EXPORT DuiImageWidgetStyleContainer : public DuiWidgetStyleContainer +{ + DUI_STYLE_CONTAINER_INTERNAL(DuiImageWidgetStyle) +}; + +#endif + diff --git a/src/style/duiinfobannerstyle.h b/src/style/duiinfobannerstyle.h new file mode 100644 index 000000000..133657791 --- /dev/null +++ b/src/style/duiinfobannerstyle.h @@ -0,0 +1,39 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIINFOBANNERSTYLE_H +#define DUIINFOBANNERSTYLE_H + +#include + +class DUI_EXPORT DuiInfoBannerStyle : public DuiSceneWindowStyle +{ + Q_OBJECT + DUI_STYLE_INTERNAL(DuiInfoBannerStyle) + + DUI_STYLE_ATTRIBUTE(QSize, imageSize, ImageSize) + DUI_STYLE_ATTRIBUTE(QSize, iconSize, IconSize) +}; + +class DUI_EXPORT DuiInfoBannerStyleContainer : public DuiSceneWindowStyleContainer +{ + DUI_STYLE_CONTAINER_INTERNAL(DuiInfoBannerStyle) +}; + +#endif diff --git a/src/style/duilabelstyle.h b/src/style/duilabelstyle.h new file mode 100644 index 000000000..b6583a28e --- /dev/null +++ b/src/style/duilabelstyle.h @@ -0,0 +1,90 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUILABELSTYLE_H +#define DUILABELSTYLE_H + +#include +#include +#include + +/*! + \class DuiLabelStyle + \brief Style class for DuiLabel. + + \code + DuiLabelStyle { + color: blue; + font: arial 12; + } + \endcode + + \ingroup styles + \sa DuiLabelStyleContainer DuiWidgetStyle \ref styling DuiLabel +*/ +class DUI_EXPORT DuiLabelStyle : public DuiWidgetStyle +{ + Q_OBJECT + DUI_STYLE_INTERNAL(DuiLabelStyle) + + /*! + \property DuiLabelStyle::color + \brief Label font color. + + See QColor::setNamedColor for possbile values. + */ + DUI_STYLE_ATTRIBUTE(QColor, color, Color) + + /*! + \property DuiLabelStyle::font + \brief Label font. + */ + DUI_STYLE_ATTRIBUTE(QFont, font, Font) + + /*! + \property DuiLabelStyle::highlightColor + \brief Color for highlighted text fragments. + + See QColor::setNamedColor for possbile values. + */ + DUI_STYLE_ATTRIBUTE(QColor, highlightColor, HighlightColor) + + /*! + \property DuiLabelStyle::activeHighlightColor + \brief Color for active (aka link that is being pressed down) highlighted text fragments. + + See QColor::setNamedColor for possbile values. + */ + DUI_STYLE_ATTRIBUTE(QColor, activeHighlightColor, ActiveHighlightColor) +}; + +/*! + \class DuiLabelStyleContainer + \brief Style mode container class for DuiLabelStyle. + + \ingroup styles + \sa DuiLabelStyle +*/ +class DUI_EXPORT DuiLabelStyleContainer : public DuiWidgetStyleContainer +{ + DUI_STYLE_CONTAINER_INTERNAL(DuiLabelStyle) +}; + +#endif + diff --git a/src/style/duilayoutanimationstyle.h b/src/style/duilayoutanimationstyle.h new file mode 100644 index 000000000..50d2f4d64 --- /dev/null +++ b/src/style/duilayoutanimationstyle.h @@ -0,0 +1,37 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUILAYOUTANIMATIONSTYLE_H +#define DUILAYOUTANIMATIONSTYLE_H + +#include + +class DUI_EXPORT DuiLayoutAnimationStyle : public DuiAnimationStyle +{ + Q_OBJECT + DUI_STYLE_INTERNAL(DuiLayoutAnimationStyle) +}; + +// TODO: get rid of this container +class DuiLayoutAnimationStyleContainer : public DuiAnimationStyleContainer +{ + DUI_STYLE_CONTAINER_INTERNAL(DuiLayoutAnimationStyle) +}; + +#endif diff --git a/src/style/duiliststyle.h b/src/style/duiliststyle.h new file mode 100644 index 000000000..1566c665d --- /dev/null +++ b/src/style/duiliststyle.h @@ -0,0 +1,40 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUILISTSTYLE_H +#define DUILISTSTYLE_H + +#include +#include + +class DUI_EXPORT DuiListStyle : public DuiWidgetStyle +{ + Q_OBJECT + DUI_STYLE_INTERNAL(DuiListStyle) + + DUI_STYLE_ATTRIBUTE(QString, groupHeaderObjectName, GroupHeaderObjectName) +}; + +class DUI_EXPORT DuiListStyleContainer : public DuiWidgetStyleContainer +{ + DUI_STYLE_CONTAINER_INTERNAL(DuiListStyle) +}; + +#endif + diff --git a/src/style/duimashupcanvasstyle.h b/src/style/duimashupcanvasstyle.h new file mode 100644 index 000000000..5da9d50c3 --- /dev/null +++ b/src/style/duimashupcanvasstyle.h @@ -0,0 +1,45 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIMASHUPCANVASSTYLE_H_ +#define DUIMASHUPCANVASSTYLE_H_ + +#include + +/*! + * DuiMashupCanvasStyle is the style class for DuiMashupCanvas. + */ +class DUI_EXPORT DuiMashupCanvasStyle : public DuiWidgetStyle +{ + Q_OBJECT + DUI_STYLE(DuiMashupCanvasStyle) + + //! Whether the applets on this mashup canvas should be inside containers or not + DUI_STYLE_ATTRIBUTE(bool, containerMode, ContainerMode) +}; + +/*! + * DuiMashupCanvasStyleContainer is the style container class for DuiMashupCanvas. + */ +class DUI_EXPORT DuiMashupCanvasStyleContainer : public DuiWidgetStyleContainer +{ + DUI_STYLE_CONTAINER(DuiMashupCanvasStyle) +}; + +#endif /* DUIMASHUPCANVASSTYLE_H_ */ diff --git a/src/style/duimessageboxstyle.h b/src/style/duimessageboxstyle.h new file mode 100644 index 000000000..c5e1c7e9e --- /dev/null +++ b/src/style/duimessageboxstyle.h @@ -0,0 +1,37 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIMESSAGEBOXSTYLE_H +#define DUIMESSAGEBOXSTYLE_H + +#include + +class DUI_EXPORT DuiMessageBoxStyle : public DuiDialogStyle +{ + Q_OBJECT + DUI_STYLE_INTERNAL(DuiMessageBoxStyle) +}; + +class DUI_EXPORT DuiMessageBoxStyleContainer : public DuiDialogStyleContainer +{ + DUI_STYLE_CONTAINER_INTERNAL(DuiMessageBoxStyle) +}; + +#endif + diff --git a/src/style/duimodalscenewindowstyle.h b/src/style/duimodalscenewindowstyle.h new file mode 100644 index 000000000..68387ceef --- /dev/null +++ b/src/style/duimodalscenewindowstyle.h @@ -0,0 +1,37 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIMODALSCENEWINDOWSTYLE_H +#define DUIMODALSCENEWINDOWSTYLE_H + +#include + +class DUI_EXPORT DuiModalSceneWindowStyle : public DuiSceneWindowStyle +{ + Q_OBJECT + DUI_STYLE_INTERNAL(DuiModalSceneWindowStyle) +}; + +class DUI_EXPORT DuiModalSceneWindowStyleContainer : public DuiSceneWindowStyleContainer +{ + DUI_STYLE_CONTAINER_INTERNAL(DuiModalSceneWindowStyle) +}; + +#endif + diff --git a/src/style/duinavigationbarstyle.h b/src/style/duinavigationbarstyle.h new file mode 100644 index 000000000..d35f8596c --- /dev/null +++ b/src/style/duinavigationbarstyle.h @@ -0,0 +1,42 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUINAVIGATIONBARSTYLE_H +#define DUINAVIGATIONBARSTYLE_H + +#include + +class DUI_EXPORT DuiNavigationBarStyle : public DuiSceneWindowStyle +{ + Q_OBJECT + DUI_STYLE_INTERNAL(DuiNavigationBarStyle) + + DUI_STYLE_ATTRIBUTE(int, itemSpacing, ItemSpacing) + DUI_STYLE_ATTRIBUTE(int, buttonAnimationLength, ButtonAnimationLength) + DUI_STYLE_ATTRIBUTE(int, height, Height) +}; + +class DUI_EXPORT DuiNavigationBarStyleContainer : public DuiSceneWindowStyleContainer +{ + DUI_STYLE_CONTAINER_INTERNAL(DuiNavigationBarStyle) + DUI_STYLE_MODE(Fullscreen) +}; + +#endif + diff --git a/src/style/duiobjectmenustyle.h b/src/style/duiobjectmenustyle.h new file mode 100644 index 000000000..9f08be2f7 --- /dev/null +++ b/src/style/duiobjectmenustyle.h @@ -0,0 +1,39 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIOBJECTMENUSTYLE_H +#define DUIOBJECTMENUSTYLE_H + +#include + +class DuiScalableImage; + +class DUI_EXPORT DuiObjectMenuStyle : public DuiSceneWindowStyle +{ + Q_OBJECT + DUI_STYLE_INTERNAL(DuiObjectMenuStyle) +}; + +class DUI_EXPORT DuiObjectMenuStyleContainer : public DuiSceneWindowStyleContainer +{ + DUI_STYLE_CONTAINER_INTERNAL(DuiObjectMenuStyle) +}; + +#endif + diff --git a/src/style/duioverlaystyle.h b/src/style/duioverlaystyle.h new file mode 100644 index 000000000..762a0e94b --- /dev/null +++ b/src/style/duioverlaystyle.h @@ -0,0 +1,36 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIOVERLAYSTYLE_H +#define DUIOVERLAYSTYLE_H + +#include + +class DUI_EXPORT DuiOverlayStyle : public DuiSceneWindowStyle +{ + Q_OBJECT + DUI_STYLE_INTERNAL(DuiOverlayStyle) +}; + +class DUI_EXPORT DuiOverlayStyleContainer : public DuiSceneWindowStyleContainer +{ + DUI_STYLE_CONTAINER_INTERNAL(DuiOverlayStyle) +}; + +#endif diff --git a/src/style/duipageswitchanimationstyle.h b/src/style/duipageswitchanimationstyle.h new file mode 100644 index 000000000..2f4b4216b --- /dev/null +++ b/src/style/duipageswitchanimationstyle.h @@ -0,0 +1,42 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIPAGESWITCHANIMATIONSTYLE_H +#define DUIPAGESWITCHANIMATIONSTYLE_H + +#include +#include + +//! \internal +class DuiPageSwitchAnimationStyle : public DuiAnimationStyle +{ + Q_OBJECT + DUI_STYLE_INTERNAL(DuiPageSwitchAnimationStyle) + + DUI_STYLE_ATTRIBUTE(int, duration, Duration) + DUI_STYLE_ATTRIBUTE(QEasingCurve, easingCurve, EasingCurve) +}; + +class DuiPageSwitchAnimationStyleContainer : public DuiAnimationStyleContainer +{ + DUI_STYLE_CONTAINER_INTERNAL(DuiPageSwitchAnimationStyle) +}; +//! \internal_end + +#endif diff --git a/src/style/duipannablewidgetstyle.h b/src/style/duipannablewidgetstyle.h new file mode 100644 index 000000000..c8280be03 --- /dev/null +++ b/src/style/duipannablewidgetstyle.h @@ -0,0 +1,67 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIPANNABLEWIDGETSTYLE_H +#define DUIPANNABLEWIDGETSTYLE_H + +#include + +/*! + \class DuiPannableWidgetStyle + \brief Style class for standard pannable widgets. + + The pannable widget provides following styling attributes: + + \li pan-threshold - defines threshold distance used to recognize + panning gesture. + \li pan-click-threshold - defines maximum speed of the panning that + will be stopped by clicking. If the speed is lower, mousePress event + will be relayed to panned widget. + \li pointer-spring-k - k constant of the spring model used when the user + is panning the view. + \li friction-c - friction constant used when the user is panning the view. + \li sliding-friction-c - friction constant used when the user released + the finger and the view is moved by physics. + \li border-spring-k - friction constant used when the view was moved + beyond normal range by user and needs to return to the correct bounds. + \li border-friction-c - friction constant used when the view was moved + beyond normal range by user and needs to return to the correct bounds. + + \sa DuiPannableWidget DuiWidgetStyle +*/ +class DUI_EXPORT DuiPannableWidgetStyle : public DuiWidgetStyle +{ + Q_OBJECT + DUI_STYLE_INTERNAL(DuiPannableWidgetStyle) + + DUI_STYLE_ATTRIBUTE(qreal, panThreshold, PanThreshold) + DUI_STYLE_ATTRIBUTE(qreal, pointerSpringK, PointerSpringK) + DUI_STYLE_ATTRIBUTE(qreal, frictionC, FrictionC) + DUI_STYLE_ATTRIBUTE(qreal, slidingFrictionC, SlidingFrictionC) + DUI_STYLE_ATTRIBUTE(qreal, borderSpringK, BorderSpringK) + DUI_STYLE_ATTRIBUTE(qreal, borderFrictionC, BorderFrictionC) + DUI_STYLE_ATTRIBUTE(qreal, panClickThreshold, PanClickThreshold) +}; + +class DUI_EXPORT DuiPannableWidgetStyleContainer : public DuiWidgetStyleContainer +{ + DUI_STYLE_CONTAINER_INTERNAL(DuiPannableWidgetStyle) +}; + +#endif diff --git a/src/style/duipopupliststyle.h b/src/style/duipopupliststyle.h new file mode 100644 index 000000000..79dfbd5df --- /dev/null +++ b/src/style/duipopupliststyle.h @@ -0,0 +1,56 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIPOPUPLISTSTYLE_H +#define DUIPOPUPLISTSTYLE_H + +#include + +/*! + \class DuiPopupListStyle + \brief Style class for standard DuiPopupList. + + DuiPopupListStyle is derived from DuiDialogStyle. + + \ingroup styles + \sa DuiPopupListStyleContainer DuiDialogStyle \ref styling DuiPopupList DuiPopupListView +*/ + +class DUI_EXPORT DuiPopupListStyle : public DuiDialogStyle +{ + Q_OBJECT + DUI_STYLE_INTERNAL(DuiPopupListStyle) + +}; + +/*! + \class DuiPopupListStyleContainer + \brief Style mode container class for DuiPopupListStyle. + + \ingroup styles + \sa DuiPopupListStyle +*/ +class DUI_EXPORT DuiPopupListStyleContainer : public DuiDialogStyleContainer +{ + DUI_STYLE_CONTAINER_INTERNAL(DuiPopupListStyle) +}; + +#endif + + diff --git a/src/style/duipositionindicatorstyle.h b/src/style/duipositionindicatorstyle.h new file mode 100644 index 000000000..6f1173790 --- /dev/null +++ b/src/style/duipositionindicatorstyle.h @@ -0,0 +1,46 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIPOSITIONINDICATORSTYLE_H +#define DUIPOSITIONINDICATORSTYLE_H + +#include +#include + +class QPixmap; + +class DUI_EXPORT DuiPositionIndicatorStyle : public DuiWidgetStyle +{ + Q_OBJECT + DUI_STYLE_INTERNAL(DuiPositionIndicatorStyle) + + DUI_STYLE_PTR_ATTRIBUTE(QPixmap *, onPixmap, OnPixmap) + DUI_STYLE_PTR_ATTRIBUTE(QPixmap *, offPixmap, OffPixmap) + DUI_STYLE_ATTRIBUTE(int, pixmapDistance, PixmapDistance) + DUI_STYLE_ATTRIBUTE(int, minIndicatorDots, MinIndicatorDots) + DUI_STYLE_ATTRIBUTE(int, hideTimeout, HideTimeout) +}; + +class DUI_EXPORT DuiPositionIndicatorStyleContainer : public DuiWidgetStyleContainer +{ + DUI_STYLE_CONTAINER_INTERNAL(DuiPositionIndicatorStyle) +}; + +#endif + diff --git a/src/style/duiprogressindicatorstyle.h b/src/style/duiprogressindicatorstyle.h new file mode 100644 index 000000000..c4b34e417 --- /dev/null +++ b/src/style/duiprogressindicatorstyle.h @@ -0,0 +1,87 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIPROGRESSINDICATORSTYLE_H +#define DUIPROGRESSINDICATORSTYLE_H + +#include + +/*! + \class DuiProgressIndicatorStyle + \brief Style for progress indicator. + + \ingroup styles + \sa DuiProgressIndicatorStyleContainer +*/ +class DUI_EXPORT DuiProgressIndicatorStyle : public DuiWidgetStyle +{ + Q_OBJECT + DUI_STYLE_INTERNAL(DuiProgressIndicatorStyle) + + /*! + \property DuiProgressIndicatorStyle::activeImage + \brief Image of the active bar element. + */ + DUI_STYLE_PTR_ATTRIBUTE(DuiScalableImage *, activeImage, ActiveImage) + + /*! + \property DuiProgressIndicatorStyle::inactiveImage + \brief Image of the inactive bar element. + */ + DUI_STYLE_PTR_ATTRIBUTE(DuiScalableImage *, inactiveImage, InactiveImage) + + /*! + \property DuiProgressIndicatorStyle::speed + \brief Speed of unknown duration progress animation (distance/sec). + */ + DUI_STYLE_ATTRIBUTE(int, speed, Speed) + + /*! + \property DuiProgressIndicatorStyle::activeElementCount + \brief The number of active elements in circular progress indicator (unknown duration). + */ + DUI_STYLE_ATTRIBUTE(int, activeElementCount, ActiveElementCount) + + /*! + \property DuiProgressIndicatorStyle::elementSize + \brief Size of an element in the circle. + */ + DUI_STYLE_ATTRIBUTE(qreal, elementSize, ElementSize) + + /*! + \property DuiProgressIndicatorStyle::elementDistance + \brief Distance between circle elements as a multiplier to element size. + */ + DUI_STYLE_ATTRIBUTE(qreal, elementDistance, ElementDistance) +}; + +/*! + \class DuiProgressIndicatorStyleContainer + \brief This class groups all the styling modes for progress indicator. + + \ingroup styles + \sa DuiProgressIndicatorStyle +*/ +class DUI_EXPORT DuiProgressIndicatorStyleContainer : public DuiWidgetStyleContainer +{ + DUI_STYLE_CONTAINER_INTERNAL(DuiProgressIndicatorStyle) +}; + +#endif + diff --git a/src/style/duiscenelayereffectdimstyle.h b/src/style/duiscenelayereffectdimstyle.h new file mode 100644 index 000000000..933e8c935 --- /dev/null +++ b/src/style/duiscenelayereffectdimstyle.h @@ -0,0 +1,41 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISCENELAYEREFFECTDIMSTYLE_H +#define DUISCENELAYEREFFECTDIMSTYLE_H + +#include +#include + +class DUI_EXPORT DuiSceneLayerEffectDimStyle : public DuiSceneLayerEffectStyle +{ + Q_OBJECT + DUI_STYLE_INTERNAL(DuiSceneLayerEffectDimStyle) + + DUI_STYLE_ATTRIBUTE(qreal, opacity, Opacity) + DUI_STYLE_ATTRIBUTE(QEasingCurve, easingCurve, EasingCurve) + DUI_STYLE_ATTRIBUTE(int, fadeDuration, FadeDuration) +}; + +class DUI_EXPORT DuiSceneLayerEffectDimStyleContainer : public DuiSceneLayerEffectStyleContainer +{ + DUI_STYLE_CONTAINER_INTERNAL(DuiSceneLayerEffectDimStyle) +}; + +#endif diff --git a/src/style/duiscenelayereffectstyle.h b/src/style/duiscenelayereffectstyle.h new file mode 100644 index 000000000..ffa5fa713 --- /dev/null +++ b/src/style/duiscenelayereffectstyle.h @@ -0,0 +1,37 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISCENELAYEREFFECTSTYLE_H +#define DUISCENELAYEREFFECTSTYLE_H + +#include + +class DUI_EXPORT DuiSceneLayerEffectStyle : public DuiSceneWindowStyle +{ + Q_OBJECT + DUI_STYLE_INTERNAL(DuiSceneLayerEffectStyle) +}; + +class DUI_EXPORT DuiSceneLayerEffectStyleContainer : public DuiSceneWindowStyleContainer +{ + DUI_STYLE_CONTAINER_INTERNAL(DuiSceneLayerEffectStyle) +}; + +#endif + diff --git a/src/style/duiscenewindowanimationstyle.h b/src/style/duiscenewindowanimationstyle.h new file mode 100644 index 000000000..15ff095a3 --- /dev/null +++ b/src/style/duiscenewindowanimationstyle.h @@ -0,0 +1,47 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISCENEWINDOWANIMATIONSTYLE_H +#define DUISCENEWINDOWANIMATIONSTYLE_H + +#include +//#include + +class DUI_EXPORT DuiSceneWindowAnimationStyle : public DuiAnimationStyle +{ + Q_OBJECT + DUI_STYLE_INTERNAL(DuiSceneWindowAnimationStyle) + + DUI_STYLE_ATTRIBUTE(int, showDuration, ShowDuration) + DUI_STYLE_ATTRIBUTE(int, hideDuration, HideDuration) + DUI_STYLE_ATTRIBUTE(int, moveDuration, MoveDuration) + + //DUI_STYLE_ATTRIBUTE(QEasingCurve, showCurve, ShowCurve) + //DUI_STYLE_ATTRIBUTE(QEasingCurve, hideCurve, HideCurve) + //DUI_STYLE_ATTRIBUTE(QEasingCurve, moveCurve, MoveCurve) + +}; + +// TODO: get rid of this container +class DuiSceneWindowAnimationStyleContainer : public DuiAnimationStyleContainer +{ + DUI_STYLE_CONTAINER_INTERNAL(DuiSceneWindowAnimationStyle) +}; + +#endif diff --git a/src/style/duiscenewindowanimatorstyle.h b/src/style/duiscenewindowanimatorstyle.h new file mode 100644 index 000000000..6d10ce2dc --- /dev/null +++ b/src/style/duiscenewindowanimatorstyle.h @@ -0,0 +1,47 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISCENEWINDOWANIMATORSTYLE_H +#define DUISCENEWINDOWANIMATORSTYLE_H + +#include +#include + +class DUI_EXPORT DuiSceneWindowAnimatorStyle : public DuiStyle +{ + Q_OBJECT + DUI_STYLE_INTERNAL(DuiSceneWindowAnimatorStyle) + + DUI_STYLE_ATTRIBUTE(QString, transitionInType, TransitionInType) + DUI_STYLE_ATTRIBUTE(int, transitionInDuration, TransitionInDuration) + DUI_STYLE_ATTRIBUTE(bool, transitionInFade, TransitionInFade) + DUI_STYLE_ATTRIBUTE(QString, transitionOutType, TransitionOutType) + DUI_STYLE_ATTRIBUTE(int, transitionOutDuration, TransitionOutDuration) + DUI_STYLE_ATTRIBUTE(bool, transitionOutFade, TransitionOutFade) + DUI_STYLE_ATTRIBUTE(QPoint, transitionInDestination, TransitionInDestination) + DUI_STYLE_ATTRIBUTE(QPoint, transitionOutDestination, TransitionOutDestination) +}; + +class DUI_EXPORT DuiSceneWindowAnimatorStyleContainer : public DuiStyleContainer +{ + DUI_STYLE_CONTAINER_INTERNAL(DuiSceneWindowAnimatorStyle) +}; + +#endif + diff --git a/src/style/duiscenewindowstyle.h b/src/style/duiscenewindowstyle.h new file mode 100644 index 000000000..b48290ebb --- /dev/null +++ b/src/style/duiscenewindowstyle.h @@ -0,0 +1,44 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISCENEWINDOWSTYLE_H +#define DUISCENEWINDOWSTYLE_H + +#include +#include + +class DUI_EXPORT DuiSceneWindowStyle : public DuiWidgetStyle +{ + Q_OBJECT + DUI_STYLE_INTERNAL(DuiSceneWindowStyle) + + DUI_STYLE_ATTRIBUTE(QString, dismissAnimation, DismissAnimation) + + DUI_STYLE_ATTRIBUTE(Qt::Alignment, horizontalAlign, HorizontalAlign) + DUI_STYLE_ATTRIBUTE(Qt::Alignment, verticalAlign, VerticalAlign) + DUI_STYLE_ATTRIBUTE(QPointF, offset, Offset) +}; + +class DUI_EXPORT DuiSceneWindowStyleContainer : public DuiWidgetStyleContainer +{ + DUI_STYLE_CONTAINER_INTERNAL(DuiSceneWindowStyle) +}; + +#endif + diff --git a/src/style/duiseparatorstyle.h b/src/style/duiseparatorstyle.h new file mode 100644 index 000000000..be501f7d3 --- /dev/null +++ b/src/style/duiseparatorstyle.h @@ -0,0 +1,64 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISEPARATORSTYLE_H +#define DUISEPARATORSTYLE_H + +#include + +/*! + \class DuiSeparatorStyle + \brief Style class for DuiSeparator. + + \code + DuiSeparatorStyle { + span: 0.6mm; + } + \endcode + + \ingroup styles + \sa DuiSeparatorStyleContainer DuiWidgetStyle \ref styling DuiSeparator +*/ + +class DUI_EXPORT DuiSeparatorStyle : public DuiWidgetStyle +{ + Q_OBJECT + DUI_STYLE_INTERNAL(DuiSeparatorStyle) + + /*! + \property DuiSeparatorStyle::span + \brief separator span. + */ + DUI_STYLE_ATTRIBUTE(int, span, Span) +}; + +/*! + \class DuiSeparatorStyleContainer + \brief Style mode container class for DuiSeparatorStyle. + + \ingroup styles + \sa DuiSeparatorStyle +*/ +class DUI_EXPORT DuiSeparatorStyleContainer : public DuiWidgetStyleContainer +{ + DUI_STYLE_CONTAINER_INTERNAL(DuiSeparatorStyle) +}; + +#endif + diff --git a/src/style/duisettingslanguagesettingsfactorystyle.h b/src/style/duisettingslanguagesettingsfactorystyle.h new file mode 100644 index 000000000..bc0d5ef7f --- /dev/null +++ b/src/style/duisettingslanguagesettingsfactorystyle.h @@ -0,0 +1,64 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISETTINGSLANGUAGESETTINGSFACTORYSTYLE_H_ +#define DUISETTINGSLANGUAGESETTINGSFACTORYSTYLE_H_ + +#include + +/*! + * DuiSettingsLanguageSettingsFactoryStyle is the style class for DuiSettingsLanguageSettingFactory. + */ +class DUI_EXPORT DuiSettingsLanguageSettingsFactoryStyle : public DuiWidgetStyle +{ + Q_OBJECT + DUI_STYLE_INTERNAL(DuiSettingsLanguageSettingsFactoryStyle) + + //! The image ID of the content indicator to be shown next to clickable items + DUI_STYLE_ATTRIBUTE(QString, contentIndicator, ContentIndicator) + + //! The size of the content indicator + DUI_STYLE_ATTRIBUTE(QSize, contentIndicatorSize, ContentIndicatorSize) + + // TODO: remove this when there's support from DuiContainer for the styling + //! The left margin for the content indicator when it is inside a DuiContainer + DUI_STYLE_ATTRIBUTE(qreal, contentIndicatorContainerMargin, ContentIndicatorContainerMargin) + + //! The top margin of the content indicator when it is not inside a DuiContainer + DUI_STYLE_ATTRIBUTE(qreal, contentIndicatorTopMargin, ContentIndicatorTopMargin) + + //! The left margin of the content indicator when it is not inside a DuiContainer + DUI_STYLE_ATTRIBUTE(qreal, contentIndicatorLeftMargin, ContentIndicatorLeftMargin) + + //! The right margin of the content indicator when it is not inside a DuiContainer + DUI_STYLE_ATTRIBUTE(qreal, contentIndicatorRightMargin, ContentIndicatorRightMargin) + + //! The bottom margin of the content indicator when it is not inside a DuiContainer + DUI_STYLE_ATTRIBUTE(qreal, contentIndicatorBottomMargin, ContentIndicatorBottomMargin) +}; + +/*! + * DuiSettingsLanguageSettingsFactoryStyleContainer is the style container class for DuiSettingsLanguageSettingFactory. + */ +class DUI_EXPORT DuiSettingsLanguageSettingsFactoryStyleContainer : public DuiWidgetStyleContainer +{ + DUI_STYLE_CONTAINER_INTERNAL(DuiSettingsLanguageSettingsFactoryStyle) +}; + +#endif /* DUISETTINGSLANGUAGESETTINGSFACTORYSTYLE_H_ */ diff --git a/src/style/duisliderstyle.h b/src/style/duisliderstyle.h new file mode 100644 index 000000000..5e973cd16 --- /dev/null +++ b/src/style/duisliderstyle.h @@ -0,0 +1,122 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISLIDERSTYLE_H +#define DUISLIDERSTYLE_H + +#include +#include +#include + +#include + +class QPixmap; +class DuiScalableImage; + +/*! + \class DuiSliderStyle + \brief Style class for DuiSlider and DuiSeekBar. + + \ingroup styles + \sa DuiSliderStyleContainer DuiWidgetStyle \ref styling DuiSliderView +*/ +class DUI_EXPORT DuiSliderStyle : public DuiWidgetStyle +{ + Q_OBJECT + DUI_STYLE_INTERNAL(DuiSliderStyle) + + /*! + \property DuiSliderStyle::handlePixmap + \brief Handle image for released status of horizontal slider. + */ + DUI_STYLE_PTR_ATTRIBUTE(QPixmap *, handlePixmap, HandlePixmap) + /*! + \property DuiSliderStyle::handlePressedPixmap + \brief Handle image for pressed status of horizontal slider. + */ + DUI_STYLE_PTR_ATTRIBUTE(QPixmap *, handlePressedPixmap, HandlePessedPixmap) + /*! + \property DuiSliderStyle::handleVerticalPixmap + \brief Handle image for relesed status of vertical slider. + */ + DUI_STYLE_PTR_ATTRIBUTE(QPixmap *, handleVerticalPixmap, HandleVerticalPixmap) + /*! + \property DuiSliderStyle::handleVerticalPressedPixmap + \brief Handle image for pressed status of vertical slider. + */ + DUI_STYLE_PTR_ATTRIBUTE(QPixmap *, handleVerticalPressedPixmap, HandleVerticalPessedPixmap) + /*! + \property DuiSliderStyle::backgroundBaseImage + \brief Background image for slider rail for horizontal slider. + */ + DUI_STYLE_PTR_ATTRIBUTE(DuiScalableImage *, backgroundBaseImage, BackgroundBaseImage) + /*! + \property DuiSliderStyle::backgroundElapsedImage + \brief Background image for elapsed value range of slider rail for horizontal slider. + */ + DUI_STYLE_PTR_ATTRIBUTE(DuiScalableImage *, backgroundElapsedImage, BackgroundElapsedImage) + /*! + \property DuiSliderStyle::backgroundReceivedImage + \brief Background image for received value range of slider rail for horizontal slider. + */ + DUI_STYLE_PTR_ATTRIBUTE(DuiScalableImage *, backgroundReceivedImage, BackgroundReceivedImage) + /*! + \property DuiSliderStyle::backgroundBaseImage + \brief Background image for slider rail for vertical slider. + */ + DUI_STYLE_PTR_ATTRIBUTE(DuiScalableImage *, backgroundVerticalBaseImage, BackgroundVerticalBaseImage) + /*! + \property DuiSliderStyle::backgroundElapsedImage + \brief Background image for elapsed value range of slider rail for vertical slider. + */ + DUI_STYLE_PTR_ATTRIBUTE(DuiScalableImage *, backgroundVerticalElapsedImage, BackgroundVerticalElapsedImage) + /*! + \property DuiSliderStyle::backgroundReceivedImage + \brief Background image for received value range of slider rail for vertical slider. + */ + DUI_STYLE_PTR_ATTRIBUTE(DuiScalableImage *, backgroundVerticalReceivedImage, BackgroundVerticalReceivedImage) + /*! + \property DuiSliderStyle::grooveThickness + \brief Thickness of slider groove. + */ + DUI_STYLE_ATTRIBUTE(qreal, grooveThickness, GrooveThickness) + /*! + \property DuiSlider::groovePreferredLength + \brief Preferred length of slider groove (measured along it) + */ + DUI_STYLE_ATTRIBUTE(qreal, groovePreferredLength, GroovePreferredLength) + /*! + \property DuiSlider::grooveMinimumLength + \brief Minimum length of slider groove (measured along it) + */ + DUI_STYLE_ATTRIBUTE(qreal, grooveMinimumLength, GrooveMinimumLength) + /*! + \property DuiSlider::grooveMaximumLength + \brief Maximum length of slider groove (measured along it) + */ + DUI_STYLE_ATTRIBUTE(qreal, grooveMaximumLength, GrooveMaximumLength) +}; + +class DUI_EXPORT DuiSliderStyleContainer : public DuiWidgetStyleContainer +{ + DUI_STYLE_CONTAINER_INTERNAL(DuiSliderStyle) +}; + +#endif + diff --git a/src/style/duispinnerstyle.h b/src/style/duispinnerstyle.h new file mode 100644 index 000000000..8f820b3e4 --- /dev/null +++ b/src/style/duispinnerstyle.h @@ -0,0 +1,88 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISPINNERSTYLE_H +#define DUISPINNERSTYLE_H + +#include + +/*! + \class DuiSpinnerStyle + \brief Style for progress indicator. + + \ingroup styles + \sa DuiSpinnerStyleContainer +*/ +class DUI_EXPORT DuiSpinnerStyle : public DuiWidgetStyle +{ + Q_OBJECT + DUI_STYLE_INTERNAL(DuiSpinnerStyle) + + /*! + \property DuiSpinnerStyle::activeImage + \brief Image of the active bar element. + */ + DUI_STYLE_PTR_ATTRIBUTE(QPixmap *, activeImage, ActiveImage) + + /*! + \property DuiSpinnerStyle::inactiveImage + \brief Image of the inactive bar element. + */ + DUI_STYLE_PTR_ATTRIBUTE(QPixmap *, inactiveImage, InactiveImage) + + /*! + \property DuiSpinnerStyle::speed + \brief Speed of unknown duration progress animation (distance/sec). + */ + DUI_STYLE_ATTRIBUTE(int, speed, Speed) + + /*! + \property DuiSpinnerStyle::activeElementCount + \brief The number of active elements in circular progress indicator (unknown duration). + */ + DUI_STYLE_ATTRIBUTE(int, activeElementCount, ActiveElementCount) + + /*! + \property DuiSpinnerStyle::elementSize + \brief Size of an element in the circle. + */ + DUI_STYLE_ATTRIBUTE(qreal, elementSize, ElementSize) + + + /*! + \property DuiSpinnerStyle::elementCount + \brief Count of elements in spinner. + */ + DUI_STYLE_ATTRIBUTE(int, elementCount, ElementCount) +}; + +/*! + \class DuiSpinnerStyleStyleContainer + \brief This class groups all the styling modes for progress indicator. + + \ingroup styles + \sa DuiSpinnerStyle +*/ +class DUI_EXPORT DuiSpinnerStyleContainer : public DuiWidgetStyleContainer +{ + DUI_STYLE_CONTAINER_INTERNAL(DuiSpinnerStyle) +}; + +#endif + diff --git a/src/style/duistyle.cpp b/src/style/duistyle.cpp new file mode 100644 index 000000000..23e4701c4 --- /dev/null +++ b/src/style/duistyle.cpp @@ -0,0 +1,258 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duistyle.h" +#include "duistyle_p.h" +#include "duitheme.h" +#include "duitheme_p.h" +#include "duiapplication.h" +#include "duiapplicationwindow.h" + +// TODO: get rid of this include, make DuiStyle not to use duigen +#include "gen_duistyledata.h" +#include + +/* TODO: Will be removed once all the pointers are removed from the styles + and pixmaps & scalable images doesn't need release calls */ +Q_DECLARE_METATYPE(const QPixmap *) +Q_DECLARE_METATYPE(const DuiScalableImage *) +void releaseAllocatedResourcesFromStyle(const DuiStyle *style) +{ + // TODO: Fix this in duitheme so, that the pixmaps are not pointers + // and therefore we don't need to call release at all. + const int propertyCount = style->metaObject()->propertyCount(); + for (int i = 0; i < propertyCount; ++i) { + const QMetaProperty &property = style->metaObject()->property(i); + if (property.isReadable()) { + const char *type = property.typeName(); + if (strcmp(type, "const QPixmap*") == 0) { + DuiTheme::releasePixmap(qvariant_cast(property.read(style))); + } else if (strcmp(type, "const DuiScalableImage*") == 0) { + DuiTheme::releaseScalableImage(qvariant_cast(property.read(style))); + } + } + } +} + +/////////////////// +// PRIVATE CLASS // +/////////////////// +int DuiStyle::references() const +{ + return data->references; +} + +int DuiStyle::addReference() +{ + data->references++; + return data->references; +} + +int DuiStyle::removeReference() +{ + data->references--; + if (data->references <= 0) { + releaseAllocatedResourcesFromStyle(this); + deleteLater(); // Use deleteLater() for QObjects instead of "delete this" + return 0; + } + return data->references; +} + +DuiStyleContainerPrivate::DuiStyleContainerPrivate() : + currentMode("default") +{ + defaultStyle[Dui::Landscape] = NULL; + defaultStyle[Dui::Portrait] = NULL; + currentStyle[Dui::Landscape] = &defaultStyle[Dui::Landscape]; + currentStyle[Dui::Portrait] = &defaultStyle[Dui::Portrait]; + parent = NULL; +} + +DuiStyleContainerPrivate::~DuiStyleContainerPrivate() +{ + DuiTheme::releaseStyle(defaultStyle[Dui::Landscape]); + DuiTheme::releaseStyle(defaultStyle[Dui::Portrait]); +} + +////////////////// +// PUBLIC CLASS // +////////////////// + +// public constructor +DuiStyleContainer::DuiStyleContainer() : + d_ptr(new DuiStyleContainerPrivate) +{ + d_ptr->q_ptr = this; + DuiThemePrivate::registerStyleContainer(this); +} + +// protected constructor +DuiStyleContainer::DuiStyleContainer(DuiStyleContainerPrivate *dd) : + d_ptr(dd) +{ + d_ptr->q_ptr = this; + DuiThemePrivate::registerStyleContainer(this); +} + +// destructor +DuiStyleContainer::~DuiStyleContainer() +{ + DuiThemePrivate::unregisterStyleContainer(this); + delete d_ptr; +} + +void DuiStyleContainer::initialize(const QString &objectName, const QString &type, const DuiWidgetController *parent) +{ + // The style type should never be "default" - that would probably be a view type + // that's mistakenly being used as a style type. + // The caller probably means "" instead. + Q_ASSERT(type != "default"); + + d_ptr->objectName = objectName; + d_ptr->type = type; + d_ptr->parent = parent; + + reloadStyles(); +} + +// set the container objectName +void DuiStyleContainer::setObjectName(const QString &objectName) +{ + if (!d_ptr->defaultStyle || objectName != d_ptr->objectName) { + d_ptr->objectName = objectName; + reloadStyles(); + } +} + +// set the container typeName +void DuiStyleContainer::setType(const QString &type) +{ + // The style type should never be "default" - that would probably be a view type + // that's mistakenly being used as a style type. + // The caller probably means "" instead. + Q_ASSERT(type != "default"); + + if (!d_ptr->defaultStyle || type != d_ptr->type) { + d_ptr->type = type; + reloadStyles(); + } +} +// returns the object name of the style container +QString DuiStyleContainer::objectName() const +{ + return d_ptr->objectName; +} + +// returns the type name of the style container +QString DuiStyleContainer::type() const +{ + return d_ptr->type; +} + +void DuiStyleContainer::setParent(const DuiWidgetController *parent) +{ + if (d_ptr->parent != parent) { + d_ptr->parent = parent; + reloadStyles(); + } +} + +const DuiWidgetController *DuiStyleContainer::parent() const +{ + return d_ptr->parent; +} + + +// this method is for this class and derived classes to set the current style +// changes the pointer reference of current style +void DuiStyleContainer::setCurrentStyle(const DuiStyle*& landscapeStyle, const DuiStyle*& portraitStyle) +{ + Q_ASSERT(landscapeStyle); + Q_ASSERT(portraitStyle); + d_ptr->currentStyle[Dui::Landscape] = &landscapeStyle; + d_ptr->currentStyle[Dui::Portrait] = &portraitStyle; +} + +// getter for derived classes +const DuiStyle *DuiStyleContainer::currentStyle() const +{ + Dui::Orientation orientation = Dui::Landscape; + + if (DuiApplication::activeWindow()) + orientation = DuiApplication::activeWindow()->orientation(); + + return *(d_ptr->currentStyle[orientation]); +} + +void DuiStyleContainer::setCurrentMode(const QString &mode) +{ + d_ptr->currentMode = mode; +} + +QString DuiStyleContainer::currentMode() +{ + return d_ptr->currentMode; +} + +// returns pointer to the current style +const DuiStyle *DuiStyleContainer::operator->() const +{ + return currentStyle(); +} + + +// virtual method which returns the name of the style in this container instance +const char *DuiStyleContainer::styleType() const +{ + return "DuiStyle"; +} + +// virtual method which will reload all styles used in this container instance +// this method will be called when e.g. objectName changes +void DuiStyleContainer::reloadStyles() +{ + DuiTheme::releaseStyle(d_ptr->defaultStyle[Dui::Landscape]); + d_ptr->defaultStyle[Dui::Landscape] = NULL; + + DuiTheme::releaseStyle(d_ptr->defaultStyle[Dui::Portrait]); + d_ptr->defaultStyle[Dui::Portrait] = NULL; + + if (d_ptr->currentMode == "default") { + setModeDefault(); + } +} + +// sets the current style to default +void DuiStyleContainer::setModeDefault() +{ + d_ptr->currentMode = "default"; + if (!d_ptr->defaultStyle[Dui::Landscape]) { + const DuiStyle *tmp = d_ptr->defaultStyle[Dui::Landscape]; + d_ptr->defaultStyle[Dui::Landscape] = DuiTheme::style(styleType(), objectName(), "", type(), Dui::Landscape, parent()); + DuiTheme::releaseStyle(tmp); + + } + if (!d_ptr->defaultStyle[Dui::Portrait]) { + const DuiStyle *tmp = d_ptr->defaultStyle[Dui::Portrait]; + d_ptr->defaultStyle[Dui::Portrait] = DuiTheme::style(styleType(), objectName(), "", type(), Dui::Portrait, parent()); + DuiTheme::releaseStyle(tmp); + } + setCurrentStyle(d_ptr->defaultStyle[Dui::Landscape], d_ptr->defaultStyle[Dui::Portrait]); +} diff --git a/src/style/duistyle.h b/src/style/duistyle.h new file mode 100644 index 000000000..e49bab117 --- /dev/null +++ b/src/style/duistyle.h @@ -0,0 +1,131 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISTYLE_H +#define DUISTYLE_H + +#include +#include "duiexport.h" + +// style macro +#define DUI_STYLE(CLASS) \ + public: \ + CLASS(); \ + protected: \ + virtual ~CLASS(); \ + CLASS(class CLASS##Data* data); \ + class CLASS##Data *data; \ + private: + +// style macro for internal styles +#define DUI_STYLE_INTERNAL(CLASS) \ + public: \ + CLASS(); \ + virtual ~CLASS(); \ + protected: \ + CLASS(class CLASS##Data* data); \ + private: + +// style attribute macro +#define DUI_STYLE_ATTRIBUTE(TYPE, NAME, CAMELNAME) \ + Q_PROPERTY(TYPE NAME READ NAME WRITE set##CAMELNAME) \ + public: \ + const TYPE& NAME() const; \ + void set##CAMELNAME(const TYPE& NAME); \ + private: + +// style attribute macro for pointers +#define DUI_STYLE_PTR_ATTRIBUTE(TYPE, NAME, CAMELNAME) \ + Q_PROPERTY(TYPE NAME READ NAME WRITE set##CAMELNAME) \ + public: \ + const TYPE NAME() const; \ + void set##CAMELNAME(const TYPE NAME); \ + private: + +// style container macro +#define DUI_STYLE_CONTAINER(STYLE_CLASS) \ + public: \ + STYLE_CLASS##Container(); \ + virtual ~STYLE_CLASS##Container(); \ + const STYLE_CLASS* operator->() const; \ + protected: \ + STYLE_CLASS##Container(class STYLE_CLASS##ContainerPrivate* dd); \ + virtual void reloadStyles(); \ + virtual const char* styleType() const; \ + class STYLE_CLASS##ContainerPrivate * const d_ptr; \ + private: \ + Q_DECLARE_PRIVATE(STYLE_CLASS##Container) + +// style container macro for internal styles +#define DUI_STYLE_CONTAINER_INTERNAL(STYLE_CLASS) \ + public: \ + STYLE_CLASS##Container(); \ + virtual ~STYLE_CLASS##Container(); \ + const STYLE_CLASS* operator->() const; \ + protected: \ + STYLE_CLASS##Container(class STYLE_CLASS##ContainerPrivate* dd); \ + virtual void reloadStyles(); \ + virtual const char* styleType() const; \ + private: \ + Q_DECLARE_PRIVATE(STYLE_CLASS##Container) + +// style mode macro +#define DUI_STYLE_MODE(MODE) \ + public: \ + void setMode##MODE(); + +class DuiWidgetController; + +class DUI_EXPORT DuiStyle : public QObject +{ + Q_OBJECT + DUI_STYLE(DuiStyle) + +protected: + int references() const; + int addReference(); + int removeReference(); + + friend class DuiStyleSheet; +}; + +class DUI_EXPORT DuiStyleContainer +{ + DUI_STYLE_CONTAINER(DuiStyle) + DUI_STYLE_MODE(Default) +public: + void initialize(const QString &objectName, const QString &type, const DuiWidgetController *parent); + + void setObjectName(const QString &objectName); + void setType(const QString &type); + QString objectName() const; + QString type() const; + void setParent(const DuiWidgetController *parent); + const DuiWidgetController *parent() const; +protected: + void setCurrentStyle(const DuiStyle*& landscapeStyle, const DuiStyle*& portraitStyle); + const DuiStyle *currentStyle() const; + + void setCurrentMode(const QString &mode); + QString currentMode(); + + friend class DuiTheme; +}; + +#endif diff --git a/src/style/duistyle_p.h b/src/style/duistyle_p.h new file mode 100644 index 000000000..b90735d81 --- /dev/null +++ b/src/style/duistyle_p.h @@ -0,0 +1,43 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISTYLE_P_H +#define DUISTYLE_P_H + +#include +class DuiStyle; +class DuiWidgetController; + +class DuiStyleContainerPrivate +{ + friend class DuiStyleContainer; +public: + DuiStyleContainerPrivate(); + virtual ~DuiStyleContainerPrivate(); + QString currentMode; +private: + const DuiStyle *defaultStyle[2]; + const DuiStyle **currentStyle[2]; + QString objectName; + QString type; + DuiStyleContainer *q_ptr; + const DuiWidgetController *parent; +}; + +#endif diff --git a/src/style/duistylecreator.cpp b/src/style/duistylecreator.cpp new file mode 100644 index 000000000..0f9e282fe --- /dev/null +++ b/src/style/duistylecreator.cpp @@ -0,0 +1,52 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duistylecreator.h" +#include "duiclassfactory.h" + +class DuiStyleCreatorBasePrivate +{ +public: + QString assemblyName; + Dui::AssemblyType assemblyType; +}; + +DuiStyleCreatorBase::DuiStyleCreatorBase(const char *styleClassName, const char *styleAssemblyName, Dui::AssemblyType styleAssemblyType) : + d_ptr(new DuiStyleCreatorBasePrivate) +{ + d_ptr->assemblyName = styleAssemblyName; + d_ptr->assemblyType = styleAssemblyType; + DuiClassFactory::instance()->registerStyleCreator(this, styleClassName); +} + +DuiStyleCreatorBase::~DuiStyleCreatorBase() +{ + DuiClassFactory::instance()->unregisterStyleCreator(this); + delete d_ptr; +} + +QString DuiStyleCreatorBase::assemblyName() const +{ + return d_ptr->assemblyName; +} + +Dui::AssemblyType DuiStyleCreatorBase::assemblyType() const +{ + return d_ptr->assemblyType; +} diff --git a/src/style/duistylecreator.h b/src/style/duistylecreator.h new file mode 100644 index 000000000..f5d0d062a --- /dev/null +++ b/src/style/duistylecreator.h @@ -0,0 +1,124 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISTYLECREATOR_H +#define DUISTYLECREATOR_H + +#include "duiexport.h" +#include +#include + +#if defined DUI_LIBRARY_NAME +#define DUI_REGISTER_STYLE(STYLE) \ + static const DuiStyleCreator Rich label can be styled."; + DuiLabel* label = new DuiLabel(styledText); + \endcode + + Links in rich label: + \code + //create label with a link + QString text = "Rich label can contain links ."; + DuiLabel* label = new DuiLabel(styledText); + + //connect to signal to receive notification when user clicks a link in label + connect(label, SIGNAL(linkActivated(QString)), this, SLOT(linkActivated(QString))); + \endcode + \sa DuiLabelModel DuiLabelStyle Supported HTML Subset +*/ +class DUI_EXPORT DuiLabel : public DuiWidgetController +{ + Q_OBJECT + DUI_CONTROLLER(DuiLabel) + + /*! + \property DuiLabel::alignment + \brief Alignmentation of the label. + + See DuiLabelModel::alignment for details. + */ + Q_PROPERTY(Qt::Alignment alignment READ alignment WRITE setAlignment) + + /*! + \property DuiLabel::wordWrap + \brief Word wrapping mode of the label. + + See DuiLabelModel::wordWrap for details. + */ + Q_PROPERTY(bool wordWrap READ wordWrap WRITE setWordWrap) + + /*! + \property DuiLabel::textElide + \brief Text eliding mode of the label. + + See DuiLabelModel::textElide for details. + */ + Q_PROPERTY(bool textElide READ textElide WRITE setTextElide) + + /*! + \property DuiLabel::text + \brief Text of the label. + + See DuiLabelModel::text for details. + */ + Q_PROPERTY(QString text READ text WRITE setText) + + /*! + \property DuiLabel::text + \brief Color of the label text. + + See DuiLabelModel::color for details. + */ + Q_PROPERTY(QColor color READ color WRITE setColor) + +public: + + /*! + \brief Constructs label widget. + \param parent optional parent. + \param model optional model. + */ + DuiLabel(QGraphicsItem *parent = 0, DuiLabelModel *model = 0); + + /*! + \brief Constructs a label with a text. + \param text Label text. + \param parent Optional parent. + */ + explicit DuiLabel(QString const &text, QGraphicsItem *parent = 0); + + /*! + \brief Destructs label widget. + */ + virtual ~DuiLabel(); + + /*! + \brief Set an alignmentation for the text. + \sa Qt::Alignment + */ + void setAlignment(Qt::Alignment alignment); + + /*! + \brief Returns the current alignmentation. + \return alignment + */ + Qt::Alignment alignment() const; + + /*! + \brief Enable/disable automatic word wrapping. + */ + void setWordWrap(bool wrap); + + /*! + \brief Returns whether the text in label will be wrapped or not. + + If the label doesn't have enough space to show the full text on one + line, the text will be wrapped to multiple lines. + + \return wrap mode + */ + bool wordWrap() const; + + /*! + Returns the current text. + \return text + */ + QString text() const; + + /*! + \brief Enable/disable automatic text eliding. + + If the label doesn't have enough space to show the full text on one + line, the will be elided with three dots. + + \sa Qt::TextElideMode + */ + void setTextElide(bool elide); + + /*! + \brief Returns the elide mode of the label. + \return elide mode of the label + + \sa Qt::TextElideMode + */ + bool textElide() const; + + /*! + \brief Set the font used in DuiLabel. + + By default DuiLabel uses font defined in the css file. This method + can be used to change the font from code. + + Overrides QGraphicsWidget::setFont(const QFont &font) + */ + void setFont(const QFont &font); + + /*! + \brief Return the current font. + + The current font is either a font previously set with setFont() or + if nothing has been manually set the one that has been defined in css + for this particular label. + + Overrides QGraphicsWidget::font() const. + + \return current font + */ + QFont font() const; + + /*! + \brief Set the text color for the DuiLabel. + + By default DuiLabel uses color defined in the css file. This method + can be used to change the color from code. Giving invalid color + (QColor()) takes font in the css back to use. + */ + void setColor(const QColor &color); + + /*! + \brief Returns the color previously set with setColor(). + + \return current color + */ + QColor color() const; + + /*! + \brief Add highlighter object to duilabel. + + \sa DuiLabelHighlighter + */ + void addHighlighter(DuiLabelHighlighter *highlighter); + + /*! + \brief Remove highlighter object from duilabel. + + \sa DuiLabelHighlighter + */ + void removeHighlighter(DuiLabelHighlighter *highlighter); + + /*! + \brief Remove all highlighter objects from duilabel. + + \sa DuiLabelHighlighter + */ + void removeAllHighlighters(); + +public Q_SLOTS: + + /*! + \brief Set text for the label. + */ + void setText(const QString &text); + +Q_SIGNALS: + /*! + \brief A signal which is emitted when an anchor in the label is clicked. + + \a link contains the clicked link. The signal is only emitted when the link + is defined using anchor " nokia " html + tag. + + */ + void linkActivated(const QString &link); + +protected: + + //! \reimp + virtual void changeEvent(QEvent *event); + virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent *event); + virtual void setupModel(); + //! \reimp_end + +private: + Q_DISABLE_COPY(DuiLabel) + Q_DECLARE_PRIVATE(DuiLabel) +}; +#endif diff --git a/src/widgets/duilabel_p.h b/src/widgets/duilabel_p.h new file mode 100644 index 000000000..6c94abab2 --- /dev/null +++ b/src/widgets/duilabel_p.h @@ -0,0 +1,30 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUILABEL_P_H +#define DUILABEL_P_H + +#include "private/duiwidgetcontroller_p.h" + +class DuiLabelPrivate : public DuiWidgetControllerPrivate +{ + Q_DECLARE_PUBLIC(DuiLabel) +}; + +#endif diff --git a/src/widgets/duilabelhighlighter.cpp b/src/widgets/duilabelhighlighter.cpp new file mode 100644 index 000000000..4dc920849 --- /dev/null +++ b/src/widgets/duilabelhighlighter.cpp @@ -0,0 +1,63 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duilabelhighlighter.h" + +class DuiCommonLabelHighlighterPrivate +{ +public: + QRegExp m_regExp; +}; + +DuiLabelHighlighter::~DuiLabelHighlighter() +{ +} + +bool DuiLabelHighlighter::validate(QString &item) const +{ + Q_UNUSED(item); + return true; +} +DuiCommonLabelHighlighter::DuiCommonLabelHighlighter(const QRegExp ®Exp) + : d_ptr(new DuiCommonLabelHighlighterPrivate) +{ + Q_D(DuiCommonLabelHighlighter); + d->m_regExp = regExp; +} + +DuiCommonLabelHighlighter::~DuiCommonLabelHighlighter() +{ +} + +QRegExp DuiCommonLabelHighlighter::highlightExpression() const +{ + Q_D(const DuiCommonLabelHighlighter); + return d->m_regExp; +} + +void DuiCommonLabelHighlighter::click(const QString &item) +{ + emit clicked(item); +} + +void DuiCommonLabelHighlighter::longPress(const QString &item) +{ + emit longPressed(item); +} + diff --git a/src/widgets/duilabelhighlighter.h b/src/widgets/duilabelhighlighter.h new file mode 100644 index 000000000..dad9db01f --- /dev/null +++ b/src/widgets/duilabelhighlighter.h @@ -0,0 +1,129 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUILABELHIGHLIGHTER_H +#define DUILABELHIGHLIGHTER_H + +#include +#include +#include "duiexport.h" + +/*! + \class DuiLabelHighlighter + \brief Abstract base class for label highlighter objects. + + Class is used to highlight text fragments from DuiLabel. Class will also + receive user interaction events when clicking and long pressing a highlighted + piece of text. + + \ingroup widgets +*/ +class DUI_EXPORT DuiLabelHighlighter +{ +public: + + /*! + \brief Destructs DuiLabelHighlighter. + */ + virtual ~DuiLabelHighlighter(); + + /*! + \brief Returns regular expression for highlighting text fragments. + */ + virtual QRegExp highlightExpression() const = 0; + + /*! + \brief Method for validating highlighted items. + + Return true if the item is really valid, return false it the item + is invalid. The validated \a item can be changed if wanted. The + outputted \a item will be the same that is given to the click() and + longPress() methods. Default implementation just returns true. + */ + virtual bool validate(QString &item) const; + + /*! + \brief Callback method when user clicks a highlighted item. + */ + virtual void click(const QString &item) = 0; + + /*! + \brief Callback method when user long presses a highlighted item. + */ + virtual void longPress(const QString &item) = 0; +}; + +/*! + \class DuiCommonLabelHighlighter + \brief Common highlighter class for easily highlighting items from DuiLabel without inheriting own classes. + + Inherits DuiLabelHighlighter and emits signals for the click and longPress interactions. + + \ingroup widgets +*/ +class DuiCommonLabelHighlighterPrivate; +class DUI_EXPORT DuiCommonLabelHighlighter : public QObject, public DuiLabelHighlighter +{ + Q_OBJECT + +public: + + /*! + \brief Constructs common highlighter class. + */ + DuiCommonLabelHighlighter(const QRegExp ®Exp); + + /*! + \brief Destructs DuiCommonLabelHighlighter. + */ + virtual ~DuiCommonLabelHighlighter(); + + /*! + \brief Returns the expression that was given as parameter into the constructor. + */ + virtual QRegExp highlightExpression() const; + + /*! + \brief Emits clicked() signal; + */ + virtual void click(const QString &item); + + /*! + \brief Emits longPressed() signal; + */ + virtual void longPress(const QString &item); + +Q_SIGNALS: + + /*! + \brief A signal which is emitted when a highlighted item in label is clicked. + */ + void clicked(const QString &item); + + /*! + \brief A signal which is emitted when a highlighted item in label is long pressed. + */ + void longPressed(const QString &item); + +private: + DuiCommonLabelHighlighterPrivate *const d_ptr; + Q_DECLARE_PRIVATE(DuiCommonLabelHighlighter) +}; + +#endif diff --git a/src/widgets/duilabelmodel.cpp b/src/widgets/duilabelmodel.cpp new file mode 100644 index 000000000..3ed01ea37 --- /dev/null +++ b/src/widgets/duilabelmodel.cpp @@ -0,0 +1,36 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duilabelmodel.h" + +void DuiLabelModel::addHighlighter(DuiLabelHighlighter *highlighter) +{ + DuiLabelHighlighterList &list = _highlighters(); + if (list.indexOf(highlighter) == -1) { + list.append(highlighter); + memberModified(Highlighters); + } +} + +void DuiLabelModel::removeHighlighter(DuiLabelHighlighter *highlighter) +{ + DuiLabelHighlighterList &list = _highlighters(); + if (list.removeOne(highlighter)) + memberModified(Highlighters); +} diff --git a/src/widgets/duilabelmodel.h b/src/widgets/duilabelmodel.h new file mode 100644 index 000000000..b9a7ca231 --- /dev/null +++ b/src/widgets/duilabelmodel.h @@ -0,0 +1,139 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUILABELMODEL_H +#define DUILABELMODEL_H + +#include +#include + +class DuiLabelHighlighter; +typedef QList DuiLabelHighlighterList; + +/*! + \class DuiLabelModel + \brief Model class for DuiLabel. + + \ingroup models + \sa DuiLabel +*/ +class DUI_EXPORT DuiLabelModel : public DuiWidgetModel +{ + Q_OBJECT + DUI_MODEL_INTERNAL(DuiLabelModel) + + /*! + \property DuiLabelModel::text + \brief The text of the label. + */ + DUI_MODEL_PROPERTY(QString, text, Text, true, QString()) + + /*! + \property DuiLabelModel::wordWrap + \brief Word wrapping mode of the label. + + When set to true, the label automatically wraps the text into multiple + lines, if whole text does not fit into one line. + */ + DUI_MODEL_PROPERTY(bool, wordWrap, WordWrap, true, false) + + /*! + \property DuiLabelModel::alignment + \brief Alignmentation of the label. + */ + DUI_MODEL_PROPERTY(Qt::Alignment, alignment, Alignment, true, Qt::AlignLeft | Qt::AlignVCenter) + + /*! + \property DuiLabelModel::textDirection + \brief Text direction of the label. + */ + DUI_MODEL_PROPERTY(Qt::LayoutDirection, textDirection, TextDirection, true, qApp->layoutDirection()) + + /*! + \property DuiLabelModel::textElide + \brief Text eliding mode of the label. + + When set to true, the label automatically elides text with three dots if + the whole text does not fit into one line. + */ + DUI_MODEL_PROPERTY(bool, textElide, TextElide, true, false) + + /*! + \property DuiLabelModel::useModelFont + \brief Boolean value which defines whether to use the font from model or CSS. + + If true the font defined by DuiLabelModel::font property is used, if + false font defined in CSS is used. + */ + DUI_MODEL_PROPERTY(bool, useModelFont, UseModelFont, true, false) + + /*! + \property DuiLabelModel::font + \brief Default font for the label. + + Defines the default font to be used in label. This font is used only if + DuiLabelModel::useModelFont is set to true otherwise the font defined + in CSS is used. + */ + DUI_MODEL_PROPERTY(QFont, font, Font, true, QFont()) + + /*! + \property DuiLabelModel::color + \brief Default color for the label. + + Defines the default color to be used in label. This coor is used only if + it has been set set to a valid value (color.isValid() == true) otherwise + the color defined in CSS is used. + */ + DUI_MODEL_PROPERTY(QColor, color, Color, true, QColor()) + + /*! + \property DuiLabelModel::highlighters + \brief List of active text highlighter objects for the label. + + Highlighter objects are used for highlighting different types of text + fragments like urls, email addresses etc. Objects also receive callbacks + when the highlighted items are interacted by the user. + */ + DUI_MODEL_PROPERTY(DuiLabelHighlighterList, highlighters, Highlighters, true, DuiLabelHighlighterList()) + +public: + void emitLinkActivated(const QString &link) const { + Q_EMIT linkActivated(link); + } + + /*! + \brief Add highlighter to list. + */ + void addHighlighter(DuiLabelHighlighter *highlighter); + + /*! + \brief Remove highlighter from list. + */ + void removeHighlighter(DuiLabelHighlighter *highlighter); + +Q_SIGNALS: + /*! + * \brief A signal which is emitted when URL in this widget is clicked. + */ + void linkActivated(const QString &link) const; +}; + +#endif + diff --git a/src/widgets/duilist.cpp b/src/widgets/duilist.cpp new file mode 100644 index 000000000..37a1436ca --- /dev/null +++ b/src/widgets/duilist.cpp @@ -0,0 +1,210 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include +#include + +#include +#include "duilist.h" +#include "duitheme.h" +#include "duibutton.h" +#include "duilist_p.h" +#include "duilabel.h" +#include "duipannableviewport.h" + +#include "duiwidgetcreator.h" +DUI_REGISTER_WIDGET(DuiList) + +DuiListPrivate::DuiListPrivate() +{ +} + +DuiListPrivate::~DuiListPrivate() +{ +} + +void DuiListPrivate::init() +{ + Q_Q(DuiList); + + q->setSelectionMode(DuiList::NoSelection); + q->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding)); //grow to available space in both directions +} + +DuiList::DuiList(DuiListPrivate *dd, DuiListModel *model, QGraphicsItem *parent) + : DuiWidgetController(dd, model, parent) +{ + Q_D(DuiList); + d->init(); +} + +DuiList::DuiList(QGraphicsItem *parent) + : DuiWidgetController(new DuiListPrivate, new DuiListModel, parent) + +{ + Q_D(DuiList); + d->init(); +} + +DuiList::~DuiList() +{ +} + +void DuiList::updateData(const QList& modifications) +{ + const char *member; + for (int i = 0; i < modifications.count(); i++) { + member = modifications[i]; + if (member == DuiListModel::ListIsMoving) { + model()->listIsMoving() ? emit panningStarted() : emit panningStopped(); + } + } +} + +void DuiList::setItemModel(QAbstractItemModel *itemModel) +{ + setSelectionModel(NULL); + + if (itemModel) + setSelectionModel(new QItemSelectionModel(itemModel)); + + model()->setItemModel(itemModel); +} + + +QAbstractItemModel *DuiList::itemModel() const +{ + return model()->itemModel(); +} + +void DuiList::scrollTo(const QModelIndex &index) +{ + emit scrollToIndex(index); + scrollTo(index, DuiList::EnsureVisibleHint); +} + +void DuiList::scrollTo(const QModelIndex &index, ScrollHint hint) +{ + emit scrollToIndex(index); + + model()->beginTransaction(); + model()->setScrollHint(hint); + model()->setScrollToIndex(index); + model()->commitTransaction(); +} + +QItemSelectionModel *DuiList::selectionModel() const +{ + return model()->selectionModel(); +} + +void DuiList::setSelectionModel(QItemSelectionModel *selectionModel) +{ + if (selectionModel == this->selectionModel()) { + return; + } + + model()->setSelectionModel(selectionModel); + emit selectionModelChanged(selectionModel); +} + +void DuiList::selectItem(const QModelIndex &index) +{ + QItemSelectionModel *sModel = selectionModel(); + + if (index.isValid() && sModel->model() != index.model()) { + qWarning("DuiList::selectItem() failed: " + "Trying to select an item that is for" + " a different model than the view "); + return; + } + + emit itemClicked(index); + + if (sModel != NULL) { + if (selectionMode() == DuiList::MultiSelection) { + if (sModel->isSelected(index)) { + sModel->select(index, QItemSelectionModel::Deselect); + } else { + sModel->select(index, QItemSelectionModel::Select); + } + } else if (selectionMode() == DuiList::SingleSelection) { + sModel->select(index, QItemSelectionModel::SelectCurrent); + } + } +} + +void DuiList::setCellCreator(DuiCellCreator *itemCreator) +{ + model()->setCellCreator(itemCreator); +} + +const DuiCellCreator *DuiList::cellCreator() const +{ + return model()->cellCreator(); +} + +const QModelIndex DuiList::firstVisibleItem() const +{ + return model()->firstVisibleItem(); +} + +const QModelIndex DuiList::lastVisibleItem() const +{ + return model()->lastVisibleItem(); +} + +bool DuiList::showGroups() const +{ + return model()->showGroups(); +} + +void DuiList::setShowGroups(bool showGroups) +{ + model()->setShowGroups(showGroups); +} + +int DuiList::columns() const +{ + return model()->columns(); +} + +void DuiList::setColumns(int columns) +{ + model()->setColumns(columns); +} + +void DuiList::setSelectionMode(DuiList::SelectionMode mode) +{ + Q_D(DuiList); + d->selectionMode = mode; + + QItemSelectionModel *sModel = selectionModel(); + + if (sModel) + sModel->clearSelection(); +} + +DuiList::SelectionMode DuiList::selectionMode() const +{ + Q_D(const DuiList); + return d->selectionMode; +} diff --git a/src/widgets/duilist.h b/src/widgets/duilist.h new file mode 100644 index 000000000..25ac39aab --- /dev/null +++ b/src/widgets/duilist.h @@ -0,0 +1,321 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUILIST_H +#define DUILIST_H + +#include + +#include "duiwidgetcontroller.h" +#include + +class QGraphicsSceneResizeEvent; +class DuiListPrivate; +class QItemSelectionModel; +class QAbstractItemModel; +class QModelIndex; +class DuiCellCreator; + +/*! + \class DuiList + \brief DuiList implements a list view. + + DuiList provides support for data that inherits QAbstractItemModel and can be set + by setItemModel(). + + See http://doc.trolltech.com/4.5/model-view-creating-models.html#a-read-only-example-model + for how to build a custom item model that can be used with DuiList. + + A very minimal basic item model example is shown below. The example model has 1 + items and that item is DuiContentItem. + + Important thing to remember is model defines protocol between model and list. Model defines + the way data will be passed to DuiCellCreator which will create widgets. + + Model will look like this: + \code + + class TestModel : public QAbstractListModel + { + Q_OBJECT + + public: + TestModel(QObject *parent = 0) + : QAbstractListModel(parent) {} + + int rowCount(const QModelIndex &parent = QModelIndex()) const; + QVariant data(const QModelIndex &index, int role) const; + + }; + + + int TestModel::rowCount(const QModelIndex &parent) const + { + Q_UNUSED(parent); + return 1; + } + + QVariant TestModel::data(const QModelIndex &index, int role) const + { + if (role == Qt::DisplayRole) { + QStringList rowData; + rowData << "Angelina"; // first name + rowData << "Joli"; // last name + return QVariant(rowData); + } + + return QVariant(); + } + + \endcode + + Model doesn't tell DuiList how to create actual widgets, we need DuiCellCreator for that. + DuiAbstractCellCreator is the best candidate for simple case (keep in mind that you can change style of DuiContentItem only + in it's constructor, so if other style is needed, DuiAbstractCellCreator will not work, DuiCellCreator should be used instead): + + \code + class DuiContentItemCreator : public DuiAbstractCellCreator + { + public: + void updateCell(const QModelIndex& index, DuiWidget * cell) const + { + DuiContentItem * contentItem = qobject_cast(cell); + QVariant data = index.data(Qt::DisplayRole); + QStringList rowData = data.value(); + contentItem->setTitle(rowData[0]); + contentItem->setSubtitle(rowData[1]); + } + }; + \endcode + + And finally it can be combined in a list: + + \code + DuiList * list = new DuiList(panel); + DuiContentItemCreator * cellCreator = new DuiContentItemCreator; + list->setCellCreator(cellCreator); + TestModel * model = new TestModel; + list->setItemModel(model); + \endcode + + See also DuiListView, DuiWidgetFactory. + */ + +class DUI_EXPORT DuiList : public DuiWidgetController +{ + Q_OBJECT + DUI_CONTROLLER(DuiList) + + /*! + \property DuiList::showGroups set to true to make group headers visible + */ + Q_PROPERTY(bool showGroups READ showGroups WRITE setShowGroups) + + /*! + \property DuiList::columns specifies how many columns the list uses for presenting items + */ + Q_PROPERTY(int columns READ columns WRITE setColumns) + + /*! + \property DuiList::selectionMode specifies how selection should work in DuiList + */ + Q_PROPERTY(SelectionMode selectionMode READ selectionMode WRITE setSelectionMode) + + friend class Ut_DuiList; + friend class Pt_DuiList; + +public: + /*! + This enumerated type is used by DuiList to indicate how it reacts to selection by the user. + */ + enum SelectionMode { + /*! + Items cannot be selected. + */ + NoSelection, + /*! + When the user selects an item, any already-selected item becomes unselected. + */ + SingleSelection, + /*! + When the user selects an item in the usual way, the selection status of that item is toggled and the other items are left alone. + */ + MultiSelection + }; + + enum ScrollHint { + /*! + Scroll to ensure that the item is visible. + */ + EnsureVisibleHint, + /*! + Scroll to position the item at the top of the viewport. + */ + PositionAtTopHint, + /*! + Scroll to position the item at the bottom of the viewport. + */ + PositionAtBottomHint, + /*! + Scroll to position the item at the center of the viewport. + */ + PositionAtCenterHint + }; + + /*! + * \brief Constructor for creating an empty object. + * \param parent Parent object. + */ + DuiList(QGraphicsItem *parent = 0); + + /*! + * \brief Destructor. + */ + virtual ~DuiList(); + + /*! + \brief Sets object to fetch displayed items from. Similar to 'setModel' method in QListView. + */ + void setItemModel(QAbstractItemModel *itemModel); + + /*! + Returns model, associated with the DuiList. + */ + QAbstractItemModel *itemModel() const; + + /*! + Set's cell creator which will map data from model to widgets which will be displayed by DuiList. + + \sa DuiCellCreator + */ + void setCellCreator(DuiCellCreator *cellCreator); + + /*! + Returns cell creator associated with DuiList + */ + const DuiCellCreator *cellCreator() const; + + /*! + \brief Sets the amount of columns to be used for presenting list items. Set to 1 by default. + */ + void setColumns(int columns); + int columns() const; + + /*! + \brief Returns the current selection model + */ + QItemSelectionModel *selectionModel() const; + + /*! + \brief Sets selection model. + */ + void setSelectionModel(QItemSelectionModel *selectionModel); + + /*! + \brief Sets selection mode. By default NoSelection is set. + Check SelectionMode enumeration for details. + */ + void setSelectionMode(DuiList::SelectionMode mode); + + /*! + \return selection mode of a list + */ + DuiList::SelectionMode selectionMode() const; + + /*! + \return index of first visible item + */ + const QModelIndex firstVisibleItem() const; + + /*! + \return index of last visible item + */ + const QModelIndex lastVisibleItem() const; + + /*! + \return true if DuiList shows groups, otherwise false + */ + bool showGroups() const; + + /*! + \brief Specifies whether list should show groups or not. + */ + void setShowGroups(bool showGroups); + +public Q_SLOTS: + /*! + \brief Convenience function - Select the given item. + If index is not valid, the current selection is not changed. + */ + void selectItem(const QModelIndex &index); + + /*! + \brief Scrolls list to a specific index. Call to function will ensure + that item with specified index becomes visible. + */ + void scrollTo(const QModelIndex &index); + + /*! + \brief Scrolls list to a specific index with specified hint. + */ + void scrollTo(const QModelIndex &index, ScrollHint hint); + +Q_SIGNALS: + /*! + \brief Emitted when scrollTo(index) is called to tell the view to scroll + to the given item index + */ + void scrollToIndex(const QModelIndex &index); + + /*! + \brief Emitted when the selection model has changed + */ + void selectionModelChanged(QItemSelectionModel *selectionModel); + + /*! + \brief Emitted when an item is clicked + */ + void itemClicked(const QModelIndex &index); + + /*! + \brief Emitted when list is moving, e.g. pannable by user + */ + void panningStarted(); + + /*! + \brief Emitted when list stopped moving + */ + void panningStopped(); + +protected: + DuiList(DuiListPrivate *dd, DuiListModel *model, QGraphicsItem *parent); + + /*! + Notification of model data modifications. + */ + virtual void updateData(const QList& modifications); + +private: + Q_DECLARE_PRIVATE(DuiList) + Q_DISABLE_COPY(DuiList) + friend class DuiListView; +}; + +#endif + diff --git a/src/widgets/duilist_p.h b/src/widgets/duilist_p.h new file mode 100644 index 000000000..aafebd9f8 --- /dev/null +++ b/src/widgets/duilist_p.h @@ -0,0 +1,61 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUILIST_P_H +#define DUILIST_P_H + +#include "private/duiwidgetcontroller_p.h" + +#include +#include +#include +#include +#include +#include +#include + +class DuiPannableViewport; +class DuiWidget; + +#include "duilist.h" + +class DuiListPrivate : protected DuiWidgetControllerPrivate +{ + Q_DECLARE_PUBLIC(DuiList) + + +public: + DuiListPrivate(); + virtual ~DuiListPrivate(); + + void init(); + + DuiList::SelectionMode selectionMode; + +public slots: + /*! + * \brief This slot is called when items are changed in the model. The changed items are those + * from topLeft to bottomRight inclusive. If just one item is changed topLeft == bottomRight. + * Equivalent to the same method in QListView. + */ + //void dataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight); + +}; + +#endif diff --git a/src/widgets/duilistmodel.cpp b/src/widgets/duilistmodel.cpp new file mode 100644 index 000000000..dce5af669 --- /dev/null +++ b/src/widgets/duilistmodel.cpp @@ -0,0 +1,31 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duilistmodel.h" + +void DuiListModel::setScrollToIndex(const QModelIndex &index) +{ + _scrollToIndex() = index; + memberModified(ScrollToIndex); +} + +const QModelIndex &DuiListModel::scrollToIndex() const +{ + return _scrollToIndex(); +} diff --git a/src/widgets/duilistmodel.h b/src/widgets/duilistmodel.h new file mode 100644 index 000000000..f3c0ade4b --- /dev/null +++ b/src/widgets/duilistmodel.h @@ -0,0 +1,52 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUILISTMODEL_H +#define DUILISTMODEL_H + +#include +#include +#include +#include +#include + +#include +#include "duiabstractcellcreator.h" + +class DUI_EXPORT DuiListModel : public DuiWidgetModel +{ + Q_OBJECT + DUI_MODEL_INTERNAL(DuiListModel) + +private: + + DUI_MODEL_PTR_PROPERTY(QAbstractItemModel *, itemModel, ItemModel, true, 0) + DUI_MODEL_PTR_PROPERTY(DuiCellCreator *, cellCreator, CellCreator, true, 0) + DUI_MODEL_PROPERTY(QModelIndex, firstVisibleItem, FirstVisibleItem, true, QModelIndex()) + DUI_MODEL_PROPERTY(QModelIndex, lastVisibleItem, LastVisibleItem, true, QModelIndex()) + DUI_MODEL_PROPERTY(bool, showGroups, ShowGroups, true, false) + DUI_MODEL_PROPERTY(int, columns, Columns, true, 1) + DUI_MODEL_PTR_PROPERTY(QItemSelectionModel *, selectionModel, SelectionModel, true, NULL) + DUI_MODEL_PROPERTY(bool, listIsMoving, ListIsMoving, true, false) + DUI_MODEL_PROPERTY(QModelIndex, scrollToIndex, ScrollToIndex, false, QModelIndex()) + DUI_MODEL_PROPERTY(int, scrollHint, ScrollHint, true, 0) +}; + +#endif + diff --git a/src/widgets/duilistnamespace.h b/src/widgets/duilistnamespace.h new file mode 100644 index 000000000..59bda746d --- /dev/null +++ b/src/widgets/duilistnamespace.h @@ -0,0 +1,75 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUILISTNAMESPACE_H +#define DUILISTNAMESPACE_H + +#include +#include "duiexport.h" + +/*! + \deprecated Since 0.17. There is no replacement for this. Just create your own empty model. + */ +class DuiEmptyModel : public QAbstractItemModel +{ +public: + explicit DuiEmptyModel(QObject *parent = 0) : QAbstractItemModel(parent) {} + QModelIndex index(int, int, const QModelIndex &) const { + return QModelIndex(); + } + QModelIndex parent(const QModelIndex &) const { + return QModelIndex(); + } + int rowCount(const QModelIndex &) const { + return 0; + } + int columnCount(const QModelIndex &) const { + return 0; + } + bool hasChildren(const QModelIndex &) const { + return false; + } + QVariant data(const QModelIndex &, int) const { + return QVariant(); + } +}; + +//! \deprecated Since 0.17. There is no replacement for this. Just create your own empty model. +Q_GLOBAL_STATIC(DuiEmptyModel, duiEmptyModel) + +namespace DuiListNameSpace +{ + //! \deprecated Since 0.17. Not in used. + enum DUIListRoles { + ItemTypeRole = Qt::UserRole + 1, + SubtitleRole + }; + + //! \deprecated Since 0.17. Not in used. + enum ItemType { + GridItem = 0, + Custom + }; +} + +class DuiWidget; +typedef DuiWidget *DuiWidgetPtr; +Q_DECLARE_METATYPE(DuiWidgetPtr) + +#endif diff --git a/src/widgets/duimessagebox.cpp b/src/widgets/duimessagebox.cpp new file mode 100644 index 000000000..68370a987 --- /dev/null +++ b/src/widgets/duimessagebox.cpp @@ -0,0 +1,60 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duimessagebox.h" +#include "duimessagebox_p.h" + +#include "duiwidgetcreator.h" +DUI_REGISTER_WIDGET(DuiMessageBox) + +DuiMessageBoxPrivate::DuiMessageBoxPrivate() +{ +} + +DuiMessageBox::DuiMessageBox(const QString &text, Dui::StandardButtons buttons) + : DuiDialog(new DuiMessageBoxPrivate, buttons, new DuiMessageBoxModel, DuiSceneWindow::MessageBox) +{ + model()->setText(text); + + setCentralWidget(0); + setTitleBarVisible(false); +} + +DuiMessageBox::DuiMessageBox(const QString &title, const QString &text, Dui::StandardButtons buttons) + : DuiDialog(new DuiMessageBoxPrivate, buttons, new DuiMessageBoxModel, DuiSceneWindow::MessageBox) +{ + setTitle(title); + model()->setText(text); + + setCentralWidget(0); +} + +DuiMessageBox::~DuiMessageBox() +{ +} + +QString DuiMessageBox::text() const +{ + return model()->text(); +} + +void DuiMessageBox::setText(const QString &text) +{ + model()->setText(text); +} diff --git a/src/widgets/duimessagebox.h b/src/widgets/duimessagebox.h new file mode 100644 index 000000000..2ac12246a --- /dev/null +++ b/src/widgets/duimessagebox.h @@ -0,0 +1,97 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIMESSAGEBOX_H +#define DUIMESSAGEBOX_H + +#include +#include + +class DuiMessageBoxPrivate; + +/*! + \class DuiMessageBox + \brief DuiMessageBox provides a dialog for informing the user or for asking the user a question. + + A DuiMessageBox is a DuiDialog that displays text in its central area. + + By default a DuiMessageBox has no central widget, but just the message text in its place. + You can still add a central widget to it though, by calling setCentralWidget(). It will + then be placed between the title bar and the message text. + */ +class DUI_EXPORT DuiMessageBox : public DuiDialog +{ + Q_OBJECT + DUI_CONTROLLER(DuiMessageBox) + +public: + /*! + * \brief Constructs a message box with the given \a text and set of standard \a buttons. + * + * By default, the title bar will be hidden. + * + * \param text Text to be displayed in the dialog's central area + * \param standardButtons Standard buttons to be put in the button box. + * \sa DuiDialog::StandardButtons + */ + DuiMessageBox(const QString &text = QString(), Dui::StandardButtons standardButtons = Dui::OkButton); + + /*! + * \brief Constructs a message box with the given \a title, \a text and + * set of standard \a buttons. + * + * \param title Dialog's title, shown in the title bar. + * \param text Text to be displayed in the dialog's central area + * \param buttons Standard buttons to be put in the button box. + * \sa DuiDialog::StandardButtons + */ + DuiMessageBox(const QString &title, const QString &text, + Dui::StandardButtons buttons = Dui::OkButton); + + + /*! + * \brief Returns the dialog's text. + * \return Text being displayed in the dialog's central area. + * \sa setText() + */ + QString text() const; + + /*! + * \brief Sets the dialog's text. + * + * \param text Text to be displayed in the dialog's central area. + * \sa text() + */ + void setText(const QString &text); + + /*! + * \brief Destructor + */ + virtual ~DuiMessageBox(); + +private: + Q_DECLARE_PRIVATE(DuiMessageBox) + Q_DISABLE_COPY(DuiMessageBox) + + friend class DuiMessageBoxView; + friend class DuiMessageBoxViewPrivate; +}; + +#endif + diff --git a/src/widgets/duimessagebox_p.h b/src/widgets/duimessagebox_p.h new file mode 100644 index 000000000..dfc3f6819 --- /dev/null +++ b/src/widgets/duimessagebox_p.h @@ -0,0 +1,33 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIMESSAGEBOX_P_H +#define DUIMESSAGEBOX_P_H + +#include "duimessagebox.h" +#include "duidialog_p.h" + +class DuiMessageBoxPrivate : public DuiDialogPrivate +{ + Q_DECLARE_PUBLIC(DuiMessageBox) +public: + DuiMessageBoxPrivate(); +}; + +#endif diff --git a/src/widgets/duimessageboxmodel.h b/src/widgets/duimessageboxmodel.h new file mode 100644 index 000000000..73af917ac --- /dev/null +++ b/src/widgets/duimessageboxmodel.h @@ -0,0 +1,39 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIMESSAGEBOXMODEL_H +#define DUIMESSAGEBOXMODEL_H + +#include + +#include + +class DUI_EXPORT DuiMessageBoxModel : public DuiDialogModel +{ + Q_OBJECT + DUI_MODEL_INTERNAL(DuiMessageBoxModel) +public: + +private: + + DUI_MODEL_PROPERTY(QString, text, Text, true, QString()) +}; + +#endif + diff --git a/src/widgets/duimodalscenewindow.cpp b/src/widgets/duimodalscenewindow.cpp new file mode 100644 index 000000000..4b9c507bf --- /dev/null +++ b/src/widgets/duimodalscenewindow.cpp @@ -0,0 +1,58 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duimodalscenewindow.h" +#include "duimodalscenewindow_p.h" + +#include "duiwidgetcreator.h" +DUI_REGISTER_WIDGET(DuiModalSceneWindow) + +DuiModalSceneWindowPrivate::DuiModalSceneWindowPrivate() +{ +} + +DuiModalSceneWindowPrivate::~DuiModalSceneWindowPrivate() +{ +} + +void DuiModalSceneWindowPrivate::init() +{ +} + +DuiModalSceneWindow::DuiModalSceneWindow() : + DuiSceneWindow(new DuiModalSceneWindowPrivate(), new DuiModalSceneWindowModel(), DuiSceneWindow::ModalSceneWindow, QString()) +{ + Q_D(DuiModalSceneWindow); + + d->init(); +} + +DuiModalSceneWindow::DuiModalSceneWindow(DuiModalSceneWindowPrivate *dd, DuiModalSceneWindowModel *model, DuiSceneWindow::WindowType windowType) : + DuiSceneWindow(dd, model, windowType, QString()) +{ + Q_D(DuiModalSceneWindow); + + d->init(); +} + +DuiModalSceneWindow::~DuiModalSceneWindow() +{ +} + +#include "moc_duimodalscenewindow.cpp" diff --git a/src/widgets/duimodalscenewindow.h b/src/widgets/duimodalscenewindow.h new file mode 100644 index 000000000..9f283a362 --- /dev/null +++ b/src/widgets/duimodalscenewindow.h @@ -0,0 +1,72 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIMODALSCENEWINDOW_H +#define DUIMODALSCENEWINDOW_H + +#include "duiscenewindow.h" +#include "duimodalscenewindowmodel.h" + +class DuiModalSceneWindowPrivate; + +/*! + * \class DuiModalSceneWindow + * \brief The DuiModalSceneWindow class provides an empty scene window + * with modality and layer effect + * + * A modalscenewindow is a top-level scene window which can be used to + * create custom, modal scene windows. It has modality and a layer + * effect which visually blocks the scene windows with lower z + * value. It shares the z value with dialogs. + * + * A typical way of using modalscenewindow is to style its size, + * alignment and offset, instantiate it, set a layout to it and + * populate the layout with any components the use case requires. + */ +class DUI_EXPORT DuiModalSceneWindow : public DuiSceneWindow +{ + Q_OBJECT + DUI_CONTROLLER(DuiModalSceneWindow) + +public: + + /*! + * \brief Constructs a modalscenewindow. + */ + DuiModalSceneWindow(); + +protected: + DuiModalSceneWindow(DuiModalSceneWindowPrivate *dd, DuiModalSceneWindowModel *model, DuiSceneWindow::WindowType windowType); + +public: + + /*! + * \brief Destructor for modalscenewindow class + */ + virtual ~DuiModalSceneWindow(); + +private: + Q_DECLARE_PRIVATE(DuiModalSceneWindow) + Q_DISABLE_COPY(DuiModalSceneWindow) + + friend class DuiModalSceneWindowView; + friend class DuiModalSceneWindowViewPrivate; +}; + +#endif diff --git a/src/widgets/duimodalscenewindow_p.h b/src/widgets/duimodalscenewindow_p.h new file mode 100644 index 000000000..6778688d2 --- /dev/null +++ b/src/widgets/duimodalscenewindow_p.h @@ -0,0 +1,37 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIMODALSCENEWINDOW_P_H +#define DUIMODALSCENEWINDOW_P_H + +#include "duiscenewindow_p.h" +#include "duimodalscenewindow.h" + +class DuiModalSceneWindowPrivate : public DuiSceneWindowPrivate +{ + Q_DECLARE_PUBLIC(DuiModalSceneWindow) + +public: + + DuiModalSceneWindowPrivate(); + ~DuiModalSceneWindowPrivate(); + void init(); +}; + +#endif diff --git a/src/widgets/duimodalscenewindowmodel.h b/src/widgets/duimodalscenewindowmodel.h new file mode 100644 index 000000000..8a858fa37 --- /dev/null +++ b/src/widgets/duimodalscenewindowmodel.h @@ -0,0 +1,32 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIMODALSCENEWINDOWMODEL_H +#define DUIMODALSCENEWINDOWMODEL_H + +#include "duiscenewindowmodel.h" + +class DUI_EXPORT DuiModalSceneWindowModel : public DuiSceneWindowModel +{ + Q_OBJECT + DUI_MODEL_INTERNAL(DuiModalSceneWindowModel) +}; + +#endif + diff --git a/src/widgets/duinavigationbar.cpp b/src/widgets/duinavigationbar.cpp new file mode 100644 index 000000000..5e1814251 --- /dev/null +++ b/src/widgets/duinavigationbar.cpp @@ -0,0 +1,116 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include "duinavigationbar.h" +#include "duinavigationbar_p.h" + +#include "duinavigationbarmodel.h" + +#include "duiwidgetcreator.h" +DUI_REGISTER_WIDGET(DuiNavigationBar) + + +/* + * constructor of private class + */ +DuiNavigationBarPrivate::DuiNavigationBarPrivate() + : homeButtonPanel(0) +{ +} + +/* + * destructor of private class + */ +DuiNavigationBarPrivate::~DuiNavigationBarPrivate() +{ +} + +/* + * general initialization function + */ +void DuiNavigationBarPrivate::init() +{ +} + +/* + * constructor of public class + */ +DuiNavigationBar::DuiNavigationBar() + : DuiSceneWindow(new DuiNavigationBarPrivate, new DuiNavigationBarModel, DuiSceneWindow::NavigationBar) +{ + Q_D(DuiNavigationBar); + d->init(); +} + +DuiNavigationBar::~DuiNavigationBar() +{ +} + +QString DuiNavigationBar::viewMenuIconID() const +{ + return model()->viewMenuIconID(); +} + +bool DuiNavigationBar::isProgressIndicatorVisible() const +{ + return model()->progressIndicatorVisible(); +} + +bool DuiNavigationBar::isArrowIconVisible() const +{ + return model()->arrowIconVisible(); +} + +void DuiNavigationBar::setViewMenuIconID(const QString &id) +{ + model()->setViewMenuIconID(id); +} + +void DuiNavigationBar::setProgressIndicatorVisible(bool visible) +{ + model()->setProgressIndicatorVisible(visible); +} + +void DuiNavigationBar::setArrowIconVisible(bool visible) +{ + model()->setArrowIconVisible(visible); +} + +void DuiNavigationBar::notifyUser() +{ + model()->setNotifyUser(true); +} + +void DuiNavigationBar::setViewMenuDescription(const QString &text) +{ + model()->setViewMenuDescription(text); +} + +void DuiNavigationBar::dockToolBar(DuiToolBar *toolbar) +{ + model()->setToolBar(toolbar); +} + +void DuiNavigationBar::undockToolBar() +{ + dockToolBar(NULL); +} + +#include "moc_duinavigationbar.cpp" diff --git a/src/widgets/duinavigationbar.h b/src/widgets/duinavigationbar.h new file mode 100644 index 000000000..67b8e1e67 --- /dev/null +++ b/src/widgets/duinavigationbar.h @@ -0,0 +1,118 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUINAVIGATIONBAR_H +#define DUINAVIGATIONBAR_H + +#include +#include + +class DuiNavigationBarPrivate; +class DuiToolBar; + +/*! + * \class DuiNavigationBar + * \brief DuiNavigationBar implements a navigation bar with viewmenu + * + * DuiNavigationBar doesn't have that many parameters which are read from + * theme. The theming is done changing the items which lay inside the + * navigation bar. + */ + +class DUI_EXPORT DuiNavigationBar : public DuiSceneWindow +{ + Q_OBJECT + DUI_CONTROLLER(DuiNavigationBar) + +#ifdef UNIT_TEST + friend class Ut_DuiNavigationBar; +#endif // UNIT_TEST + +public: + /*! + * \brief Default constructor. Creates a navigation bar. + */ + DuiNavigationBar(); + + /*! + \brief Destroys the navigation bar. + */ + virtual ~DuiNavigationBar(); + + /** + * Returns the iconID of the icon of the view menu button. + */ + QString viewMenuIconID() const; + + /** + * Returns if the progress indicator is visible + */ + bool isProgressIndicatorVisible() const; + + /*! + \brief Returns true if the arrow icon is visible. + */ + bool isArrowIconVisible() const; + +public Q_SLOTS: + /** \brief Trigger notification of the user via the navigation bar. + * + * This slot asks the NavigationBarView to notify the user, e.g. + * by flashing the Home button. + */ + void notifyUser(); + + /** \brief Dock a toolbar. + * \param toolbar The toolbar to dock. + */ + void dockToolBar(DuiToolBar *toolbar); + + /** \brief Undock a toolbar. + */ + void undockToolBar(); + + void setViewMenuDescription(const QString &text); + + /** + * Sets the new icon of the view menu button. + * \param the id of the icon that should be shown. + */ + void setViewMenuIconID(const QString &id); + + /** + * Sets the visible of progress indicator + * \param bool visible + */ + void setProgressIndicatorVisible(bool visible); + + /** + * Sets the visible of progress indicator + */ + void setArrowIconVisible(bool visible); + +Q_SIGNALS: + //! \brief viewmenuButton was clicked + void viewmenuTriggered(); + +private: + Q_DISABLE_COPY(DuiNavigationBar) + Q_DECLARE_PRIVATE(DuiNavigationBar) +}; + +#endif diff --git a/src/widgets/duinavigationbar_p.h b/src/widgets/duinavigationbar_p.h new file mode 100644 index 000000000..9f44e5fed --- /dev/null +++ b/src/widgets/duinavigationbar_p.h @@ -0,0 +1,51 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUINAVIGATIONBAR_P_H +#define DUINAVIGATIONBAR_P_H + +#include + +#include "duinavigationbar.h" +#include "duihomebuttonpanel.h" + +#include + +class QGraphicsLinearLayout; +class QGraphicsGridLayout; +class DuiButton; +class QGraphicsWidget; +class DuiStyle; +class QGraphicsItemAnimation; +class QTimeLine; + +class DuiNavigationBarPrivate : public DuiSceneWindowPrivate +{ + Q_DECLARE_PUBLIC(DuiNavigationBar) + +public: + DuiNavigationBarPrivate(); + virtual ~DuiNavigationBarPrivate(); + + void init(); + + QPointer homeButtonPanel; +}; + +#endif diff --git a/src/widgets/duinavigationbarmodel.h b/src/widgets/duinavigationbarmodel.h new file mode 100644 index 000000000..81077e244 --- /dev/null +++ b/src/widgets/duinavigationbarmodel.h @@ -0,0 +1,40 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUINAVIGATIONBARMODEL_H +#define DUINAVIGATIONBARMODEL_H + +#include + +class DuiToolBar; + +class DUI_EXPORT DuiNavigationBarModel : public DuiSceneWindowModel +{ + Q_OBJECT + DUI_MODEL_INTERNAL(DuiNavigationBarModel) + + DUI_MODEL_PROPERTY(bool, notifyUser, NotifyUser, true, false) + DUI_MODEL_PROPERTY(QString, viewMenuDescription, ViewMenuDescription, true, "Menu") + DUI_MODEL_PROPERTY(QString, viewMenuIconID, ViewMenuIconID, true, QString()) + DUI_MODEL_PROPERTY(bool, progressIndicatorVisible, ProgressIndicatorVisible, true, false) + DUI_MODEL_PROPERTY(bool, arrowIconVisible, ArrowIconVisible, true, false) + DUI_MODEL_PTR_PROPERTY(DuiToolBar *, toolBar, ToolBar, true, 0) +}; + +#endif diff --git a/src/widgets/duiobjectmenu.cpp b/src/widgets/duiobjectmenu.cpp new file mode 100644 index 000000000..f073224ce --- /dev/null +++ b/src/widgets/duiobjectmenu.cpp @@ -0,0 +1,92 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include + +#include "duiobjectmenu.h" +#include "duiscenewindow_p.h" +#include "duiaction.h" +#include "duiscenemanager.h" + +#include "duiwidgetcreator.h" +DUI_REGISTER_WIDGET_NO_CREATE(DuiObjectMenu) + +DuiObjectMenu::DuiObjectMenu(DuiWidget *target) + : DuiSceneWindow(new DuiSceneWindowPrivate, new DuiObjectMenuModel, DuiSceneWindow::ObjectMenu) +{ + QList actionList = target->actions(); + DuiActionList list; + + // go trough all actions in the target widget and add the the actions + // which are associated to object menu to model. + const int actionListCount = actionList.count(); + for (int i = 0; i < actionListCount; ++i) { + DuiAction *action = qobject_cast(actionList.at(i)); + if (action && (action->location() & DuiAction::ObjectMenuLocation)) { + list.append(action); + } + } + + model()->setActions(list); + + // install event filter to the target widget, so we get notified + // when actions are added,removed or changed. + target->installEventFilter(this); +} + +DuiObjectMenu::~DuiObjectMenu() +{ +} + +bool DuiObjectMenu::eventFilter(QObject *obj, QEvent *event) +{ + Q_UNUSED(obj); + DuiAction *action = NULL; + + // if the event was related to object menu actions, we'll modify the model accordingly. + switch (event->type()) { + case QEvent::ActionAdded: + if ((action = qobject_cast(((QActionEvent *)event)->action()))) { + if (action->location() & DuiAction::ObjectMenuLocation) + model()->addAction(action); + } + break; + case QEvent::ActionChanged: + if ((action = qobject_cast(((QActionEvent *)event)->action()))) { + if (action->location() & DuiAction::ObjectMenuLocation) + model()->modifyAction(action); + } + break; + case QEvent::ActionRemoved: + if ((action = qobject_cast(((QActionEvent *)event)->action()))) { + if (action->location() & DuiAction::ObjectMenuLocation) + model()->removeAction(action); + } + break; + default: + break; + } + return false; +} + +void DuiObjectMenu::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) +{ + event->accept(); +} diff --git a/src/widgets/duiobjectmenu.h b/src/widgets/duiobjectmenu.h new file mode 100644 index 000000000..871c524dd --- /dev/null +++ b/src/widgets/duiobjectmenu.h @@ -0,0 +1,146 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIOBJECTMENU_H +#define DUIOBJECTMENU_H + +#include +#include + +class QGraphicsSceneContextMenuEvent; + +//! \internal + +/*! + \class DuiObjectMenu + \brief DuiObjectMenu is a context-menu like widget, which shows object menu actions from any widget. + + \ingroup widgets + + This class is used by DuiWidget and will be launched automatically if the + widget gets a context menu event and the widget has some object menu + actions associated to it. To add context menu actions to a widget see the + code snippet below. + \code + // Create an action with title "Edit" and parent it to widget + // so the action is freed when the widget gets destroyed. + DuiAction* action = new DuiAction("Edit", widget); + + // Associate this action to object menu. + action->setLocation(DuiAction::ObjectMenu); + + // And add the action to the widget. + widget->addAction(action); + \endcode + + This class can also be used manually, but normally it's enough to just add + actions to a widget and let the system handle the menu. + + \section DuiObjectMenuOverview Overview + Object Menu is a popup menu of commands attached to an element that + contains functions related to it. It can be seen to be quite close to + the idea of a context-sensitive menu ("right click menu"). + + Object menu is opened by long tapping the element. There is a visual + transition for opening the menu, starting after a certain time period. + When the menu is activated, the background is dimmed (including Home + and Back buttons). + + \section DuiObjectMenuUsageGuidlines Usage guidlines + \li Object menu is a good place for shortcuts: for things that would + take several clicks and actions to otherwise access from the view + the user launched the menu from. If an action would take two short + clicks in the views vs. a long click to open the menu and a click + in the menu, it doesn't really save time and effort from the users + anymore. + + \li Object menu promotes certain device features. If you need to make a + choice between several features, choose features that are to be + promoted for the users. + + \li Object menu must not be the only place to find a function. Not all + users will find the object menu. + + \li Although the object menu is scalable, aim to keep the amount of + commands low (max 6-8) so that panning would not be required. New + software plug-ins can add functionality to the object menu. + + \li The object menu should not duplicate the primary action (which can + be accessed by short tapping the element). + + \li For content items, it is mandatory to include "See related" and + "Mark as favorite" in the Object Menu. "Delete" and "Details" are + also highly recommended. + + \li Since object menu is a hidden feature, aim to have consistency in + the menus: aim to have similar functions always for a similar + content item. The users should have a pretty good guess of whether + a certain action is in the object menu before they open the menu. + + \li If there is a well known icon for a given function (like search or + asso-browsing), show the icon also in the object menu for the given + function. + + \li Be careful in placing commands that are not clear to the users: A + function like "Call" is very vague: Which number does it call to? + Which service it will use to make the call? + + \li Selecting commands from the object menu by default should launch + the item in a subview of the current view, not as a new task. + (Exceptions can be made in certain cases.) + + \section DuiObjectMenuVariants Variants + \li \link DuiObjectMenuView Generic view \endlink + + \section DuiObjectMenuWidgetOpenIssues Open issues + + + \sa DuiObjectMenuModel DuiObjectMenuStyle + */ + +class DuiObjectMenu : public DuiSceneWindow +{ + Q_OBJECT + Q_DISABLE_COPY(DuiObjectMenu) + DUI_CONTROLLER(DuiObjectMenu) + +public: + /*! + \brief Constructs an object menu. + + Object menu is always associated to exactly one widget. The menu shows + automatically all object menu actions from the \a target widget. + */ + explicit DuiObjectMenu(DuiWidget *target); + + /*! + \brief Destructs an object menu. + */ + virtual ~DuiObjectMenu(); + +protected: + //! \reimp + virtual bool eventFilter(QObject *obj, QEvent *event); + virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent *event); + //! \reimp_end + +}; +//! \internal_end + +#endif diff --git a/src/widgets/duiobjectmenumodel.cpp b/src/widgets/duiobjectmenumodel.cpp new file mode 100644 index 000000000..e24254c74 --- /dev/null +++ b/src/widgets/duiobjectmenumodel.cpp @@ -0,0 +1,37 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiobjectmenumodel.h" + +void DuiObjectMenuModel::addAction(DuiAction *action) +{ + _actions().append(action); + emit actionAdded(action); +} + +void DuiObjectMenuModel::removeAction(DuiAction *action) +{ + _actions().removeOne(action); + emit actionRemoved(action); +} + +void DuiObjectMenuModel::modifyAction(DuiAction *action) +{ + emit actionModified(action); +} diff --git a/src/widgets/duiobjectmenumodel.h b/src/widgets/duiobjectmenumodel.h new file mode 100644 index 000000000..f71879c6e --- /dev/null +++ b/src/widgets/duiobjectmenumodel.h @@ -0,0 +1,94 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIOBJECTMENUMODEL_H +#define DUIOBJECTMENUMODEL_H + +#include + +class DuiAction; + +typedef QList DuiActionList; + +/*! + \class DuiObjectMenuModel + \brief DuiObjectMenuModel contains a number of object menu actions related to one widget. + + \ingroup models + + \sa DuiObjectMenu +*/ +class DUI_EXPORT DuiObjectMenuModel : public DuiSceneWindowModel +{ + Q_OBJECT + DUI_MODEL_INTERNAL(DuiObjectMenuModel) + + /*! + \property DuiObjectMenuModel::actions + \brief A list of object menu actions. + + This property contains all object menu actions. + This list is modified by DuiObjectMenu via addAction(), removeAction() and modifyAction() and is always up to date. + */ + DUI_MODEL_PROPERTY(DuiActionList, actions, Actions, true, DuiActionList()) + +public: + /*! + \brief Adds the \a action to the actions list. + + This method should be used instead of modifying the actions list directly. + When the action has been added, this method will emit a actionAdded() signal. + */ + void addAction(DuiAction *action); + + /*! + \brief Removes the \a action from the actions list. + + This method should be used instead of modifying the actions list directly. + When the action has been removed, this method will emit a actionRemoved() signal. + */ + void removeAction(DuiAction *action); + + /*! + \brief Emits a actionModified() signal. + + When modifying an action, this method should be used to inform all participants of the modification. + This method will emit a actionModified() signal. + */ + void modifyAction(DuiAction *action); + +Q_SIGNALS: + /*! + \brief This signal is emitted when an action has been added to actions list. + */ + void actionAdded(DuiAction *action); + + /*! + \brief This signal is emitted when an action has been removed from actions list. + */ + void actionRemoved(DuiAction *action); + + /*! + \brief This signal is emitted when an action has been modified in actions list. + */ + void actionModified(DuiAction *action); +}; + +#endif + diff --git a/src/widgets/duioverlay.cpp b/src/widgets/duioverlay.cpp new file mode 100644 index 000000000..a072e60a6 --- /dev/null +++ b/src/widgets/duioverlay.cpp @@ -0,0 +1,85 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include "duiscenewindowmodel.h" +#include "duioverlay.h" +#include "duioverlay_p.h" + +#include "duiwidgetcreator.h" +DUI_REGISTER_WIDGET(DuiOverlay) + +void DuiOverlayPrivate::init() +{ + Q_Q(DuiOverlay); + + mainLayout = new QGraphicsLinearLayout(Qt::Horizontal); + mainLayout->setContentsMargins(0, 0, 0, 0); + mainLayout->setSpacing(0); + + widget = new DuiWidget; + + mainLayout->addItem(widget); + q->setLayout(mainLayout); +} + +void DuiOverlayPrivate::deleteWidget() +{ + if (widget) { + mainLayout->removeItem(widget); + widget->deleteLater(); + widget = 0; + } +} + +void DuiOverlayPrivate::placeWidget(DuiWidget *widget) +{ + if (widget) { + mainLayout->addItem(widget); + this->widget = widget; + } +} + +DuiOverlay::DuiOverlay(QGraphicsItem *parent) : + DuiSceneWindow(new DuiOverlayPrivate, new DuiSceneWindowModel, DuiSceneWindow::Overlay, "overlay", parent) +{ + Q_D(DuiOverlay); + + d->init(); +} + +DuiOverlay::~DuiOverlay() +{ +} + +DuiWidget *DuiOverlay::widget() const +{ + Q_D(const DuiOverlay); + + return d->widget; +} + +void DuiOverlay::setWidget(DuiWidget *widget) +{ + Q_D(DuiOverlay); + + d->deleteWidget(); + d->placeWidget(widget); +} diff --git a/src/widgets/duioverlay.h b/src/widgets/duioverlay.h new file mode 100644 index 000000000..f18e3ac93 --- /dev/null +++ b/src/widgets/duioverlay.h @@ -0,0 +1,82 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIOVERLAY_H +#define DUIOVERLAY_H + +#include "duiscenewindow.h" +#include "duiscenewindowmodel.h" + +class DuiOverlayPrivate; + +/*! + * \class DuiOverlay + * \brief The DuiOverlay class displays a widget on top of the viewport. + * + * DuiOverlay class enables creation and displaying of a widget on top of the + * current viewport. It provides a widget which is ready for use out of the box. + * It follows the idea used for DuiApplication's centralWidget(), i.e. it can be + * used as a panel (can have a layout applied and filled with other widgets) or + * simply substituted with another widget. The widget can be positioned inside + * the scene using alignment and offset defined in stylesheet. + * + * \sa DuiApplicationPage + */ +class DUI_EXPORT DuiOverlay : public DuiSceneWindow +{ + Q_OBJECT + DUI_CONTROLLER(DuiSceneWindow) + +public: + + /*! + * \brief Constructs a widget with the given \a parent. + */ + DuiOverlay(QGraphicsItem *parent = 0); + + /*! + * \brief Destructor. + */ + virtual ~DuiOverlay(); + + /*! + * \brief Returns a pointer to the topmost widget. By default this class + * provides a widget (panel) on which other widgets can be placed. + */ + DuiWidget *widget() const; + + /*! + * \brief Sets the given \a widget as a topmost widget. The ownership + * of the \a widget is passed to the DuiOverlay instance. + * \param widget A widget to be set as topmost. + */ + void setWidget(DuiWidget *widget); + +private: + + Q_DECLARE_PRIVATE(DuiOverlay) + Q_DISABLE_COPY(DuiOverlay) + + friend class DuiOverlayView; +#ifdef UNIT_TEST + friend class Ut_DuiOverlay; +#endif +}; + +#endif diff --git a/src/widgets/duioverlay_p.h b/src/widgets/duioverlay_p.h new file mode 100644 index 000000000..f4eb37ed8 --- /dev/null +++ b/src/widgets/duioverlay_p.h @@ -0,0 +1,43 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIOVERLAY_P_H +#define DUIOVERLAY_P_H + +#include +#include "duioverlay.h" + +class DuiWidget; +class QGraphicsLinearLayout; + +class DuiOverlayPrivate : public DuiSceneWindowPrivate +{ + Q_DECLARE_PUBLIC(DuiOverlay) + +public: + void init(); + + void deleteWidget(); + void placeWidget(DuiWidget *widget); + + DuiWidget *widget; + QGraphicsLinearLayout *mainLayout; +}; + +#endif diff --git a/src/widgets/duipannableviewport.cpp b/src/widgets/duipannableviewport.cpp new file mode 100644 index 000000000..70d0f4c8b --- /dev/null +++ b/src/widgets/duipannableviewport.cpp @@ -0,0 +1,340 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include +#include + +#include "duipositionindicator.h" +#include "duipannableviewport.h" +#include "duipannableviewport_p.h" +#include "duipannableviewportlayout.h" +#include +#include + +#include "duiwidgetcreator.h" +DUI_REGISTER_WIDGET(DuiPannableViewport) + +namespace +{ + //! Z-value of the panned widget + const int ZValuePannedWidget = 0; + //! Z-value of the position indicator + const int ZValuePosInd = 1; +} + +DuiPannableViewportPrivate::DuiPannableViewportPrivate() + : DuiPannableWidgetPrivate(), + currentRange(QRectF()), + pannedWidget(0), + viewportLayout(0), + positionIndicator(0), + haveEmittedSizePosChanged(false) +{ +} + +DuiPannableViewportPrivate::~DuiPannableViewportPrivate() +{ +} + +void DuiPannableViewportPrivate::emitSizePosChanged(const QSizeF &viewportSize, + const QRectF &pannedRange, + const QPointF &pannedPos) +{ + Q_Q(DuiPannableViewport); + + if (!haveEmittedSizePosChanged || + (lastEmittedViewportSize != viewportSize || + lastEmittedPannedRange != pannedRange || + lastEmittedPannedPos != pannedPos)) { + + lastEmittedViewportSize = viewportSize; + lastEmittedPannedRange = pannedRange; + lastEmittedPannedPos = pannedPos; + + haveEmittedSizePosChanged = true; + + emit(q->sizePosChanged(viewportSize, pannedRange, pannedPos)); + } +} + +void DuiPannableViewportPrivate::recalculatePhysRange() +{ + Q_Q(DuiPannableViewport); + + // Recalculates the range of the physics. Takes into consideration + // the current size of the viewport and the current range + + QSizeF physicsRangeSize = currentRange.size() - q->size(); + + if (physicsRangeSize.width() < 0.0) { + physicsRangeSize.setWidth(0.0); + } + + if (physicsRangeSize.height() < 0.0) { + physicsRangeSize.setHeight(0.0); + } + + q->physics()->setRange(QRectF(currentRange.topLeft(), physicsRangeSize)); + + emitSizePosChanged(q->size(), currentRange, q->position()); +} + +void DuiPannableViewportPrivate::sendOnDisplayChangeEventToDuiWidgets(QGraphicsItem *item, + DuiOnDisplayChangeEvent *event) +{ + Q_Q(DuiPannableViewport); + bool isDuiWidget = false; + + if (item->isWidget()) { + DuiWidget *duiWidget = qobject_cast(static_cast(item)); + + if (duiWidget) { + isDuiWidget = true; + + // Let that DuiWidget handle the propagation from now on. + q->scene()->sendEvent(duiWidget, event); + } + } + + if (!isDuiWidget) { + // That guy won't send the word forward. So we have to do it for him. + QList childItemsList = item->childItems(); + int childItemsCount = childItemsList.count(); + + for (int i = 0; i < childItemsCount; i++) { + sendOnDisplayChangeEventToDuiWidgets(childItemsList.at(i), event); + } + } +} + +void DuiPannableViewportPrivate::_q_resolvePannedWidgetIsOnDisplay() +{ + Q_Q(DuiPannableViewport); + DuiOnDisplayChangeEvent *event = 0; + + if (q->isOnDisplay() && q->sceneManager() != 0) { + QRectF visibleSceneRect(QPoint(0, 0), q->sceneManager()->visibleSceneSize()); + event = new DuiOnDisplayChangeEvent(DuiOnDisplayChangeEvent::MustBeResolved, visibleSceneRect); + + // If I just do a send(q->widget(), event) and widget() happens not to be a DuiWidget + // (e.g., plain QGraphicsWidget layouting DuiWidgets inside) the event propagation + // just won't happen. + sendOnDisplayChangeEventToDuiWidgets(q->widget(), event); + } +} + +DuiPannableViewport::DuiPannableViewport(QGraphicsItem *parent) + : DuiPannableWidget(new DuiPannableViewportPrivate(), new DuiPannableViewportModel, parent) +{ + Q_D(DuiPannableViewport); + setFlags(QGraphicsItem::ItemClipsChildrenToShape); + + setPosition(QPointF()); + setRange(QRectF()); + + d->positionIndicator = new DuiPositionIndicator(this); + d->positionIndicator->setZValue(ZValuePosInd); + connect(this, + SIGNAL(sizePosChanged(QSizeF, QRectF, QPointF)), + d->positionIndicator, + SLOT(updateSizePosData(QSizeF, QRectF, QPointF))); + + d->viewportLayout = new DuiPannableViewportLayout; + d->viewportLayout->setPanningDirections(panDirection()); + d->viewportLayout->setContentsMargins(0, 0, 0, 0); + setLayout(d->viewportLayout); + + connect(this, + SIGNAL(panningStopped()), + SLOT(_q_resolvePannedWidgetIsOnDisplay())); +} + +DuiPannableViewport::~DuiPannableViewport() +{ + QGraphicsWidget *oldwidget = widget(); + setWidget(0); + if (oldwidget) { + delete oldwidget; + oldwidget = 0; + } +} + +void DuiPannableViewport::setAutoRange(bool enable) +{ + Q_D(DuiPannableViewport); + + model()->setAutoRange(enable); + + if (enable) { + if (d->pannedWidget) { + d->currentRange = QRectF(QPointF(), d->pannedWidget->size()); + } else { + d->currentRange = QRectF(); + } + + // Recalculates the physics range when automatic range is taken + // into use + d->recalculatePhysRange(); + } +} + +bool DuiPannableViewport::autoRange() const +{ + return model()->autoRange(); +} + +void DuiPannableViewport::setClipping(bool enabled) +{ + model()->setClipWidget(enabled); + + if (enabled) { + setFlags(QGraphicsItem::ItemClipsChildrenToShape); + } else { + setFlags(0); + } +} + +bool DuiPannableViewport::hasClipping() const +{ + return model()->clipWidget(); +} + +void DuiPannableViewport::setWidget(QGraphicsWidget *widget) +{ + Q_D(DuiPannableViewport); + + d->pannedWidget = widget; + d->viewportLayout->setWidget(widget); + + if (widget) { + widget->setPos(-position()); + widget->setZValue(ZValuePannedWidget); + } + + if (autoRange()) { + if (widget) { + d->currentRange = QRectF(QPointF(), widget->size()); + } else { + d->currentRange = QRectF(); + } + } + + // Recalculates the physics range for the new panned widget + d->recalculatePhysRange(); +} + +QGraphicsWidget *DuiPannableViewport::widget() const +{ + Q_D(const DuiPannableViewport); + return d->pannedWidget; +} + +void DuiPannableViewport::setRange(const QRectF &r) +{ + Q_D(DuiPannableViewport); + + if (!autoRange()) { + d->currentRange = r; + + // Recalculates the physics range for new manually set range + d->recalculatePhysRange(); + } +} + +QRectF DuiPannableViewport::range() const +{ + Q_D(const DuiPannableViewport); + + return d->currentRange; +} + +void DuiPannableViewport::resizeEvent(QGraphicsSceneResizeEvent *event) +{ + Q_D(DuiPannableViewport); + Q_UNUSED(event); + + if (autoRange()) { + if (d->pannedWidget) { + d->currentRange = QRectF(QPointF(), d->pannedWidget->size()); + } else { + d->currentRange = QRectF(); + } + } + + // Recalculates the physics range because viewport size has changed + d->recalculatePhysRange(); + + d->positionIndicator->resize(event->newSize()); +} + +void DuiPannableViewport::updatePosition(const QPointF &p) +{ + Q_D(DuiPannableViewport); + + QPointF roundedP = QPointF(floor(p.x()), floor(p.y())); + + // Parameter p is in the local coordinate system of pannedWidget but + // pannedWidget position is in pannable viewport's coordinate system. + // + // Therefore pannedWidget position is set as a negate of physics position (p), + // because the panned widget needs to flow to the opposite direction of the + // panning. + + if (d->pannedWidget) { + d->pannedWidget->setPos(-roundedP); + } + + // position has changed + d->emitSizePosChanged(size(), d->currentRange, roundedP); +} + +void DuiPannableViewport::setPanDirection(const Qt::Orientations &panDirection) +{ + Q_D(DuiPannableViewport); + + DuiPannableWidget::setPanDirection(panDirection); + + if (d->viewportLayout) { + d->viewportLayout->setPanningDirections(panDirection); + } + + updateGeometry(); +} + +void DuiPannableViewport::updateGeometry() +{ + Q_D(DuiPannableViewport); + + if (autoRange()) { + if (d->pannedWidget) { + d->currentRange = QRectF(QPointF(), d->pannedWidget->size()); + } else { + d->currentRange = QRectF(); + } + } + + // Recalculates the physics range because panned widget size has changed + d->recalculatePhysRange(); + + DuiPannableWidget::updateGeometry(); +} + +#include "moc_duipannableviewport.cpp" diff --git a/src/widgets/duipannableviewport.h b/src/widgets/duipannableviewport.h new file mode 100644 index 000000000..7186b4427 --- /dev/null +++ b/src/widgets/duipannableviewport.h @@ -0,0 +1,181 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIPANNABLEVIEWPORT_H +#define DUIPANNABLEVIEWPORT_H + +#include "duipannablewidget.h" +#include + +class QGraphicsWidget; +class DuiPannableViewportPrivate; +class DuiPositionIndicator; + +/*! + * \class DuiPannableViewport + * \brief DuiPannableViewport is a viewport widget which can be used + * to make any widget pannable. + * + * DuiPannableViewport contains a widget (set with setWidget()) and + * displays it inside the viewport. The area is monitored for panning + * gestures and when one is detected, the widget is scrolled in the + * viewport. Other mouse events are forwarded to the panned widget. + * + * sizePosChanged() signal is emitted when the size of the viewport, + * the the panned range or the position of the panning changes. It can + * be used to track the currently visible area of the widget. + * + * Viewport has an autoRange feature which sets the panning range + * based on the preferred size of the panned widget. This can be + * turned off after which the method setRange() can be used to set the + * panning range. + * + * The viewport creates a position indicator widget on top of it which + * shows the panning position. + * + * Example: + * + * \code + * DuiPannableViewport* viewport = new DuiPannableViewport(parent); + * DuiImage* image = new DuiImage("myimage.png"); + * viewport->setWidget(image); + * \endcode + * + * \sa DuiPannableWidget DuiPannableWidgetStyle + * + */ +class DUI_EXPORT DuiPannableViewport : public DuiPannableWidget +{ + Q_OBJECT + DUI_CONTROLLER(DuiPannableViewport) + + //! \brief Enable status of autoRange feature + Q_PROPERTY(bool autoRange READ autoRange WRITE setAutoRange) + //! \brief Current panning range + Q_PROPERTY(QRectF range READ range WRITE setRange) + //! \brief Current panned widget + Q_PROPERTY(QGraphicsWidget *widget READ widget WRITE setWidget) + //! \brief Clipping status of the panned widget + Q_PROPERTY(bool clipping READ hasClipping WRITE setClipping) + +public: + /*! + * \brief Constructs a pannable viewport with a \a parent. + */ + DuiPannableViewport(QGraphicsItem *parent = 0); + + /*! + * \brief Destroys the pannable widget. + */ + virtual ~DuiPannableViewport(); + + /*! + * \brief Sets the state of the autoRange feature. + * + * When AutoRange is set on, the panning range is automatically + * determined based on the size() of the panned widget. + */ + void setAutoRange(bool enable); + + /*! + * \brief Returns the state of the autoRange feature. + */ + bool autoRange() const; + + /*! + * \brief Sets the clipping state of the panned widget. + * + * Normally this needs to be true. It can be set to false if the + * pannable viewport occupies the whole screen in which case the + * clipping of the panned widget to viewport is redundant. + */ + void setClipping(bool enabled); + + /*! + * \brief Returns the clipping state. + */ + bool hasClipping() const; + + /*! + * \brief Sets the \a widget which will be displayed and panned in + * the viewport. + * + * Ownership of the widget is transferred to pannable viewport. + */ + void setWidget(QGraphicsWidget *widget); + + /*! + * \brief Returns the widget which is currently panned. + */ + QGraphicsWidget *widget() const; + + /*! + * \brief If autoRange is disabled, manually sets the range of the + * panning. + * + * This method overrides the method in DuiPannableWidget. Note + * that in DuiPannableViewport the meaning of the range is + * different from DuiPannableWidget (range is not the range of the + * physics (i.e. allowed movement) but it is the range of the area + * that can be panned over). + */ + void setRange(const QRectF &range); + + /*! + * \brief Returns the current panning range. + */ + virtual QRectF range() const; + + //! \reimp + void setPanDirection(const Qt::Orientations &panDirection); + void resizeEvent(QGraphicsSceneResizeEvent *event); + void updateGeometry(); + //! \reimp_end + +Q_SIGNALS: + + /*! + * \brief When viewport size, the panning range or the panning + * position changes, this signal is emitted. + */ + void sizePosChanged(const QSizeF &viewportSize, const QRectF &pannedRange, const QPointF &pannedPos); + +public Q_SLOTS: + + /*! + * \brief Receives the position updates from the physics and moves + * the panned widget based on them. + * + * This slot should only be used by physics engine. + */ + virtual void updatePosition(const QPointF &position); + +private: + Q_DISABLE_COPY(DuiPannableViewport) + Q_DECLARE_PRIVATE(DuiPannableViewport) + Q_PRIVATE_SLOT(d_func(), void _q_resolvePannedWidgetIsOnDisplay()) + +#ifdef UNIT_TEST + // Test unit is defined as a friend of production code to access private members + friend class Ut_DuiPannableViewport; +#endif + +}; + +#endif diff --git a/src/widgets/duipannableviewport_p.h b/src/widgets/duipannableviewport_p.h new file mode 100644 index 000000000..7ab112ffc --- /dev/null +++ b/src/widgets/duipannableviewport_p.h @@ -0,0 +1,65 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIPANNABLEVIEWPORT_P_H +#define DUIPANNABLEVIEWPORT_P_H + +#include "duipannablewidget_p.h" + +class QGraphicsWidget; +class DuiStyle; +class DuiPositionIndicator; +class QGraphicsLinearLayout; +class DuiPannableViewportLayout; + +class DuiPannableViewportPrivate : public DuiPannableWidgetPrivate +{ + Q_DECLARE_PUBLIC(DuiPannableViewport) +public: + DuiPannableViewportPrivate(); + virtual ~DuiPannableViewportPrivate(); + + QRectF currentRange; + QGraphicsWidget *pannedWidget; + DuiPannableViewportLayout *viewportLayout; + DuiPositionIndicator *positionIndicator; + + bool haveEmittedSizePosChanged; + QSizeF lastEmittedViewportSize; + QRectF lastEmittedPannedRange; + QPointF lastEmittedPannedPos; + + void emitSizePosChanged(const QSizeF &viewportSize, + const QRectF &pannedRange, + const QPointF &pannedPos); + + /*! + * \brief Recalculates the range of the base class (i.e. range of + * the physics). + */ + void recalculatePhysRange(); + + void sendOnDisplayChangeEventToDuiWidgets(QGraphicsItem *item, + DuiOnDisplayChangeEvent *event); + void _q_resolvePannedWidgetIsOnDisplay(); + + friend class Ut_DuiPannableViewport; +}; + +#endif diff --git a/src/widgets/duipannableviewportlayout.cpp b/src/widgets/duipannableviewportlayout.cpp new file mode 100644 index 000000000..11c4ff79a --- /dev/null +++ b/src/widgets/duipannableviewportlayout.cpp @@ -0,0 +1,65 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duipannableviewportlayout.h" + +#include + +DuiPannableViewportLayout::DuiPannableViewportLayout(QGraphicsLayoutItem *parent) + : QGraphicsLinearLayout(parent), + pannedWidget(0), + panningDirections(0) +{ +} + +void DuiPannableViewportLayout::setPanningDirections(const Qt::Orientations &newDirections) +{ + panningDirections = newDirections; +} + + +void DuiPannableViewportLayout::setWidget(QGraphicsWidget *widget) +{ + if (pannedWidget) { + removeAt(0); + } + + pannedWidget = widget; + + if (widget) { + addItem(widget); + } +} + +void DuiPannableViewportLayout::setGeometry(const QRectF &rect) +{ + QRectF unboundedRect = rect; + + if (pannedWidget) { + if (panningDirections.testFlag(Qt::Horizontal)) { + unboundedRect.setWidth(pannedWidget->effectiveSizeHint(Qt::PreferredSize).width()); + } + + if (panningDirections.testFlag(Qt::Vertical)) { + unboundedRect.setHeight(pannedWidget->effectiveSizeHint(Qt::PreferredSize).height()); + } + } + + QGraphicsLinearLayout::setGeometry(unboundedRect); +} diff --git a/src/widgets/duipannableviewportlayout.h b/src/widgets/duipannableviewportlayout.h new file mode 100644 index 000000000..82a002c36 --- /dev/null +++ b/src/widgets/duipannableviewportlayout.h @@ -0,0 +1,46 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +// Make doxygen skip this internal class +//! \cond +#ifndef DUIPANNABLEVIEWPORTLAYOUT_H +#define DUIPANNABLEVIEWPORTLAYOUT_H + +#include + +class DuiPannableViewportLayout : public QGraphicsLinearLayout +{ +public: + DuiPannableViewportLayout(QGraphicsLayoutItem *parent = 0); + + void setPanningDirections(const Qt::Orientations &panningDirections); + + void setWidget(QGraphicsWidget *widget); + + //! \reimp + void setGeometry(const QRectF &rect); + //! \reimp_end + +private: + QGraphicsWidget *pannedWidget; + Qt::Orientations panningDirections; +}; + +#endif +//! \endcond diff --git a/src/widgets/duipannableviewportmodel.h b/src/widgets/duipannableviewportmodel.h new file mode 100644 index 000000000..9e2b3f943 --- /dev/null +++ b/src/widgets/duipannableviewportmodel.h @@ -0,0 +1,35 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIPANNABLEVIEWPORTMODEL_H +#define DUIPANNABLEVIEWPORTMODEL_H + +#include + +class DUI_EXPORT DuiPannableViewportModel : public DuiPannableWidgetModel +{ + Q_OBJECT + DUI_MODEL_INTERNAL(DuiPannableViewportModel) + + DUI_MODEL_PROPERTY(bool, autoRange, AutoRange, true, true) + DUI_MODEL_PROPERTY(bool, clipWidget, ClipWidget, true, true) +}; + +#endif + diff --git a/src/widgets/duipannablewidget.cpp b/src/widgets/duipannablewidget.cpp new file mode 100644 index 000000000..3697d4e60 --- /dev/null +++ b/src/widgets/duipannablewidget.cpp @@ -0,0 +1,752 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include + +#include "duipannablewidget.h" +#include "duipannablewidget_p.h" +#include "duitheme.h" +#include "duicancelevent.h" + +#include "duiondisplaychangeevent.h" + +#include "duiwidgetcreator.h" +DUI_REGISTER_WIDGET(DuiPannableWidget) + +namespace +{ + //! Limiter for the resent list + const int ResentListMaxSize = 10; + //! Z-value of the glass + const int ZValueGlass = 2; + //! Hardcoded timeout value for tap&hold gesture; + const int TapAndHoldTimeoutValue = 500; +} + +/* + * DuiPannableWidget handles the event interception by setting up a + * 'glass' widget on top of the pannable widget and its possible + * children. Glass forwards all mouse events to pannable widget which + * interprets them. The press event is just stored first and in case + * the gesture turns out to be not a panning one, the press is resend + * to scene. It is also put to the exclude list and when seen for the + * second time in mouse press handler, it is ignored. For this to + * work, just before the resending the mouse is ungrabbed in the glass + * which enables Qt to forward the event deeper after ignoring. + * After the forwarded press, all events go directly to the possible + * widget under the glass. + * + * If debugging of glass events is needed, it is recommend to override + * sceneEvent since also the mouse grabs and ungrabs are seen on that + * level. + */ + +/** + * Copies QGraphicsSceneMouseEvent data from one instance to another. + * Note that this function copies only data defined in QGraphicsSceneMouseEvent. + * Target event will keep its event type and other properties defined in QGraphicsSceneMouseEvent + * subclasses. + */ +void copyGraphicsSceneMouseEvent(QGraphicsSceneMouseEvent &target, const QGraphicsSceneMouseEvent &source) +{ + target.setPos(source.pos()); + target.setScenePos(source.scenePos()); + target.setScreenPos(source.screenPos()); + + target.setButtons(source.buttons()); + Qt::MouseButtons buttons = source.buttons(); + Qt::MouseButton buttonbit = (Qt::MouseButton)0x1; + while (buttons != 0x0) { + if (buttons & buttonbit) { + // Button pressed + target.setButtonDownPos(buttonbit, source.buttonDownPos(buttonbit)); + target.setButtonDownScenePos(buttonbit, source.buttonDownScenePos(buttonbit)); + target.setButtonDownScreenPos(buttonbit, source.buttonDownScreenPos(buttonbit)); + + // Unset button + buttons = buttons & ~buttonbit; + } + buttonbit = (Qt::MouseButton)(buttonbit << 1); + } + + target.setLastPos(source.lastPos()); + target.setLastScenePos(source.lastScenePos()); + target.setLastScreenPos(source.lastScreenPos()); + target.setButton(source.button()); + target.setModifiers(source.modifiers()); +} + + +//! \cond +class DuiPannableWidgetGlass : public DuiWidget +{ +public: + DuiPannableWidgetGlass(QGraphicsItem *parent = 0); + virtual ~DuiPannableWidgetGlass(); + + virtual QRectF boundingRect() const; + + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + virtual void ungrabMouseEvent(QEvent *event); + virtual void timerEvent(QTimerEvent *event); + + DuiPannableWidget *pannableWidget; +}; +//! \endcond + +DuiPannableWidgetGlass::DuiPannableWidgetGlass(QGraphicsItem *parent) : + DuiWidget(parent) +{ + this->pannableWidget = dynamic_cast(parent); +} + + +DuiPannableWidgetGlass::~DuiPannableWidgetGlass() +{ +} + + +QRectF DuiPannableWidgetGlass::boundingRect() const +{ + return QRectF(QPointF(), pannableWidget->size()); +} + + +void DuiPannableWidgetGlass::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + pannableWidget->glassMousePressEvent(event); +} + + +void DuiPannableWidgetGlass::mouseMoveEvent(QGraphicsSceneMouseEvent *event) +{ + pannableWidget->glassMouseMoveEvent(event); +} + + +void DuiPannableWidgetGlass::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + pannableWidget->glassMouseReleaseEvent(event); +} + +void DuiPannableWidgetGlass::ungrabMouseEvent(QEvent *event) +{ + pannableWidget->glassUngrabMouseEvent(event); +} + +void DuiPannableWidgetGlass::timerEvent(QTimerEvent *event) +{ + pannableWidget->glassTimeoutEvent(event); +} + +DuiPannableWidgetPrivate::DuiPannableWidgetPrivate() : + state(DuiPannableWidgetPrivate::Wait), + itemCount(0), + pressEvent(QEvent::GraphicsSceneMousePress), + physics(0), + mouseGrabber(0), + resentList(), + tapAndHoldTimerId(0) +{ +} + +DuiPannableWidgetPrivate::~DuiPannableWidgetPrivate() +{ + delete physics; +} + +void DuiPannableWidgetPrivate::translateEventToItemCoordinates(const QGraphicsItem *srcItem, const QGraphicsItem *destItem, QGraphicsSceneMouseEvent *event) +{ + //we only handle left button here. Every other buttons are filtered out in the glassMousePressEvents(); + event->setButtonDownPos(Qt::LeftButton, destItem->mapFromItem(srcItem, event->buttonDownPos(Qt::LeftButton))); + event->setLastPos(destItem->mapFromItem(srcItem, event->lastPos())); + event->setPos(destItem->mapFromItem(srcItem, event->pos())); +} + +void DuiPannableWidgetPrivate::resetState() +{ + physics->pointerRelease(); + physics->stop(); + state = DuiPannableWidgetPrivate::Wait; +} + +void DuiPannableWidgetPrivate::deliverMouseEvent(QGraphicsSceneMouseEvent *event) +{ + Q_Q(DuiPannableWidget); + if (mouseGrabber && q->scene()->items().contains(mouseGrabber)) { + translateEventToItemCoordinates(glass, mouseGrabber, event); + q->scene()->sendEvent(mouseGrabber, event); + } +} + +void DuiPannableWidgetPrivate::tapAndHoldStartTimer() +{ + tapAndHoldTimerId = glass->startTimer(TapAndHoldTimeoutValue); +} + +void DuiPannableWidgetPrivate::tapAndHoldStopTimer() +{ + if (tapAndHoldTimerId) { + glass->killTimer(tapAndHoldTimerId); + tapAndHoldTimerId = 0; + } +} + +DuiPannableWidget::DuiPannableWidget(DuiPannableWidgetPrivate *dd, DuiPannableWidgetModel *model, + QGraphicsItem *parent) + : DuiWidgetController(dd, model, parent) +{ + init(); +} + + +DuiPannableWidget::DuiPannableWidget(QGraphicsItem *parent) : + DuiWidgetController(new DuiPannableWidgetPrivate(), new DuiPannableWidgetModel, parent) +{ + init(); +} + +void DuiPannableWidget::init() +{ + Q_D(DuiPannableWidget); + + d->physics = new DuiPhysics2DPanning(this); + + connect(d->physics, SIGNAL(updatePosition(QPointF)), + this, SLOT(updatePosition(QPointF))); + + connect(d->physics, SIGNAL(panningStopped()), + this, SIGNAL(panningStopped())); + + d->glass = new DuiPannableWidgetGlass(this); + d->glass->setZValue(ZValueGlass); + + d->glass->setObjectName("glass"); + + setPosition(QPointF()); + setRange(QRectF()); +} + +DuiPannableWidget::~DuiPannableWidget() +{ +} + + +DuiPhysics2DPanning *DuiPannableWidget::physics() const +{ + Q_D(const DuiPannableWidget); + return d->physics; +} + + +void DuiPannableWidget::setEnabled(bool enabled) +{ + Q_D(DuiPannableWidget); + + model()->setEnabled(enabled); + + if (!enabled) { + d->physics->pointerRelease(); + + d->state = DuiPannableWidgetPrivate::Wait; + + d->physics->stop(); + } +} + + +bool DuiPannableWidget::isEnabled() +{ + return model()->enabled(); +} + + +void DuiPannableWidget::setRange(const QRectF &r) +{ + Q_D(const DuiPannableWidget); + d->physics->setRange(r); +} + + +QRectF DuiPannableWidget::range() const +{ + Q_D(const DuiPannableWidget); + return d->physics->range(); +} + + +void DuiPannableWidget::setPosition(const QPointF &p) +{ + Q_D(const DuiPannableWidget); + d->physics->setPosition(p); + emit positionChanged(p); +} + + +QPointF DuiPannableWidget::position() const +{ + Q_D(const DuiPannableWidget); + return d->physics->position(); +} + + +bool DuiPannableWidget::checkForResent(QEvent *event) +{ + Q_D(DuiPannableWidget); + + const int size = d->resentList.size(); + for (int i = 0; i < size; ++i) { + const DuiPannableWidgetPrivate::resentItem &item = d->resentList.at(i); + if (item.type == (static_cast(event))->type() && + item.screenPos == (static_cast(event))->screenPos() && + item.button == (static_cast(event))->button()) { + + d->resentList.removeAt(i); + + return true; + } + } + + return false; +} + +void DuiPannableWidget::updatePosition(const QPointF &position) +{ + Q_UNUSED(position); +} + + +void DuiPannableWidget::glassMousePressEvent(QGraphicsSceneMouseEvent *event) +{ + Q_D(DuiPannableWidget); + + if (!isEnabled()) { + // Glass: Ignoring, panning disabled + + event->ignore(); + return; + } + + if (event->button() != Qt::LeftButton) { + // Glass: Ignoring, not a left button + + event->ignore(); + return; + } + + if (!(panDirection().testFlag(Qt::Horizontal) || panDirection().testFlag(Qt::Vertical))) { + // Glass: Ignoring, no enabled panning directions + + event->ignore(); + return; + } + + if (checkForResent(event)) { + // Glass: Ignoring, already seen + + event->ignore(); + return; + } + + switch (d->state) { + case DuiPannableWidgetPrivate::Wait: + // Saves the event so it can be passed forward if the + // press doesn't end to be a panning action + + copyGraphicsSceneMouseEvent(d->pressEvent, *event); + + if (!d->physics->inMotion()) { + // sending it now, we will send "cancel" if it will be needed. + + d->glass->ungrabMouse(); + this->resendEvent(&d->pressEvent); + d->mouseGrabber = scene()->mouseGrabberItem(); + d->itemCount = scene()->items().size(); + d->glass->grabMouse(); + + d->tapAndHoldStartTimer(); + } + + d->physics->pointerPress(event->pos()); + + d->state = DuiPannableWidgetPrivate::Evaluate; + break; + + default: + // Evaluate and pan states don't see press events + break; + } +} + +void DuiPannableWidget::glassMouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + Q_D(DuiPannableWidget); + + // This is not going to be tap&hold. + d->tapAndHoldStopTimer(); + + if (!isEnabled()) { + //Widget disabled in the middle of the gesture. We need to deliver + //the events to the underlaying widget if we have it. + d->deliverMouseEvent(event); + d->resetState(); + //All events from this interaction has been delivered or dropped. + //We can now safely become really disabled. + d->mouseGrabber = 0; + d->glass->ungrabMouse(); + return; + } + + switch (d->state) { + case DuiPannableWidgetPrivate::Evaluate: { + + d->glass->ungrabMouse(); + //ungrab event handler will ensure that physics is stopped + //and pointer is released. + + QPointF velocity = d->physics->velocity(); + + if (!d->physics->inMotion()) { + // If the scene's item count has changed between mouse press and release, + // there is a possibility that the mousegrabber pointer points to deleted + // object which potentially leads to a crash. + if (d->itemCount != scene()->items().size()) { + resendEvent(&d->pressEvent); // we need to setup implicit mouse grabber + resendEvent(event); + } else { + d->deliverMouseEvent(event); + } + } else if (qAbs(velocity.x()) < model()->panClickThreshold() && + qAbs(velocity.y()) < model()->panClickThreshold()) { + if (d->mouseGrabber) { + resendEvent(&d->pressEvent); // we need to setup implicit mouse grabber + resendEvent(event); + } + } else { + sendCancel(&d->pressEvent); + } + + d->state = DuiPannableWidgetPrivate::Wait; + break; + } + case DuiPannableWidgetPrivate::Pan: + d->physics->pointerRelease(); + + d->state = DuiPannableWidgetPrivate::Wait; + break; + + default: + // Wait state sees a release event in case of a press / move + // to a passive direction causing a stop of physics because of + // physics being inmotion + break; + } +} + + +void DuiPannableWidget::glassMouseMoveEvent(QGraphicsSceneMouseEvent *event) +{ + Q_D(DuiPannableWidget); + QPointF delta; + qreal distAct, distPass; + + if (!isEnabled()) { + //Widget disabled in the middle of the gesture. We need to deliver + //the events to the underlaying widget if we have it. + d->deliverMouseEvent(event); + d->resetState(); + //We don't ungrab at this point because we want to deliver + //rest of the events from this interaction to the underlaying widget. + return; + } + + switch (d->state) { + case DuiPannableWidgetPrivate::Evaluate: + + // Check if the movement is big enough to justify panning + + delta = event->pos() - d->pressEvent.pos(); + + if (panDirection().testFlag(Qt::Horizontal) && !panDirection().testFlag(Qt::Vertical)) { + distAct = abs((int)delta.x()); + distPass = abs((int)delta.y()); + + } else if (!panDirection().testFlag(Qt::Horizontal) && panDirection().testFlag(Qt::Vertical)) { + distAct = abs((int)delta.y()); + distPass = abs((int)delta.x()); + + } else { + // 0.7*(x + y) approximates sqrt(x^2 + y^2) + + distAct = 0.7 * (abs((int)delta.x()) + abs((int)delta.y())); + distPass = 0; + } + + if (distAct > panThreshold()) { + + // This is panning, cancel the press event. + sendCancel(&d->pressEvent); + d->physics->pointerMove(event->pos()); + + // This is not going to be tap&hold. + d->tapAndHoldStopTimer(); + + d->state = DuiPannableWidgetPrivate::Pan; + } else if (distPass > panThreshold()) { + d->physics->pointerRelease(); + + // This is not going to be tap&hold. + d->tapAndHoldStopTimer(); + + if (!d->physics->inMotion()) { + + d->glass->ungrabMouse(); + + resendEvent(&d->pressEvent); // we need to setup implicit mouse grabber + resendEvent(event); + } else { + d->physics->stop(); + } + + d->state = DuiPannableWidgetPrivate::Wait; + } + + break; + + case DuiPannableWidgetPrivate::Pan: + + d->physics->pointerMove(event->pos()); + + d->state = DuiPannableWidgetPrivate::Pan; + break; + + default: + // Wait state sees a move event in case of a press / move to a + // passive direction causing a stop of physics because of + // physics being inmotion + break; + } +} + +void DuiPannableWidget::glassUngrabMouseEvent(QEvent *event) +{ + Q_UNUSED(event); + Q_D(DuiPannableWidget); + + //We will reset the state so that pannable widget + //will be ready to receive next mousePress. + switch (d->state) { + case DuiPannableWidgetPrivate::Evaluate: + case DuiPannableWidgetPrivate::Pan: + d->resetState(); + break; + default: + break; + } +} + +void DuiPannableWidget::glassTimeoutEvent(QTimerEvent *event) +{ + Q_D(DuiPannableWidget); + + //If it's not our timer, we shouldn't do anything. + if (event->timerId() != d->tapAndHoldTimerId) + return; + + //We don't need another timer event, and this is not a singleshot timer. + d->tapAndHoldStopTimer(); + + //We will reset the state so that pannable widget + //will be ready to receive next mousePress. + switch (d->state) { + case DuiPannableWidgetPrivate::Evaluate: { + QGraphicsSceneContextMenuEvent contextEvent(QEvent::GraphicsSceneContextMenu); + contextEvent.setPos(d->pressEvent.pos()); + contextEvent.setScenePos(d->pressEvent.scenePos()); + contextEvent.setScreenPos(d->pressEvent.screenPos()); + + QApplication::sendEvent(scene(), &contextEvent); + + if (contextEvent.isAccepted()) { + + sendCancel(&d->pressEvent); + d->resetState(); + + //We will still receive mouse release, but + //we aren't interested in it. + d->mouseGrabber = 0; + d->glass->ungrabMouse(); + } + break; + } + default: + break; + } +} + +void DuiPannableWidget::resendEvent(QGraphicsSceneMouseEvent *event) +{ + Q_D(DuiPannableWidget); + + QEvent::Type type; + struct DuiPannableWidgetPrivate::resentItem resentItem; + + switch (event->type()) { + case QEvent::GraphicsSceneMousePress: + type = QEvent::MouseButtonPress; + break; + + case QEvent::GraphicsSceneMouseRelease: + type = QEvent::MouseButtonRelease; + break; + + case QEvent::GraphicsSceneMouseMove: + type = QEvent::MouseMove; + break; + + default: + // Shouldn't end up here + return; + + break; + } + + if ((this->scene() == NULL) || (this->scene()->views().size() == 0)) { + + // If this widget has been removed from the scene and/or there + // is no view, return + return; + } + + QMouseEvent mouse_event(type, + this->scene()->views()[0]->mapFromScene(event->scenePos()), + event->screenPos(), + event->button(), + event->buttons(), + event->modifiers()); + + /* + duiDebug("DuiPannableWidget") << "Event: " << type + << " " << this->scene()->views()[0]->mapFromScene(event->scenePos()) + << " " << event->screenPos() + << " " << event->button() + << " " << event->buttons() + << " " << event->modifiers(); + */ + + if (type == QEvent::MouseButtonPress) { + // Puts the event to exclude list + + resentItem.type = event->type(); + resentItem.screenPos = event->screenPos(); + resentItem.button = event->button(); + + // Size limiter for the list. Prevents the list from growing in + // unlimited fashion in case of an unexpected loss of events + + while (d->resentList.size() > ResentListMaxSize) { + d->resentList.removeLast(); + } + + d->resentList.append(resentItem); + } + + QApplication::sendEvent(this->scene()->views()[0]->viewport(), &mouse_event); +} + +// onDisplayChangeEvent in DuiWidget handles DuiPannableWidgets in a +// wrong way: because a pannable widget fits always in viewRect of a +// window, it never passes MustBeResolved event to its children, even if +// the contents of the widget would not fit to its rectangle. This re-imp +// passes MustBeResolved in any case. +void DuiPannableWidget::onDisplayChangeEvent(DuiOnDisplayChangeEvent *event) +{ + Q_D(DuiPannableWidget); + + switch (event->state()) { + case DuiOnDisplayChangeEvent::MustBeResolved: + case DuiOnDisplayChangeEvent::FullyOnDisplay: + if (!d->onDisplay || !d->onDisplaySet) { + + d->onDisplay = true; + d->onDisplaySet = true; + + // Call the virtual handler and emit the signal + enterDisplayEvent(); + emit displayEntered(); + + DuiOnDisplayChangeEvent ev(DuiOnDisplayChangeEvent::MustBeResolved, + event->viewRect()); + + // Explicitly set the states of the children + Q_FOREACH(QGraphicsItem * item, childItems()) { + scene()->sendEvent(item, &ev); + } + } + break; + + default: + DuiWidget::onDisplayChangeEvent(event); + break; + } +} + +void DuiPannableWidget::sendCancel(QGraphicsSceneMouseEvent *event) +{ + Q_D(DuiPannableWidget); + Q_UNUSED(event); + + if ((this->scene() == NULL) || (this->scene()->views().size() == 0)) { + + // If this widget has been removed from the scene and/or there + // is no view, return + return; + } + + if (!d->mouseGrabber || !scene()->items().contains(d->mouseGrabber)) { + // We don't have the recipient of the cancel event, don't send it. + return; + } + + DuiCancelEvent cancelEvent; + scene()->sendEvent(d->mouseGrabber, &cancelEvent); +} + +void DuiPannableWidget::setPanDirection(const Qt::Orientations &panDirection) +{ + model()->setPanDirection(panDirection); +} + +Qt::Orientations DuiPannableWidget::panDirection() +{ + return model()->panDirection(); +} + +void DuiPannableWidget::setPanThreshold(qreal value) +{ + model()->setPanThreshold(value); +} + +qreal DuiPannableWidget::panThreshold() +{ + return model()->panThreshold(); +} diff --git a/src/widgets/duipannablewidget.h b/src/widgets/duipannablewidget.h new file mode 100644 index 000000000..218de5a58 --- /dev/null +++ b/src/widgets/duipannablewidget.h @@ -0,0 +1,238 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIPANNABLEWIDGET_H +#define DUIPANNABLEWIDGET_H + +#include "duiwidgetcontroller.h" +#include "duiphysics2dpanning.h" +#include + +class QTimerEvent; +class QGraphicsSceneMouseEvent; +class DuiPannableWidgetPrivate; +class DuiOnDisplayChangeEvent; + +/*! + * \class DuiPannableWidget + * \brief Base class which adds support for panning gesture + * + * DuiPannableWidget creates a glass on top of itself and using the + * glass, intercepts events coming from QGraphicsScene onto its area + * and interprets them. If the events form a panning gesture, a + * physics class is used to create a natural Newtonian movement in the + * direction of panning. Panning position is provided as an + * overridable slot UpdatePosition(). If the events don't form a + * panning gesture, they are forwarded underneath the glass. + */ +class DUI_EXPORT DuiPannableWidget : public DuiWidgetController +{ + Q_OBJECT + DUI_CONTROLLER(DuiPannableWidget) + + //! \brief Enabled status + Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled) + //! \brief Enabled panning directions + Q_PROPERTY(Qt::Orientations panDirection READ panDirection WRITE setPanDirection) + //! \brief Panning range + Q_PROPERTY(QRectF range READ range WRITE setRange) + //! \brief Panning position + Q_PROPERTY(QPointF position READ position WRITE setPosition NOTIFY positionChanged USER true) + //! \brief Panning threshold + Q_PROPERTY(qreal panThreshold READ panThreshold WRITE setPanThreshold) + +public: + /*! + * \brief Constructs a pannable widget with a \a parent. + */ + DuiPannableWidget(QGraphicsItem *parent = 0); + + /*! + * \brief Destroys the pannable widget. + */ + virtual ~DuiPannableWidget(); + + /*! + * \brief Returns the physics class instance used in + * panning. Normally only used by the view. + */ + DuiPhysics2DPanning *physics() const; + + /*! + * \brief Sets the enabled status of the pannable widget. + * + * If pannable widget is disabled but panning gesture is ongoing, + * the pointer is forced programmatically up. + * + */ + void setEnabled(bool enabled); + + /*! + * \brief Returns the enabled status of the pannable widget. + */ + bool isEnabled(); + + /*! + * \brief Sets the \a range of the panning. + * + * When range is zero along some axis, user can still make a + * panning gesture on that direction but the position snaps back + * to 0.0. If the range is shrank so that the current position + * goes to border, the border springs are activated. + * + * By default, the range is QRectF(0,0). + */ + virtual void setRange(const QRectF &range); + + /*! + * \brief Returns the range of the panning. + */ + virtual QRectF range() const; + + /*! + * \brief Sets the \a position of the panning. + * + * If the new position is in the border, the border springs are + * activated. + * + * By default, the position is QPointF(0,0). + */ + virtual void setPosition(const QPointF &position); + + /*! + * \brief Returns the current position of the panning. + */ + virtual QPointF position() const; + + /*! + * \brief Sets the enabled panning directions. + * + * The accepted values are Qt::Horizontal and/or Qt::Vertical. + */ + virtual void setPanDirection(const Qt::Orientations &panDirection); + + /*! + * \brief Returns the enabled panning directions. + * + * By default, the panning is enabled in Qt::Vertical direction. + */ + Qt::Orientations panDirection(); + + /*! + * \brief Sets the panning threshold. This method should be used + * only by the view. For setting this value, use css. + */ + void setPanThreshold(qreal value); + + /*! + * \brief Returns the current panning threshold. + */ + qreal panThreshold(); + +public Q_SLOTS: + /*! + * \brief Virtual slot for receiving position changes from + * physics. + */ + virtual void updatePosition(const QPointF &position); + +Q_SIGNALS: + + /*! + * \brief this signal is emitted when the position of the pannableWidget changes + */ + void positionChanged(QPointF newPosition); + + /*! + * \brief Signals that the panning has stopped. + */ + void panningStopped(); + +protected: + /*! + * Protected constructor for derived classes. + */ + DuiPannableWidget(DuiPannableWidgetPrivate *dd, DuiPannableWidgetModel *model, + QGraphicsItem *parent); + + //! \reimp + virtual void onDisplayChangeEvent(DuiOnDisplayChangeEvent *event); + //! \reimp_end + +private: + Q_DISABLE_COPY(DuiPannableWidget) + Q_DECLARE_PRIVATE(DuiPannableWidget) + + /*! + * \brief Method for handling the press events from the glass. + */ + void glassMousePressEvent(QGraphicsSceneMouseEvent *event); + + /*! + * \brief Method for handling the release events from the glass. + */ + void glassMouseReleaseEvent(QGraphicsSceneMouseEvent *event); + + /*! + * \brief Method for handling the move events from the glass. + */ + void glassMouseMoveEvent(QGraphicsSceneMouseEvent *event); + + /*! + * \brief Method for handling situation when some underlying + * widget grabs mouse. + */ + void glassUngrabMouseEvent(QEvent *event); + + /*! + * \brief Method for delivering timeout events when recognizing + * tap&hold gesture. + */ + void glassTimeoutEvent(QTimerEvent *event); + + /*! + * \brief Method for checking if the event is on the resent list + * and should pass the glass when it hits it the second time. + */ + bool checkForResent(QEvent *event); + + /*! + * \brief Method for posting a captured event back to viewport. + */ + void resendEvent(QGraphicsSceneMouseEvent *event); + + /*! + * \brief Method for sending cancel event to viewport. + */ + void sendCancel(QGraphicsSceneMouseEvent *baseEvent); + + /*! + * \brief Init method. + */ + void init(); + +#ifdef UNIT_TEST + // Test unit is defined as a friend of production code to access private members + friend class Ut_DuiPannableWidget; +#endif + + friend class DuiPannableWidgetGlass; +}; + +#endif diff --git a/src/widgets/duipannablewidget_p.h b/src/widgets/duipannablewidget_p.h new file mode 100644 index 000000000..3de6ef1e4 --- /dev/null +++ b/src/widgets/duipannablewidget_p.h @@ -0,0 +1,94 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIPANNABLEWIDGET_P_H +#define DUIPANNABLEWIDGET_P_H + +#include +#include +#include + +#include "private/duiwidgetcontroller_p.h" + +class QPoint; +class QEvent; +class QTransform; +class QGraphicsItem; +class QGraphicsSceneMouseEvent; +class DuiPhysics2DPanning; +class DuiStyle; +class DuiPannableWidgetGlass; + +class DuiPannableWidgetPrivate : public DuiWidgetControllerPrivate +{ + Q_DECLARE_PUBLIC(DuiPannableWidget) +public: + explicit DuiPannableWidgetPrivate(); + virtual ~DuiPannableWidgetPrivate(); + + enum states {Wait, Evaluate, Pan}; + int state; + int itemCount; + + QGraphicsSceneMouseEvent pressEvent; + + DuiPhysics2DPanning *physics; + DuiPannableWidgetGlass *glass; + QGraphicsItem *mouseGrabber; + + struct resentItem { + QEvent::Type type; + QPoint screenPos; + Qt::MouseButton button; + }; + + QList resentList; + + int tapAndHoldTimerId; +public: + + /*! + * \brief Internal method neccessary to correctly handle event positions. + */ + void translateEventToItemCoordinates(const QGraphicsItem *srcItem, + const QGraphicsItem *destItem, + QGraphicsSceneMouseEvent *event); + + /*! + * \brief Method used for resetting state of the pannable widget. + */ + void resetState(); + + /*! + * \brief Method used for delivering event to interested widget. + */ + void deliverMouseEvent(QGraphicsSceneMouseEvent *event); + + /*! + * \brief Method used for starting tap&hold timer. + */ + void tapAndHoldStartTimer(); + + /*! + * \brief Method used for stopping tap&hold timer. + */ + void tapAndHoldStopTimer(); +}; + +#endif diff --git a/src/widgets/duipannablewidgetmodel.h b/src/widgets/duipannablewidgetmodel.h new file mode 100644 index 000000000..4e41f1978 --- /dev/null +++ b/src/widgets/duipannablewidgetmodel.h @@ -0,0 +1,36 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIPANNABLEWIDGETMODEL_H +#define DUIPANNABLEWIDGETMODEL_H + +#include + +class DUI_EXPORT DuiPannableWidgetModel : public DuiWidgetModel +{ + Q_OBJECT + DUI_MODEL_INTERNAL(DuiPannableWidgetModel) + + DUI_MODEL_PROPERTY(bool, enabled, Enabled, true, true) + DUI_MODEL_PROPERTY(qreal, panThreshold, PanThreshold, true, 10.0) + DUI_MODEL_PROPERTY(qreal, panClickThreshold, PanClickThreshold, true, 0.2) + DUI_MODEL_PROPERTY(Qt::Orientations, panDirection, PanDirection, true, Qt::Vertical) +}; + +#endif diff --git a/src/widgets/duiphysics2dpanning.cpp b/src/widgets/duiphysics2dpanning.cpp new file mode 100644 index 000000000..88bd64814 --- /dev/null +++ b/src/widgets/duiphysics2dpanning.cpp @@ -0,0 +1,401 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include + +#include "duipannablewidget.h" +#include "duiphysics2dpanning.h" +#include "duiphysics2dpanning_p.h" + +static const int PanningTimelineDuration = 1000000; /* in ms */ +static const int PanningTimelineInterval = 20; /* in ms */ +static const int PositionNoiseDampingDelta = 2; /* in px */ + +DuiPhysics2DIntegrationStrategy::~DuiPhysics2DIntegrationStrategy() +{ + +} + +void DuiPhysics2DIntegrationStrategy::integrate(qreal &pos, + qreal &vel, + qreal &pointerSpring, + qreal &acc, + qreal rangeStart, + qreal rangeEnd, + IntegrationData &data + ) +{ + qreal force; + + // Damping + if (pos >= rangeStart && pos <= rangeEnd) { + + // Inside range + if (data.pointer) { + force = -data.frictionC * vel; + } else { + force = -data.slideFrictionC * vel; + } + } else { + // Outside range (in border) + force = -data.borderFrictionC * vel; + } + + // Border springs + if (pos < rangeStart) { + force += data.borderSpringK * (rangeStart - pos); + //Special case - when the border is crossed, + //we don't want the view to "bounce" from the border. + //We snap in this place to rangeStart value; + if ((data.pointer == false) && (pos + vel + force >= rangeStart)) { + vel = force = 0; + pos = rangeStart; + } + } + + if (pos > rangeEnd) { + force += -data.borderSpringK * (pos - rangeEnd); + //Special case - when the border is crossed + //we don't want the view to "bounce" from the border. + //We snap in this place to rangeEnd value; + if ((data.pointer == false) && (pos + vel + force <= rangeEnd)) { + vel = force = 0; + pos = rangeEnd; + } + } + + // Integration. Currently does not use time_delta or mass (assumed as 1.0) + + if (data.pointer) { + + // Damping of acceleration with pointer spring values. + force += data.pointerSpringK * pointerSpring; + // Increasing the speed by the last movement of the pointer + acc = force - pointerSpring; + vel += acc; + + if (abs(pointerSpring) > PositionNoiseDampingDelta) { + pos -= pointerSpring; + pointerSpring = 0; + } + + } else { + + acc = force; + + vel += acc; + pos += vel; + pointerSpring += vel; + } +} + +DuiPhysics2DPanningPrivate::DuiPhysics2DPanningPrivate(DuiPannableWidget *parentPannableWidget) : + parentPannableWidget(parentPannableWidget), + range(QRectF(0.0, 0.0, 0.0, 0.0)), + posX(0.0), + posY(0.0), + velX(0.0), + velY(0.0), + pointerSpringX(0.0), + pointerSpringY(0.0), + sceneLastPos(QPointF()), + timeLine(new QTimeLine()), + currFrame(0), + integrationStrategy(0) +{ + integrationData.pointerSpringK = 0.0; + integrationData.frictionC = 0.0; + integrationData.slideFrictionC = 0.0; + integrationData.borderSpringK = 0.0; + integrationData.borderFrictionC = 0.0; + integrationData.pointer = false; +} + + +DuiPhysics2DPanningPrivate::~DuiPhysics2DPanningPrivate() +{ + delete timeLine; +} + + +DuiPhysics2DPanning::DuiPhysics2DPanning(DuiPannableWidget *parentPannableWidget) + : QObject(), + d_ptr(new DuiPhysics2DPanningPrivate(parentPannableWidget)) +{ + Q_D(DuiPhysics2DPanning); + d->integrationStrategy = new DuiPhysics2DIntegrationStrategy(); + connect(d->timeLine, SIGNAL(frameChanged(int)), + this, SLOT(integrator(int))); +} + + +DuiPhysics2DPanning::~DuiPhysics2DPanning() +{ + Q_D(DuiPhysics2DPanning); + delete d->integrationStrategy; + delete d_ptr; +} + +void DuiPhysics2DPanning::setIntegrationStrategy(DuiPhysics2DIntegrationStrategy *strategy) +{ + if (!strategy) return; + + Q_D(DuiPhysics2DPanning); + delete d->integrationStrategy; + d->integrationStrategy = strategy; +} + +DuiPhysics2DIntegrationStrategy *DuiPhysics2DPanning::integrationStrategy() const +{ + Q_D(const DuiPhysics2DPanning); + return d->integrationStrategy; +} + +void DuiPhysics2DPanning::start() +{ + Q_D(DuiPhysics2DPanning); + if (!inMotion()) { + d->velX = 0.0; + d->velY = 0.0; + + d->timeLine->setDuration(PanningTimelineDuration); + d->timeLine->setUpdateInterval(PanningTimelineInterval); + d->timeLine->setFrameRange(0, 29999); + d->timeLine->setCurrentTime(0); + d->timeLine->setCurveShape(QTimeLine::LinearCurve); + d->currFrame = 0; + d->timeLine->start(); + } +} + + +void DuiPhysics2DPanning::stop() +{ + Q_D(DuiPhysics2DPanning); + d->timeLine->stop(); + emit panningStopped(); +} + + +void DuiPhysics2DPanning::setRange(const QRectF &range) +{ + Q_D(DuiPhysics2DPanning); + d->range = range; + + // Updates position after range setting (but this is not enough to + // drag the position inside range in case range shrinks and puts + // position outside it) + emit updatePosition(QPointF(d->posX, d->posY)); + + // Starts physics to return the position into range (border spring + // activates). This does not cover the former case since physics + // emits no updatePosition signals in case the position is still + // inside range + start(); +} + + +QRectF DuiPhysics2DPanning::range() const +{ + Q_D(const DuiPhysics2DPanning); + return d->range; +} + + +void DuiPhysics2DPanning::setPosition(const QPointF &position) +{ + Q_D(DuiPhysics2DPanning); + + if (QPointF(d->posX, d->posY) != position) { + d->posX = position.x(); + d->posY = position.y(); + + emit updatePosition(position); + + // Starts the physics in case the position is set to border + // and it needs to slide back into range + start(); + } +} + + +QPointF DuiPhysics2DPanning::position() const +{ + Q_D(const DuiPhysics2DPanning); + + return QPointF(d->posX, d->posY); +} + + +QPointF DuiPhysics2DPanning::velocity() const +{ + Q_D(const DuiPhysics2DPanning); + + return QPointF(d->velX, d->velY); +} + + +bool DuiPhysics2DPanning::inMotion() const +{ + Q_D(const DuiPhysics2DPanning); + + return (d->timeLine->state() == QTimeLine::Running); +} + + +void DuiPhysics2DPanning::pointerPress(const QPointF &pos) +{ + Q_D(DuiPhysics2DPanning); + + // Enables the pointer spring, sets it to zero length and + // starts the integrator + + d->integrationData.pointer = true; + d->sceneLastPos = pos; + + d->pointerSpringX = 0.0; + d->pointerSpringY = 0.0; +} + + +void DuiPhysics2DPanning::pointerMove(const QPointF &pos) +{ + Q_D(DuiPhysics2DPanning); + + // Tenses the pointer spring with the amount of movement of the pointer + + QPointF delta = pos - d->sceneLastPos; + + d->sceneLastPos = pos; + + d->pointerSpringX += delta.x(); + d->pointerSpringY += delta.y(); + start(); +} + + +void DuiPhysics2DPanning::pointerRelease() +{ + Q_D(DuiPhysics2DPanning); + + // Disables the pointer spring + + d->integrationData.pointer = false; +} + +void DuiPhysics2DPanning::setPointerSpringK(qreal value) +{ + d_ptr->integrationData.pointerSpringK = value; +} + +void DuiPhysics2DPanning::setFriction(qreal value) +{ + d_ptr->integrationData.frictionC = value; +} + +void DuiPhysics2DPanning::setSlidingFriction(qreal value) +{ + d_ptr->integrationData.slideFrictionC = value; +} + +void DuiPhysics2DPanning::setBorderSpringK(qreal value) +{ + d_ptr->integrationData.borderSpringK = value; +} + +void DuiPhysics2DPanning::setBorderFriction(qreal value) +{ + d_ptr->integrationData.borderFrictionC = value; +} + +void DuiPhysics2DPanning::integrator(int frame) +{ + Q_D(DuiPhysics2DPanning); + + qreal accX, accY; + qreal tempPosX; + qreal tempPosY; + int i = 0; + + tempPosX = d->posX; + tempPosY = d->posY; + + while (frame > d->currFrame) { + if (d->parentPannableWidget->panDirection().testFlag(Qt::Horizontal)) { + d->integrationStrategy->integrate(d->posX, + d->velX, + d->pointerSpringX, + accX, + d->range.left(), + d->range.right(), + d->integrationData + ); + } else { + d->posX = 0.0; + d->velX = 0.0; + accX = 0.0; + } + + if (d->parentPannableWidget->panDirection().testFlag(Qt::Vertical)) { + d->integrationStrategy->integrate(d->posY, + d->velY, + d->pointerSpringY, + accY, + d->range.top(), + d->range.bottom(), + d->integrationData + ); + + } else { + d->posY = 0.0; + d->velY = 0.0; + accY = 0.0; + } + + // Checking if the viewport is currently dragged beyond it's borders and the integration should + // continue even though the speed is low. + bool inRangeX = (d->parentPannableWidget->panDirection().testFlag(Qt::Horizontal) == false) || + (d->posX >= d->range.left() && d->posX <= d->range.right()); + + bool inRangeY = (d->parentPannableWidget->panDirection().testFlag(Qt::Vertical) == false) || + (d->posY >= d->range.top() && d->posY <= d->range.bottom()); + + // Integration stop condition. + if (inRangeX && inRangeY && + qAbs(accX) < 1 && + qAbs(accY) < 1 && + qAbs(d->velX) < 1 && + qAbs(d->velY) < 1 && + !d->integrationData.pointer) { + d->timeLine->stop(); + + emit panningStopped(); + + break; + } + + d->currFrame++; + i++; + } + + if (tempPosX != d->posX || tempPosY != d->posY) { + emit(updatePosition(QPointF(d->posX, d->posY))); + } +} + diff --git a/src/widgets/duiphysics2dpanning.h b/src/widgets/duiphysics2dpanning.h new file mode 100644 index 000000000..cbc763c92 --- /dev/null +++ b/src/widgets/duiphysics2dpanning.h @@ -0,0 +1,245 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIPHYSICS2DPANNING_H +#define DUIPHYSICS2DPANNING_H + +#include "duiexport.h" + +#include + +class QSizeF; +class QRectF; +class QPointF; + +class DuiPannableWidget; +class DuiPhysics2DPanningPrivate; + +/*! + * @note Currently the physics works best using units which are not + * consistent. The panning gestures are interpreted as meters, the + * mass of the position works best when 1 (kg) and the time delta used + * in formulas is 1 sec (although the integration is done 50 + * times/sec). This could be re-checked and values could be adjusted + * to sensible magnitudes (gestures interpreted as millimeters, time delta + * as 50 times/sec etc.) + */ + +class DUI_EXPORT DuiPhysics2DIntegrationStrategy +{ +public: + + /*! + * \brief Destructs an integrator strategy object. + */ + virtual ~DuiPhysics2DIntegrationStrategy(); + + struct IntegrationData { + bool pointer; + qreal pointerSpringK; + qreal frictionC; + qreal slideFrictionC; + qreal borderSpringK; + qreal borderFrictionC; + }; + + /*! + * \brief Method used to calculate values for next frame of + * panning movement. + */ + virtual void integrate(qreal &position, + qreal &velocity, + qreal &pointerSpring, + qreal &acceleration, + qreal rangeStart, + qreal rangeEnd, + IntegrationData &data); +}; + +/*! + * \class DuiPhysics2DPanning + * + * \brief This class is an integrator which integrates an + * object/position in 1D or 2D space using Newtonian physics it is + * typically used by DuiPannableWidget. + * + * The main force in the physics is originating from the pointer via a + * spring. Additional forces come into play if the position goes + * outside the range (border springs are applied). There are various + * friction constants slowing down the movement + */ +class DUI_EXPORT DuiPhysics2DPanning : public QObject +{ + Q_OBJECT + +public: + /*! + * \brief Constructs an integrator used by \a parentPannableWidget. + */ + DuiPhysics2DPanning(DuiPannableWidget *parentPannableWidget); + + /*! + * \brief Destructs an integrator. + */ + virtual ~DuiPhysics2DPanning(); + + /*! + * \brief Sets the integration strategy object that will be used + * during simulation. + * + * In case that NULL object is provided, no action is taken and + * old integration strategy object will still be used. + * The DuiPhysics2DPanning class takes responsibility + * for deletion of the object. + */ + void setIntegrationStrategy(DuiPhysics2DIntegrationStrategy *strategy); + + /*! + * \brief Returns the currently used integration strategy object. + */ + DuiPhysics2DIntegrationStrategy *integrationStrategy() const; + + /*! + * \brief Sets the \a range of the physics. + * + * If the range is shrank so that the current position goes to + * border, the border springs are activated. + */ + void setRange(const QRectF &range); + + /*! + * \brief Returns the range of the physics. + */ + QRectF range() const; + + /*! + * \brief Sets the \a position of the physics. + * + * If the new position is in the border, the border springs are + * activated. + */ + void setPosition(const QPointF &position); + + /*! + * \brief Returns the current position of the physics. + */ + QPointF position() const; + + /*! + * \brief Returns the current velocity of the physics. + */ + QPointF velocity() const; + + /*! + * \brief Tells physics that pointer is pressed. + */ + void pointerPress(const QPointF &pos); + + /*! + * \brief Tells physics that pointer is moved. + * + * Tenses the pointer spring. + */ + void pointerMove(const QPointF &pos); + + /*! + * \brief Tells physics that pointer is release. + */ + void pointerRelease(); + + /*! + * \brief Sets a physics parameter: K value for the pointer spring. + */ + void setPointerSpringK(qreal value); + + /*! + * \brief Sets a physics parameter: Friction when a pointer is + * down and position is not in border. + */ + void setFriction(qreal value); + + /*! + * \brief Sets a physics parameter: Friction when a pointer is up + * and position is not in border. + */ + void setSlidingFriction(qreal value); + + /*! + * \brief Sets a physics parameter: K value for the border spring. + */ + void setBorderSpringK(qreal value); + + /*! + * \brief Sets a physics parameter: Friction when a pointer is up + * and position is in border. + */ + void setBorderFriction(qreal value); + + /*! + * \brief Returns the movement status of the integrated position. + */ + bool inMotion() const; + + /*! + * \brief Stops the physics. + */ + void stop(); + +public Q_SLOTS: + + /*! + * \brief Integrator for the physics. + * + * Called periodically by an internal timer. + */ + void integrator(int frame); + +Q_SIGNALS: + /*! + * \brief Signals a change in the \a position of the physics. + */ + void updatePosition(const QPointF &position); + + /*! + * \brief Signals that the panning animation has stopped + */ + void panningStopped(); + +protected: + /*! + * \brief Pointer to private implementation. + */ + DuiPhysics2DPanningPrivate *const d_ptr; + +private: + Q_DISABLE_COPY(DuiPhysics2DPanning) + Q_DECLARE_PRIVATE(DuiPhysics2DPanning) + + /*! + * \brief Starts the physics by setting up a repetitive timer. + */ + void start(); + +#ifdef UNIT_TEST + //! Test unit is defined as a friend of production code to access private members + friend class Ut_DuiPhysics2DPanning; +#endif +}; + +#endif diff --git a/src/widgets/duiphysics2dpanning_p.h b/src/widgets/duiphysics2dpanning_p.h new file mode 100644 index 000000000..4773e16f9 --- /dev/null +++ b/src/widgets/duiphysics2dpanning_p.h @@ -0,0 +1,57 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIPHYSICS2DPANNING_P_H +#define DUIPHYSICS2DPANNING_P_H + +#include +#include +#include +#include "duiphysics2dpanning.h" + +class DuiStyle; +class QTimeLine; +class DuiPannableWidget; + +class DuiPhysics2DPanningPrivate +{ +public: + DuiPhysics2DPanningPrivate(DuiPannableWidget *parentPannableWidget); + virtual ~DuiPhysics2DPanningPrivate(); + + DuiPannableWidget *parentPannableWidget; + + DuiPhysics2DIntegrationStrategy::IntegrationData integrationData; + + QRectF range; + qreal posX; + qreal posY; + qreal velX; + qreal velY; + qreal pointerSpringX; + qreal pointerSpringY; + QPointF sceneLastPos; + + QTimeLine *timeLine; + int currFrame; + + DuiPhysics2DIntegrationStrategy *integrationStrategy; +}; + +#endif diff --git a/src/widgets/duipopuplist.cpp b/src/widgets/duipopuplist.cpp new file mode 100644 index 000000000..32132d7a8 --- /dev/null +++ b/src/widgets/duipopuplist.cpp @@ -0,0 +1,171 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duipopuplist.h" +#include "duipopuplist_p.h" +#include "duilistnamespace.h" + +#include +#include + +#include +#include +#include + +#define MINBATCHSIZE 10 + +#include "duiwidgetcreator.h" +DUI_REGISTER_WIDGET(DuiPopupList) + +DuiPopupListPrivate::DuiPopupListPrivate() + : itemModel(0), selectionModel(0) +{ +} + +DuiPopupListPrivate::~DuiPopupListPrivate() +{ +} + +DuiPopupList::DuiPopupList() + : DuiDialog(new DuiPopupListPrivate(), new DuiPopupListModel(), DuiSceneWindow::PopupList) +{ + setCentralWidget(0); +} + +DuiPopupList::DuiPopupList(DuiPopupListPrivate *dd, DuiPopupListModel *model, DuiSceneWindow::WindowType windowType) + : DuiDialog(dd, model, windowType) +{ + setCentralWidget(0); +} + +DuiPopupList::~DuiPopupList() +{ +} + +void DuiPopupList::setItemModel(QAbstractItemModel *itemModel) +{ + Q_D(DuiPopupList); + + if (d->itemModel == itemModel) + return; + + if (itemModel == NULL) + d->itemModel = duiEmptyModel(); + else + d->itemModel = itemModel; + + emit itemModelChanged(d->itemModel); + + setSelectionModel(new QItemSelectionModel(d->itemModel, this)); +} + +QAbstractItemModel *DuiPopupList::itemModel() const +{ + Q_D(const DuiPopupList); + return d->itemModel; +} + +void DuiPopupList::setSelectionModel(QItemSelectionModel *selectionModel) +{ + if (selectionModel == NULL) return; + if (selectionModel->model() != itemModel()) { + qWarning("DuiPopupList::setSelectionModel() failed: " + "Trying to set a selection model, which works on " + "a different model than the view."); + return; + } + + Q_D(DuiPopupList); + + d->selectionModel = selectionModel; + emit selectionModelChanged(selectionModel); +} + +QItemSelectionModel *DuiPopupList::selectionModel() const +{ + Q_D(const DuiPopupList); + return d->selectionModel; +} + +int DuiPopupList::batchSize() const +{ + return model()->batchSize(); +} + +QModelIndex DuiPopupList::currentIndex() const +{ + Q_D(const DuiPopupList); + if (!d->selectionModel || !d->selectionModel->hasSelection()) + return QModelIndex(); + + return d->selectionModel->currentIndex(); +} + +void DuiPopupList::scrollTo(const QModelIndex &index) +{ + Q_D(DuiPopupList); + if (index.model() != d->itemModel) return; + emit scrollToIndex(index); +} + +void DuiPopupList::click(const QModelIndex &index) +{ + Q_D(DuiPopupList); + if (index.model() != d->itemModel) return; + + d->selectionModel->select(index, QItemSelectionModel::ClearAndSelect); + d->selectionModel->setCurrentIndex(index, QItemSelectionModel::Current); + + emit clicked(index); + emit currentIndexChanged(index); + + accept(); +} + +void DuiPopupList::setCurrentIndex(const QModelIndex &index) +{ + Q_D(DuiPopupList); + if (d->itemModel == NULL) + return; + + if (index.isValid() && d->selectionModel->model() != index.model()) { + qWarning("DuiPopupList::selectItem() failed: " + "Trying to select an item that is for" + " a different model than the view "); + return; + } + + // Since we didn't change the current index, no new signals should not send + if (index == currentIndex()) return; + + if (index.isValid()) { + d->selectionModel->select(index, QItemSelectionModel::ClearAndSelect); + d->selectionModel->setCurrentIndex(index, QItemSelectionModel::Current); + } else + d->selectionModel->clear(); + + emit currentIndexChanged(index); +} + +void DuiPopupList::setBatchSize(int size) +{ + if (size < MINBATCHSIZE) return; + model()->setBatchSize(size); +} + diff --git a/src/widgets/duipopuplist.h b/src/widgets/duipopuplist.h new file mode 100644 index 000000000..5d3de3d35 --- /dev/null +++ b/src/widgets/duipopuplist.h @@ -0,0 +1,242 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIPOPUPLIST_H +#define DUIPOPUPLIST_H + +#include "duidialog.h" +#include "duipopuplistmodel.h" +#include + +class DuiPopupListPrivate; +class DuiPannableViewport; +class QAbstractItemModel; +class QItemSelectionModel; + +/** + \class DuiPopupList + \brief DuiPopupList implements a popup list for the Dui Framework. + + \ingroup widgets + + DuiPopupList is providing limited number and predefined/system-defined set of values to the user, + among which the user can choose one option, the selected option is displayed to the user. + The alternatives in Popup list are mutually exclusive. + + DuiPopupList derived from DuiDialog. + + It makes heavy use of Qt's Interview Framework to move most code out of the view into in a model + to be implemented by the user. + + Use one of the various Qt convenience models if subclassing a model is not necessary. + + Currently, we expect the model to have only one level of depth, e.g. a table or list and not a tree model. + Qt's QComboBox can handle trees to by setting a root index but because writing tree models is more + complex and showing a sublist is a rather rare use case, API is kept simple and expects simple models. + + \section DuiPopupListUseGuidelines Usage guidelines + - Guidelines + - Popup list can be used if you have three or more items to display. + - In case you have less than 3 items, consider using toggle button. Usage of toggle button will save one finger press (= will save users time). + - In case you have more items, consider displaying your choices with other component than popup list. Possibly separate view. + - In case that you need to display dynamically changing item(s), popup list not good way to display the content. It is better to select dialog or some + other view that is capable of displaying a lot of content. By selecting one view for the user in all situations, you will make interactions to feel more + predictable. + - Popup list content items cannot be added or removed by the user. + - Popup list size: + - Popup list gets its size based on the longest popup list item. Very long labels inside the popup list will be truncated when device is rotated to portrait. + - Therefore it is important not to place too long popup list items inside the popup list. + - Suggested total width for the popup list button is 35-40% of landscape screen width. Label that can be placed inside is button area - popup icon - + borders around each visual element. + - Application defines popup list items. + - You can place inside the popup list similar objects as in list. + - Prefer labels that have approximately same length. + - Choices need to be mutually exclusive. + - Define default popup list value for the popup list. + - If you know safe choice or most often selected choice from the popup list, display that as default popuplist value. + - In case there is no default value, the prompt text is displayed as popup list value. + - Define the order of the popup list items. Use some logical order such as from A to Z, or time-based order. + - Define the location for the popup list. + + \section DuiPopupListExampleCodes Example codes + If you just want the user to pick from a list of strings, use QStringListModel like: + + \code + DuiPopupList *popuplist = new DuiPopupList(); + QStringListModel *model = new QStringListModel(this); + QStringList stringList; + stringList << "Item 1" << "Item 2"; + model->setStringList(stringList); + popuplist->setItemModel(model); + popuplist->appear(); + \endcode + + \sa DuiPopupListModel DuiPopupListStyle + */ + +class DUI_EXPORT DuiPopupList : public DuiDialog +{ + + Q_OBJECT + DUI_CONTROLLER(DuiPopupList) + + /** + \property DuiPopupList::batchSize + \brief See DuiPopupListModel::batchSize + */ + Q_PROPERTY(int batchSize READ batchSize WRITE setBatchSize) + +public: + + /** + Constructs a new popuplist with no content + */ + DuiPopupList(); + + /** + Destroys the popuplist. + */ + virtual ~DuiPopupList(); + + /** + Sets the item model \a model as the new datasource + for the PopupList. If you do not want to write + your own model, use QStringList model as + a convenience adapter + + DuiPopupList does not take ownership of the model. + It is up the caller to ensure that it will be + deleted. If the model is replaced, it is up to the + caller to ensure the previous model is not leaked + + @arg model The model to use as a new datasource + */ + virtual void setItemModel(QAbstractItemModel *itemModel); + + /** + Returns the model that this PopupList is presenting. + */ + QAbstractItemModel *itemModel() const; + + /** + Sets the current selection model to the given \a selectionModel. + + Note that, if you call setItemModel() after this function, the given \a selectionModel + will be replaced by one created by the view. + + \note It is up to the application to delete the old selection model if it is no + longer needed; i.e., if it is not being used by other views. This will happen + automatically when its parent object is deleted. However, if it does not have a + parent, or if the parent is a long-lived object, it may be preferable to call its + deleteLater() function to explicitly delete it. + + \sa selectionModel(), setItemModel(), clearSelection() + */ + virtual void setSelectionModel(QItemSelectionModel *selectionModel); + + /** + Returns the current selection model. + \sa setSelectionModel() + */ + QItemSelectionModel *selectionModel() const; + + /** + \brief Returns the items size which created inside popuplist. + */ + int batchSize() const; + + /** + Scrolls the view if necessary to ensure that the item at \a index is visible. + */ + virtual void scrollTo(const QModelIndex &index); + + /** + Return the model index of the item that is currently being + shown as the selected item + * + @return the current item model index or invalid QModelIndex + */ + QModelIndex currentIndex() const; + +public Q_SLOTS: + + /** + \brief Performs a click + All the usual signals associated with a click are emitted as appropriate. + */ + void click(const QModelIndex &index); + + /** + Select the given item, deselecting all others. + This is equivalent to: + \code + selectionModel()->select(index, QItemSelectionModel::ClearAndSelect) + \endcode + If index is not valid, the current selection is cleared + */ + void setCurrentIndex(const QModelIndex &index); + + /** + \brief Set the item size which created inside popuplist. + */ + void setBatchSize(int); + +Q_SIGNALS: + + /** + This signal is emitted when the item model has changed. + */ + void itemModelChanged(QAbstractItemModel *); + + /** + This signal is emitted when the selection model has changed. + */ + void selectionModelChanged(QItemSelectionModel *); + + /** + This signal is emitted when the item is clicked. + */ + void clicked(const QModelIndex &index); + + /** + This signal is emitted when the current selected item is changed. + */ + void currentIndexChanged(QModelIndex index); + + /** + This signal is emitted when scrollTo(index) is called to tell the view to scroll to the given item index. + */ + void scrollToIndex(const QModelIndex &index); + +protected: + + //! \cond + DuiPopupList(DuiPopupListPrivate *dd, DuiPopupListModel *model, DuiSceneWindow::WindowType windowType); + //! \endcond + +private: + Q_DECLARE_PRIVATE(DuiPopupList) + Q_DISABLE_COPY(DuiPopupList) + + friend class DuiPopupListView; + friend class DuiPopupListViewPrivate; +}; + +#endif + diff --git a/src/widgets/duipopuplist_p.h b/src/widgets/duipopuplist_p.h new file mode 100644 index 000000000..3bd553c0f --- /dev/null +++ b/src/widgets/duipopuplist_p.h @@ -0,0 +1,41 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIPOPUPLIST_P_H +#define DUIPOPUPLIST_P_H + +#include "duidialog_p.h" +#include + +class QAbstractItemModel; +class QItemSelectionModel; + +class DuiPopupListPrivate : public DuiDialogPrivate +{ + +public: + Q_DECLARE_PUBLIC(DuiPopupList) + DuiPopupListPrivate(); + virtual ~DuiPopupListPrivate(); + + QAbstractItemModel *itemModel; + QPointer selectionModel; +}; + +#endif diff --git a/src/widgets/duipopuplistmodel.h b/src/widgets/duipopuplistmodel.h new file mode 100644 index 000000000..9c950f719 --- /dev/null +++ b/src/widgets/duipopuplistmodel.h @@ -0,0 +1,47 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIPOPUPLISTMODEL_H +#define DUIPOPUPLISTMODEL_H + +#include "duidialogmodel.h" + +/*! + \class DuiPopupListModel + \brief Data model class for DuiPopupList. + + \ingroup models + \sa DuiPopupListModel +*/ + +class DUI_EXPORT DuiPopupListModel : public DuiDialogModel +{ + Q_OBJECT + DUI_MODEL_INTERNAL(DuiPopupListModel) + + /*! + \property DuiPopupListModel::batchSize + \brief This property holds the number of items laid out in each batch. + The default value is 20. + */ + DUI_MODEL_PROPERTY(int, batchSize, BatchSize, true, 20) + +}; + +#endif diff --git a/src/widgets/duipositionindicator.cpp b/src/widgets/duipositionindicator.cpp new file mode 100644 index 000000000..7e66c927c --- /dev/null +++ b/src/widgets/duipositionindicator.cpp @@ -0,0 +1,74 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include "duipositionindicator.h" +#include "duipositionindicator_p.h" +#include "duipositionindicatorview.h" + +#include "duiwidgetcreator.h" +DUI_REGISTER_WIDGET(DuiPositionIndicator) + +DuiPositionIndicator::DuiPositionIndicator(QGraphicsItem *parent) + : DuiWidgetController(new DuiPositionIndicatorModel, parent) +{ + setAcceptedMouseButtons(0); +} + +DuiPositionIndicator::DuiPositionIndicator(DuiPositionIndicatorPrivate* /*dd*/, DuiPositionIndicatorModel *model, + QGraphicsItem *parent) + : DuiWidgetController(NULL, model, parent) +{ + setAcceptedMouseButtons(0); +} + +DuiPositionIndicator::~DuiPositionIndicator() +{ +} + +QSizeF DuiPositionIndicator::viewportSize() const +{ + return model()->viewportSize(); +} + +QRectF DuiPositionIndicator::pannedRange() const +{ + return model()->pannedRange(); +} + +QPointF DuiPositionIndicator::pannedPos() const +{ + return model()->pannedPos(); +} + +void DuiPositionIndicator::updateSizePosData(const QSizeF &viewportSize, const QRectF &pannedRange, const QPointF &pannedPos) +{ + if (this->viewportSize() != viewportSize) { + model()->setViewportSize(viewportSize); + } + + if (this->pannedRange() != pannedRange) { + model()->setPannedRange(pannedRange); + } + + if (this->pannedPos() != pannedPos) { + model()->setPannedPos(pannedPos); + } +} + diff --git a/src/widgets/duipositionindicator.h b/src/widgets/duipositionindicator.h new file mode 100644 index 000000000..44f50a8a1 --- /dev/null +++ b/src/widgets/duipositionindicator.h @@ -0,0 +1,106 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIPOSITIONINDICATOR_H +#define DUIPOSITIONINDICATOR_H + + +#include "duiwidgetcontroller.h" +#include + +class DuiPositionIndicatorPrivate; + +/*! + * \class DuiPositionIndicator + * + * \brief DuiPositionIndicator visualizes a position indicator. It is + * typically used by DuiPannableViewport (which automatically creates + * one) to show the panning position but works also separately. + * + * The size of DuiPositionIndicator is set by the layout it is in but + * it only draws on the area near the edges of its area. + * + * DuiPositionIndicator has a slot updateSizePosData() which needs to + * be called when size of viewport, panned area inside the viewport or + * panning position changes. + * + * DuiPositionIndicator is a non-interactive widget. It only shows the + * current position, and it doesn't react to mouse events. +*/ + + +class DUI_EXPORT DuiPositionIndicator : public DuiWidgetController +{ + Q_OBJECT + + DUI_CONTROLLER(DuiPositionIndicator) + + Q_PROPERTY(QSizeF viewportSize READ viewportSize) + Q_PROPERTY(QRectF pannedRange READ pannedRange) + Q_PROPERTY(QPointF pannedPos READ pannedPos) + +public: + /*! + * \brief Constructs a DuiPositionIndicator with the specified + * panning direction and \a parent. + */ + DuiPositionIndicator(QGraphicsItem *parent = 0); + + /*! + * Destructs the DuiPositionIndicator. + */ + virtual ~DuiPositionIndicator(); + + /*! + * \brief Returns the latest stored size information of the + * pannable viewport to which the position indicator is attached + * to. + */ + QSizeF viewportSize() const; + + /*! + * \brief Returns the latest stored size of the panned range + * (normally the size of the widget that is being panned, see + * DuiPannableViewport). + */ + QRectF pannedRange() const; + + /*! + * \brief Returns the latest stored current position of the panned + * widget. + */ + QPointF pannedPos() const; + +public Q_SLOTS: + + /*! + * \brief Updates the size and position data. + */ + void updateSizePosData(const QSizeF &viewportSize, const QRectF &pannedRange, const QPointF &pannedPos); + +protected: + + DuiPositionIndicator(DuiPositionIndicatorPrivate *dd, DuiPositionIndicatorModel *model, QGraphicsItem *parent); + +private: + Q_DECLARE_PRIVATE(DuiPositionIndicator) + Q_DISABLE_COPY(DuiPositionIndicator) +}; + +#endif diff --git a/src/widgets/duipositionindicator_p.h b/src/widgets/duipositionindicator_p.h new file mode 100644 index 000000000..5433bb748 --- /dev/null +++ b/src/widgets/duipositionindicator_p.h @@ -0,0 +1,26 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIPOSITIONINDICATOR_P_H +#define DUIPOSITIONINDICATOR_P_H + +#include "private/duiwidgetcontroller_p.h" + +#endif + diff --git a/src/widgets/duipositionindicatormodel.h b/src/widgets/duipositionindicatormodel.h new file mode 100644 index 000000000..e5dc37749 --- /dev/null +++ b/src/widgets/duipositionindicatormodel.h @@ -0,0 +1,41 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIPOSITIONINDICATORMODEL_H +#define DUIPOSITIONINDICATORMODEL_H + +#include + +#include +#include +#include +#include + +class DUI_EXPORT DuiPositionIndicatorModel : public DuiWidgetModel +{ + Q_OBJECT + DUI_MODEL_INTERNAL(DuiPositionIndicatorModel) + + DUI_MODEL_PROPERTY(QSizeF, viewportSize, ViewportSize, true, QSizeF()) + DUI_MODEL_PROPERTY(QRectF, pannedRange, PannedRange, true, QRectF()) + DUI_MODEL_PROPERTY(QPointF, pannedPos, PannedPos, true, QPointF()) +}; + +#endif + diff --git a/src/widgets/duiprogressindicator.cpp b/src/widgets/duiprogressindicator.cpp new file mode 100644 index 000000000..1f69bc091 --- /dev/null +++ b/src/widgets/duiprogressindicator.cpp @@ -0,0 +1,135 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include + +#include "duiprogressindicator.h" +#include "duiprogressindicator_p.h" + +#include "duiwidgetcreator.h" +DUI_REGISTER_WIDGET(DuiProgressIndicator) + +const DuiTheme::ViewType DuiProgressIndicator::spinnerType = "spinner"; +const DuiTheme::ViewType DuiProgressIndicator::barType = "bar"; + + +DuiProgressIndicatorPrivate::DuiProgressIndicatorPrivate() +{ +} + +DuiProgressIndicatorPrivate::~DuiProgressIndicatorPrivate() +{ +} + +void DuiProgressIndicatorPrivate::init() +{ +} + +DuiProgressIndicator::DuiProgressIndicator(DuiProgressIndicatorPrivate *dd, DuiProgressIndicatorModel *model, QGraphicsItem *parent) + : DuiWidgetController(dd, model, parent) +{ + Q_D(DuiProgressIndicator); + + d->init(); +} + +DuiProgressIndicator::DuiProgressIndicator(QGraphicsItem *parent, const QString &viewType) + : DuiWidgetController(new DuiProgressIndicatorPrivate, new DuiProgressIndicatorModel, parent) +{ + setViewType(viewType); + Q_D(DuiProgressIndicator); + + d->init(); +} + +DuiProgressIndicator::~DuiProgressIndicator() +{ +} + + +void DuiProgressIndicator::reset() +{ + setValue(minimum()); + setUnknownDuration(false); +} + + +void DuiProgressIndicator::setRange(int minimum, int maximum) +{ + model()->setMinimum(minimum); + model()->setMaximum(qMax(minimum, maximum)); + if (model()->value() < model()->minimum() || model()->value() > model()->maximum()) + reset(); +} + +void DuiProgressIndicator::setValue(int value) +{ + if (model()->value() == value) + return; + + if ((value > model()->maximum()) || (value < model()->minimum())) + return; + + model()->setValue(value); + emit valueChanged(value); +} + +int DuiProgressIndicator::value() const +{ + return model()->value(); +} + + +void DuiProgressIndicator::setMinimum(int minimum) +{ + setRange(minimum, qMax(maximum(), minimum)); +} + + +int DuiProgressIndicator::minimum() const +{ + return model()->minimum(); +} + + +void DuiProgressIndicator::setMaximum(int maximum) +{ + setRange(qMin(minimum(), maximum), maximum); +} + + +int DuiProgressIndicator::maximum() const +{ + return model()->maximum(); +} + + +void DuiProgressIndicator::setUnknownDuration(bool unknownDuration) +{ + model()->setUnknownDuration(unknownDuration); +} + + +bool DuiProgressIndicator::unknownDuration() const +{ + return model()->unknownDuration(); +} + + + diff --git a/src/widgets/duiprogressindicator.h b/src/widgets/duiprogressindicator.h new file mode 100644 index 000000000..b8c8d82b4 --- /dev/null +++ b/src/widgets/duiprogressindicator.h @@ -0,0 +1,223 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIPROGRESSINDICATOR_H +#define DUIPROGRESSINDICATOR_H + +#include "duiwidgetcontroller.h" +#include + +class DuiProgressIndicatorPrivate; + +/*! + \class DuiProgressIndicator + \brief Progress indicators are used to visualize graphically the current status of an operation. + + \ingroup widgets + + \tableofcontents + \section DuiProgressIndicatorOverview Overview + Progress indicator can have known or unknown duration. + + \section ProgressIndicatorUseGuidelines Usage guidelines + \li For operations with known duration use progress indicator with known duration. + \li For operations with unknown duration use progress indicator with unknown duration. + \li Application design can decide whether to show progress indicator for the whole view + (e.g. a web page in web browser) or for single items in the view separately + (e.g. downloading online photos from Flickr web feed in Gallery). + \li Application can decide to display label indicating the state of the operation next to indicator such as + "124 / 345 kt received." or "75%". + \li If the wait operation applies to the whole view, a spinner should be used to temporarily replace the view's + view menu icon. + + \section ProgressIndicatorVariants Variants + \li \link DuiProgressIndicatorBarView Progress bar \endlink + \li \link DuiProgressIndicatorCircularView Spinner \endlink + +\section DuiProgressIndicatorExamples Examples + Here's how to create progress bar with fixed range. It also shows how to listen the value changed signal: + \code + DuiProgressIndicator* progressbar = new DuiProgressIndicator(parent, DuiProgressIndicator::barType); + progressbar->setRange(0, 9); + connect(progressbar, SIGNAL(valueChanged(int)), SLOT(valueChangedSlot(int))); + \endcode + + This is how to create spinner with unknown duration: + \code + DuiProgressIndicator* spinner = new DuiProgressIndicator(parent, DuiProgressIndicator::spinnerType); + spinner->setRunUnknown(true); + \endcode + + \section ProgressIndicatorOpenIssues Open issues + \li How we can utilize device sensors together with progress indicators to create small WOW effects? + \li Progress indicator visualization can be generated procedurally using the device sensors, + for example by tilting the device liquid/sand inside the progress indicator moves while the + indicator still shows the current status of the operation. How to? Depends on the selected type + of the indicator. + \li Operation duration + haptic feedback: after the indicator has been shown for long enough + (current assumption: 8 seconds), a tacticon (=small vibra indicator) should be presented + when the indicator goes away. This enables the user to turn his/her attention back on the + device when it becomes usable again. + + \sa DuiProgressIndicatorModel DuiProgressIndicatorStyle +*/ + +class DUI_EXPORT DuiProgressIndicator : public DuiWidgetController +{ + Q_OBJECT + DUI_CONTROLLER(DuiProgressIndicator) + + /*! + \property DuiProgressIndicator::minimum + \brief This property holds the progress indicator's minimum value. + + When setting this property, the \l maximum is adjusted if necessary to ensure that the range remains + valid. If the current value falls outside the new range, the progress bar is reset with reset(). + */ + Q_PROPERTY(int minimum READ minimum WRITE setMinimum) + + /*! + \property DuiProgressIndicator::maximum + \brief This property holds the progress indicator's maximum value. + + When setting this property, the \l minimum is adjusted if necessary to ensure that the range remains + valid. If the current value falls outside the new range, the progress bar is reset with reset(). + */ + Q_PROPERTY(int maximum READ maximum WRITE setMaximum) + + /*! + \property DuiProgressIndicator::value + \brief This property holds the progress indicator's current value. + + Attempting to change the current value to one outside the minimum-maximum range has no effect on the + current value. + */ + Q_PROPERTY(int value READ value WRITE setValue NOTIFY valueChanged) + + /*! + \property DuiProgressIndicator::unknownDuration + \brief This property holds whether the progress indicator is type of known duration / unknown duration. + */ + Q_PROPERTY(bool unknownDuration READ unknownDuration WRITE setUnknownDuration) + +public: + + /*! + \var DuiProgressIndicator::spinnerType + \brief View type for spinner. + */ + static const DuiTheme::ViewType spinnerType; + /*! + \var DuiProgressIndicator::barType + \brief View type for progress bar. + */ + static const DuiTheme::ViewType barType; + + /*! + \brief Constructs a progress indicator with a \a parent. + \param parent Parent widget + \param viewType Optional Associated view + */ + explicit DuiProgressIndicator(QGraphicsItem *parent = 0, const QString &viewType = QString()); + + /*! + \brief Destructor + */ + virtual ~DuiProgressIndicator(); + + /*! + \brief Returns the maximum value of the progress indicator. + \return Maximum value of the progress indicator + */ + int maximum() const; + + /*! + \brief Returns the minimum value of the progress indicator. + \return Minimum value of the progress indicator + */ + int minimum() const; + + /*! + \brief Returns the value of the progress indicator. + \return Value of the progress indicator + */ + int value() const; + + /*! + \brief Status of indicating progress with unknown duration. + \return True, if indicator is running in unknown duration mode + */ + bool unknownDuration() const; + +Q_SIGNALS: + + /*! + \brief Signal is emitted when the value of the indicator changes. + */ + void valueChanged(int value); + +public Q_SLOTS: + + /*! + \brief Rewinds the indicator and stops unknown duration indicator. + */ + void reset(); + + /*! + \brief Set the \a maximum value of the indicator. + */ + void setMaximum(int maximum); + + /*! + \brief Set the \a minimum value of the indicator. + */ + void setMinimum(int minimum); + + /*! + \brief Sets the progress bar's minimum and maximum values to minimum and maximum respectively. + If maximum is smaller than minimum, minimum becomes the only legal value. + If the current value falls outside the new range, the progress bar is reset with reset(). + */ + void setRange(int minimum, int maximum); + + /*! + \brief Set the \a value of the indicator. + Attempting to change the current value to one outside the minimum-maximum range has no effect on the current value. + \param value indicator value + */ + void setValue(int value); + + /*! + \brief Sets whether the indicator is working in known duration / unknown duration mode. + \param run True, to set the progress indicator to unknown duration mode + */ + void setUnknownDuration(bool unknownDuration); + +protected: + //! \cond + DuiProgressIndicator(DuiProgressIndicatorPrivate *dd, DuiProgressIndicatorModel *model, QGraphicsItem *parent); + //! \endcond + +private: + Q_DECLARE_PRIVATE(DuiProgressIndicator) + Q_DISABLE_COPY(DuiProgressIndicator) + friend class Ut_DuiProgressIndicator; +}; + +#endif diff --git a/src/widgets/duiprogressindicator_p.h b/src/widgets/duiprogressindicator_p.h new file mode 100644 index 000000000..81837d08b --- /dev/null +++ b/src/widgets/duiprogressindicator_p.h @@ -0,0 +1,37 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIPROGRESSINDICATOR_P_H +#define DUIPROGRESSINDICATOR_P_H + +#include "private/duiwidgetcontroller_p.h" +class DuiStyle; + +class DuiProgressIndicatorPrivate : protected DuiWidgetControllerPrivate +{ +public: + Q_DECLARE_PUBLIC(DuiProgressIndicator) + DuiProgressIndicatorPrivate(); + virtual ~DuiProgressIndicatorPrivate(); + + void init(); + +}; + +#endif diff --git a/src/widgets/duiprogressindicatormodel.h b/src/widgets/duiprogressindicatormodel.h new file mode 100644 index 000000000..f7607d8ff --- /dev/null +++ b/src/widgets/duiprogressindicatormodel.h @@ -0,0 +1,64 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIPROGRESSINDICATORMODEL_H +#define DUIPROGRESSINDICATORMODEL_H + +#include + +/*! + \class DuiProgressIndicatorModel + \brief This is the data model class for progress indicator. + + \ingroup models + \sa DuiProgressIndicator +*/ + +class DUI_EXPORT DuiProgressIndicatorModel : public DuiWidgetModel +{ + Q_OBJECT + DUI_MODEL_INTERNAL(DuiProgressIndicatorModel) + + /*! + * \property DuiProgressIndicatorModel::value + * \brief This property holds the progress indicator's current value. + */ + DUI_MODEL_PROPERTY(int, value, Value, true, 0) + + /*! + * \property DuiProgressIndicatorModel::minimum + * \brief This property holds the progress indicator's minimum value. + */ + DUI_MODEL_PROPERTY(int, minimum, Minimum, true, 0) + + /*! + * \property DuiProgressIndicatorModel::maximum + * \brief This property holds the progress indicator's maximum value. + */ + DUI_MODEL_PROPERTY(int, maximum, Maximum, true, 100) + + /*! + * \property DuiProgressIndicatorModel::unknownDuration + * \brief This property holds whether the progress indicator is type of known duration / unknown duration. + */ + DUI_MODEL_PROPERTY(bool, unknownDuration, UnknownDuration, true, false) +}; + +#endif + diff --git a/src/widgets/duiscenelayereffectmodel.h b/src/widgets/duiscenelayereffectmodel.h new file mode 100644 index 000000000..443f89cd0 --- /dev/null +++ b/src/widgets/duiscenelayereffectmodel.h @@ -0,0 +1,33 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISCENELAYEREFFECTMODEL_H +#define DUISCENELAYEREFFECTMODEL_H + +#include + +class DUI_EXPORT DuiSceneLayerEffectModel : public DuiSceneWindowModel +{ + Q_OBJECT + DUI_MODEL_INTERNAL(DuiSceneLayerEffectModel) + + DUI_MODEL_PROPERTY(bool, enabled, Enabled, true, false) +}; + +#endif diff --git a/src/widgets/duiscenewindow.cpp b/src/widgets/duiscenewindow.cpp new file mode 100644 index 000000000..e9375ea67 --- /dev/null +++ b/src/widgets/duiscenewindow.cpp @@ -0,0 +1,251 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include "duiscenewindow.h" +#include "duiscenewindowmodel.h" +#include "duiscenewindow_p.h" +#include "duiscene.h" +#include "duiscenemanager.h" +#include "duiscenemanager_p.h" +#include "duiapplication.h" +#include "duiscenewindowview.h" +#include "duiwindow.h" + +#include "duiwidgetcreator.h" +DUI_REGISTER_WIDGET_NO_CREATE(DuiSceneWindow) + +DuiSceneWindowPrivate::DuiSceneWindowPrivate() +{ + managedManually = false; + shown = false; + dismissed = false; + policy = DuiSceneWindow::KeepWhenDone; + effect = NULL; +} + +void DuiSceneWindowPrivate::appear(bool now, DuiWindow *window, DuiSceneWindow::DeletionPolicy policy) +{ + Q_Q(DuiSceneWindow); + + if (!window) { + window = DuiApplication::activeWindow(); + if (!window) { + // TODO: Create and show() a Dui[Application]Window on the fly? + duiWarning("DuiSceneWindow") + << "Construct and show DuiWindow before showing a scene window"; + return; + } + } + + if (now) { + window->sceneManager()->showWindowNow(q, policy); + } else { + window->sceneManager()->showWindow(q, policy); + } +} + +DuiSceneWindow::DuiSceneWindow(QGraphicsItem *parent) : + DuiWidgetController(new DuiSceneWindowPrivate, new DuiSceneWindowModel, parent) +{ + Q_D(DuiSceneWindow); + + d->windowType = PlainSceneWindow; +} + +bool DuiSceneWindowPrivate::dismiss(bool now) +{ + Q_Q(DuiSceneWindow); + + /* ABI FREEZE: Release this + DuiDismissEvent dismissEvent; + QApplication::sendEvent(q, &dismissEvent); + + if (!dismissEvent.isAccepted()) { + return false; + } + */ + + if (q->sceneManager()) { + if (now) { + q->sceneManager()->closeWindowNow(q); + } else { + q->sceneManager()->closeWindow(q); + } + } + + return true; +} + + +DuiSceneWindow::DuiSceneWindow(DuiSceneWindowPrivate *dd, DuiSceneWindowModel *model, DuiSceneWindow::WindowType windowType, const QString &viewType, QGraphicsItem *parent) : + DuiWidgetController(dd, model, parent) +{ + Q_D(DuiSceneWindow); + setViewType(viewType); + + d->windowType = windowType; +} + +DuiSceneWindow::~DuiSceneWindow() +{ + if (sceneManager()) + sceneManager()->d_func()->detachWindow(this); +} + +DuiSceneWindow::WindowType DuiSceneWindow::windowType() const +{ + Q_D(const DuiSceneWindow); + return d->windowType; +} + +DuiSceneWindow::DeletionPolicy DuiSceneWindow::deletionPolicy() const +{ + Q_D(const DuiSceneWindow); + return d->policy; +} + +bool DuiSceneWindow::isManagedManually() const +{ + Q_D(const DuiSceneWindow); + return d->managedManually; +} + +void DuiSceneWindow::setManagedManually(bool managedManually) +{ + Q_D(DuiSceneWindow); + d->managedManually = managedManually; +} + +void DuiSceneWindow::appear(DuiWindow *window, DuiSceneWindow::DeletionPolicy policy) +{ + Q_D(DuiSceneWindow); + d->appear(false, window, policy); +} + +void DuiSceneWindow::appearNow(DuiWindow *window, DuiSceneWindow::DeletionPolicy policy) +{ + Q_D(DuiSceneWindow); + d->appear(true, window, policy); +} + +void DuiSceneWindow::appear(DuiSceneWindow::DeletionPolicy policy) +{ + Q_D(DuiSceneWindow); + d->appear(false, 0, policy); +} + +void DuiSceneWindow::appearNow(DuiSceneWindow::DeletionPolicy policy) +{ + Q_D(DuiSceneWindow); + d->appear(true, 0, policy); +} + +void DuiSceneWindow::disappear() +{ + if (sceneManager()) + sceneManager()->hideWindow(this); +} + +void DuiSceneWindow::disappearNow() +{ + if (sceneManager()) + sceneManager()->hideWindowNow(this); +} + +Qt::Alignment DuiSceneWindow::alignment() const +{ + Qt::Alignment result = 0; + + if (view()) { + const DuiSceneWindowView *sceneWindowView = + qobject_cast(view()); + + if (sceneWindowView) { + result = sceneWindowView->alignment(); + } + } + + if (layoutDirection() == Qt::RightToLeft) { + if (result.testFlag(Qt::AlignLeft)) { + result &= ~Qt::AlignLeft; + result |= Qt::AlignRight; + } else if (result.testFlag(Qt::AlignRight)) { + result &= ~Qt::AlignRight; + result |= Qt::AlignLeft; + } + } + + return result; +} + +QPointF DuiSceneWindow::offset() const +{ + QPointF result; + + if (view()) { + const DuiSceneWindowView *sceneWindowView = + qobject_cast(view()); + + if (sceneWindowView) { + result = sceneWindowView->offset(); + } + } else { + result = QPointF(0, 0); + } + + return result; +} + +bool DuiSceneWindow::dismiss() +{ + Q_D(DuiSceneWindow); + return d->dismiss(false); +} + +bool DuiSceneWindow::dismissNow() +{ + Q_D(DuiSceneWindow); + return d->dismiss(true); +} + +/* ABI FREEZE: Release this +void DuiSceneWindow::dismissEvent(DuiDismissEvent *event) +{ + event->accept(); +} +*/ + +void DuiSceneWindow::closeEvent(QCloseEvent *event) +{ + event->ignore(); + dismiss(); +} + +bool DuiSceneWindow::event(QEvent *event) +{ + /* ABI FREEZE: Release this + if (event->type() == DuiDismissEvent::eventType()) { + dismissEvent(static_cast(event)); + } + */ + + return DuiWidgetController::event(event); +} diff --git a/src/widgets/duiscenewindow.h b/src/widgets/duiscenewindow.h new file mode 100644 index 000000000..9fbe0d153 --- /dev/null +++ b/src/widgets/duiscenewindow.h @@ -0,0 +1,294 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISCENEWINDOW_H +#define DUISCENEWINDOW_H + +#include +#include + +class DuiDismissEvent; +class DuiWindow; +class DuiSceneWindowPrivate; + +/*! + * \class DuiSceneWindow + * \brief DuiSceneWindow objects are the base graphical items in a Direct UI scene. + * + * All graphical components of a standard Direct UI application are held in + * a DuiSceneWindow of some type. DuiSceneWindow instances form the base + * level of a Direct UI application's scene graph. + * + * DuiSceneWindows in a DuiScene are analogous to top level windows in a + * traditional windowing system. + * + * The actual size and position of a DuiSceneWindow are by default managed by + * DuiSceneManager according to DuiSceneWindowStyle properties. If you want to + * manually resize and position a DuiSceneWindow you have to explicitly set + * the managedManually property to true. + * + * \sa DuiSceneManager + */ +class DUI_EXPORT DuiSceneWindow : public DuiWidgetController +{ + Q_OBJECT + DUI_CONTROLLER(DuiSceneWindow) + + Q_PROPERTY(bool managedManually READ isManagedManually WRITE setManagedManually) + +public: + /*! + * This enum defines how to handle scene window after hiding it using disappear() or disappearNow(). + */ + enum DeletionPolicy { + KeepWhenDone, //!< Window is kept alive after being dismissed or disappeared + DestroyWhenDone, //!< Window is destroyed after being dismissed or disappeared + DestroyWhenDismissed //!< Window is destroyed after being dismissed + }; + + /*! + * Defines multiple window types which will have different Z value + */ + enum WindowType { + ApplicationPage = 0, // DuiApplicationPage + NavigationBar, // DuiNavigationBar + EscapeButtonPanel, // DuiEscapeButtonPanel + DockWidget, // DuiDockWidget + LayerEffect, // DuiSceneLayerEffect + Dialog, // DuiDialog + MessageBox, // DuiMessageBox + ApplicationMenu, // DuiApplicationMenu + ObjectMenu, // DuiObjectMenu + ModalSceneWindow, // DuiModalSceneWindow + PopupList, // DuiPopupList + NotificationInformation, // DuiNotification - Information + NotificationEvent, // DuiNotification - Event + Overlay, // DuiOverlay + Completer, // DuiCompleter + HomeButtonPanel, // DuiHomeButtonPanel + PlainSceneWindow // DuiSceneWindow + }; + + /*! + * Creates an empty scene window. It's a fullscreen container of the + * lowest Z value, that can be a parent for its child widgets and layouts. + * \note You normally wouldn't want to instantiate this class directly and + * instead use one of the provided subclasses. + */ + explicit DuiSceneWindow(QGraphicsItem *parent = 0); + + /*! + * Destructor of the DuiSceneWindow class. + */ + virtual ~DuiSceneWindow(); + +public Q_SLOTS: + /*! + * Shows the scene window on the window specified by \a window and registers + * it in the associated DuiSceneManager. Uses animation to show the window. + * \param window The window on which the scene window is going to be shown. + * \param policy Deletion policy, defines the ownership for this window + * + * \sa appearNow() + */ + virtual void appear(DuiWindow *window, DuiSceneWindow::DeletionPolicy policy = KeepWhenDone); + + /*! + * Shows the scene window on the window specified by \a window and registers + * it in the associated DuiSceneManager. Doesn't use the animation to show the window. + * \param window The window on which the scene window is going to be shown. + * \param policy Deletion policy, defines the ownership for this window + * + * \sa appear() + */ + virtual void appearNow(DuiWindow *window, DuiSceneWindow::DeletionPolicy policy = KeepWhenDone); + + /*! + * Shows the scene window on the currently active window and registers + * it in the associated DuiSceneManager. Uses the animation to show the window. + * \param policy Deletion policy, defines the ownership for this window + * + * \sa appearNow(), DuiApplication::activeWindow() + */ + virtual void appear(DuiSceneWindow::DeletionPolicy policy = KeepWhenDone); + + /*! + * Shows the scene window on the currently active window and registers + * it in the associated DuiSceneManager. Doesn't use the animation to show the window. + * \param policy Deletion policy, defines the ownership for this window + * + * \sa appear(), DuiApplication::activeWindow() + */ + virtual void appearNow(DuiSceneWindow::DeletionPolicy policy = KeepWhenDone); + + /*! + * Hides this window and unregisters it from the DuiSceneManager. + * Uses the associated animation to hide the window. + * + * \sa disappearNow() + */ + virtual void disappear(); + + /*! + * Hides this window and unregisters it from the DuiSceneManager. + * Doesn't use the animation to hide the window. + * + * \sa disappear() + */ + virtual void disappearNow(); + + /* ! + * \brief Dismisses the scene window. + * + * Returns true if the scene window was dismissed; otherwise returns false. + * This slot will first send a DuiDismissEvent to the widget, which may or may + * not accept the event. If the event was ignored, nothing happens. If the event + * was accepted, it will disappear() the scene window. + * + * If DestroyWhenDone was used on the last appear() or appearNow() call and + * the event was accepted, the scene window will be deleted after its + * disappearance is finished. + * + * Please refer to DuiDismissEvent documentation for more information. + * + * \sa dismissNow(), dismissEvent(), disappear(), deleteWhenDone() + */ + bool dismiss(); + + /* ! + * \brief Dismisses the scene window immediately. + * + * Same as dismiss() differing only that it will cause disappearNow() to be called + * if event is accepted instead of disappear() + * + * \sa dismiss(), disappearNow() + */ + bool dismissNow(); + +public: + /*! + * Returns the currently active deletion policy of this window. + * \return Deletion policy of this window, KeepWhenDone as a default. + * \sa DeletionPolicy + */ + DeletionPolicy deletionPolicy() const; + + /*! + * Returns the window type. + * \sa WindowType + */ + DuiSceneWindow::WindowType windowType() const; + + /*! + * Returns true if window is managed manually, i.e. + * scene manager doesn't care about its size and + * position. Default value is false, i.e. window + * is resized and positioned inside the scene by + * the scene manager, according to its style attributes. + */ + bool isManagedManually() const; + + /*! + * Allows to explicitly enable/disable manual management + * of the size and position of the window by the scene manager. + * Manual management is disabled by default, letting + * the scene manager adjust size and position of the window + * accorting to its style attributes. If manual management + * is enabled, the window can be positioned using e.g. resize(), + * setPos() and/or setGeometry() and it's responsible itself for + * proper adjusting its geometry when viewport orientation changes. + */ + void setManagedManually(bool managedManually); + +Q_SIGNALS: + /*! + \brief Emitted when the show animation of the scene window has been finished. + */ + // TODO: check if these should be transferred to DuiWidgetController + // as the showAnimation and hideAnimation are stored in there. + void windowShown() const; + + /*! + \brief windowHidden() signal is emitted when the hide animation of the scene window has been finished. + */ + void windowHidden() const; + + /*! + * \brief Emitted when window's style attributes have changed + * and it needs to be repositioned by the scene manager. + */ + void repositionNeeded(); + +protected: + //! \internal + DuiSceneWindow(DuiSceneWindowPrivate *dd, DuiSceneWindowModel *model, + DuiSceneWindow::WindowType windowType, + const QString &viewType = QString(""), QGraphicsItem *parent = 0); + //! \internal_end + + /*! + * \brief Returns the current alignment. + * Alignment defines how scene manager will position the window on the screen. + * This property has no effect if the window is being managed manually. + * \sa isManagedManually() + * \returns The current alignment. + */ + Qt::Alignment alignment() const; + + /*! + * \brief Returns the current offset. + * \returns The current offset. + */ + QPointF offset() const; + + /* Add ! here + * \brief Event handler for DuiDismissEvent + * + * This event handler can be reimplemented in a subclass to receive scene window + * dismiss events. The default implementation accepts the \a event. + * + * \sa dismiss() + */ + /* ABI FREEZE: Release this + virtual void dismissEvent(DuiDismissEvent *event); + */ + + /*! + * Default implementation calls dismiss() and ignores the event. + * Reimplement in a subclass to specify a different behavior + * \sa QGraphicsWidget::closeEvent() + */ + virtual void closeEvent(QCloseEvent *event); + + //! \reimp + virtual bool event(QEvent *e); + //! \reimp_end + +private: + Q_DECLARE_PRIVATE(DuiSceneWindow) + + friend class DuiSceneWindowView; + friend class DuiSceneManagerPrivate; + + /* TODO: temporarily required for calling DuiSceneWindow::done() + from DuiSceneManager::{hide,show}Window{,Now}()*/ + friend class DuiSceneManager; +}; + +#endif diff --git a/src/widgets/duiscenewindow_p.h b/src/widgets/duiscenewindow_p.h new file mode 100644 index 000000000..6ee45b3e6 --- /dev/null +++ b/src/widgets/duiscenewindow_p.h @@ -0,0 +1,57 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISCENEWINDOW_P_H +#define DUISCENEWINDOW_P_H + +#include "duiscenewindow.h" +#include "private/duiwidgetcontroller_p.h" + +class DuiWindow; +class DuiSceneLayerEffect; + +class DuiSceneWindowPrivate : public DuiWidgetControllerPrivate +{ + Q_DECLARE_PUBLIC(DuiSceneWindow) + +public: + DuiSceneWindowPrivate(); + + // helper function for the public appear() and appearNow() + // since both are very similar + void appear(bool now, DuiWindow *window, DuiSceneWindow::DeletionPolicy policy); + + // helper function for the public dismiss() and dismissNow() + bool dismiss(bool now); + + DuiSceneWindow::WindowType windowType; + DuiSceneWindow::DeletionPolicy policy; + + Qt::Alignment alignment; + QPointF offset; + + bool managedManually; + bool shown; + bool dismissed; + + DuiSceneLayerEffect *effect; +}; + + +#endif diff --git a/src/widgets/duiscenewindowmodel.h b/src/widgets/duiscenewindowmodel.h new file mode 100644 index 000000000..f85518d68 --- /dev/null +++ b/src/widgets/duiscenewindowmodel.h @@ -0,0 +1,32 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISCENEWINDOWMODEL_H +#define DUISCENEWINDOWMODEL_H + +#include + +class DUI_EXPORT DuiSceneWindowModel : public DuiWidgetModel +{ + Q_OBJECT + DUI_MODEL_INTERNAL(DuiSceneWindowModel) +}; + +#endif + diff --git a/src/widgets/duiseekbar.cpp b/src/widgets/duiseekbar.cpp new file mode 100644 index 000000000..a0856decc --- /dev/null +++ b/src/widgets/duiseekbar.cpp @@ -0,0 +1,104 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiseekbar.h" +#include "duislider_p.h" +#include "duitheme.h" + +#include "duiwidgetcreator.h" +DUI_REGISTER_WIDGET(DuiSeekBar) + +DuiSeekBar::DuiSeekBar(QGraphicsItem *parent, DuiSeekBarModel *model) : + DuiSlider(new DuiSliderPrivate, model == NULL ? new DuiSeekBarModel : model, parent) +{ +} + +// Sets the minimum of the active area. Does not have to depend on actual range. +void DuiSeekBar::setLoadedContentMinimum(int minimum) +{ + int mMinimum = model()->loadedContentMin(); + int mMaximum = model()->loadedContentMax(); + + // the maximum will be at least the minimum + if (minimum > mMaximum) { + mMaximum = minimum; + model()->setLoadedContentMax(mMaximum); + } + + if (minimum != mMinimum) { + mMinimum = minimum; + model()->setLoadedContentMin(mMinimum); + } + + if ((model()->value() < model()->loadedContentMin()) || + (model()->value() > model()->loadedContentMax())) + emit outOfLoadedContentRange(); +} + +// Sets the maximum of the active area. Does not have to depend on actual range. +void DuiSeekBar::setLoadedContentMaximum(int maximum) +{ + int mMinimum = model()->loadedContentMin(); + int mMaximum = model()->loadedContentMax(); + + // the minimum will be at most the minimum + if (maximum < mMinimum) { + mMinimum = maximum; + model()->setLoadedContentMin(mMinimum); + } + + if (maximum != mMaximum) { + mMaximum = maximum; + model()->setLoadedContentMax(mMaximum); + } + + if ((model()->value() < model()->loadedContentMin()) || + (model()->value() > model()->loadedContentMax())) + emit outOfLoadedContentRange(); +} + +void DuiSeekBar::setLoadedContentRange(int minimum, int maximum) +{ + setLoadedContentMaximum(maximum); + // If maximum < minimum, both will be set to minimum + setLoadedContentMinimum(minimum); + + if ((model()->value() < model()->loadedContentMin()) || + (model()->value() > model()->loadedContentMax())) + emit outOfLoadedContentRange(); +} + +void DuiSeekBar::setValue(int value) +{ + DuiSlider::setValue(value); + + if ((value < model()->loadedContentMin()) || + (value > model()->loadedContentMax())) + emit outOfLoadedContentRange(); +} + +int DuiSeekBar::loadedContentMinimum() const +{ + return model()->loadedContentMin(); +} + +int DuiSeekBar::loadedContentMaximum() const +{ + return model()->loadedContentMax(); +} diff --git a/src/widgets/duiseekbar.h b/src/widgets/duiseekbar.h new file mode 100644 index 000000000..2ab52cc9b --- /dev/null +++ b/src/widgets/duiseekbar.h @@ -0,0 +1,126 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISEEKBAR_H +#define DUISEEKBAR_H + +#include "duislider.h" +#include + +/*! + \class DuiSlider + \brief DuiSeekBar is a special type of DuiSlider used for displaying playback status for multimedia content. + + \ingroup widgets + + \section DuiSeekBar Overview + Seekbar includes received and non-received parts to visualize e.g. streamed/buffered content. + +\section DuiSeekBarExampleCodes Example codes + Seekbar load new content when seekbar value goes out of loadedcontent range: + \code + //connect outOfLoadedContentRange signal to playerOutOfLoadedContentRange local slot + QObject::connect(playerSeekBar, SIGNAL(outOfLoadedContentRange()), this, SLOT(playerOutOfLoadedContentRange())); + void SeekBarTesterPage::playerOutOfLoadedContentRange() + { + loadedContentMinimum = playerSeekBar->value(); + loadedContentMaximum = playerSeekBar->value(); + + playerSeekBar->setLoadedContentMinimum(loadedContentMinimum); + playerSeekBar->setLoadedContentMaximum(loadedContentMaximum); + } + \endcode + + \sa DuiSeekBarModel DuiSliderStyle +*/ + +class DUI_EXPORT DuiSeekBar : public DuiSlider +{ + Q_OBJECT + DUI_CONTROLLER(DuiSeekBar) + + /*! + \property DuiSlider::loadedContentMinimum + \brief Minimum value in seekbar loaded content range. + + See DuiSeekBarModel::loadedContentMin for details. + */ + Q_PROPERTY(int loadedContentMinimum READ loadedContentMinimum WRITE setLoadedContentMinimum) + + /*! + \property DuiSlider::loadedContentMaximum + \brief Maximum value in seekbar loaded content range. + + See DuiSeekBarModel::loadedContentMax for details. + */ + Q_PROPERTY(int loadedContentMaximum READ loadedContentMaximum WRITE setLoadedContentMaximum) + +public: + /*! + \brief Constructs a sekkbar. + \param parent Parent dui widget + \param viewType Optional view type + */ + explicit DuiSeekBar(QGraphicsItem *parent = 0, DuiSeekBarModel *model = 0); + + /*! + \brief Gets minimum value in seekbar loaded content range. + \return minimum value in seekbar loaded content range + */ + int loadedContentMinimum() const; + /*! + \brief Gets maximum value in seekbar loaded content range. + \return maximum value in seekbar loaded content range + */ + int loadedContentMaximum() const; + +public Q_SLOTS: + /*! + \brief Sets minimum value in seekbar loaded content range. + \param minimum value in loaded content range + */ + void setLoadedContentMinimum(int minimum); + + /*! + \brief Sets maximum value in seekbar loaded content range. + \param maximum value in loaded content range + */ + void setLoadedContentMaximum(int maximum); + + /*! + \brief Sets seekbar loaded content range. + \param minimum value in loaded content range + \param maximum value in loaded content range + */ + void setLoadedContentRange(int minimum, int maximum); + + /*! + \brief Sets new value for seekbar. + \param value a value to be set (value is bounded into sekkbar value range) + */ + virtual void setValue(int value); + +Q_SIGNALS: + /*! + \brief Emitted when value goes out of loaded content range + */ + void outOfLoadedContentRange(); +}; + +#endif diff --git a/src/widgets/duiseekbarmodel.h b/src/widgets/duiseekbarmodel.h new file mode 100644 index 000000000..9e76794cf --- /dev/null +++ b/src/widgets/duiseekbarmodel.h @@ -0,0 +1,51 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISEEKBARMODEL_H +#define DUISEEKBARMODEL_H + +#include + +/*! + \class DuiSliderModel + \brief Model class for DuiSlider. + + \ingroup models + \sa DuiSlider +*/ +class DUI_EXPORT DuiSeekBarModel : public DuiSliderModel +{ + Q_OBJECT + DUI_MODEL_INTERNAL(DuiSeekBarModel) + +private: + /*! + \property DuiSeekBarModel::loadedContentMin + \brief Minimum value of seekbar loaded content range. + */ + DUI_MODEL_PROPERTY(int, loadedContentMin, LoadedContentMin, true, 0) + /*! + \property DuiSeekBarModel::loadedContentMax + \brief Maximum value of seekbar loaded content range. + */ + DUI_MODEL_PROPERTY(int, loadedContentMax, LoadedContentMax, true, 0) +}; + +#endif + diff --git a/src/widgets/duiseparator.cpp b/src/widgets/duiseparator.cpp new file mode 100644 index 000000000..e954f1032 --- /dev/null +++ b/src/widgets/duiseparator.cpp @@ -0,0 +1,57 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duitheme.h" +#include "duiseparator.h" +#include "duiseparator_p.h" +#include "duiwidgetmodel.h" + +#include "duiwidgetcreator.h" +DUI_REGISTER_WIDGET(DuiSeparator) + +DuiSeparatorPrivate::DuiSeparatorPrivate() : + DuiWidgetControllerPrivate() +{ +} + +DuiSeparatorPrivate::~DuiSeparatorPrivate() +{ +} + +DuiSeparator::DuiSeparator(QGraphicsItem *parent, Qt::Orientation orientation) : + DuiWidgetController(new DuiSeparatorPrivate(), new DuiSeparatorModel(), parent) +{ + if (orientation != Qt::Horizontal) + model()->setOrientation(orientation); +} + +DuiSeparator::~DuiSeparator() +{ +} + +Qt::Orientation DuiSeparator::orientation() +{ + return model()->orientation(); +} + +void DuiSeparator::setOrientation(Qt::Orientation orientation) +{ + model()->setOrientation(orientation); +} + diff --git a/src/widgets/duiseparator.h b/src/widgets/duiseparator.h new file mode 100644 index 000000000..3434a0cd2 --- /dev/null +++ b/src/widgets/duiseparator.h @@ -0,0 +1,74 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISEPARATOR_H +#define DUISEPARATOR_H + +#include +#include +#include "duiseparatormodel.h" + +class DuiSeparatorPrivate; + +/*! + * \class DuiSeparator + * \brief DuiSeparator is a generic separator widget. + */ +class DUI_EXPORT DuiSeparator : public DuiWidgetController +{ + Q_OBJECT + DUI_CONTROLLER(DuiSeparator) + + /*! + \property DuiSeparator::orientation + \brief See DuiSeparatorModel::orientation + */ + Q_PROPERTY(Qt::Orientation orientation READ orientation WRITE setOrientation) + +public: + /*! + \brief Constructs the separator. + */ + DuiSeparator(QGraphicsItem *parent = 0, Qt::Orientation orientation = Qt::Horizontal); + + + /*! + \brief Destroys the separator. + */ + virtual ~DuiSeparator(); + + /*! + \brief Gets the orientation. + */ + Qt::Orientation orientation(); + +public Q_SLOTS: + /*! + \brief Set the orientation. + */ + void setOrientation(Qt::Orientation orientation); + +private: + Q_DECLARE_PRIVATE(DuiSeparator) + Q_DISABLE_COPY(DuiSeparator) + +}; + +#endif // DUISEPARATOR_H + diff --git a/src/widgets/duiseparator_p.h b/src/widgets/duiseparator_p.h new file mode 100644 index 000000000..9f03c53f4 --- /dev/null +++ b/src/widgets/duiseparator_p.h @@ -0,0 +1,34 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISEPARATOR_P_H +#define DUISEPARATOR_P_H + +#include "private/duiwidgetcontroller_p.h" + +class DuiSeparatorPrivate : protected DuiWidgetControllerPrivate +{ +public: + Q_DECLARE_PUBLIC(DuiSeparator) + + DuiSeparatorPrivate(); + virtual ~DuiSeparatorPrivate(); +}; + +#endif //DUISEPARATOR_P_H diff --git a/src/widgets/duiseparatormodel.h b/src/widgets/duiseparatormodel.h new file mode 100644 index 000000000..20993eafc --- /dev/null +++ b/src/widgets/duiseparatormodel.h @@ -0,0 +1,47 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISEPARATORMODEL_H +#define DUISEPARATORMODEL_H + +#include + +/*! + \class DuiSeparatorModel + \brief Data model class for DuiSeparator + + \ingroup models + \sa DuiSeparator +*/ + +class DUI_EXPORT DuiSeparatorModel : public DuiWidgetModel +{ + Q_OBJECT + DUI_MODEL_INTERNAL(DuiSeparatorModel) + + /*! + \property DuiSeparatorModel::orientation + \brief display orientation + */ + DUI_MODEL_PROPERTY(Qt::Orientation, orientation, Orientation, true, Qt::Horizontal) + +}; + +#endif + diff --git a/src/widgets/duislider.cpp b/src/widgets/duislider.cpp new file mode 100644 index 000000000..370d12989 --- /dev/null +++ b/src/widgets/duislider.cpp @@ -0,0 +1,254 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include "duislider.h" +#include "duiseekbar.h" +#include "duislider_p.h" +#include "duitheme.h" + +#include "duiwidgetcreator.h" +DUI_REGISTER_WIDGET(DuiSlider) + +DuiSliderPrivate::DuiSliderPrivate() +{ +} + + +DuiSliderPrivate::~DuiSliderPrivate() +{ +} + +int DuiSliderPrivate::adjustValue(int minimum, int value, int maximum, int steps) +{ + if (steps < 0) + steps = -steps; + + if ((steps < 1) || (steps > maximum - minimum - 1)) + return value; + + int numberOfSteps = qRound(((qreal(value) - qreal(minimum)) * qreal(steps)) / (qreal(maximum) - qreal(minimum))); + return minimum + (numberOfSteps * qRound((qreal(maximum) - qreal(minimum)) / qreal(steps))); +} + +DuiSlider::DuiSlider(QGraphicsItem *parent, const QString &viewType) + : DuiWidgetController(new DuiSliderPrivate(), new DuiSliderModel, parent) +{ + setViewType(viewType); +} + +DuiSlider::DuiSlider(DuiSliderPrivate *dd, DuiSliderModel *model, QGraphicsItem *parent, const QString &viewType) + : DuiWidgetController(dd, model, parent) +{ + setViewType(viewType); +} + +DuiSlider::~DuiSlider() +{ +} + +void DuiSlider::setMinimum(int minimum) +{ + model()->setMinimum(minimum); +} + +void DuiSlider::setMaximum(int maximum) +{ + model()->setMaximum(maximum); +} + +void DuiSlider::setRange(int minimum, int maximum) +{ + setMaximum(maximum); + setMinimum(minimum); +} + +void DuiSlider::setSteps(int steps) +{ + Q_D(DuiSlider); + + model()->setSteps(steps); + + int tmpValue = d->adjustValue(model()->minimum(), + model()->value(), + model()->maximum(), + model()->steps()); + + if (tmpValue != model()->value()) + model()->setValue(tmpValue); +} + +void DuiSlider::setValue(int value) +{ + Q_D(DuiSlider); + int tmpValue = d->adjustValue(model()->minimum(), + value, + model()->maximum(), + model()->steps()); + model()->setValue(tmpValue); +} + +void DuiSlider::updateData(const QList& modifications) +{ + DuiWidgetController::updateData(modifications); + + const char *member; + foreach(member, modifications) { + if (member == DuiSliderModel::Value) { + emit valueChanged(model()->value()); + } else if (member == DuiSliderModel::State) { + if (model()->state() == DuiSliderModel::Pressed) + emit sliderPressed(); + else + emit sliderReleased(); + } + } +} + +int DuiSlider::minimum() const +{ + return model()->minimum(); +} + +int DuiSlider::maximum() const +{ + return model()->maximum(); +} + +int DuiSlider::steps() const +{ + return model()->steps(); +} + +int DuiSlider::value() const +{ + return model()->value(); +} + +void DuiSlider::setOrientation(Qt::Orientation orientation) +{ + model()->setOrientation(orientation); +} + +Qt::Orientation DuiSlider::orientation() const +{ + return model()->orientation(); +} + +void DuiSlider::setMinLabelIconID(const QString &iconID) +{ + model()->setMinLabelIcon(iconID); +} + +void DuiSlider::setMinLabelVisible(bool visible) +{ + model()->setMinLabelVisible(visible); +} + +void DuiSlider::setMinLabel(const QString &text) +{ + model()->setMinLabelText(text); +} + +void DuiSlider::setMaxLabelIconID(const QString &iconID) +{ + model()->setMaxLabelIcon(iconID); +} + +void DuiSlider::setMaxLabelVisible(bool visible) +{ + model()->setMaxLabelVisible(visible); +} + +void DuiSlider::setMaxLabel(const QString &text) +{ + model()->setMaxLabelText(text); +} + +void DuiSlider::setHandleLabelIconID(const QString &iconID) +{ + model()->setHandleLabelIcon(iconID); +} + +void DuiSlider::setHandleLabelVisible(bool visible) +{ + model()->setHandleLabelVisible(visible); +} + +void DuiSlider::setHandleLabel(const QString &text) +{ + model()->setHandleLabelText(text); +} + +QString DuiSlider::minLabelIconID() const +{ + return model()->minLabelIcon(); +} + +QString DuiSlider::minLabelText() const +{ + return model()->minLabelText(); +} + +QString DuiSlider::maxLabelIconID() const +{ + return model()->maxLabelIcon(); +} + +QString DuiSlider::maxLabelText() const +{ + return model()->maxLabelText(); +} + +QString DuiSlider::handleLabelIconID() const +{ + return model()->handleLabelIcon(); +} + +QString DuiSlider::handleLabelText() const +{ + return model()->handleLabelText(); +} + +bool DuiSlider::isMinLabelVisible() const +{ + return model()->minLabelVisible(); +} + +bool DuiSlider::isMaxLabelVisible() const +{ + return model()->maxLabelVisible(); +} + +bool DuiSlider::isHandleLabelVisible() const +{ + return model()->handleLabelVisible(); +} + +void DuiSlider::setState(DuiSliderModel::SliderState state) +{ + model()->setState(state); + update(); +} + +DuiSliderModel::SliderState DuiSlider::state() const +{ + return model()->state(); +} diff --git a/src/widgets/duislider.h b/src/widgets/duislider.h new file mode 100644 index 000000000..ea36959c7 --- /dev/null +++ b/src/widgets/duislider.h @@ -0,0 +1,455 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISLIDER_H +#define DUISLIDER_H + +#include "duiwidgetcontroller.h" +#include + +class DuiSliderPrivate; + +/*! + \class DuiSlider + \brief DuiSlider is used for continuous set of values, among which user can choose one value. + + \ingroup widgets + + \section DuiSliderOverview Overview + Slider defines a given value range from where user can choose one given value by moving + the slider thumb to required position along the slider groove. Sliders are interactive + elements. + + DuiSliders can be oriented horizontally or vertically, and they support left-to-right or + right-to-left UI direction. + + Sliders have minimum and maximum labels located at the 2 endings of slider groove and thumb + label located at thumb position. + + \section DuiSliderGuidelines Usage guidelines + DuiSliders allow setting and getting of minimum and maximum values (value range) and + current value and setting of number of steps. + + DuiSlider labels can be visible or hidden. + + DuiSliders can have margins and paddings with thickness defined in CSS. + + \section DuiSliderExampleCodes Example codes + Slider value displayed in handle indicator: + \code + //connect valueChanged signal to modifySliderValue local slot + QObject::connect(slider, SIGNAL(valueChanged(int)), this, SLOT(modifySliderValue(int))); + + //modifySliderValue + void SliderTesterPage::modifySliderValue(int newValue) + { + slider->setHandleLabel(QString::number(newValue)); + } + \endcode + Show / hide slider handle when slider is pressed / released: + \code + //connect sliderPressed signal to showSliderHandle local slot + QObject::connect(slider, SIGNAL(sliderPressed()), this, SLOT(showSliderHandle(int))); + + //connect sliderReleased signal to hideSliderHandle local slot + QObject::connect(slider, SIGNAL(sliderReleased()), this, SLOT(hideSliderHandle(int))); + + //modifySliderValue + void SliderTesterPage::showSliderHandle() + { + slider->setHandleLabelVisible(true); + } + + void SliderTesterPage::hideSliderHandle() + { + slider->setHandleLabelVisible(false); + } + \endcode + + \sa DuiSliderModel DuiSliderStyle +*/ +class DUI_EXPORT DuiSlider : public DuiWidgetController +{ + Q_OBJECT + DUI_CONTROLLER(DuiSlider) + + /*! + \property DuiSlider::state + \brief Slider state (pressed or released). + + See DuiSliderModel::state for details. + */ + Q_PROPERTY(DuiSliderModel::SliderState state READ state WRITE setState DESIGNABLE false) + + /*! + \property DuiSlider::orientation + \brief Slider orientation (horizontal or vertical). + + See DuiSliderModel::orientation for details. + */ + Q_PROPERTY(Qt::Orientation orientation READ orientation WRITE setOrientation) + + /*! + \property DuiSlider::minLabelIconID + \brief Slider minimum indicator image identifier. + + See DuiSliderModel::minLabelIcon for details. + */ + Q_PROPERTY(QString minLabelIconID READ minLabelIconID WRITE setMinLabelIconID) + + /*! + \property DuiSlider::maxLabelIconID + \brief Slider maximum indicator image identifier. + + See DuiSliderModel::maxLabelIcon for details. + */ + Q_PROPERTY(QString maxLabelIconID READ maxLabelIconID WRITE setMaxLabelIconID) + + /*! + \property DuiSlider::handleLabelIconID + \brief Slider handle indicator image identifier. + + See DuiSliderModel::handleLabelIcon for details. + */ + Q_PROPERTY(QString handleLabelIconID READ handleLabelIconID WRITE setHandleLabelIconID) + + /*! + \property DuiSlider::minLabelText + \brief Slider minimum indicator text. + + See DuiSliderModel::minLabelText for details. + */ + Q_PROPERTY(QString minLabelText READ minLabelText WRITE setMinLabel) + + /*! + \property DuiSlider::maxLabelText + \brief Slider maximum indicator text. + + See DuiSliderModel::maxLabelText for details. + */ + Q_PROPERTY(QString maxLabelText READ maxLabelText WRITE setMaxLabel) + + /*! + \property DuiSlider::handleLabelText + \brief Slider handle indicator text. + + See DuiSliderModel::handleLabelText for details. + */ + Q_PROPERTY(QString handleLabelText READ handleLabelText WRITE setHandleLabel) + + /*! + \property DuiSlider::minLabelVisible + \brief Slider minimum indicator visibility. + + See DuiSliderModel::minLabelVisible for details. + */ + Q_PROPERTY(bool minLabelVisible READ isMinLabelVisible WRITE setMinLabelVisible) + + /*! + \property DuiSlider::maxLabelVisible + \brief Slider maximum indicator visibility. + + See DuiSliderModel::maxLabelVisible for details. + */ + Q_PROPERTY(bool maxLabelVisible READ isMaxLabelVisible WRITE setMaxLabelVisible) + + /*! + \property DuiSlider::handleLabelVisible + \brief Slider handle indicator visibility. + + See DuiSliderModel::handleLabelVisible for details. + */ + Q_PROPERTY(bool handleLabelVisible READ isHandleLabelVisible WRITE setHandleLabelVisible) + + /*! + \property DuiSlider::minimum + \brief Minimum value in slider value range. + + See DuiSliderModel::minimum for details. + */ + Q_PROPERTY(int minimum READ minimum WRITE setMinimum) + + /*! + \property DuiSlider::maximum + \brief Maximum value in slider value range. + + See DuiSliderModel::maximum for details. + */ + Q_PROPERTY(int maximum READ maximum WRITE setMaximum) + + /*! + \property DuiSlider::steps + \brief Values steps in slider value range. + + See DuiSliderModel::steps for details. + */ + Q_PROPERTY(int steps READ steps WRITE setSteps) + + /*! + \property DuiSlider::value + \brief Slider value. + + See DuiSliderModel::value for details. + */ + Q_PROPERTY(int value READ value WRITE setValue NOTIFY valueChanged USER true) +public: + + /*! + \brief Constructs a slider. + \param parent Parent dui widget + \param viewType Optional view type + */ + explicit DuiSlider(QGraphicsItem *parent = 0, const QString &viewType = QString()); + + /*! + \brief Destructor + */ + virtual ~DuiSlider(); + + /*! + \brief Gets minimum value in slider value range. + \return minimum value in slider value range + */ + int minimum() const; + + /*! + \brief Gets maximum value in slider value range. + \return maximum value in slider value range + */ + int maximum() const; + + /*! + \brief Gets number of values steps. + \return number of value steps + */ + int steps() const; + + /*! + \brief Gets slider value. + \return slider value + */ + int value() const; + + /*! + \brief Sets slider orientation. + \param direction Slider orientation (Qt::Horizontal for horizontal sliders,\n + Qt::Vertical for vertical sliders) + */ + void setOrientation(Qt::Orientation direction); + + /*! + \brief Gets slider current orientation. + \return current orientation of the slider (Qt::Horizontal for horizontal sliders,\n + Qt::Vertical for vertical sliders) + */ + Qt::Orientation orientation() const; + + //newly added public methods + /*! + \brief Sets minimum indicator image identifier. + \param text Minimum indicator image identifier + */ + void setMinLabelIconID(const QString &iconID); + + /*! + \brief Sets minimum indicator visibility. + \param visible True if minimum indicator is visible false if it is not visible. + */ + void setMinLabelVisible(bool visible); + + /*! + \brief Sets minimum indicator text. + \param text Minimum indicator text + */ + void setMinLabel(const QString &text); + + /*! + \brief Sets maximum indicator image identifier. + \param text Maximum indicator image identifier + */ + void setMaxLabelIconID(const QString &iconID); + + /*! + \brief Sets maximum indicator visibility. + \param visible True if maximum indicator is visible false if it is not visible. + */ + void setMaxLabelVisible(bool visible); + + /*! + \brief Sets maximum indicator text. + \param text Maximum indicator text + */ + void setMaxLabel(const QString &text); + + /*! + \brief Sets thumb indicator image identifier. + \param iconID Image identifier + */ + void setHandleLabelIconID(const QString &iconID); + + /*! + \brief Sets handle indicator visibility. + \param visible True to set handle indicator visible false to set it invisible + */ + void setHandleLabelVisible(bool visible); + + /*! + \brief Sets handle indicator text. + \param text The text string + */ + void setHandleLabel(const QString &text); + + /*! + \brief Gets minimum indicator image identifier + \return minimum indicator image identifier + */ + QString minLabelIconID() const; + + /*! + \brief Gets minimum indicator text. + \return minimum indicator text + */ + QString minLabelText() const; + + /*! + \brief Gets maximum indicator image identifier. + \return maximum indicator image identifier + */ + QString maxLabelIconID() const; + + /*! + \brief Gets maximum indicator text. + \return maximum indicator text + */ + QString maxLabelText() const; + + /*! + \brief Gets handle indicator image identifier. + \return handle indicator image identifier + */ + QString handleLabelIconID() const; + + /*! + \brief Gets handle indicator text. + \return handle indicator text + */ + QString handleLabelText() const; + + /*! + \brief Returns true if minimum indicator is visible and false if it is not visible. + \return minimum indicator visibility + */ + bool isMinLabelVisible() const; + + /*! + \brief Returns true if maximum indicator is visible and false if is not visible. + \return maximum indicator visibility + */ + bool isMaxLabelVisible() const; + + /*! + \brief Returns true if handle indicator is visible and false if is not visible. + \return handle indicator visibility + */ + bool isHandleLabelVisible() const; + + /*! + \brief Set slider state programmatically. + \param state going to be set + */ + void setState(DuiSliderModel::SliderState state); + + /*! + \brief Returns slider state. + \return slider state + */ + DuiSliderModel::SliderState state() const; + +public Q_SLOTS: + /*! + \brief Sets the slider's minimum value. + \param minimum value in slider value range + */ + void setMinimum(int minimum); + + /*! + \brief Sets the new maximum value for slider. + \param maximum value in slider value range + */ + void setMaximum(int maximum); + + /*! + \brief Sets the value range for slider. + \param minimum value in slider value range + \param maximum value in slider value range + */ + void setRange(int minimum, int maximum); + + /*! + \brief Set number of value steps for slider. + \param value steps to be set (for 0 there will not be steps)\n + If there are steps slider values are limited to integer multiples of step values. + */ + void setSteps(int steps); + + /*! + \brief Set a new value for slider. + \param value a value to be set (value is bounded into slider value range) + */ + virtual void setValue(int value); + +Q_SIGNALS: + /*! + \brief Signal emitted when slider value is changed. + \param newValue new value + */ + void valueChanged(int newValue); + + /*! + \brief Emitted when the user presses the slider. + */ + void sliderPressed(); + + /*! + \brief Emitted when the user releases the slider. + */ + void sliderReleased(); + +protected Q_SLOTS: + /*! + \brief Signal emitted when some \sa DuiModel attribute is modified. + */ + virtual void updateData(const QList& modifications); + +protected: + /*! + \brief Constructs a slider with private class and model. + \param dd Private class instance + \param model Model instance + \param parent Parent dui widget + \param viewType Optional view type + */ + DuiSlider(DuiSliderPrivate *dd, DuiSliderModel *model, QGraphicsItem *parent, const QString &viewType = QString()); + +private: + Q_DISABLE_COPY(DuiSlider) + Q_DECLARE_PRIVATE(DuiSlider) +}; + +#endif diff --git a/src/widgets/duislider_p.h b/src/widgets/duislider_p.h new file mode 100644 index 000000000..6bddab63d --- /dev/null +++ b/src/widgets/duislider_p.h @@ -0,0 +1,35 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISLIDER_P_H +#define DUISLIDER_P_H + +#include "private/duiwidgetcontroller_p.h" + +class DuiSliderPrivate : public DuiWidgetControllerPrivate +{ + Q_DECLARE_PUBLIC(DuiSlider) +public: + DuiSliderPrivate(); + virtual ~DuiSliderPrivate(); + + int adjustValue(int minimum, int value, int maximum, int steps); +}; + +#endif diff --git a/src/widgets/duislidermodel.cpp b/src/widgets/duislidermodel.cpp new file mode 100644 index 000000000..e8863850a --- /dev/null +++ b/src/widgets/duislidermodel.cpp @@ -0,0 +1,103 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duislidermodel.h" + +const int &DuiSliderModel::minimum() const +{ + return _minimum(); +} + +void DuiSliderModel::setMinimum(const int &minimum) +{ + //update the value and emit change signal only if the value has changed + if (minimum != _minimum()) { + _minimum() = minimum; + memberModified(Minimum); + } + + // the maximum will be at least the minimum + if (minimum > _maximum()) { + setMaximum(minimum); + } + + //limit the value to new min and max + setValue(value()); +} + +const int &DuiSliderModel::maximum() const +{ + return _maximum(); +} + +void DuiSliderModel::setMaximum(const int &maximum) +{ + //update the value and emit change signal only if the value has changed + if (maximum != _maximum()) { + _maximum() = maximum; + memberModified(Maximum); + } + + // the minimum will be at most the maximum + if (maximum < _minimum()) { + setMinimum(maximum); + } + + //limit the value to new min and max + setValue(value()); +} + +const int &DuiSliderModel::value() const +{ + return _value(); +} + +void DuiSliderModel::setValue(const int &value) +{ + int setVal = value; + if (setVal < _minimum()) { + setVal = _minimum(); + } + + if (setVal > _maximum()) { + setVal = _maximum(); + } + + if (setVal != _value()) { + _value() = setVal; + memberModified(Value); + } +} + +const int &DuiSliderModel::steps() const +{ + return _steps(); +} + +void DuiSliderModel::setSteps(const int &steps) +{ + int setSteps = steps; + if (setSteps < 0) + setSteps = -steps; + + if (setSteps != _steps()) { + _steps() = setSteps; + memberModified(Steps); + } +} diff --git a/src/widgets/duislidermodel.h b/src/widgets/duislidermodel.h new file mode 100644 index 000000000..dbecd82ec --- /dev/null +++ b/src/widgets/duislidermodel.h @@ -0,0 +1,129 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISLIDERMODEL_H +#define DUISLIDERMODEL_H + +#include + +/*! + \class DuiSliderModel + \brief Model class for DuiSlider. + + \ingroup models + \sa DuiSlider +*/ +class DUI_EXPORT DuiSliderModel : public DuiWidgetModel +{ + Q_OBJECT + DUI_MODEL_INTERNAL(DuiSliderModel) + +public: + /*! + \brief Defined whether slider handle is pressed (DuiSliderModel::Pressed) + or released (DuiSliderModel::Released). + */ + enum SliderState { + Pressed, + Released + }; + +private: + /*! + \property DuiSliderModel::state + \brief Slider state (it can be either DuiSliderModel::Released or DuiSliderModel::Pressed). + */ + DUI_MODEL_PROPERTY(DuiSliderModel::SliderState, state, State, true, DuiSliderModel::Released) + /*! + \property DuiSliderModel::minimum + \brief Slider range minimum value. + */ + DUI_MODEL_PROPERTY(int, minimum, Minimum, false, 0) + /*! + \property DuiSliderModel::maximum + \brief Slider range maximum value. + */ + DUI_MODEL_PROPERTY(int, maximum, Maximum, false, 100) + /*! + \property DuiSliderModel::value + \brief Slider value (value in slider range). Values are bounded into slider range. + */ + DUI_MODEL_PROPERTY(int, value, Value, false, 0) + /*! + \property DuiSliderModel::steps + \brief Slider value range subinterval (steps). If 0 there are no steps. + If there are steps slider values are limited to integer multiples + of step values. + */ + DUI_MODEL_PROPERTY(int, steps, Steps, false, 0) + /*! + \property DuiSliderModel::orientation + \brief Slider orientation. Can be Qt::Horizontal or Qt::Vertical. + */ + DUI_MODEL_PROPERTY(Qt::Orientation, orientation, Orientation, true, Qt::Horizontal) + /*! + \property DuiSliderModel::minLabelIcon + \brief Slider minimum indicator image identifier. + */ + DUI_MODEL_PROPERTY(QString, minLabelIcon, MinLabelIcon, true, QString()) + /*! + \property DuiSliderModel::minLabelText + \brief Slider minimum indicator text. + */ + DUI_MODEL_PROPERTY(QString, minLabelText, MinLabelText, true, QString()) + /*! + \property DuiSliderModel::minLabelVisible + \brief Slider minimum indicator visibility. + */ + DUI_MODEL_PROPERTY(bool, minLabelVisible, MinLabelVisible, true, false) + /*! + \property DuiSliderModel::maxLabelIcon + \brief Slider maximum indicator image identifier. + */ + DUI_MODEL_PROPERTY(QString, maxLabelIcon, MaxLabelIcon, true, QString()) + /*! + \property DuiSliderModel::maxLabelText + \brief Slider maximum indicator text. + */ + DUI_MODEL_PROPERTY(QString, maxLabelText, MaxLabelText, true, QString()) + /*! + \property DuiSliderModel::maxLabelVisible + \brief Slider maximum indicator visibility. + */ + DUI_MODEL_PROPERTY(bool, maxLabelVisible, MaxLabelVisible, true, false) + /*! + \property DuiSliderModel::handleLabelIcon + \brief Slider handle indicator image identifier. + */ + DUI_MODEL_PROPERTY(QString, handleLabelIcon, HandleLabelIcon, true, QString()) + /*! + \property DuiSliderModel::handleLabelText + \brief Slider handle indicator text. + */ + DUI_MODEL_PROPERTY(QString, handleLabelText, HandleLabelText, true, QString()) + /*! + \property DuiSliderModel::handleLabelVisible + \brief Slider handle indicator visibility. + */ + DUI_MODEL_PROPERTY(bool, handleLabelVisible, HandleLabelVisible, true, false) + +}; + +#endif + diff --git a/src/widgets/duistylablewidget.cpp b/src/widgets/duistylablewidget.cpp new file mode 100644 index 000000000..fe8f9a3fe --- /dev/null +++ b/src/widgets/duistylablewidget.cpp @@ -0,0 +1,128 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duistylablewidget.h" +#include "duiscalableimage.h" + +#include "duiwidgetcreator.h" +DUI_REGISTER_WIDGET(DuiStylableWidget) + +/* Private class acting as a creator for stylable widgets + subclasses. It also takes responsibility for deleting + creators when the application is quitting. +*/ +class DuiStylableWidgetCreator : DuiWidgetCreatorBase +{ +public: + + static void registerCreator(const QMetaObject *metaObject, + const char *widgetAssemblyName, + Dui::AssemblyType widgetAssemblyType) { + const DuiStylableWidgetCreator *widgetCreator = creatorInstanceHolder.value(metaObject->className(), NULL); + if (!widgetCreator) { + DuiStylableWidgetCreator *creator = new DuiStylableWidgetCreator(metaObject, + widgetAssemblyName, + widgetAssemblyType); + creatorInstanceHolder.insert(metaObject->className(), creator); + } + } + +protected: + DuiStylableWidgetCreator(const QMetaObject *_widgetMetaObject, + const char *widgetAssemblyName, + Dui::AssemblyType widgetAssemblyType) : + DuiWidgetCreatorBase(_widgetMetaObject->className(), widgetAssemblyName, widgetAssemblyType), + widgetMetaObject(_widgetMetaObject) + {} + + virtual ~DuiStylableWidgetCreator() + {} + + virtual DuiWidgetController *create() const { + return NULL; + } + + virtual const QMetaObject *metaObject() const { + return widgetMetaObject; + } + +private: + class CreatorInstanceHolder : public QMap + { + public: + ~CreatorInstanceHolder() { + foreach(DuiStylableWidgetCreator * creator, this->values()) + delete creator; + } + }; + + static CreatorInstanceHolder creatorInstanceHolder; + const QMetaObject *widgetMetaObject; +}; + +DuiStylableWidgetCreator::CreatorInstanceHolder DuiStylableWidgetCreator::creatorInstanceHolder; + +DuiStylableWidget::DuiStylableWidget(QGraphicsItem *parent) : DuiWidgetController(parent) +{ +} + +DuiStylableWidget::~DuiStylableWidget() +{ +} + +void DuiStylableWidget::drawBackground(QPainter *painter, const QStyleOptionGraphicsItem *option) const +{ + Q_UNUSED(option); + if (!style()->backgroundImage() && !style()->backgroundColor().isValid()) + return; + + qreal oldOpacity = painter->opacity(); + painter->setOpacity(style()->backgroundOpacity() * effectiveOpacity()); + + QSizeF s = size() - QSizeF(style()->marginLeft() + style()->marginRight(), style()->marginTop() + style()->marginBottom()); + if (style()->backgroundImage()) { + style()->backgroundImage()->draw(0, 0, s.width(), s.height(), painter); + } else { //style background color must be valid + painter->fillRect(QRectF(QPointF(0, 0), s), QBrush(style()->backgroundColor())); + } + painter->setOpacity(oldOpacity); +} + +void DuiStylableWidget::drawContents(QPainter *painter, const QStyleOptionGraphicsItem *option) const +{ + Q_UNUSED(painter); + Q_UNUSED(option); +} + +void DuiStylableWidget::drawForeground(QPainter *painter, const QStyleOptionGraphicsItem *option) const +{ + Q_UNUSED(painter); + Q_UNUSED(option); +} + +void DuiStylableWidget::applyStyle() +{ +} + +void DuiStylableWidget::registerStylableWidgetType(const QMetaObject *metaObject, + const char *widgetAssemblyName, + Dui::AssemblyType widgetAssemblyType) +{ + DuiStylableWidgetCreator::registerCreator(metaObject, widgetAssemblyName, widgetAssemblyType); +} diff --git a/src/widgets/duistylablewidget.h b/src/widgets/duistylablewidget.h new file mode 100644 index 000000000..26fb62f9e --- /dev/null +++ b/src/widgets/duistylablewidget.h @@ -0,0 +1,195 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISTYLABLEWIDGET_H +#define DUISTYLABLEWIDGET_H + +#include +#include +#include + +#ifdef DUI_LIBRARY_NAME +#define DUI_STYLABLE_WIDGET(STYLE) \ + public: \ + inline static const char* staticStyleType() { return #STYLE; } \ + inline virtual const char* styleType() const { return #STYLE; } \ + protected: \ + virtual DuiWidgetStyleContainer* createStyleContainer() const { return new STYLE##Container(); } \ + private: \ + inline STYLE##Container& style() { return static_cast(DuiStylableWidget::style()); } \ + inline const STYLE##Container& style() const { return static_cast(DuiStylableWidget::style()); } \ + class StylableWidgetCreatorRegisterer { \ + public: \ + StylableWidgetCreatorRegisterer() { \ + registerStylableWidgetType(&staticMetaObject, DUI_LIBRARY_NAME, Dui::Library); \ + }; \ + }; \ + StylableWidgetCreatorRegisterer stylableWidgetCreatorRegisterer; +#elif defined DUI_APPLICATION_NAME +#define DUI_STYLABLE_WIDGET(STYLE) \ + public: \ + inline static const char* staticStyleType() { return #STYLE; } \ + inline virtual const char* styleType() const { return #STYLE; } \ + protected: \ + virtual DuiWidgetStyleContainer* createStyleContainer() const { return new STYLE##Container(); } \ + private: \ + inline STYLE##Container& style() { return static_cast(DuiStylableWidget::style()); } \ + inline const STYLE##Container& style() const { return static_cast(DuiStylableWidget::style()); } \ + class StylableWidgetCreatorRegisterer { \ + public: \ + StylableWidgetCreatorRegisterer() { \ + registerStylableWidgetType(&staticMetaObject, DUI_APPLICATION_NAME, Dui::Application); \ + }; \ + }; \ + StylableWidgetCreatorRegisterer stylableWidgetCreatorRegisterer; +#endif + +/*! + \class DuiStylableWidget + + \brief DuiStylableWidget is a convenience class to create simple, non-MVC widgets. + + DuiStylableWidget class implements basic functionality to support + simple, non-MVC widgets which can be stylable at the same time. + + In order to use it, a new class should be inherited from DuiStylableWidget + and DUI_STYLABLE_WIDGET macro should be used to define the style + class for this widget: + + \code + class MyStylableClass : public DuiStylableWidget + { + public: + MyStylableClass(); + + protected: + // Method to be overridden for custom painting operations. + virtual void drawContents(QPainter* painter, const QStyleOptionGraphicsItem* option) const; + private: + DUI_STYLABLE_WIDGET(MyStyle) + }; + \endcode + + MyStyle class should follow typical style declaration: + \code + #include + + class DUI_EXPORT MyStyle : public DuiWidgetStyle + { + Q_OBJECT + DUI_STYLE(MyStyle) + + DUI_STYLE_ATTRIBUTE(bool, drawTiledHorizontal, DrawTiledHorizontal) + DUI_STYLE_ATTRIBUTE(QString, imageHorizontal, ImageHorizontal) + DUI_STYLE_ATTRIBUTE(QString, imageVertical, ImageVertical) + }; + + class DUI_EXPORT MyStyleContainer : public DuiWidgetStyleContainer + { + DUI_STYLE_CONTAINER(MyStyle) + }; + \endcode + + Please note, that paint() should NOT be overridden in order to draw the contents of the widget. + Following methods should be used instead: drawBackground() drawContents() drawForeground(). + + When calculating the area to which the widget should be drawn, please take + margins into consideration: + \code + QRectF paintingRect = QRectF( QPointF(style()->marginLeft(), style()->marginTop()), + size() - QSizeF(style()->marginRight(),style()->marginBottom())); + \endcode +*/ +class DUI_EXPORT DuiStylableWidget : public DuiWidgetController +{ + Q_OBJECT + + friend class DuiStylableWidgetView; + +public: + /*! + * \brief Constructor that sets up the widget. + * \param parent Parent widget. + */ + explicit DuiStylableWidget(QGraphicsItem *parent = 0); + + /*! + * \brief Destructor + */ + virtual ~DuiStylableWidget(); + + inline static const char *staticStyleType() { + return "DuiWidgetStyle"; + } + inline virtual const char *styleType() const { + return "DuiWidgetStyle"; + } + +protected: + + /*! + Notification for derived classes. This method gets called when a new style is applied for this widget. + This happens e.g. when the object is constructed and when a new object name is given to the widget. + */ + virtual void applyStyle(); + + /*! + * Draws the background for this widget. This method should be overridden + * in order to provide background drawing functionality. The base implementation + * uses background-image css attribute to draw a background beneath the widget. + */ + virtual void drawBackground(QPainter *painter, const QStyleOptionGraphicsItem *option) const; + + /*! + * Draws the contents for this widget. This method should be overridden to draw + * contents of the widget. + */ + virtual void drawContents(QPainter *painter, const QStyleOptionGraphicsItem *option) const; + + /*! + * Draws the foreground for this widget. This method should be overridden to draw + * the foreground overlay of the widget. + */ + virtual void drawForeground(QPainter *painter, const QStyleOptionGraphicsItem *option) const; + + /*! + * Creates a record about the stylable widget type which is then used + * to match the widget to the proper style. + * Note: This method should not be called directly, it is going to be + * used by DUI_STYLABLE_WIDGET macro definition. + */ + static void registerStylableWidgetType(const QMetaObject *metaObject, + const char *widgetAssemblyName, + Dui::AssemblyType widgetAssemblyType); + +protected: + /*! + This method should only be overridden by DUI_STYLABLE_WIDGET macro. + It provides widget style container to be used in derived classes. + */ + virtual DuiWidgetStyleContainer *createStyleContainer() const { + return new DuiWidgetStyleContainer(); + } + +private: + Q_DISABLE_COPY(DuiStylableWidget) + +}; + +#endif // DUISTYLABLEWIDGET_H diff --git a/src/widgets/duitextedit.cpp b/src/widgets/duitextedit.cpp new file mode 100644 index 000000000..3deb53841 --- /dev/null +++ b/src/widgets/duitextedit.cpp @@ -0,0 +1,1852 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duitextedit.h" +#include "duitextedit_p.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "duiapplication.h" +#include "duiapplicationwindow.h" +#include "duiapplicationpage.h" +#include "duitheme.h" +#include "duibreakiterator.h" +#include "duinamespace.h" +#include "duipreeditinjectionevent.h" +#include "duiwidgetview.h" +#include "duiapplication.h" +#include "duiapplicationwindow.h" +#include "duicompleter.h" +#include "duiscenemanager.h" + +#include "duiwidgetcreator.h" +DUI_REGISTER_WIDGET(DuiTextEdit) + +namespace +{ + //! character set for Number field type + const QString NumberCharacterSet = "[\\+\\-]{0,1}([0-9]+(\\.[0-9]*){0,1}){1,1}"; + + //! character set for Phone Number field type + const QString PhoneNumberCharacterSet = "[\\+0-9#\\*\\-\\+pw.\\/() ]+"; + + //! character set for Email field type + const QString EmailCharacterSet = "[a-zA-Z0-9.!#$%&'*+-\\/=?\\^_\\`{|}~@]+"; + + const QChar PlusSign('+'); + const QChar MinusSign('-'); +} + + +/*! + * \brief Constructor + * \param type widget type (single line or multiline) + */ +DuiTextEditPrivate::DuiTextEditPrivate() + : validator(0), + ownValidator(false), + completer(0), + editActive(false) +{ +} + + +/*! + * \brief Destructor + */ +DuiTextEditPrivate::~DuiTextEditPrivate() +{ + if (ownValidator == true) { + delete validator; + } +} + + +QTextCursor *DuiTextEditPrivate::cursor() const +{ + Q_Q(const DuiTextEdit); + return q->model()->cursor(); +} + + +/*! + * \brief Moves cursor, parameters as in QTextCursor::movePosition() + */ +void DuiTextEditPrivate::moveCursor(QTextCursor::MoveOperation moveOp, + QTextCursor::MoveMode moveMode, int n) +{ + Q_Q(DuiTextEdit); + + // Cursor movement will enter basic mode + commitPreedit(); + q->deselect(); + + if (cursor()->movePosition(moveOp, moveMode, n)) { + q->model()->updateCursor(); + q->updateMicroFocus(); + emit q->cursorPositionChanged(); + } +} + + +/*! + * \brief Backspace functionality, doesn't change mode + */ +bool DuiTextEditPrivate::doBackspace() +{ + Q_Q(DuiTextEdit); + + if (q->isReadOnly()) { + return false; + } + + QTextCursor currentPositionCursor = q->textCursor(); + currentPositionCursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::KeepAnchor); + QTextDocumentFragment currentFragment = currentPositionCursor.selection(); + cursor()->deletePreviousChar(); + + if (validateCurrentBlock() == true) { + return true; + + } else { + // document doesn't validate after delete -> put the character back + cursor()->insertFragment(currentFragment); + return false; + } +} + + +/*! + * \brief Deletes a character at cursor position + */ +bool DuiTextEditPrivate::doDelete() +{ + Q_Q(DuiTextEdit); + + if (q->isReadOnly()) { + return false; + } + + QTextCursor currentPositionCursor(q->textCursor()); + currentPositionCursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor); + QTextDocumentFragment currentFragment = currentPositionCursor.selection(); + cursor()->deleteChar(); + + if (validateCurrentBlock() == true) { + emit q->cursorPositionChanged(); + return true; + + } else { + // document doesn't validate after delete -> put the character back + cursor()->insertFragment(currentFragment); + return false; + } +} + + +/*! + * \brief Insert tab to the char stream & move cursor in front of it + */ +bool DuiTextEditPrivate::doTab() +{ + // TODO: missing Qt::tab action - this is on purpose or not? + return doTextInsert("\t"); +} + + +/*! + * \brief Inserts a line break + */ +bool DuiTextEditPrivate::doLineBreak() +{ + Q_Q(DuiTextEdit); + + // Ignore line breaks on single line widget. + if (q->model()->line() == DuiTextEditModel::SingleLine) { + return false; + + } else { + return doTextInsert("\n"); + } +} + + +/*! + * \brief Inserts sign before number or cycle between + and - + * \return True if text was changed + */ +bool DuiTextEditPrivate::doSignCycle() +{ + Q_Q(DuiTextEdit); + + if (q->contentType() != Dui::NumberContentType) { + return false; + } + + QTextCursor editCursor(q->textCursor()); + QChar firstChar(q->document()->characterAt(0)); + bool validChange = false; + + editCursor.setPosition(0); + if (firstChar != PlusSign && firstChar != MinusSign) { + firstChar = QChar(); + } else { + // we are going to replace existing sign + editCursor.setPosition(1, QTextCursor::KeepAnchor); + } + + editCursor.insertText(firstChar == MinusSign ? PlusSign : MinusSign); + + validChange = validateCurrentBlock(); + if (!validChange) { + // undo our change + editCursor.deletePreviousChar(); + if (!firstChar.isNull()) { + editCursor.insertText(firstChar); + } + } + + return validChange; +} + + +/*! + * \brief Inserts text to the cursor position + * \param text text to be inserted + * \return true if some text was successfully inserted + */ +bool DuiTextEditPrivate::doTextInsert(const QString &text) +{ + Q_Q(DuiTextEdit); + + if (q->isReadOnly() == true) { + return false; + } + + bool changed = false; + QString filteredText = text; + + // Bug in QTextDocument::characterCount? + int characterCount = q->document()->characterCount() - 1; + Q_ASSERT(characterCount >= 0); + + // Total characterCount mustn't exceed maxLength. + if (characterCount + filteredText.length() > q->maxLength()) { + filteredText.truncate(q->maxLength() - characterCount); + changed = true; + } + + // on single line newline are changed into spaces + if (q->lineMode() == DuiTextEditModel::SingleLine) { + filteredText.replace(QChar('\n'), QChar(' ')); + } + + int textPosition = 0; + int filteredTextLength = filteredText.length(); + int snippetLength = -1; + + do { + if (textPosition >= filteredTextLength) { + break; + } + + if (filteredText.at(textPosition) == QChar('\n')) { + // newline is appended separately. they are only available here on multiline + // mode, so they are permitted + cursor()->insertText(QChar('\n')); + textPosition++; + changed = true; + continue; + } + + // text is inserted up to one line at a time because otherwise new blocks could be created + int nextNewline = filteredText.indexOf(QChar('\n'), textPosition, Qt::CaseInsensitive); + snippetLength = nextNewline; + + if (snippetLength != -1) { + snippetLength = snippetLength - textPosition; + } + + QString textSnippet = filteredText.mid(textPosition, snippetLength); + + int cursorPosBefore = cursor()->position(); + cursor()->insertText(textSnippet); + + if (validateCurrentBlock() == true) { + changed = true; + + } else { + // validation failed, need to restore the previous state + cursor()->setPosition(cursorPosBefore, QTextCursor::KeepAnchor); + cursor()->removeSelectedText(); + } + + textPosition += snippetLength; + } while (snippetLength != -1); + + return changed; +} + + +bool DuiTextEditPrivate::validateCurrentBlock() +{ + if (validator == 0) { + return true; + } + + QTextBlock currentBlock = cursor()->block(); + QString blockText = currentBlock.text(); + int blockPosition = cursor()->position() - currentBlock.position(); + + QString blockTextCopy = blockText; + int blockPositionCopy = blockPosition; + + QValidator::State validationResult = validator->validate(blockTextCopy, blockPositionCopy); + + if (validationResult != QValidator::Invalid) { + if (blockTextCopy != blockText) { + // duiDebug("DuiTextEditPrivate") << __PRETTY_FUNCTION__ << "replacing" << blockText + // << "with" << blockTextCopy; + // the validator changed the string somehow, need to set block content again + QTextCursor blockCursor(*cursor()); + + // first clear the content of the block + int start = currentBlock.position(); + QString currentContent = currentBlock.text(); + int end = start + currentContent.length(); + + blockCursor.setPosition(start); + blockCursor.setPosition(end, QTextCursor::KeepAnchor); + // duiDebug("DuiTextEditPrivate") << "Start of selection:" << start; + // duiDebug("DuiTextEditPrivate") << "End of selection:" << blockCursor.position(); + blockCursor.removeSelectedText(); + + // set to new values + blockCursor.insertText(blockTextCopy); + cursor()->setPosition(blockPositionCopy + currentBlock.position()); + } + + return true; + + } else { + return false; + } +} + + +/*! + * \brief sets preedit to given parameters with given formatting attributes + */ +void DuiTextEditPrivate::setPreeditText(const QString &text, + const QList &attributes) +{ + QTextCursor *textCursor = cursor(); + + // Remove old pre-edit text + removePreedit(); + + int preeditTextLength = text.count(); + + QTextBlock block = textCursor->block(); + QTextLayout *layout = block.layout(); + + QList preeditStyles; + + // parse attributes + const int size = attributes.size(); + for (int i = 0; i < size; ++i) { + const QInputMethodEvent::Attribute &attribute = attributes.at(i); + if (attribute.type == QInputMethodEvent::TextFormat) { + const QTextCharFormat format = attribute.value.value().toCharFormat(); + + if (format.isValid()) { + QTextLayout::FormatRange style; + style.start = attribute.start + textCursor->position() - block.position(); + style.length = attribute.length; + style.format = format; + preeditStyles.append(style); + } + } + // TODO: should honor Cursor attribute too + } + + // set the preedit styling as additional format of the current qtextlayout. + // preedit is implemented as selected normal text with additional formatting on current + // QTextLayout. Using the additional formats here seems a bit dangerous. In principle Qt + // says the layout from a block shouldn't be changed except from + // QAbstractTextDocumentLayout::documentChanged(), but in reality e.g. QTextEdit + // uses it like this, and even sets the preedit to the layout. + // If this becomes problematic, we should move this formatting to paintContext of the view. + layout->setAdditionalFormats(preeditStyles); + + textCursor->insertText(text); + + // mark preedit as selection + int position = textCursor->position(); + textCursor->movePosition(QTextCursor::PreviousCharacter, QTextCursor::MoveAnchor, + preeditTextLength); + textCursor->setPosition(position, QTextCursor::KeepAnchor); +} + + +/*! + * \brief Commit current pre-edit so it becomes normal text + */ +void DuiTextEditPrivate::commitPreedit() +{ + Q_Q(DuiTextEdit); + + // Nothing to commit if not pre-editing + if (isPreediting() == false) { + return; + } + + QTextCursor *textCursor = cursor(); + + int characterCount = q->document()->characterCount() - 1; + if (characterCount > q->maxLength()) { + // Set markers for current selection as follows: + // Preserved preedit text Erased preedit text + // "Erased preedit text" is the part that causes overall length to exceed maxLength(). + int exceedingCharCount = characterCount - q->maxLength(); + int start = textCursor->selectionStart(); + int end = textCursor->selectionEnd(); + int startErase = end - exceedingCharCount; + + if (startErase < start) { + // Character count exceeded maxLength even before this preedit. + // Only erase the whole preedit text. + startErase = start; + } + + // Erase and then set new modified selection. + textCursor->setPosition(startErase, QTextCursor::MoveAnchor); + textCursor->setPosition(end, QTextCursor::KeepAnchor); + textCursor->removeSelectedText(); + textCursor->setPosition(start, QTextCursor::MoveAnchor); + textCursor->setPosition(startErase, QTextCursor::KeepAnchor); + } + + // clear styling + QTextBlock block = textCursor->block(); + QTextLayout *layout = block.layout(); + layout->clearAdditionalFormats(); + + if (validateCurrentBlock() == true) { + // make preedit selection part of the normal text + textCursor->clearSelection(); + + } else { + // block content with the preedit doesn't validate, need to remove the commit string + textCursor->removeSelectedText(); + } + + setMode(DuiTextEditModel::EditModeBasic); + q->updateMicroFocus(); + + if (q->hasFocus()) { + // make sure the committed preedit doesn't get left on the input context + QInputContext *ic = qApp->inputContext(); + if (ic) { + ic->reset(); + } + } + + emit q->textChanged(); +} + + +/*! + * \brief Removes pre-edit text, doesn't affect mode state + */ +void DuiTextEditPrivate::removePreedit() +{ + if (isPreediting() == false) { + return; + } + + QTextBlock block = cursor()->block(); + QTextLayout *layout = block.layout(); + layout->clearAdditionalFormats(); + + cursor()->removeSelectedText(); +} + + + +/*! + * Set text edit mode + * NOTE: every function calling setMode is potential candidate + * to emit signal copyAvailable(bool) + * \param mode text edit mode + */ +void DuiTextEditPrivate::setMode(DuiTextEditModel::EditMode mode) +{ + Q_Q(DuiTextEdit); + + q->model()->setEdit(mode); +} + + +/*! + * \brief Set cursor position. + * \return false if \a index is an invalid cursor postion. + */ +bool DuiTextEditPrivate::setCursorPosition(int index) +{ + Q_Q(DuiTextEdit); + + bool val = false; + QTextBlock block = q->document()->findBlock(index); + + if (block.isValid()) { + val = true; + commitPreedit(); // note: also calls updateMicroFocus() + if (index != cursor()->position()) { + cursor()->setPosition(index); + emit q->cursorPositionChanged(); + q->model()->updateCursor(); + } + } + + return val; +} + + +/*! + * \brief Returns true if given position is on pre-edit string. + * Note: preedit starting position is not considered to be on top + */ +bool DuiTextEditPrivate::isPositionOnPreedit(int cursorPosition) const +{ + if (isPreediting() == false) { + return false; + } + + QTextCursor *textCursor = cursor(); + int start = textCursor->anchor(); + int end = textCursor->position(); + return (cursorPosition > start && cursorPosition < end); +} + + +bool DuiTextEditPrivate::isPreediting() const +{ + Q_Q(const DuiTextEdit); + + return (q->mode() == DuiTextEditModel::EditModeActive); +} + + +/*! + * \brief Sends mouse events to input context mouse handling method + * \param position cursor position + * \param event event information + */ +void DuiTextEditPrivate::notifyInputContextMouseHandler(int position, + QGraphicsSceneMouseEvent *event) +{ + if (isPositionOnPreedit(position) == false) { + // only send events on top of preedit + return; + } + + QInputContext *ic = qApp->inputContext(); + + if (ic == 0) { + return; + } + + // translate to normal mouse event and send to input context + QEvent::Type mouseEventType = translateGraphicsSceneMouseTypeToQMouse(event->type()); + QPoint mousePoint = event->screenPos(); // right? + QMouseEvent mouseEvent(mouseEventType, mousePoint, event->button(), + event->buttons(), event->modifiers()); + int preeditOffset = position - cursor()->anchor(); + ic->mouseHandler(preeditOffset, &mouseEvent); +} + + +/*! + * \brief Emits signal copyAvailable if content echo mode is normal + * \param yes bool Signal parameter + */ +void DuiTextEditPrivate::sendCopyAvailable(bool yes) +{ + Q_Q(DuiTextEdit); + if (q->echoMode() != DuiTextEditModel::Normal) { + return; + } + + emit q->copyAvailable(yes); +} + + +/*! + * \brief Translates qgraphics mouse event type to plain mouse type (static) + * \param input event type + */ +QEvent::Type DuiTextEditPrivate::translateGraphicsSceneMouseTypeToQMouse(QEvent::Type input) +{ + QEvent::Type result; + + switch (input) { + case QEvent::GraphicsSceneMouseDoubleClick: + result = QEvent::MouseButtonDblClick; + break; + + case QEvent::GraphicsSceneMousePress: + result = QEvent::MouseButtonPress; + break; + + case QEvent::GraphicsSceneMouseRelease: + result = QEvent::MouseButtonRelease; + break; + + case QEvent::GraphicsSceneMouseMove: + result = QEvent::MouseMove; + break; + + default: + result = QEvent::None; + } + + return result; +} + +QRegion DuiTextEditPrivate::inputMethodArea() +{ + QRegion region; + QInputContext *ic = qApp->inputContext(); + // This property is updated by DuiInputContext itself internally + QVariant prop = ic->property("InputMethodArea"); + if (prop.isValid()) { + // The region is serialized to list of rects + // as QVariant doesn't support QRegion + QList areaList = prop.toList(); + const int count = areaList.count(); + for (int i = 0; i < count; ++i) { + region = region.united(areaList.at(i).toRect()); + } + } + + return region; +} + +void DuiTextEditPrivate::_q_confirmCompletion(const QString &completion) +{ + Q_Q(DuiTextEdit); + if (!completer) + return; + //select prefix + QString prefix = completer->completionPrefix(); + QTextBlock block = cursor()->block(); + int cursorPos = cursor()->position() - block.position(); + QString text = block.text(); + int index = -1; + do { + index++; + index = text.indexOf(prefix, index); + } while ((index >= 0) && (index < cursorPos - prefix.length())); + + //select prefix, then insert confirmed completion, this way is faster than backspacing + commitPreedit(); + cursor()->setPosition(index + block.position()); + cursor()->setPosition(index + block.position() + prefix.length(), QTextCursor::KeepAnchor); + cursor()->removeSelectedText(); + doTextInsert(completion); + q->updateMicroFocus(); +} + + + +/////////////////////////////////////////////// +// Actual class implementation + + +DuiTextEdit::DuiTextEdit(DuiTextEditModel::LineMode type, const QString &text, + QGraphicsItem *parent) + : DuiWidgetController(new DuiTextEditPrivate, new DuiTextEditModel, parent) +{ + setFlag(QGraphicsItem::ItemAcceptsInputMethod, true); + + model()->setDocument(new QTextDocument(text, this->model())); + QTextCursor *cursor = new QTextCursor(document()); + model()->setCursor(cursor); + model()->setLine(type); + + QTextOption option = document()->defaultTextOption(); + option.setTextDirection(layoutDirection()); + + if (type == DuiTextEditModel::SingleLine) { + option.setWrapMode(QTextOption::NoWrap); + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + } else { + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); //Set to expand vertically only in multiline mode + } + + document()->setDefaultTextOption(option); + + cursor->movePosition(QTextCursor::End); + + setFocusPolicy(Qt::ClickFocus); +} + + +DuiTextEdit::~DuiTextEdit() +{ + // kludge so view doesn't receive memberModified() signals for the deleted pointers + model()->beginTransaction(); + + //should delete QTextDocument and QTextCursor + delete model()->document(); + delete model()->cursor(); + + model()->setDocument(NULL); + model()->setCursor(NULL); +} + + +void DuiTextEdit::setSelection(int start, int length, bool useBoundaries) +{ + Q_D(DuiTextEdit); + + if (!isSelectionEnabled()) { + return; + } + + QString text = document()->toPlainText(); + + // boundary check for positions + start = qBound(0, start, text.length()); + length = qBound(-start, length, text.length() - start); + + d->commitPreedit(); + + // determine beginning of selection and the end + int begin; + int end; + + if (length > 0) { + begin = start; + end = start + length; + } else { + begin = qMax(start + length, 0); + end = begin - length; + } + + if (useBoundaries) { + DuiBreakIterator breakIterator(text); + begin = breakIterator.previousInclusive(begin); + + if (breakIterator.isBoundary(end) == false) { + end = breakIterator.next(end); + } + } + + // check if change actually happens + QTextCursor *currentCursor = d->cursor(); + if (begin == currentCursor->anchor() && end == currentCursor->position()) { + return; + } + updateMicroFocus(); + + // make an actual selection + currentCursor->setPosition(begin); + currentCursor->setPosition(end, QTextCursor::KeepAnchor); + + // update mode to selection or basic if needed + if (begin != end) { + if (mode() != DuiTextEditModel::EditModeSelect) { + d->setMode(DuiTextEditModel::EditModeSelect); + d->sendCopyAvailable(true); + } + } else if (mode() != DuiTextEditModel::EditModeBasic) { + bool wasSelecting = hasSelectedText(); + d->setMode(DuiTextEditModel::EditModeBasic); + + if (wasSelecting) { + d->sendCopyAvailable(false); + } + } + + model()->updateCursor(); + + emit selectionChanged(); + + return; +} + + +QString DuiTextEdit::selectedText() const +{ + if (mode() != DuiTextEditModel::EditModeSelect) { + return QString(); + } else { + return textCursor().selectedText(); + } +} + + +bool DuiTextEdit::hasSelectedText() const +{ + return mode() == DuiTextEditModel::EditModeSelect; +} + +int DuiTextEdit::selectionStart() const +{ + if (mode() == DuiTextEditModel::EditModeSelect) { + return textCursor().selectionStart(); + } else { + return -1; + } +} + + +bool DuiTextEdit::isSelectionEnabled() const +{ + return (textInteractionFlags() & + (Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard)) != 0; +} + + +void DuiTextEdit::keyPressEvent(QKeyEvent *event) +{ + Q_D(DuiTextEdit); + + // assuming that just moving the cursor or text copying requires some interaction flag + if (textInteractionFlags() == Qt::NoTextInteraction) { + return; + } + + QTextCursor::MoveOperation moveDirection = QTextCursor::NoMove; + int key = event->key(); + + // first check if this is cursor movement + switch (key) { + case Qt::Key_Left: + moveDirection = QTextCursor::Left; + break; + + case Qt::Key_Right: + moveDirection = QTextCursor::Right; + break; + + case Qt::Key_Down: + moveDirection = QTextCursor::Down; + break; + + case Qt::Key_Up: + moveDirection = QTextCursor::Up; + break; + + } + + // if input was just movement, we're done + if (moveDirection != QTextCursor::NoMove) { + if (mode() != DuiTextEditModel::EditModeBasic) { + d->cursor()->clearSelection(); + model()->setEdit(DuiTextEditModel::EditModeBasic); + emit selectionChanged(); + } + + d->moveCursor(moveDirection, QTextCursor::MoveAnchor, 1); + event->accept(); + return; + } + + if (event->matches(QKeySequence::Copy)) { + copy(); + event->accept(); + return; + } + + if ((textInteractionFlags() & Qt::TextEditable) == 0) { + return; + } + + if (event->matches(QKeySequence::Paste)) { + paste(); + event->accept(); + return; + } + + // we continue by assuming some input is to be made + + // first input made with PasswordEchoOnEdit clears the previous contents + if (echoMode() == DuiTextEditModel::PasswordEchoOnEdit && d->editActive == false) { + clear(); + } + + d->editActive = true; + + bool wasSelecting = hasSelectedText(); + + QTextDocumentFragment selectedFragment; + int selectionStart = -1; + + if (wasSelecting == true) { + selectionStart = d->cursor()->selectionStart(); + selectedFragment = d->cursor()->selection(); + d->cursor()->removeSelectedText(); + + } else { + d->commitPreedit(); + } + + bool accept = false; + + switch (key) { + case Qt::Key_Backspace: + // backspace and delete in selection mode are special cases, only selection is removed + if (wasSelecting == false) { + accept = d->doBackspace(); + } else { + accept = true; + } + break; + + case Qt::Key_Delete: + if (wasSelecting == false) { + accept = d->doDelete(); + } else { + accept = true; + } + break; + + case Qt::Key_Tab: + accept = d->doTab(); + break; + + case Qt::Key_Space: + accept = d->doTextInsert(" "); + break; + + case Qt::Key_Return: + accept = d->doLineBreak(); + break; + + case Qt::Key_plusminus: + accept = d->doSignCycle(); + break; + + default: { + QString text = event->text(); + if (!text.isEmpty() && text.at(0).isPrint()) { + accept = d->doTextInsert(event->text()); + } + } + } + + if (accept == true) { + event->accept(); + + if (wasSelecting == true) { + d->setMode(DuiTextEditModel::EditModeBasic); + emit selectionChanged(); + d->sendCopyAvailable(false); + } + + model()->updateCursor(); + updateMicroFocus(); + emit textChanged(); + emit cursorPositionChanged(); + + } else { + if (wasSelecting == true) { + // need to put the selection back + d->cursor()->setPosition(selectionStart, QTextCursor::KeepAnchor); + d->cursor()->removeSelectedText(); + d->cursor()->insertFragment(selectedFragment); + d->cursor()->setPosition(selectionStart, QTextCursor::KeepAnchor); + } + } +} + +void DuiTextEdit::focusInEvent(QFocusEvent *event) +{ + Q_D(DuiTextEdit); + + if (textInteractionFlags() == Qt::NoTextInteraction) + return; + + d->editActive = false; + + if (sceneManager()) + sceneManager()->requestSoftwareInputPanel(this); + + if (model()->autoSelectionEnabled() == true) { + selectAll(); + } + + if (completer()) { + //The completer can be shared by several widgets, so call its setWidget, + //and connect related slots again when getting focus. + completer()->setWidget(this); + connect(completer(), SIGNAL(confirmed(QString)), + this, SLOT(_q_confirmCompletion(QString))); + connect(this, SIGNAL(textChanged()), + completer(), SLOT(complete())); + } + + emit gainedFocus(event->reason()); + updateMicroFocus(); +} + + +void DuiTextEdit::focusOutEvent(QFocusEvent *event) +{ + Q_UNUSED(event); + Q_D(DuiTextEdit); + + if (textInteractionFlags() == Qt::NoTextInteraction) + return; + + d->commitPreedit(); + deselect(); + + if (d->completer) { + //hide completer when focus out + d->completer->hideCompleter(); + //disconnect related slots when the widget losing focus + disconnect(completer(), 0, this, 0); + } + + emit lostFocus(event->reason()); + if (sceneManager()) + sceneManager()->closeSoftwareInputPanel(); +} + + +bool DuiTextEdit::insert(const QString &text) +{ + Q_D(DuiTextEdit); + + bool wasSelecting = hasSelectedText(); + + // back to basic mode + if ((mode() == DuiTextEditModel::EditModeSelect) && d->cursor()->hasSelection()) { + d->cursor()->removeSelectedText(); + emit selectionChanged(); + } else if (mode() == DuiTextEditModel::EditModeActive) { + d->removePreedit(); + } + + d->setMode(DuiTextEditModel::EditModeBasic); + + if (wasSelecting) { + d->sendCopyAvailable(false); + } + + bool insertionSuccess = d->doTextInsert(text); + + // either something was inserted or something was deleted, or both + if (insertionSuccess || wasSelecting) { + emit textChanged(); + updateMicroFocus(); + } + + return insertionSuccess; +} + + +bool DuiTextEdit::setText(const QString &text) +{ + Q_D(DuiTextEdit); + + int cursorPosBefore = d->cursor()->position(); + bool wasSelecting = hasSelectedText(); + + // clear the state + d->removePreedit(); + d->cursor()->clearSelection(); + document()->clear(); + d->setMode(DuiTextEditModel::EditModeBasic); + + //set cursor to the start again + d->cursor()->movePosition(QTextCursor::Start); + + QString filteredText = text; + + // Limit text length. + filteredText.truncate(maxLength()); + + if (lineMode() == DuiTextEditModel::SingleLine) { + filteredText.replace(QChar('\n'), QChar(' ')); + } + + d->cursor()->insertText(filteredText); + + bool accepted = hasAcceptableInput(); + + if (accepted == true) { + updateMicroFocus(); + emit textChanged(); + + } else { + document()->clear(); + } + + if (d->cursor()->position() != cursorPosBefore) { + emit cursorPositionChanged(); + } + + if (wasSelecting) { + d->sendCopyAvailable(false); + } + + return accepted; +} + + +QString DuiTextEdit::text() const +{ + return document()->toPlainText(); +} + + +int DuiTextEdit::cursorPosition() const +{ + Q_D(const DuiTextEdit); + return d->cursor()->position(); +} + + +bool DuiTextEdit::setCursorPosition(int index) +{ + Q_D(DuiTextEdit); + + d->commitPreedit(); + deselect(); + bool val = d->setCursorPosition(index); + + return val; +} + + +void DuiTextEdit::handleMousePress(int cursorPosition, QGraphicsSceneMouseEvent *event) +{ + Q_D(DuiTextEdit); + + d->notifyInputContextMouseHandler(cursorPosition, event); +} + + +void DuiTextEdit::handleMouseRelease(int eventCursorPosition, QGraphicsSceneMouseEvent *event) +{ + Q_D(DuiTextEdit); + + if (textInteractionFlags() == Qt::NoTextInteraction) + return; + + int cursorPositionBefore = cursorPosition(); + + deselect(); + + if (d->isPositionOnPreedit(eventCursorPosition) == false) { + // input context takes care of releases happening on top of preedit, the rest + // is handled here + d->commitPreedit(); + + QString text = document()->toPlainText(); + DuiBreakIterator breakIterator(text); + QInputContext *ic = qApp->inputContext(); + + // clicks on word boundaries move the cursor + if (breakIterator.isBoundary(eventCursorPosition) == true) { + d->setCursorPosition(eventCursorPosition); + + } else { + if (inputMethodCorrectionEnabled()) { + // clicks on words remove them from the normal contents and makes them preedit. + int start = breakIterator.previousInclusive(eventCursorPosition); + int end = breakIterator.next(eventCursorPosition); + QString preedit = text.mid(start, end - start); + + d->cursor()->setPosition(start); + d->cursor()->setPosition(end, QTextCursor::KeepAnchor); + QTextDocumentFragment preeditFragment = d->cursor()->selection(); + d->cursor()->removeSelectedText(); + + // offer the word to input context as preedit. if the input context accepts it and + // plays nicely, it should offer the preedit right back, changing the mode to + // active. + bool injectionAccepted = false; + + if (ic) { + DuiPreeditInjectionEvent event(preedit); + QCoreApplication::sendEvent(ic, &event); + + injectionAccepted = event.isAccepted(); + } + + // if injection wasn't supported, put the text back and fall back to cursor changing + if (injectionAccepted == false) { + d->cursor()->insertFragment(preeditFragment); + d->setCursorPosition(eventCursorPosition); + } + + } else { + d->setCursorPosition(eventCursorPosition); + } + } + + } else { + d->notifyInputContextMouseHandler(eventCursorPosition, event); + } + + if (cursorPosition() != cursorPositionBefore) { + updateMicroFocus(); + } +} + + +void DuiTextEdit::handleMouseMove(int cursorPosition, QGraphicsSceneMouseEvent *event) +{ + Q_D(DuiTextEdit); + d->notifyInputContextMouseHandler(cursorPosition, event); +} + + +void DuiTextEdit::selectAll() +{ + Q_D(DuiTextEdit); + d->commitPreedit(); + + d->cursor()->setPosition(0); + d->cursor()->movePosition(QTextCursor::End, QTextCursor::KeepAnchor); + + if (d->cursor()->position() > 0) { + // change mode only if there was something to select + if (mode() != DuiTextEditModel::EditModeSelect) { + d->setMode(DuiTextEditModel::EditModeSelect); + } + + model()->updateCursor(); + emit selectionChanged(); + d->sendCopyAvailable(true); + } +} + + +void DuiTextEdit::clear() +{ + setText(""); +} + + +void DuiTextEdit::copy() +{ + QClipboard *clipboard = QApplication::clipboard(); + + if (!hasSelectedText() + || echoMode() != DuiTextEditModel::Normal // only allow copy from normal echo mode entry + || !clipboard) { + return; + } + + clipboard->setText(textCursor().selectedText()); +} + + +void DuiTextEdit::paste() +{ + Q_D(DuiTextEdit); + QClipboard *clipboard = QApplication::clipboard(); + bool wasSelecting = hasSelectedText(); + bool changed = false; + + + if (isReadOnly() || !clipboard) { + return; + } + + QString text = clipboard->text(); + + if (text.isEmpty()) { + return; + } + + // back to basic mode + if (wasSelecting) { + d->cursor()->removeSelectedText(); + emit selectionChanged(); + } else if (mode() == DuiTextEditModel::EditModeActive) { + d->commitPreedit(); + } + + d->setMode(DuiTextEditModel::EditModeBasic); + if (wasSelecting) { + d->sendCopyAvailable(false); + } + + if (d->validator) { + //use slow algorithm if validator was assigned + foreach(const QChar & c, text) { + changed = d->doTextInsert(c) || changed; + } + } else { + changed = d->doTextInsert(text); + } + + if (changed) { + emit textChanged(); + updateMicroFocus(); + } else { + duiDebug("DuiTextEdit") << __PRETTY_FUNCTION__ << "paste failed"; + emit pasteFailed(); + } +} + + +DuiTextEditModel::EditMode DuiTextEdit::mode() const +{ + return model()->edit(); +} + + +DuiTextEditModel::LineMode DuiTextEdit::lineMode() const +{ + return model()->line(); +} + + +Dui::TextContentType DuiTextEdit::contentType() const +{ + return model()->type(); +} + + +void DuiTextEdit::inputMethodEvent(QInputMethodEvent *event) +{ + // FIXME: replacement info not honored. + Q_D(DuiTextEdit); + + QString preedit = event->preeditString(); + QString commitString = event->commitString(); + + if (lineMode() == DuiTextEditModel::SingleLine) { + preedit.replace('\n', ' '); + commitString.replace('\n', ' '); + } + + // get and remove the current selection + const bool wasSelecting = hasSelectedText(); + QTextDocumentFragment selectedFragment; + int selectionStart = -1; + + if (wasSelecting == true) { + selectionStart = d->cursor()->selectionStart(); + selectedFragment = d->cursor()->selection(); + d->cursor()->removeSelectedText(); + } + + const bool wasPreediting = d->isPreediting(); + + d->removePreedit(); + + if (d->editActive == false && + echoMode() == DuiTextEditModel::PasswordEchoOnEdit && + (commitString.isEmpty() == false || preedit.isEmpty() == false)) { + // in this mode, clear the contents before starting editing and doing new input + clear(); + } + + d->editActive = true; + + bool insertionSuccess = false; + + // append possible commit string + if (commitString.isEmpty() == false) { + insertionSuccess = d->doTextInsert(commitString); + + if (insertionSuccess == false && wasSelecting == true) { + // validation failed, put the old selection back + d->cursor()->setPosition(selectionStart, QTextCursor::KeepAnchor); + d->cursor()->removeSelectedText(); + d->cursor()->insertFragment(selectedFragment); + d->cursor()->setPosition(selectionStart, QTextCursor::KeepAnchor); + } + } + + bool changed = false; + + if (insertionSuccess || (preedit.isEmpty() && wasPreediting)) { + // return to basic mode on insertion or removed preedit + d->setMode(DuiTextEditModel::EditModeBasic); + changed = true; + } + + if (!preedit.isEmpty()) { + QList attributes = event->attributes(); + d->setPreeditText(preedit, attributes); + d->setMode(DuiTextEditModel::EditModeActive); + changed = true; + } + + if (changed) { + updateMicroFocus(); + emit textChanged(); + emit cursorPositionChanged(); + } + + if (wasSelecting != hasSelectedText()) { + d->sendCopyAvailable(hasSelectedText()); + } +} + + +void DuiTextEdit::changeEvent(QEvent *event) +{ + if (event->type() == QEvent::LayoutDirectionChange) { + QTextOption option = document()->defaultTextOption(); + option.setTextDirection(layoutDirection()); + document()->setDefaultTextOption(option); + } + + DuiWidgetController::changeEvent(event); +} + + +QTextDocument *DuiTextEdit::document() const +{ + return model()->document(); +} + + +QTextCursor DuiTextEdit::textCursor() const +{ + return QTextCursor(*model()->cursor()); +} + + +void DuiTextEdit::setTextCursor(const QTextCursor &cursor) +{ + Q_D(DuiTextEdit); + + DuiTextEditModel::EditMode newMode; + + if (cursor.hasSelection()) { + newMode = DuiTextEditModel::EditModeSelect; + } else { + newMode = DuiTextEditModel::EditModeBasic; + } + + DuiTextEditModel::EditMode oldMode = model()->edit(); + bool changed = (*model()->cursor() != cursor); + + d->commitPreedit(); + *(d->cursor()) = cursor; + model()->setEdit(newMode); + + if ((newMode == DuiTextEditModel::EditModeSelect && changed) || + (newMode == DuiTextEditModel::EditModeBasic && + oldMode == DuiTextEditModel::EditModeSelect)) { + emit selectionChanged(); + } + + if (changed) { + emit cursorPositionChanged(); + } + + if (echoMode() == DuiTextEditModel::Normal) { + if ((newMode == DuiTextEditModel::EditModeSelect) && (newMode != oldMode)) { + emit copyAvailable(true); + } else if ((newMode == DuiTextEditModel::EditModeBasic) && + oldMode == DuiTextEditModel::EditModeSelect) { + emit copyAvailable(false); + } + } +} + + +void DuiTextEdit::setContentType(Dui::TextContentType type) +{ + Q_D(DuiTextEdit); + Qt::InputMethodHints newHint; + + model()->setType(type); + + // FIXME: doesn't work if model has content type already from somewhere + if (d->ownValidator == true) { + delete d->validator; + } + + d->validator = 0; + + QRegExp rx; + + switch (type) { + case Dui::NumberContentType: + rx.setPattern(NumberCharacterSet); + d->validator = new QRegExpValidator(rx, 0); + setInputMethodCorrectionEnabled(false); + newHint = Qt::ImhFormattedNumbersOnly; + break; + + case Dui::PhoneNumberContentType: + rx.setPattern(PhoneNumberCharacterSet); + d->validator = new QRegExpValidator(rx, 0); + setInputMethodCorrectionEnabled(false); + newHint = Qt::ImhDialableCharactersOnly; + break; + + case Dui::EmailContentType: + rx.setPattern(EmailCharacterSet); + d->validator = new QRegExpValidator(rx, 0); + setInputMethodCorrectionEnabled(false); + setInputMethodAutoCapitalizationEnabled(false); + newHint = Qt::ImhEmailCharactersOnly; + break; + + case Dui::UrlContentType: + setInputMethodAutoCapitalizationEnabled(false); + //TODO: No check rule for URL yet + newHint = Qt::ImhUrlCharactersOnly; + break; + + default: + setInputMethodAutoCapitalizationEnabled(true); + break; + } + + // if a validator was created, we own it + if (d->validator != 0) { + d->ownValidator = true; + } + + setInputMethodHints((inputMethodHints() & ~Qt::ImhExclusiveInputMask) | newHint); +} + + +QVariant DuiTextEdit::inputMethodQuery(Qt::InputMethodQuery query) const +{ + Q_D(const DuiTextEdit); + QTextBlock block = d->cursor()->block(); + + switch ((int)query) { + case Qt::ImCursorPosition: + return QVariant(cursorPosition() - block.position()); + + case Qt::ImSurroundingText: + return QVariant(block.text()); + + case Qt::ImCurrentSelection: + return QVariant(selectedText()); + + case Dui::InputEnabledQuery: + return QVariant(!isReadOnly()); + + case Dui::ImCorrectionEnabledQuery: + return QVariant(inputMethodCorrectionEnabled()); + + case Dui::InputMethodToolbarQuery: + return QVariant(attachedToolbar()); + + default: + return DuiWidgetController::inputMethodQuery(query); + } +} + + +void DuiTextEdit::setTextInteractionFlags(Qt::TextInteractionFlags flags) +{ + Q_D(DuiTextEdit); + + // don't set same flags twice + if (model()->textInteractionFlags() == flags) + return; + + model()->setTextInteractionFlags(flags); + + // if not editable, remove focus and hide cursor. Commit preedit + if (!(model()->textInteractionFlags() & Qt::TextEditable)) { + d->commitPreedit(); + setFocusPolicy(Qt::NoFocus); + + } else { + setFocusPolicy(Qt::ClickFocus); + } + + // TODO: notify input context if editability changed + + // TODO: Check other flags (Qt::TextSelectableByKeyboard etc) if necessary +} + + +Qt::TextInteractionFlags DuiTextEdit::textInteractionFlags() const +{ + return model()->textInteractionFlags(); +} + + +bool DuiTextEdit::isReadOnly() const +{ + Qt::TextInteractionFlags flags = textInteractionFlags(); + return !(flags & Qt::TextEditable); +} + + +void DuiTextEdit::setReadOnly(bool readOnly) +{ + Qt::TextInteractionFlags flags = textInteractionFlags(); + + if (readOnly == true) { + flags = flags & ~Qt::TextEditable; + } else { + flags = flags | Qt::TextEditable; + } + + setTextInteractionFlags(flags); +} + + +DuiTextEditModel::EchoMode DuiTextEdit::echoMode() const +{ + return model()->echo(); +} + + +void DuiTextEdit::setEchoMode(DuiTextEditModel::EchoMode echoMode) +{ + model()->setEcho(echoMode); + if (echoMode != DuiTextEditModel::Normal) { + setInputMethodHints(inputMethodHints() | Qt::ImhHiddenText); + setInputMethodCorrectionEnabled(false); + + } else { + setInputMethodHints(inputMethodHints() & ~Qt::ImhHiddenText); + } + + if (mode() == DuiTextEditModel::EditModeSelect) { + emit copyAvailable(echoMode == DuiTextEditModel::Normal); + } +} + + +void DuiTextEdit::deselect() +{ + Q_D(DuiTextEdit); + + if (mode() == DuiTextEditModel::EditModeSelect) { + d->cursor()->clearSelection(); + d->setMode(DuiTextEditModel::EditModeBasic); + model()->updateCursor(); + d->sendCopyAvailable(false); + updateMicroFocus(); + } +} + + +bool DuiTextEdit::isAutoSelectionEnabled() const +{ + return isSelectionEnabled() && model()->autoSelectionEnabled(); +} + + +void DuiTextEdit::setAutoSelectionEnabled(bool enable) +{ + model()->setAutoSelectionEnabled(enable); +} + + +void DuiTextEdit::setInputMethodCorrectionEnabled(bool enabled) +{ + // only allow setting correction enabled for normal echo mode + if (echoMode() == DuiTextEditModel::Normal || enabled == false) { + model()->setInputMethodCorrectionEnabled(enabled); + } +} + + +bool DuiTextEdit::inputMethodCorrectionEnabled() const +{ + return model()->inputMethodCorrectionEnabled(); +} + + +void DuiTextEdit::setInputMethodPredictionEnabled(bool enabled) +{ + model()->setInputMethodPredictionEnabled(enabled); + if (enabled) { + setInputMethodHints(inputMethodHints() & ~Qt::ImhNoPredictiveText); + } else { + setInputMethodHints(inputMethodHints() | Qt::ImhNoPredictiveText); + } +} + +bool DuiTextEdit::inputMethodPredictionEnabled() const +{ + return !(inputMethodHints() & Qt::ImhNoPredictiveText); +} + +int DuiTextEdit::maxLength() const +{ + return model()->maxLength(); +} + +void DuiTextEdit::setMaxLength(int numChars) +{ + if (numChars < 0) { + numChars = 0; + } + model()->setMaxLength(numChars); + + // Bug in QTextDocument::characterCount? + int characterCount = document()->characterCount() - 1; + Q_ASSERT(characterCount >= 0); + + if (characterCount > maxLength()) { + Q_D(DuiTextEdit); + + // If we have preedit commit it first + d->commitPreedit(); + + // Make sure we're not in selection mode. + d->setMode(DuiTextEditModel::EditModeBasic); + + // Check again + characterCount = document()->characterCount() - 1; + if (characterCount > maxLength()) { + // Select everything after position maxLength and remove the selection. + d->setCursorPosition(maxLength()); + d->moveCursor(QTextCursor::End, QTextCursor::KeepAnchor); + d->cursor()->removeSelectedText(); + } + } +} + +void DuiTextEdit::setInputMethodAutoCapitalizationEnabled(bool enabled) +{ + model()->setInputMethodAutoCapitalizationEnabled(enabled); + if (enabled) { + setInputMethodHints(inputMethodHints() & ~Qt::ImhNoAutoUppercase); + } else { + setInputMethodHints(inputMethodHints() | Qt::ImhNoAutoUppercase); + } +} + + +bool DuiTextEdit::inputMethodAutoCapitalizationEnabled() const +{ + return !(inputMethodHints() & Qt::ImhNoAutoUppercase); +} + + +void DuiTextEdit::setPrompt(const QString &prompt) +{ + // TODO: should replace newlines with spaces in single line? + model()->setPrompt(prompt); +} + + +QString DuiTextEdit::prompt() const +{ + return model()->prompt(); +} + + +void DuiTextEdit::setValidator(const QValidator *validator) +{ + Q_D(DuiTextEdit); + + if (d->ownValidator == true) { + delete d->validator; + } + + d->validator = validator; + d->ownValidator = false; +} + + +const QValidator *DuiTextEdit::validator() const +{ + Q_D(const DuiTextEdit); + return d->validator; +} + + +bool DuiTextEdit::hasAcceptableInput() const +{ + Q_D(const DuiTextEdit); + + if (d->validator == 0) { + return true; + } else { + QString textCopy = model()->document()->toPlainText(); + int cursorCopy = model()->cursor()->position(); + QValidator::State result = d->validator->validate(textCopy, cursorCopy); + return (result == QValidator::Acceptable); + } +} + +void DuiTextEdit::setCompleter(DuiCompleter *completer) +{ + Q_D(DuiTextEdit); + if (completer == d->completer) + return; + if (d->completer) { + disconnect(d->completer, 0, this, 0); + d->completer->setWidget(0); + } + + d->completer = completer; + if (d->completer) { + d->completer->setWidget(this); + setInputMethodCorrectionEnabled(false); + + if (hasFocus()) { + updateMicroFocus(); + connect(d->completer, SIGNAL(confirmed(QString)), + this, SLOT(_q_confirmCompletion(QString))); + } + } +} + +DuiCompleter *DuiTextEdit::completer() +{ + Q_D(DuiTextEdit); + return d->completer; +} + +void DuiTextEdit::attachToolbar(const QString &name) +{ + model()->setToolbar(name); +} + +QString DuiTextEdit::attachedToolbar() const +{ + return model()->toolbar(); +} + +#include "moc_duitextedit.cpp" diff --git a/src/widgets/duitextedit.h b/src/widgets/duitextedit.h new file mode 100644 index 000000000..8da72913c --- /dev/null +++ b/src/widgets/duitextedit.h @@ -0,0 +1,456 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUITEXTEDIT_H +#define DUITEXTEDIT_H + +#include +#include +#include "duinamespace.h" + +class DuiTextEditPrivate; +class QTextDocument; +class QTextCursor; +class QValidator; +class DuiCompleter; + + +/*! + * \class DuiTextEdit + * \brief DuiTextEdit is used to edit and display both plain and rich text. + * + * This widget can be used to show text and allow user to edit it. + * Roughly corresponds Qt's QTextEdit and QLineEdit widgets, the LineMode + * determines which. The mode can be set only at the constructor. + * + * DuiTextEdit can operate in single or multiline mode. + * In single line mode no new lines can be added. If the text + * is too long to fit inside the widget, it can be scrolled horizontally in the + * basic DuiTextEditView, but + * text will not be wrapped to new lines. In multi line mode new lines can be + * added as necessary. The widget may also grow to make room for new lines, and + * if that is not enough, contents can be scrolled horizontally. + * + * Caution: please do not use setInputMethodHints(Qt::InputMethodHints) with + * objects of this class, you have to use setContentType, setInputMethodCorrectionEnabled, + * setMaskedInput and other similar function instead. + * + * If you just need to display a small text snippet then you should use + * DuiLabel instead. + * + */ +class DUI_EXPORT DuiTextEdit : public DuiWidgetController +{ + Q_OBJECT + DUI_CONTROLLER(DuiTextEdit) + + Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged USER true) + // TODO: following type should be Dui::TextContentType, unfortunately due to a moc bug, + // such code doesn't compile with the current Qt. Need to change this when it works. + Q_PROPERTY(TextContentType contentType READ contentType WRITE setContentType) + Q_PROPERTY(Qt::TextInteractionFlags textInteractionFlags READ textInteractionFlags WRITE setTextInteractionFlags) + Q_PROPERTY(QString prompt READ prompt WRITE setPrompt) + + Q_PROPERTY(bool inputMethodCorrectionEnabled READ inputMethodCorrectionEnabled WRITE setInputMethodCorrectionEnabled) + Q_PROPERTY(bool isReadOnly READ isReadOnly WRITE setReadOnly) + Q_PROPERTY(bool inputMethodAutoCapitalizationEnabled READ inputMethodAutoCapitalizationEnabled WRITE setInputMethodAutoCapitalizationEnabled) + Q_PROPERTY(QString selectedText READ selectedText) //TODO: not usable from outside at the moment, DUI_MODEL_PROPERTY always need set and get function. + Q_PROPERTY(bool autoSelectionEnabled READ isAutoSelectionEnabled WRITE setAutoSelectionEnabled) + Q_PROPERTY(bool inputMethodPredictionEnabled READ inputMethodPredictionEnabled WRITE setInputMethodPredictionEnabled) + Q_PROPERTY(int maxLength READ maxLength WRITE setMaxLength) + Q_PROPERTY(DuiTextEditModel::EchoMode echoMode READ echoMode WRITE setEchoMode) + +public: + typedef Dui::TextContentType TextContentType; // workaround for moc bug + + /*! + * \brief Default constructor. Creates a textedit field with a specified text and line mode. + * \param type widget type (single line or multiline) + * \param text optional text. + * \param parent optional parent. + */ + explicit DuiTextEdit(DuiTextEditModel::LineMode type = DuiTextEditModel::SingleLine, + const QString &text = QString(), QGraphicsItem *parent = 0); + + /*! + \brief Destructor + */ + virtual ~DuiTextEdit(); + + /** + * \brief Returns cursor position inside the text edit field. + * \return cursor position of the text edit widget. + */ + int cursorPosition() const; + + /** + * \brief Returns the edit mode of the text edit widget. + * \return the edit mode. + */ + DuiTextEditModel::EditMode mode() const; + + /** + * \brief Returns the line mode of the text edit widget. + * \return the line mode. + */ + DuiTextEditModel::LineMode lineMode() const; + + /** + * \brief Returns the content type of the text edit widget. + */ + Dui::TextContentType contentType() const; + + /*! + * \brief Returns current text + * \return QString containing current widget text + */ + QString text() const; + + /*! + * \brief Returns the current document + * \return pointer to the document + */ + QTextDocument *document() const; + + /*! + * \brief Returns a copy of the currently visible cursor. + */ + QTextCursor textCursor() const; + + /*! + * \brief Sets the currently visible cursor. + */ + void setTextCursor(const QTextCursor &cursor); + + /*! + * \brief set content type + */ + void setContentType(Dui::TextContentType type); + + /*! + * \brief Set text interaction flags + * \param flags @see Qt::TextInteractionFlags + */ + void setTextInteractionFlags(Qt::TextInteractionFlags); + + /*! + * \brief Text interaction flags @see Qt::TextInteractionFlags + * \return Text interaction flags + */ + Qt::TextInteractionFlags textInteractionFlags() const; + + // The mouse handling is a bit complex. The controller receives the events first and + // passes them to view. However, the controller has to notify input context on events + // happening on top of preedit, so views should use the following methods back. + // Right now release handler does lot of state changes. Mostly because it involves + // input context which is kept out of view. This results in quite tightly coupled + // controller and view. Might be better to later move some more mouse logic to the view. + + /*! + * \brief Handle mouse press event on the widget. THIS IS PURELY FOR THE VIEW. + * View should call this when receiving mouse presses that may happen on preedit (active mode). + * The implementation will notify possible input context. + * \param cursorPosition position of the click within characters + * \param event event the view received + */ + void handleMousePress(int cursorPosition, QGraphicsSceneMouseEvent *event); + + /*! + * \brief Handle mouse release event on the widget. THIS IS PURELY FOR THE VIEW. + * View should call this on mouse releases, except when release ends a selection the view + * has not started. + * The implementation will notify possible input context, relocate the cursor or make + * clicked word as preedit if possible. + * \param cursorPosition position of the click within characters + * \param event event the view received + */ + void handleMouseRelease(int cursorPosition, QGraphicsSceneMouseEvent *event); + + /*! + * \brief Handle mouse move event on the widget. THIS IS PURELY FOR THE VIEW. + * View should call this when receiving mouse moves that may happen on preedit (active mode). + * The implementation will notify possible input context. + * \param cursorPosition position of the click within characters + * \param event event the view received + */ + void handleMouseMove(int cursorPosition, QGraphicsSceneMouseEvent *event); + + /*! + * \brief Returns whether the text entry is read only + */ + bool isReadOnly() const; + + /*! + * \brief If readOnly equal true, then set the text entry to read only, vice versa + */ + void setReadOnly(bool); + + /*! + * \brief Returns the current echo mode + */ + DuiTextEditModel::EchoMode echoMode() const; + + /*! + * \brief Sets the echo mode which determines how input is made visible. + */ + void setEchoMode(DuiTextEditModel::EchoMode echoMode); + + /*! + * \brief removes any selection and changes mode to basic + */ + void deselect(); + + /*! + * \brief Selects text from word boundary to another so that start and start+length are + included in the selection + */ + void setSelection(int start, int length, bool useBoundaries = false); + + /* + * \brief returns the index of first selected character in the widget or -1 if no text is + * selected + */ + int selectionStart() const; + + /* + * \brief returns the selected text or empty string if no text is selected + */ + QString selectedText() const; + + //! Returns true if some or all of the text has been selected + bool hasSelectedText() const; + + /*! + * \brief tell whether text is allowed to be selected + * \return true if text selection is allowed, otherwise false + */ + bool isSelectionEnabled() const; + + /*! + * \brief Returns whether text should be selected when focus is gained + */ + bool isAutoSelectionEnabled() const; + + /*! + * \brief Enables or disables text auto selection + * if enabled, all text will be selected when focus is gained + */ + void setAutoSelectionEnabled(bool enable); + + /** + * \brief sets correction on the input method server side to be enabled or disabled + */ + void setInputMethodCorrectionEnabled(bool enabled); + + /** + * \brief returns if correction support is enabled for input method servers + */ + bool inputMethodCorrectionEnabled() const; + + /** + * \brief sets word prediction on the input method server side to be enabled or disabled + */ + void setInputMethodPredictionEnabled(bool enabled); + + /** + * \brief returns if word prediction support is enabled for input method servers + */ + bool inputMethodPredictionEnabled() const; + + /** + * \brief Returns maximum allowed length for text in the text edit. + */ + int maxLength() const; + + /** + * \brief Sets the maximum allowed length for text in the text edit. + * + * It is still possible, however, to exceed the maximum by inserting text + * with QTextCursor::insertText(). + * + * If truncation occurs any selected text will be unselected. + * + * \param[in] numChars The number of characters to set as maximum length. + */ + void setMaxLength(int numChars); + + /* + * \brief sets auto-capitalization on the input method server side to be enabled or disabled + */ + void setInputMethodAutoCapitalizationEnabled(bool enabled); + + /* + * \brief returns if auto-capitalization support is enabled for input method servers + */ + bool inputMethodAutoCapitalizationEnabled() const; + + /*! + * \brief sets prompt value + * \param prompt prompt text + * Prompt is shown inside text entry when the entry doesn't have focus or contents + */ + void setPrompt(const QString &prompt); + + /*! + * \brief returns current prompt text + */ + QString prompt() const; + + /*! + * \brief sets the DuiTextEdit only to accept input that the validator accepts. + * \param validator the validator for input text + * Validator will check that current paragraph validates after text insertion, and + * disallows insertion on validation failure. The whole content is used to check + * on hasAcceptableInput(). Note: Checking per paragraph doesn not include the possible + * paragraph ending newline. + */ + void setValidator(const QValidator *validator); + + /*! + * \brief returns a pointer to the current validator or 0 if no validator is used + */ + const QValidator *validator() const; + + /*! + * \brief returns boolean value that indicates if input satisfies the validator + */ + bool hasAcceptableInput() const; + + /*! + * \brief Sets this text edit to provide auto completions from the completer. + */ + void setCompleter(DuiCompleter *completer); + + /*! + * \brief Returns the completer pointer, which is used by this text edit. + */ + DuiCompleter *completer(); + + /*! + * \brief Attaches a custom toolbar named \a name. + */ + void attachToolbar(const QString &name); + + /*! + * \brief Returns the name of current attached custom toolbar. + */ + QString attachedToolbar() const; + +public Q_SLOTS: + /** + * \brief Set text for this widget. This replaces the existing text. + * \param text New text for this text edit widget. + * \return false if \a text is not allowed to be set. + * On successful insertion, the cursor is moved to the end of the text + */ + bool setText(const QString &text); + + /** + * \brief deletes any selection or preedit, and inserts text to the cursor position + * \param text text to insert + * \return true if \a text was accepted + */ + bool insert(const QString &text); + + /*! + * \brief Sets the cursor position of the text edit field. Moves to basic mode by committing + * preedit and removing selection. + * \param index The index at which the cursor appears. + * \return false if \a index is an invalid cursor position. + */ + bool setCursorPosition(int index); + + /*! + * \brief makes the whole document text selected. No-op if there is no content. + */ + void selectAll(); + + /*! + * \brief deletes all content in the widget + */ + void clear(); + + /*! + * \brief Copies the selected text to the clipboard. + * If there is no selected text nothing happens. + */ + void copy(); + + /*! + * \brief Pastes the plain text from the clipboard into the text edit at the current cursor position. + * If there is no text in the clipboard nothing happens. + * If clipboard content is rejected by assigned validator then signal pasteFailed() is emitted. + */ + void paste(); + +Q_SIGNALS: + /** + * \brief A signal which is emitted whenever the widget gets the focus. + */ + void gainedFocus(Qt::FocusReason); + + /** + * \brief A signal which is emitted whenever the widget lost the focus. + */ + void lostFocus(Qt::FocusReason); + + /** + * \brief A signal which is emitted whenever the text has been changed. + */ + void textChanged(); + + //! \brief This signal is emitted whenever the selection changes + void selectionChanged(); + + //! \brief A signal to be emitted when the cursor position changes + void cursorPositionChanged(); + + //! \brief This signal is emitted when text is selected or de-selected in the text edit. + // When text is selected this signal will be emitted with yes set to true. + // If no text has been selected or if the selected text is de-selected this signal is emitted with yes set to false. + void copyAvailable(bool yes); + + /*! + * \brief This signal is emitted when paste is failed and nothing was inserted + */ + void pasteFailed(); + +protected: + /*! \reimp */ + virtual void keyPressEvent(QKeyEvent *event); + virtual void focusInEvent(QFocusEvent *event); + virtual void focusOutEvent(QFocusEvent *event); + virtual void inputMethodEvent(QInputMethodEvent *); + virtual void changeEvent(QEvent *event); + virtual QVariant inputMethodQuery(Qt::InputMethodQuery query) const; + /*! \reimp_end */ + +private: + Q_DECLARE_PRIVATE(DuiTextEdit) + Q_DISABLE_COPY(DuiTextEdit) + + friend class DuiCompleter; +#ifdef UNIT_TEST + friend class Ut_DuiTextEdit; + friend class Ut_DuiTextEditView; +#endif + Q_PRIVATE_SLOT(d_func(), void _q_confirmCompletion(const QString &)) +}; + +#endif diff --git a/src/widgets/duitextedit_p.h b/src/widgets/duitextedit_p.h new file mode 100644 index 000000000..7b67a2b96 --- /dev/null +++ b/src/widgets/duitextedit_p.h @@ -0,0 +1,88 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUITEXTEDIT_P_H +#define DUITEXTEDIT_P_H + +#include +#include +#include +#include + +class QGraphicsSceneMouseEvent; +class QValidator; +class DuiCompleter; + +#include "private/duiwidgetcontroller_p.h" +#include "duitextedit.h" + +class DuiNavigationBar; + +class DuiTextEditPrivate : public DuiWidgetControllerPrivate +{ + Q_DECLARE_PUBLIC(DuiTextEdit) + +public: + DuiTextEditPrivate(); + virtual ~DuiTextEditPrivate(); + + QTextCursor *cursor() const; + void moveCursor(QTextCursor::MoveOperation moveOp, + QTextCursor::MoveMode moveMode = QTextCursor::MoveAnchor, int n = 1); + + bool doBackspace(); + bool doDelete(); + bool doTab(); + bool doTextInsert(const QString &text); + bool doLineBreak(); + bool doSignCycle(); + + bool validateCurrentBlock(); + + bool setCursorPosition(int index); + + void setPreeditText(const QString &text, + const QList &attributes); + void commitPreedit(); + void removePreedit(); + bool isPositionOnPreedit(int cursorPosition) const; + bool isPreediting() const; + + void setMode(DuiTextEditModel::EditMode mode); + + void notifyInputContextMouseHandler(int position, QGraphicsSceneMouseEvent *event); + + void sendCopyAvailable(bool yes); + + static QEvent::Type translateGraphicsSceneMouseTypeToQMouse(QEvent::Type input); + + QRegion inputMethodArea(); + + void _q_confirmCompletion(const QString &); + +private: + const QValidator *validator; + bool ownValidator; // setting content type creates a validator that the widget owns + + DuiCompleter *completer; + + bool editActive; // true if editing started after getting focus +}; + +#endif diff --git a/src/widgets/duitexteditmodel.h b/src/widgets/duitexteditmodel.h new file mode 100644 index 000000000..ff6c656c2 --- /dev/null +++ b/src/widgets/duitexteditmodel.h @@ -0,0 +1,97 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUITEXTEDITMODEL_H +#define DUITEXTEDITMODEL_H + +#include +#include +#include +#include "duinamespace.h" + +class DUI_EXPORT DuiTextEditModel : public DuiWidgetModel +{ + Q_OBJECT + DUI_MODEL_INTERNAL(DuiTextEditModel) + +public: + + //! Edit mode for DuiTextEdit + enum EditMode { + //! The main mode of operation, no selection or preedit + EditModeBasic, + + //! preedit editing initiated + EditModeActive, + + //! Text selected + EditModeSelect + }; + + //! Line mode for DuiTextEdit, single line or multiline + enum LineMode { + //! Only one line allowed, no more can be created + SingleLine, + + //! May have arbitrary number of lines + MultiLine + }; + + enum EchoMode { + //! Display characters as they are entered, default. + Normal, + + //! Do not display entered characters. + NoEcho, + + //! Entered characters are replaced by mask characters. + Password, + + //! Input is displayed clear text while doing input, replaced by mask characters afterwards. + PasswordEchoOnEdit + }; + +private: + + DUI_MODEL_PROPERTY(DuiTextEditModel::EditMode, edit, Edit, true, DuiTextEditModel::EditModeBasic) + DUI_MODEL_PROPERTY(DuiTextEditModel::LineMode, line, Line, true, DuiTextEditModel::SingleLine) + DUI_MODEL_PTR_PROPERTY(QTextDocument *, document, Document, true, NULL) + DUI_MODEL_PTR_PROPERTY(QTextCursor *, cursor, Cursor, true, NULL) + + DUI_MODEL_PROPERTY(QString, text, Text, true, QString()) + DUI_MODEL_PROPERTY(Dui::TextContentType, type, Type, true, Dui::FreeTextContentType) + DUI_MODEL_PROPERTY(Qt::TextInteractionFlags, textInteractionFlags, TextInteractionFlags, true, Qt::TextEditorInteraction) + + DUI_MODEL_PROPERTY(bool, inputMethodCorrectionEnabled, InputMethodCorrectionEnabled, true, true) + DUI_MODEL_PROPERTY(bool, isReadOnly, ReadOnly, true, false) + DUI_MODEL_PROPERTY(bool, inputMethodAutoCapitalizationEnabled, InputMethodAutoCapitalizationEnabled, true, true) + DUI_MODEL_PROPERTY(bool, autoSelectionEnabled, AutoSelectionEnabled, true, false) + DUI_MODEL_PROPERTY(bool, inputMethodPredictionEnabled, InputMethodPredictionEnabled, true, false) + DUI_MODEL_PROPERTY(int, maxLength, MaxLength, true, std::numeric_limits::max()) + DUI_MODEL_PROPERTY(QString, prompt, Prompt, true, QString()) + DUI_MODEL_PROPERTY(QString, toolbar, Toolbar, true, QString()) + DUI_MODEL_PROPERTY(DuiTextEditModel::EchoMode, echo, Echo, true, DuiTextEditModel::Normal) + +public: + void updateCursor() { + memberModified(DuiTextEditModel::Cursor); + } +}; + +#endif diff --git a/src/widgets/duitoolbar.cpp b/src/widgets/duitoolbar.cpp new file mode 100644 index 000000000..08bc64238 --- /dev/null +++ b/src/widgets/duitoolbar.cpp @@ -0,0 +1,71 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duitoolbar.h" +#include "duitoolbar_p.h" + +#include +#include + +#include "duitheme.h" +#include "duiwidgetaction.h" +#include "duibutton.h" +#include "duibuttongroup.h" +#include "duiwidget.h" + +#include "duiwidgetcreator.h" +DUI_REGISTER_WIDGET(DuiToolBar) + +DuiToolBarPrivate::DuiToolBarPrivate() +{ +} + +DuiToolBarPrivate::~DuiToolBarPrivate() +{ +} + +void DuiToolBarPrivate::initLayout() +{ + Q_Q(DuiToolBar); + + QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(); + layout->setContentsMargins(0, 0, 0, 0); + layout->setSpacing(0); + q->setLayout(layout); +} + +DuiToolBar::DuiToolBar(QGraphicsItem *parent, const QString &viewType) + : DuiWidgetController(new DuiToolBarPrivate(), new DuiWidgetModel(), parent) +{ + Q_D(DuiToolBar); + d->initLayout(); + Q_UNUSED(viewType); +} + +DuiToolBar::DuiToolBar(DuiToolBarPrivate *dd, DuiWidgetModel *model, QGraphicsItem *parent) + : DuiWidgetController(dd, model, parent) +{ + Q_D(DuiToolBar); + d->initLayout(); +} + +DuiToolBar::~DuiToolBar() +{ +} + diff --git a/src/widgets/duitoolbar.h b/src/widgets/duitoolbar.h new file mode 100644 index 000000000..85799604f --- /dev/null +++ b/src/widgets/duitoolbar.h @@ -0,0 +1,134 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUITOOLBAR_H +#define DUITOOLBAR_H + +#include "duiwidgetcontroller.h" + +class DuiToolBarPrivate; + +/*! + \class DuiToolBar + \brief DuiToolBar provides a container for buttons and text input field. + + \ingroup widgets + + \section DuiToolBarOverview Overview + Toolbar is a container for buttons and text input field. It contains actions that are + relevant to the view but not related to any individual item displayed directly within + the content area. + + This class is not recommended to be used directly instead action can be added to + the toolbar in the page using: + action->setLocation(DuiAction::ToolBarLocation); + + Setting up a new toolbar is quite easy. The following example shows how actions are added + to a toolbar. + \code + DuiToolBar* toolbar = new DuiToolBar(); + DuiAction * iconAction = new DuiAction("Icon-pictures","Pictures", this); + iconAction->setLocation(DuiAction::ToolBarLocation); + toolbar->addAction(iconAction); + DuiTextEdit *entry = new DuiTextEdit(); + entry->setViewType("toolbar"); + DuiWidgetAction *action = new DuiWidgetAction(this); + action->setLocation(DuiAction::ToolBarLocation); + action->setWidget(entry); + toolbar->addAction(action); + \endcode + + \section DuiToolBarUseGuidelines Usage guidelines + - The toolbar is functionally in the same role as in the view menu: it has commands that + are not related specifically to any content item or button displayed within the contents + of the view. + - The toolbar should be utilized only if the commands are expected to be used often. The + toolbar takes away space from the content area. If the commands are not important to the + view and the main use cases, it is recommendable to not have a toolbar at all, and place + the commands in the view menu. Similarly, reconsider your design if you would have only + one or two buttons to the toolbar; commands can be placed to the view menu, or embedded + to the view. + - Note that the toolbar is not scalable: do not place commands in the toolbar if the view is + expected to grow with more functionalities in the future. + - The commands in the toolbar and in the view menu are not to be duplicated. + - Since the Direct UI style has no focus for the items in the content view, it is not + possible to create toolbars that have actions that affect on a single item on screen. For + instance you shouldn't design a toolbar with "Reply", "Delete", "Move" etc. commands, if + the assumption is that these commands would apply only to a single item. + - The toolbar affects the scrollable area and the scroll position indicator in portrait mode. + The scrollable area ends on top of the toolbar (so that the latest in the list should not + end up being stuck behind the toolbar) + - The user is not able to personalize the contents of the toolbar. The application designer + decides what is shown in toolbar and what in view menu. + - Application design can also decide whether toolbar is used in both landscape and portrait + modes. For example, a toolbar can be shown only in landscape mode, and then in portrait + mode the functionalities are provided somewhere else (for instance in the view menu). + - The toolbar can be hidden if application designer decides so, for example when using + full-screen media, virtual keyboard or web browser. Toolbar is hidden and shown together + with command area. + - The toolbar remains in a fixed position on screen, on top of contents that are displayed. + + \section DuiToolBarVariants Variants + \li \link DuiToolBarView Default toolbar view \endlink + + \section DuiToolBarOpenIssues Open issues + + \sa DuiToolbarStyle +*/ + +class DUI_EXPORT DuiToolBar : public DuiWidgetController +{ + Q_OBJECT + +public: + + /*! + \brief Constructs a toolbar containing no actions with optional \a parent + and \a viewType + */ + DuiToolBar(QGraphicsItem *parent = 0, const QString &viewType = ""); + + /*! + \brief Destructs the toolbar object. + */ + virtual ~DuiToolBar(); + +protected: + + /*! + \brief protected constructor + \param dd Shared private class + \param model The model. This must not be NULL. + \param parent Parent widget + */ + DuiToolBar(DuiToolBarPrivate *dd, DuiWidgetModel *model, QGraphicsItem *parent); + + Q_DECLARE_PRIVATE(DuiToolBar) + +private: + Q_DISABLE_COPY(DuiToolBar) + + friend class DuiToolBarView; + +#ifdef UNIT_TEST + friend class Ut_DuiToolBar; +#endif +}; + +#endif diff --git a/src/widgets/duitoolbar_p.h b/src/widgets/duitoolbar_p.h new file mode 100644 index 000000000..5cd1e395e --- /dev/null +++ b/src/widgets/duitoolbar_p.h @@ -0,0 +1,41 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUITOOLBAR_P_H +#define DUITOOLBAR_P_H + +#include "private/duiwidgetcontroller_p.h" + +class DuiAction; +class DuiWidget; +class DuiButton; + +class DuiToolBarPrivate : public DuiWidgetControllerPrivate +{ + Q_DECLARE_PUBLIC(DuiToolBar) + +public: + DuiToolBarPrivate(); + virtual ~DuiToolBarPrivate(); + + + void initLayout(); +}; + +#endif diff --git a/src/widgets/duiviewcreator.cpp b/src/widgets/duiviewcreator.cpp new file mode 100644 index 000000000..599a49bd4 --- /dev/null +++ b/src/widgets/duiviewcreator.cpp @@ -0,0 +1,32 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiviewcreator.h" +#include "duiclassfactory.h" + +DuiViewCreatorBase::DuiViewCreatorBase(const char *viewClassName) +{ + DuiClassFactory::instance()->registerViewCreator(this, viewClassName); +} + +DuiViewCreatorBase::~DuiViewCreatorBase() +{ + DuiClassFactory::instance()->unregisterViewCreator(this); +} + diff --git a/src/widgets/duiviewcreator.h b/src/widgets/duiviewcreator.h new file mode 100644 index 000000000..575884a2c --- /dev/null +++ b/src/widgets/duiviewcreator.h @@ -0,0 +1,78 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIVIEWCREATOR_H +#define DUIVIEWCREATOR_H + +#include "duiexport.h" +#include + +#define DUI_REGISTER_VIEW_NEW(VIEW, CONTROLLER) \ + static const DuiViewCreator g_ViewCreator(#VIEW); + + +#define DUI_REGISTER_VIEW(VIEW, CONTROLLER) \ + static const DuiViewCreator g_ViewCreator(#VIEW); + +// forward declarations +class DuiWidgetView; +class DuiWidgetController; + +// base class for DuiViewCreators +// you can implement your own creator or use DuiViewCreator template class with +// DUI_REGISTER_VIEW-macro. +class DUI_EXPORT DuiViewCreatorBase +{ +public: + DuiViewCreatorBase(const char *viewClassName); + virtual ~DuiViewCreatorBase(); + /*! + Returns new style instance. + Ownership is transferred to caller. + */ + virtual DuiWidgetView *create(const DuiWidgetController *controller) const = 0; + + /*! + Returns the type of the style the view uses. + */ + virtual const char *styleType() const = 0; +}; + +template +class DUI_EXPORT DuiViewCreator : public DuiViewCreatorBase +{ +public: + DuiViewCreator(const char *viewClassName) : + DuiViewCreatorBase(viewClassName) + {} + virtual ~DuiViewCreator() + {} + + virtual DuiWidgetView *create(const DuiWidgetController *controller) const { + return new VIEW((CONTROLLER *)controller); + //return new VIEW(dynamic_cast(controller)); + } + + virtual const char *styleType() const { + return VIEW::staticStyleType(); + } +}; + +#endif + diff --git a/src/widgets/duiwidgetlistmodel_p.h b/src/widgets/duiwidgetlistmodel_p.h new file mode 100644 index 000000000..d073704dd --- /dev/null +++ b/src/widgets/duiwidgetlistmodel_p.h @@ -0,0 +1,37 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIWIDGETLISTMODEL_P_H +#define DUIWIDGETLISTMODEL_P_H + +class DuiWidget; + +class DuiWidgetListModelPrivate +{ + +public: + DuiWidgetListModelPrivate(); + ~DuiWidgetListModelPrivate(); + + QList widgets; + QList groupHeaders; + +}; + +#endif diff --git a/src/widgets/duiwidgetmodel.cpp b/src/widgets/duiwidgetmodel.cpp new file mode 100644 index 000000000..67541f292 --- /dev/null +++ b/src/widgets/duiwidgetmodel.cpp @@ -0,0 +1,134 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiwidgetmodel.h" +#include "duiwidgetmodel_p.h" + +#include +#include + +/////////////////// +// PRIVATE CLASS // +/////////////////// +DuiWidgetModelPrivate::DuiWidgetModelPrivate() : + transactionInProgress(false), + referenceCount(0) +{ +} + +DuiWidgetModelPrivate::~DuiWidgetModelPrivate() +{ +} + +////////////////// +// PUBLIC CLASS // +////////////////// + +void DuiWidgetModel::memberModified(const char *const member) +{ + if (d_ptr->transactionInProgress) { + d_ptr->modifiedMembers.enqueue(member); + } else { + QList list; + list.append(member); + emit modified(list); + } +} + +void DuiWidgetModel::beginTransaction() +{ + if (d_ptr->transactionInProgress) { + duiWarning("DuiWidgetModel") << "beginTransaction() - transaction already started!"; + return; + } + + d_ptr->transactionInProgress = true; +} + +void DuiWidgetModel::commitTransaction() +{ + if (d_ptr->transactionInProgress == false) { + duiWarning("DuiWidgetModel") << "commitTransaction() - no transaction ongoing!"; + return; + } + + d_ptr->transactionInProgress = false; + emit modified(d_ptr->modifiedMembers); + d_ptr->modifiedMembers.clear(); +} + +void DuiWidgetModel::increaseReferenceCount() +{ + ++d_ptr->referenceCount; +} + +void DuiWidgetModel::decreaseReferenceCount() +{ + --d_ptr->referenceCount; + if (d_ptr->referenceCount == 0) + deleteLater(); +} + +QDataStream &operator<<(QDataStream &stream, const DuiWidgetModel &model) +{ + const QMetaObject *metaObject = model.metaObject(); + QString hashString = metaObject->className(); + + int propertyCount = metaObject->propertyCount(); + for (int i = 0; i != propertyCount; ++i) { + hashString += metaObject->property(i).name(); + hashString += metaObject->property(i).typeName(); + } + + uint hash = qHash(hashString); + stream << hash; + for (int i = 0; i != propertyCount; ++i) { + stream << metaObject->property(i).read(&model); + } + + return stream; +} + +QDataStream &operator>>(QDataStream &stream, DuiWidgetModel &model) +{ + const QMetaObject *metaObject = model.metaObject(); + QString hashString = metaObject->className(); + + int propertyCount = metaObject->propertyCount(); + for (int i = 0; i != propertyCount; ++i) { + hashString += metaObject->property(i).name(); + hashString += metaObject->property(i).typeName(); + } + + uint realHash = qHash(hashString); + uint hash; + stream >> hash; + if (hash != realHash) { + qFatal("Deserializing of %s failed from QDataStream, Q_PROPERTY table doesn't match!", metaObject->className()); + } + + for (int i = 0; i != propertyCount; ++i) { + QVariant v; + stream >> v; + metaObject->property(i).write(&model, v); + } + + return stream; +} + diff --git a/src/widgets/duiwidgetmodel.h b/src/widgets/duiwidgetmodel.h new file mode 100644 index 000000000..41764db3e --- /dev/null +++ b/src/widgets/duiwidgetmodel.h @@ -0,0 +1,139 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIWIDGETMODEL_H +#define DUIWIDGETMODEL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +// model macro +#define DUI_MODEL(CLASS) \ + public: \ + CLASS(); \ + virtual ~CLASS(); \ + protected: \ + CLASS(class CLASS##Data* data); \ + class CLASS##Data *data; \ + private: + + +// model macro for internal models +#define DUI_MODEL_INTERNAL(CLASS) \ + public: \ + CLASS(); \ + virtual ~CLASS(); \ + protected: \ + CLASS(class CLASS##Data* data); \ + private: + +// model macro with private class +#define DUI_MODEL_WITH_PRIVATE(CLASS) \ + public: \ + CLASS(); \ + virtual ~CLASS(); \ + protected: \ + CLASS(class CLASS##Data* data, class CLASS##Private* dd = NULL); \ + class CLASS##Data *data; \ + class CLASS##Private* const d_ptr; \ + private: \ + Q_DECLARE_PRIVATE(CLASS) + +// model macro with private class for internal models +#define DUI_MODEL_INTERNAL_WITH_PRIVATE(CLASS) \ + public: \ + CLASS(); \ + virtual ~CLASS(); \ + protected: \ + CLASS(class CLASS##Data* data, class CLASS##Private* dd = NULL); \ + private: \ + Q_DECLARE_PRIVATE(CLASS) + +// model property macro +// TYPE is the type of the property, e.g. QString, QColor or bool. +// NAME is the name of the property. NAME specifies name for Q_PROPERTY and also defines the getter name. +// CAMELNAME should be the same as NAME but with capital first letter. +// GENERATEMETHODS is either true or false and it defines whether the system should generate getter and setter automatically. +// INITIALVALUE is the initial value for the property. +// +// INITIALVALUE and GENERATEMETHODS expands to nothing in header, so they can be changed without API break. +// +// DUI_MODEL_PROPERTY(QString, text, Text, true) +// DUI_MODEL_PROPERTY(bool, visible, Visible, true) +#define DUI_MODEL_PROPERTY(TYPE, NAME, CAMELNAME, GENERATEMETHODS, INITIALVALUE) \ + Q_PROPERTY(TYPE NAME READ NAME WRITE set##CAMELNAME) \ + public: \ + static const char* const CAMELNAME; \ + const TYPE& NAME() const; \ + void set##CAMELNAME(const TYPE& NAME); \ + private: \ + TYPE& _##NAME(); \ + const TYPE& _##NAME() const; + +#define DUI_MODEL_PTR_PROPERTY(TYPE, NAME, CAMELNAME, GENERATEMETHODS, INITIALVALUE) \ + Q_PROPERTY(TYPE NAME READ NAME WRITE set##CAMELNAME) \ + public: \ + static const char* const CAMELNAME; \ + TYPE NAME() const; \ + void set##CAMELNAME(TYPE NAME); \ + private: + +/*! + \class DuiWidgetModel + \brief DuiWidgetModel implements a base class for MVC + + */ +class DUI_EXPORT DuiWidgetModel : public QObject +{ + Q_OBJECT + DUI_MODEL_WITH_PRIVATE(DuiWidgetModel) + DUI_MODEL_PROPERTY(QString, objectName, ObjectName, true, QString::null) + DUI_MODEL_PROPERTY(DuiTheme::ViewType, viewType, ViewType, true, DuiWidgetController::defaultType) + DUI_MODEL_PROPERTY(QPointF, position, Position, true, QPointF(0.0, 0.0)) + DUI_MODEL_PROPERTY(QSizeF, size, Size, true, QSizeF(0.0, 0.0)) + DUI_MODEL_PROPERTY(qreal, opacity, Opacity, true, 1.0) + +public: + + void beginTransaction(); + void commitTransaction(); + + void increaseReferenceCount(); + void decreaseReferenceCount(); + +Q_SIGNALS: + void modified(const QList& members); + +protected: + void memberModified(const char *const member); +private: + friend DUI_EXPORT QDataStream &operator<<(QDataStream &stream, const DuiWidgetModel &model); + friend DUI_EXPORT QDataStream &operator>>(QDataStream &stream, DuiWidgetModel &model); +}; + +DUI_EXPORT QDataStream &operator<<(QDataStream &stream, const DuiWidgetModel &model); +DUI_EXPORT QDataStream &operator>>(QDataStream &stream, DuiWidgetModel &model); + +#endif diff --git a/src/widgets/duiwidgetmodel_p.h b/src/widgets/duiwidgetmodel_p.h new file mode 100644 index 000000000..bdd9c87eb --- /dev/null +++ b/src/widgets/duiwidgetmodel_p.h @@ -0,0 +1,36 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIWIDGETMODEL_P_H +#define DUIWIDGETMODEL_P_H + +#include + +class DuiWidgetModelPrivate +{ +public: + DuiWidgetModelPrivate(); + virtual ~DuiWidgetModelPrivate(); + QQueue modifiedMembers; + bool transactionInProgress; + int referenceCount; +}; + +#endif + diff --git a/src/widgets/duiwidgetrecycler.cpp b/src/widgets/duiwidgetrecycler.cpp new file mode 100644 index 000000000..7a6b9d7bc --- /dev/null +++ b/src/widgets/duiwidgetrecycler.cpp @@ -0,0 +1,99 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include "duiwidgetrecycler.h" +#include "duiwidgetrecycler_p.h" + +DuiWidgetRecyclerPrivate::DuiWidgetRecyclerPrivate() + : widgetCount(0), maxWidgetCount(10) +{ +} + +DuiWidgetRecyclerPrivate::~DuiWidgetRecyclerPrivate() +{ + qDeleteAll(widgets); +} + +void DuiWidgetRecyclerPrivate::resetWidgetState(DuiWidget *widget) +{ + widget->setVisible(false); + //widget->setParentItem(NULL); + //widget->setParentLayoutItem(NULL); +} + +bool DuiWidgetRecyclerPrivate::hasEnoughSpaceFor(DuiWidget *widget) +{ + return widgets.count(widget->metaObject()->className()) < maxWidgetCount; +} + +void DuiWidgetRecyclerPrivate::put(DuiWidget *widget) +{ + widgets.insert(widget->metaObject()->className(), widget); +} + +DuiWidget *DuiWidgetRecyclerPrivate::take(const QString &className) +{ + return widgets.take(className); +} + +DuiWidgetRecycler::DuiWidgetRecycler() + : d_ptr(new DuiWidgetRecyclerPrivate()) +{ +} + +DuiWidgetRecycler::~DuiWidgetRecycler() +{ + delete d_ptr; +} + +DuiWidgetRecycler *DuiWidgetRecycler::instance() +{ + static DuiWidgetRecycler recycler; + return &recycler; +} + +void DuiWidgetRecycler::setMaxItemsPerClass(int count) +{ + d_ptr->maxWidgetCount = count; +} + +int DuiWidgetRecycler::maxItemsPerClass() const +{ + return d_ptr->maxWidgetCount; +} + +void DuiWidgetRecycler::recycle(DuiWidget *widget) +{ + if (widget) { + if (d_ptr->hasEnoughSpaceFor(widget)) { + d_ptr->resetWidgetState(widget); + d_ptr->put(widget); + } else { + delete widget; + } + } +} + +DuiWidget *DuiWidgetRecycler::take(const QString &className) +{ + DuiWidget *widget = d_ptr->take(className); + + return widget; +} diff --git a/src/widgets/duiwidgetrecycler.h b/src/widgets/duiwidgetrecycler.h new file mode 100644 index 000000000..25c80be9a --- /dev/null +++ b/src/widgets/duiwidgetrecycler.h @@ -0,0 +1,127 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIWIDGETRECYCLER_H +#define DUIWIDGETRECYCLER_H + + +#include "duiexport.h" +#include + +class DuiWidgetRecyclerPrivate; +class DuiWidget; + +/*! + \class DuiWidgetRecycler + \brief DuiWidgetRecycler allows to reuse widgets when they are created + and deleted frequently, for instance in DuiList or DuiGrid. + + When widgets in DuiList/DuiGrid become invisible during panning, + they are added to the recycler. New widgets that become visible are + not constructed from scratch, instead the widgets that have been + added to the recycler are reused. + + The item model class 'data' function must be implemented as in the + following example. If the recycler has a widget of the needed class + already available, the data function must use that widget. + Otherwise the data function creates a new widget. + + Example code with DuiButtons that have the row number as their text. + + \code + + QVariant ExampleModel::data(const QModelIndex &index, int role) const + { + if (role == Qt::DisplayRole) { + DuiButton* item; + + DuiWidgetRecycler* recycler = DuiWidgetRecycler::instance(); + DuiWidget* widget = recycler->take("DuiButton"); + + item = dynamic_cast(widget); + if (item == 0) { + item = new DuiButton; + } + + QString s; + s.setNum(index.row()); + item->setText(s); + + QVariant v; + v.setValue(item); + return v; + } + + return QVariant(); + } + + \endcode +*/ + +class DUI_EXPORT DuiWidgetRecycler +{ +public: + + /*! + \brief Returns the unique instance of DuiWidgetRecycler. + */ + static DuiWidgetRecycler *instance(); + + DuiWidgetRecycler(); + + /*! + \brief Puts a new widget to the recycler. + + Widget ownership is transferred to recycler. If the widget recycler is full, + widget will be deleted. + */ + void recycle(DuiWidget *widget); + + /*! + \brief Returns a widget from the recycler, if available. + + Ownership of returned widget is transferred to the user. + Returns 0 if no widget of the specified class is available. + */ + DuiWidget *take(const QString &className); + + /*! + \brief Sets the maximum number of widgets the recycler holds at one time per class. Each class + has the same limit. + */ + void setMaxItemsPerClass(int count); + + /*! + \brief Returns possible maximum amount of widgets in the recycler per class, e.g. each class has + the same limit. + */ + int maxItemsPerClass() const; + + /*! + \brief Destructor + */ + virtual ~DuiWidgetRecycler(); + +private: + Q_DISABLE_COPY(DuiWidgetRecycler) + + DuiWidgetRecyclerPrivate *const d_ptr; +}; + +#endif diff --git a/src/widgets/duiwidgetrecycler_p.h b/src/widgets/duiwidgetrecycler_p.h new file mode 100644 index 000000000..3cc4f5145 --- /dev/null +++ b/src/widgets/duiwidgetrecycler_p.h @@ -0,0 +1,45 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIWIDGETRECYCLER_P_H +#define DUIWIDGETRECYCLER_P_H + +#include +#include + +class DuiWidget; + +class DuiWidgetRecyclerPrivate +{ + +public: + DuiWidgetRecyclerPrivate(); + ~DuiWidgetRecyclerPrivate(); + + void resetWidgetState(DuiWidget *widget); + bool hasEnoughSpaceFor(DuiWidget *widget); + void put(DuiWidget *widget); + DuiWidget *take(const QString &className); + + QMultiHash widgets; + int widgetCount; + int maxWidgetCount; +}; + +#endif diff --git a/src/widgets/duiwindow.cpp b/src/widgets/duiwindow.cpp new file mode 100644 index 000000000..dfa24546c --- /dev/null +++ b/src/widgets/duiwindow.cpp @@ -0,0 +1,715 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifdef QT_OPENGL_LIB +#include "duigles2renderer.h" +#endif + +#include +#include + +#include "duiapplication.h" +#include "duiapplicationwindow.h" +#include "duiorientationtracker.h" +#include "duideviceprofile.h" +#include "duiwindow.h" +#include "duiwindow_p.h" +#include "duideviceprofile.h" +#include "duiwidget.h" +#include "duicomponentdata.h" +#include "duiorientationchangeevent.h" +#include +#include +#include +#include +#include + +#include "duilocale.h" + +#ifdef Q_WS_X11 +# include +# include +// Avoid conflict with QEvent::KeyPress usage in DuiWindow::Event +# undef KeyPress +#endif + +/// Actual class + +DuiWindowPrivate::DuiWindowPrivate() : + glWidget(0), + sceneManager(0), + oldOrientation(Dui::Landscape), // the initial value is not used at all + orientationAngleLocked(false), + orientationLocked(false), + onDisplay(false), + onDisplaySet(false) +{ + DuiWindow *window = DuiApplication::activeWindow(); + + if (window) + angle = window->orientationAngle(); + else + angle = DuiOrientationTracker::instance()->orientationAngle(); +} + +DuiWindowPrivate::~DuiWindowPrivate() +{ +} + +void DuiWindowPrivate::init() +{ + Q_Q(DuiWindow); + +#ifdef Q_WS_X11 + // We do window decorations ourselves. Set env variable accordingly for + // development purposes + QString env = qgetenv("DUI_DECORATED"); + if (env.contains("0")) { + q->setWindowFlags(Qt::FramelessWindowHint); + } + /* Workaround until we get DUI_DECORATED defined in the target env */ +#ifdef __arm__ + else if (env.isEmpty()) { + q->setWindowFlags(Qt::FramelessWindowHint); + } +#endif + +#endif + + q->resize(q->visibleSceneSize(q->orientation())); + q->setFrameStyle(0); + q->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + q->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + + if (DuiApplication::softwareRendering() == false) { +#ifdef QT_OPENGL_LIB + duiDebug("DuiWindowPrivate") << "Renderer: OpenGL"; +#else + duiDebug("DuiWindowPrivate") << "Renderer: Software"; +#endif + } else { + duiDebug("DuiWindowPrivate") << "Renderer: Software (forced)"; + } + +#ifdef Q_WS_X11 + appendVisibilityChangeMask(); +#endif + + q->setTranslucentBackground(false); + + if (DuiApplication::fullScreen()) + q->showFullScreen(); +} + +#ifdef Q_WS_X11 +void DuiWindowPrivate::appendVisibilityChangeMask() +{ + Q_Q(DuiWindow); + + XWindowAttributes existingAttributes; + XSetWindowAttributes newAttributes; + Status status; + + status = XGetWindowAttributes(QX11Info::display(), q->winId(), &existingAttributes); + if (status == 0) { + qFatal("DuiWindow: XGetWindowAttributes() failed!"); + } + + newAttributes.event_mask = existingAttributes.your_event_mask | VisibilityChangeMask; + + XChangeWindowAttributes(QX11Info::display(), q->winId(), CWEventMask, &newAttributes); +} +#endif + +void DuiWindowPrivate::setLayoutDirection_helper(QGraphicsItem *item) +{ + if (item->isWidget()) { + QGraphicsWidget *widget = static_cast(item); + Qt::LayoutDirection direction = qApp->layoutDirection(); + // if the direction has not changed or has been specified + // directly, do not update. + if (((direction == Qt::RightToLeft) == widget->testAttribute(Qt::WA_RightToLeft)) + || widget->testAttribute(Qt::WA_SetLayoutDirection)) + return; + widget->setAttribute(Qt::WA_RightToLeft, (direction == Qt::RightToLeft)); + } + // Propagate this change to all children. + const int size = item->childItems().size(); + for (int i = 0; i < size; ++i) { + QGraphicsItem *childItem = item->childItems().at(i); + setLayoutDirection_helper(childItem); + } + if (item->isWidget()) { + // Send the notification event to this widget item. + QEvent e(QEvent::LayoutDirectionChange); + QApplication::sendEvent(static_cast(item), &e); + } +} + +Dui::Orientation DuiWindowPrivate::orientation(Dui::OrientationAngle angle) const +{ + return (angle == Dui::Angle0 || angle == Dui::Angle180) ? Dui::Landscape : Dui::Portrait; +} + +void DuiWindowPrivate::_q_sendOrientationChangedSignal() +{ + Q_Q(DuiWindow); + + if (sceneManager == 0) + return; + + emit q->orientationAngleChanged(sceneManager->orientationAngle()); + emit q->orientationChanged(sceneManager->orientation()); + notifyWidgetsAboutOrientationChange(); +} + +void DuiWindowPrivate::notifyWidgetsAboutOrientationChange() +{ + Q_Q(DuiWindow); + + Dui::Orientation newOrientation = q->orientation(); + + if (oldOrientation != newOrientation) { + if (sceneManager == 0) { + emit q->orientationChanged(newOrientation); + emit q->orientationChangeFinished(newOrientation); + } + + if (q->scene()) { + DuiOrientationChangeEvent event(newOrientation); + foreach(QGraphicsItem * item, q->scene()->items()) + q->scene()->sendEvent(item, &event); + } + } +} + +void DuiWindowPrivate::doEnterDisplayEvent() +{ + Q_Q(DuiWindow); + + onDisplay = true; + onDisplaySet = true; + + q->enterDisplayEvent(); + emit q->enteredDisplay(); +} + +void DuiWindowPrivate::doExitDisplayEvent() +{ + Q_Q(DuiWindow); + + onDisplay = false; + onDisplaySet = true; + + q->exitDisplayEvent(); + emit q->exitedDisplay(); +} + +void DuiWindowPrivate::propagateDuiOnDisplayChangeEventToScene(DuiOnDisplayChangeEvent *event) +{ + Q_Q(DuiWindow); + + DuiOnDisplayChangeEvent::State eventState; + + if (event->state() == DuiOnDisplayChangeEvent::PartiallyOnDisplay || + event->state() == DuiOnDisplayChangeEvent::FullyOnDisplay || + event->state() == DuiOnDisplayChangeEvent::MustBeResolved) { + eventState = DuiOnDisplayChangeEvent::MustBeResolved; + } else { + eventState = DuiOnDisplayChangeEvent::FullyOffDisplay; + } + + + DuiOnDisplayChangeEvent ev(eventState, q->sceneRect()); + + // FIXME: + // Actually sending the event would require overriding customEvent() which + // would mess ABI compatibility. Calling the event handler directly for now + q->scene()->d_func()->onDisplayChangeEvent(&ev); + +} + +DuiWindow::DuiWindow(DuiWindowPrivate &dd, QWidget *parent) + : QGraphicsView(parent), + d_ptr(&dd) +{ + Q_D(DuiWindow); + d->q_ptr = this; + d->init(); + DuiComponentData::registerWindow(this); +} + +DuiWindow::DuiWindow(DuiWindowPrivate &dd, DuiScene *scene, QWidget *parent) + : QGraphicsView(parent), d_ptr(&dd) +{ + Q_D(DuiWindow); + d->q_ptr = this; + d->init(); + DuiComponentData::registerWindow(this); + setSceneManager(new DuiSceneManager(scene, this)); +} + +DuiWindow::DuiWindow(DuiWindowPrivate &dd, DuiSceneManager *sceneManager, QWidget *parent) + : QGraphicsView(parent), d_ptr(&dd) +{ + Q_D(DuiWindow); + d->q_ptr = this; + d->init(); + DuiComponentData::registerWindow(this); + setSceneManager(sceneManager); +} + +DuiWindow::DuiWindow(DuiSceneManager *sceneManager, QWidget *parent) + : QGraphicsView(parent), d_ptr(new DuiWindowPrivate) +{ + Q_D(DuiWindow); + d->q_ptr = this; + d->init(); + DuiComponentData::registerWindow(this); + setSceneManager(sceneManager); +} + +DuiWindow::DuiWindow(QWidget *parent) + : QGraphicsView(parent), + d_ptr(new DuiWindowPrivate) +{ + Q_D(DuiWindow); + d->q_ptr = this; + d->init(); + DuiComponentData::registerWindow(this); +} + +DuiWindow::~DuiWindow() +{ + DuiComponentData::unregisterWindow(this); + delete d_ptr; +} + +void DuiWindow::setTranslucentBackground(bool enable) +{ + Q_D(DuiWindow); + + if (!DuiApplication::softwareRendering()) { +#ifdef QT_OPENGL_LIB + setViewportUpdateMode(DuiWindow::FullViewportUpdate); + + QGLFormat fmt; + // disable multisampling, is enabled by default in Qt + fmt.setSampleBuffers(false); + fmt.setSamples(0); + + // The sequence of calls here is important. When translucency is not + // enabled, ensure setViewport() is called before DuiGLES2Renderer + // initializes its vertices, otherwise call setViewport() after + // DuiGLES2Renderer initializes itself. Failure to do this will cause + // a crash. + if (enable) { + //d->glWidget->setAttribute(Qt::WA_TranslucentBackground); + + fmt.setAlpha(true); // Workaround for NB#153625 + d->glWidget = new QGLWidget(fmt); + QPalette palette; + palette.setColor(QPalette::Base, Qt::transparent); + d->glWidget->setAutoFillBackground(true); + d->glWidget->setPalette(palette); + } else { + d->glWidget = new QGLWidget(fmt); + setViewport(d->glWidget); + } +#ifdef DUI_USE_OPENGL + DuiGLES2Renderer::instance(d->glWidget); +#endif + if (enable) + setViewport(d->glWidget); +#endif + } else { + viewport()->setAutoFillBackground(!enable); + } + if (enable) + setAttribute(Qt::WA_TranslucentBackground); +} + +DuiScene *DuiWindow::scene() +{ + return qobject_cast(QGraphicsView::scene()); +} + +bool DuiWindow::keepCurrentOrientation() const +{ + duiWarning("DuiWindow::keepCurrentOrientation()") << "THIS METHOD IS DEPRECATED - use isOrientationLocked()"; + return isOrientationLocked(); +} + +void DuiWindow::setKeepCurrentOrientation(bool enabled) +{ + duiWarning("DuiWindow::keepCurrentOrientation()") << "THIS METHOD IS DEPRECATED - use setOrientationLocked()"; + setOrientationLocked(enabled); +} + +bool DuiWindow::isOrientationAngleLocked() const +{ + Q_D(const DuiWindow); + + return d->orientationAngleLocked; +} + +void DuiWindow::setOrientationAngleLocked(bool locked) +{ + Q_D(DuiWindow); + + if (d->orientationAngleLocked != locked) { + d->orientationAngleLocked = locked; + + // update from the orientation tracker if we're unlocking orientation changes + if (!locked) + setOrientationAngle(DuiOrientationTracker::instance()->orientationAngle()); + } +} + +bool DuiWindow::isOrientationLocked() const +{ + Q_D(const DuiWindow); + + return d->orientationLocked; +} + +void DuiWindow::setOrientationLocked(bool locked) +{ + Q_D(DuiWindow); + + if (d->orientationLocked != locked) { + d->orientationLocked = locked; + + // update from the orientation tracker if we're unlocking orientation changes + if (!locked) + setOrientationAngle(DuiOrientationTracker::instance()->orientationAngle()); + } +} + +void DuiWindow::lockOrientationAngle() +{ + setOrientationAngleLocked(true); +} + +void DuiWindow::unlockOrientationAngle() +{ + setOrientationAngleLocked(false); +} + +void DuiWindow::lockOrientation() +{ + setOrientationLocked(true); +} + +void DuiWindow::unlockOrientation() +{ + setOrientationLocked(false); +} + +void DuiWindow::setSceneManager(DuiSceneManager *sceneManager) +{ + Q_D(DuiWindow); + + if (d->sceneManager == sceneManager) { + return; + } + + if (d->sceneManager) { + delete d->sceneManager; + } + + d->sceneManager = sceneManager; + + if (sceneManager) { + connect(sceneManager, SIGNAL(orientationChanged(Dui::Orientation)), + SLOT(_q_sendOrientationChangedSignal())); + connect(sceneManager, SIGNAL(orientationChangeFinished(Dui::Orientation)), + SIGNAL(orientationChangeFinished(Dui::Orientation))); + sceneManager->setParent(this); + setScene(sceneManager->scene()); + } +} + +DuiSceneManager *DuiWindow::sceneManager() +{ + Q_D(DuiWindow); + + // A scene manager is needed. Let's create one on the fly + // if we don't have one already. + if (!d->sceneManager) { + setSceneManager(new DuiSceneManager); + } + + return d->sceneManager; +} + +DuiSceneManager *DuiWindow::sceneManager() const +{ + Q_D(const DuiWindow); + + return d->sceneManager; +} + +Dui::Orientation DuiWindow::orientation() const +{ + Q_D(const DuiWindow); + + if (d->sceneManager) { + return d->sceneManager->orientation(); + } else { + return d->orientation(d->angle); + } +} + +Dui::OrientationAngle DuiWindow::orientationAngle() const +{ + Q_D(const DuiWindow); + + if (d->sceneManager) { + return d->sceneManager->orientationAngle(); + } else { + return d->angle; + } +} + +void DuiWindow::setOrientationAngle(Dui::OrientationAngle angle, Dui::OrientationChangeMode mode) +{ + Q_D(DuiWindow); + + if (d->angle != angle) { + d->oldOrientation = orientation(); + d->angle = angle; + + if (d->sceneManager) { + d->sceneManager->setOrientationAngle(angle, mode); + } else { + emit orientationAngleChanged(angle); + d->notifyWidgetsAboutOrientationChange(); + } + + } +} + +QSize DuiWindow::visibleSceneSize(Dui::Orientation orientation) const +{ + QSize s; + + if (orientation == Dui::Landscape) { + s = DuiDeviceProfile::instance()->resolution(); + } else { + s = QSize(DuiDeviceProfile::instance()->resolution().height(), + DuiDeviceProfile::instance()->resolution().width()); + } + + return s; +} + +QSize DuiWindow::visibleSceneSize() const +{ + return visibleSceneSize(orientation()); +} + +bool DuiWindow::isOnDisplay() const +{ + Q_D(const DuiWindow); + + return d->onDisplay; +} + +void DuiWindow::enterDisplayEvent() +{} + +void DuiWindow::exitDisplayEvent() +{} + +void DuiWindow::onDisplayChangeEvent(DuiOnDisplayChangeEvent *event) +{ + Q_D(DuiWindow); + + switch (event->state()) { + + case DuiOnDisplayChangeEvent::FullyOnDisplay: + if (!d->onDisplay || !d->onDisplaySet) { + d->doEnterDisplayEvent(); + } + break; + + case DuiOnDisplayChangeEvent::FullyOffDisplay: + if (d->onDisplay || !d->onDisplaySet) { + d->doExitDisplayEvent(); + } + break; + + default: + event->ignore(); + break; + } + + if (scene()) { + d->propagateDuiOnDisplayChangeEventToScene(event); + } +} + +void DuiWindow::paintEvent(QPaintEvent *event) +{ + // Disable view updates if the theme is not fully loaded yet + // TODO: Alco check for "!isOnDisplay()" to block repaints if the + // window is not visible anyway. Enable this once this works in + // scratchbox. + if (!updatesEnabled() || DuiTheme::hasPendingRequests()) { + return; + } +#ifdef DUI_USE_OPENGL + Q_D(DuiWindow); + + if (!DuiApplication::softwareRendering()) { + DuiGLES2Renderer::activate(d->glWidget); + } +#endif // DUI_USE_OPENGL + + QGraphicsView::paintEvent(event); +} + + +bool DuiWindow::event(QEvent *event) +{ + Q_D(DuiWindow); + if (event->type() == QEvent::Show || event->type() == QEvent::WindowActivate) { + DuiComponentData::setActiveWindow(this); + } + +#if defined DUI_USE_OPENGL + if (event->type() == QEvent::Close && !DuiApplication::softwareRendering()) { + DuiGLES2Renderer::destroy(d->glWidget); + } +#endif + if (event->type() == QEvent::Close || event->type() == QEvent::WindowDeactivate) { + DuiOnDisplayChangeEvent ev(false, sceneRect()); + onDisplayChangeEvent(&ev); + if (DuiComponentData::windows().size() > 1) + DuiComponentData::setActiveWindow(DuiComponentData::windows().at(1)); + } + + if (QEvent::KeyPress == event->type()) { + bool updateNeeded = false; + + //SIMULATION OF ROTATION FOR DEVELOPMENT PURPOSES + QKeyEvent *k = (QKeyEvent *) event; + if (Qt::Key_R == k->key() && (k->modifiers() & (Qt::ControlModifier | Qt::AltModifier))) { + foreach(DuiWindow * window, DuiApplication::windows()) { + int newAngle = (window->orientationAngle() + ((k->modifiers() & Qt::ShiftModifier) ? 270 : 90)) % 360; + if (!window->isOrientationAngleLocked()) { + if (!window->isOrientationLocked() || window->orientation() == (Dui::Orientation)newAngle) + window->setOrientationAngle((Dui::OrientationAngle)newAngle); + } + } + } else if (Qt::Key_P == k->key() && (k->modifiers() & (Qt::ControlModifier | Qt::AltModifier))) { + DuiApplication::setShowPosition(!DuiApplication::showPosition()); + updateNeeded = true; + } else if (Qt::Key_S == k->key() && (k->modifiers() & (Qt::ControlModifier | Qt::AltModifier))) { + DuiApplication::setShowSize(!DuiApplication::showSize()); + updateNeeded = true; + } else if (Qt::Key_B == k->key() && (k->modifiers() & (Qt::ControlModifier | Qt::AltModifier))) { + DuiApplication::setShowBoundingRect(!DuiApplication::showBoundingRect()); + updateNeeded = true; + } else if (Qt::Key_M == k->key() && (k->modifiers() & (Qt::ControlModifier | Qt::AltModifier))) { + DuiApplication::setShowMargins(!DuiApplication::showMargins()); + updateNeeded = true; + } else if (Qt::Key_N == k->key() && (k->modifiers() & (Qt::ControlModifier | Qt::AltModifier))) { + DuiApplication::setShowObjectNames(!DuiApplication::showObjectNames()); + updateNeeded = true; + } else if (Qt::Key_F == k->key() && (k->modifiers() & (Qt::ControlModifier | Qt::AltModifier))) { + DuiApplication::setShowFps(!DuiApplication::showFps()); + updateNeeded = true; + } else if (Qt::Key_D == k->key() && (k->modifiers() & (Qt::ControlModifier | Qt::AltModifier))) { + Qt::LayoutDirection dir = DuiApplication::layoutDirection(); + + if (dir == Qt::LeftToRight) + dir = Qt::RightToLeft; + else + dir = Qt::LeftToRight; + + DuiApplication::setLayoutDirection(dir); + + updateNeeded = true; + } else if (Qt::Key_L == k->key() && (k->modifiers() & (Qt::ControlModifier | Qt::AltModifier))) { + // switch language + + DuiGConfItem languageItem("/Dui/i18n/Language"); + QString language = languageItem.value().toString(); + if (language == "en_US_POSIX" || language.isEmpty()) + language = "fi"; + else if (language == "fi") + language = "en"; + else if (language == "en") + language = "de"; + else if (language == "de") + language = "ar"; + else if (language == "ar") + language = "hu"; + else if (language == "hu") + language = "ur"; + else if (language == "ur") + language = "zh_CN"; + else + language = ""; + languageItem.set(language); + + updateNeeded = true; + } + + if (updateNeeded) { + this->viewport()->update(); + } + } else if (event->type() == QEvent::ApplicationLayoutDirectionChange) { + // tell the scene and its items about the layout change + if (scene()) { + QList items = scene()->items(); + + // call setLayoutDirection_helper() for all top-level items + foreach(QGraphicsItem * item, items) { + if (!item->parentItem()) + d->setLayoutDirection_helper(static_cast(item)); + } + } + return true; + } else if (event->type() == QEvent::LanguageChange) { + // tell the scene and its items about the language change + if (scene()) { + QList items = scene()->items(); + + foreach(QGraphicsItem * item, items) { + if (item->isWidget()) { + QGraphicsWidget *widget = static_cast(item); + + QEvent ev(QEvent::LanguageChange); + qApp->sendEvent(widget, &ev); + } + } + } + return true; + } else if (event->type() == DuiOnDisplayChangeEvent::eventNumber()) { + onDisplayChangeEvent(static_cast(event)); + return true; + } + + return QGraphicsView::event(event); +} + +#include "moc_duiwindow.cpp" diff --git a/src/widgets/duiwindow.h b/src/widgets/duiwindow.h new file mode 100644 index 000000000..5e49c65ac --- /dev/null +++ b/src/widgets/duiwindow.h @@ -0,0 +1,394 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIWINDOW_H +#define DUIWINDOW_H + +#include "duiexport.h" +#include "duinamespace.h" + +#include + +class DuiWindowPrivate; +class DuiWidget; +class DuiOrientationChangeParameters; +class DuiScene; +class DuiSceneManager; +class DuiOnDisplayChangeEvent; + +/*! + \class DuiWindow + \brief DuiWindow is the base class for all Direct UI application windows + + Example: Showing scene windows on DuiWindow. + + \code + DuiApplication app; + DuiWindow window; + DuiSceneWindow *sceneWindow = new DuiMessageBox("Hello World!"); + + window.show(); + + sceneWindow->appear(&window); + + app.exec(); + \endcode + +*/ +class DUI_EXPORT DuiWindow : public QGraphicsView +{ + + Q_OBJECT + /*! + * \property keepCurrentOrientation + * \deprecated Since 0.18.7. Use orientationLocked instead. + * \sa isOrientationLocked(), setOrientationLocked() + */ + Q_PROPERTY(bool keepCurrentOrientation READ keepCurrentOrientation WRITE setKeepCurrentOrientation) + Q_PROPERTY(bool orientationAngleLocked READ isOrientationAngleLocked WRITE setOrientationAngleLocked) + Q_PROPERTY(bool orientationLocked READ isOrientationLocked WRITE setOrientationLocked) + +public: + /*! + * \brief Creates a DuiWindow without a scene manager. + * + * A scene manager can still be assigned later on by calling + * setSceneManager(). One will also be automatically created + * if needed by the non-const version of sceneManager(). + * + * \param parent QWidget defaults to 0 + * \sa setSceneManager(), sceneManager() + */ + explicit DuiWindow(QWidget *parent = 0); + + /*! + * \brief Creates a DuiWindow with a provided scene manager. + * DuiWindow will take ownership over the given scene manager. + * + * \param sceneManager Scene manager to be used. + */ + explicit DuiWindow(DuiSceneManager *sceneManager, + QWidget *parent = 0); + + virtual ~DuiWindow(); + + /*! + * \brief Sets the translucency of DuiWindow + * + * Having a translucent background means that any window behind it will be + * shown. + * + * Calling this method is costly since it involves recreating the viewport. + * This method usually should be called only once, before showing the window. + * + * Background translucency is disabled by default. + * + * Platform notes: + * - Device: This feature requires that a compositing manager is running + * and an EGL surface with alpha channels + * - Scratchbox: MesaGL does not support ARGB GLX visuals. Only workaround + * is to run in software mode + * + * \param enable If true, DuiWindow will have a transparent background. + */ + void setTranslucentBackground(bool enable); + + /*! + * Returns a pointer to the window's DuiScene. + */ + DuiScene *scene(); + + /*! + * \brief Assigns a scene manager to the DuiWindow + * + * The existing scene manager (if any) will be deleted and replaced by + * \a sceneManager. + * + * DuiWindow will take ownership over \a sceneManager and use + * the scene that is managed by it. + * + * \param sceneManager scene manager to be used. Can be 0. + */ + void setSceneManager(DuiSceneManager *sceneManager); + + /*! + * Returns a pointer to the scene manager responsible for positioning scene windows + * in the window's DuiScene. + * + * \return scene manager being used or 0 (zero) if none was assigned. + */ + DuiSceneManager *sceneManager() const; + + /*! + * Returns a pointer to the scene manager responsible for positioning scene windows + * in the window's DuiScene. + * + * Non-const version. A scene manager will be automatically created if none + * was previously set. + */ + DuiSceneManager *sceneManager(); + + /*! + * Returns the current orientation of the window's scene. + */ + virtual Dui::Orientation orientation() const; + + /*! + * Returns the current orientation angle of the window's scene. + */ + virtual Dui::OrientationAngle orientationAngle() const; + + /*! + * Returns the visible size of the window (being also the size of its scene) + * for the given \a orientation. + */ + virtual QSize visibleSceneSize(Dui::Orientation) const; + + /*! + * Returns the visible size of the window (being also the size of its scene). + */ + virtual QSize visibleSceneSize() const; + + /*! + * \deprecated Since 0.18.7. Use isOrientationLocked() instead. + * \sa isOrientationLocked() + */ + bool keepCurrentOrientation() const; + + /*! + * \deprecated Since 0.18.7. Use setOrientationLocked() instead. + * \sa setOrientationLocked() + */ + void setKeepCurrentOrientation(bool enabled); + + /*! + * Returns true if the window orientation angle is not allowed to change + * when device orientation changes, otherwise returns false. + * The default value is false. + * + * \sa setOrientationAngleLocked() + */ + bool isOrientationAngleLocked() const; + + /*! + * Allows to control whether the window orientation angle should be updated with device orientation + * changes. If you need your window to be displayed only in certain orientation angle, + * set the desired angle using setOrientationAngle() and set this property to true. + * + * \example Locking window orientation angle + * + * \code + * DuiApplication app; + * DuiWindow window; + * + * // Set the correct orientation angle. + * // Disable animations because we don't need them at startup. + * if (window.orientation() != Dui::Angle270) + * window.setOrientationAngle(Dui::Angle270, Dui::ImmediateOrientationChange); + * window.setOrientationAngleLocked(true); + * + * window.show(); + * + * return app.exec(); + * \endcode + * + * \sa lockOrientationAngle(), unlockOrientationAngle() + */ + void setOrientationAngleLocked(bool locked); + + /*! + * Returns true if the window orientation is not allowed to change + * when device orientation changes, otherwise returns false. + * The default value is false. + * + * \sa setOrientationLocked() + */ + bool isOrientationLocked() const; + + /*! + * Allows to control whether the window orientation should be updated with device orientation + * changes. If you need your window to be displayed only in certain orientation, + * set the desired angle using setOrientationAngle() and set this property to true. + * + * \note Setting this property to true locks orientation changes, + * but allows automatic adjustments of the angle for the given orientation. + * This means that a window locked in portrait mode will adjust between + * Dui::Angle90 and Dui::Angle270 to keep "top edge" always on top and avoid + * upside-down situations. In order to lock specific orientation angle, use + * setOrientationAngleLocked(). + * + * \example Locking window orientation + * + * \code + * DuiApplication app; + * DuiWindow window; + * + * // Set the correct orientation angle. + * // Disable animations because we don't need them at startup. + * if (window.orientation() != Dui::Portrait) + * window.setOrientationAngle(Dui::Angle270, Dui::ImmediateOrientationChange); + * window.setOrientationLocked(true); + * + * window.show(); + * + * return app.exec(); + * \endcode + * + * \sa lockOrientationAngle(), unlockOrientationAngle() + */ + void setOrientationLocked(bool locked); + + //! Returns the current visibility state of the window. + virtual bool isOnDisplay() const; + +public Q_SLOTS: + /*! + * Allows to set the orientation angle of the window. When reimplementing, you should emit + * orientationChanged() and orientationAngleChanged() signals when appropriate. + * + * \param angle New orientation angle for the window + * \param mode Specifies whether the orientation change should be animated or not. + * + * \sa Dui::OrientationChangeMode + */ + virtual void setOrientationAngle(Dui::OrientationAngle angle, + Dui::OrientationChangeMode mode = Dui::AnimatedOrientationChange); + + /*! + * Locks window's orientation angle changes. Equal to calling setOrientationAngleLocked(true). + * + * \sa setOrientationAngleLocked(), unlockOrientationAngle() + */ + void lockOrientationAngle(); + + /*! + * Unlocks window's orientation angle changes. Equal to calling setOrientationAngleLocked(false). + * + * \sa setOrientationAngleLocked(), lockOrientationAngle() + */ + void unlockOrientationAngle(); + + /*! + * Locks window's orientation changes. Equal to calling setOrientationLocked(true). + * + * \sa setOrientationLocked(), unlockOrientation() + */ + void lockOrientation(); + + /*! + * Unlocks window's orientation changes. Equal to calling setOrientationLocked(false). + * + * \sa setOrientationLocked(), lockOrientation() + */ + void unlockOrientation(); + +Q_SIGNALS: + /*! + * Emitted after scene geometry has changed for a rotation. + * + * This is for widgets that need to react when the orientation is about to change, + * and is emitted after the scene geometry has changed and the rotation animation + * is about to start. + * + * \note This signal is emitted at start of the rotation animation. + * \sa orientationChanged() + */ + void orientationAngleChanged(const Dui::OrientationAngle &); + + /*! + * Emitted after scene geometry has changed for a rotation. + * + * This is for widgets that need to react when the orientation is about to change, + * and is emitted after the scene geometry has changed and the rotation animation + * is about to start. + * + * \note This signal is emitted at start of the rotation animation. + * \sa orientationAngleChanged() + */ + void orientationChanged(const Dui::Orientation &); + + /*! + * This signal is emitted when the rotation animation (if any) has finished. + * It's emitted in tandem with DuiSceneManager::orientationChangeComplete(). + * + * If window doesn't have the scene manager, this signal is emitted together with + * orientationChanged(). + * + * \sa orientationChanged() + */ + void orientationChangeFinished(const Dui::Orientation &); + + /*! + * A signal that is emitted when the window is shown or is not obscured anymore by another window. + * Note!: this is different from Qt's visibilityChanged(), which is emitted due to show() and hide(). + */ + void enteredDisplay(); + + /*! + * A signal that is emitted when the window gets obscured by another window. + * Note!: this is different from Qt's visibilityChanged(), which is emitted due to show() and hide(). + */ + void exitedDisplay(); + +protected: + //! \reimp + bool event(QEvent *event); + virtual void paintEvent(QPaintEvent *event); + //! \reimp_end + + /*! + * This event handler allows a window to notify subscribers about + * changes in its presence on the display. enterDisplayEvent() and exitDisplayEvent() + * convenience handlers are called by the default implementation. DuiOnDisplayChangeEvent + * is sent e.g. if the window gets obscured by another window. + */ + virtual void onDisplayChangeEvent(DuiOnDisplayChangeEvent *event); + + /*! + * A handler that is called when the window is shown or is not obscured anymore by another window. + * Note!: this is different from Qt's visibilityChanged(), which is emitted due to show() and hide(). + */ + virtual void enterDisplayEvent(); + + /*! + * A handler that is called when the window gets obscured by another window. + * Note!: this is different from Qt's visibilityChanged(), which is emitted due to show() and hide(). + */ + virtual void exitDisplayEvent(); + + //! \internal + explicit DuiWindow(DuiWindowPrivate &dd, QWidget *parent = 0); + explicit DuiWindow(DuiWindowPrivate &dd, DuiScene *scene, QWidget *parent = 0); + explicit DuiWindow(DuiWindowPrivate &dd, DuiSceneManager *sceneManager, QWidget *parent = 0); + + DuiWindowPrivate *const d_ptr; + //! \internal_end + +private: + Q_DISABLE_COPY(DuiWindow) + Q_DECLARE_PRIVATE(DuiWindow) + Q_PRIVATE_SLOT(d_func(), void _q_sendOrientationChangedSignal()) + +#ifdef UNIT_TEST + // to call orientationAngleChanged() + friend class Ut_DuiWindow; +#endif +}; + +#endif diff --git a/src/widgets/duiwindow_p.h b/src/widgets/duiwindow_p.h new file mode 100644 index 000000000..eb3d1743e --- /dev/null +++ b/src/widgets/duiwindow_p.h @@ -0,0 +1,78 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIWINDOW_P_H +#define DUIWINDOW_P_H + +#include +#include "duiwindow.h" + +#include + +class DuiScene; +class DuiOnDisplayChangeEvent; +class QGLWidget; + +class DuiWindowPrivate +{ +public: + + DuiWindowPrivate(); + virtual ~DuiWindowPrivate(); + + void setLayoutDirection_helper(QGraphicsItem *item); + Dui::Orientation orientation(Dui::OrientationAngle angle) const; + +#ifdef Q_WS_X11 + void appendVisibilityChangeMask(); +#endif + + QGLWidget *glWidget; + + Dui::OrientationAngle angle; + + DuiSceneManager *sceneManager; + + void _q_sendOrientationChangedSignal(); + void notifyWidgetsAboutOrientationChange(); + + Dui::Orientation oldOrientation; + bool orientationAngleLocked; + bool orientationLocked; + + void doEnterDisplayEvent(); + void doExitDisplayEvent(); + + void propagateDuiOnDisplayChangeEventToScene(DuiOnDisplayChangeEvent *event); + + bool onDisplay; + bool onDisplaySet; + + +protected: + DuiWindow *q_ptr; +private: + void init(); + Q_DECLARE_PUBLIC(DuiWindow) + +}; + + + +#endif diff --git a/src/widgets/views/duiapplicationmenubuttonview.cpp b/src/widgets/views/duiapplicationmenubuttonview.cpp new file mode 100644 index 000000000..2a2bb2d69 --- /dev/null +++ b/src/widgets/views/duiapplicationmenubuttonview.cpp @@ -0,0 +1,235 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiapplicationmenubuttonview.h" +#include "duiapplicationmenubuttonview_p.h" +#include "duiapplicationmenubutton.h" +#include "duitheme.h" +#include "duiviewcreator.h" +#include "duiimagewidget.h" +#include "duilabel.h" +#include "duiprogressindicator.h" + +#include +#include + +DuiApplicationMenuButtonViewPrivate::DuiApplicationMenuButtonViewPrivate() + : iconImage(0), arrowIconImage(0), spinner(0), layout(0) +{ +} + +DuiApplicationMenuButtonViewPrivate::~DuiApplicationMenuButtonViewPrivate() +{ +} + +void DuiApplicationMenuButtonViewPrivate::init() +{ + iconImage = new DuiImageWidget(controller); + arrowIconImage = new DuiImageWidget(controller); + + iconImage->setObjectName("NavigationBarMenuButtonIconImage"); + arrowIconImage->setObjectName("NavigationBarMenuButtonArrowImage"); + label->setObjectName("NavigationBarMenuButtonLabel"); + + layout = new QGraphicsGridLayout(); + layout->setContentsMargins(0, 0, 0, 0); + controller->setLayout(layout); +} + +void DuiApplicationMenuButtonViewPrivate::refreshStyleMode() +{ + Q_Q(DuiApplicationMenuButtonView); + + if (q->model()->down()) + q->style().setModePressed(); + else if (q->model()->checked()) + q->style().setModeSelected(); + else + q->style().setModeDefault(); + + label->setAlignment(q->style()->horizontalTextAlign() | q->style()->verticalTextAlign()); + + refreshIconImage(); +} + +void DuiApplicationMenuButtonViewPrivate::refreshLayout() +{ + Q_Q(DuiApplicationMenuButtonView); + + while (layout->count()) { + layout->removeAt(0); + } + + int colIndex = 0; + DuiApplicationMenuButton *buttonController = (DuiApplicationMenuButton *)controller; + if (buttonController->isIconVisible() && !buttonController->iconID().isEmpty()) { + iconImage->show(); + layout->addItem(iconImage, 0, colIndex++); + layout->setAlignment(iconImage, Qt::AlignCenter); + } else { + iconImage->hide(); + } + layout->addItem(label, 0, colIndex++); + layout->setAlignment(label, Qt::AlignCenter); + + arrowIconImage->hide(); + if (q->model()->progressIndicatorVisible() && spinner) { + spinner->show(); + spinner->setUnknownDuration(true); + layout->addItem(spinner, 0, colIndex++); + layout->setAlignment(spinner, Qt::AlignCenter); + } else { + if (spinner) { + spinner->hide(); + spinner->setUnknownDuration(false); + } + if (buttonController->isArrowIconVisible()) { + arrowIconImage->show(); + layout->addItem(arrowIconImage, 0, colIndex++); + layout->setAlignment(arrowIconImage, Qt::AlignCenter); + } + } + +} + +void DuiApplicationMenuButtonViewPrivate::refreshIconImage() +{ + Q_Q(DuiApplicationMenuButtonView); + + QSize size = q->style()->iconSize(); + if (toggleState()) { + if (!q->model()->toggledIconID().isEmpty()) + iconImage->setImage(q->model()->toggledIconID(), size); + } else { + iconImage->setImage(q->model()->iconID(), size); + } + + refreshLayout(); +} + +DuiApplicationMenuButtonView::DuiApplicationMenuButtonView(DuiApplicationMenuButton *controller) : + DuiButtonView(* new DuiApplicationMenuButtonViewPrivate, controller) +{ + Q_D(DuiApplicationMenuButtonView); + d->init(); +} + +DuiApplicationMenuButtonView::DuiApplicationMenuButtonView(DuiApplicationMenuButtonViewPrivate &dd, DuiApplicationMenuButton *controller) : + DuiButtonView(dd, controller) +{ + Q_D(DuiApplicationMenuButtonView); + d->init(); +} + +DuiApplicationMenuButtonView::~DuiApplicationMenuButtonView() +{ +} + +// must override DuiButtonView::resizeEvent +void DuiApplicationMenuButtonView::resizeEvent(QGraphicsSceneResizeEvent *event) +{ + DuiWidgetView::resizeEvent(event); +} + +void DuiApplicationMenuButtonView::applyStyle() +{ + Q_D(DuiApplicationMenuButtonView); + + DuiWidgetView::applyStyle(); + + d->arrowIconImage->setImage(style()->arrowIcon(), style()->arrowIconSize()); + d->refreshStyleMode(); + d->iconImage->setZoomFactor(1.0); + d->arrowIconImage->setZoomFactor(1.0); + + update(); +} + +void DuiApplicationMenuButtonView::updateData(const QList& modifications) +{ + Q_D(DuiApplicationMenuButtonView); + + DuiWidgetView::updateData(modifications); + const char *member; + foreach(member, modifications) { + if (member == DuiButtonModel::Text) { + d->label->setText(model()->text()); + } else if (member == DuiButtonModel::TextVisible) { + d->label->setVisible(model()->textVisible()); + } else if (member == DuiButtonModel::IconID || member == DuiButtonModel::ToggledIconID) { + d->refreshIconImage(); + } else if (member == DuiButtonModel::IconVisible) { + d->iconImage->setVisible(model()->iconVisible()); + d->refreshLayout(); + } else if (member == DuiApplicationMenuButtonModel::ProgressIndicatorVisible) { + // to reduce the application startup time, only create spinner when it is needed. + if (d->spinner == 0) { + d->spinner = new DuiProgressIndicator(d->controller, DuiProgressIndicator::spinnerType); + } + d->refreshLayout(); + } else if (member == DuiApplicationMenuButtonModel::ArrowIconVisible) { + d->refreshLayout(); + } else if (member == DuiButtonModel::Down || member == DuiButtonModel::Checked || + member == DuiButtonModel::Checkable) { + d->refreshStyleMode(); + } + } + update(); +} + +void DuiApplicationMenuButtonView::setupModel() +{ + Q_D(DuiApplicationMenuButtonView); + + d->label->setText(model()->text()); + d->label->setVisible(model()->textVisible()); + + d->refreshIconImage(); + + DuiWidgetView::setupModel(); +} + +QSizeF DuiApplicationMenuButtonView::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const +{ + if (which == Qt::MinimumSize || which == Qt::MaximumSize) + return DuiWidgetView::sizeHint(which, constraint); + + if (style()->preferredSize().isValid()) + return style()->preferredSize(); + + Q_D(const DuiApplicationMenuButtonView); + + qreal width = 0, height = 0; + QSizeF iconSize(0, 0); + QSizeF labelSize(0, 0); + + if (model()->iconVisible()) + iconSize = style()->iconSize(); + + if (model()->textVisible() && model()->text().isEmpty() == false) { + labelSize = d->label->sizeHint(which, constraint); + } + + width = iconSize.width() * 2 + labelSize.width(); + height = qMax(iconSize.height(), labelSize.height()); + + return QSizeF(width, height); +} + +DUI_REGISTER_VIEW_NEW(DuiApplicationMenuButtonView, DuiApplicationMenuButton) diff --git a/src/widgets/views/duiapplicationmenubuttonview.h b/src/widgets/views/duiapplicationmenubuttonview.h new file mode 100644 index 000000000..f98f89058 --- /dev/null +++ b/src/widgets/views/duiapplicationmenubuttonview.h @@ -0,0 +1,87 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLICATIONMENUBUTTONVIEW_H +#define DUIAPPLICATIONMENUBUTTONVIEW_H + +#include +#include +#include + +class DuiApplicationMenuButtonViewPrivate; +class DuiApplicationMenuButton; + +class QGraphicsSceneResizeEvent; + +//! \internal +/*! + \class DuiApplicationMenuButtonView + \brief View class for DuiApplicationMenuButton + + \ingroup views + + \sa DuiApplicationMenuButton +*/ + +class DuiApplicationMenuButtonView : public DuiButtonView +{ + Q_OBJECT + DUI_VIEW(DuiApplicationMenuButtonModel, DuiApplicationMenuButtonStyle) + +public: + + /*! + \brief Constructs the view. + \param Pointer to the controller. + */ + DuiApplicationMenuButtonView(DuiApplicationMenuButton *controller); + + /*! + \brief Destructs the view. + */ + virtual ~DuiApplicationMenuButtonView(); + + //! \reimp + virtual void resizeEvent(QGraphicsSceneResizeEvent *event); + //! \reimp_end + +protected: + + //! \reimp + virtual void applyStyle(); + virtual void setupModel(); + virtual QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const; + //! \reimp_end + + //! \cond + DuiApplicationMenuButtonView(DuiApplicationMenuButtonViewPrivate &dd, DuiApplicationMenuButton *controller); + //! \endcond + +protected slots: + //! \reimp + virtual void updateData(const QList& modifications); + //! \reimp_end + +private: + Q_DISABLE_COPY(DuiApplicationMenuButtonView) + Q_DECLARE_PRIVATE(DuiApplicationMenuButtonView) +}; +//! \internal_end + +#endif diff --git a/src/widgets/views/duiapplicationmenubuttonview_p.h b/src/widgets/views/duiapplicationmenubuttonview_p.h new file mode 100644 index 000000000..96dfa10fb --- /dev/null +++ b/src/widgets/views/duiapplicationmenubuttonview_p.h @@ -0,0 +1,50 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLICATIONBUTTONVIEW_P_H +#define DUIAPPLICATIONBUTTONVIEW_P_H + +#include "duibuttonview_p.h" + +class DuiLabel; +class DuiImageWidget; +class DuiProgressIndicator; +class QGraphicsGridLayout; + +class DuiApplicationMenuButtonViewPrivate : public DuiButtonViewPrivate +{ + Q_DECLARE_PUBLIC(DuiApplicationMenuButtonView) + +public: + DuiApplicationMenuButtonViewPrivate(); + virtual ~DuiApplicationMenuButtonViewPrivate(); + + void init(); + void refreshStyleMode(); + void refreshLayout(); + void refreshIconImage(); + + DuiImageWidget *iconImage; + DuiImageWidget *arrowIconImage; + DuiProgressIndicator *spinner; + QGraphicsGridLayout *layout; + +}; + +#endif diff --git a/src/widgets/views/duiapplicationmenuview.cpp b/src/widgets/views/duiapplicationmenuview.cpp new file mode 100644 index 000000000..887ee4499 --- /dev/null +++ b/src/widgets/views/duiapplicationmenuview.cpp @@ -0,0 +1,682 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include + +#include "duiapplicationmenuview_p.h" +#include "duiapplicationmenuview.h" +#include "duiapplicationmenu.h" +#include "duibutton.h" +#include "duibuttongroup.h" +#include "duiviewcreator.h" +#include "duitheme.h" +#include "duiwidgetaction.h" +#include "duiscalableimage.h" +#include "duipannableviewport.h" +#include "duiapplication.h" +#include "duiapplicationwindow.h" +#include "duiscenemanager.h" +#include "duiwindow.h" +#include "duilayout.h" +#include "duilinearlayoutpolicy.h" +#include "duigridlayoutpolicy.h" +#include "duicontentitem.h" +#include "duicombobox.h" + +const int maxCommandActions = 8; +const int maxCommandActionsWithStyle = 6; + +DuiApplicationMenuViewPrivate::DuiApplicationMenuViewPrivate(DuiApplicationMenu *menu) + : controllerLayout(0), + styleCommandLayout(0), + actionCommandLayout(0), + landscapePolicy(0), + portraitPolicy(0), + stylePolicy(0), + styleButtonGroup(0), + leasedWidgets(), + buttons() +{ + controller = menu; + + controllerLayout = new QGraphicsLinearLayout(Qt::Vertical, controller); + controllerLayout->setContentsMargins(0, 0, 0, 0); + controllerLayout->setSpacing(0); + + actionCommandLayout = new DuiLayout(); + actionCommandLayout->setContentsMargins(0, 0, 0, 0); + actionCommandLayout->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Preferred); + + styleCommandLayout = new DuiLayout(); + styleCommandLayout->setContentsMargins(0, 0, 0, 0); + styleCommandLayout->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Preferred); + + controllerLayout->addItem(styleCommandLayout); + controllerLayout->addItem(actionCommandLayout); + + stylePolicy = new DuiLinearLayoutPolicy(styleCommandLayout, Qt::Horizontal); + stylePolicy->setContentsMargins(0, 0, 0, 0); + stylePolicy->setSpacing(0); + + styleButtonGroup = new DuiButtonGroup(); + styleButtonGroup->setExclusive(true); + + controller->installEventFilter(this); +} + +DuiApplicationMenuViewPrivate::~DuiApplicationMenuViewPrivate() +{ + clearWidgets(leasedWidgets); + clearWidgets(buttons); + removeEventFilter(controller); +} + +void DuiApplicationMenuViewPrivate::init() +{ + createPolicy(Dui::Landscape); + createPolicy(Dui::Portrait); + + addActions(); +} + +void DuiApplicationMenuViewPrivate::createPolicy(Dui::Orientation orientation) +{ + if (orientation == Dui::Landscape) { + landscapePolicy = new DuiGridLayoutPolicy(actionCommandLayout); + actionCommandLayout->setLandscapePolicy(landscapePolicy); + landscapePolicy->setObjectName("menulandscape"); + } else { + portraitPolicy = new DuiLinearLayoutPolicy(actionCommandLayout, Qt::Vertical); + actionCommandLayout->setPortraitPolicy(portraitPolicy); + portraitPolicy->setObjectName("menuportrait"); + } +} + +void DuiApplicationMenuViewPrivate::add(QAction *action, QAction *before) +{ + if (!action || + !isLocationValid(action, DuiAction::ApplicationMenuLocation) || + (hasWidget(action) && !isWidgetUsable(action)) || + !canAddMoreActions(action)) { + return; + } + + DuiWidget *w = createWidget(action); + // add to policies only if the action is visible + if (action->isVisible()) { + DuiWidget *beforeWidget = getWidget(before); + if (isStyleAction(action)) { + addStyleWidget(w, beforeWidget); + } else { + addActionCommandWidget(w, beforeWidget); + } + } else if (w) { + w->setVisible(false); + } +} + +void DuiApplicationMenuViewPrivate::remove(QAction *action) +{ + DuiWidget *button = buttons.value(action); + DuiWidget *leased = leasedWidgets.value(action); + DuiWidget *widget = (button != 0) ? button : leased; + if (widget) { + if (isStyleAction(action)) { + removeStyleWidget(widget); + } else { + actionCommandLayout->removeItem(widget); + updateItemMode(); + } + } + if (button) { + buttons.remove(action); + delete button; + } else if (leased) { + releaseWidget(action, leased); + leasedWidgets.remove(action); + } + disconnect(action, SIGNAL(triggered()), controller, SLOT(disappear())); +} + +void DuiApplicationMenuViewPrivate::change(QAction *action) +{ + if (!changeLocation(action)) { + return; + } + changeData(action); + changeVisibility(action); + changeStyleAttribute(action); +} + +bool DuiApplicationMenuViewPrivate::eventFilter(QObject *obj, QEvent *e) +{ + QActionEvent *actionEvent = dynamic_cast(e); + + if (actionEvent) { + switch (e->type()) { + case QEvent::ActionRemoved: { + remove(actionEvent->action()); + break; + } + case QEvent::ActionAdded: { + add(actionEvent->action(), actionEvent->before()); + break; + } + case QEvent::ActionChanged: { + change(actionEvent->action()); + break; + } + default: { + break; + } + } + } + + return QObject::eventFilter(obj, e); +} + +void DuiApplicationMenuViewPrivate::addActions() +{ + QList acts = controller->actions(); + int count = acts.count(); + for (int i = 0; i < count; ++i) { + add(acts.at(i), 0); + } +} + +DuiWidget *DuiApplicationMenuViewPrivate::createWidget(QAction *action) +{ + // If widget is not already created then create it + DuiWidget *widget = buttons.value(action); + if (!widget) { + widget = leasedWidgets.value(action); + } + if (!widget) { + DuiWidgetAction *widgetAction = qobject_cast(action); + if (widgetAction) { + widget = requestWidget(widgetAction); + leasedWidgets.insert(action, widget); + } else { + widget = createButton(action); + buttons.insert(action, widget); + } + } + connect(action, SIGNAL(triggered()), controller, SLOT(disappear())); + widget->setVisible(true); + widget->setEnabled(action->isEnabled()); + return widget; +} + +DuiWidget *DuiApplicationMenuViewPrivate::createButton(QAction *action) +{ + DuiWidget *w = 0; + bool isStyle = isStyleAction(action); + if (isStyle) { + DuiButton *button = new DuiButton(action->text()); + DuiAction *duiAction = qobject_cast(action); + if (duiAction) { + button->setIconID(duiAction->iconID()); + } + connect(button, SIGNAL(clicked(bool)), action, SIGNAL(triggered())); + button->setCheckable(true); + button->setChecked(action->isChecked()); + styleButtonGroup->addButton(button); + button->setObjectName("menustylecommand"); + w = button; + } else { + DuiContentItem *item = new DuiContentItem(DuiContentItem::SingleTextLabel); + item->setTitle(action->text()); + item->setObjectName("menuactioncommand"); + connect(item, SIGNAL(clicked()), action, SIGNAL(triggered())); + w = item; + } + return w; +} + +bool DuiApplicationMenuViewPrivate::isStyleAction(QAction *action) +{ + bool isStyleAction = false; + DuiAction *duiAction = qobject_cast(action); + if (duiAction && duiAction->isStyleAction()) { + isStyleAction = true; + } + return isStyleAction; +} + +bool DuiApplicationMenuViewPrivate::isLocationValid(QAction *action, DuiAction::Location loc) +{ + bool valid = true; + DuiAction *duiAction = qobject_cast(action); + if (duiAction) { + valid = duiAction->location().testFlag(loc); + } + return valid; +} + +bool DuiApplicationMenuViewPrivate::isVisible(QAction *action) +{ + return action && + action->isVisible(); +} + +void DuiApplicationMenuViewPrivate::clearWidgets(QHash& widgets) +{ + QHashIterator iterator(widgets); + while (iterator.hasNext()) { + iterator.next(); + deleteWidget(iterator.key(), iterator.value()); + } + widgets.clear(); +} + +void DuiApplicationMenuViewPrivate::deleteWidget(QAction *action, DuiWidget *widget) +{ + if (!releaseWidget(action, widget)) { + delete widget; + } +} + +bool DuiApplicationMenuViewPrivate::releaseWidget(QAction *action, DuiWidget *widget) +{ + DuiWidgetAction *widgetAction = qobject_cast(action); + if (widgetAction) { + widgetAction->releaseWidget(widget); + } + return (widgetAction != 0); +} + +DuiWidget *DuiApplicationMenuViewPrivate::requestWidget(DuiAction *action) +{ + DuiWidget *widget = 0; + DuiWidgetAction *widgetAction = qobject_cast(action); + if (widgetAction) { + widget = widgetAction->requestWidget(controller); + } + return widget; +} + +bool DuiApplicationMenuViewPrivate::isWidgetInUseByView(DuiWidgetAction *widgetAction) +{ + return (buttons.contains(widgetAction) || leasedWidgets.contains(widgetAction)); +} + +bool DuiApplicationMenuViewPrivate::isWidgetUsable(QAction *action) +{ + DuiWidgetAction *widgetAction = qobject_cast(action); + return(widgetAction && isWidgetUsable(widgetAction)); +} + +bool DuiApplicationMenuViewPrivate::hasWidget(QAction *action) +{ + DuiWidgetAction *widgetAction = qobject_cast(action); + return(widgetAction && widgetAction->widget()); +} + +bool DuiApplicationMenuViewPrivate::isWidgetUsable(DuiWidgetAction *widgetAction) +{ + return (!widgetAction->isWidgetInUse() || isWidgetInUseByView(widgetAction)); +} + +DuiWidget *DuiApplicationMenuViewPrivate::getWidget(QAction *action) +{ + DuiWidget *button = buttons.value(action); + DuiWidget *leased = leasedWidgets.value(action); + return (button != 0) ? button : leased; +} + +bool DuiApplicationMenuViewPrivate::canAddMoreActions(QAction *action) +{ + bool canAdd = true; + if (!isStyleAction(action)) { + int commandActionsCount, styleActionsCount; + visibleActionsCount(commandActionsCount, styleActionsCount); + canAdd = (commandActionsCount < maxCommandActions); + if (styleActionsCount > 0) + canAdd = (commandActionsCount < maxCommandActionsWithStyle); + } + return canAdd; +} + +void DuiApplicationMenuViewPrivate::visibleActionsCount(int &commandActionsCount, int &styleActionsCount) +{ + commandActionsCount = 0; + styleActionsCount = 0; + QList acts = controller->actions(); + int count = acts.count(); + for (int i = 0; i < count; ++i) { + QAction *action = acts.at(i); + bool isStyle = isStyleAction(action); + styleActionsCount += isStyle; + commandActionsCount += (!isStyle); + } +} + +bool DuiApplicationMenuViewPrivate::changeLocation(QAction *action) +{ + // If the location of an action gets changed then + // remove it from the applicationmenu + if (!isLocationValid(action, DuiAction::ApplicationMenuLocation)) { + remove(action); + return false; + } + if (!getWidget(action)) { + //action does not exit (e.g. location has been reverted back) + add(action, 0); + } + return true; +} + +void DuiApplicationMenuViewPrivate::changeData(QAction *action) +{ + DuiWidget *widget = buttons.value(action); + DuiButton *button = qobject_cast(widget); + if (button) { + // Update button data accordingly + button->setText(action->text()); + button->setEnabled(action->isEnabled()); + button->setCheckable(action->isCheckable()); + button->setChecked(action->isChecked()); + DuiAction *duiAction = qobject_cast(action); + if (duiAction) { + button->setIconID(duiAction->iconID()); + } + } +} + +void DuiApplicationMenuViewPrivate::changeVisibility(QAction *action) +{ + DuiWidget *widget = getWidget(action); + if (widget) { + bool wasVisible = (landscapePolicy->indexOf(widget) >= 0) || + (portraitPolicy->indexOf(widget) >= 0); + //Check if visibility has been changed + bool visibilityChanged = (!action->isVisible() && wasVisible) || + (action->isVisible() && !wasVisible); + + refreshPolicies(visibilityChanged); + } +} + +void DuiApplicationMenuViewPrivate::changeStyleAttribute(QAction *action) +{ + DuiWidget *widget = getWidget(action); + if (widget) { + bool wasStyleCommand = (stylePolicy->indexOf(widget) >= 0); + + //Check if style attribute has been changed + bool isStyleCommand = isStyleAction(action); + bool changed = (wasStyleCommand && !isStyleCommand) || + (!wasStyleCommand && isStyleCommand); + + refreshPolicies(changed); + } +} + +void DuiApplicationMenuViewPrivate::refreshPolicies(bool refresh) +{ + if (refresh) { + clearPolicy(landscapePolicy); + clearPolicy(portraitPolicy); + clearPolicy(stylePolicy); + addActions(); + updateItemMode(); + } +} + +void DuiApplicationMenuViewPrivate::clearPolicy(DuiAbstractLayoutPolicy *policy) +{ + while (policy->count()) { + policy->removeAt(0); + } +} + +void DuiApplicationMenuViewPrivate::refreshLandscapePolicy() +{ + clearPolicy(landscapePolicy); + int index = 0; + QAction *action = 0; + QList acts = controller->actions(); + int count = acts.count(); + for (int i = 0; i < count; ++i) { + action = acts.at(i); + DuiWidget *w = getWidget(action); + if (w && action->isVisible() && !isStyleAction(action)) { + landscapePolicy->addItem(w, index / 2, index % 2); + index++; + } + } + updateItemMode(); +} + +void DuiApplicationMenuViewPrivate::updateItemMode() +{ + + DuiAbstractLayoutPolicy *policy = landscapePolicy; + int columnsCount = 2; + DuiWindow *window = DuiApplication::instance()->activeWindow(); + if (window && Dui::Portrait == window->orientation()) { + policy = portraitPolicy; + columnsCount = 1; + } + + int count = policy->count(); + + for (int index = 0; index < count; index++) { + DuiWidget *w = (DuiWidget *)policy->itemAt(index); + DuiContentItem *contentItem = qobject_cast(w); + updateContentItemMode(contentItem, columnsCount, count, index); + DuiComboBox *combobox = qobject_cast(w); + updateComboboxMode(combobox, columnsCount, count, index); + } + +} + +void DuiApplicationMenuViewPrivate::updateContentItemMode(DuiContentItem *contentItem, + int columnsCount, + int itemCount, + int index) +{ + if (!contentItem) + return; + + if (columnsCount == 1) { + if (index == itemCount - 1) { + contentItem->setItemMode(DuiContentItem::SingleColumnBottom); + } else { + contentItem->setItemMode(DuiContentItem::SingleColumnCenter); + } + } else { + int rowCount = (itemCount + 1) / 2; + int row = index / 2; + int col = index % 2; + if ((itemCount == 1) || (col == 0 && index == (itemCount - 1))) { //only one item in last row + contentItem->setItemMode(DuiContentItem::SingleColumnBottom); + } else if (row >= 0 && row < (rowCount - 1)) { + (col == 0) ? contentItem->setItemMode(DuiContentItem::Left) : contentItem->setItemMode(DuiContentItem::Right); + } else { + (col == 0) ? contentItem->setItemMode(DuiContentItem::BottomLeft) : contentItem->setItemMode(DuiContentItem::BottomRight); + } + } +} + +void DuiApplicationMenuViewPrivate::updateComboboxMode(DuiComboBox *comboBox, + int columnsCount, + int itemCount, + int index) +{ + if (!comboBox) + return; + + if (columnsCount == 1) { + if (index == itemCount - 1) { + comboBox->setObjectName("MenuComboBoxSingleColumnBottom"); + } else { + comboBox->setObjectName("MenuComboBoxSingleColumnCenter"); + } + } else { + int rowCount = (itemCount + 1) / 2; + int row = index / 2; + int col = index % 2; + if ((itemCount == 1) || (col == 0 && index == (itemCount - 1))) { //only one item in last row + comboBox->setObjectName("MenuComboBoxSingleColumnBottom"); + } else if (row >= 0 && row < (rowCount - 1)) { + (col == 0) ? comboBox->setObjectName("MenuComboBoxLeft") : comboBox->setObjectName("MenuComboBoxRight"); + } else { + (col == 0) ? comboBox->setObjectName("MenuComboBoxBottomLeft") : comboBox->setObjectName("MenuComboBoxBottomRight"); + } + } +} + +void DuiApplicationMenuViewPrivate::addStyleWidget(DuiWidget *widget, DuiWidget *before) +{ + int count = stylePolicy->count(); + if (count == 0) { + addStyleSpacer(); + addStyleSpacer(); + } + //insert at the second last position (spacer at the end and + //in the beginning) if no before exists + int index = stylePolicy->count() - 1; + if (before) { + int beforeIndex = -1; + if ((beforeIndex = stylePolicy->indexOf(before)) >= 0) { + index = beforeIndex; + } + } + stylePolicy->insertItem(index, widget, Qt::AlignCenter); +} + +void DuiApplicationMenuViewPrivate::addActionCommandWidget(DuiWidget *widget, DuiWidget *before) +{ + int portIndex = portraitPolicy->count(); + if (before) { + int beforeIndex = -1; + if ((beforeIndex = portraitPolicy->indexOf(before)) >= 0) { + portIndex = beforeIndex; + } + } + portraitPolicy->insertItem(portIndex, widget); + + //For landscape policy, there is no way to insert the items at any position + //in the grid. So have to remove them first and then re-add them all + refreshLandscapePolicy(); +} + +void DuiApplicationMenuViewPrivate::removeStyleWidget(DuiWidget *widget) +{ + styleCommandLayout->removeItem(widget); + DuiButton *button = qobject_cast(widget); + if (button) { + styleButtonGroup->removeButton(button); + } + int count = stylePolicy->count(); + if (count == 2) { //delete the spacers as well + while (stylePolicy->count()) { + QGraphicsLayoutItem *item = stylePolicy->itemAt(0); + stylePolicy->removeAt(0); + delete item; + } + } +} + +void DuiApplicationMenuViewPrivate::addStyleSpacer() +{ + QGraphicsWidget *w = new QGraphicsWidget(controller); + w->setMinimumSize(0, 0); + w->setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); + stylePolicy->addItem(w); +} + +void DuiApplicationMenuViewPrivate::makeLandscapePolicyColumnsEqual() +{ + Q_Q(DuiApplicationMenuView); + QSize sceneSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); + if (controller->sceneManager()) + sceneSize = controller->sceneManager()->visibleSceneSize(Dui::Landscape); + else if (DuiApplication::activeWindow()) + sceneSize = DuiApplication::activeWindow()->visibleSceneSize(Dui::Landscape); + else if (!DuiApplication::windows().isEmpty()) + sceneSize = DuiApplication::windows().at(0)->visibleSceneSize(Dui::Landscape); + qreal l, r; + actionCommandLayout->getContentsMargins(&l, 0, &r, 0); + int width = (sceneSize.width() - + q->style()->marginLeft() - q->style()->marginRight() - + q->style()->paddingLeft() - q->style()->paddingRight() - + l - r) / 2; + landscapePolicy->setColumnPreferredWidth(0, width); + landscapePolicy->setColumnPreferredWidth(1, width); +} + +DuiApplicationMenuView::DuiApplicationMenuView(DuiApplicationMenu *controller) : + DuiSceneWindowView(* new DuiApplicationMenuViewPrivate(controller), controller) +{ + Q_D(DuiApplicationMenuView); + d->init(); +} + +DuiApplicationMenuView::DuiApplicationMenuView(DuiApplicationMenuViewPrivate &dd, DuiApplicationMenu *controller) : + DuiSceneWindowView(dd, controller) +{ + Q_D(DuiApplicationMenuView); + d->init(); +} + +DuiApplicationMenuView::~DuiApplicationMenuView() +{ +} + +void DuiApplicationMenuView::drawBackground(QPainter *painter, const QStyleOptionGraphicsItem *option) const +{ + Q_UNUSED(option); + + Q_D(const DuiApplicationMenuView); + + if (style()->canvasOpacity() > 0.0) { + // draw canvas + painter->setOpacity(d->controller->effectiveOpacity() * style()->canvasOpacity()); + + QRectF layoutGeometry = d->controllerLayout->geometry(); + + if (style()->canvasImage()) { + style()->canvasImage()->draw(layoutGeometry.toRect(), painter); + } else { + QColor color = style()->canvasColor(); + painter->fillRect(layoutGeometry, QBrush(color)); + } + } +} + +void DuiApplicationMenuView::drawContents(QPainter *painter, const QStyleOptionGraphicsItem *option) const +{ + DuiSceneWindowView::drawContents(painter, option); +} + +void DuiApplicationMenuView::applyStyle() +{ + Q_D(DuiApplicationMenuView); + + DuiSceneWindowView::applyStyle(); + + d->makeLandscapePolicyColumnsEqual(); + d->updateItemMode(); +} + +DUI_REGISTER_VIEW_NEW(DuiApplicationMenuView, DuiApplicationMenu) + diff --git a/src/widgets/views/duiapplicationmenuview.h b/src/widgets/views/duiapplicationmenuview.h new file mode 100644 index 000000000..1b899d59b --- /dev/null +++ b/src/widgets/views/duiapplicationmenuview.h @@ -0,0 +1,117 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLICATIONMENUVIEW_H +#define DUIAPPLICATIONMENUVIEW_H + +#include "duiscenewindowview.h" +#include +#include "duiapplicationmenumodel.h" +#include + +class DuiApplicationMenu; +class DuiApplicationMenuViewPrivate; + +/*! + \class DuiApplicationMenuView + \brief View class for DuiApplicationMenu. + + \ingroup views + + \section DuiApplicationMenuViewOverview Overview + DuiApplicationMenuView is used to visualize actions placed into the DuiApplicationMenu. + DuiApplicationMenuView appears once the user clicks on the view menu title area. It is opened on + top of the current application view. Background of the view is dimmed/blurred when application + menu is open. The outlook of view menu can be changed using the styling attributes defined in + DuiApplicationMenuStyle and DuiSceneWindowStyle. + + The following action widgets are supported for this particular view: + - Button, Icon button variant + - Combobox + + \subsection DuiApplicationMenuViewCommands Commands + - There are two main types of commands: view style commands and action commands + - The view style commands set the style/order/presentation of the contents of the view, while + still staying inside the same view. Examples of style commands include a setting for list/grid + style presentation for the current view, or setting abc/recent/favourites sorting order for + the contents of the view + - Style commands are grouped and mutually exclusive, so only one can be selected at any time. + - Action commands can open new views or dialogs, essentially leaving the current view and presenting + a new UI, in the same task or then in a new task + - The view can contain only view style commands, only action commands, or both of them + - The view style and action commands are grouped together and presented separately; the view + style commands always first (on the top of the menu) + - In portrait mode, the commands are presented one item per row, vertically from top to bottom + - In landscape mode, the commands are presented in two items per row, horizontally from left to + right, then from top to bottom. + - The user should be able to turn the device orientation after opening the menu, which will redraw + the menu in the new orientation. + - Maximum number of action commands is 8, and in presence of style commands, maximum number of + action commands reduces to 6. + + \section DuiApplicationMenuInteractions Interactions + - The view can be closed by tapping anywhere outside the menu (anywhere in the dimmed area) + - The view can also be closed from the top of screen (from the view menu title, or the top right corner) + - Selecting an action command from the view menu closes the menu + - Selecting a view style command closes the view menu and sets the view and its contents in + the newly selected style. + + \sa DuiApplicationMenu DuiApplicationMenuModel DuiApplicationMenuStyle + +*/ + +class DUI_EXPORT DuiApplicationMenuView : public DuiSceneWindowView +{ + Q_OBJECT + DUI_VIEW(DuiApplicationMenuModel, DuiApplicationMenuStyle) + +public: + /*! + \brief Constructs DuiApplicationMenuView with a pointer to the controller + */ + DuiApplicationMenuView(DuiApplicationMenu *controller); + + /*! + * \brief Destructs DuiApplicationMenuView + */ + virtual ~DuiApplicationMenuView(); + + //! \reimp + virtual void drawBackground(QPainter *painter, const QStyleOptionGraphicsItem *option) const; + virtual void drawContents(QPainter *painter, const QStyleOptionGraphicsItem *option) const; + //! \reimp_end + +protected: + //! \reimp + virtual void applyStyle(); + //! \reimp_end + DuiApplicationMenuView(DuiApplicationMenuViewPrivate &dd, DuiApplicationMenu *controller); + +private: + Q_DISABLE_COPY(DuiApplicationMenuView) + Q_DECLARE_PRIVATE(DuiApplicationMenuView) + +#ifdef UNIT_TEST + friend class Pt_DuiApplicationMenu; +#endif + +}; + + +#endif diff --git a/src/widgets/views/duiapplicationmenuview_p.h b/src/widgets/views/duiapplicationmenuview_p.h new file mode 100644 index 000000000..91729079b --- /dev/null +++ b/src/widgets/views/duiapplicationmenuview_p.h @@ -0,0 +1,108 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLICATIONMENUVIEW_P_H +#define DUIAPPLICATIONMENUVIEW_P_H + +#include +#include +#include +#include "duiaction.h" +#include "duiscenewindowview_p.h" +#include "duinamespace.h" +#include "duiapplicationmenuview.h" + +class DuiApplicationMenu; +class DuiPannableViewport; +class QGraphicsLayoutItem; +class DuiAbstractLayoutPolicy; +class DuiGridLayoutPolicy; +class DuiLinearLayoutPolicy; +class DuiFlowLayoutPolicy; +class DuiButton; +class DuiWidgetAction; +class DuiLayout; +class QGraphicsLinearLayout; +class DuiButtonGroup; +class DuiWidget; +class DuiContentItem; +class DuiComboBox; + +class DuiApplicationMenuViewPrivate : public DuiSceneWindowViewPrivate, public QObject +{ + Q_DECLARE_PUBLIC(DuiApplicationMenuView) + +public: + DuiApplicationMenuViewPrivate(DuiApplicationMenu *menu); + virtual ~DuiApplicationMenuViewPrivate(); + virtual void init(); + virtual void createPolicy(Dui::Orientation o); + + virtual void add(QAction *action, QAction *before); + virtual void remove(QAction *action); + virtual void change(QAction *action); + +protected: + virtual bool eventFilter(QObject *obj, QEvent *event); + virtual void addActions(); + DuiWidget *createWidget(QAction *action); + DuiWidget *createButton(QAction *action); + bool isStyleAction(QAction *action); + bool isLocationValid(QAction *action, DuiAction::Location loc); + bool isVisible(QAction *action); + void clearWidgets(QHash& widgets); + void deleteWidget(QAction *action, DuiWidget *widget); + bool releaseWidget(QAction *action, DuiWidget *widget); + DuiWidget *requestWidget(DuiAction *action); + bool isWidgetInUseByView(DuiWidgetAction *widgetAction); + bool hasWidget(QAction *action); + bool isWidgetUsable(QAction *action); + bool isWidgetUsable(DuiWidgetAction *widgetAction); + DuiWidget *getWidget(QAction *action); + bool canAddMoreActions(QAction *action); + void visibleActionsCount(int &commandActionsCount, int &styleActionsCount); + bool changeLocation(QAction *action); + void changeData(QAction *action); + void changeVisibility(QAction *action); + void changeStyleAttribute(QAction *action); + void refreshPolicies(bool refresh); + void clearPolicy(DuiAbstractLayoutPolicy *policy); + void refreshLandscapePolicy(); + void updateItemMode(); + void updateContentItemMode(DuiContentItem *contentItem, int columnsCount, int itemCount, int index); + void updateComboboxMode(DuiComboBox *comboBox, int columnsCount, int itemCount, int index); + void addStyleWidget(DuiWidget *widget, DuiWidget *before); + void addActionCommandWidget(DuiWidget *widget, DuiWidget *before); + void removeStyleWidget(DuiWidget *widget); + void addStyleSpacer(); + void makeLandscapePolicyColumnsEqual(); + +protected: + QGraphicsLinearLayout *controllerLayout; + DuiLayout *styleCommandLayout; + DuiLayout *actionCommandLayout; + DuiGridLayoutPolicy *landscapePolicy; + DuiLinearLayoutPolicy *portraitPolicy; + DuiLinearLayoutPolicy *stylePolicy; + DuiButtonGroup *styleButtonGroup; + QHash leasedWidgets; + QHash buttons; +}; + +#endif diff --git a/src/widgets/views/duiapplicationpageview.cpp b/src/widgets/views/duiapplicationpageview.cpp new file mode 100644 index 000000000..f32f0b316 --- /dev/null +++ b/src/widgets/views/duiapplicationpageview.cpp @@ -0,0 +1,53 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiapplicationpageview.h" +#include "duiapplicationpageview_p.h" + +#include "duiapplication.h" +#include "duiapplicationwindow.h" +#include "duiscalableimage.h" +#include "duiapplicationpage.h" +#include "duiscenemanager.h" +#include "duiviewcreator.h" + +DuiApplicationPageViewPrivate::DuiApplicationPageViewPrivate() +{ +} + +DuiApplicationPageViewPrivate::~DuiApplicationPageViewPrivate() +{ +} + +DuiApplicationPageView::DuiApplicationPageView(DuiApplicationPage *controller) : + DuiSceneWindowView(*new DuiApplicationPageViewPrivate, controller) +{ +} + +DuiApplicationPageView::~DuiApplicationPageView() +{ +} +/* +QRectF DuiApplicationPageView::boundingRect() const +{ + +} +*/ + +DUI_REGISTER_VIEW_NEW(DuiApplicationPageView, DuiApplicationPage) diff --git a/src/widgets/views/duiapplicationpageview.h b/src/widgets/views/duiapplicationpageview.h new file mode 100644 index 000000000..aaed4bbac --- /dev/null +++ b/src/widgets/views/duiapplicationpageview.h @@ -0,0 +1,47 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLICATIONPAGEVIEW_H +#define DUIAPPLICATIONPAGEVIEW_H + +#include "duiscenewindowview.h" +#include + +class DuiApplicationPage; +class DuiApplicationPageViewPrivate; + +class DUI_EXPORT DuiApplicationPageView : public DuiSceneWindowView +{ + Q_OBJECT + DUI_VIEW(DuiWidgetModel, DuiApplicationPageStyle) + +public: + DuiApplicationPageView(DuiApplicationPage *controller); + virtual ~DuiApplicationPageView(); + + //! \reimp + //virtual QRectF boundingRect() const; + //! \reimp_end + +private: + Q_DECLARE_PRIVATE(DuiApplicationPageView) +}; + +#endif + diff --git a/src/widgets/views/duiapplicationpageview_p.h b/src/widgets/views/duiapplicationpageview_p.h new file mode 100644 index 000000000..5df91afa2 --- /dev/null +++ b/src/widgets/views/duiapplicationpageview_p.h @@ -0,0 +1,35 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLICATIONPAGEVIEW_P_H +#define DUIAPPLICATIONPAGEVIEW_P_H + +#include "duiapplicationpageview.h" +#include "duiscenewindowview_p.h" + +class DuiApplicationPageViewPrivate : public DuiSceneWindowViewPrivate +{ +public: + DuiApplicationPageViewPrivate(); + virtual ~DuiApplicationPageViewPrivate(); + +}; + +#endif + diff --git a/src/widgets/views/duibuttongrouplayoutpolicy_p.cpp b/src/widgets/views/duibuttongrouplayoutpolicy_p.cpp new file mode 100644 index 000000000..58cc8307e --- /dev/null +++ b/src/widgets/views/duibuttongrouplayoutpolicy_p.cpp @@ -0,0 +1,72 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duibuttongrouplayoutpolicy_p.h" +#include +#include + +DuiButtonGroupLayoutPolicy::DuiButtonGroupLayoutPolicy(DuiLayout *layout, Qt::Orientation orientation) + : DuiLinearLayoutPolicy(layout, orientation) +{ +} + +DuiButtonGroupLayoutPolicy::~DuiButtonGroupLayoutPolicy() +{ } + +void DuiButtonGroupLayoutPolicy::insertItem(int index, QGraphicsLayoutItem *item) +{ + DuiLinearLayoutPolicy::insertItem(index, item); + + updateButtonsViewTypes(); +} + +void DuiButtonGroupLayoutPolicy::removeAt(int index) +{ + DuiLinearLayoutPolicy::removeAt(index); + + updateButtonsViewTypes(); +} + +void DuiButtonGroupLayoutPolicy::updateButtonsViewTypes() +{ + const int buttonBoxSize = count(); + + if (buttonBoxSize == 0) return; + + if (buttonBoxSize == 1) { + setButtonViewType(0, "single"); + } else { + int i = 0; + setButtonViewType(i, "first"); + while (++i < buttonBoxSize - 1) { + setButtonViewType(i, "middle"); + } + setButtonViewType(i, "last"); + } +} + +void DuiButtonGroupLayoutPolicy::setButtonViewType(int index, const DuiTheme::ViewType &viewType) +{ + DuiButton *button = dynamic_cast(itemAt(index)); + if (button) { + button->setViewType(viewType); + } else { + qWarning("Only DuiButton should be added to DuiButtonGroupLayoutPolicy."); + } +} diff --git a/src/widgets/views/duibuttongrouplayoutpolicy_p.h b/src/widgets/views/duibuttongrouplayoutpolicy_p.h new file mode 100644 index 000000000..c819539a8 --- /dev/null +++ b/src/widgets/views/duibuttongrouplayoutpolicy_p.h @@ -0,0 +1,44 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIBUTTONGROUPLAYOUTPOLICY_P_H +#define DUIBUTTONGROUPLAYOUTPOLICY_P_H + +#include +#include + +class DuiButtonGroupLayoutPolicy : public DuiLinearLayoutPolicy +{ +public: + DuiButtonGroupLayoutPolicy(DuiLayout *layout, Qt::Orientation orientation); + + virtual ~DuiButtonGroupLayoutPolicy(); + + virtual void insertItem(int index, QGraphicsLayoutItem *item); + virtual void removeAt(int index); + +protected: + void updateButtonsViewTypes(); + void setButtonViewType(int index, const DuiTheme::ViewType &viewType); + +private: + Q_DISABLE_COPY(DuiButtonGroupLayoutPolicy) +}; + +#endif // DUIBUTTONGROUPLAYOUTPOLICY_P_H diff --git a/src/widgets/views/duibuttoniconview.cpp b/src/widgets/views/duibuttoniconview.cpp new file mode 100644 index 000000000..6fcef76a4 --- /dev/null +++ b/src/widgets/views/duibuttoniconview.cpp @@ -0,0 +1,301 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duibuttoniconview.h" +#include "duibuttoniconview_p.h" + +#include +#include + +#include "duiviewcreator.h" +#include "duibutton.h" +#include "duibutton_p.h" +#include "duilabel.h" +#include "duitheme.h" + + +// TODO: to be removed when the glow pixmap generation is moved to application side as an effect. +QImage glow(const QImage &image, int radius, const QColor &color); + +DuiButtonIconViewPrivate::DuiButtonIconViewPrivate() + : timelineShrink(new QTimeLine()) + , timelineGlow(new QTimeLine()) +{ + timelineShrink->setCurveShape(QTimeLine::EaseInCurve); + timelineGlow->setCurveShape(QTimeLine::SineCurve); +} + +DuiButtonIconViewPrivate::~DuiButtonIconViewPrivate() +{ + delete timelineShrink; + delete timelineGlow; +} + +void DuiButtonIconViewPrivate::drawGlowIcon(QPainter *painter, const QRectF &iconRect) const +{ + Q_Q(const DuiButtonIconView); + + if (!icon) + return; + + QRectF glowRect = iconRect; + QPointF offset(-q->style()->glowRadius(), + -q->style()->glowRadius()); + glowRect.translate(offset); + glowRect.setSize(QSizeF(icon->width() + 2 * q->style()->glowRadius(), icon->height() + 2 * q->style()->glowRadius())); + + painter->setOpacity(controller->effectiveOpacity() * timelineGlow->currentValue()); + // TODO: cache the glow image/pixmap, and update it only if icon->handle() has changed. + painter->drawImage(glowRect, glow(icon->toImage(), q->style()->glowRadius(), q->style()->glowColor())); +} + +DuiButtonIconView::DuiButtonIconView(DuiButton *controller) : + DuiButtonView(* new DuiButtonIconViewPrivate, controller) +{ + Q_D(DuiButtonIconView); + + connect(d->timelineShrink, SIGNAL(valueChanged(qreal)), + this, SLOT(scaleValueChanged(qreal))); + + connect(d->timelineGlow, SIGNAL(valueChanged(qreal)), + this, SLOT(glowValueChanged(qreal))); +} + +DuiButtonIconView::~DuiButtonIconView() +{ +} + +void DuiButtonIconView::drawContents(QPainter *painter, const QStyleOptionGraphicsItem *option) const +{ + Q_D(const DuiButtonIconView); + + bool scaling = (d->timelineShrink->state() == QTimeLine::Running) || (model()->down()); + bool glowing = (!model()->down()) && (d->timelineGlow->state() == QTimeLine::Running) && + model()->iconVisible(); + + if (!scaling && !glowing) { + DuiButtonView::drawContents(painter, option); + } else { + QRectF iconRect = d->iconRect; + + if (scaling) { + int w = size().width() / 2; + int h = size().height() / 2; + painter->translate(QPoint(w, h)); + + // update iconRect and textRect for translate + QPointF offset(-w, -h); + iconRect.translate(offset); + + // Scales the painting if zoom timeline running or button pressed + float value = d->timelineShrink->currentValue(); + float s = 1.0f - style()->shrinkFactor() * value; + painter->setRenderHint(QPainter::SmoothPixmapTransform); + painter->scale(s, s); + } + + // draw glow icon + if (glowing) + d->drawGlowIcon(painter, iconRect); + + painter->setOpacity(d->controller->effectiveOpacity()); + + drawIcon(painter, iconRect); + } +} + +void DuiButtonIconView::drawBackground(QPainter *painter, const QStyleOptionGraphicsItem *option) const +{ + Q_UNUSED(painter); + Q_UNUSED(option); +} + +void DuiButtonIconView::applyStyle() +{ + Q_D(DuiButtonIconView); + + DuiButtonView::applyStyle(); + + d->timelineShrink->setDuration(style()->shrinkDuration()); + d->timelineGlow->setDuration(style()->glowDuration()); +} + +void DuiButtonIconView::scaleValueChanged(qreal value) +{ + Q_UNUSED(value); + Q_D(DuiButtonIconView); + + float s = 1.0f - style()->shrinkFactor() * value; + if (s != 1.0f) + d->label->setTransformOriginPoint(d->label->size().width() / 2.0f, d->label->size().height() / 2.0f); + else + d->label->setTransformOriginPoint(0.0f, 0.0f); + d->label->setScale(s); + + update(); +} + +void DuiButtonIconView::glowValueChanged(qreal value) +{ + Q_UNUSED(value); + update(); +} + + +void DuiButtonIconView::updateData(const QList& modifications) +{ + Q_D(DuiButtonIconView); + + DuiButtonView::updateData(modifications); + const char *member; + foreach(member, modifications) { + if (member == DuiButtonModel::Down) { + //start shrinking animation + d->timelineShrink->setDirection(model()->down() ? QTimeLine::Forward : QTimeLine::Backward); + if (d->timelineShrink->state() == QTimeLine::NotRunning) + d->timelineShrink->start(); + + //start glowing if the button was released + if (!model()->down()) { + if (d->timelineGlow->state() == QTimeLine::Running) + d->timelineGlow->setCurrentTime(0); + else + d->timelineGlow->start(); + } + } + } +} + +DUI_REGISTER_VIEW_NEW(DuiButtonIconView, DuiButton) + + +//////////////////////////////////////////////////// +// glow generation + + +// blur image +static void blur(const QImage *source, QImage *destination, int radius, const QColor &color) +{ + QSize s = destination->size(); + int width = s.width(); + int height = s.height(); + + QImage tmp(s, QImage::Format_ARGB32); + + qreal GlowColorR = color.redF(); + qreal GlowColorG = color.greenF(); + qreal GlowColorB = color.blueF(); + + int total, alpha; + QRgb *buffer; + + // horizontal + for (int y = 0; y < height; ++y) { + total = 0; + buffer = (QRgb *)tmp.scanLine(y); + + // Process entire window for first pixel + //for (int kx = -radius; kx <= radius; ++kx) + if (y >= radius && y < height - radius) { + total = qAlpha(source->pixel(0, y - radius)); + + alpha = total / (radius * 2 + 1); + *buffer = qRgba(0, 0, 0, alpha); + buffer++; + + // Subsequent pixels just update window total + for (int x = 1; x < width; ++x) { + // Subtract pixel leaving window + if (x - radius * 2 - 1 >= 0) // && x - radius*2 < source->size().width()) + total -= qAlpha(source->pixel(x - radius * 2 - 1, y - radius)); + + // Add pixel entering window + if (x > 0 && x < source->size().width()) + total += qAlpha(source->pixel(x, y - radius)); + + alpha = total / (radius * 2 + 1); + + *buffer = qRgba(0, 0, 0, alpha); + buffer++; + } + } else { + for (int x = 0; x < width; ++x) { + *buffer = qRgba(0, 0, 0, 0); + buffer++; + } + } + } + + qreal r, g, b, a; + // vertical + for (int x = 0; x < width; ++x) { + total = 0; + + // Process entire window for first pixel + //for (int ky = -radius; ky <= radius; ++ky) + for (int ky = 0; ky <= radius; ++ky) + total += qAlpha(tmp.pixel(x, ky)); + + alpha = total / (radius * 2 + 1); + + r = alpha * GlowColorR * 2; + g = alpha * GlowColorG * 2; + b = alpha * GlowColorB * 2; + a = alpha * 2; + if (r > 255) r = 255; + if (g > 255) g = 255; + if (b > 255) b = 255; + if (a > 255) a = 255; + + buffer = (QRgb *)destination->scanLine(0); + *(buffer + x) = qRgba(r, g, b, a); + + // Subsequent pixels just update window total + for (int y = 1; y < height; ++y) { + // Subtract pixel leaving window + if (y - radius - 1 >= 0) + total -= qAlpha(tmp.pixel(x, y - radius - 1)); + + // Add pixel entering window + if (y + radius < height) + total += qAlpha(tmp.pixel(x, y + radius)); + + alpha = total / (radius * 2 + 1); + + r = alpha * GlowColorR * 2; + g = alpha * GlowColorG * 2; + b = alpha * GlowColorB * 2; + a = alpha * 2; + if (r > 255) r = 255; + if (g > 255) g = 255; + if (b > 255) b = 255; + if (a > 255) a = 255; + + buffer = (QRgb *)destination->scanLine(y); + *(buffer + x) = qRgba(r, g, b, a); + } + } +} + +QImage glow(const QImage &image, int radius, const QColor &color) +{ + QImage g(image.width() + 2 * radius, image.height() + 2 * radius, QImage::Format_ARGB32); + blur(&image, &g, radius, color); + return g; +} diff --git a/src/widgets/views/duibuttoniconview.h b/src/widgets/views/duibuttoniconview.h new file mode 100644 index 000000000..40445d55d --- /dev/null +++ b/src/widgets/views/duibuttoniconview.h @@ -0,0 +1,122 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIBUTTONICONVIEW_H +#define DUIBUTTONICONVIEW_H + +#include "duibuttonview.h" +#include +#include + +class DuiButtonIconViewPrivate; +class DuiButton; + +/*! + \class DuiButtonIconView + \brief View class for icon button. + + \ingroup views + + \section DuiButtonIconViewOverview Overview + DuiButtonIconView draws an icon and text similarly as DuiButtonView + using the same styling attributes. However this view adds some animations + when interacting with a button: + + - When pressing button down it starts to shrink the graphics so it + looks like the button is actually pressed down. + DuiButtonIconStyle::shrinkDuration and DuiButtonIconStyle::shrinkFactor + attributes are used the define the outlook for the shrinking animation. + - When releasing button it starts to glow and grow back to it's normal + size. DuiButtonIconStyle::glowColor, DuiButtonIconStyle::glowDuration + and DuiButtonIconStyle::glowRadius style attributes can be used to + change the visualization of the glow. + + + + * DuiButtonIconView supports the following CSS features: + * + * glowColor (type: QColor e.g. #ff0000) : sets the color of the glow effect
+ * glowDuration (type: int) : sets the time in ms for the glow effect to last
+ * glowRadius (type: int) : sets the extent of the glow effect
+ * shrinkDuration (type: int) : time how long the shrink effect takes
+ * shrinkFactor (type: float) : how much smaller should the shrunk button be?
+ + \section DuiButtonIconViewInteractions Interactions + See \ref DuiButtonViewInteractions. + + \section DuiButtonIconViewOpenIssues Open issues + - The outlook of the whole icon button: are glow and shrinking really + used in this? + + \sa DuiButton DuiButtonView DuiButtonIconStyle +*/ +class DUI_EXPORT DuiButtonIconView : public DuiButtonView +{ + Q_OBJECT + DUI_VIEW(DuiButtonModel, DuiButtonIconStyle) + +public: + + /*! + \brief Constructs the view. + \param Pointer to the controller. + */ + DuiButtonIconView(DuiButton *controller); + + /*! + \brief Destructs the view. + */ + virtual ~DuiButtonIconView(); + +protected: + //! \reimp + virtual void drawContents(QPainter *painter, const QStyleOptionGraphicsItem *option) const; + virtual void drawBackground(QPainter *painter, const QStyleOptionGraphicsItem *option) const; + virtual void applyStyle(); + //! \reimp_end + +protected Q_SLOTS: + + //! \reimp + virtual void updateData(const QList& modifications); + //! \reimp_end + +private Q_SLOTS: + + /*! + \brief Receives signals from scale timeline + */ + void scaleValueChanged(qreal value); + + /*! + \brief Receives signals from glow timeline + */ + void glowValueChanged(qreal value); + +private: + Q_DISABLE_COPY(DuiButtonIconView) + Q_DECLARE_PRIVATE(DuiButtonIconView) + +#ifdef UNIT_TEST + friend class Ut_DuiButtonIconView; +#endif + +}; + +#endif diff --git a/src/widgets/views/duibuttoniconview_p.h b/src/widgets/views/duibuttoniconview_p.h new file mode 100644 index 000000000..3e79c5555 --- /dev/null +++ b/src/widgets/views/duibuttoniconview_p.h @@ -0,0 +1,41 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIBUTTONICONVIEW_P_H +#define DUIBUTTONICONVIEW_P_H + +#include "duibuttonview_p.h" + +class QTimeLine; +class QPixmap; + +class DuiButtonIconViewPrivate : public DuiButtonViewPrivate +{ + Q_DECLARE_PUBLIC(DuiButtonIconView) +public: + DuiButtonIconViewPrivate(); + ~DuiButtonIconViewPrivate(); + + void drawGlowIcon(QPainter *painter, const QRectF &iconRect) const; + + QTimeLine *timelineShrink; + QTimeLine *timelineGlow; +}; + +#endif diff --git a/src/widgets/views/duibuttonswitchview.cpp b/src/widgets/views/duibuttonswitchview.cpp new file mode 100644 index 000000000..abed1722d --- /dev/null +++ b/src/widgets/views/duibuttonswitchview.cpp @@ -0,0 +1,317 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duibuttonswitchview.h" +#include "duibuttonswitchview_p.h" + +#include +#include +#include + +#include "duiviewcreator.h" +#include "duibutton.h" +#include "duibutton_p.h" +#include "duilabel.h" +#include "duitheme.h" +#include "duidebug.h" +#include "duiscalableimage.h" +//#include "duigles2renderer.h" + +#include +#include +#include + + +DuiButtonSwitchViewPrivate::DuiButtonSwitchViewPrivate() : + m_thumbDown(false), + m_thumbDragged(false), + m_thumbPos(0, 0) +{ +} + +DuiButtonSwitchViewPrivate::~DuiButtonSwitchViewPrivate() +{ +} + +void DuiButtonSwitchViewPrivate::createMaskedSlider() +{ + Q_Q(DuiButtonSwitchView); + + //create images from pixmaps to get access to pixel data + + //TODO this is only SW solution, the proper masking will be implemented with GLES2 shaders + + //scale the mask to match the view size + if (q->size().isValid()) { + QPixmap scrollerPm(q->size().width(), q->size().height()); + scrollerPm.fill(QColor(0, 0, 0, 0)); + QPainter p0(&scrollerPm); + q->style()->sliderMask()->draw(QPoint(0, 0), scrollerPm.size(), &p0); + p0.end(); + m_maskedSliderImage = scrollerPm.toImage().convertToFormat(QImage::Format_ARGB32); + } + + //TODO: could be done only when style changes + m_sliderImage = q->style()->sliderImage()->pixmap()->toImage(); +} + +void DuiButtonSwitchViewPrivate::updateMaskedSlider() +{ + //TODO this is only SW solution, the proper masking solution will be done with gl shader + + //mask the slider image, result is stored to m_maskedSliderImage + int width = m_maskedSliderImage.width(); + int height = m_maskedSliderImage.height(); + int offset = (m_sliderImage.width() / 2) - thumbPos().x() - (thumbSize().width() / 2); + for (int y = 0; y < height; ++y) { + const uint *scanline = (const uint *) m_sliderImage.scanLine(y) + offset; + uint *result = (uint *) m_maskedSliderImage.scanLine(y); + for (int x = 0; x < width; ++x) { + *result = ((*result) & 0xff000000) | ((*scanline) & 0x00ffffff); + scanline++; + result++; + } + } +} + +QSize DuiButtonSwitchViewPrivate::thumbSize() const +{ + Q_Q(const DuiButtonSwitchView); + + QSize thumb = q->style()->thumbImage()->pixmap()->size(); + QSizeF view = q->size(); + + //scale the thumb to fit inside the view, aspect ratio is kept the same + if (thumb.height() != view.height()) { + float f = view.height() / thumb.height(); + return thumb * f; + } else + return thumb; +} + +QPoint DuiButtonSwitchViewPrivate::thumbPos() const +{ + Q_Q(const DuiButtonSwitchView); + + //when thumb is not dragged it is on another end of the view + if (!m_thumbDragged) { + QSize thumb = thumbSize(); + int h = (q->size().height() / 2) - (thumb.height() / 2); + if (q->model()->checked()) + return QPoint(q->size().width() - thumb.width(), h); + else + return QPoint(0, h); + } + //return dragged thumb position + else { + return m_thumbPos; + } +} + +void DuiButtonSwitchViewPrivate::updateImages() +{ + createMaskedSlider(); + + //TODO: Is there better solution for this? + + //if the images are not yet valid due to asynchronous resource loading + //launch singleShot timer until everything has been loaded, this is needed + //to be able to optimize SW rendering for the masked slider background + if (m_maskedSliderImage.isNull() || m_sliderImage.isNull() || + m_maskedSliderImage.size() == QSize(1, 1) || m_sliderImage.size() == QSize(1, 1)) { + const int timeout = 500; + //duiWarning("DuiButtonSwitchViewPrivate") << "updateImages() Images not valid yet, refreshing after" << timeout << "ms"; + Q_Q(DuiButtonSwitchView); + QTimer::singleShot(timeout, q, SLOT(updateImages())); + } else + updateMaskedSlider(); +} + +DuiButtonSwitchView::DuiButtonSwitchView(DuiButton *controller) : + DuiButtonView(* new DuiButtonSwitchViewPrivate, controller) +{ +} + +DuiButtonSwitchView::~DuiButtonSwitchView() +{ +} + +void DuiButtonSwitchView::resizeEvent(QGraphicsSceneResizeEvent *event) +{ + DuiWidgetView::resizeEvent(event); + + Q_D(DuiButtonSwitchView); + + //create and update slider image masking + d->updateImages(); +} + +void DuiButtonSwitchView::drawContents(QPainter *painter, const QStyleOptionGraphicsItem *option) const +{ + Q_UNUSED(option); + Q_D(const DuiButtonSwitchView); + + //((DuiButtonSwitchViewPrivate*)d)->createMaskedSlider(); + //((DuiButtonSwitchViewPrivate*)d)->updateMaskedSlider(); + + painter->drawImage(QRect(QPoint(0, 0), size().toSize()), d->m_maskedSliderImage); + style()->thumbImage()->draw(d->thumbPos(), d->thumbSize(), painter); +} + +void DuiButtonSwitchView::applyStyle() +{ + DuiButtonView::applyStyle(); + + Q_D(DuiButtonSwitchView); + + //create and update slider image masking + d->updateImages(); +} + +void DuiButtonSwitchView::updateData(const QList& modifications) +{ + DuiButtonView::updateData(modifications); + Q_D(DuiButtonSwitchView); + const char *member; + foreach(member, modifications) { + if (member == DuiButtonModel::Checked) { + d->updateMaskedSlider(); + } + //else if( member == DuiButtonModel::IconID ) { + // + //} + } +} + +void DuiButtonSwitchView::setupModel() +{ + DuiButtonView::setupModel(); + Q_D(DuiButtonSwitchView); + d->updateMaskedSlider(); +} + + + + +void DuiButtonSwitchView::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + //quick escape if the switch is already down + if (model()->down()) { + return; + } + + Q_D(DuiButtonSwitchView); + QRect thumb(d->thumbPos(), d->thumbSize()); + + if (thumb.contains(event->pos().toPoint())) { + + //start drag from ON or OFF position + d->m_thumbPos = d->thumbPos(); + + + //if (style()->pressFeedback()) { + // style()->pressFeedback()->play(); + //} + + d->mouseOffset = event->pos().x() - d->controller->pos().x() - d->m_thumbPos.x(); + + d->m_thumbDown = true; + } + + //set switch to down mode + model()->setDown(true); +} + + + +void DuiButtonSwitchView::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + //DuiButtonView::mouseReleaseEvent(event); + Q_D(DuiButtonSwitchView); + + Q_UNUSED(event); + + if (!model()->down()) { + return; + } + + //check if the thumb has been dragged + if (d->m_thumbDown && d->m_thumbDragged) { + + d->m_thumbDown = false; + d->m_thumbDragged = false; + model()->setDown(false); + //if (style()->releaseFeedback()) { + // style()->releaseFeedback()->play(); + //} + + //QPointF touch = event->scenePos(); + //QRectF rect = d->controller->sceneBoundingRect(); + //rect.adjust(-RELEASE_MISS_DELTA, -RELEASE_MISS_DELTA, + // RELEASE_MISS_DELTA, RELEASE_MISS_DELTA); + //if (rect.contains(touch)) { + //model()->click(); + if (d->m_thumbPos.x() + (d->thumbSize().width() / 2) > (size().width() / 2)) { + model()->setChecked(true); + } else { + model()->setChecked(false); + } + //} + + d->updateMaskedSlider(); + } + //user just clicked the switch, act like normal checkable button + else { + d->m_thumbDown = false; + d->m_thumbDragged = false; + DuiButtonView::mouseReleaseEvent(event); + } +} + +void DuiButtonSwitchView::mouseMoveEvent(QGraphicsSceneMouseEvent *event) +{ + Q_D(DuiButtonSwitchView); + + //drag only if the thumb was pressed down + if (d->m_thumbDown) { + QPointF pos = event->pos() - d->controller->pos(); + int x = qRound(pos.x()) - d->mouseOffset; + if (x < 0) + x = 0; + else if (x > (size().width() - d->thumbSize().width())) + x = size().width() - d->thumbSize().width(); + + d->m_thumbPos.setX(x); + d->m_thumbDragged = true; + d->updateMaskedSlider(); + + update(); + } +} + +void DuiButtonSwitchView::cancelEvent(DuiCancelEvent *event) +{ + Q_UNUSED(event); + model()->setDown(false); + update(); +} + +#include "moc_duibuttonswitchview.cpp" + +DUI_REGISTER_VIEW_NEW(DuiButtonSwitchView, DuiButton) diff --git a/src/widgets/views/duibuttonswitchview.h b/src/widgets/views/duibuttonswitchview.h new file mode 100644 index 000000000..0689759c5 --- /dev/null +++ b/src/widgets/views/duibuttonswitchview.h @@ -0,0 +1,140 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIBUTTONSWITCHVIEW_H +#define DUIBUTTONSWITCHVIEW_H + +#include +#include +#include + +class DuiButtonSwitchViewPrivate; +class DuiButton; + +/*! + \class DuiButtonSwitchView + \brief View class for switch button. + + \ingroup views + + \section DuiButtonSwitchViewOverview Overview + + + + + + + +
\image html switch_button_off.png \image html switch_button_on.png \image html switch_button_drag.png
+ + This type of button acts as a visual "toggle switch" that can be turned + on or off. + + A Switch differs from a push button and an icon button visually: the + button looks like a switch, communicating that pressing this button + will not go to another view or will not perform any other actions except + to toggle the state of the button. In addition to pressing, Switch state + can be toggled also by dragging. + + A Switch consists always of a graphic image representing a "physical switch", + with an optional text label. If a label is needed, it should be placed + next to the Switch button. + + A Switch button supports two states: + - Function off: The function is off, and it can be turned on. + - Function on: The function is on, and it can be turned off. + + The Switch has its own haptic feedback: switching button from off to on + feels different than when switching from on to off. + + \section DuiButtonSwitchViewInteractions Interactions + Users can change the state of switch button by tapping on it or dragging + the handle/thumb to different position. + + - Press down: Highlights the switch button. + - Tap (button down + button up): Toggles the state of + the switch. + - Tap and drag: Toggles the state of the switch. + - Tap down and drag finger out of the switch, release finger: + Cancels the press and does not change the state. + - Tap down and drag finger to scroll UI: Cancels the press + and does not change the state. + + + \section DuiButtonSwitchViewOpenIssues Open issues + + \sa DuiButton DuiButtonView DuiButtonSwitchStyle +*/ +class DUI_EXPORT DuiButtonSwitchView : public DuiButtonView +{ + Q_OBJECT + DUI_VIEW(DuiButtonModel, DuiButtonSwitchStyle) + +public: + + /*! + \brief Constructs the view. + \param Pointer to the controller. + */ + DuiButtonSwitchView(DuiButton *controller); + + /*! + \brief Destructs the view. + */ + virtual ~DuiButtonSwitchView(); + + //! \reimp + virtual void resizeEvent(QGraphicsSceneResizeEvent *event); + //! \reimp_end + +protected: + //! \reimp + virtual void drawContents(QPainter *painter, const QStyleOptionGraphicsItem *option) const; + virtual void applyStyle(); + virtual void setupModel(); + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event); + virtual void cancelEvent(DuiCancelEvent *event); + //! \reimp_end + +protected slots: + + //! \reimp + virtual void updateData(const QList& modifications); + //! \reimp_end + +private slots: + + + +private: + + Q_DISABLE_COPY(DuiButtonSwitchView) + Q_DECLARE_PRIVATE(DuiButtonSwitchView) + + Q_PRIVATE_SLOT(d_func(), void updateImages()) + +#ifdef UNIT_TEST + friend class Ut_DuiButtonSwitchView; +#endif + +}; + +#endif diff --git a/src/widgets/views/duibuttonswitchview_p.h b/src/widgets/views/duibuttonswitchview_p.h new file mode 100644 index 000000000..d509b1931 --- /dev/null +++ b/src/widgets/views/duibuttonswitchview_p.h @@ -0,0 +1,51 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIBUTTONSWITCHVIEW_P_H +#define DUIBUTTONSWITCHVIEW_P_H + +#include "duibuttonview_p.h" + +class DuiButtonSwitchViewPrivate : public DuiButtonViewPrivate +{ + Q_DECLARE_PUBLIC(DuiButtonSwitchView) + +public: + DuiButtonSwitchViewPrivate(); + ~DuiButtonSwitchViewPrivate(); + + void createMaskedSlider(); + void updateMaskedSlider(); + + QSize thumbSize() const; + QPoint thumbPos() const; + + void updateImages(); + + int mouseOffset; + + bool m_thumbDown; + bool m_thumbDragged; + QPoint m_thumbPos; + + QImage m_maskedSliderImage; + QImage m_sliderImage; +}; + +#endif diff --git a/src/widgets/views/duibuttonview.cpp b/src/widgets/views/duibuttonview.cpp new file mode 100644 index 000000000..5bbd0e30d --- /dev/null +++ b/src/widgets/views/duibuttonview.cpp @@ -0,0 +1,380 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duibuttonview.h" +#include "duibuttonview_p.h" + +#include +#include +#include + +#include "duibutton.h" +#include "duibutton_p.h" // For the member indexes of the model +#include "duifeedback.h" +#include "duitheme.h" +#include "duiscalableimage.h" +#include "duiviewcreator.h" +#include "duiscenemanager.h" +#include "duilabel.h" +#include "duidebug.h" +#include "duitimestamp.h" + +// Distance in pixels from the widget bounding box inside which a release is still accepted +#define RELEASE_MISS_DELTA 30 + +DuiButtonViewPrivate::DuiButtonViewPrivate() + : icon(0), toggledIcon(0), label(NULL) +{ +} + +DuiButtonViewPrivate::~DuiButtonViewPrivate() +{ + DuiTheme::releasePixmap(icon); + DuiTheme::releasePixmap(toggledIcon); +} + +// As the condition of text color and background change for button +bool DuiButtonViewPrivate::toggleState() const +{ + Q_Q(const DuiButtonView); + if (q->model()->checkable()) { + bool state = (!q->model()->checked() && q->model()->down()) + || (q->model()->checked() && !q->model()->down()); + return state; + } else + return q->model()->down(); +} + +void DuiButtonViewPrivate::refreshStyleMode() +{ + Q_Q(DuiButtonView); + + if (q->model()->down()) + q->style().setModePressed(); + else if (q->model()->checked()) + q->style().setModeSelected(); + else + q->style().setModeDefault(); + + label->setAlignment(q->style()->horizontalTextAlign() | q->style()->verticalTextAlign()); + label->setFont(q->style()->font()); + label->setColor(q->style()->textColor()); + + //update the icons only if the iconSize in the style has changed + QSize size = q->style()->iconSize(); + if (icon && icon->size() != size) { + loadIcon(icon, q->model()->iconID(), size); + } + if (toggledIcon && toggledIcon->size() != size) { + loadIcon(toggledIcon, q->model()->toggledIconID(), size); + } + + calcIconTextRects(); +} + +void DuiButtonViewPrivate::calcIconTextRects() +{ + Q_Q(const DuiButtonView); + + //total horizontal and vertical text margins + int hTextMargin = q->style()->textMarginLeft() + q->style()->textMarginRight(); + int vTextMargin = q->style()->textMarginTop() + q->style()->textMarginBottom(); + + //total horizontal and vertical padding + int hPadding = q->style()->paddingLeft() + q->style()->paddingRight(); + int vPadding = q->style()->paddingTop() + q->style()->paddingBottom(); + + //area for the content (icon and text) + QRect contentRect(q->style()->paddingLeft(), q->style()->paddingTop(), + q->size().width() - hPadding, + q->size().height() - vPadding); + + //text rect when there is no icon + QRect textRect = QRect(contentRect.left() + q->style()->textMarginLeft(), + contentRect.top() + q->style()->textMarginTop(), + contentRect.width() - hTextMargin, + contentRect.height() - vTextMargin); + + //icon visible and valid? + if (q->model()->iconVisible() && (icon || toggledIcon)) { + + int iconWidth = q->style()->iconSize().width(); + int iconHeight = q->style()->iconSize().height(); + + //text visible and valid? + if (q->model()->textVisible() && !q->model()->text().isEmpty()) { + + switch (q->style()->iconAlign()) { + //icon on left and text on right + case Qt::AlignLeft: { + iconRect = QRectF(contentRect.left(), contentRect.center().y() - (iconHeight / 2), iconWidth, iconHeight); + textRect.setX(iconRect.right() + q->style()->textMarginLeft()); + textRect.setWidth(contentRect.width() - iconWidth - hTextMargin); + break; + } + + //icon on right and text on left + case Qt::AlignRight: { + iconRect = QRectF(contentRect.right() - iconWidth, contentRect.center().y() - (iconHeight / 2), iconWidth, iconHeight); + textRect.setWidth(contentRect.width() - iconWidth - hTextMargin); + break; + } + + //icon on bottom and text on top + case Qt::AlignBottom: { + iconRect = QRectF(contentRect.center().x() - (iconWidth / 2), contentRect.bottom() - iconHeight, iconWidth, iconHeight); + textRect.setHeight(contentRect.height() - iconHeight - vTextMargin); + break; + } + + //icon on top and text on bottom + default: { + iconRect = QRectF(contentRect.center().x() - (iconWidth / 2), contentRect.top(), iconWidth, iconHeight); + textRect.setY(iconRect.bottom() + q->style()->textMarginTop()); + textRect.setHeight(contentRect.height() - iconHeight - vTextMargin); + break; + } + } + } + // no text + else { + //icon on center + iconRect = QRectF(contentRect.center().x() - (iconWidth / 2), contentRect.center().y() - (iconHeight / 2), iconWidth, iconHeight); + } + } + + //adjust label with button margins + label->setGeometry(textRect.translated(q->marginLeft(), q->marginTop())); +} + +void DuiButtonViewPrivate::loadIcon(const QPixmap*& icon, const QString &newIconId, const QSize &newIconSize) +{ + DuiTheme::releasePixmap(icon); + icon = 0; + if (!newIconId.isEmpty()) + icon = DuiTheme::pixmap(newIconId, newIconSize); +} + + +DuiButtonView::DuiButtonView(DuiButton *controller) : + DuiWidgetView(* new DuiButtonViewPrivate, controller) +{ + Q_D(DuiButtonView); + d->label = new DuiLabel(controller); + d->label->setParentItem(controller); + d->label->setTextElide(true); + d->label->setObjectName("ButtonLabel"); +} + +DuiButtonView::DuiButtonView(DuiButtonViewPrivate &dd, DuiButton *controller) : + DuiWidgetView(dd, controller) +{ + Q_D(DuiButtonView); + d->label = new DuiLabel(controller); + d->label->setParentItem(controller); + d->label->setTextElide(true); + d->label->setObjectName("ButtonLabel"); +} + +DuiButtonView::~DuiButtonView() +{ + Q_D(DuiButtonView); + if (d->label) { + delete d->label; + d->label = 0; + } +} + +void DuiButtonView::resizeEvent(QGraphicsSceneResizeEvent *event) +{ + Q_D(DuiButtonView); + + DuiWidgetView::resizeEvent(event); + + d->calcIconTextRects(); +} + +void DuiButtonView::drawContents(QPainter *painter, const QStyleOptionGraphicsItem *option) const +{ + Q_UNUSED(option); + + Q_D(const DuiButtonView); + duiTimestamp("DuiButtonView", QString("start text=%1").arg(model()->text())); + drawIcon(painter, d->iconRect); + duiTimestamp("DuiButtonView", QString("end text=%1").arg(model()->text())); +} + +void DuiButtonView::drawIcon(QPainter *painter, const QRectF &iconRect) const +{ + if (model()->iconVisible()) { + Q_D(const DuiButtonView); + + bool toggleState = d->toggleState(); + + const QPixmap *pixmap = NULL; + if (toggleState && d->toggledIcon) + pixmap = d->toggledIcon; + else + pixmap = d->icon; + + if (pixmap) + painter->drawPixmap(iconRect, *pixmap, QRectF(pixmap->rect())); + } +} + +/*DuiLabel* DuiButtonView::label() +{ + Q_D(const DuiButtonView); + return d->label; +}*/ + +void DuiButtonView::applyStyle() +{ + Q_D(DuiButtonView); + + DuiWidgetView::applyStyle(); + + d->refreshStyleMode(); + + update(); +} + +void DuiButtonView::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + Q_UNUSED(event); + + if (model()->down()) { + return; + } + model()->setDown(true); + + style()->pressFeedback().play(); +} + +void DuiButtonView::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + Q_D(DuiButtonView); + + Q_UNUSED(event); + + if (!model()->down()) { + return; + } + model()->setDown(false); + + style()->releaseFeedback().play(); + + QPointF touch = event->scenePos(); + QRectF rect = d->controller->sceneBoundingRect(); + rect.adjust(-RELEASE_MISS_DELTA, -RELEASE_MISS_DELTA, + RELEASE_MISS_DELTA, RELEASE_MISS_DELTA); + if (rect.contains(touch)) + model()->click(); +} + +void DuiButtonView::cancelEvent(DuiCancelEvent *event) +{ + Q_UNUSED(event); + + if (!model()->down()) { + return; + } + model()->setDown(false); +} + +void DuiButtonView::updateData(const QList& modifications) +{ + Q_D(DuiButtonView); + + DuiWidgetView::updateData(modifications); + const char *member; + foreach(member, modifications) { + if (member == DuiButtonModel::Text) { + d->label->setText(model()->text()); + d->calcIconTextRects(); + } else if (member == DuiButtonModel::TextVisible) { + d->label->setVisible(model()->textVisible()); + d->calcIconTextRects(); + } else if (member == DuiButtonModel::IconID) { + d->loadIcon(d->icon, model()->iconID(), style()->iconSize()); + d->calcIconTextRects(); + } else if (member == DuiButtonModel::ToggledIconID) { + d->loadIcon(d->toggledIcon, model()->toggledIconID(), style()->iconSize()); + d->calcIconTextRects(); + } else if (member == DuiButtonModel::IconVisible) { + d->calcIconTextRects(); + } else if (member == DuiButtonModel::Down || member == DuiButtonModel::Checked || + member == DuiButtonModel::Checkable) { + d->refreshStyleMode(); + } + } + update(); +} + +void DuiButtonView::setupModel() +{ + Q_D(DuiButtonView); + + DuiWidgetView::setupModel(); + + d->loadIcon(d->icon, model()->iconID(), style()->iconSize()); + d->loadIcon(d->toggledIcon, model()->toggledIconID(), style()->iconSize()); + d->calcIconTextRects(); + + d->label->setText(model()->text()); + d->label->setVisible(model()->textVisible()); + + update(); +} + +QSizeF DuiButtonView::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const +{ + Q_D(const DuiButtonView); + + if (which == Qt::MinimumSize || which == Qt::MaximumSize) + return DuiWidgetView::sizeHint(which, constraint); + + if (style()->preferredSize().isValid()) + return style()->preferredSize(); + + + QSizeF iconSize(0, 0); + if (model()->iconVisible() && d->icon) + iconSize = d->icon->size(); + + QSizeF textSize(0, 0); + if (model()->textVisible() && !model()->text().isEmpty()) { + QFontMetricsF fm(style()->font()); + textSize = fm.size(0, model()->text()); + textSize += QSizeF(style()->textMarginLeft() + style()->textMarginRight(), style()->textMarginTop() + style()->textMarginBottom()); + } + + qreal width = 0, height = 0; + if (style()->iconAlign() == Qt::AlignTop || style()->iconAlign() == Qt::AlignBottom) { + width = qMax(iconSize.width(), textSize.width()); + height = iconSize.height() + textSize.height(); + } else { + width = iconSize.width() + textSize.width(); + height = qMax(iconSize.height(), textSize.height()); + } + + return QSizeF(width + style()->paddingLeft() + style()->paddingRight(), height + style()->paddingTop() + style()->paddingBottom()); +} + +DUI_REGISTER_VIEW_NEW(DuiButtonView, DuiButton) diff --git a/src/widgets/views/duibuttonview.h b/src/widgets/views/duibuttonview.h new file mode 100644 index 000000000..25acc1635 --- /dev/null +++ b/src/widgets/views/duibuttonview.h @@ -0,0 +1,164 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIBUTTONVIEW_H +#define DUIBUTTONVIEW_H + +#include +#include +#include + +class DuiButtonViewPrivate; +class DuiButtonViewTest; +class DuiButton; + +class QGraphicsSceneResizeEvent; + +/*! + \class DuiButtonView + \brief View class for standard push buttons. + + \ingroup views + + \section DuiButtonViewOverview Overview + + + + + + +
\image html push_button.png \image html push_button_down.png
+ + DuiButtonView is used to visualize push buttons and toggle + buttons. The view draws a fixed background and an icon, text or both + on top of it. If the view is for a checkable button, it uses a different + background and different text color for the checked state. + + The outlook of button can be changed using the styling attributes defined + in DuiButtonStyle and DuiWidgetStyle. DuiWidgetStyle::backgroundImage, + DuiWidgetStyle::backgroundColor and DuiWidgetStyle::backgroundOpacity + can be used to change appearance of the button itself. If background image + is not defined then the background is drawn with solid color. The icon + and text position and outlook can be changed through DuiButtonStyle. + Following rules apply: + + - Only text is visible. + - Text can be freely positioned using DuiButtonStyle::verticalTextAlign, + DuiButtonStyle::horizontalTextAlign, DuiButtonStyle::textMarginLeft, + DuiButtonStyle::textMarginRight, DuiButtonStyle::textMarginTop and + DuiButtonStyle::textMarginBottom attributes. + - Only icon is visible. + - Icon can be freely positioned using DuiButtonStyle::iconSize and + DuiButtonStyle::iconAlign attributes. + - Text and icon are both visible. + - Space taken by the icon is calculated first and then the rest of + available space is used for the text. The space taken by the text + is adjustable with text margin attributes. + - If icon is aligned to left, then the text goes to right or if icon is + aligned to top then the text goes automatically below that. + + A button can be in one of the following functional states: + - Enabled: default state. Button can be tapped to perform an action. + - Disabled: tapping the button doesn't perform any action. + - Disabled state is not indicated in any specific way, button is + shown normally (i.e. no dimming etc.) + + \section DuiButtonViewInteractions Interactions + The Push Button does not support long press functionality, so it makes + no difference how long the button is held down. If user presses a button + and drags while it is in a pannable area, then button follows the finger + and tactile feedback is cancel. When releasing the finger after panning, + the button interaction is not activated. + + - Press down: Highlights the button. + - Tap (button down + button up): Performs an action defined + by application. + - Tap down and drag finger out of the button and release finger: + Cancels the button press. + - Tap down and drag finger to scroll UI: Cancels the button + press. + + \section DuiButtonViewOpenIssues Open issues + - There should be a informative banner telling why the button is disabled, + unless the reason is very self evident. + - The Button labels should follow the truncation rules of the Label widget. + + \sa DuiButton DuiButtonView DuiButtonStyle +*/ + +class DUI_EXPORT DuiButtonView : public DuiWidgetView +{ + Q_OBJECT + DUI_VIEW(DuiButtonModel, DuiButtonStyle) + +public: + + /*! + \brief Constructs the view. + \param Pointer to the controller. + */ + DuiButtonView(DuiButton *controller); + + /*! + \brief Destructs the view. + */ + virtual ~DuiButtonView(); + + //! \reimp + virtual void resizeEvent(QGraphicsSceneResizeEvent *event); + //! \reimp_end + +protected: + + //! \reimp + virtual void drawContents(QPainter *painter, const QStyleOptionGraphicsItem *option) const; + virtual void applyStyle(); + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + virtual void setupModel(); + virtual void cancelEvent(DuiCancelEvent *event); + virtual QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const; + //! \reimp_end + + /*! + \brief Draws the button icon (toggled or normal depending on the state + of the button) into the given \a iconRect. + */ + virtual void drawIcon(QPainter *painter, const QRectF &iconRect) const; + + //! \cond + DuiButtonView(DuiButtonViewPrivate &dd, DuiButton *controller); + //! \endcond + +protected Q_SLOTS: + //! \reimp + virtual void updateData(const QList& modifications); + //! \reimp_end + +private: + Q_DISABLE_COPY(DuiButtonView) + Q_DECLARE_PRIVATE(DuiButtonView) + +#ifdef UNIT_TEST + friend class Ut_DuiButtonView; +#endif + +}; + +#endif diff --git a/src/widgets/views/duibuttonview_p.h b/src/widgets/views/duibuttonview_p.h new file mode 100644 index 000000000..05e609983 --- /dev/null +++ b/src/widgets/views/duibuttonview_p.h @@ -0,0 +1,51 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIBUTTONVIEW_P_H +#define DUIBUTTONVIEW_P_H + +#include "private/duiwidgetview_p.h" + +class QPixmap; +class DuiScalableImage; +class DuiLabel; + +class DuiButtonViewPrivate : public DuiWidgetViewPrivate +{ + Q_DECLARE_PUBLIC(DuiButtonView) + +public: + DuiButtonViewPrivate(); + virtual ~DuiButtonViewPrivate(); + + const QPixmap *icon; + const QPixmap *toggledIcon; + + DuiLabel *label; + + QRectF iconRect; + + void calcIconTextRects(); + bool toggleState() const; + void refreshStyleMode(); + + void loadIcon(const QPixmap*& icon, const QString &newIconId, const QSize &newIconSize); +}; + +#endif diff --git a/src/widgets/views/duicheckboxview.cpp b/src/widgets/views/duicheckboxview.cpp new file mode 100644 index 000000000..86daafdd4 --- /dev/null +++ b/src/widgets/views/duicheckboxview.cpp @@ -0,0 +1,57 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duicheckboxview.h" +#include "duicheckboxview_p.h" + +#include "duiscalableimage.h" + +#include + +#include "duidebug.h" + +DuiCheckboxViewPrivate::DuiCheckboxViewPrivate() + : DuiButtonViewPrivate() +{ +} + +DuiCheckboxViewPrivate::~DuiCheckboxViewPrivate() +{ +} + +DuiCheckboxView::DuiCheckboxView(DuiButton *controller) : + DuiButtonView(* new DuiCheckboxViewPrivate, controller) +{ +} + +DuiCheckboxView::~DuiCheckboxView() +{ +} + +void DuiCheckboxView::drawContents(QPainter *painter, const QStyleOptionGraphicsItem *option) const +{ + Q_UNUSED(option); + + if (style()->checkmarkImage() && model()->checked()) { + QSizeF pos = (size() / 2) - (style()->checkmarkImage()->size() / 2); + painter->drawPixmap(pos.width(), pos.height(), *style()->checkmarkImage()); + } +} + +DUI_REGISTER_VIEW_NEW(DuiCheckboxView, DuiButton) diff --git a/src/widgets/views/duicheckboxview.h b/src/widgets/views/duicheckboxview.h new file mode 100644 index 000000000..767629f82 --- /dev/null +++ b/src/widgets/views/duicheckboxview.h @@ -0,0 +1,99 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUICHECKBOXVIEW_H +#define DUICHECKBOXVIEW_H + +#include +#include +#include + +class DuiCheckboxViewPrivate; + +/*! + \class DuiCheckboxView + \brief View class for a checkbox button. + + \ingroup views + + \section DuiCheckboxViewOverview Overview + + + + + + + +
\image html checkbox_off.png \image html checkbox_on.png \image html checkbox_on_down.png
+ + Checkbox is a variant of button that allows users to set a state of a + variable or setting which has two values, On and Off. Checkbox essentially + does the same thing as the Switch variant. + + \section DuiCheckboxViewInteractions Interactions + Users can change the state of checkbox by tapping on it (or the accompanying + text label). If the state of the checkbox is On, it is changed to Off. + If the state of the checkbox is On, it is changed to Off. If the checkbox + is disabled the tapping has not effect. + + - Press down: Highlights the checkbox. + - Tap (button down + button up): Toggles the state of + the checkbox. + - Tap down and drag finger out of the checkbox and release finger: + Cancels the press and does not change the state. + - Tap down and drag finger to scroll UI: Cancels the press + and does not change the state. + + \section DuiCheckboxViewOpenIssues Open issues + - Checkbox should include a text label describing the setting or variable + in question. This label has the same interactions as the Checkbox button itself. + + \sa DuiButton DuiButtonView DuiCheckboxStyle +*/ +class DUI_EXPORT DuiCheckboxView : public DuiButtonView +{ + Q_OBJECT + DUI_VIEW(DuiButtonModel, DuiCheckboxStyle) + +public: + + /*! + \brief Constructs the view. + \param Pointer to the controller. + */ + DuiCheckboxView(DuiButton *controller); + + /*! + \brief Destructs the view. + */ + virtual ~DuiCheckboxView(); + +protected: + + //! \reimp + virtual void drawContents(QPainter *painter, const QStyleOptionGraphicsItem *option) const; + //! \reimp_end + +private: + + Q_DISABLE_COPY(DuiCheckboxView) + Q_DECLARE_PRIVATE(DuiCheckboxView) +}; + +#endif diff --git a/src/widgets/views/duicheckboxview_p.h b/src/widgets/views/duicheckboxview_p.h new file mode 100644 index 000000000..f2272b3e3 --- /dev/null +++ b/src/widgets/views/duicheckboxview_p.h @@ -0,0 +1,34 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUICHECKBOXVIEW_P_H +#define DUICHECKBOXVIEW_P_H + +#include "duibuttonview_p.h" + +class DuiCheckboxViewPrivate : public DuiButtonViewPrivate +{ + Q_DECLARE_PUBLIC(DuiCheckboxView) + +public: + DuiCheckboxViewPrivate(); + ~DuiCheckboxViewPrivate(); +}; + +#endif diff --git a/src/widgets/views/duicomboboxview.cpp b/src/widgets/views/duicomboboxview.cpp new file mode 100644 index 000000000..2ee9726dd --- /dev/null +++ b/src/widgets/views/duicomboboxview.cpp @@ -0,0 +1,224 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duicomboboxview.h" +#include "duicomboboxview_p.h" +#include "duicombobox.h" + +#include "duitheme.h" +#include "duiimagewidget.h" +#include "duilabel.h" +#include "duiscalableimage.h" +#include "duiviewcreator.h" +#include "duipopuplist.h" +#include "duiapplicationwindow.h" +#include "duiscenemanager.h" +#include "duilocale.h" + +#include +#include + +DuiComboBoxViewPrivate::DuiComboBoxViewPrivate() + : controller(0), layout(0), title(0), subtitle(0), icon(0), popuplist(0) +{ +} + +DuiComboBoxViewPrivate::~DuiComboBoxViewPrivate() +{ + if (popuplist != 0) + delete popuplist; +} + +void DuiComboBoxViewPrivate::init() +{ + Q_Q(DuiComboBoxView); + + layout = new QGraphicsGridLayout(); + layout->setContentsMargins(0, 0, 0, 0); + layout->setSpacing(0); + controller->setLayout(layout); + + icon = new DuiImageWidget(); + icon->setObjectName("DuiComboBoxIcon"); + + title = new DuiLabel(); + title->setObjectName("DuiComboBoxTitle"); + + subtitle = new DuiLabel(); + subtitle->setObjectName("DuiComboBoxSubtitle"); + _q_itemModelCurrentIndexChanged(-1); + + QObject::connect(controller, SIGNAL(currentIndexChanged(int)), q, SLOT(_q_itemModelCurrentIndexChanged(int))); + QObject::connect(controller, SIGNAL(clicked()), q, SLOT(_q_showPopup())); +} + +void DuiComboBoxViewPrivate::initLayout() +{ + int count = layout->count(); + for (int i = count - 1; i >= 0; --i) + layout->removeAt(i); + + if (controller->isIconVisible() && !icon->image().isEmpty()) { + icon->show(); + layout->addItem(icon, 0, 0, 2, 1); + layout->addItem(title, 0, 1); + layout->addItem(subtitle, 1, 1); + } else { + icon->hide(); + layout->addItem(title, 0, 0); + layout->addItem(subtitle, 1, 0); + } +} + +void DuiComboBoxViewPrivate::_q_itemModelCurrentIndexChanged(int currentIndex) +{ + if (currentIndex != -1) { + subtitle->setText(controller->itemText(currentIndex)); + } else { + //~ uispec-document DirectUI_Common_Strings_UI_Specification_0.7.doc + //: default value for Popup List button sublabel when nothing has been selected yet + //% "Tap to Select" + subtitle->setText(qtTrId("xx_ComboBoxSubtitle")); + } +} + +void DuiComboBoxViewPrivate::_q_showPopup() +{ + if (controller->count() == 0) return; + + if (controller->sceneManager()) { + if (!popuplist) { + popuplist = new DuiPopupList(); + } + + popuplist->setItemModel(controller->itemModel()); + popuplist->setSelectionModel(controller->selectionModel()); + popuplist->setTitle(controller->title()); + controller->sceneManager()->showWindow(popuplist); + } +} + +DuiComboBoxView::DuiComboBoxView(DuiComboBox *controller) : + DuiWidgetView(* new DuiComboBoxViewPrivate, controller) +{ + Q_D(DuiComboBoxView); + d->controller = controller; + d->init(); + +} + +DuiComboBoxView::DuiComboBoxView(DuiComboBoxViewPrivate &dd, DuiComboBox *controller) : + DuiWidgetView(dd, controller) +{ + Q_D(DuiComboBoxView); + d->controller = controller; + d->init(); +} + +DuiComboBoxView::~DuiComboBoxView() +{ +} + +void DuiComboBoxView::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + Q_UNUSED(event); + Q_D(DuiComboBoxView); + + if (d->controller->isDown()) + return; + + d->controller->setDown(true); +} + +void DuiComboBoxView::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + Q_D(DuiComboBoxView); + + if (!d->controller->isDown()) + return; + + d->controller->setDown(false); + + QPointF touch = event->scenePos(); + QRectF rect = d->controller->sceneBoundingRect(); + if (rect.contains(touch)) { + d->controller->click(); + } +} + +void DuiComboBoxView::cancelEvent(DuiCancelEvent *event) +{ + Q_D(DuiComboBoxView); + Q_UNUSED(event); + + if (!d->controller->isDown()) + return; + + d->controller->setDown(false); + + update(); +} + +void DuiComboBoxView::updateData(const QList& modifications) +{ + Q_D(DuiComboBoxView); + + DuiWidgetView::updateData(modifications); + + const char *member; + const int count = modifications.count(); + for (int i = 0; i < count; ++i) { + member = modifications[i]; + + if (member == DuiComboBoxModel::IconID) { + d->icon->setImage(model()->iconID()); + d->initLayout(); + } else if (member == DuiComboBoxModel::Title) { + QString text = model()->title(); + d->title->setText(text); + if (d->popuplist) + d->popuplist->setTitle(text); + } else if (member == DuiComboBoxModel::IconVisible) { + d->initLayout(); + } else if (member == DuiComboBoxModel::Down) { + if (model()->down()) + style().setModePressed(); + else + style().setModeDefault(); + update(); + } + } +} + +void DuiComboBoxView::setupModel() +{ + Q_D(DuiComboBoxView); + DuiWidgetView::setupModel(); + + d->initLayout(); + + d->icon->setImage(model()->iconID()); + d->title->setText(model()->title()); + if (!d->controller->currentText().isEmpty()) + d->subtitle->setText(d->controller->currentText()); +} + +DUI_REGISTER_VIEW_NEW(DuiComboBoxView, DuiComboBox) + +#include "moc_duicomboboxview.cpp" diff --git a/src/widgets/views/duicomboboxview.h b/src/widgets/views/duicomboboxview.h new file mode 100644 index 000000000..d60c33d4b --- /dev/null +++ b/src/widgets/views/duicomboboxview.h @@ -0,0 +1,87 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUICOMBOBOXVIEW_H +#define DUICOMBOBOXVIEW_H + +#include "duiwidgetview.h" +#include "duicomboboxmodel.h" +#include "duicomboboxstyle.h" + +class DuiComboBox; +class DuiComboBoxViewPrivate; + +/*! + \class DuiComboBoxView + \brief View class for DuiComboBox. + + \ingroup views + + DuiComboBoxView is used to visualize comboBox. + + \sa DuiComboBox DuiComboBoxStyle + */ + +class DUI_EXPORT DuiComboBoxView : public DuiWidgetView +{ + Q_OBJECT + DUI_VIEW(DuiComboBoxModel, DuiComboBoxStyle) + +public: + /*! + \brief Constructor + \param controller Pointer to the controller + */ + DuiComboBoxView(DuiComboBox *controller); + + /*! + \brief Destructor + */ + virtual ~DuiComboBoxView(); + +protected slots: + //! \reimp + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + virtual void cancelEvent(DuiCancelEvent *event); + virtual void updateData(const QList& modifications); + //! \reimp_end + +protected: + //! \reimp + virtual void setupModel(); + //! \reimp_end + + //! \internal + DuiComboBoxView(DuiComboBoxViewPrivate &dd, DuiComboBox *controller); + //! \internal_end + +private: + Q_DISABLE_COPY(DuiComboBoxView) + Q_DECLARE_PRIVATE(DuiComboBoxView) + + Q_PRIVATE_SLOT(d_func(), void _q_itemModelCurrentIndexChanged(int)) + Q_PRIVATE_SLOT(d_func(), void _q_showPopup()) + +#ifdef UNIT_TEST + friend class Ut_DuiComboBox; +#endif +}; + +#endif diff --git a/src/widgets/views/duicomboboxview_p.h b/src/widgets/views/duicomboboxview_p.h new file mode 100644 index 000000000..e0ec8bb24 --- /dev/null +++ b/src/widgets/views/duicomboboxview_p.h @@ -0,0 +1,53 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUICOMBOBOXVIEW_P_H +#define DUICOMBOBOXVIEW_P_H + +#include "private/duiwidgetview_p.h" +#include + +class QGraphicsGridLayout; +class DuiComboBox; +class DuiImageWidget; +class DuiLabel; +class DuiPopupList; + +class DuiComboBoxViewPrivate : public DuiWidgetViewPrivate +{ + Q_DECLARE_PUBLIC(DuiComboBoxView) + +public: + DuiComboBoxViewPrivate(); + virtual ~DuiComboBoxViewPrivate(); + + void init(); + void initLayout(); + void _q_showPopup(); + void _q_itemModelCurrentIndexChanged(int currentIndex); + + DuiComboBox *controller; + QGraphicsGridLayout *layout; + DuiLabel *title; + DuiLabel *subtitle; + DuiImageWidget *icon; + DuiPopupList *popuplist; +}; + +#endif diff --git a/src/widgets/views/duicompleterview.cpp b/src/widgets/views/duicompleterview.cpp new file mode 100644 index 000000000..fa0684962 --- /dev/null +++ b/src/widgets/views/duicompleterview.cpp @@ -0,0 +1,344 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duicompleter.h" +#include "duicompleterview.h" +#include "duicompleterview_p.h" + +#include "duitextedit.h" +#include "duioverlay.h" +#include "duilabel.h" +#include "duibutton.h" +#include "duipopuplist.h" +#include "duiapplication.h" +#include "duiapplicationwindow.h" +#include "duiscenemanager.h" + +#include +#include +#include + +namespace +{ + //! default height for completer + const int DefaultCompleterHeight = 60; + //!default object names + const QString CompleterCandidatesLabelObjectName("DuiCompleterCandidatesLabel"); + const QString CompleterTotalButtonObjectName("DuiCompleterTotalButton"); + //! default maximum hits is 10 + const int DefaultMaximumHits = 10; +} + +DuiCompleterViewPrivate::DuiCompleterViewPrivate(DuiCompleter *controller, DuiCompleterView *q) + : controller(controller), + q_ptr(q), + completionLabel(0), + completionsButton(0), + layout(0), + popup(0), + overLaypreferredSize(QSizeF(0, 0)) +{ + completionLabel = new DuiLabel(controller); + completionLabel->setObjectName(CompleterCandidatesLabelObjectName); + completionLabel->setTextElide(true); + completionLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + completionsButton = new DuiButton(controller); + completionsButton->setObjectName(CompleterTotalButtonObjectName); + + layout = new QGraphicsLinearLayout(Qt::Horizontal, controller); + layout->setContentsMargins(0, 0, 0, 0); + layout->setSpacing(0); + layout->addItem(completionLabel); + layout->setAlignment(completionLabel, Qt::AlignCenter); + layout->addItem(completionsButton); + layout->setAlignment(completionsButton, Qt::AlignCenter); + + controller->setLayout(layout); + + //click focus, and eat focusout for the textedit widget + completionLabel->setFocusPolicy(Qt::ClickFocus); + controller->setFocusPolicy(Qt::ClickFocus); + controller->setManagedManually(true); +} + +DuiCompleterViewPrivate::~DuiCompleterViewPrivate() +{ + delete completionLabel; + completionLabel = 0; + delete completionsButton; + completionsButton = 0; + + delete popup; + popup = 0; +} + + +void DuiCompleterViewPrivate::init() +{ + connect(completionsButton, SIGNAL(clicked()), this, SLOT(showPopup())); + //TODO: only connect the signal DuiSceneManager::orientationChanged(), + //which is still not correctly emitted by DuiSceneManager at the right time + connect(controller->widget(), SIGNAL(rotationChanged()), + this, SLOT(organizeContents())); + connect(controller, SIGNAL(shown()), this, SLOT(createContents())); + connect(controller, SIGNAL(hidden()), this, SLOT(clear())); +} + +void DuiCompleterViewPrivate::organizeContents() +{ + Q_Q(DuiCompleterView); + + if (!controller->widget() || !controller->isActive()) + return; + QSize screenSize = DuiApplication::activeWindow()->visibleSceneSize(); + int textWidgetWidth = 0; + + //duicompleter has by default the same width than the according Text-field that it is attached to. + //default position is aligning left bottom with text widget + const QRect textWidgetRect = controller->widget()->mapToScene( + controller->widget()->boundingRect()).boundingRect().toRect(); + textWidgetWidth = textWidgetRect.width(); + + int width = 0; + int height = DefaultCompleterHeight; + + if (q->style()->height() > 0) + height = q->style()->height(); + + int textWidth = 0; + //using the font information from the label to caculate the width (of the plain label text) + //TODO: use the DuiLabel::preferredSize() instead of calculate by ourselves. + textWidth = QFontMetrics(completionLabel->font()).width( + QTextDocumentFragment::fromHtml(completionLabel->text()).toPlainText()); + + const int labelMargin = q->style()->labelMargin(); + const int buttonWidth = q->style()->buttonWidth(); + const int displayBorder = q->style()->displayBorder(); + + width = textWidth + 2 * labelMargin; + bool buttonVisible = (!completionsButton->text().isEmpty()) && completionsButton->isVisible(); + if (buttonVisible) { + const int buttonMargin = q->style()->buttonMargin(); + width += buttonWidth + buttonMargin; + } + // Input suggestions that do not fit into the available space force the completer to grow. + // First the completer grows to the right until it reaches the displayBorder. + // If then continues growing to the left until it reaches the left displayBorder. + // This means that the maximum size of the completer is the width of the display minus 2*displayBorder + if (width < textWidgetWidth) + width = textWidgetWidth; + if (width > (screenSize.width() - 2 * displayBorder)) { + width = screenSize.width() - 2 * displayBorder; + } + overLaypreferredSize = QSizeF(width, height); + + QPoint completerPos = locatePosition(textWidgetRect); + if ((completerPos.x() + width) > (screenSize.width() - displayBorder)) { + completerPos.setX(screenSize.width() - displayBorder - width); + } + //add y position offset + const int yPositionOffset = q->style()->yPositionOffset(); + if (yPositionOffset > 0) { + completerPos.setY(completerPos.y() - yPositionOffset); + } + + //adjust position, to avoid the completer to be beyond the screen edge + //completer's position is fixed, aligning left bottom with text widget + //judge completion should stay at text widget below or upper + if (height > (screenSize.height() - completerPos.y())) { + completerPos.setY(completerPos.y() - controller->widget()->boundingRect().height() + - height + yPositionOffset); + } + if (completerPos != controller->pos()) + controller->setPos(completerPos); + q->updateGeometry(); +} + +QPoint DuiCompleterViewPrivate::locatePosition(const QRect &r) const +{ + QSize screenSize = DuiApplication::activeWindow()->visibleSceneSize(); + QPoint p; + switch (DuiApplication::activeWindow()->orientationAngle()) { + case Dui:: Angle90: + p = r.topLeft(); + p = QPoint(p.y(), (screenSize.height() - p.x())); + break; + case Dui:: Angle180: + p = r.topRight(); + p = QPoint((screenSize.width() - p.x()), (screenSize.height() - p.y())); + break; + case Dui:: Angle270: + p = r.bottomRight(); + p = QPoint((screenSize.width() - p.y()), p.x()); + break; + case Dui:: Angle0: + default: + p = r.bottomLeft(); + break; + } + return p; +} + +void DuiCompleterViewPrivate::createContents() +{ + Q_Q(DuiCompleterView); + + if (controller->widget() && q->model()->matchedModel()) { + //add controller to scence when first time to show, it is neccessary for later setFocusProxy + if (!controller->widget()->scene()->items().contains(controller)) + controller->widget()->scene()->addItem(controller); + QString text; + if (q->model()->matchedModel()->rowCount() > q->model()->matchedIndex()) { + QVariant var = q->model()->matchedModel()->data( + q->model()->matchedModel()->index(q->model()->matchedIndex(), 0)); + if (var.isValid()) + text += var.toString(); + } + if (text.isEmpty()) + return; + + //highlight the completionPrefix + QString prefix = q->model()->completionPrefix(); + text = text.replace('<', "<"); + text = text.replace('>', ">"); + prefix = prefix.replace('<', "<"); + prefix = prefix.replace('>', ">"); + QRegExp exp(QString("^%1").arg(prefix), Qt::CaseInsensitive); + int index = exp.indexIn(text); + if (index == -1) { + exp.setPattern(QString("\\W%1").arg(prefix)); + index = exp.indexIn(text) + 1; + } + + QString highlightColor = q->style()->highlightColor().name(); + QString replacedString = text.mid(index, prefix.length()); + text = text.replace(index, replacedString.length(), + QString("" + replacedString + "").arg(highlightColor)); + completionLabel->setText(text); + + //set button's visibility and label + int total = q->model()->matchedModel()->rowCount(); + if (total > 1) { + if (total <= DefaultMaximumHits) + completionsButton->setText(QString("%1").arg(total)); + else + completionsButton->setText(QString(">%1").arg(DefaultMaximumHits)); + completionsButton->setFocusProxy(controller->widget()); + completionsButton->setVisible(true); + layout->addItem(completionsButton); + layout->setAlignment(completionsButton, Qt::AlignCenter); + } else { + completionsButton->setText(""); + completionsButton->setFocusProxy(0); + completionsButton->setVisible(false); + layout->removeItem(completionsButton); + } + + completionLabel->setFocusProxy(controller->widget()); + controller->setFocusProxy(controller->widget()); + + //set the focus back to textwidget + //even we already set focus proxy for controller, this step is still necessary, + //otherwise the textwidget can not get focus. + controller->scene()->setFocusItem(controller->widget()); + organizeContents(); + } +} + +void DuiCompleterViewPrivate::clear() +{ + overLaypreferredSize = QSize(0, 0); + //clear focus proxy + completionLabel->setFocusProxy(0); + completionsButton->setFocusProxy(0); + controller->setFocusProxy(0); +} + + +void DuiCompleterViewPrivate::showPopup() +{ + Q_Q(DuiCompleterView); + if (!q->model()->matchedModel() || q->model()->matchedModel()->rowCount() <= 0) + return; + + if (!popup) { + popup = new DuiPopupList(); + popup->setItemModel(q->model()->matchedModel()); + } + + if (popup->currentIndex().row() < 0) + popup->setCurrentIndex(popup->itemModel()->index(0, 0)); + + //if the label of the button is ">10", should query all before showing popup + if (completionsButton->text() == QString(">%1").arg(DefaultMaximumHits)) + controller->queryAll(); + //hide completion widget before showing popup + controller->hideCompleter(); + q->model()->setPopupActive(true); + if (controller->sceneManager()->execDialog(popup) == DuiDialog::Accepted) { + //only confirm when accept + controller->scene()->setFocusItem(controller->widget()); + q->model()->setMatchedIndex(popup->currentIndex().row()); + controller->confirm(); + } else { + controller->scene()->setFocusItem(controller->widget()); + } + q->model()->setPopupActive(false); +} + + +DuiCompleterView::DuiCompleterView(DuiCompleter *controller) + : DuiSceneWindowView(controller), + d_ptr(new DuiCompleterViewPrivate(controller, this)) +{ + Q_D(DuiCompleterView); + d->init(); +} + + +DuiCompleterView::~DuiCompleterView() +{ + Q_D(DuiCompleterView); + delete d; +} + +void DuiCompleterView::applyStyle() +{ + Q_D(DuiCompleterView); + DuiSceneWindowView::applyStyle(); + d->organizeContents(); +} + +QSizeF DuiCompleterView::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const +{ + Q_UNUSED(which); + Q_UNUSED(constraint); + Q_D(const DuiCompleterView); + return d->overLaypreferredSize; +} + +void DuiCompleterView::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + Q_D(DuiCompleterView); + if (d->controller && d->controller->isVisible()) + d->controller->confirm(); + event->accept(); +} + +DUI_REGISTER_VIEW_NEW(DuiCompleterView, DuiCompleter) diff --git a/src/widgets/views/duicompleterview.h b/src/widgets/views/duicompleterview.h new file mode 100644 index 000000000..d79479a67 --- /dev/null +++ b/src/widgets/views/duicompleterview.h @@ -0,0 +1,57 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUICOMPLETERVIEW_H +#define DUICOMPLETERVIEW_H + +#include "duiscenewindowview.h" +#include "duicompletermodel.h" +#include "duicompleterstyle.h" + +class DuiCompleter; +class DuiCompleterViewPrivate; + +class DUI_EXPORT DuiCompleterView : public DuiSceneWindowView +{ + Q_OBJECT + DUI_VIEW(DuiCompleterModel, DuiCompleterStyle) + +public: + DuiCompleterView(DuiCompleter *controller); + virtual ~DuiCompleterView(); + + //! \reimp + virtual QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const; + //! \reimp_end + +protected: + //! \reimp + virtual void applyStyle(); + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + //! \reimp_end + +private: + DuiCompleterViewPrivate *const d_ptr; + + Q_DISABLE_COPY(DuiCompleterView) + Q_DECLARE_PRIVATE(DuiCompleterView) +}; + +#endif + diff --git a/src/widgets/views/duicompleterview_p.h b/src/widgets/views/duicompleterview_p.h new file mode 100644 index 000000000..3793c3d3c --- /dev/null +++ b/src/widgets/views/duicompleterview_p.h @@ -0,0 +1,71 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUICOMPLETERVIEW_P_H +#define DUICOMPLETERVIEW_P_H + +#include "duicompleter.h" +#include "duicompleterview.h" +#include "private/duiwidgetview_p.h" + +class DuiCompleter; +class DuiWidgetController; +class DuiLabel; +class DuiButton; +class DuiPopupList; +class QStringListModel; +class QGraphicsLinearLayout; + +//! \internal +class DuiCompleterViewPrivate : public QObject +{ + Q_OBJECT + Q_DECLARE_PUBLIC(DuiCompleterView) + +public: + DuiCompleterViewPrivate(DuiCompleter *controller, DuiCompleterView *q); + virtual ~DuiCompleterViewPrivate(); + +protected slots: + + void createContents(); + + void clear(); + + void showPopup(); + + void organizeContents(); + +protected: + void init(); + + QPoint locatePosition(const QRect &r) const; + + //! The DuiCompleter controller + DuiCompleter *controller; + DuiCompleterView *q_ptr; + + DuiLabel *completionLabel; + DuiButton *completionsButton; + QGraphicsLinearLayout *layout; + DuiPopupList *popup; + QSizeF overLaypreferredSize; +}; + +#endif diff --git a/src/widgets/views/duicontainerview.cpp b/src/widgets/views/duicontainerview.cpp new file mode 100644 index 000000000..bf68f3a0f --- /dev/null +++ b/src/widgets/views/duicontainerview.cpp @@ -0,0 +1,367 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "duicontainerview.h" +#include "duicontainerview_p.h" +#include "duicontainerheader_p.h" +#include "duicontainer.h" + +#include "duiscalableimage.h" +#include "duiviewcreator.h" +#include "duitheme.h" + +DuiContainerViewPrivate::DuiContainerViewPrivate() + : controller(0) + , mainLayout(new QGraphicsLinearLayout(Qt::Vertical)) + , headerLayout(0) + , header(0) + , icon(0) // created only if needed + , title(0) + , text(0) + , background(0) + , headerPressed(false) + , progressIndicator(0) +{ +} + +DuiContainerViewPrivate::~DuiContainerViewPrivate() +{ + // Remove the old central widget but don't destroy since the controller does it + mainLayout->removeAt(mainLayout->count() - 1); +} + +void DuiContainerViewPrivate::init() +{ + controller->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred)); + + // pack + mainLayout->setContentsMargins(0, 0, 0, 0); + mainLayout->setSpacing(0); + + mainLayout->addItem(controller->centralWidget()); + + controller->setLayout(mainLayout); +} + +/* + * creates the header by adding a header widget, a layout and + * labels + */ + +void DuiContainerViewPrivate::createHeader() +{ + if (!header) { + header = new DuiContainerHeader(); + + headerLayout = new QGraphicsLinearLayout(Qt::Horizontal); + headerLayout->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum)); + headerLayout->setContentsMargins(0, 0, 0, 0); + header->setLayout(headerLayout); + + title = new DuiLabel(); + text = new DuiLabel(); + + title->setObjectName("DuiContainerTitle"); + text->setAlignment(Qt::AlignVCenter | Qt::AlignRight); + + headerLayout->addItem(title); + headerLayout->setAlignment(title, Qt::AlignVCenter | Qt::AlignLeft); + title->show(); + + headerLayout->addItem(text); + headerLayout->setAlignment(text, Qt::AlignVCenter | Qt::AlignRight); + text->show(); + + // insert icon if available + if (icon) { + headerLayout->insertItem(0, icon); + headerLayout->setAlignment(icon, Qt::AlignVCenter | Qt::AlignLeft); + icon->show(); + } + + mainLayout->insertItem(0, header); + } +} + +/* + * delete header, mainLayout will now reuse the space previously + * demanded by the header + */ + +void DuiContainerViewPrivate::removeHeader() +{ + if (header) { + /* + delete header and its children, the header must be delted with + deleteLater() as this gets called from a slot. + */ + header->deleteLater(); + header = 0; + title = 0; + text = 0; + icon = 0; + progressIndicator = 0; + headerLayout = 0; + } +} + +/* + * create icon if it doesn't exist + */ + +void DuiContainerViewPrivate::setupIcon(const QSize &size) +{ + if (!icon) + icon = new DuiImageWidget; + + icon->setImage(controller->model()->icon(), size); + icon->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); + + // insert it if header is available + if (header) { + headerLayout->insertItem(0, icon); + headerLayout->setAlignment(icon, Qt::AlignVCenter | Qt::AlignLeft); + icon->show(); + } +} + +void DuiContainerViewPrivate::createProgressIndicator() +{ + if (!progressIndicator) + progressIndicator = new DuiProgressIndicator; + progressIndicator->setUnknownDuration(true); +} + + +void DuiContainerViewPrivate::layoutProgressIndicator() +{ + if (header) { + headerLayout->addItem(progressIndicator); + headerLayout->setAlignment(progressIndicator, Qt::AlignVCenter | Qt::AlignRight); + progressIndicator->show(); + } +} + +DuiContainerView::DuiContainerView(DuiContainer *controller) : + DuiWidgetView(*new DuiContainerViewPrivate, controller) +{ + Q_D(DuiContainerView); + d->controller = controller; + + // setup main infrastructure + d->init(); + + connect(this, SIGNAL(headerClicked()), controller, SIGNAL(headerClicked())); +} + +DuiContainerView::DuiContainerView(DuiContainerViewPrivate &dd, DuiContainer *controller) : + DuiWidgetView(dd, controller) +{ + Q_D(DuiContainerView); + d->controller = controller; + + d->init(); + + connect(this, SIGNAL(headerClicked()), controller, SIGNAL(headerClicked())); +} + +DuiContainerView::~DuiContainerView() +{ +} + +void DuiContainerView::drawBackground(QPainter *painter, const QStyleOptionGraphicsItem *option) const +{ + Q_UNUSED(option); + Q_D(const DuiContainerView); + + // draw the background + painter->setOpacity(0.9 * d->controller->effectiveOpacity()); + if (style()->backgroundImage()) { + const qreal headerHeight = d->header ? d->header->size().height() : 0; + style()->backgroundImage()->draw(0, headerHeight, size().width(), size().height() - headerHeight, painter); + } +} + +void DuiContainerView::applyStyle() +{ + Q_D(DuiContainerView); + + DuiWidgetView::applyStyle(); + + // get background from style + d->background = style()->backgroundImage(); +} + +void DuiContainerView::updateData(const QList& modifications) +{ + Q_D(DuiContainerView); + DuiWidgetView::updateData(modifications); + + const DuiContainerModel *model = DuiContainerView::model(); + + // make sure the header exists before icons or centralWidget are set + // or modified + if (model->headerVisible()) { + d->createHeader(); + + QObject::connect(d->header, SIGNAL(pressed()), this, SLOT(headerPressed())); + QObject::connect(d->header, SIGNAL(released()), this, SLOT(headerReleased())); + QObject::connect(d->header, SIGNAL(moved()), this, SLOT(headerMoved())); + QObject::connect(d->header, SIGNAL(canceled()), this, SLOT(headerCanceled())); + + // update labels + d->title->setText(model->title()); + d->text->setText(model->text()); + + // make sure the icon is present if headerVisible() changed at runtime + if (!model->icon().isEmpty()) + d->setupIcon(style()->iconSize()); + + // same for the progress indicator + if (model->progressIndicatorVisible()) { + d->createProgressIndicator(); + d->layoutProgressIndicator(); + } + + } else { + d->removeHeader(); + } + + const char *member; + foreach(member, modifications) { + if (member == DuiContainerModel::CentralWidget) { + // Remove the old central widget but don't destroy since the controller does it + d->mainLayout->removeAt(d->mainLayout->count() - 1); + // Add the new central widget + d->mainLayout->addItem(d->controller->centralWidget()); + + // icon value changed + } else if (member == DuiContainerModel::Icon) { + // set new icon + if (!model->icon().isEmpty()) { + d->setupIcon(style()->iconSize()); + } else { + d->headerLayout->removeItem(d->icon); + d->icon->hide(); + } + } else if (member == DuiContainerModel::ProgressIndicatorVisible) { + if (model->progressIndicatorVisible()) { + d->createProgressIndicator(); + d->layoutProgressIndicator(); + } else { + delete d->progressIndicator; + d->progressIndicator = 0; + } + } + } + + // update visuals + update(); +} + +void DuiContainerView::setupModel() +{ + Q_D(DuiContainerView); + DuiWidgetView::setupModel(); + + // initially creating the header if defined in the model + if (model()->headerVisible()) { + d->createHeader(); + + QObject::connect(d->header, SIGNAL(pressed()), this, SLOT(headerPressed())); + QObject::connect(d->header, SIGNAL(released()), this, SLOT(headerReleased())); + + d->title->setText(model()->title()); + d->text->setText(model()->text()); + + // create icon if it is set to be shown by the model + if (!model()->icon().isEmpty()) + d->setupIcon(style()->iconSize()); + + } + + int spacing = style()->internalItemSpacing(); + int margin = style()->internalMargins(); + + // In case of strange or missing values while reading css + if (spacing < 0 || spacing > 100) + spacing = 0; + if (margin < 0 || margin > 100) + margin = 0; + + d->mainLayout->setContentsMargins(margin, margin, margin, margin); + d->mainLayout->setSpacing(spacing); + + d->mainLayout->addItem(d->controller->centralWidget()); + + if (model()->progressIndicatorVisible()) { + d->createProgressIndicator(); + d->layoutProgressIndicator(); + } +} + +void DuiContainerView::headerMoved() +{ + Q_D(DuiContainerView); + + if (d->headerPressed) { + d->headerPressed = false; + update(); + } +} + +void DuiContainerView::headerCanceled() +{ + Q_D(DuiContainerView); + + if (d->headerPressed) { + d->headerPressed = false; + update(); + } +} + +void DuiContainerView::headerPressed() +{ + Q_D(DuiContainerView); + d->headerPressed = true; +} + +void DuiContainerView::headerReleased() +{ + Q_D(DuiContainerView); + + if (d->headerPressed) { + emit headerClicked(); + d->headerPressed = false; + update(); + } +} + +// bind view and controller together +DUI_REGISTER_VIEW_NEW(DuiContainerView, DuiContainer) diff --git a/src/widgets/views/duicontainerview.h b/src/widgets/views/duicontainerview.h new file mode 100644 index 000000000..0613d1a5f --- /dev/null +++ b/src/widgets/views/duicontainerview.h @@ -0,0 +1,96 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUICONTAINERVIEW_H +#define DUICONTAINERVIEW_H + +#include +#include +#include +#include + +class DuiContainerViewPrivate; +class DuiContainer; + +/*! + * \class DuiContainerView + * \brief DuiContainerView implements a view for the DuiContainer + * + * \section DuiContainerViewOverview Overview + * A Container has a minimum width of 18mm, it's maximum width is the width of + * the screen. By default, the user can set it to a value between these + * boundaries. The minimum height is the minimum height of the header which is + * 5.06mm. There is no maximum height of the container. + * + * \section DuiContainerViewInteractions Interactions + * Supported interactions: Long tap. User of the component can specify object + * menu for content items in native application views. Long tap for applet's + * content items, not currently implemented. + * + * \sa DuiContainer, DuiContainerModel + */ +class DUI_EXPORT DuiContainerView : public DuiWidgetView +{ + Q_OBJECT + DUI_VIEW(DuiContainerModel, DuiContainerStyle) + +public: + /*! + * \brief Constructor + * \param controller Pointer to the container's controller + */ + DuiContainerView(DuiContainer *controller); + + /*! + * \brief Destructor + */ + virtual ~DuiContainerView(); + +protected: + //! \reimp + virtual void drawBackground(QPainter *painter, const QStyleOptionGraphicsItem *option) const; + virtual void applyStyle(); + virtual void setupModel(); + //! \reimp_end + + DuiContainerView(DuiContainerViewPrivate &dd, DuiContainer *controller); + +private Q_SLOTS: + //! \reimp + virtual void updateData(const QList& modifications); + //! \reimp_end + +public Q_SLOTS: + void headerPressed(); + void headerReleased(); + void headerCanceled(); + void headerMoved(); + +Q_SIGNALS: + /*! + * \brief Signal for informing that the header was clicked + */ + void headerClicked(); + +private: + Q_DISABLE_COPY(DuiContainerView) + Q_DECLARE_PRIVATE(DuiContainerView) +}; + +#endif diff --git a/src/widgets/views/duicontainerview_p.h b/src/widgets/views/duicontainerview_p.h new file mode 100644 index 000000000..1eeeb3a1a --- /dev/null +++ b/src/widgets/views/duicontainerview_p.h @@ -0,0 +1,78 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIMASHUPCONTAINERVIEW_P_H +#define DUIMASHUPCONTAINERVIEW_P_H + +#include "private/duiwidgetview_p.h" + +class DuiContainer; +class QGraphicsLinearLayout; + +class DuiButton; +class DuiLabel; +class DuiImageWidget; +class DuiSeparator; +class QPixmap; +class DuiScalableImage; +class DuiContainerHeader; +class DuiProgressIndicator; + +class DuiContainerViewPrivate : public DuiWidgetViewPrivate +{ +public: + DuiContainerViewPrivate(); + virtual ~DuiContainerViewPrivate(); + + DuiContainer *controller; + + void init(); + + void createHeader(); + void removeHeader(); + void setupIcon(const QSize &size); + + void createProgressIndicator(); + void layoutProgressIndicator(); + + // vertical main layout + QGraphicsLinearLayout *mainLayout; + + // layout for the header component of the container + QGraphicsLinearLayout *headerLayout; + + // widgets for the header + DuiContainerHeader *header; + DuiImageWidget *icon; + DuiLabel *title; + DuiLabel *text; + + const DuiScalableImage *background; + + //! Whether the header is in "pressed" state + bool headerPressed; + + DuiProgressIndicator *progressIndicator; + + DuiContainerView *q_ptr; + Q_DECLARE_PUBLIC(DuiContainerView) +}; + + +#endif diff --git a/src/widgets/views/duicontentitem.cpp b/src/widgets/views/duicontentitem.cpp new file mode 100644 index 000000000..263fbdf04 --- /dev/null +++ b/src/widgets/views/duicontentitem.cpp @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duicontentitem.h" \ No newline at end of file diff --git a/src/widgets/views/duicontentitemview.cpp b/src/widgets/views/duicontentitemview.cpp new file mode 100644 index 000000000..f861503b8 --- /dev/null +++ b/src/widgets/views/duicontentitemview.cpp @@ -0,0 +1,384 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include +#include +#include + +#include +#include + +#include "duicontentitem.h" +#include "duicontentitemview.h" +#include "duicontentitemview_p.h" + +static const int NOCONTENTITEMSTYLE = -1; +QVector DuiContentItemViewPrivate::backgroundFunctions; + +DuiContentItemViewPrivate::DuiContentItemViewPrivate() + : titleLabel(NULL), subtitleLabel(NULL), imageWidget(NULL), configuredStyle(NOCONTENTITEMSTYLE), down(false) +{ + layout = new QGraphicsGridLayout; + layout->setContentsMargins(0, 0, 0, 0); + layout->setSpacing(0); + + initBackgroundFunctions(); +} + +DuiContentItemViewPrivate::~DuiContentItemViewPrivate() +{ + clearLayout(); + delete titleLabel; + delete subtitleLabel; + delete imageWidget; +} + +void DuiContentItemViewPrivate::initBackgroundFunctions() +{ + if (backgroundFunctions.size() == 0) { + backgroundFunctions.resize(DuiContentItem::SingleColumnBottom + 1); + backgroundFunctions[DuiContentItem::Default] = &DuiContentItemStyle::backgroundImage; + backgroundFunctions[DuiContentItem::TopLeft] = &DuiContentItemStyle::backgroundImageTopLeft; + backgroundFunctions[DuiContentItem::Top] = &DuiContentItemStyle::backgroundImageTop; + backgroundFunctions[DuiContentItem::TopRight] = &DuiContentItemStyle::backgroundImageTopRight; + backgroundFunctions[DuiContentItem::Left] = &DuiContentItemStyle::backgroundImageLeft; + backgroundFunctions[DuiContentItem::Center] = &DuiContentItemStyle::backgroundImageCenter; + backgroundFunctions[DuiContentItem::Right] = &DuiContentItemStyle::backgroundImageRight; + backgroundFunctions[DuiContentItem::BottomLeft] = &DuiContentItemStyle::backgroundImageBottomLeft; + backgroundFunctions[DuiContentItem::Bottom] = &DuiContentItemStyle::backgroundImageBottom; + backgroundFunctions[DuiContentItem::BottomRight] = &DuiContentItemStyle::backgroundImageBottomRight; + backgroundFunctions[DuiContentItem::Single] = &DuiContentItemStyle::backgroundImageSingle; + backgroundFunctions[DuiContentItem::SingleRowLeft] = &DuiContentItemStyle::backgroundImageSinglerowLeft; + backgroundFunctions[DuiContentItem::SingleRowCenter] = &DuiContentItemStyle::backgroundImageSinglerowCenter; + backgroundFunctions[DuiContentItem::SingleRowRight] = &DuiContentItemStyle::backgroundImageSinglerowRight; + backgroundFunctions[DuiContentItem::SingleColumnTop] = &DuiContentItemStyle::backgroundImageSinglecolumnTop; + backgroundFunctions[DuiContentItem::SingleColumnCenter] = &DuiContentItemStyle::backgroundImageSinglecolumnCenter; + backgroundFunctions[DuiContentItem::SingleColumnBottom] = &DuiContentItemStyle::backgroundImageSinglecolumnBottom; + } +} + +DuiLabel *DuiContentItemViewPrivate::title() +{ + if (!titleLabel) { + titleLabel = new DuiLabel(controller); + Q_Q(DuiContentItemView); + titleLabel->setObjectName(q->style()->titleObjectName()); + } + + return titleLabel; +} + +DuiLabel *DuiContentItemViewPrivate::subtitle() +{ + if (!subtitleLabel) { + subtitleLabel = new DuiLabel(controller); + Q_Q(DuiContentItemView); + subtitleLabel->setObjectName(q->style()->subtitleObjectName()); + } + + return subtitleLabel; +} + +DuiImageWidget *DuiContentItemViewPrivate::image() +{ + if (!imageWidget) { + imageWidget = new DuiImageWidget(controller); + Q_Q(DuiContentItemView); + imageWidget->setObjectName(q->style()->imageObjectName()); + } + + return imageWidget; +} + +void DuiContentItemViewPrivate::initLayout(DuiContentItem::ContentItemStyle style) +{ + if (configuredStyle == style) + return; + + clearLayout(); + + configuredStyle = style; + + switch (style) { + case DuiContentItem::IconAndTwoTextLabels: + image()->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); + layout->addItem(image(), 0, 0, 4, 1); + layout->addItem(new QGraphicsWidget(controller), 0, 1); + layout->addItem(title(), 1, 1); + layout->addItem(subtitle(), 2, 1); + layout->addItem(new QGraphicsWidget(controller), 3, 1); + + image()->setVisible(true); + title()->setVisible(true); + subtitle()->setVisible(true); + break; + + case DuiContentItem::SingleTextLabel: + layout->addItem(title(), 0, 0, Qt::AlignCenter); + + if (subtitleLabel) + subtitleLabel->setVisible(false); + if (imageWidget) + imageWidget->setVisible(false); + break; + + case DuiContentItem::IconAndSingleTextLabel: + layout->addItem(image(), 0, 0); + layout->addItem(title(), 0, 1, Qt::AlignCenter); + image()->setVisible(true); + title()->setVisible(true); + + if (subtitleLabel) + subtitleLabel->setVisible(false); + break; + + case DuiContentItem::TwoTextLabels: + layout->addItem(new QGraphicsWidget(controller), 0, 0); + layout->addItem(title(), 1, 0, Qt::AlignBottom | Qt::AlignCenter); + layout->addItem(subtitle(), 2, 0, Qt::AlignTop | Qt::AlignCenter); + layout->addItem(new QGraphicsWidget(controller), 3, 0); + + if (imageWidget) + imageWidget->setVisible(false); + break; + + case DuiContentItem::SingleIcon: + layout->addItem(image(), 0, 0, Qt::AlignCenter); + image()->setVisible(true); + + if (titleLabel) + title()->setVisible(false); + if (subtitleLabel) + subtitle()->setVisible(false); + + break; + + case DuiContentItem::IconAndSingleTextLabelVertical: + layout->addItem(image(), 0, 0, Qt::AlignCenter); + layout->addItem(title(), 1, 0, Qt::AlignCenter); + + title()->setAlignment(Qt::AlignCenter); + + image()->setVisible(true); + title()->setVisible(true); + + if (subtitleLabel) + subtitleLabel->setVisible(false); + break; + + case DuiContentItem::IconAndTwoTextLabelsVertical: + layout->addItem(image(), 0, 0, Qt::AlignCenter); + + layout->addItem(title(), 1, 0, Qt::AlignCenter); + layout->addItem(subtitle(), 2, 0, Qt::AlignCenter); + + + title()->setAlignment(Qt::AlignCenter); + subtitle()->setAlignment(Qt::AlignCenter); + + image()->setVisible(true); + title()->setVisible(true); + subtitle()->setVisible(true); + + break; + }; +} + +void DuiContentItemViewPrivate::clearLayout() +{ + for (int i = 0; i < layout->count(); i++) + layout->removeAt(0); +} + +void DuiContentItemViewPrivate::setTitle(const QString &string) +{ + title()->setText(string); +} + +void DuiContentItemViewPrivate::setSubtitle(const QString &string) +{ + subtitle()->setText(string); +} + +void DuiContentItemViewPrivate::setImage(const QPixmap &pixmap) +{ + image()->setPixmap(pixmap); +} + +void DuiContentItemViewPrivate::applyStyle() +{ + Q_Q(DuiContentItemView); + + if (titleLabel) + titleLabel->setObjectName(q->style()->titleObjectName()); + + if (subtitleLabel) + subtitleLabel->setObjectName(q->style()->subtitleObjectName()); + + if (imageWidget) + imageWidget->setObjectName(q->style()->imageObjectName()); +} + +DuiContentItemView::DuiContentItemView(DuiContentItem *controller) + : DuiWidgetView(* new DuiContentItemViewPrivate, controller) +{ + Q_D(DuiContentItemView); + d->controller = controller; + controller->setLayout(d->layout); +} + +DuiContentItemView::DuiContentItemView(DuiContentItemViewPrivate &dd, DuiContentItem *controller) + : DuiWidgetView(dd, controller) +{ + Q_D(DuiContentItemView); + d->controller = controller; + controller->setLayout(d->layout); +} + +DuiContentItemView::~DuiContentItemView() +{ + +} + +void DuiContentItemView::applyStyle() +{ + DuiWidgetView::applyStyle(); + + Q_D(DuiContentItemView); + d->applyStyle(); +} + +void DuiContentItemView::updateData(const QList &modifications) +{ + Q_D(DuiContentItemView); + + DuiWidgetView::updateData(modifications); + + const char *member; + for (int i = 0; i < modifications.count(); i++) { + member = modifications[i]; + if (member == DuiContentItemModel::Title) { + d->setTitle(model()->title()); + } else if (member == DuiContentItemModel::Subtitle) { + d->setSubtitle(model()->subtitle()); + } else if (member == DuiContentItemModel::ItemImage) { + d->setImage(d->controller->pixmap()); + } else if (member == DuiContentItemModel::Selected) { + setSelected(model()->selected()); + } + } +} + +void DuiContentItemView::setupModel() +{ + Q_D(DuiContentItemView); + + DuiWidgetView::setupModel(); + + if (!model()->title().isEmpty()) + d->setTitle(model()->title()); + if (!model()->subtitle().isEmpty()) + d->setSubtitle(model()->subtitle()); + if (!d->controller->pixmap().isNull()) + d->setImage(d->controller->pixmap()); + + d->initLayout(static_cast(model()->itemStyle())); +} + +void DuiContentItemView::cancelEvent(DuiCancelEvent *event) +{ + Q_D(DuiContentItemView); + d->down = false; + + if (d->controller->isSelected()) { + style().setModeSelected(); + } else { + style().setModeDefault(); + } + + applyStyle(); + update(); + + event->accept(); +} + +void DuiContentItemView::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + Q_D(DuiContentItemView); + + /* + if(d->controller->isSelectable()) + { + */ + d->down = true; + style().setModePressed(); + applyStyle(); + update(); + + event->accept(); + /* + } else { + event->ignore(); + } + event->ignore(); + */ +} + +void DuiContentItemView::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + Q_D(DuiContentItemView); + + if (d->down) { + d->down = false; + event->accept(); + + style().setModeDefault(); + applyStyle(); + update(); + + d->controller->click(); + } else { + event->ignore(); + } +} + +void DuiContentItemView::drawBackground(QPainter *painter, const QStyleOptionGraphicsItem *option) const +{ + Q_UNUSED(option); + + DuiContentItemViewPrivate::backgroundFunc func = DuiContentItemViewPrivate::backgroundFunctions[model()->itemMode()]; + const DuiContentItemStyle *itemStyle = style().operator ->(); + const DuiScalableImage *itemBackground = ((*itemStyle).*func)(); + itemBackground->draw(0, 0, size().width(), size().height(), painter); +} + +void DuiContentItemView::setSelected(bool selected) +{ + if (selected) + style().setModeSelected(); + else + style().setModeDefault(); + + applyStyle(); + updateGeometry(); +} + +DUI_REGISTER_VIEW_NEW(DuiContentItemView, DuiContentItem) diff --git a/src/widgets/views/duicontentitemview.h b/src/widgets/views/duicontentitemview.h new file mode 100644 index 000000000..dabf74cf3 --- /dev/null +++ b/src/widgets/views/duicontentitemview.h @@ -0,0 +1,81 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUICONTENTITEMVIEW_H__ +#define DUICONTENTITEMVIEW_H__ + +#include "duiwidgetview.h" +#include "duicontentitemmodel.h" +#include "duicontentitemstyle.h" + +class DuiContentItem; +class DuiContentItemViewPrivate; + +/*! + \class DuiContentItemView + \brief View class for DuiContentItem. + + \ingroup views + + \section DuiContentItemView Overview + DuiContentItemView draws DuiContentItem as a 2 text lines and a thumbnail and any combination of those depending + on the style. + + DuiContentItemView supports 4 different layouts for text and thumnbail. They have to be set through DuiContentItem::setItemStyle(). + + \image html content-item-styles.png + + DuiContentItemView supports different modes which has to be set through DuiContentItem::setItemMode() + + \image html content-item-modes.png + */ +class DUI_EXPORT DuiContentItemView : public DuiWidgetView +{ + Q_OBJECT + DUI_VIEW(DuiContentItemModel, DuiContentItemStyle) + +public: + DuiContentItemView(DuiContentItem *controller); + virtual ~DuiContentItemView(); + +protected slots: + virtual void updateData(const QList &modifications); + +protected: + //! \reimp + virtual void drawBackground(QPainter *painter, const QStyleOptionGraphicsItem *option) const; + virtual void setupModel(); + virtual void applyStyle(); + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + virtual void cancelEvent(DuiCancelEvent *event); + //! \reimp_end + + void setSelected(bool selected); + + //! \cond + DuiContentItemView(DuiContentItemViewPrivate &dd, DuiContentItem *controller); + //! \cond_end + +private: + Q_DISABLE_COPY(DuiContentItemView) + Q_DECLARE_PRIVATE(DuiContentItemView) +}; + +#endif diff --git a/src/widgets/views/duicontentitemview_p.h b/src/widgets/views/duicontentitemview_p.h new file mode 100644 index 000000000..1c97d6317 --- /dev/null +++ b/src/widgets/views/duicontentitemview_p.h @@ -0,0 +1,69 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUICONTENTITEM_P_H__ +#define DUICONTENTITEM_P_H__ + +#include "duicontentitemstyle.h" +#include "duicontentitem.h" +#include "private/duiwidgetview_p.h" +#include "duicontentitemstyle.h" + +class DuiLabel; +class DuiImageWidget; +class DuiScalableImage; +class QGraphicsGridLayout; + +class DuiContentItemViewPrivate : public DuiWidgetViewPrivate +{ + Q_DECLARE_PUBLIC(DuiContentItemView) + +public: + DuiContentItemViewPrivate(); + virtual ~DuiContentItemViewPrivate(); + + inline DuiLabel *title(); + inline DuiLabel *subtitle(); + inline DuiImageWidget *image(); + + inline void setTitle(const QString &string); + inline void setSubtitle(const QString &string); + inline void setImage(const QPixmap &pixmap); + + void initLayout(DuiContentItem::ContentItemStyle style); + void clearLayout(); + + void applyStyle(); + + typedef const DuiScalableImage*(DuiContentItemStyle::*backgroundFunc)() const; + + static void initBackgroundFunctions(); + static QVector backgroundFunctions; + +private: + DuiContentItem *controller; + DuiLabel *titleLabel; + DuiLabel *subtitleLabel; + DuiImageWidget *imageWidget; + QGraphicsGridLayout *layout; + int configuredStyle; + bool down; +}; + +#endif diff --git a/src/widgets/views/duidialogview.cpp b/src/widgets/views/duidialogview.cpp new file mode 100644 index 000000000..12c1c7514 --- /dev/null +++ b/src/widgets/views/duidialogview.cpp @@ -0,0 +1,568 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duidialogview.h" +#include "duidialogview_p.h" + +#include "duidialog.h" +#include "duidialog_p.h" +#include "duiviewcreator.h" +#include "duipannableviewport.h" +#include "duiscenemanager.h" +#include +#include +#include +#include +#include +#include "duibuttongrouplayoutpolicy_p.h" + +#include + +DuiDialogViewPrivate::DuiDialogViewPrivate() + : rootLayout(0), + topSpacer(0), + bottomSpacer(0), + leftSpacer(0), + rightSpacer(0), + horizontalWidget(0), + horizontalLayout(0), + dialogBox(0), + contentsLayout(0), + centralWidget(0), + titleBar(0), + titleLabel(0), + spinner(0), + closeButton(0), + buttonBox(0), + buttonBoxLayout(0), + buttonBoxLayoutPolicy(0) +{ +} + +DuiDialogViewPrivate::~DuiDialogViewPrivate() +{ +} + +void DuiDialogViewPrivate::createWidgetHierarchy() +{ + rootLayout = createLayout(Qt::Vertical); + static_cast(controller)->setLayout(rootLayout); + + topSpacer = createSpacer(); + rootLayout->addItem(topSpacer); + + createHorizontalLayout(); + // If I directly add horizontalLayout to rootLayout (instead + // of assigning it to a widget and then adding that widget) + // the sizes go nuts. + // Yet another bug in QGraphicsLayout... + horizontalWidget = new QGraphicsWidget; + horizontalWidget->setLayout(horizontalLayout); + rootLayout->addItem(horizontalWidget); + //rootLayout->addItem(horizontalLayout); +} + +QGraphicsWidget *DuiDialogViewPrivate::createSpacer() +{ + QGraphicsWidget *spacer = new QGraphicsWidget(); + + spacer->hide(); + spacer->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); + spacer->setMinimumSize(0, 0); + spacer->setPreferredSize(0, 0); + + return spacer; +} + +QGraphicsLinearLayout *DuiDialogViewPrivate::createLayout(Qt::Orientation orientation) +{ + QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(orientation); + layout->setContentsMargins(0, 0, 0, 0); + layout->setSpacing(0); + return layout; +} + +void DuiDialogViewPrivate::createHorizontalLayout() +{ + horizontalLayout = createLayout(Qt::Horizontal); + + leftSpacer = createSpacer(); + leftSpacer->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred); + horizontalLayout->addItem(leftSpacer); + + createDialogBox(); + horizontalLayout->addItem(dialogBox); + + rightSpacer = createSpacer(); + rightSpacer->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred); + horizontalLayout->addItem(rightSpacer); +} + +void DuiDialogViewPrivate::createDialogBox() +{ + dialogBox = new QGraphicsWidget; + dialogBox->setObjectName("DuiDialogBox"); + dialogBoxLayout = createLayout(Qt::Vertical); + dialogBox->setLayout(dialogBoxLayout); + + createTitleBar(); + dialogBoxLayout->addItem(titleBar); + + contentsViewport = new DuiPannableViewport; + contentsViewport->setObjectName("DuiDialogContentsViewport"); + dialogBoxLayout->addItem(contentsViewport); + + contents = new QGraphicsWidget(); + contents->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); + contentsViewport->setWidget(contents); + contentsLayout = createLayout(Qt::Vertical); + contentsLayout->setContentsMargins(0, 0, 0, 0); + contents->setLayout(contentsLayout); + + createButtonBox(); + contentsLayout->addItem(buttonBox); +} + +void DuiDialogViewPrivate::createButtonBox() +{ + buttonBox = new QGraphicsWidget; + buttonBoxLayout = new DuiLayout(); + buttonBoxLayoutPolicy = new DuiButtonGroupLayoutPolicy(buttonBoxLayout, Qt::Horizontal); + buttonBoxLayout->setPolicy(buttonBoxLayoutPolicy); + buttonBoxLayout->setContentsMargins(0, 0, 0, 0); + buttonBox->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); + + buttonBox->setLayout(buttonBoxLayout); +} + +void DuiDialogViewPrivate::createTitleBar() +{ + QGraphicsLinearLayout *layout = createLayout(Qt::Horizontal); + titleBar = new DuiStylableWidget; + titleBar->setObjectName("DuiDialogTitleBar"); + titleBar->setLayout(layout); + titleBar->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); + + spinner = new DuiProgressIndicator(titleBar, DuiProgressIndicator::spinnerType); + spinner->setUnknownDuration(true); + spinner->setObjectName("DuiDialogProgressIndicator"); + layout->addItem(spinner); + spinner->setVisible(false); // hidden by default + + titleLabel = new DuiLabel(titleBar); + titleLabel->setAlignment(Qt::AlignCenter); + titleLabel->setTextElide(true); + titleLabel->setObjectName("DuiDialogTitleLabel"); + layout->addItem(titleLabel); + layout->setAlignment(titleLabel, Qt::AlignCenter); + + closeButton = new DuiButton(titleBar); + closeButton->setObjectName("DuiDialogCloseButton"); + closeButton->setViewType("icon"); + closeButton->setIconID("Icon-close"); + layout->addItem(closeButton); + layout->setAlignment(closeButton, Qt::AlignVCenter | Qt::AlignHCenter); + QObject::connect(closeButton, SIGNAL(clicked()), controller, SLOT(reject())); +} + +DuiDialogView::DuiDialogView(DuiDialog *controller) : + DuiSceneWindowView(*new DuiDialogViewPrivate, controller) +{ + Q_D(DuiDialogView); + d->controller = controller; + d->createWidgetHierarchy(); +} + +DuiDialogView::DuiDialogView(DuiDialogViewPrivate &dd, DuiDialog *controller) + : DuiSceneWindowView(dd, controller) +{ + Q_D(DuiDialogView); + d->controller = controller; + d->createWidgetHierarchy(); +} + + +DuiDialogView::~DuiDialogView() +{ + Q_D(DuiDialogView); + + // Make sure the model's centralWidget doesn't get deleted along with us. + d->setCentralWidget(0); +} + +void DuiDialogView::applyStyle() +{ + Q_D(DuiDialogView); + DuiDialogPrivate *dialogPrivate = d->controller->d_func(); + + if (dialogPrivate->dumbMode) { + return; + } + + DuiSceneWindowView::applyStyle(); + + // update title bar height + d->titleBar->setMinimumHeight(style()->titleBarHeight()); + d->titleBar->setPreferredHeight(style()->titleBarHeight()); + d->titleBar->setMaximumHeight(style()->titleBarHeight()); + + // set dimensions separately to that we may have one dimensions set + // and the other unset (-1). + d->dialogBox->setMinimumWidth(style()->dialogMinimumSize().width()); + d->dialogBox->setMinimumHeight(style()->dialogMinimumSize().height()); + + // set dimensions separately to that we may have one dimensions set + // and the other unset (-1). + d->dialogBox->setPreferredWidth(style()->dialogPreferredSize().width()); + d->dialogBox->setPreferredHeight(style()->dialogPreferredSize().height()); + + d->buttonBox->setContentsMargins( + 0, style()->verticalSpacing(), 0, 0); + + d->buttonBoxLayoutPolicy->setOrientation(style()->buttonBoxOrientation()); + d->buttonBoxLayoutPolicy->setSpacing(style()->buttonSpacing()); + + d->rootLayout->setContentsMargins( + style()->dialogLeftMargin(), /* left */ + style()->dialogTopMargin(), /* top */ + style()->dialogRightMargin(), /* right */ + style()->dialogBottomMargin() /* bottom */); + + d->setupDialogVerticalAlignment(); +} + +void DuiDialogViewPrivate::setupDialogVerticalAlignment() +{ + Q_Q(DuiDialogView); + + if (q->style()->dialogVerticalAlignment() & Qt::AlignVCenter + && bottomSpacer == 0) { + + // switch to center alignment + + bottomSpacer = createSpacer(); + rootLayout->addItem(bottomSpacer); + + } else if (!(q->style()->dialogVerticalAlignment() & Qt::AlignVCenter) + && bottomSpacer != 0) { + + // switch to bottom alignment. + + rootLayout->removeItem(bottomSpacer); + delete bottomSpacer; + bottomSpacer = 0; + } +} + +void DuiDialogViewPrivate::updateWidgetVisibility(QGraphicsWidget *widget, bool visible, int index, + QGraphicsLinearLayout *layout) +{ + if (widget->isVisible() == visible) { + // nothing to do here + return; + } + + // invisible items still occupy space in layouts, therefore I manually have + // to remove them. + + if (visible) { + // I am currenly invisible and therefore not part of the layout. + // To become visible I have to be added to the layout. + layout->insertItem(index, widget); + } else { + // I am currently visible and therefore part of the layout. + // To become invisible I have to be removed from it. + layout->removeItem(widget); + } + + // update visibility property + widget->setVisible(visible); + + if (widget == titleBar) { + if (visible) { + contentsViewport->setViewType(DuiPannableWidget::defaultType); + } else { + contentsViewport->setViewType("titlebarless"); + } + } +} + +void DuiDialogViewPrivate::repopulateButtonBox() +{ + Q_Q(DuiDialogView); + DuiButton *button; + + while (buttonBoxLayout->count() > 0) { + button = static_cast(buttonBoxLayout->itemAt(0)); + buttonBoxLayout->removeAt(0); + delete button; + } + + DuiDialogButtonsList buttonModelsList = q->model()->buttons(); + + const int buttonModelsSize = buttonModelsList.size(); + for (int i = 0; i < buttonModelsSize; ++i) { + addButton(q->model()->button(i)); + } +} + +void DuiDialogViewPrivate::updateButtonBox() +{ + removeButtonsNotInDialogModel(); + addButtonsFromDialogModel(); +} + +void DuiDialogViewPrivate::removeButtonsNotInDialogModel() +{ + Q_Q(DuiDialogView); + DuiButton *button; + DuiDialogButtonsList buttonModelsList = q->model()->buttons(); + int i = 0; + + while (i < buttonBoxLayout->count()) { + button = static_cast(buttonBoxLayout->itemAt(i)); + if (!buttonModelsList.contains(button->model())) { + buttonBoxLayout->removeAt(i); + delete button; + } else { + ++i; + } + } +} + +void DuiDialogViewPrivate::addButtonsFromDialogModel() +{ + Q_Q(DuiDialogView); + DuiButtonModel *buttonModel; + DuiDialogButtonsList buttonModelsList = q->model()->buttons(); + + const int buttonModelsSize = buttonModelsList.size(); + for (int i = 0; i < buttonModelsSize; ++i) { + buttonModel = buttonModelsList[i]; + + if (!isButtonInButtonBox(buttonModel)) { + addButton(buttonModel); + } + } +} + +bool DuiDialogViewPrivate::isButtonInButtonBox(DuiButtonModel *buttonModel) +{ + int i = 0; + bool foundButton = false; + const int buttonBoxSize = buttonBoxLayout->count(); + + while (i < buttonBoxSize && !foundButton) { + foundButton = static_cast(buttonBoxLayout->itemAt(i))->model() == buttonModel; + if (!foundButton) { + ++i; + } + } + + return foundButton; +} + +void DuiDialogViewPrivate::addButton(DuiButtonModel *buttonModel) +{ + Q_Q(DuiDialogView); + Dui::StandardButton currButtonType; + DuiButton *newButton = new DuiButton(0, buttonModel); + DuiButton *currButton = 0; + bool buttonAdded = false; + int i = 0; + Dui::StandardButton buttonType = q->model()->standardButton(buttonModel); + + /* The order of buttons should be arranged so, that from left-to-right, + top-down, the positive/confirming button should be the first one, and + the negative/canceling action should be the last. + + OBS: buttons should be also mirrored in right-to-left-layouts, e.g. Arabic. + */ + do { + if (i < buttonBoxLayout->count()) { + currButton = static_cast(buttonBoxLayout->itemAt(i)); + + currButtonType = q->model()->standardButton(currButton->model()); + + if (stdButtonOrder(buttonType) < stdButtonOrder(currButtonType)) { + buttonBoxLayoutPolicy->insertItem(i, newButton); + buttonAdded = true; + } + + ++i; + } else { + // just add it to the end of the layout. + buttonBoxLayoutPolicy->addItem(newButton); + buttonAdded = true; + } + } while (!buttonAdded); +} + +int DuiDialogViewPrivate::stdButtonOrder(Dui::StandardButton buttonType) +{ + int order; + + switch (buttonType) { + // Positive actions + case Dui::OkButton: + case Dui::SaveButton: + case Dui::SaveAllButton: + case Dui::OpenButton: + case Dui::YesButton: + case Dui::YesToAllButton: + case Dui::RetryButton: + case Dui::ApplyButton: + case Dui::DoneButton: + order = 1; + break; + + // Negative actions + case Dui::NoButton: + case Dui::NoToAllButton: + case Dui::AbortButton: + case Dui::IgnoreButton: + case Dui::CloseButton: + case Dui::CancelButton: + case Dui::DiscardButton: + case Dui::HelpButton: + case Dui::ResetButton: + case Dui::RestoreDefaultsButton: + order = 2; + break; + + default: + order = 3; + break; + }; + + return order; +} + +void DuiDialogViewPrivate::setCentralWidget(DuiWidget *newCentralWidget) +{ + if (centralWidget) { + contentsLayout->removeItem(centralWidget); + delete centralWidget; + centralWidget = 0; + } + + // Place the new one + if (newCentralWidget) { + contentsLayout->insertItem(0, newCentralWidget); + centralWidget = newCentralWidget; + } +} + +void DuiDialogView::setupModel() +{ + Q_D(DuiDialogView); + DuiDialogPrivate *dialogPrivate = d->controller->d_func(); + + DuiSceneWindowView::setupModel(); + + if (dialogPrivate->dumbMode) { + return; + } + + d->titleLabel->setText(model()->title()); + d->closeButton->setVisible(model()->closeButtonVisible()); + d->spinner->setVisible(model()->progressIndicatorVisible()); + + d->updateWidgetVisibility(d->buttonBox, + model()->buttonBoxVisible(), + d->contentsLayout->count(), + d->contentsLayout); + + d->updateWidgetVisibility(d->titleBar, + model()->titleBarVisible(), + 0, + d->dialogBoxLayout); + + d->repopulateButtonBox(); + + d->setCentralWidget(model()->centralWidget()); +} + +void DuiDialogView::updateData(const QList &modifications) +{ + Q_D(DuiDialogView); + + DuiSceneWindowView::updateData(modifications); + + DuiDialogPrivate *dialogPrivate = d->controller->d_func(); + const char *member; + + if (dialogPrivate->dumbMode) { + return; + } + + foreach(member, modifications) { + if (member == DuiDialogModel::CloseButtonVisible) { + d->closeButton->setVisible(model()->closeButtonVisible()); + } else if (member == DuiDialogModel::ProgressIndicatorVisible) { + d->spinner->setVisible(model()->progressIndicatorVisible()); + } else if (member == DuiDialogModel::Title) { + d->titleLabel->setText(model()->title()); + } else if (member == DuiDialogModel::ButtonBoxVisible) { + d->updateWidgetVisibility(d->buttonBox, + model()->buttonBoxVisible(), + d->contentsLayout->count(), + d->contentsLayout); + } else if (member == DuiDialogModel::TitleBarVisible) { + d->updateWidgetVisibility(d->titleBar, + model()->titleBarVisible(), + 0, + d->dialogBoxLayout); + + } else if (member == DuiDialogModel::CentralWidget) { + d->setCentralWidget(model()->centralWidget()); + } else if (member == DuiDialogModel::Buttons) { + d->updateButtonBox(); + } + } +} + +QPainterPath DuiDialogView::shape() const +{ + Q_D(const DuiDialogView); + QPainterPath path; + + path = d->dialogBox->shape(); + + path.translate(d->horizontalWidget->pos()); + + path.translate(d->dialogBox->geometry().x(), + d->dialogBox->geometry().y()); + + return path; +} + +QGraphicsLinearLayout *DuiDialogView::contentsLayout() +{ + Q_D(DuiDialogView); + return d->contentsLayout; +} + +DuiPannableViewport *DuiDialogView::contentsViewport() +{ + Q_D(DuiDialogView); + return d->contentsViewport; +} + +DUI_REGISTER_VIEW_NEW(DuiDialogView, DuiDialog) diff --git a/src/widgets/views/duidialogview.h b/src/widgets/views/duidialogview.h new file mode 100644 index 000000000..9bddb40f2 --- /dev/null +++ b/src/widgets/views/duidialogview.h @@ -0,0 +1,130 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIDIALOGVIEW_H +#define DUIDIALOGVIEW_H + +#include +#include "duiscenewindowview.h" +#include "duidialogmodel.h" + +class DuiDialog; +class DuiDialogViewPrivate; +class DuiPannableViewport; + +class QGraphicsLinearLayout; + +/*! + \class DuiDialogView + \brief View class for standard dialogs. + + \ingroup views + + \section DuiDialogViewOverview Overview + + DuiDialogView is used to visualize dialog windows. A dialog is comprised by + three components: a title bar, central widget and a button box. Each of this components + can be hidden. See DuiDialog for more details. + + When the button box is visible, buttons can have different appearance depending on their + position - left button can have different background, than right or middle. + It is done in style sheet by defining different button viewTypes: \em first, \em middle, + \em last, \em single. The last one is used when there is only one button in the dialog. + + When the title bar is hidden, the dialog background can be styled differently, + for example can have rounded corners. ViewType name for it is \em titlebarless. + + Example stylesheet: + \code + ... + + DuiPannableWidgetStyle[titlebarless]#DuiDialogContentsViewport { + background-image: "duidialog-query-background" 8px 8px 8px 0px; + } + + DuiButtonStyle[first].Landscape { + margin-right: 0; + background-image: "duidialog-left-button-background" 10px 10px 10px 10px; + } + + DuiButtonStyle[first].Landscape:pressed { + background-image: "duidialog-left-button-background-pressed" 10px 10px 10px 10px; + } + + DuiButtonStyle[first].Portrait { + margin-bottom: 0; + background-image: "duidialog-top-button-background" 10px 10px 10px 10px; + } + + DuiButtonStyle[first].Portrait:pressed { + background-image: "duidialog-top-button-background-pressed" 10px 10px 10px 10px; + } + + ... + \endcode + + \sa DuiDialog, DuiDialogStyle +*/ + +class DUI_EXPORT DuiDialogView : public DuiSceneWindowView +{ + Q_OBJECT + DUI_VIEW(DuiDialogModel, DuiDialogStyle) + +public: + DuiDialogView(DuiDialog *controller); + virtual ~DuiDialogView(); + +protected: + DuiDialogView(DuiDialogViewPrivate &dd, DuiDialog *controller); + + /*! + * \brief Returns the layout used to arrange the dialog's contents. + * The layout contains three items: title bar, central widget and button box. + * + * This method is useful for derived classes that wants to add new elements + * to the dialog. + * + * Be careful not to remove any items already there since it will effectively + * cripple the existing functionality. + * + * \return Layout with the dialog's contents. + */ + QGraphicsLinearLayout *contentsLayout(); + + DuiPannableViewport *contentsViewport(); + + //! \reimp + virtual QPainterPath shape() const; + virtual void applyStyle(); + virtual void setupModel(); + +protected slots: + virtual void updateData(const QList& modifications); + //! \reimp_end + +private: + Q_DECLARE_PRIVATE(DuiDialogView) + Q_DISABLE_COPY(DuiDialogView) +#ifdef UNIT_TEST + friend class Ut_DuiDialog; +#endif +}; + +#endif diff --git a/src/widgets/views/duidialogview_p.h b/src/widgets/views/duidialogview_p.h new file mode 100644 index 000000000..8ab53fbb3 --- /dev/null +++ b/src/widgets/views/duidialogview_p.h @@ -0,0 +1,140 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIDIALOGVIEW_P_H +#define DUIDIALOGVIEW_P_H + +#include "duidialogview.h" +#include "duiscenewindowview_p.h" +#include + +class DuiDialog; +class DuiDialogPrivate; +class DuiButton; +class DuiLabel; +class DuiPannableViewport; +class DuiProgressIndicator; +class DuiLayout; +class DuiButtonGroupLayoutPolicy; + +/* +Widget hierarchy: +================== + +DuiDialog (DuiSceneWindow), rootLayout + | + |- top spacer + | + |- horizontal widget + | | + | |- left spacer + | | + | |- dialogBox (the actual graphical dialog) + | | | + | | |- title bar + | | | | + | | | |- spinner + | | | | + | | | |- title label + | | | | + | | | |- close button + | | | + | | |- contents viewport (a pannable viewport) + | | | + | | |- contents (inside a pannable viewport) + | | | + | | |- central widget + | | | + | | |- button box + | | + | | - right spacer + | + |- bottom spacer (only when dialog-vertical-alignment = center) +*/ + +class DuiDialogViewPrivate : public DuiSceneWindowViewPrivate +{ + Q_DECLARE_PUBLIC(DuiDialogView) + +public: + DuiDialogViewPrivate(); + virtual ~DuiDialogViewPrivate(); + + void updateWidgetVisibility(QGraphicsWidget *widget, bool visible, int index, + QGraphicsLinearLayout *layout); + void setupDialogVerticalAlignment(); + + void createWidgetHierarchy(); + void createHorizontalLayout(); + void createTitleBar(); + void createButtonBox(); + void createDialogBox(); + static QGraphicsWidget *createSpacer(); + static QGraphicsLinearLayout *createLayout(Qt::Orientation orientation); + void repopulateButtonBox(); + static int stdButtonOrder(Dui::StandardButton buttonType); + void removeButtonsNotInDialogModel(); + void addButtonsFromDialogModel(); + bool isButtonInButtonBox(DuiButtonModel *buttonModel); + void setCentralWidget(DuiWidget *newCentralWidget); + void addButton(DuiButtonModel *buttonModel); + void updateButtonBox(); + + DuiDialog *controller; + + // Layout applied to the controller itself. + QGraphicsLinearLayout *rootLayout; + + QGraphicsWidget *topSpacer; + QGraphicsWidget *bottomSpacer; + QGraphicsWidget *leftSpacer; + QGraphicsWidget *rightSpacer; + + QGraphicsWidget *horizontalWidget; + QGraphicsLinearLayout *horizontalLayout; + + // The dialog box itself. + // Contains a title bar and a pannable viewport for the dialog's contents + QGraphicsWidget *dialogBox; + QGraphicsLinearLayout *dialogBoxLayout; + + // Widget that contains the contents of the dialog box. + // It has the central widget and the button box. + // Classes inheriting from DuiDialog may add new items to it. + // We expect that specialized classes don't remove our items from + // it by themselves. + QGraphicsWidget *contents; + QGraphicsLinearLayout *contentsLayout; + + DuiPannableViewport *contentsViewport; + + DuiWidget *centralWidget; + + DuiWidget *titleBar; + DuiLabel *titleLabel; + DuiProgressIndicator *spinner; + DuiButton *closeButton; + + QGraphicsWidget *buttonBox; + DuiLayout *buttonBoxLayout; + DuiButtonGroupLayoutPolicy *buttonBoxLayoutPolicy; +}; + +#endif + diff --git a/src/widgets/views/duidockwidgetview.cpp b/src/widgets/views/duidockwidgetview.cpp new file mode 100644 index 000000000..33e2d129c --- /dev/null +++ b/src/widgets/views/duidockwidgetview.cpp @@ -0,0 +1,48 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duidockwidgetview.h" +#include "duidockwidgetview_p.h" +#include "duidockwidget.h" +#include + +#include "duitheme.h" +#include "duiviewcreator.h" + +DuiDockWidgetViewPrivate::DuiDockWidgetViewPrivate() + : controller(0) +{ +} + +DuiDockWidgetViewPrivate::~DuiDockWidgetViewPrivate() +{ +} + +DuiDockWidgetView::DuiDockWidgetView(DuiDockWidget *controller) + : DuiSceneWindowView(* new DuiDockWidgetViewPrivate, controller) +{ + Q_D(DuiDockWidgetView); + d->controller = controller; +} + +DuiDockWidgetView::~DuiDockWidgetView() +{ +} + +DUI_REGISTER_VIEW_NEW(DuiDockWidgetView, DuiDockWidget) diff --git a/src/widgets/views/duidockwidgetview.h b/src/widgets/views/duidockwidgetview.h new file mode 100644 index 000000000..e6a6a968e --- /dev/null +++ b/src/widgets/views/duidockwidgetview.h @@ -0,0 +1,46 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +// Make doxygen skip this internal class +//! \cond +#ifndef DUIDOCKWIDGETVIEW_H +#define DUIDOCKWIDGETVIEW_H + +#include "duiscenewindowview.h" +#include "duidockwidgetmodel.h" +#include + +class DuiDockWidgetViewPrivate; +class DuiDockWidget; + +class DuiDockWidgetView : public DuiSceneWindowView +{ + Q_OBJECT + DUI_VIEW(DuiDockWidgetModel, DuiDockWidgetStyle) +public: + explicit DuiDockWidgetView(DuiDockWidget *controller); + virtual ~DuiDockWidgetView(); + +private: + Q_DISABLE_COPY(DuiDockWidgetView) + Q_DECLARE_PRIVATE(DuiDockWidgetView) +}; + +#endif // DUIDOCKWIDGETVIEW +//! \endcond diff --git a/src/widgets/views/duidockwidgetview_p.h b/src/widgets/views/duidockwidgetview_p.h new file mode 100644 index 000000000..b9598681d --- /dev/null +++ b/src/widgets/views/duidockwidgetview_p.h @@ -0,0 +1,36 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIDOCKWIDGETVIEW_P_H +#define DUIDOCKWIDGETVIEW_P_H + +#include "duiscenewindowview_p.h" + +class DuiDockWidget; + +class DuiDockWidgetViewPrivate : public DuiSceneWindowViewPrivate +{ +public: + DuiDockWidgetViewPrivate(); + ~DuiDockWidgetViewPrivate(); + + DuiDockWidget *controller; +}; + +#endif diff --git a/src/widgets/views/duiescapebuttonpanelview.cpp b/src/widgets/views/duiescapebuttonpanelview.cpp new file mode 100644 index 000000000..f3a1001e9 --- /dev/null +++ b/src/widgets/views/duiescapebuttonpanelview.cpp @@ -0,0 +1,149 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiescapebuttonpanelview.h" +#include "duiescapebuttonpanelview_p.h" +#include "duibutton.h" +#include "duiviewcreator.h" +#include "duiescapebuttonpanel.h" + +#include +#include +#include + +DuiEscapeButtonPanelViewPrivate::DuiEscapeButtonPanelViewPrivate() : + opacityTimeLine(0), + escapeMode(DuiEscapeButtonPanelModel::CloseMode) +{ +} + +DuiEscapeButtonPanelViewPrivate::~DuiEscapeButtonPanelViewPrivate() +{ +} + +void DuiEscapeButtonPanelViewPrivate::init() +{ + Q_Q(DuiEscapeButtonPanelView); + + QGraphicsGridLayout *mainLayout = new QGraphicsGridLayout; + mainLayout->setContentsMargins(0, 0, 0, 0); + mainLayout->setSpacing(0); + + backButton = new DuiButton(controller); + closeButton = new DuiButton(controller); + + backButton->setObjectName("BackButton"); + backButton->setViewType("icon"); + backButton->setIconID("Icon-back"); + + closeButton->setObjectName("CloseButton"); + closeButton->setViewType("icon"); + closeButton->setIconID("Icon-close"); + + mainLayout->addItem(closeButton, 0, 0); + mainLayout->addItem(backButton, 0, 0); + controller->setLayout(mainLayout); + + QObject::connect(backButton, SIGNAL(clicked()), controller, SIGNAL(buttonClicked())); + QObject::connect(closeButton, SIGNAL(clicked()), controller, SIGNAL(buttonClicked())); + + opacityTimeLine = new QTimeLine(500, q); + QObject::connect(opacityTimeLine, SIGNAL(finished()), + q, SLOT(finalizeEscapeButtonTransition())); + + QObject::connect(opacityTimeLine, SIGNAL(valueChanged(qreal)), + q, SLOT(opacityChange(qreal))); + + finalizeEscapeButtonTransition(); +} + +void DuiEscapeButtonPanelViewPrivate::finalizeEscapeButtonTransition() +{ + switch (escapeMode) { + case DuiEscapeButtonPanelModel::CloseMode: + backButton->hide(); + closeButton->show(); + break; + case DuiEscapeButtonPanelModel::BackMode: + closeButton->hide(); + backButton->show(); + break; + default: + qCritical() << "DuiEscapeButtonPanelViewPrivate::finalizeEscapeButtonTransition: unknown mode for escape button"; + break; + }; +} + +void DuiEscapeButtonPanelViewPrivate::opacityChange(qreal step) +{ + qreal opposite = 1.0 - step; + switch (escapeMode) { + case DuiEscapeButtonPanelModel::CloseMode: + closeButton->setOpacity(step); + backButton->setOpacity(opposite); + break; + case DuiEscapeButtonPanelModel::BackMode: + closeButton->setOpacity(opposite); + backButton->setOpacity(step); + break; + default: + qCritical() << "DuiEscapeButtonPanelViewPrivate::opacityChange: unknown mode for escape button"; + break; + }; +} + +DuiEscapeButtonPanelView::DuiEscapeButtonPanelView(DuiEscapeButtonPanel *controller) : + DuiSceneWindowView(* new DuiEscapeButtonPanelViewPrivate, controller) +{ + Q_D(DuiEscapeButtonPanelView); + d->controller = controller; + d->init(); +} + +DuiEscapeButtonPanelView::~DuiEscapeButtonPanelView() +{ +} + +void DuiEscapeButtonPanelView::applyStyle() +{ + Q_D(DuiEscapeButtonPanelView); + + DuiSceneWindowView::applyStyle(); + + d->opacityTimeLine->setDuration(style()->buttonAnimationLength()); +} + +void DuiEscapeButtonPanelView::updateData(const QList& modifications) +{ + DuiSceneWindowView::updateData(modifications); + + Q_D(DuiEscapeButtonPanelView); + + const char *member; + foreach(member, modifications) { + if (member == DuiEscapeButtonPanelModel::Mode) { + d->escapeMode = model()->mode(); + d->opacityTimeLine->start(); + } + } +} + +#include "moc_duiescapebuttonpanelview.cpp" + +DUI_REGISTER_VIEW_NEW(DuiEscapeButtonPanelView, DuiEscapeButtonPanel) diff --git a/src/widgets/views/duiescapebuttonpanelview.h b/src/widgets/views/duiescapebuttonpanelview.h new file mode 100644 index 000000000..0f8560ebe --- /dev/null +++ b/src/widgets/views/duiescapebuttonpanelview.h @@ -0,0 +1,63 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIESCAPEBUTTONPANELVIEW_H +#define DUIESCAPEBUTTONPANELVIEW_H + +#include "duiscenewindowview.h" +#include "duiescapebuttonpanelmodel.h" +#include + +class DuiEscapeButtonPanelViewPrivate; +class DuiEscapeButtonPanel; + +/*! + * \class DuiEscapeButtonPanelView + * \brief The DuiEscapeButtonPanelView class just draws an escape button. + * + * It just draws an escape button on an otherwise empty scene window. + */ +class DUI_EXPORT DuiEscapeButtonPanelView : public DuiSceneWindowView +{ + Q_OBJECT + DUI_VIEW(DuiEscapeButtonPanelModel, DuiEscapeButtonPanelStyle) + +public: + DuiEscapeButtonPanelView(DuiEscapeButtonPanel *controller); + virtual ~DuiEscapeButtonPanelView(); + +protected: + //! \reimp + virtual void applyStyle(); + //! \reimp_end + +protected Q_SLOTS: + //! \reimp + virtual void updateData(const QList& modifications); + //! \reimp_end + +private: + Q_DISABLE_COPY(DuiEscapeButtonPanelView) + Q_DECLARE_PRIVATE(DuiEscapeButtonPanelView) + + Q_PRIVATE_SLOT(d_func(), void finalizeEscapeButtonTransition()) + Q_PRIVATE_SLOT(d_func(), void opacityChange(qreal)) +}; + +#endif // DUIESCAPEBUTTONPANELVIEW_P diff --git a/src/widgets/views/duiescapebuttonpanelview_p.h b/src/widgets/views/duiescapebuttonpanelview_p.h new file mode 100644 index 000000000..c6c0033d5 --- /dev/null +++ b/src/widgets/views/duiescapebuttonpanelview_p.h @@ -0,0 +1,51 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIESCAPEBUTTONPANELVIEW_P_H +#define DUIESCAPEBUTTONPANELVIEW_P_H + +#include "duiscenewindowview_p.h" +#include "duiescapebuttonpanelmodel.h" + +class DuiEscapeButtonPanel; +class DuiButton; +class QTimeLine; + +class DuiEscapeButtonPanelViewPrivate : public DuiSceneWindowViewPrivate +{ + Q_DECLARE_PUBLIC(DuiEscapeButtonPanelView) + +public: + DuiEscapeButtonPanelViewPrivate(); + virtual ~DuiEscapeButtonPanelViewPrivate(); + + virtual void init(); + + void finalizeEscapeButtonTransition(); + void opacityChange(qreal step); + + DuiButton *backButton; + DuiButton *closeButton; + QTimeLine *opacityTimeLine; + DuiEscapeButtonPanelModel::EscapeMode escapeMode; + + DuiEscapeButtonPanel *controller; +}; + +#endif diff --git a/src/widgets/views/duiextendingbackgroundview.cpp b/src/widgets/views/duiextendingbackgroundview.cpp new file mode 100644 index 000000000..d11ebea9c --- /dev/null +++ b/src/widgets/views/duiextendingbackgroundview.cpp @@ -0,0 +1,129 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiextendingbackgroundview.h" +#include "duiextendingbackgroundview_p.h" + +#include +#include +#include +//#include +#include +#include +#include +#include + +DuiExtendingBackgroundViewPrivate::DuiExtendingBackgroundViewPrivate() : + controller(NULL) +{ +} + +DuiExtendingBackgroundViewPrivate::~DuiExtendingBackgroundViewPrivate() +{ +} + +void DuiExtendingBackgroundViewPrivate::init(DuiWidgetController *controller) +{ + this->controller = controller; +} + +QRect DuiExtendingBackgroundViewPrivate::backgroundGeometry() const +{ + Q_Q(const DuiExtendingBackgroundView); + + // Calculate background size + int x = 0; + int y = 0; + int width = q->geometry().width(); + int height = q->geometry().height(); + + // Get the borders of the scalable background image + int left = 0, right = 0, top = 0, bottom = 0; + const DuiScalableImage *bg = q->style()->backgroundImage(); + if (bg != NULL) { + bg->borders(&left, &right, &top, &bottom); + } + + // If the background should extend beyond a border recalculate offset and size + if (q->style()->extendDirection() == "left") { + x -= q->geometry().x() + left; + width += q->geometry().x() + left; + } else if (q->style()->extendDirection() == "right") { + width = DuiApplication::activeWindow()->visibleSceneSize().width() - q->geometry().x() + right; + } else if (q->style()->extendDirection() == "top") { + y -= q->geometry().y() + top; + height += q->geometry().y() + top; + } else if (q->style()->extendDirection() == "bottom") { + height = DuiApplication::activeWindow()->visibleSceneSize().height() - q->geometry().y() + bottom; + } + + return QRect(x, y, width, height); +} + + +DuiExtendingBackgroundView::DuiExtendingBackgroundView(DuiWidgetController *controller) : + DuiWidgetView(* new DuiExtendingBackgroundViewPrivate, controller) +{ + Q_D(DuiExtendingBackgroundView); + d->init(controller); +} + +DuiExtendingBackgroundView::DuiExtendingBackgroundView(DuiExtendingBackgroundViewPrivate &dd, DuiWidgetController *controller) : + DuiWidgetView(dd, controller) +{ + Q_D(DuiExtendingBackgroundView); + d->init(controller); +} + +DuiExtendingBackgroundView::~DuiExtendingBackgroundView() +{ +} + +void DuiExtendingBackgroundView::drawBackground(QPainter *painter, const QStyleOptionGraphicsItem *) const +{ + Q_D(const DuiExtendingBackgroundView); + + const DuiScalableImage *bg = style()->backgroundImage(); + if (bg != NULL) { + // Draw the background + painter->setOpacity(d->controller->effectiveOpacity()); + bg->draw(d->backgroundGeometry(), painter); + } +} + +void DuiExtendingBackgroundView::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + // Don't pass mouse events through + event->accept(); +} + +void DuiExtendingBackgroundView::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + // Don't pass mouse events through + event->accept(); +} + +QRectF DuiExtendingBackgroundView::boundingRect() const +{ + Q_D(const DuiExtendingBackgroundView); + + return d->backgroundGeometry(); +} + +DUI_REGISTER_VIEW_NEW(DuiExtendingBackgroundView, DuiWidgetController) diff --git a/src/widgets/views/duiextendingbackgroundview.h b/src/widgets/views/duiextendingbackgroundview.h new file mode 100644 index 000000000..a3e6e9e3e --- /dev/null +++ b/src/widgets/views/duiextendingbackgroundview.h @@ -0,0 +1,72 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIEXTENDINGBACKGROUNDVIEW_H +#define DUIEXTENDINGBACKGROUNDVIEW_H + +#include +#include +#include + +class DuiExtendingBackgroundViewPrivate; + +/*! + * The extending background view draws a background that can extend beyond + * the edges of the bounding rectangle. + */ +class DUI_EXPORT DuiExtendingBackgroundView : public DuiWidgetView +{ + Q_OBJECT + DUI_VIEW(DuiWidgetModel, DuiExtendingBackgroundStyle) + +public: + /*! + * Constructs an DuiExtendingBackgroundView. + * + * \param controller the DuiWidgetController to be used + */ + DuiExtendingBackgroundView(DuiWidgetController *container); + + /*! + * Destroys the DuiExtendingBackgroundView. + */ + virtual ~DuiExtendingBackgroundView(); + +protected: + //! \reimp + virtual QRectF boundingRect() const; + virtual void drawBackground(QPainter *painter, const QStyleOptionGraphicsItem *option) const; + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + //! \reimp_end + + /*! + * Constructs an DuiExtendingBackgroundView. Should be used from derived classes. + * + * \param dd the private class + * \param controller the DuiWidgetController to be used + */ + DuiExtendingBackgroundView(DuiExtendingBackgroundViewPrivate &dd, DuiWidgetController *controller); + +private: + Q_DISABLE_COPY(DuiExtendingBackgroundView) + Q_DECLARE_PRIVATE(DuiExtendingBackgroundView) +}; + +#endif // DUIEXTENDINGBACKGROUNDVIEW_H diff --git a/src/widgets/views/duiextendingbackgroundview_p.h b/src/widgets/views/duiextendingbackgroundview_p.h new file mode 100644 index 000000000..af62630a9 --- /dev/null +++ b/src/widgets/views/duiextendingbackgroundview_p.h @@ -0,0 +1,64 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIEXTENDINGBACKGROUNDVIEW_P_H_ +#define DUIEXTENDINGBACKGROUNDVIEW_P_H_ + +#include "private/duiwidgetview_p.h" + +class DuiWidgetController; +class DuiExtendingBackgroundView; + +/*! + * The private class for DuiExtendingBackgroundView. + */ +class DuiExtendingBackgroundViewPrivate : public DuiWidgetViewPrivate +{ + Q_DECLARE_PUBLIC(DuiExtendingBackgroundView) + +public: + /*! + * Creates an instance of DuiExtendingBackgroundViewPrivate. + */ + DuiExtendingBackgroundViewPrivate(); + + /*! + * Destroys the DuiExtendingBackgroundViewPrivate. + */ + virtual ~DuiExtendingBackgroundViewPrivate(); + + /*! + * Initializes the private class. + * + * \param controller the DuiWidgetController for the view + */ + void init(DuiWidgetController *controller); + + /*! + * Calculates the background geometry. + * + * \return the geometry of the background + */ + QRect backgroundGeometry() const; + + //! The Desktop controller + DuiWidgetController *controller; +}; + +#endif /* DUIEXTENDINGBACKGROUNDVIEW_P_H_ */ diff --git a/src/widgets/views/duifastlistview.cpp b/src/widgets/views/duifastlistview.cpp new file mode 100644 index 000000000..f6c525234 --- /dev/null +++ b/src/widgets/views/duifastlistview.cpp @@ -0,0 +1,342 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "duifastlistview.h" +#include "duifastlistview_p.h" + +//// DuiFastListView ///// +DuiFastListView::DuiFastListView(DuiWidgetController *widgetController) : DuiWidgetView(widgetController), d_ptr(NULL) +{ + controller = dynamic_cast(widgetController); +} + +DuiFastListView::~DuiFastListView() +{ + delete d_ptr; +} + +void DuiFastListView::init() +{ + Q_ASSERT(controller); + + delete d_ptr; + + if (model()->columns() > 1) { + if (model()->showGroups()) + d_ptr = new DuiFastMultiColumnListViewPrivate; + else + d_ptr = new DuiFastPlainMultiColumnListViewPrivate; + } else { + if (model()->showGroups()) + d_ptr = new DuiFastGroupHeaderListViewPrivate; + else + d_ptr = new DuiFastPlainListViewPrivate; + } + + if (model()->showGroups()) + d_ptr->setHeadersCreator(new DuiDefaultHeadersCreator(style()->groupHeaderObjectName())); + + d_ptr->q_ptr = this; + d_ptr->controller = dynamic_cast(controller); + d_ptr->setSeparator(new DuiSeparator); + + connectSelectionModel(); + + d_ptr->resetModel(model()); +} + +void DuiFastListView::updateData(const QList& modifications) +{ + DuiWidgetView::updateData(modifications); + + const char *member; + for (int i = 0; i < modifications.count(); i++) { + member = modifications[i]; + + if (member == DuiListModel::ItemModel || member == DuiListModel::ShowGroups || member == DuiListModel::Columns) { + init(); + updateGeometry(); + } else if (member == DuiListModel::SelectionModel) { + connectSelectionModel(); + } else if (member == DuiListModel::ScrollToIndex) { + scrollTo(model()->scrollToIndex(), static_cast(model()->scrollHint())); + } + } +} + +void DuiFastListView::connectSelectionModel() +{ + disconnect(this, SLOT(selectionChanged(QItemSelection, QItemSelection))); + if (model()->selectionModel()) { + connect(model()->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)), + this, SLOT(selectionChanged(QItemSelection, QItemSelection))); + } +} + +void DuiFastListView::setupModel() +{ + DuiWidgetView::setupModel(); + + init(); + updateGeometry(); +} + +void DuiFastListView::applyStyle() +{ + DuiWidgetView::applyStyle(); + + if (d_ptr) { + d_ptr->updateItemSize(); + d_ptr->setHeadersCreator(new DuiDefaultHeadersCreator(style()->groupHeaderObjectName())); + } +} + +QSizeF DuiFastListView::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const +{ + if (!d_ptr) + return DuiWidgetView::sizeHint(which, constraint); + + return QSizeF(-1, d_ptr->totalHeight()); +} + +void DuiFastListView::setGeometry(const QRectF &rect) +{ + if (d_ptr) { + d_ptr->viewWidth = rect.width(); + d_ptr->updateItemSize(); + d_ptr->updateSeparatorSize(); + relayoutItemsInExposedRect(); + } + + DuiWidgetView::setGeometry(rect); +} + +void DuiFastListView::relayoutItemsInExposedRect() +{ + if (d_ptr->model && model()->cellCreator()) { + QModelIndex firstVisibleRow = d_ptr->locateVisibleIndexAt(d_ptr->viewportTopLeft.y()); + d_ptr->updateFirstVisibleRow(firstVisibleRow); + QModelIndex lastVisibleRow = d_ptr->locateVisibleIndexAt(d_ptr->viewportTopLeft.y() + d_ptr->viewportVisibleHeight); + d_ptr->updateLastVisibleRow(lastVisibleRow); + + QPoint firstVisibleItemPos(0, d_ptr->locatePosOfItem(firstVisibleRow)); + QPoint lastVisibleItemPos(0, d_ptr->locatePosOfItem(lastVisibleRow)); + d_ptr->removeInvisibleItems(firstVisibleItemPos, lastVisibleItemPos); + + if (d_ptr->model->rowCount() > 0) + d_ptr->createVisibleItems(firstVisibleRow, lastVisibleRow); + } +} + +void DuiFastListView::drawForeground(QPainter *painter, const QStyleOptionGraphicsItem *option) const +{ + Q_UNUSED(painter); + + QRectF exposedRect(option->exposedRect); + if ((d_ptr->viewportTopLeft != exposedRect.topLeft()) || (d_ptr->viewportVisibleHeight < exposedRect.height()) || (d_ptr->forceRepaint)) { + d_ptr->forceRepaint = false; + + d_ptr->viewportTopLeft = exposedRect.topLeft(); + if (d_ptr->viewportVisibleHeight < exposedRect.height()) + d_ptr->viewportVisibleHeight = exposedRect.height(); + + d_ptr->exposedRectChanged(exposedRect); + const_cast(this)->relayoutItemsInExposedRect(); + } +} + +void DuiFastListView::drawBackground(QPainter *painter, const QStyleOptionGraphicsItem *option) const +{ + Q_UNUSED(option); + + // Temporarely disable separator drawing when group headers are shown + if (d_ptr->separator->boundingRect().height() == 0 || model()->showGroups()) + return; + + // TODO move this code to private class + for (int currentRow = model()->firstVisibleItem().row(); currentRow <= model()->lastVisibleItem().row(); currentRow++) { + if (currentRow == 0) + continue; + + QPointF itemPos(0, d_ptr->locatePosOfItem(currentRow)); + int separatorPos = itemPos.y() - d_ptr->separator->boundingRect().height(); + + painter->translate(0, separatorPos); + d_ptr->separator->paint(painter, option); + painter->translate(0, -separatorPos); + } +} + +void DuiFastListView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) +{ + if (!model()->firstVisibleItem().isValid() && !model()->lastVisibleItem().isValid()) + return; + + const DuiCellCreator *cellCreator = model()->cellCreator(); + + int firstVisibleRow = d_ptr->indexToFlatRow(model()->firstVisibleItem()); + int lastVisibleRow = d_ptr->indexToFlatRow(model()->lastVisibleItem()); + int topLeftRow = d_ptr->indexToFlatRow(topLeft); + int bottomRightRow = d_ptr->indexToFlatRow(bottomRight); + + int top = qMax(topLeftRow, firstVisibleRow); + int bottom = qMin(bottomRightRow, lastVisibleRow); + + for (int i = top; i <= bottom; i++) { + QModelIndex cellIndex = d_ptr->flatRowToIndex(i); + if (!d_ptr->isGroupHeader(cellIndex)) { + DuiWidget *cell = d_ptr->findCellAtRow(i); + cellCreator->updateCell(cellIndex, cell); + } + } +} + +/*! + * This slot is called when items are inserted under the given \a parent. + * The changed items are those from \a start to \a end inclusive. + * + * \sa QAbstractItemView::rowsInserted(), exposedRectUpdated() + */ +void DuiFastListView::rowsInserted(const QModelIndex &parent, int start, int end) +{ + Q_UNUSED(parent); + Q_UNUSED(start); + Q_UNUSED(end); + // updateGeometry adjusts container scroll bars and reposition cells + updateGeometry(); + + // if rows are inserted in visible chunk, update cells + QAbstractItemModel *itemModel = model()->itemModel(); + if (itemModel) { + d_ptr->clearVisibleItemsArray(); + d_ptr->createVisibleItems(start, end); + // using itemModel->index instead of parent.child() - parent is usually empty for lists + // TODO list with multiple columns? + int itemCount = itemModel->rowCount(parent); + // If we inserted somewhere in the middle, we should update all items after insertion point + dataChanged(itemModel->index(start, 0, parent), itemModel->index(itemCount, 0, parent)); + } +} + +/*! + * This slot is called when items under the given \a parent are removed. + * The removed items are those from \a start to \a end inclusive. + * + * \sa rowsInserted(), exposedRectUpdated() + */ +void DuiFastListView::rowsRemoved(const QModelIndex &parent, int start, int end) +{ + Q_UNUSED(parent); + Q_UNUSED(start); + Q_UNUSED(end); + + layoutChanged(); +} + +void DuiFastListView::layoutChanged() +{ + relayoutItemsInExposedRect(); + dataChanged(model()->firstVisibleItem(), model()->lastVisibleItem()); +} + +void DuiFastListView::modelReset() +{ + layoutChanged(); +} + +void DuiFastListView::rowsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, + const QModelIndex &destinationParent, int destinationRow) +{ + Q_UNUSED(sourceParent); + Q_UNUSED(sourceStart); + Q_UNUSED(sourceEnd); + Q_UNUSED(destinationParent); + Q_UNUSED(destinationRow); + + layoutChanged(); +} + +void DuiFastListView::selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) +{ + d_ptr->selectionChange(selected, deselected); +} + +void DuiFastListView::itemClick() +{ + QObject *s = sender(); + DuiWidget *senderWidget = qobject_cast(s); + if (senderWidget) + d_ptr->cellClicked(senderWidget); +} + +void DuiFastListView::scrollTo(const QModelIndex &index, DuiList::ScrollHint hint) +{ + if (index.isValid()) { + int cellPosition = d_ptr->locatePosOfItem(index); + + DuiPannableViewport *pannableViewport = + DuiFastListViewPrivateNamespace::findParentWidgetOfType(controller); + + if (pannableViewport) { + QPointF targetPosition = pannableViewport->position(); + QPointF listPosition(controller->mapToItem(pannableViewport->widget(), 0, 0)); + + qreal pannableViewportHeight = pannableViewport->boundingRect().height(); + switch (hint) { + case DuiList::PositionAtTopHint: + targetPosition.setY(controller->pos().y() + cellPosition); + break; + + case DuiList::PositionAtBottomHint: + targetPosition.setY(cellPosition + d_ptr->itemHeight + listPosition.y() - pannableViewportHeight); + break; + + case DuiList::PositionAtCenterHint: + targetPosition.setY(listPosition.y() + cellPosition + d_ptr->itemHeight / 2 - pannableViewportHeight / 2); + break; + + case DuiList::EnsureVisibleHint: + if (cellPosition < d_ptr->viewportTopLeft.y()) { + targetPosition.setY(controller->pos().y() + cellPosition); + } else if (cellPosition + d_ptr->itemHeight > d_ptr->viewportTopLeft.y() + pannableViewportHeight) { + targetPosition.setY(cellPosition + d_ptr->itemHeight + listPosition.y() - pannableViewportHeight); + } + + break; + } + + targetPosition.setY(qMax(targetPosition.y(), (qreal)0)); + targetPosition.setY(qMin(targetPosition.y(), pannableViewport->widget()->boundingRect().height() - pannableViewportHeight)); + + pannableViewport->setPosition(targetPosition); + } + } +} + +DUI_REGISTER_VIEW_NEW(DuiFastListView, DuiList) diff --git a/src/widgets/views/duifastlistview.h b/src/widgets/views/duifastlistview.h new file mode 100644 index 000000000..c60c4e3ca --- /dev/null +++ b/src/widgets/views/duifastlistview.h @@ -0,0 +1,79 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIFASTLISTVIEW_H__ +#define DUIFASTLISTVIEW_H__ + +#include +#include +#include +#include + +class DuiController; +class DuiList; +class DuiListModel; +class DuiFastListViewPrivate; + +class DUI_EXPORT DuiFastListView : public DuiWidgetView +{ + Q_OBJECT + DUI_VIEW(DuiListModel, DuiListStyle) + +public: + DuiFastListView(DuiWidgetController *controller); + virtual ~DuiFastListView(); + + virtual void setGeometry(const QRectF &rect); + virtual QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const; + +public slots: + void relayoutItemsInExposedRect(); + +protected: + virtual void drawForeground(QPainter *painter, const QStyleOptionGraphicsItem *option) const; + virtual void drawBackground(QPainter *painter, const QStyleOptionGraphicsItem *option) const; + +protected slots: + virtual void updateData(const QList& modifications); + void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight); + void rowsInserted(const QModelIndex &parent, int start, int end); + void rowsRemoved(const QModelIndex &parent, int start, int end); + void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected); + void itemClick(); + void layoutChanged(); + void modelReset(); + void rowsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, + const QModelIndex &destinationParent, int destinationRow); + +protected: + virtual void setupModel(); + virtual void applyStyle(); + +private: + void init(); + void connectSelectionModel(); + void scrollTo(const QModelIndex &index, DuiList::ScrollHint hint); + +private: + DuiFastListViewPrivate *d_ptr; + DuiList *controller; + friend class DuiFastListViewPrivate; +}; + +#endif diff --git a/src/widgets/views/duifastlistview_p.cpp b/src/widgets/views/duifastlistview_p.cpp new file mode 100644 index 000000000..9bb5cb382 --- /dev/null +++ b/src/widgets/views/duifastlistview_p.cpp @@ -0,0 +1,922 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include + +#include + +#include "duicontentitem.h" +#include "duiabstractcellcreator.h" +#include "duifastlistview_p.h" + +#include "duifastlistview.h" + +using namespace DuiFastListViewPrivateNamespace; + +static const int MOVINGDETECTORTIMEOUT = 500; + +DuiFastListViewPrivate::DuiFastListViewPrivate() : recycler(new DuiWidgetRecycler) +{ + itemHeight = 0; + viewWidth = 0; + model = NULL; + moving = false; + separator = NULL; + headersCreator = NULL; + hdrHeight = NULL; + forceRepaint = false; + viewportTopLeft = QPointF(); + viewportVisibleHeight = 0; + movingDetectorTimer.setSingleShot(true); + connect(&movingDetectorTimer, SIGNAL(timeout()), this, SLOT(movingDetectionTimerTimeout())); +} + +DuiFastListViewPrivate::~DuiFastListViewPrivate() +{ + clearVisibleItemsArray(); + movingDetectorTimer.stop(); + delete headersCreator; + delete separator; + delete recycler; +} + +void DuiFastListViewPrivate::setSeparator(DuiWidget *separator) +{ + this->separator = separator; +} + +void DuiFastListViewPrivate::setHeadersCreator(DuiCellCreator *creator) +{ + delete headersCreator; + headersCreator = creator; +} + +void DuiFastListViewPrivate::movingDetectionTimerTimeout() +{ + moving = false; + controllerModel->setListIsMoving(false); + movingDetectorTimer.stop(); +} + +void DuiFastListViewPrivate::clearVisibleItemsArray() +{ + foreach(DuiWidget * item, visibleItems) { + deleteItem(item); + } + + visibleItems.clear(); +} + +void DuiFastListViewPrivate::cellClicked(DuiWidget *source) +{ + DuiWidget *widget = source; + QModelIndex cellIndex(locateVisibleIndexAt(widget->pos().y())); + controller->selectItem(cellIndex); +} + +void DuiFastListViewPrivate::selectionChange(const QItemSelection &selected, const QItemSelection &deselected) +{ + foreach(DuiWidget * widget, visibleItems) { + // TODO convert into hashmap + QModelIndex widgetIndex(locateVisibleIndexAt(widget->y())); + if (selected.contains(widgetIndex)) + widget->setSelected(true); + if (deselected.contains(widgetIndex)) + widget->setSelected(false); + } +} + +void DuiFastListViewPrivate::deleteItem(DuiWidget *widget) +{ + recycler->recycle(widget); +} + +DuiWidget *DuiFastListViewPrivate::createCell(int row) +{ + const DuiCellCreator *cellCreator = controllerModel->cellCreator(); + QModelIndex index(flatRowToIndex(row)); + DuiWidget *cell = cellCreator->createCell(index, *recycler); + cell->setParent(NULL); + cell->setParentItem(controller); + cell->setVisible(true); + cell->resize(viewWidth, cell->preferredHeight()); + + // TODO this is not optimal, I'm pretty sure, need to find better way to keep + // selection. Refactor into it's own function. + QItemSelectionModel *selectionModel = controllerModel->selectionModel(); + cell->setSelected(selectionModel->isSelected(index)); + + // TODO this code can be executed only when panning is stopped. Refactor into + // it's own function + if (cell->metaObject()->indexOfSignal("clicked()") != -1) { + QObject::connect(cell, SIGNAL(clicked()), q_ptr, SLOT(itemClick()), Qt::UniqueConnection); + } + + return cell; +} + +void DuiFastListViewPrivate::exposedRectChanged(const QRectF &exposedRect) +{ + if (exposedRect.topLeft() != oldExposedRectPosition) { + movingDetectorTimer.start(MOVINGDETECTORTIMEOUT); + + if (!moving) { + moving = true; + controllerModel->setListIsMoving(true); + } + + oldExposedRectPosition = exposedRect.topLeft(); + } +} + +void DuiFastListViewPrivate::updateItemHeight() +{ + const DuiCellCreator *cellCreator = controller->cellCreator(); + if (cellCreator) + itemHeight = cellCreator->cellSize().height(); +} + +void DuiFastListViewPrivate::removeInvisibleItems(const QPoint &firstVisibleItemCoord, + const QPoint &lastVisibleItemCoord) +{ + for (QVector::iterator iter = visibleItems.begin(); iter != visibleItems.end();) { + DuiWidget *cell = *iter; + qreal cellPosY = cell->pos().y(); + + if (cellPosY < firstVisibleItemCoord.y() || cellPosY > lastVisibleItemCoord.y()) { + deleteItem(*iter); + iter = visibleItems.erase(iter); + } else { + ++iter; + } + } +} + +DuiWidget *DuiFastListViewPrivate::findCellAtRow(int row) +{ + foreach(DuiWidget * widget, visibleItems) { + QPointF pos(widget->pos()); + int widgetRow = locateVisibleRowAt(pos.y(), pos.x()); + if (widgetRow == row) + return widget; + } + + return NULL; +} + +void DuiFastListViewPrivate::createVisibleItems(int firstVisibleRow, int lastVisibleRow) +{ + for (int currentRow = firstVisibleRow; currentRow <= lastVisibleRow; currentRow++) { + DuiWidget *existingCell = findCellAtRow(currentRow); + if (existingCell != NULL) + continue; + + DuiWidget *cell = createItem(currentRow); + visibleItems.append(cell); + cell->setPos(QPointF(0, locatePosOfItem(currentRow))); + } +} + +void DuiFastListViewPrivate::resetModel(DuiListModel *duiListModel) +{ + forceRepaint = true; + + disconnect(q_ptr, SLOT(dataChanged(QModelIndex, QModelIndex))); + disconnect(q_ptr, SLOT(rowsInserted(QModelIndex, int, int))); + disconnect(q_ptr, SLOT(rowsRemoved(QModelIndex, int, int))); + disconnect(q_ptr, SLOT(layoutChanged())); + disconnect(q_ptr, SLOT(modelReset())); + disconnect(q_ptr, SLOT(rowsMoved(QModelIndex, int, int, QModelIndex, int))); + + controllerModel = duiListModel; + model = duiListModel->itemModel(); + clearVisibleItemsArray(); + updateItemHeight(); + updateFirstVisibleRow(QModelIndex()); + updateLastVisibleRow(QModelIndex()); + + if (model) { + connect(model, SIGNAL(dataChanged(QModelIndex, QModelIndex)), q_ptr, SLOT(dataChanged(QModelIndex, QModelIndex))); + connect(model, SIGNAL(rowsInserted(QModelIndex, int, int)), q_ptr, SLOT(rowsInserted(QModelIndex, int, int))); + connect(model, SIGNAL(rowsRemoved(QModelIndex, int, int)), q_ptr, SLOT(rowsRemoved(QModelIndex, int, int))); + connect(model, SIGNAL(layoutChanged()), q_ptr, SLOT(layoutChanged())); + connect(model, SIGNAL(modelReset()), q_ptr, SLOT(modelReset())); + connect(model, SIGNAL(rowsMoved(QModelIndex, int, int, QModelIndex, int)), q_ptr, SLOT(rowsMoved(QModelIndex, int, int, QModelIndex, int))); + } +} + +void DuiFastListViewPrivate::updateItemSize() +{ + foreach(DuiWidget * cell, visibleItems) { + cell->resize(viewWidth, cell->preferredHeight()); + } +} + +void DuiFastListViewPrivate::updateSeparatorSize() +{ + QRectF separatorBoundingRect(separator->boundingRect()); + separator->setGeometry(QRectF(QPointF(0, 0), QSizeF(viewWidth, separatorBoundingRect.height()))); +} + +void DuiFastListViewPrivate::updateFirstVisibleRow(const QModelIndex &index) +{ + controllerModel->setFirstVisibleItem(index); +} + +void DuiFastListViewPrivate::updateLastVisibleRow(const QModelIndex &index) +{ + controllerModel->setLastVisibleItem(index); +} + +bool DuiFastListViewPrivate::isGroupHeader(const QModelIndex &index) +{ + Q_UNUSED(index); + + return false; +} + +//////////// +// Plain list +//////////// +DuiFastPlainListViewPrivate::DuiFastPlainListViewPrivate() +{ + +} + +DuiFastPlainListViewPrivate::~DuiFastPlainListViewPrivate() +{ + +} + +int DuiFastPlainListViewPrivate::separatorsCount() const +{ + return itemsCount() - 1; +} + +int DuiFastPlainListViewPrivate::totalHeight() +{ + int itemsCount = this->itemsCount(); + int separatorHeight = separator->boundingRect().height(); + int separatorsCount = this->separatorsCount(); + int totalHeight = itemsCount * itemHeight + separatorsCount * separatorHeight; + return totalHeight; +} + +int DuiFastPlainListViewPrivate::itemsCount() const +{ + if (model == 0) + return NULL; + + return model->rowCount(); +} + +DuiWidget *DuiFastPlainListViewPrivate::createItem(int row) +{ + return createCell(row); +} + +int DuiFastPlainListViewPrivate::indexToFlatRow(const QModelIndex &index) const +{ + return index.row(); +} + +QModelIndex DuiFastPlainListViewPrivate::flatRowToIndex(int row) const +{ + return model->index(row, 0); +} + +int DuiFastPlainListViewPrivate::locateVisibleRowAt(int y, int x) +{ + Q_UNUSED(x); + // Formula for calculating position of specific row is following: + // row * itemHeight + (row - 1) * separatorHeight = pos + // to calculate row lets do basic math: + // row = (pos + separatorHeight) / (itemHeight + separatorHeight) + // since row is integer, we need to round it properly, so adding half height of item + int separatorHeight = separator->boundingRect().height(); + int row = (y + (itemHeight / 2) + separatorHeight) / (itemHeight + separatorHeight); + + int modelRowCount = model->rowCount(); + if (row >= modelRowCount) + row = modelRowCount - 1; + + return row; +} + +// TODO write unit test for this +int DuiFastPlainListViewPrivate::locatePosOfItem(int row) +{ + int itemHeights = row * itemHeight; + int separatorHeights = 0; + if (row > 0) + separatorHeights = row * separator->boundingRect().height(); + + return itemHeights + separatorHeights; +} + +int DuiFastPlainListViewPrivate::locatePosOfItem(const QModelIndex &index) +{ + return locatePosOfItem(index.row()); +} + +QModelIndex DuiFastPlainListViewPrivate::locateVisibleIndexAt(int pos) +{ + int row = locateVisibleRowAt(pos); + if (row < 0) + return model->index(0, 0); + + return model->index(row, 0); +} + +void DuiFastPlainListViewPrivate::createVisibleItems(const QModelIndex &firstVisibleRow, + const QModelIndex &lastVisibleRow) +{ + DuiFastListViewPrivate::createVisibleItems(firstVisibleRow.row(), lastVisibleRow.row()); +} + +//////////// +// MultiColumn without group headers +//////////// +DuiFastPlainMultiColumnListViewPrivate::DuiFastPlainMultiColumnListViewPrivate() +{ +} + +DuiFastPlainMultiColumnListViewPrivate::~DuiFastPlainMultiColumnListViewPrivate() +{ +} + +int DuiFastPlainMultiColumnListViewPrivate::itemsToRows(int items) const +{ + int columns = controllerModel->columns(); + int rows = items / columns; + if (items > rows * columns) + rows++; + + return rows; +} + +int DuiFastPlainMultiColumnListViewPrivate::flatRowToColumn(int row) const +{ + int columns = controllerModel->columns(); + int itemRow = row / columns; + int flatRowColumn = row - itemRow * columns; + + return flatRowColumn; +} + +int DuiFastPlainMultiColumnListViewPrivate::locatePosOfItem(int row) +{ + int columns = controllerModel->columns(); + int rows = row / columns; + int itemHeights = rows * itemHeight; + int separatorHeights = 0; + if (rows > 0) + separatorHeights = rows * separator->boundingRect().height(); + + return itemHeights + separatorHeights; +} + +int DuiFastPlainMultiColumnListViewPrivate::totalHeight() +{ + int rowsCount = itemsToRows(itemsCount()); + int separatorHeight = separator->boundingRect().height(); + int separatorsCount = this->separatorsCount(); + int totalHeight = rowsCount * itemHeight + separatorsCount * separatorHeight; + return totalHeight; +} + +DuiWidget *DuiFastPlainMultiColumnListViewPrivate::createItem(int row) +{ + DuiWidget *cell = createCell(row); + cell->resize(viewWidth / controllerModel->columns(), cell->preferredHeight()); + + return cell; +} + +int DuiFastPlainMultiColumnListViewPrivate::locateVisibleRowAt(int y, int x) +{ + int separatorHeight = separator->boundingRect().height(); + int columns = controllerModel->columns(); + int row = y * columns / (separatorHeight + itemHeight); + + if (row >= itemsCount()) + row = itemsCount() - 1; + + int column = 0; + if (viewWidth) + column = x / (viewWidth / columns); + + return row + column; +} + +void DuiFastPlainMultiColumnListViewPrivate::updateItemSize() +{ + int columns = controllerModel->columns(); + int columnWidth = viewWidth / columns; + + foreach(DuiWidget * cell, visibleItems) { + int cellFlatRow = widgetFlatRows[cell]; + int cellColumn = flatRowToColumn(cellFlatRow); + cell->resize(columnWidth, cell->preferredHeight()); + cell->setPos(QPointF(cellColumn * columnWidth, cell->pos().y())); + } +} + +void DuiFastPlainMultiColumnListViewPrivate::cellClicked(DuiWidget *source) +{ + int clickedFlatRow = widgetFlatRows.value(source); + QModelIndex cellIndex(flatRowToIndex(clickedFlatRow)); + controller->selectItem(cellIndex); +} + +void DuiFastPlainMultiColumnListViewPrivate::selectionChange(const QItemSelection &selected, const QItemSelection &deselected) +{ + foreach(DuiWidget * widget, visibleItems) { + int widgetFlatRow = widgetFlatRows.value(widget); + QModelIndex widgetIndex(flatRowToIndex(widgetFlatRow)); + if (selected.contains(widgetIndex)) + widget->setSelected(true); + if (deselected.contains(widgetIndex)) + widget->setSelected(false); + } +} + +void DuiFastPlainMultiColumnListViewPrivate::createVisibleItems(const QModelIndex &firstVisibleRow, + const QModelIndex &lastVisibleRow) +{ + if (!viewWidth) // required for x position + return; + + int firstRow = firstVisibleRow.row(); + int lastRow = lastVisibleRow.row(); + + for (int currentRow = firstRow; currentRow <= lastRow; currentRow++) { + DuiWidget *cell = findCellAtRow(currentRow); + if (!cell && flatRowToColumn(currentRow) == 0) { + + // Create widgets to all columns in this row + for (int column = 0; column < controllerModel->columns(); ++column) { + cell = createItem(currentRow + column); + visibleItems.append(cell); + widgetFlatRows[cell] = currentRow + column; + cell->setPos(QPointF(column*(viewWidth / controllerModel->columns()), locatePosOfItem(currentRow + column))); + if (currentRow + column + 1 == itemsCount() || flatRowToColumn(currentRow + column + 1) == 0) + break; + } + } + } +} + +//////////// +// Group Header +//////////// +DuiFastGroupHeaderListViewPrivate::DuiFastGroupHeaderListViewPrivate() +{ + +} + +DuiFastGroupHeaderListViewPrivate::~DuiFastGroupHeaderListViewPrivate() +{ + +} + +void DuiFastGroupHeaderListViewPrivate::createVisibleItems(const QModelIndex &firstVisibleRow, + const QModelIndex &lastVisibleRow) +{ + DuiFastListViewPrivate::createVisibleItems(indexToFlatRow(firstVisibleRow), indexToFlatRow(lastVisibleRow)); +} + +QModelIndex DuiFastGroupHeaderListViewPrivate::locateVisibleIndexAt(int pos) +{ + int row = locateVisibleRowAt(pos); + if (row < 0) + return model->index(0, 0); + + return flatRowToIndex(row); +} + +int DuiFastGroupHeaderListViewPrivate::separatorsCount() const +{ + int itemsCount = this->headersCount(); + int seperators = 0; + for (int i = 0; i < itemsCount; i++) { + int itemsCountInGroup = this->itemsCount(i); + if (itemsCountInGroup == 0) + continue; + + seperators += itemsCountInGroup - 1; + } + + return seperators; +} + +void DuiFastGroupHeaderListViewPrivate::resetModel(DuiListModel *duiListModel) +{ + DuiFastListViewPrivate::resetModel(duiListModel); + + headersPositions.resize(this->headersCount()); + updateHeadersPositions(); + updateHeadersRows(); +} + +int DuiFastGroupHeaderListViewPrivate::locatePosOfItem(const QModelIndex &index) +{ + if (index.parent().isValid()) { + return locatePosOfItem(index.parent().row(), index.row()); + } else { + return locatePosOfItem(index.row(), -1); + } +} + +int DuiFastGroupHeaderListViewPrivate::locatePosOfItem(int headerIndex, int itemIndex) +{ + if (itemIndex == -1) { + // we hitted header + return headersPositions[headerIndex]; + } + + int pos = headersPositions[headerIndex] + headerHeight(); + if (itemIndex == 0) + return pos; + + int itemHeights = itemIndex * itemHeight; + int separatorHeight = separator->boundingRect().height(); + int separatorHeights = 0; + separatorHeights = itemIndex * separatorHeight; + + pos += separatorHeights + itemHeights; + return pos; +} + +int DuiFastGroupHeaderListViewPrivate::locatePosOfItem(int row) +{ + int headerIndex = dFindLowerIndex(headersRows, row); + int relativeRow = row - headersRows[headerIndex] - 1; // we have to subtruct header + return locatePosOfItem(headerIndex, relativeRow); +} + +int DuiFastGroupHeaderListViewPrivate::locateVisibleRowAt(int y, int x) +{ + Q_UNUSED(x); + int headerIndex = dFindLowerIndex(headersPositions, y); + + int headerPosition = headersPositions[headerIndex]; + int headerRow = headersRows[headerIndex]; + int relativePos = y - headerPosition; + int headerHeight = this->headerHeight(); + if (relativePos < headerHeight) + return headerRow; + + int separatorHeight = separator->boundingRect().height(); + int row = (relativePos + (itemHeight / 2) + separatorHeight - headerHeight) / (itemHeight + separatorHeight); + return headerRow + row + 1; +} + +QModelIndex DuiFastGroupHeaderListViewPrivate::flatRowToIndex(int row) const +{ + if (!headersRows.contains(row)) { + int headerIndex = dFindLowerIndex(headersRows, row); + QModelIndex parent(model->index(headerIndex, 0)); + int relativeRow = row - headersRows[headerIndex] - 1; + int itemsCount = this->itemsCount(headerIndex); + if (relativeRow >= itemsCount) + relativeRow = itemsCount - 1; + QModelIndex index(model->index(relativeRow, 0, parent)); + return index; + } + + int headerIndex = headersRows.indexOf(row); + return model->index(headerIndex, 0); +} + +void DuiFastGroupHeaderListViewPrivate::updateHeadersPositions() +{ + int headersCount = this->headersCount(); + + headersPositions.clear(); + if (headersCount == 0) + return; + + int headerHeight = this->headerHeight(); + headersPositions << 0; + int previousIndexPosition = 0; + for (int i = 1; i < headersCount; i++) { + int groupSize = this->groupSize(i - 1); + headersPositions << previousIndexPosition + headerHeight + groupSize; + previousIndexPosition += headerHeight + groupSize; + } +} + +void DuiFastGroupHeaderListViewPrivate::updateHeadersRows() +{ + int headersCount = this->headersCount(); + + headersRows.clear(); + if (headersCount == 0) + return; + + headersRows << 0; + int prevGroupSize = 0; + for (int i = 1; i < headersCount; i++) { + prevGroupSize += itemsCount(i - 1); + headersRows << (i + prevGroupSize); + } +} + +int DuiFastGroupHeaderListViewPrivate::indexToFlatRow(const QModelIndex &index) const +{ + if (!index.isValid()) + return -1; + + if (index.parent().isValid()) { + // always need to add 1 because of parent. + return headersRows[index.parent().row()] + index.row() + 1; + } + + return headersRows[index.row()]; +} + +DuiWidget *DuiFastGroupHeaderListViewPrivate::createItem(int row) +{ + if (!headersRows.contains(row)) { + return createCell(row); + } else { + int headerIndex = dFindLowerIndex(headersRows, row); + return createHeader(headerIndex); + } +} + +DuiWidget *DuiFastGroupHeaderListViewPrivate::createHeader(int headerIndex) +{ + DuiWidget *header = headersCreator->createCell(model->index(headerIndex, 0), *recycler); + header->setParent(NULL); + header->setParentItem(controller); + header->setVisible(true); + header->resize(viewWidth, header->preferredHeight()); + return header; +} + +int DuiFastGroupHeaderListViewPrivate::headerHeight() +{ + if (!hdrHeight) { + DuiWidget *header = createHeader(0); + hdrHeight = header->boundingRect().height(); + deleteItem(header); + } + return hdrHeight; +} + +int DuiFastGroupHeaderListViewPrivate::headersCount() const +{ + return model->rowCount(); +} + +int DuiFastGroupHeaderListViewPrivate::itemsCount(int headerIndex) const +{ + QModelIndex index(model->index(headerIndex, 0)); + return model->rowCount(index); +} + +int DuiFastGroupHeaderListViewPrivate::itemsCount() const +{ + if (!controllerModel->showGroups()) + return model->rowCount(); + + int groupsCount = model->rowCount(); + int totalItemsCount = 0; + for (int i = 0; i < groupsCount; i++) { + totalItemsCount += itemsCount(i); + } + + return totalItemsCount; +} + +int DuiFastGroupHeaderListViewPrivate::groupSize(int headerIndex) const +{ + int itemsCount = this->itemsCount(headerIndex); + return ((itemsCount * itemHeight) + (itemsCount - 1) * separator->boundingRect().height()); +} + +int DuiFastGroupHeaderListViewPrivate::totalHeight() +{ + int headersCount = this->headersCount(); + int itemsCount = this->itemsCount(); + int separatorHeight = separator->boundingRect().height(); + int separatorsCount = this->separatorsCount(); + int totalHeight = headersCount * headerHeight() + itemsCount * itemHeight + separatorsCount * separatorHeight; + return totalHeight; +} + +bool DuiFastGroupHeaderListViewPrivate::isGroupHeader(const QModelIndex &index) +{ + return !index.parent().isValid(); +} + +void DuiFastGroupHeaderListViewPrivate::createVisibleItems(int firstVisibleRow, int lastVisibleRow) +{ + DuiFastListViewPrivate::createVisibleItems(firstVisibleRow, lastVisibleRow); + updateHeadersPositions(); + updateHeadersRows(); +} + +//////////// +// MultiColumn with group headers +//////////// + +DuiFastMultiColumnListViewPrivate::DuiFastMultiColumnListViewPrivate() +{ +} + +DuiFastMultiColumnListViewPrivate::~DuiFastMultiColumnListViewPrivate() +{ +} + +int DuiFastMultiColumnListViewPrivate::itemsToRows(int items) const +{ + int columns = controllerModel->columns(); + int rows = items / columns; + if (items > rows * columns) + rows++; + + return rows; +} + +int DuiFastMultiColumnListViewPrivate::rowsInGroup(int headerIndex) const +{ + int itemsInGroup = itemsCount(headerIndex); + int rowsInGroup = itemsToRows(itemsInGroup); + + return rowsInGroup; +} + +int DuiFastMultiColumnListViewPrivate::flatRowToColumn(int row) const +{ + if (headersRows.contains(row)) + return 0; // group headers are always in column 0 + + int headerIndex = dFindLowerIndex(headersRows, row); + int relativeRow = row - headersRows[headerIndex] - 1; + int columns = controllerModel->columns(); + int itemRow = relativeRow / columns; + int flatRowColumn = relativeRow - itemRow * columns; + + return flatRowColumn; +} + +void DuiFastMultiColumnListViewPrivate::updateItemSize() +{ + int columns = controllerModel->columns(); + int columnWidth = viewWidth / columns; + + foreach(DuiWidget * cell, visibleItems) { + int cellFlatRow = widgetFlatRows[cell]; + int cellColumn = flatRowToColumn(cellFlatRow); + cell->resize(columnWidth, cell->preferredHeight()); + cell->setPos(QPointF(cellColumn * columnWidth, cell->pos().y())); + } +} + +void DuiFastMultiColumnListViewPrivate::cellClicked(DuiWidget *source) +{ + int clickedFlatRow = widgetFlatRows.value(source); + QModelIndex cellIndex(flatRowToIndex(clickedFlatRow)); + controller->selectItem(cellIndex); +} + +void DuiFastMultiColumnListViewPrivate::selectionChange(const QItemSelection &selected, const QItemSelection &deselected) +{ + foreach(DuiWidget * widget, visibleItems) { + int widgetFlatRow = widgetFlatRows.value(widget); + QModelIndex widgetIndex(flatRowToIndex(widgetFlatRow)); + if (selected.contains(widgetIndex)) + widget->setSelected(true); + if (deselected.contains(widgetIndex)) + widget->setSelected(false); + } +} + +void DuiFastMultiColumnListViewPrivate::createVisibleItems(const QModelIndex &firstVisibleRow, + const QModelIndex &lastVisibleRow) +{ + if (!viewWidth) // required for x position + return; + + int firstRow = indexToFlatRow(firstVisibleRow); + int lastRow = indexToFlatRow(lastVisibleRow); + + for (int currentRow = firstRow; currentRow <= lastRow; currentRow++) { + DuiWidget *cell = findCellAtRow(currentRow); + if (!cell && flatRowToColumn(currentRow) == 0) { + + // Create widgets to all columns in this row + for (int column = 0; column < controllerModel->columns(); ++column) { + cell = createItem(currentRow + column); + visibleItems.append(cell); + widgetFlatRows[cell] = currentRow + column; + cell->setPos(QPointF(column*(viewWidth / controllerModel->columns()), locatePosOfItem(currentRow + column))); + if (currentRow + column + 1 == itemsCount() + model->rowCount() || flatRowToColumn(currentRow + column + 1) == 0) + break; + } + } + } +} + +int DuiFastMultiColumnListViewPrivate::locatePosOfItem(int headerIndex, int itemIndex) +{ + if (itemIndex == -1) + return headersPositions[headerIndex]; + + int pos = headersPositions[headerIndex] + headerHeight(); + if (itemIndex == 0) + return pos; + + int rows = itemsToRows(itemIndex + 1) - 1; // rows after the 1st one + int itemHeights = rows * itemHeight; + int separatorHeights = rows * separator->boundingRect().height(); + pos += separatorHeights + itemHeights; + + return pos; +} + +int DuiFastMultiColumnListViewPrivate::locatePosOfItem(int row) +{ + int headerIndex = dFindLowerIndex(headersRows, row); + int relativeRow = row - headersRows[headerIndex] - 1; + + return locatePosOfItem(headerIndex, relativeRow); +} + +int DuiFastMultiColumnListViewPrivate::locatePosOfItem(const QModelIndex &index) +{ + return DuiFastGroupHeaderListViewPrivate::locatePosOfItem(index); +} + +int DuiFastMultiColumnListViewPrivate::locateVisibleRowAt(int y, int x) +{ + Q_UNUSED(x); + int headerIndex = dFindLowerIndex(headersPositions, y); + int headerRow = headersRows[headerIndex]; + int relativePos = y - headersPositions[headerIndex]; + int headerHeight = this->headerHeight(); + if (relativePos < headerHeight) + return headerRow; + + relativePos -= headerHeight; + int separatorHeight = separator->boundingRect().height(); + int columns = controllerModel->columns(); + + // row/columns * itemHeight + row/columns * separatorHeight = pos -> r/c*i + r/c*s = p -> r = p*c/(s+i) + int row = relativePos * columns / (separatorHeight + itemHeight); + int column = 0; + if (viewWidth) + column = x / (viewWidth / columns); + return headerRow + row + column + 1; +} + +DuiWidget *DuiFastMultiColumnListViewPrivate::createItem(int row) +{ + if (!headersRows.contains(row)) { + DuiWidget *cell = createCell(row); + cell->resize(viewWidth / controllerModel->columns(), cell->preferredHeight()); + return cell; + } else { + int headerIndex = dFindLowerIndex(headersRows, row); + return createHeader(headerIndex); + } +} + +int DuiFastMultiColumnListViewPrivate::groupSize(int headerIndex) const +{ + int rows = rowsInGroup(headerIndex); + int groupSize = rows * itemHeight + (rows - 1) * separator->boundingRect().height(); + + return groupSize; +} + +int DuiFastMultiColumnListViewPrivate::totalHeight() +{ + int totalHeight = 0; + for (int i = 0; i < headersCount(); ++i) { + totalHeight += headerHeight() + groupSize(i); + } + + return totalHeight; +} diff --git a/src/widgets/views/duifastlistview_p.h b/src/widgets/views/duifastlistview_p.h new file mode 100644 index 000000000..1e0d203bb --- /dev/null +++ b/src/widgets/views/duifastlistview_p.h @@ -0,0 +1,303 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIFASTLISTVIEWPRIVATE_H__ +#define DUIFASTLISTVIEWPRIVATE_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "duiabstractcellcreator.h" +#include "private/duiwidgetview_p.h" + +class DuiWidget; +class DuiFastListView; +class DuiList; +class DuiListModel; +class DuiWidgetRecycler; +class QAbstractItemModel; +class QItemSelectionModel; +class QItemSelection; + +namespace DuiFastListViewPrivateNamespace +{ + template + T *findParentWidgetOfType(QGraphicsItem *widget) + { + T *targetWidget = NULL; + QGraphicsWidget *parentWidget = widget->parentWidget(); + while (parentWidget && targetWidget == NULL) { + targetWidget = qobject_cast(parentWidget); + parentWidget = parentWidget->parentWidget(); + } + + return targetWidget; + } + + template + inline int dFindLowerIndex(const QVector &vec, const T &item) + { + int start = 0, end = vec.size() - 1; + int i = (start + end + 1) >> 1; + while (end - start > 0) { + if (vec.at(i) > item) + end = i - 1; + else + start = i; + i = (start + end + 1) >> 1; + } + return i; + } +} + +class DuiFastListViewPrivate : public QObject +{ + Q_OBJECT + +public: + DuiFastListViewPrivate(); + virtual ~DuiFastListViewPrivate(); + + void clearVisibleItemsArray(); + void updateItemHeight(); + + DuiWidget *createCell(int row); + void deleteItem(DuiWidget *widget); + + void setSeparator(DuiWidget *separator); + void setHeadersCreator(DuiCellCreator *headersCreator); + + void removeInvisibleItems(const QPoint &firstVisibleItemCoord, const QPoint &lastVisibleItemCoord); + + DuiWidget *findCellAtRow(int row); + + void updateSeparatorSize(); + + void exposedRectChanged(const QRectF &exposedRect); + + void updateFirstVisibleRow(const QModelIndex &index); + void updateLastVisibleRow(const QModelIndex &index); + +public: + virtual void cellClicked(DuiWidget *source); + virtual void selectionChange(const QItemSelection &selected, const QItemSelection &deselected); + virtual void updateItemSize(); + virtual void resetModel(DuiListModel *controllerModel); + virtual int locateVisibleRowAt(int y, int x = 0) = 0; + + virtual int locatePosOfItem(int row) = 0; + virtual int locatePosOfItem(const QModelIndex &index) = 0; + virtual int itemsCount() const = 0; + virtual QModelIndex flatRowToIndex(int row) const = 0; + virtual int indexToFlatRow(const QModelIndex &index) const = 0; + virtual void createVisibleItems(int firstVisibleRow, int lastVisibleRow); + virtual void createVisibleItems(const QModelIndex &firstVisibleRow, + const QModelIndex &lastVisibleRow) = 0; + + virtual DuiWidget *createItem(int row) = 0; + virtual int totalHeight() = 0; + virtual int separatorsCount() const = 0; + virtual QModelIndex locateVisibleIndexAt(int pos) = 0; + virtual bool isGroupHeader(const QModelIndex &index); + +public slots: + void movingDetectionTimerTimeout(); + +public: + DuiFastListView *q_ptr; + DuiList *controller; + DuiListModel *controllerModel; + QAbstractItemModel *model; + DuiWidgetRecycler *recycler; + DuiWidget *separator; + DuiCellCreator *headersCreator; + + QVector visibleItems; + QPointF viewportTopLeft; + int viewportVisibleHeight; + + int itemHeight; + int viewWidth; + int hdrHeight; + + bool forceRepaint; + + // Section for panning detection + QPointF oldExposedRectPosition; + bool moving; + QTimer movingDetectorTimer; +}; + +class DuiFastPlainListViewPrivate : public DuiFastListViewPrivate +{ +public: + DuiFastPlainListViewPrivate(); + virtual ~DuiFastPlainListViewPrivate(); + +public: + virtual int totalHeight(); + + virtual QModelIndex locateVisibleIndexAt(int pos); + virtual int locateVisibleRowAt(int y, int x = 0); + + virtual int locatePosOfItem(int row); + virtual int locatePosOfItem(const QModelIndex &index); + virtual int separatorsCount() const; + virtual int itemsCount() const; + virtual int indexToFlatRow(const QModelIndex &index) const; + virtual QModelIndex flatRowToIndex(int row) const; + virtual void createVisibleItems(const QModelIndex &firstVisibleRow, + const QModelIndex &lastVisibleRow); + virtual DuiWidget *createItem(int row); +}; + +class DuiFastPlainMultiColumnListViewPrivate : public DuiFastPlainListViewPrivate +{ +public: + DuiFastPlainMultiColumnListViewPrivate(); + virtual ~DuiFastPlainMultiColumnListViewPrivate(); + +public: + int itemsToRows(int items) const; + int flatRowToColumn(int row) const; + +public: + virtual int locatePosOfItem(int row); + virtual int totalHeight(); + virtual DuiWidget *createItem(int row); + virtual int locateVisibleRowAt(int y, int x = 0); + virtual void updateItemSize(); + virtual void cellClicked(DuiWidget *source); + virtual void selectionChange(const QItemSelection &selected, const QItemSelection &deselected); + virtual void createVisibleItems(const QModelIndex &firstVisibleRow, + const QModelIndex &lastVisibleRow); +public: + QHash widgetFlatRows; + DuiWidget *hseparator; +}; + +class DuiFastGroupHeaderListViewPrivate : public DuiFastListViewPrivate +{ +public: + DuiFastGroupHeaderListViewPrivate(); + virtual ~DuiFastGroupHeaderListViewPrivate(); + +public: + DuiWidget *createHeader(int headerIndex); + int headerHeight(); + int headersCount() const; + int itemsCount(int index) const; + void updateHeadersPositions(); + void updateHeadersRows(); + +public: + virtual int indexToFlatRow(const QModelIndex &index) const; + virtual int locatePosOfItem(int headerIndex, int itemIndex); // groups only + virtual int groupSize(int headerIndex) const; + virtual void resetModel(DuiListModel *controllerModel); + virtual int totalHeight(); + + virtual QModelIndex locateVisibleIndexAt(int pos); + virtual int locateVisibleRowAt(int y, int x = 0); + + virtual int locatePosOfItem(int row); + virtual int locatePosOfItem(const QModelIndex &index); + virtual int separatorsCount() const; + virtual int itemsCount() const; + virtual QModelIndex flatRowToIndex(int row) const; + + void createVisibleItems(int firstVisibleRow, int lastVisibleRow); + virtual void createVisibleItems(const QModelIndex &firstVisibleRow, + const QModelIndex &lastVisibleRow); + virtual DuiWidget *createItem(int row); + virtual bool isGroupHeader(const QModelIndex &index); + +public: + QVector headersPositions; + QVector headersRows; +}; + +class DuiFastMultiColumnListViewPrivate : public DuiFastGroupHeaderListViewPrivate +{ +public: + DuiFastMultiColumnListViewPrivate(); + virtual ~DuiFastMultiColumnListViewPrivate(); + +public: + int itemsToRows(int items) const; + int rowsInGroup(int headerIndex) const; + int flatRowToColumn(int row) const; + +public: + virtual void updateItemSize(); + virtual void cellClicked(DuiWidget *source); + virtual void selectionChange(const QItemSelection &selected, const QItemSelection &deselected); + virtual int locatePosOfItem(int headerIndex, int itemIndex); + virtual int locatePosOfItem(const QModelIndex &index); + virtual int groupSize(int headerIndex) const; + virtual int totalHeight(); + virtual int locateVisibleRowAt(int y, int x = 0); + virtual int locatePosOfItem(int row); + virtual void createVisibleItems(const QModelIndex &firstVisibleRow, + const QModelIndex &lastVisibleRow); + virtual DuiWidget *createItem(int row); + +public: + QHash widgetFlatRows; + DuiWidget *hseparator; +}; + +class DuiDefaultHeadersCreator : public DuiAbstractCellCreator +{ +public: + DuiDefaultHeadersCreator(const QString &headerObjectName) { + this->headerObjectName = headerObjectName; + } + + virtual ~DuiDefaultHeadersCreator() { + + } + + virtual DuiWidget *createCell(const QModelIndex &index, DuiWidgetRecycler &recycler) const { + DuiLabel *header = dynamic_cast(recycler.take(DuiLabel::staticMetaObject.className())); + if (header == NULL) { + header = new DuiLabel; + header->setObjectName(headerObjectName); + } + updateCell(index, header); + + return header; + } + + virtual void updateCell(const QModelIndex &index, DuiWidget *cell) const { + DuiLabel *header = dynamic_cast(cell); + QString title = index.data(Qt::DisplayRole).toString(); + header->setText(title); + } + +private: + QString headerObjectName; +}; + +#endif diff --git a/src/widgets/views/duigriditemview.cpp b/src/widgets/views/duigriditemview.cpp new file mode 100644 index 000000000..e064189d4 --- /dev/null +++ b/src/widgets/views/duigriditemview.cpp @@ -0,0 +1,245 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duigriditemview.h" +#include "duigriditemview_p.h" +#include "duigriditem.h" + +#include "duiscalableimage.h" +#include "duitheme.h" +#include "duiimagewidget.h" +#include "duilabel.h" +#include "duiviewcreator.h" + +#include +#include + +DuiGridItemViewPrivate::DuiGridItemViewPrivate() + : controller(0), layout(0), title(0), subtitle(0), image(0), layoutDirty(false) +{ +} + +DuiGridItemViewPrivate::~DuiGridItemViewPrivate() +{ +} + +// Use lazy initialize to reduce useless widget and get better performance +void DuiGridItemViewPrivate::init() +{ + layout = new QGraphicsGridLayout(); + layout->setContentsMargins(0, 0, 0, 0); + layout->setSpacing(0); + controller->setLayout(layout); + + iconAlign = Qt::AlignLeft; +} + +void DuiGridItemViewPrivate::initLayout() const +{ + int count = layout->count(); + for (int i = count - 1; i >= 0; --i) + layout->removeAt(i); + + DuiGridItemModel *model = (DuiGridItemModel *)controller->model(); + if (!model->imageVisible()) { + // Label + initTitle(); + layout->addItem(title, 0, 0); + layout->setAlignment(title, Qt::AlignVCenter | Qt::AlignHCenter); + } else { + if (!model->titleVisible() && !model->subtitleVisible()) { + // Image + initImage(); + layout->addItem(image, 0, 0); + layout->setAlignment(image, Qt::AlignVCenter | Qt::AlignHCenter); + } else if (!model->subtitleVisible()) { + // ImageLabel + initTitle(); + initImage(); + + if (iconAlign == Qt::AlignLeft) { + layout->addItem(image, 0, 0); + layout->addItem(title, 0, 1); + } else { + layout->addItem(title, 0, 0); + layout->addItem(image, 0, 1); + } + } else { + // Grid Item + initTitle(); + initSubtitle(); + initImage(); + + if (iconAlign == Qt::AlignLeft) { + layout->addItem(image, 0, 0, 2, 1); + layout->addItem(title, 0, 1); + layout->addItem(subtitle, 1, 1); + } else { + layout->addItem(image, 0, 1, 2, 1); + layout->addItem(title, 0, 0); + layout->addItem(subtitle, 1, 0); + } + } + } + + layoutDirty = false; +} + +void DuiGridItemViewPrivate::initTitle() const +{ + if (title == 0) { + title = new DuiLabel(); + title->setObjectName("DuiGridItemTitle"); + } +} + +void DuiGridItemViewPrivate::initSubtitle() const +{ + if (subtitle == 0) { + subtitle = new DuiLabel(); + subtitle->setObjectName("DuiGridItemSubtitle"); + } +} + +void DuiGridItemViewPrivate::initImage() const +{ + if (image == 0) { + image = new DuiImageWidget(); + image->setObjectName("DuiGridItemImage"); + } +} + +void DuiGridItemViewPrivate::setTitle(const QString &text) +{ + if (text.isEmpty()) return; + initTitle(); + title->setText(text); +} + +void DuiGridItemViewPrivate::setSubtitle(const QString &text) +{ + if (text.isEmpty()) return; + initSubtitle(); + subtitle->setText(text); +} + +void DuiGridItemViewPrivate::setImage(const QString &name) +{ + if (name.isEmpty() && controller->pixmap().isNull()) return; + + Q_Q(DuiGridItemView); + initImage(); + + if (name.isEmpty()) + image->setPixmap(controller->pixmap()); + else + image->setImage(name, q->style()->iconSize()); +} + +void DuiGridItemViewPrivate::_q_updateImage() +{ + initImage(); + image->setPixmap(controller->pixmap()); +} + +DuiGridItemView::DuiGridItemView(DuiGridItem *controller) : + DuiWidgetView(* new DuiGridItemViewPrivate, controller) +{ + Q_D(DuiGridItemView); + d->controller = controller; + d->init(); + + connect(controller, SIGNAL(pixmapChanged()), this, SLOT(_q_updateImage())); +} + +DuiGridItemView::DuiGridItemView(DuiGridItemViewPrivate &dd, DuiGridItem *controller) : + DuiWidgetView(dd, controller) +{ + Q_D(DuiGridItemView); + d->controller = controller; + d->init(); + + connect(controller, SIGNAL(pixmapChanged()), this, SLOT(_q_updateImage())); +} + +DuiGridItemView::~DuiGridItemView() +{ +} + +void DuiGridItemView::applyStyle() +{ + Q_D(DuiGridItemView); + + DuiWidgetView::applyStyle(); + + // change the icon Alignment + if (d->iconAlign != style()->iconAlign()) { + d->iconAlign = style()->iconAlign(); + d->layoutDirty = true; + } +} + +void DuiGridItemView::drawContents(QPainter *painter, const QStyleOptionGraphicsItem *option) const +{ + Q_D(const DuiGridItemView); + if (d->layoutDirty) + d->initLayout(); + + DuiWidgetView::drawContents(painter, option); +} + +void DuiGridItemView::updateData(const QList& modifications) +{ + Q_D(DuiGridItemView); + + DuiWidgetView::updateData(modifications); + + const char *member; + const int count = modifications.count(); + for (int i = 0; i < count; ++i) { + member = modifications[i]; + + if (member == DuiGridItemModel::Image) { + d->setImage(model()->image()); + } else if (member == DuiGridItemModel::Title) { + d->setTitle(model()->title()); + } else if (member == DuiGridItemModel::Subtitle) { + d->setSubtitle(model()->subtitle()); + } else if (member == DuiGridItemModel::ImageVisible || member == DuiGridItemModel::TitleVisible || + member == DuiGridItemModel::SubtitleVisible) { + d->layoutDirty = true; + } + } +} + +void DuiGridItemView::setupModel() +{ + Q_D(DuiGridItemView); + DuiWidgetView::setupModel(); + + d->setTitle(model()->title()); + d->setSubtitle(model()->subtitle()); + d->setImage(model()->image()); + d->layoutDirty = true; +} + +DUI_REGISTER_VIEW_NEW(DuiGridItemView, DuiGridItem) + +#include "moc_duigriditemview.cpp" + diff --git a/src/widgets/views/duigriditemview.h b/src/widgets/views/duigriditemview.h new file mode 100644 index 000000000..3c1554ea8 --- /dev/null +++ b/src/widgets/views/duigriditemview.h @@ -0,0 +1,79 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIGRIDITEMVIEW_H +#define DUIGRIDITEMVIEW_H + +#include "duiwidgetview.h" +#include "duigriditemmodel.h" +#include "duigriditemstyle.h" + +class DuiGridItem; +class DuiGridItemViewPrivate; + +/*! + \class DuiGridItemView + \brief View class for DuiGridItem. + + \ingroup views + + \section DuiGridItemViewOverview Overview + DuiGridItemView implements a view for the DuiGridItem widget. + */ + +class DUI_EXPORT DuiGridItemView : public DuiWidgetView +{ + Q_OBJECT + DUI_VIEW(DuiGridItemModel, DuiGridItemStyle) + +public: + /*! + \brief Constructor + \param controller Pointer to the controller + */ + DuiGridItemView(DuiGridItem *controller); + + /*! + \brief Destructor + */ + virtual ~DuiGridItemView(); + +protected slots: + //! \reimp + virtual void updateData(const QList& modifications); + //! \reimp_end + +protected: + //! \reimp + virtual void drawContents(QPainter *painter, const QStyleOptionGraphicsItem *option) const; + virtual void setupModel(); + virtual void applyStyle(); + //! \reimp_end + + //! \internal + DuiGridItemView(DuiGridItemViewPrivate &dd, DuiGridItem *controller); + //! \internal_end + +private: + Q_DISABLE_COPY(DuiGridItemView) + Q_DECLARE_PRIVATE(DuiGridItemView) + Q_PRIVATE_SLOT(d_func(), void _q_updateImage()) +}; + +#endif diff --git a/src/widgets/views/duigriditemview_p.h b/src/widgets/views/duigriditemview_p.h new file mode 100644 index 000000000..ae0300a96 --- /dev/null +++ b/src/widgets/views/duigriditemview_p.h @@ -0,0 +1,60 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIGRIDITEMVIEW_P_H +#define DUIGRIDITEMVIEW_P_H + +#include "private/duiwidgetview_p.h" + +class QPixmap; +class QGraphicsGridLayout; +class DuiGridItem; +class DuiImageWidget; +class DuiLabel; + +class DuiGridItemViewPrivate : public DuiWidgetViewPrivate +{ + Q_DECLARE_PUBLIC(DuiGridItemView) + +public: + DuiGridItemViewPrivate(); + virtual ~DuiGridItemViewPrivate(); + + virtual void init(); + virtual void initLayout() const; + + inline void initTitle() const; + inline void initSubtitle() const; + inline void initImage() const; + + void setTitle(const QString &text); + void setSubtitle(const QString &text); + void setImage(const QString &name); + void _q_updateImage(); + + DuiGridItem *controller; + QGraphicsGridLayout *layout; + mutable DuiLabel *title; + mutable DuiLabel *subtitle; + mutable DuiImageWidget *image; + mutable bool layoutDirty; + Qt::Alignment iconAlign; +}; + +#endif diff --git a/src/widgets/views/duihomebuttonpanelview.cpp b/src/widgets/views/duihomebuttonpanelview.cpp new file mode 100644 index 000000000..8a48566fa --- /dev/null +++ b/src/widgets/views/duihomebuttonpanelview.cpp @@ -0,0 +1,75 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duihomebuttonpanelview.h" +#include "duihomebuttonpanelview_p.h" +#include "duibutton.h" +#include "duiviewcreator.h" +#include "duihomebuttonpanel.h" + +#include + +DuiHomeButtonPanelViewPrivate::DuiHomeButtonPanelViewPrivate() + : button(0), controller(0) +{ +} + +DuiHomeButtonPanelViewPrivate::~DuiHomeButtonPanelViewPrivate() +{ + if (button) { + delete button; + button = 0; + } +} + +void DuiHomeButtonPanelViewPrivate::init() +{ + QGraphicsLinearLayout *mainLayout = new QGraphicsLinearLayout(Qt::Horizontal); + mainLayout->setContentsMargins(0, 0, 0, 0); + mainLayout->setSpacing(0); + + button = new DuiButton(controller); + + mainLayout->addItem(button); + controller->setLayout(mainLayout); + + QObject::connect(button, SIGNAL(clicked()), controller, SIGNAL(buttonClicked())); +} + +void DuiHomeButtonPanelViewPrivate::setupButton() +{ + button->setObjectName("DuiHomeButton"); + button->setViewType("icon"); + button->setIconID("Icon-home"); +} + +DuiHomeButtonPanelView::DuiHomeButtonPanelView(DuiHomeButtonPanel *controller) : + DuiSceneWindowView(* new DuiHomeButtonPanelViewPrivate, controller) +{ + Q_D(DuiHomeButtonPanelView); + d->controller = controller; + d->init(); + d->setupButton(); +} + +DuiHomeButtonPanelView::~DuiHomeButtonPanelView() +{ +} + +DUI_REGISTER_VIEW_NEW(DuiHomeButtonPanelView, DuiHomeButtonPanel) diff --git a/src/widgets/views/duihomebuttonpanelview.h b/src/widgets/views/duihomebuttonpanelview.h new file mode 100644 index 000000000..96fbbc39e --- /dev/null +++ b/src/widgets/views/duihomebuttonpanelview.h @@ -0,0 +1,48 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIHOMEBUTTONPANELVIEW_H +#define DUIHOMEBUTTONPANELVIEW_H + +#include "duiscenewindowview.h" + +class DuiHomeButtonPanel; +class DuiHomeButtonPanelViewPrivate; + +/*! + * \class DuiHomeButtonPanelView + * \brief The DuiHomeButtonPanelView class just draws a home button. + * + * It just draws a home button on an otherwise empty scene window. + */ +class DUI_EXPORT DuiHomeButtonPanelView : public DuiSceneWindowView +{ + Q_OBJECT + DUI_VIEW(DuiSceneWindowModel, DuiSceneWindowStyle) + +public: + DuiHomeButtonPanelView(DuiHomeButtonPanel *controller); + virtual ~DuiHomeButtonPanelView(); + +private: + Q_DISABLE_COPY(DuiHomeButtonPanelView) + Q_DECLARE_PRIVATE(DuiHomeButtonPanelView) +}; + +#endif diff --git a/src/widgets/views/duihomebuttonpanelview_p.h b/src/widgets/views/duihomebuttonpanelview_p.h new file mode 100644 index 000000000..5e2e99cf6 --- /dev/null +++ b/src/widgets/views/duihomebuttonpanelview_p.h @@ -0,0 +1,47 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIHOMEBUTTONPANELVIEW_P_H +#define DUIHOMEBUTTONPANELVIEW_P_H + +#include "duiscenewindowview_p.h" +#include "duihomebuttonpanelview.h" + +class DuiHomeButtonPanel; +class DuiButton; + +class DuiHomeButtonPanelViewPrivate : public DuiSceneWindowViewPrivate +{ + Q_DECLARE_PUBLIC(DuiHomeButtonPanelView) + +public: + DuiHomeButtonPanelViewPrivate(); + virtual ~DuiHomeButtonPanelViewPrivate(); + + virtual void init(); + virtual void setupButton(); + + //! The actual home button + DuiButton *button; + + //! The DuiHomeButtonPanel controller + DuiHomeButtonPanel *controller; +}; + +#endif diff --git a/src/widgets/views/duiimagewidgetview.cpp b/src/widgets/views/duiimagewidgetview.cpp new file mode 100644 index 000000000..071b4241d --- /dev/null +++ b/src/widgets/views/duiimagewidgetview.cpp @@ -0,0 +1,241 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiimagewidgetview.h" + +#include + +#include "duiimagewidget.h" +#include "duiimagewidget_p.h" +#include "duiviewcreator.h" +#include "private/duiwidgetview_p.h" + +class DuiImageWidgetViewPrivate : public DuiWidgetViewPrivate +{ +public: + DuiImageWidgetViewPrivate(); + ~DuiImageWidgetViewPrivate(); + + DuiImageWidget *controller; +}; + +DuiImageWidgetViewPrivate::DuiImageWidgetViewPrivate() + : controller(0) +{ +} + +DuiImageWidgetViewPrivate::~DuiImageWidgetViewPrivate() +{ +} + +DuiImageWidgetView::DuiImageWidgetView(DuiImageWidget *controller) : + DuiWidgetView(* new DuiImageWidgetViewPrivate, controller) +{ + Q_D(DuiImageWidgetView); + d->controller = controller; +} + +DuiImageWidgetView::DuiImageWidgetView(DuiImageWidgetViewPrivate &dd, DuiImageWidget *controller) : + DuiWidgetView(dd, controller) +{ + Q_D(DuiImageWidgetView); + d->controller = controller; +} + +DuiImageWidgetView::~DuiImageWidgetView() +{ +} + +void DuiImageWidgetView::drawContents(QPainter *painter, const QStyleOptionGraphicsItem *option) const +{ + Q_UNUSED(option); + + Q_D(const DuiImageWidgetView); + + // no image, return + QSizeF imageSize = d->controller->d_func()->imageDataSize(); + if (imageSize.isEmpty()) return; + + // the source image section size will be used finally + QSizeF sourceSize = imageSize; + + // get target size, bounded by widget size + QSizeF widgetSize = size(); + QSizeF targetSize = widgetSize; + QSizeF t; + + // get the image display size + qreal fx, fy; + d->controller->zoomFactor(&fx, &fy); + + t.setWidth(imageSize.width()*fx); + t.setHeight(imageSize.height()*fy); + + // update sourceSize for crop section by compare with targetSize, simulate zoom effect + qreal value; + if (t.width() > targetSize.width()) { + value = sourceSize.width(); + sourceSize.setWidth(qRound(value * targetSize.width() / t.width())); + } + if (t.height() > targetSize.height()) { + value = sourceSize.height(); + sourceSize.setHeight(qRound(value * targetSize.height() / t.height())); + } + + // limited by target size + t = targetSize.boundedTo(t); + + // protection codes + if (sourceSize.width() < 1.0) + sourceSize.setWidth(1.0); + if (sourceSize.height() < 1.0) + sourceSize.setHeight(1.0); + + // get values from controller + const QPixmap *pixmap = d->controller->pixmap(); + + qreal leftBorder = style()->borderLeft(); + qreal topBorder = style()->borderTop(); + qreal rightBorder = style()->borderRight(); + qreal bottomBorder = style()->borderBottom(); + + qreal w = leftBorder + rightBorder; + qreal h = topBorder + bottomBorder; + + // calculate if need draw border + // notice: no border on the cropped edge + QSizeF originSize = pixmap->size(); + + if (originSize.width() > sourceSize.width()) + w = 0; + + if (originSize.height() > sourceSize.height()) + h = 0; + + // calculate the rectangle of draw + qreal dx = (widgetSize.width() - t.width()) / 2.0; + qreal dy = (widgetSize.height() - t.height()) / 2.0; + + // calculate draw rect + QRectF drawRect, sourceRect, border; + drawRect.setRect(dx, dy, t.width(), t.height()); + + // draw borders outside of target + // if both borders equals 0, do not draw border + if (w > 0 || h > 0) { + + QColor borderColor = style()->borderColor(); + qreal borderOpacity = style()->borderOpacity(); + QBrush brush(borderColor); + + qreal oldOpacity = painter->opacity(); + painter->setOpacity(borderOpacity); + + dx = drawRect.x() - leftBorder; + dy = drawRect.y() - topBorder; + + if (w > 0 && h == 0) { + // only have horizontal border + border = QRectF(dx, drawRect.y(), leftBorder, drawRect.height()); + painter->fillRect(border, brush); + + border = QRectF(drawRect.x() + drawRect.width(), drawRect.y(), rightBorder, drawRect.height()); + painter->fillRect(border, brush); + } else if (w == 0 && h > 0) { + // only have vertical border + border = QRectF(drawRect.x(), dy, drawRect.width(), topBorder); + painter->fillRect(border, brush); + + border = QRectF(drawRect.x(), drawRect.y() + drawRect.height(), drawRect.width(), bottomBorder); + painter->fillRect(border, brush); + } else { + + // draw top border + border = QRectF(dx, dy, drawRect.width() + w, topBorder); + painter->fillRect(border, brush); + + // draw left border + border = QRectF(dx, drawRect.y(), leftBorder, drawRect.height()); + painter->fillRect(border, brush); + + // draw right border + border = QRectF(drawRect.x() + drawRect.width(), drawRect.y(), rightBorder, drawRect.height()); + painter->fillRect(border, brush); + + // draw bottom border + border = QRectF(dx, drawRect.y() + drawRect.height(), drawRect.width() + w, bottomBorder); + painter->fillRect(border, brush); + } + painter->setOpacity(oldOpacity); + } + + // draw image + QPointF topLeft = d->controller->crop().topLeft(); + + if (topLeft == QPointF(-1.0, -1.0)) { + + // calculate default crop section + dx = (originSize.width() - sourceSize.width()) / 2.0; + dy = (originSize.height() - sourceSize.height()) / 2.0; + + sourceRect = QRectF(dx, dy, sourceSize.width(), sourceSize.height()); + } else { + + // calculate crop section by given topLeft corner + dx = topLeft.x(); + dy = topLeft.y(); + + sourceRect = QRectF(dx, dy, qMin(dx + sourceSize.width(), originSize.width()), + qMin(dy + sourceSize.height(), originSize.height())); + } + + painter->drawPixmap(drawRect, *pixmap, sourceRect); +} + +void DuiImageWidgetView::resizeEvent(QGraphicsSceneResizeEvent *event) +{ + DuiWidgetView::resizeEvent(event); + update(); +} + +QSizeF DuiImageWidgetView::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const +{ + Q_D(const DuiImageWidgetView); + + QSizeF s = DuiWidgetView::sizeHint(which, constraint); + + if (s == QSizeF(-1, -1)) { + if (which == Qt::MinimumSize) + return QSize(0, 0); + if (which == Qt::MaximumSize) + return QSizeF(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); + return d->controller->imageSize(); + } + + if (which == Qt::MinimumSize || which == Qt::MaximumSize) + return s; + + if (style()->preferredSize().isValid()) + return style()->preferredSize(); + + return d->controller->imageSize(); +} + +DUI_REGISTER_VIEW_NEW(DuiImageWidgetView, DuiImageWidget) + diff --git a/src/widgets/views/duiimagewidgetview.h b/src/widgets/views/duiimagewidgetview.h new file mode 100644 index 000000000..fe1c265e4 --- /dev/null +++ b/src/widgets/views/duiimagewidgetview.h @@ -0,0 +1,85 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIIMAGEWIDGETVIEW_H +#define DUIIMAGEWIDGETVIEW_H + +#include "duiexport.h" +#include "duiwidgetview.h" +#include "duiimagewidgetmodel.h" +#include "duiimagewidgetstyle.h" + +class DuiImageWidgetViewPrivate; +class DuiImageWidget; + +/*! + \class DuiImageWidgetView + \brief View class for standard dui images. + + \ingroup views + + DuiImageWidgetView is used to visualize image. + + \section DuiImageWidgetView Border + DuiImageWidgetView draws a fixed width and color border surround the image. + When image is cropped, the cropped edge will have no border. + + The border of image can be changed using the styling attributes defined + in DuiImageWidgetStyle. DuiImageWidgetStyle::borderTop, DuiImageWidgetStyle::borderLeft, + DuiImageWidgetStyle::borderRight, DuiImageWidgetStyle::borderBottom, + DuiImageWidgetStyle::borderColor and DuiImageWidgetStyle::borderOpacity + + */ + +class DUI_EXPORT DuiImageWidgetView : public DuiWidgetView +{ + Q_OBJECT + DUI_VIEW(DuiImageWidgetModel, DuiImageWidgetStyle) + +public: + /*! + \brief Constructor + \param controller Pointer to the DuiImageWidget + */ + DuiImageWidgetView(DuiImageWidget *controller); + + /*! + \brief Destructor + */ + virtual ~DuiImageWidgetView(); + + //! \reimp + virtual void resizeEvent(QGraphicsSceneResizeEvent *event); + //! \reimp_end + +protected: + //! \reimp + virtual void drawContents(QPainter *painter, const QStyleOptionGraphicsItem *option) const; + virtual QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const; + //! \reimp_end + + //! \cond + DuiImageWidgetView(DuiImageWidgetViewPrivate &dd, DuiImageWidget *controller); + //! \endcond + +private: + Q_DECLARE_PRIVATE(DuiImageWidgetView) +}; + +#endif diff --git a/src/widgets/views/duiinfobannereventview.cpp b/src/widgets/views/duiinfobannereventview.cpp new file mode 100644 index 000000000..77cd42ad7 --- /dev/null +++ b/src/widgets/views/duiinfobannereventview.cpp @@ -0,0 +1,151 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +// TODO: Consider calculating size hint from the content + +#include "duiinfobannereventview.h" +#include "duiinfobannereventview_p.h" + +#include "duiinfobanner.h" +#include "duiviewcreator.h" +#include "duiimagewidget.h" +#include "duilabel.h" + +#include +#include + +DuiInfoBannerEventViewPrivate::DuiInfoBannerEventViewPrivate(DuiInfoBanner *controller) : + DuiSceneWindowViewPrivate(), + banner(controller), label(0), image(0), icon(0), layout(0) +{ +} + +DuiInfoBannerEventViewPrivate::~DuiInfoBannerEventViewPrivate() +{ +} + +void DuiInfoBannerEventViewPrivate::init() +{ + label = new DuiLabel(); + label->setAlignment(Qt::AlignCenter); + label->setTextElide(true); + label->setObjectName("EventInfoBannerBody"); + + image = new DuiImageWidget(); + image->setObjectName("EventInfoBannerImage"); + icon = new DuiImageWidget(); + icon->setObjectName("EventInfoBannerIcon"); + + layout = new QGraphicsLinearLayout(Qt::Horizontal); + layout->setContentsMargins(0, 0, 0, 0); + layout->setSpacing(0); + controller->setLayout(layout); + + layout->addItem(image); + layout->addItem(label); + layout->addItem(icon); + layout->setAlignment(label, Qt::AlignCenter); +} + +DuiInfoBannerEventView::DuiInfoBannerEventView(DuiInfoBanner *controller) : + DuiSceneWindowView(* new DuiInfoBannerEventViewPrivate(controller), controller) +{ + Q_D(DuiInfoBannerEventView); + d->init(); +} + +DuiInfoBannerEventView::DuiInfoBannerEventView(DuiInfoBannerEventViewPrivate &dd, DuiInfoBanner *controller) : + DuiSceneWindowView(dd, controller) +{ + Q_D(DuiInfoBannerEventView); + d->init(); +} + +DuiInfoBannerEventView::~DuiInfoBannerEventView() +{ +} + +void DuiInfoBannerEventView::updateData(const QList& modifications) +{ + DuiSceneWindowView::updateData(modifications); + + Q_D(DuiInfoBannerEventView); + const char *member; + + foreach(member, modifications) { + if (member == DuiInfoBannerModel::BodyText) { + d->label->setText(model()->bodyText()); + } else if (member == DuiInfoBannerModel::ImageID) { + d->image->setImage(model()->imageID(), style()->imageSize()); + } else if (member == DuiInfoBannerModel::Pixmap) { + d->image->setPixmap(model()->pixmap()); + } else if (member == DuiInfoBannerModel::IconID) { + d->icon->setImage(model()->iconID(), style()->iconSize()); + } + } +} + +void DuiInfoBannerEventView::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + Q_UNUSED(event); +} + +void DuiInfoBannerEventView::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + Q_D(DuiInfoBannerEventView); + + QPointF touch = event->scenePos(); + QRectF rect = d->controller->sceneBoundingRect(); + if (rect.contains(touch)) { + d->banner->click(); + } +} + +void DuiInfoBannerEventView::setupModel() +{ + DuiSceneWindowView::setupModel(); + + Q_D(DuiInfoBannerEventView); + + d->label->setText(model()->bodyText()); + d->icon->setImage(model()->iconID(), style()->iconSize()); + + if (!model()->imageID().isEmpty()) { + d->image->setImage(model()->imageID(), style()->imageSize()); + } else { + d->image->setPixmap(model()->pixmap()); + } +} + +void DuiInfoBannerEventView::applyStyle() +{ + DuiSceneWindowView::applyStyle(); + + Q_D(DuiInfoBannerEventView); + + if (!model()->imageID().isEmpty()) { + d->image->setImage(model()->imageID(), style()->imageSize()); + } else { + d->image->setPixmap(model()->pixmap()); + } + + d->icon->setImage(model()->iconID(), style()->iconSize()); +} + +DUI_REGISTER_VIEW_NEW(DuiInfoBannerEventView, DuiInfoBanner) diff --git a/src/widgets/views/duiinfobannereventview.h b/src/widgets/views/duiinfobannereventview.h new file mode 100644 index 000000000..c02e53911 --- /dev/null +++ b/src/widgets/views/duiinfobannereventview.h @@ -0,0 +1,125 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIINFOBANNEREVENTVIEW_H +#define DUIINFOBANNEREVENTVIEW_H + +#include "duiscenewindowview.h" +#include "duiinfobannermodel.h" +#include "duiinfobannerstyle.h" + +class DuiInfoBanner; +class DuiInfoBannerEventViewPrivate; + +/*! + \class DuiInfoBannerEventView + \brief A class that represents a modeless notification banner. + + \ingroup views + + \section DuiInfoBannerEventViewOverview Overview + - An event banner is a modeless notification banner that appears on screen on top of the given UI + (all but in certain exception cases, like full screen video playback). + - An event banner is used for events that should be persistent: i.e. if the user does not click on + the event banner when it is shown, they will be shown on the Home screen. + - The banner disappears from the screen after a timeout, after the timeout the incoming event can + be found from the Home view. + - The event banner has an action associated to it: usually tapping the notification opens the item + in a new task. + - If the application view where a new event occurs is in the foreground, no extra notification + should displayed, the update should be shown directly in the foreground UI. + - If there is several information updates happening at the same time the incoming event banners should + be shown one after another. + - The event banners should not overlap the virtual keyboard: if the VKB is + open, the preview should be positioned above the keyboard. + - Event banners have (currently) a fixed size. + + \image html eventbanner.png + + \section DuiInfoBannerEventViewInteractions Interactions + + + + + + + + + + + + + + + + + + + + + + +
EventActionTransitionTactile feedbackAudio feedback
-Appear on screenAppearing from the background ont the foreground on the defined spot on screenOPEN: tactile feedback?OPEN: audio feedback?
Ignore, do nothingNotification is ignoredFading on to the background moving at the same time on the Home button -- "droppping on Home"OPEN: tactile feedback?OPEN: audio feedback?
Drag notification away from the screenNotification is dismissedOPEN: transition?CancelOPEN: audio feedback?
Single tap on the notificationOpen item in new taskTransition showing a new task openingPress, releasePress, release
+ + \sa DuiNotification +*/ + +class DUI_EXPORT DuiInfoBannerEventView : public DuiSceneWindowView +{ + Q_OBJECT + DUI_VIEW(DuiInfoBannerModel, DuiInfoBannerStyle) + +public: + /*! + \brief Constructor + \param controller Pointer to the banner's controller + */ + DuiInfoBannerEventView(DuiInfoBanner *controller); + + /*! + \brief Destructor + */ + virtual ~DuiInfoBannerEventView(); + +protected: + //! \reimp + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + virtual void setupModel(); + virtual void applyStyle(); + //! \reimp_end + + /*! + \brief Constructor for derived classes + \param dd Private class implementation + \param controller Pointer to the banner's controller + */ + DuiInfoBannerEventView(DuiInfoBannerEventViewPrivate &dd, DuiInfoBanner *controller); + +protected Q_SLOTS: + //! \reimp + virtual void updateData(const QList& modifications); + //! \reimp_end + +private: + Q_DECLARE_PRIVATE(DuiInfoBannerEventView) +}; + +#endif + diff --git a/src/widgets/views/duiinfobannereventview_p.h b/src/widgets/views/duiinfobannereventview_p.h new file mode 100644 index 000000000..d45415a9d --- /dev/null +++ b/src/widgets/views/duiinfobannereventview_p.h @@ -0,0 +1,49 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIINFOBANNEREVENTVIEW_P_H +#define DUIINFOBANNEREVENTVIEW_P_H + +#include "duiscenewindowview_p.h" + +class DuiLabel; +class DuiImageWidget; +class QGraphicsLinearLayout; + +class DuiInfoBannerEventViewPrivate : public DuiSceneWindowViewPrivate +{ + Q_DECLARE_PUBLIC(DuiInfoBannerEventView) + +public: + DuiInfoBannerEventViewPrivate(DuiInfoBanner *controller); + virtual ~DuiInfoBannerEventViewPrivate(); + + virtual void init(); + + //! A label for the notification text + DuiInfoBanner *banner; + DuiLabel *label; + DuiImageWidget *image; + DuiImageWidget *icon; + + //! The layout of the notification + QGraphicsLinearLayout *layout; +}; + +#endif diff --git a/src/widgets/views/duiinfobannerinformationview.cpp b/src/widgets/views/duiinfobannerinformationview.cpp new file mode 100644 index 000000000..f9a59aa0c --- /dev/null +++ b/src/widgets/views/duiinfobannerinformationview.cpp @@ -0,0 +1,181 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiinfobannerinformationview.h" +#include "duiinfobannerinformationview_p.h" + +#include "duiinfobanner.h" +#include "duiviewcreator.h" +#include "duiimagewidget.h" +#include "duilabel.h" +#include "duibutton.h" + +#include +#include + +DuiInfoBannerInformationViewPrivate::DuiInfoBannerInformationViewPrivate(DuiInfoBanner *banner) : + DuiSceneWindowViewPrivate(), + banner(banner), label(0), image(0), button(0), layout(0) +{ +} + +DuiInfoBannerInformationViewPrivate::~DuiInfoBannerInformationViewPrivate() +{ +} + +void DuiInfoBannerInformationViewPrivate::init() +{ + label = new DuiLabel(); + label->setAlignment(Qt::AlignCenter); + label->setTextElide(true); + label->setObjectName("SystemInfoBannerBody"); + + image = new DuiImageWidget(); + image->setObjectName("SystemInfoBannerImage"); + + layout = new QGraphicsGridLayout(); + layout->setContentsMargins(0, 0, 0, 0); + layout->setSpacing(0); + + layout->addItem(image, 0, 0); + layout->addItem(label, 0, 1); + + button = new DuiButton(controller); + button->setObjectName("SystemInfoBannerButton"); + + controller->setLayout(layout); +} + +void DuiInfoBannerInformationViewPrivate::setButtonText(const QString &text) +{ + if (!text.isEmpty()) { + if (layout->count() == 2) + layout->addItem(button, 1, 0, 1, 2); + button->setText(text); + button->setVisible(true); + } else { + if (layout->count() == 3) + layout->removeAt(2); + button->setVisible(false); + } + +} + +DuiInfoBannerInformationView::DuiInfoBannerInformationView(DuiInfoBanner *controller) : + DuiSceneWindowView(* new DuiInfoBannerInformationViewPrivate(controller), controller) +{ + Q_D(DuiInfoBannerInformationView); + d->init(); +} + +DuiInfoBannerInformationView::DuiInfoBannerInformationView(DuiInfoBannerInformationViewPrivate &dd, DuiInfoBanner *controller) : + DuiSceneWindowView(dd, controller) +{ + Q_D(DuiInfoBannerInformationView); + d->init(); +} + +DuiInfoBannerInformationView::~DuiInfoBannerInformationView() +{ +} + +QSizeF DuiInfoBannerInformationView::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const +{ + Q_D(const DuiInfoBannerInformationView); + + QSizeF base = DuiSceneWindowView::sizeHint(which, constraint); + + QSizeF buttonSize(0, 0); + if (!model()->buttonText().isEmpty()) + buttonSize = d->button->sizeHint(which, constraint); + + base.setHeight(base.height() + buttonSize.height()); + + return base; +} + +void DuiInfoBannerInformationView::updateData(const QList& modifications) +{ + DuiSceneWindowView::updateData(modifications); + + Q_D(DuiInfoBannerInformationView); + const char *member; + + const int count = modifications.count(); + for (int i = 0; i < count; ++i) { + member = modifications[i]; + if (member == DuiInfoBannerModel::BodyText) { + d->label->setText(model()->bodyText()); + } else if (member == DuiInfoBannerModel::ImageID) { + d->image->setImage(model()->imageID(), style()->imageSize()); + } else if (member == DuiInfoBannerModel::Pixmap) { + d->image->setPixmap(model()->pixmap()); + } else if (member == DuiInfoBannerModel::ButtonText) { + d->setButtonText(model()->buttonText()); + } + } +} + +void DuiInfoBannerInformationView::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + Q_UNUSED(event); +} + +void DuiInfoBannerInformationView::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + Q_D(DuiInfoBannerInformationView); + + QPointF touch = event->scenePos(); + QRectF rect = d->controller->sceneBoundingRect(); + if (rect.contains(touch)) { + d->banner->click(); + } +} + +void DuiInfoBannerInformationView::setupModel() +{ + DuiSceneWindowView::setupModel(); + + Q_D(DuiInfoBannerInformationView); + + QObject::connect(d->button, SIGNAL(clicked()), d->banner, SIGNAL(buttonClicked())); + d->label->setText(model()->bodyText()); + d->setButtonText(model()->buttonText()); + + if (!model()->imageID().isEmpty()) { + d->image->setImage(model()->imageID(), style()->imageSize()); + } else { + d->image->setPixmap(model()->pixmap()); + } +} + +void DuiInfoBannerInformationView::applyStyle() +{ + DuiSceneWindowView::applyStyle(); + + Q_D(DuiInfoBannerInformationView); + + if (!model()->imageID().isEmpty()) { + d->image->setImage(model()->imageID(), style()->imageSize()); + } else { + d->image->setPixmap(model()->pixmap()); + } +} + +DUI_REGISTER_VIEW_NEW(DuiInfoBannerInformationView, DuiInfoBanner) diff --git a/src/widgets/views/duiinfobannerinformationview.h b/src/widgets/views/duiinfobannerinformationview.h new file mode 100644 index 000000000..20514e5f0 --- /dev/null +++ b/src/widgets/views/duiinfobannerinformationview.h @@ -0,0 +1,160 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIINFOBANNERINFORMATIONVIEW_H +#define DUIINFOBANNERINFORMATIONVIEW_H + +#include "duiscenewindowview.h" +#include "duiinfobannermodel.h" +#include "duiinfobannerstyle.h" + +class DuiInfoBanner; +class DuiInfoBannerInformationViewPrivate; + +/*! + \class DuiInfoBannerInformationView + \brief A class that represents a modeless notification banner. + + \ingroup views + + \section DuiInfoBannerInformationViewOverview Overview + - Information banners are UI elements that allow the device to communicate information that the + foreground UI is not capable of communicating. + - All information banners are modeless and temporal elements, disappearing after a timeout (or a + given time period). + - Information banners can include Progress notification elements within themselves. + - Information banners differ from Incoming event banners that they do not appear on the Home screen + notification area. + - Information banners are not interactive, any click onto it dismisses the status banner. + - Information banners can include Labels and Images. + - Information banners determine their size by the amount of contents that they need to display. + - Information banner should not overlap the virtual keyboard: if the VKB is open, the status banner + should be positioned above the keyboard. + + \image html infobanner.png + + \section DuiInfoBannerInformationViewInteractions Interactions + + + + + + + + + + + + + + + + + +
EventActionTransitionTactile feedbackAudio feedback
-Appear on screenAppearing from the background ont the foreground on the defined spot on screen(optional)(optional)
Ignore, do nothingUp to the designer, default: disappear from screenFading on to the backgroundOPEN: tactile feedback?OPEN: audio feedback?
Click on the status bannerDisappear from the screenFading to the backgroundNo feedbackNo feedback
+ + \section DuiInfoBannerInteractiveOverview Interactive information banner + - An interactive information banner extends the status banner by providing a functionality associated + with the status banner. + - An interactive information banner can have only one function associated to it. The button can be + enabled using DuiInfoBanner::setButtonText method. + - Interactive information banners determine their size by the amount of contents that they need to display. + - An interactive information banner may also be used for cancellable operations, containing a "Cancel" + button for canceling the process. + - Note that the interactive information banner is still modeless: if you need to have a modal + progress operation, use a variant of the Dialog component. + - Do not hack the interactive information banner to be modal! + - Interactive information banner should not overlap the virtual keyboard: if the VKB is open, the + interactive information banner should be positioned above the keyboard. + + \image html interactiveinfobanner.png + + \section DuiInfoBannerInteractiveInteractions Interactions + + + + + + + + + + + + + + + + + + + + + + +
EventActionTransitionTactile feedbackAudio feedback
-Appear on screen (location up to designer)OPEN: Transition?OPEN: tactile feedback?OPEN: audio feedback?
Ignore, do nothingRemain in the screen until the process is finished (no defined timeout time)-None, or if the process takes long time a tactile feedback is used to show user that it has finished-
Single tap on button inside notificationThe functionality has to be defined by application designerDepending on the functionPress, releasePress, release
Click on the interactive status banner (outside the button)Disappear from the screenFading to the backgroundNo feedbackNo feedback
+ + \sa DuiNotification +*/ +class DUI_EXPORT DuiInfoBannerInformationView : public DuiSceneWindowView +{ + Q_OBJECT + DUI_VIEW(DuiInfoBannerModel, DuiInfoBannerStyle) + +public: + /*! + \brief Constructor + \param controller Pointer to the banner's controller + */ + DuiInfoBannerInformationView(DuiInfoBanner *controller); + + /*! + \brief Destructor + */ + virtual ~DuiInfoBannerInformationView(); + + //! \reimp + virtual QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const; + //! \reimp_end + +protected: + //! \reimp + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + virtual void setupModel(); + virtual void applyStyle(); + //! \reimp_end + + /*! + \brief Constructor for derived classes + \param dd Private class implementation + \param controller Pointer to the banner's controller + */ + DuiInfoBannerInformationView(DuiInfoBannerInformationViewPrivate &dd, DuiInfoBanner *controller); + +protected Q_SLOTS: + //! \reimp + virtual void updateData(const QList& modifications); + //! \reimp_end +private: + Q_DECLARE_PRIVATE(DuiInfoBannerInformationView) +}; + +#endif + diff --git a/src/widgets/views/duiinfobannerinformationview_p.h b/src/widgets/views/duiinfobannerinformationview_p.h new file mode 100644 index 000000000..26bba595a --- /dev/null +++ b/src/widgets/views/duiinfobannerinformationview_p.h @@ -0,0 +1,51 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIINFOBANNERINFORMATIONVIEW_P_H +#define DUIINFOBANNERINFORMATIONVIEW_P_H + +#include "duiscenewindowview_p.h" + +class DuiLabel; +class DuiImageWidget; +class DuiButton; +class QGraphicsGridLayout; + +class DuiInfoBannerInformationViewPrivate : public DuiSceneWindowViewPrivate +{ + Q_DECLARE_PUBLIC(DuiInfoBannerInformationView) + +public: + DuiInfoBannerInformationViewPrivate(DuiInfoBanner *banner); + virtual ~DuiInfoBannerInformationViewPrivate(); + + virtual void init(); + virtual void setButtonText(const QString &text); + + //! A label for the banner text + DuiInfoBanner *banner; + DuiLabel *label; + DuiImageWidget *image; + DuiButton *button; + + //! The layout of the notification + QGraphicsGridLayout *layout; +}; + +#endif diff --git a/src/widgets/views/duilabelview.cpp b/src/widgets/views/duilabelview.cpp new file mode 100644 index 000000000..0bd337095 --- /dev/null +++ b/src/widgets/views/duilabelview.cpp @@ -0,0 +1,209 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duilabelview.h" +#include "duilabelview_p.h" +#include "duilabelmodel.h" +#include "duilabel.h" +#include "duiviewcreator.h" + +#include +#include +#include +#include +#include + +DuiLabelViewPrivate::DuiLabelViewPrivate() +{ + impl = new DuiLabelViewSimple(this); + cacheKey.sprintf("%p", (void *)(this)); +} + +DuiLabelViewPrivate::~DuiLabelViewPrivate() +{ + delete impl; +} + +const DuiLabelModel *DuiLabelViewPrivate::model() const +{ + Q_Q(const DuiLabelView); + return q->model(); +} + +const DuiLabelStyle *DuiLabelViewPrivate::style() const +{ + Q_Q(const DuiLabelView); + return q->style().operator ->(); +} + +const QRectF DuiLabelViewPrivate::boundingRect() const +{ + Q_Q(const DuiLabelView); + return q->boundingRect(); +} + +DuiLabelView::DuiLabelView(DuiLabel *controller) : + DuiWidgetView(new DuiLabelViewPrivate) +{ + Q_D(DuiLabelView); + d->controller = controller; +} + +DuiLabelView::~DuiLabelView() +{ +} + +void DuiLabelView::applyStyle() +{ + DuiWidgetView::applyStyle(); + Q_D(DuiLabelView); + QPixmapCache::remove(d->cacheKey); + d->impl->applyStyle(); + updateGeometry(); +} + +void DuiLabelView::drawContents(QPainter *painter, const QStyleOptionGraphicsItem *option) const +{ + Q_D(const DuiLabelView); + Q_UNUSED(option); + + //give size adjusted with padding to the actual implementation class + QSizeF padding(style()->paddingLeft() + style()->paddingRight(), + style()->paddingTop() + style()->paddingBottom()); + d->impl->drawContents(painter, size() - padding); +} + +void DuiLabelView::resizeEvent(QGraphicsSceneResizeEvent *event) +{ + DuiWidgetView::resizeEvent(event); + + Q_D(DuiLabelView); + QPixmapCache::remove(d->cacheKey); + + QSizeF padding(style()->paddingLeft() + style()->paddingRight(), + style()->paddingTop() + style()->paddingBottom()); + + event->setOldSize(event->oldSize() - padding); + event->setNewSize(event->newSize() - padding); + + if (d->impl->resizeEvent(event)) { + updateGeometry(); + } +} + +QFont DuiLabelView::font() const +{ + return style()->font(); +} + +QSizeF DuiLabelView::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const +{ + Q_D(const DuiLabelView); + + QSizeF size = DuiWidgetView::sizeHint(which, constraint); + if (!size.isValid()) { + QSizeF implsize = d->impl->sizeHint(which, constraint); + if (size.width() == -1) + size.setWidth(implsize.width() + style()->paddingLeft() + style()->paddingRight()); + if (size.height() == -1) + size.setHeight(implsize.height() + style()->paddingTop() + style()->paddingBottom()); + } + return size; +} + +void DuiLabelView::setupModel() +{ + DuiWidgetView::setupModel(); + Q_D(DuiLabelView); + + bool isRichText = Qt::mightBeRichText(model()->text()); + // Check has label type changed since last call to this method. Re-allocate label with correct type. + if (d->impl->isRich() != isRichText) { + delete d->impl; + if (isRichText) + d->impl = new DuiLabelViewRich(d); + else + d->impl = new DuiLabelViewSimple(d); + } + d->impl->setupModel(); + + QPixmapCache::remove(d->cacheKey); +} + + +void DuiLabelView::updateData(const QList& modifications) +{ + + DuiWidgetView::updateData(modifications); + + Q_D(DuiLabelView); + + if (modifications.contains(DuiLabelModel::Text)) { + bool isRichText = Qt::mightBeRichText(model()->text()); + // Check has label type changed since last call to this method. Re-allocate label with correct type. + if (d->impl->isRich() != isRichText) { + delete d->impl; + if (isRichText) + d->impl = new DuiLabelViewRich(d); + else + d->impl = new DuiLabelViewSimple(d); + } + } + + if (d->impl->updateData(modifications)) + updateGeometry(); + QPixmapCache::remove(d->cacheKey); + update(); +} + +void DuiLabelView::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + Q_D(DuiLabelView); + d->impl->mousePressEvent(event); +} + +void DuiLabelView::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + Q_D(DuiLabelView); + d->impl->mouseReleaseEvent(event); +} + +void DuiLabelView::cancelEvent(DuiCancelEvent *event) +{ + Q_D(DuiLabelView); + d->impl->cancelEvent(event); +} + +void DuiLabelView::longPressEvent(QGraphicsSceneContextMenuEvent *event) +{ + Q_D(DuiLabelView); + event->ignore(); + d->impl->longPressEvent(event); +} + + +DUI_REGISTER_VIEW_NEW(DuiLabelView, DuiLabel) + + + + + + + + diff --git a/src/widgets/views/duilabelview.h b/src/widgets/views/duilabelview.h new file mode 100644 index 000000000..5882f9aba --- /dev/null +++ b/src/widgets/views/duilabelview.h @@ -0,0 +1,144 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUILABELVIEW_H +#define DUILABELVIEW_H + +#include +#include +#include + +class DuiLabel; +class DuiLabelViewPrivate; +class QGraphicsSceneResizeEvent; +class DuiCancelEvent; + +/*! + \class DuiLabelView + \brief Standard view class for DuiLabel. + + \ingroup views + + \section DuiLabelViewOverview Overview + Label view class that supports rendering of simple unformatted text and rich + html formatted text. + + + + + + + + + + + + + + + + + + +
\image html label_simple.png Default simple label.
\image html label_simple_custom.png Simple label with custom font and color.
\image html label_simple_elided.png Simple label with eliding enabled.
\image html label_rich.png Rich label with html styling.
+ + \section DuiLabelViewInteractions Interactions + Links in rich text can be opened by clicking them. Simple unformatted label + is totally non-interactive. + + \section DuiLabelViewOpenIssues Open issues + - Rich label should support text selection. + - Graphics: Appearance of the link, text selection needs to be defined. Does the link have icon + styled text, or only styled text? + - Guidelines for truncating phone number, localized strings, rich label beginning truncation maybe needed later. + + \sa DuiLabelStyle DuiWidgetView +*/ + +class DUI_EXPORT DuiLabelView : public DuiWidgetView +{ + //FIXME + //Temporary remove this when proper longPressEvents are coming to view. + friend class DuiLabel; + + Q_OBJECT + DUI_VIEW(DuiLabelModel, DuiLabelStyle) + +public: + + /*! + \brief Constructs label view. + \param Pointer to the controller. + */ + DuiLabelView(DuiLabel *controller); + + /*! + \brief Destructs label view. + */ + virtual ~DuiLabelView(); + + //! \reimp + virtual void drawContents(QPainter *painter, const QStyleOptionGraphicsItem *option) const; + virtual void resizeEvent(QGraphicsSceneResizeEvent *event); + //! \reimp_end + +protected: + + /*! + \brief Mouse press event handler. + + Accepted when displaying rich text and when clicking an anchor. Ignored + if displaying simple text or clicking outside anchor. + */ + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + + /*! + \brief Mouse release event handler. + + If released over an anchor DuiLabelModel::linkActivated() signal is emitted. + */ + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + + //FIXME + //Temporary remove this when proper longPressEvents are coming to view. + void longPressEvent(QGraphicsSceneContextMenuEvent *event); + + //! \reimp + virtual QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const; + virtual void setupModel(); + virtual void applyStyle(); + virtual QFont font() const; + virtual void cancelEvent(DuiCancelEvent *event); + //! \reimp_end + +protected Q_SLOTS: + + //! \reimp + virtual void updateData(const QList& modifications); + //! \reimp_end + +private: + Q_DISABLE_COPY(DuiLabelView) + Q_DECLARE_PRIVATE(DuiLabelView) + +#ifdef UNIT_TEST + friend class Pt_DuiLabel; +#endif +}; + +#endif diff --git a/src/widgets/views/duilabelview_p.h b/src/widgets/views/duilabelview_p.h new file mode 100644 index 000000000..b7b48324f --- /dev/null +++ b/src/widgets/views/duilabelview_p.h @@ -0,0 +1,111 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUILABELVIEW_P_H +#define DUILABELVIEW_P_H + +#include +#include +#include "private/duiwidgetview_p.h" + +class DuiLabel; +class DuiLabelView; +class QGraphicsSceneResizeEvent; + + +class DuiLabelViewSimple +{ +public: + DuiLabelViewSimple(DuiLabelViewPrivate *viewPrivate); + virtual ~DuiLabelViewSimple(); + + virtual QPixmap generatePixmap(); + virtual void drawContents(QPainter *painter, const QSizeF &size); + virtual bool resizeEvent(QGraphicsSceneResizeEvent *event); + virtual QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const; + virtual void setupModel(); + virtual bool updateData(const QList& modifications); + virtual bool isRich(); + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + virtual void cancelEvent(DuiCancelEvent *event); + virtual void longPressEvent(QGraphicsSceneContextMenuEvent *event); + virtual void applyStyle(); + + DuiLabelViewPrivate *viewPrivate; + + QSizeF preferredSize; + QPoint textOffset; +}; + +class DuiLabelViewRich : public DuiLabelViewSimple +{ + +public: + DuiLabelViewRich(DuiLabelViewPrivate *viewPrivate); + virtual ~DuiLabelViewRich(); + + virtual QPixmap generatePixmap(); + virtual void drawContents(QPainter *painter, const QSizeF &size); + virtual bool shouldElide() const; + virtual bool resizeEvent(QGraphicsSceneResizeEvent *event); + virtual QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const; + virtual void setupModel(); + virtual bool updateData(const QList& modifications); + virtual bool isRich(); + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + virtual void cancelEvent(DuiCancelEvent *event); + virtual void longPressEvent(QGraphicsSceneContextMenuEvent *event); + + virtual void applyStyle(); + + void ensureDocumentIsReady(); + int cursorPositionOfLastVisibleCharacter(); + void updateRichTextEliding(); + void updateHighlighting(); + QString wrapTextWithSpanTag(const QString &text) const; + + mutable QTextDocument textDocument; + bool textDocumentDirty; + QPoint pixmapOffset; + int mouseDownCursorPos; +}; + +class DuiLabelViewPrivate : public DuiWidgetViewPrivate +{ + Q_DECLARE_PUBLIC(DuiLabelView) + +public: + DuiLabelViewPrivate(); + virtual ~DuiLabelViewPrivate(); + + const DuiLabelModel *model() const; + const DuiLabelStyle *style() const; + const QRectF boundingRect() const; + + // need define this for there are overload functions in controller + DuiLabel *controller; + + QString cacheKey; + DuiLabelViewSimple *impl; + QTextOption textOptions; +}; + +#endif diff --git a/src/widgets/views/duilabelview_rich.cpp b/src/widgets/views/duilabelview_rich.cpp new file mode 100644 index 000000000..3e032df0b --- /dev/null +++ b/src/widgets/views/duilabelview_rich.cpp @@ -0,0 +1,461 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duilabelview.h" +#include "duilabelview_p.h" +#include "duilabelmodel.h" +#include "duifeedback.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "duiviewcreator.h" +#include "duilabel.h" +#include "duilabel_p.h" +#include "duilabelhighlighter.h" +#include "duidebug.h" + +static const QString unicodeEllipsisString = QString("...");//QChar(0x2026); + +static const int DUI_HIGHLIGHT_PROPERTY = QTextFormat::UserProperty; +static const int DUI_HIGHLIGHTER_ID_PROPERTY = QTextFormat::UserProperty + 1; + +DuiLabelViewRich::DuiLabelViewRich(DuiLabelViewPrivate *viewPrivate) : + DuiLabelViewSimple(viewPrivate), textDocumentDirty(true), mouseDownCursorPos(-1) +{ + textDocument.setDocumentMargin(0); +} + +DuiLabelViewRich::~DuiLabelViewRich() +{ +} + + +QPixmap DuiLabelViewRich::generatePixmap() +{ + ensureDocumentIsReady(); + updateRichTextEliding(); + updateHighlighting(); + + // Document's rect can be very big if it doesn't fit label's space, however + // label as well can be bigger then the amount of text. Intersecting 2 rectangles + // will give us smallest visible area, where content should be painted. + QRectF paintingRect = QRectF(QPointF(0, 0), textDocument.size()).intersected(viewPrivate->boundingRect()); + + //include horizontal padding into the pixmap to make + //the text wrap correctly, the vertical padding is added + //when drawing the pixmap into the screen + const DuiLabelStyle *style = viewPrivate->style(); + paintingRect.adjust(0, 0, style->paddingLeft(), 0); + + //draw the textdocument into the pixmap + QPixmap pixmap(paintingRect.size().toSize()); + if (!pixmap.isNull()) { + pixmap.fill(Qt::transparent); + QPainter painter(&pixmap); + painter.translate(style->paddingLeft(), 0); + textDocument.drawContents(&painter, paintingRect); + } + + return pixmap; +} + +void DuiLabelViewRich::drawContents(QPainter *painter, const QSizeF &size) +{ + QPixmap pixmap; + if (!QPixmapCache::find(viewPrivate->cacheKey, pixmap)) { + pixmap = generatePixmap(); + QPixmapCache::insert(viewPrivate->cacheKey, pixmap); + } + if (!pixmap.isNull()) { + // There's no way to set document height to QTextDocument. The document height contains + // only the area which has text written, therefore being 'compact'. This leads to fact that + // the vertical alignment is not working, because the widget can be bigger in size when compared + // to the text document. Therefore we need to do the vertical alignment manually in here. + // Perform manual alignment for bottom alignment. + pixmapOffset = QPoint(0, viewPrivate->style()->paddingTop()); + if (viewPrivate->textOptions.alignment() & Qt::AlignBottom) { + pixmapOffset.setY(viewPrivate->style()->paddingTop() + size.height() - pixmap.size().height()); + } + // Perform manual alignment for vertical center alignment. + else if (viewPrivate->textOptions.alignment() & Qt::AlignVCenter) { + pixmapOffset.setY(viewPrivate->style()->paddingTop() + ((size.height() / 2) - (pixmap.size().height() / 2))); + } + + painter->drawPixmap(pixmapOffset, pixmap); + } +} + +/** + * Returns true if label should be elided. + */ +bool DuiLabelViewRich::shouldElide() const +{ + static const int MAXIMUM_NON_ELIDING_TEXT_SIZE = 4; + return viewPrivate->model()->textElide() && ((textDocument.size().width() > viewPrivate->boundingRect().size().width()) || (textDocument.size().height() > viewPrivate->boundingRect().size().height())) && (textDocument.characterCount() > MAXIMUM_NON_ELIDING_TEXT_SIZE); +} + +void DuiLabelViewRich::ensureDocumentIsReady() +{ + if (textDocumentDirty) { + // QTextDocument doesn't update layout when text options + // are set. + textDocumentDirty = false; + textDocument.setDefaultTextOption(viewPrivate->textOptions); + textDocument.setUndoRedoEnabled(true); + textDocument.setDefaultFont(viewPrivate->controller->font()); + // default text color can be specified only via stylesheet. However + // text should be enclosed with tags: text to let CSS + // engine apply color + QColor textColor(viewPrivate->model()->color().isValid() ? viewPrivate->model()->color() : viewPrivate->style()->color()); + QColor anchorColor(viewPrivate->style()->highlightColor()); + QString styleSheet = QString::fromLatin1("* { color: %1; } a {color: %2;}").arg(textColor.name()).arg(anchorColor.name()); + textDocument.setDefaultStyleSheet(styleSheet); + + // To force it relayout text, it should be set again + QString t = viewPrivate->model()->text(); + t.replace(QChar('\n'), "
"); + textDocument.setHtml(wrapTextWithSpanTag(t)); + //textDocument.setHtml(wrapTextWithSpanTag(viewPrivate->model()->text())); + } +} + +bool DuiLabelViewRich::resizeEvent(QGraphicsSceneResizeEvent *event) +{ + // There is no way to specify sizeHint for a text without knowing possible width. + + // 1st phase, when QT calls sizeHint, view will return approximate values for + // minimum and preffered size. When resizeEvent comes, layout already knows + // sizes of components, and here comes + // 2nd phase, when we identify widget's height, based on width. Our height will + // change and we don't want to occupy more space then need, so we have to call + // updateGeometry, to tell layout to update sizeHint cache. This function + // return true if such update is needed. + // forward resize event to text document + // if height is changed + QSizeF oldSize(textDocument.size()); + textDocument.setTextWidth(event->newSize().width()); + QSizeF newSize(textDocument.size()); + if (newSize.height() != oldSize.height()) + return true; + else + return false; +} + +QSizeF DuiLabelViewRich::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const +{ + switch (which) { + case Qt::MinimumSize: { + QFontMetrics fm(viewPrivate->controller->font()); + return QSizeF(fm.width(""), textDocument.size().height()); + } + + case Qt::PreferredSize: { + //remove existing eliding if there + textDocument.undo(); + + // resize text document to constraint width, + // then return its size + QSizeF size; + if (constraint.width() > 0) { + qreal oldWidth = textDocument.textWidth(); + textDocument.setTextWidth(constraint.width()); + size = textDocument.size(); + textDocument.setTextWidth(oldWidth); + } else { + size = textDocument.size(); + } + + return size; + } + + case Qt::MaximumSize: + return QSizeF(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); + + default: + qWarning("DuiLabel::sizeHint() don't know how to handle the value of 'which' "); + } + + return QSizeF(0, 0); +} + +void DuiLabelViewRich::setupModel() +{ + const DuiLabelModel *model = viewPrivate->model(); + viewPrivate->textOptions.setWrapMode(model->wordWrap() ? QTextOption::WordWrap : QTextOption::NoWrap); + viewPrivate->textOptions.setTextDirection(model->textDirection()); + viewPrivate->textOptions.setAlignment(model->alignment()); + + // We have to update rich text document now because next call + // can be sizeHint and at that time will be too late to do it + //textDocument.setHtml(model->text()); + textDocumentDirty = true; + ensureDocumentIsReady(); +} + +bool DuiLabelViewRich::updateData(const QList& modifications) +{ + //mark as true if sizehint needs updating + bool needUpdate = false; + + const DuiLabelModel *model = viewPrivate->model(); + const char *member = NULL; + foreach(member, modifications) { + if (member == DuiLabelModel::Text) { + //textDocument.setHtml(model->text()); + + // Document text width must be enlarged just like resizeEvent() + // does with labels that initially have richtext content. + textDocument.setTextWidth(viewPrivate->boundingRect().width()); + needUpdate = true; + textDocumentDirty = true; + } else if (member == DuiLabelModel::WordWrap) { + if (model->wordWrap()) { + viewPrivate->textOptions.setWrapMode(QTextOption::WordWrap); + } else { + viewPrivate->textOptions.setWrapMode(QTextOption::NoWrap); + } + textDocumentDirty = true; + } else if (member == DuiLabelModel::TextDirection) { + viewPrivate->textOptions.setTextDirection(model->textDirection()); + textDocumentDirty = true; + } else if (member == DuiLabelModel::Alignment) { + viewPrivate->textOptions.setAlignment(model->alignment()); + textDocumentDirty = true; + } else if (member == DuiLabelModel::TextElide) { + textDocumentDirty = true; + } else if (member == DuiLabelModel::UseModelFont || member == DuiLabelModel::Font) { + textDocument.setTextWidth(viewPrivate->boundingRect().width()); + needUpdate = true; + textDocumentDirty = true; + } else if (member == DuiLabelModel::Highlighters) { + textDocumentDirty = true; + } + } + + // We have to update rich text document now because next call + // can be sizeHint and at that time will be too late to do it + ensureDocumentIsReady(); + return needUpdate; +} + +bool DuiLabelViewRich::isRich() +{ + return true; +} + +void DuiLabelViewRich::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + event->ignore(); + int cursorPos = textDocument.documentLayout()->hitTest(event->pos() - pixmapOffset, Qt::ExactHit); + if (cursorPos >= 0) { + QTextCursor cursor(&textDocument); + cursor.setPosition(cursorPos); + QTextCharFormat format = cursor.charFormat(); + //highlighted anchor is pressed + if (format.boolProperty(DUI_HIGHLIGHT_PROPERTY)) { + event->accept(); + mouseDownCursorPos = cursorPos; + QPixmapCache::remove(viewPrivate->cacheKey); + viewPrivate->controller->update(); + viewPrivate->style()->pressFeedback().play(); + } + //application defined anchor is pressed + else if (format.isAnchor()) { + event->accept(); + viewPrivate->style()->pressFeedback().play(); + } + } +} + +void DuiLabelViewRich::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + int cursorPos = textDocument.documentLayout()->hitTest(event->pos() - pixmapOffset, Qt::ExactHit); + if (cursorPos >= 0) { + QTextCursor cursor(&textDocument); + cursor.setPosition(cursorPos); + QTextCharFormat format = cursor.charFormat(); + //highlighted anchor is released + if (format.boolProperty(DUI_HIGHLIGHT_PROPERTY)) { + int idx = cursor.charFormat().intProperty(DUI_HIGHLIGHTER_ID_PROPERTY); + if (idx < viewPrivate->model()->highlighters().size()) + viewPrivate->model()->highlighters()[idx]->click(format.anchorHref()); + + viewPrivate->style()->releaseFeedback().play(); + } + //application defined anchor is released + else if (format.isAnchor()) { + viewPrivate->style()->releaseFeedback().play(); + viewPrivate->model()->emitLinkActivated(format.anchorHref()); + } + } + mouseDownCursorPos = -1; + QPixmapCache::remove(viewPrivate->cacheKey); + viewPrivate->controller->update(); +} + +void DuiLabelViewRich::cancelEvent(DuiCancelEvent *event) +{ + Q_UNUSED(event); + if (mouseDownCursorPos > 0) { + mouseDownCursorPos = -1; + QPixmapCache::remove(viewPrivate->cacheKey); + viewPrivate->controller->update(); + viewPrivate->style()->releaseFeedback().play(); + } +} + +void DuiLabelViewRich::longPressEvent(QGraphicsSceneContextMenuEvent *event) +{ + int cursorPos = textDocument.documentLayout()->hitTest(event->pos() - pixmapOffset, Qt::ExactHit); + if (cursorPos >= 0) { + QTextCursor cursor(&textDocument); + cursor.setPosition(cursorPos); + QTextCharFormat format = cursor.charFormat(); + if (format.boolProperty(DUI_HIGHLIGHT_PROPERTY)) { + event->accept(); + int idx = cursor.charFormat().intProperty(DUI_HIGHLIGHTER_ID_PROPERTY); + if (idx < viewPrivate->model()->highlighters().size()) + viewPrivate->model()->highlighters()[idx]->longPress(format.anchorHref()); + + viewPrivate->style()->pressFeedback().play(); + } + } + mouseDownCursorPos = -1; + QPixmapCache::remove(viewPrivate->cacheKey); + viewPrivate->controller->update(); +} + + +/** + * Find cursor position of last visible character of document. + * It starts from the bottom right corner, goes up until finds + * text by hitTest function. + * + * @return cursor position + */ +int DuiLabelViewRich::cursorPositionOfLastVisibleCharacter() +{ + QPointF bottomRight(viewPrivate->boundingRect().bottomRight()); + // defines how quickly we will scan through area + QPointF delta(0, 5); + int cursorPos = -1; + while (bottomRight.y() > delta.y() && cursorPos == -1) { + cursorPos = textDocument.documentLayout()->hitTest(bottomRight, Qt::ExactHit); + bottomRight -= delta; + } + + return cursorPos; +} + +void DuiLabelViewRich::updateRichTextEliding() +{ + // if we cut several characters last time + // undo() will put them back + textDocument.undo(); + + if (shouldElide()) { + //TODO + //Reconsider this. How can we efficiently find last FULLY visible character? + //Hit testing per pixel basis was bad and was not properly working. This + //implementation is as bad but this works correctly. + + //estimate the last visible character by roughly removing text from label + int charJump = (textDocument.characterCount() <= 30) ? textDocument.characterCount() / 2 : 20; + QTextCursor cursor(&textDocument); + cursor.beginEditBlock(); + while (shouldElide()) { + cursor.movePosition(QTextCursor::End); + charJump = (cursor.position() <= charJump) ? (textDocument.characterCount() / 2) : 20; + cursor.setPosition(cursor.position() - charJump, QTextCursor::KeepAnchor); + cursor.removeSelectedText(); + textDocument.setTextWidth(viewPrivate->boundingRect().size().width()); + } + cursor.endEditBlock(); + int charcount = textDocument.characterCount() + charJump; + textDocument.undo(); + + //find the last visible character by removing one character at a time + //starting from the rough estimation end position + charJump = 1; + cursor.beginEditBlock(); + cursor.movePosition(QTextCursor::End); + cursor.movePosition(QTextCursor::Left, QTextCursor::KeepAnchor, textDocument.characterCount() - charcount + unicodeEllipsisString.size()); + cursor.insertText(unicodeEllipsisString); + textDocument.setTextWidth(viewPrivate->boundingRect().size().width()); + while (shouldElide()) { + cursor.movePosition(QTextCursor::End); + cursor.setPosition(cursor.position() - charJump - unicodeEllipsisString.size(), QTextCursor::KeepAnchor); + cursor.insertText(unicodeEllipsisString); + textDocument.setTextWidth(viewPrivate->boundingRect().size().width()); + } + cursor.endEditBlock(); + } +} + +void DuiLabelViewRich::updateHighlighting() +{ + //TODO: Should the highlight format come from the highlighter object? + + DuiLabelHighlighterList list = viewPrivate->model()->highlighters(); + const int listSize = list.size(); + for (int i = 0; i < listSize; ++i) { + const DuiLabelHighlighter *highlighter = list[i]; + QTextCursor cursor(&textDocument); + while (!cursor.isNull() && !cursor.atEnd()) { + cursor = textDocument.find(highlighter->highlightExpression(), cursor); + if (!cursor.isNull()) { + QString item = cursor.selectedText(); + if (highlighter->validate(item)) { + QTextCharFormat format = cursor.charFormat(); + format.setFontUnderline(true); + format.setAnchor(true); + format.setAnchorHref(item); + format.setProperty(DUI_HIGHLIGHT_PROPERTY, true); + format.setProperty(DUI_HIGHLIGHTER_ID_PROPERTY, i); + if (mouseDownCursorPos >= cursor.selectionStart() && mouseDownCursorPos <= cursor.selectionEnd()) { + format.setForeground(QBrush(viewPrivate->style()->activeHighlightColor())); + //format.setBackground(QBrush(viewPrivate->style()->activeHighlightColor())); + } else + format.setForeground(QBrush(viewPrivate->style()->highlightColor())); + //cursor.mergeCharFormat(format); + cursor.setCharFormat(format); + } + } + } + } +} + + +QString DuiLabelViewRich::wrapTextWithSpanTag(const QString &text) const +{ + QString spanTag("%1"); + return spanTag.arg(text); +} + +void DuiLabelViewRich::applyStyle() +{ + textDocumentDirty = true; + ensureDocumentIsReady(); +} diff --git a/src/widgets/views/duilabelview_simple.cpp b/src/widgets/views/duilabelview_simple.cpp new file mode 100644 index 000000000..f42442b81 --- /dev/null +++ b/src/widgets/views/duilabelview_simple.cpp @@ -0,0 +1,222 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duilabelview.h" +#include "duilabelview_p.h" +#include "duilabelmodel.h" +#include "duilabel.h" +#include "duiviewcreator.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +DuiLabelViewSimple::DuiLabelViewSimple(DuiLabelViewPrivate *viewPrivate) : + viewPrivate(viewPrivate), preferredSize(-1, -1) +{ +} + +DuiLabelViewSimple::~DuiLabelViewSimple() +{ + QPixmapCache::remove(viewPrivate->cacheKey); +} + +QPixmap DuiLabelViewSimple::generatePixmap() +{ + const DuiLabelModel *model = viewPrivate->model(); + const DuiLabelStyle *style = viewPrivate->style(); + QRectF paintingRect(viewPrivate->boundingRect().adjusted(style->paddingLeft(), style->paddingTop(), -style->paddingRight(), -style->paddingBottom())); + QString textToRender = model->text(); + if (model->textElide() && textToRender.size() > 4) { + QFontMetrics fm(viewPrivate->controller->font()); + textToRender = fm.elidedText(model->text(), Qt::ElideRight, paintingRect.width()); + } + + if (textToRender.isEmpty()) { + return QPixmap(); + } + + QImage fontImg(1, 1, QImage::Format_ARGB32_Premultiplied); + QPainter fontPainter(&fontImg); + fontPainter.setFont(viewPrivate->controller->font()); + fontPainter.setLayoutDirection(model->textDirection()); + QRectF fontBoundingRect = fontPainter.boundingRect(paintingRect, viewPrivate->textOptions.alignment() | Qt::TextSingleLine, textToRender); + + QPixmap pixmap(fontBoundingRect.size().toSize()); + if (!pixmap.isNull()) { + pixmap.fill(Qt::transparent); + QPainter painter(&pixmap); + painter.setFont(viewPrivate->controller->font()); + painter.setPen(model->color().isValid() ? model->color() : style->color()); + painter.setLayoutDirection(model->textDirection()); + painter.drawText(QRect(0, 0, fontBoundingRect.width(), fontBoundingRect.height()), viewPrivate->textOptions.alignment() | Qt::TextSingleLine, textToRender); + + textOffset.setX(fontBoundingRect.x()); + textOffset.setY(fontBoundingRect.y()); + } + + return pixmap; +} + +void DuiLabelViewSimple::drawContents(QPainter *painter, const QSizeF &size) +{ + Q_UNUSED(size); + QPixmap pixmap; + if (!QPixmapCache::find(viewPrivate->cacheKey, pixmap)) { + pixmap = generatePixmap(); + QPixmapCache::insert(viewPrivate->cacheKey, pixmap); + } + if (!pixmap.isNull()) { + painter->drawPixmap(textOffset, pixmap); + } +} + +bool DuiLabelViewSimple::resizeEvent(QGraphicsSceneResizeEvent *event) +{ + // There is no way to specify sizeHint for a text without knowing possible width. + // 1st phase, when Qt calls sizeHint, view will return approximate values for + // minimum and preferred size. When resizeEvent comes, layout already knows + // sizes of components, and here comes + // 2nd phase, when we identify widget's height, based on width. Our height will + // change and we don't want to occupy more space then need, so we have to call + // updateGeometry, to tell layout to update sizeHint cache. This function + // return true if such update is needed. + + QFontMetricsF fm(viewPrivate->controller->font()); + QRectF bR = fm.boundingRect(QRectF(QPoint(0, 0), event->newSize()), viewPrivate->textOptions.alignment(), viewPrivate->model()->text()); + if (bR.height() > fm.height()) { + preferredSize = QSizeF(bR.width(), bR.height()); + return true; + } else + return false; +} + +QSizeF DuiLabelViewSimple::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const +{ + switch (which) { + case Qt::MinimumSize: { + QFontMetricsF fm(viewPrivate->controller->font()); + QRectF r(0, 0, constraint.width(), constraint.height()); + + if (r.width() < 0) { + r.setWidth(QWIDGETSIZE_MAX); + } + if (r.height() < 0) { + r.setHeight(QWIDGETSIZE_MAX); + } + + QRectF bR(fm.boundingRect(r, viewPrivate->textOptions.alignment() | Qt::TextSingleLine, + viewPrivate->model()->text())); + + return QSizeF(fm.width(""), bR.height()); + } + case Qt::PreferredSize: { + qreal w = constraint.width(); + qreal h = constraint.height(); + if (w < 0) { + w = QWIDGETSIZE_MAX; + } + if (h < 0) { + h = QWIDGETSIZE_MAX; + } + if (preferredSize.width() >= 0 && preferredSize.width() < w) + w = preferredSize.width(); + if (preferredSize.height() >= 0 && preferredSize.height() < h) + h = preferredSize.height(); + + QFontMetricsF fm(viewPrivate->controller->font()); + QRectF bR(fm.boundingRect(QRectF(0, 0, w, h), viewPrivate->textOptions.alignment() | Qt::TextSingleLine, + viewPrivate->model()->text())); + return bR.size().boundedTo(QSizeF(w, h)); + } + case Qt::MaximumSize: { + return QSizeF(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); + } + default: + qWarning("DuiLabel::sizeHint() don't know how to handle the value of 'which' "); + } + + return QSizeF(0, 0); +} + +void DuiLabelViewSimple::setupModel() +{ + viewPrivate->textOptions.setTextDirection(viewPrivate->model()->textDirection()); + viewPrivate->textOptions.setAlignment(viewPrivate->model()->alignment()); +} + +bool DuiLabelViewSimple::updateData(const QList& modifications) +{ + const char *member = NULL; + bool needUpdate = false; + + foreach(member, modifications) { + if (member == DuiLabelModel::Text) { + preferredSize = QSizeF(-1, -1); + needUpdate = true; + } else if (member == DuiLabelModel::WordWrap) { + if (viewPrivate->model()->wordWrap()) { + viewPrivate->textOptions.setWrapMode(QTextOption::WordWrap); + } else { + viewPrivate->textOptions.setWrapMode(QTextOption::NoWrap); + } + } else if (member == DuiLabelModel::TextDirection) { + viewPrivate->textOptions.setTextDirection(viewPrivate->model()->textDirection()); + } else if (member == DuiLabelModel::Alignment) { + viewPrivate->textOptions.setAlignment(viewPrivate->model()->alignment()); + } else if (member == DuiLabelModel::UseModelFont || member == DuiLabelModel::Font) { + needUpdate = true; + } + } + return needUpdate; +} + +bool DuiLabelViewSimple::isRich() +{ + return false; +} + +void DuiLabelViewSimple::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + event->ignore(); //propagate link up to owner of label +} + +void DuiLabelViewSimple::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + Q_UNUSED(event); +} + +void DuiLabelViewSimple::cancelEvent(DuiCancelEvent *event) +{ + Q_UNUSED(event); +} + +void DuiLabelViewSimple::longPressEvent(QGraphicsSceneContextMenuEvent *event) +{ + Q_UNUSED(event); +} + +void DuiLabelViewSimple::applyStyle() +{ +} diff --git a/src/widgets/views/duimenuobjectview.cpp b/src/widgets/views/duimenuobjectview.cpp new file mode 100644 index 000000000..00fcc5110 --- /dev/null +++ b/src/widgets/views/duimenuobjectview.cpp @@ -0,0 +1,443 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duimenuobjectview.h" + +#include + +#include "duiapplicationmenu.h" +#include "duimenuobjectview_p.h" +#include "duibutton.h" +#include "duiviewcreator.h" + +#include "duipannableviewport.h" +#include "duiwidgetaction.h" +#include "duitheme.h" +#include "duiscalableimage.h" +#include "duiscenemanager.h" +#include "duilayout.h" +#include "duilinearlayoutpolicy.h" +#include + +DuiObjectMenuLayoutPolicy::DuiObjectMenuLayoutPolicy(DuiLayout *layout) : + DuiAbstractLayoutPolicy(layout) +{ } + +void DuiObjectMenuLayoutPolicy::setItemGeometry(QGraphicsLayoutItem *item, const QRectF &geom) +{ + geometries[item] = geom; + + QSizeF maximum = item->effectiveSizeHint(Qt::MaximumSize); + QSizeF minimum = item->effectiveSizeHint(Qt::MinimumSize); + QRectF new_geometry = QRectF(geom.topLeft(), geom.size().boundedTo(maximum).expandedTo(minimum)); + + QRectF target(contentsArea().topLeft() + new_geometry.topLeft(), new_geometry.size()); + setItemGeometry(item, target); + + updateGeometry(); +} + +void DuiObjectMenuLayoutPolicy::removeAt(int index) +{ + QGraphicsLayoutItem *item = itemAt(index); + if (item) { + geometries.remove(item); + } + DuiAbstractLayoutPolicy::removeAt(index); +} + +void DuiObjectMenuLayoutPolicy::relayout() +{ + QPointF topLeft = contentsArea().topLeft(); + + int i = count(); + while (--i >= 0) { + QGraphicsLayoutItem *item = itemAt(i); + QRectF new_geometry = geometries[item]; + QSizeF maximum = item->effectiveSizeHint(Qt::MaximumSize); + QSizeF minimum = item->effectiveSizeHint(Qt::MinimumSize); + new_geometry = QRectF(new_geometry.topLeft(), new_geometry.size().boundedTo(maximum).expandedTo(minimum)); + + QPointF topLeft = contentsArea().topLeft(); + QRectF target(topLeft + new_geometry.topLeft(), new_geometry.size()); + setItemGeometry(item, target); + } +} + +void DuiObjectMenuLayoutPolicy::addItem(QGraphicsLayoutItem *item) +{ + DuiAbstractLayoutPolicy::addItem(item); +} + +QSizeF DuiObjectMenuLayoutPolicy::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const +{ + if (which == Qt::MaximumSize) { + // maximum size is the QWIDGETSIZE_MAX + QSizeF new_size = constraint; + if (new_size.width() < 0) + new_size.setWidth(QWIDGETSIZE_MAX); + if (new_size.height() < 0) + new_size.setHeight(QWIDGETSIZE_MAX); + return new_size; + } + + // minimum and preferred size of a layout is the bounding box of the children + int i = count(); + QRectF boundingBox; + while (--i >= 0) { + // iterate through children + boundingBox = boundingBox.united(itemGeometry(i)); + } + + qreal right, bottom; + layout()->getContentsMargins(NULL, NULL, &right, &bottom); + return QSizeF(boundingBox.right() + right - layout()->geometry().left(), boundingBox.bottom() + bottom - layout()->geometry().top()); +} + + + +DuiMenuObjectViewPrivate::DuiMenuObjectViewPrivate(DuiApplicationMenu *menu) + : controller(menu), + linearPolicy(0), customPolicy(0) +{ +} + +DuiMenuObjectViewPrivate::~DuiMenuObjectViewPrivate() +{ + removeEventFilter(controller); +} + +void DuiMenuObjectViewPrivate::refreshLayout() +{ + Q_Q(DuiMenuObjectView); + + if (controller->sceneManager() == 0) + return; + + // refresh layout items + int i; + for (i = customPolicy->count() - 1; i >= 0; --i) { + customPolicy->removeAt(i); + linearPolicy->removeAt(i); + } + + QList actions = controller->actions(); + const int actionsCount = actions.count(); + for (i = 0; i < actionsCount; ++i) { + QAction *action = actions[i]; + DuiAction *duiAction = qobject_cast(action); + if (!duiAction) continue; + if ((duiAction->location() & DuiAction::ObjectMenuLocation) == 0) continue; + if (!duiAction->isVisible()) continue; + + // add to both layouts + DuiWidget *widget = widgets.value(duiAction); + if (!widget) { + addWidget(action); + widget = widgets.value(duiAction); + } + + if (widget) { + linearPolicy->addItem(widget); + customPolicy->addItem(widget); + } + } + + const int width = q->size().width(); + + // if item count < 4, make it linear + const int customPolicyCount = customPolicy->count(); + if (customPolicy->count() < 4) { + for (i = 0; i < customPolicyCount; ++i) { + QGraphicsLayoutItem *item = customPolicy->itemAt(i); + QRectF rect(0, 0, 0, 0); + rect.setLeft(width / 4); + rect.setTop(i * q->style()->itemHeight()); + rect.setWidth(width / 2); + rect.setHeight(q->style()->itemHeight()); + customPolicy->setItemGeometry(item, rect); + } + } else { // otherwise make it two columns so that if the item count in both columns are not equal, the other is vertically centered + const bool even_count = (customPolicyCount % 2) == 0 ? true : false; + int row_count = customPolicyCount / 2; + + if (!even_count) + row_count++; + + // first column + for (i = 0; i < row_count; ++i) { + QGraphicsLayoutItem *item = customPolicy->itemAt(i); + QRectF rect(0, 0, 0, 0); + rect.setTop(i * q->style()->itemHeight()); + rect.setWidth(width / 2); + rect.setHeight(q->style()->itemHeight()); + customPolicy->setItemGeometry(item, rect); + } + + // second column + for (i = row_count; i < customPolicyCount; ++i) { + QGraphicsLayoutItem *item = customPolicy->itemAt(i); + + int row = i - row_count; + QRectF rect(0, 0, 0, 0); + rect.setTop(row * q->style()->itemHeight()); + rect.setLeft((width / 2)); + + if (!even_count) { + rect.setTop(rect.top() + (q->style()->itemHeight() / 2)); + } + + rect.setWidth(width / 2); + rect.setHeight(q->style()->itemHeight()); + customPolicy->setItemGeometry(item, rect); + } + } + + QSize visibleSceneSize = controller->sceneManager()->visibleSceneSize(Dui::Portrait); + // center the widgets, first the linear layout + qreal height = visibleSceneSize.height(); + qreal offset = height - ((qreal)linearPolicy->count() * (qreal)q->style()->itemHeight()); + linearPolicy->setContentsMargins(0, offset / 2.0, 0, offset / 2.0); + + visibleSceneSize.transpose(); + + // and the custom one + height = visibleSceneSize.height(); + offset = height - ((qreal)customPolicyCount / 2.0 * (qreal)q->style()->itemHeight()); + customPolicy->setContentsMargins(0, offset / 2.0, 0, offset / 2.0); +} + +void DuiMenuObjectViewPrivate::addWidget(QAction *action) +{ + Q_Q(DuiMenuObjectView); + + // check whether it is a dui action, TODO: Figure out if we need to support QActions + DuiAction *duiAction = qobject_cast(action); + if (!duiAction) + return; + + // is this an object menu item? + if ((duiAction->location() & DuiAction::ObjectMenuLocation) == 0) + return; + + // show only if it is visible + if (duiAction->isVisible()) { + + // Check whether a widget was submitted for this action, if not, create button + DuiWidgetAction *widgetAction = qobject_cast(duiAction); + + DuiWidget *widget = NULL; + + if (widgetAction) { + widget = widgetAction->requestWidget(container); + } else { + // create button for this action + DuiButton *button = new DuiButton(duiAction->text(), container); + button->setViewType("objectmenuitem"); + button->setIconID(duiAction->iconID()); + + QObject::connect(button, SIGNAL(clicked(bool)), controller, SLOT(hideMenu())); + QObject::connect(button, SIGNAL(clicked(bool)), action, SIGNAL(triggered())); + + // store this separately so we can later on access it + buttons.insert(duiAction, button); + widget = button; + } + + if (widget) { + // store widget so we can easily access it later on if needed + widgets.insert(duiAction, widget); + + // TODO: This could be better + QSize preferredSize(q->size().width() / 2, q->style()->itemHeight()); + widget->setPreferredSize(preferredSize); + widget->setMinimumHeight(q->style()->itemHeight()); + widget->setMaximumHeight(q->style()->itemHeight()); + widget->setVisible(true); + widget->setEnabled(action->isEnabled()); + + } + } +} + +void DuiMenuObjectViewPrivate::removeWidget(QAction *action) +{ + // check whether it is a dui action, TODO: Figure out if we need to support QActions + DuiAction *duiAction = qobject_cast(action); + if (!duiAction) + return; + + DuiWidget *widget = widgets.value(duiAction); + if (widget) { + // Remove the widget from both layouts + linearPolicy->removeItem(widget); + customPolicy->removeItem(widget); + + // Check whether we did the widget for this action and clean up + DuiButton *button = buttons.value(duiAction, NULL); + buttons.remove(duiAction); + widgets.remove(duiAction); + + DuiWidgetAction *widgetAction = qobject_cast(duiAction); + if (widgetAction) + widgetAction->releaseWidget(widget); + + if (button) + delete button; + } +} + +void DuiMenuObjectViewPrivate::actionChanged(QAction *action) +{ + DuiAction *da = qobject_cast(action); + + // check whether we did the button for this action + if (da) { + DuiButton *button = buttons.value(da, NULL); + if (button) { + // update button data accordingly + button->setText(da->text()); + button->setIconID(da->iconID()); + button->setEnabled(da->isEnabled()); + } + } +} + +void DuiMenuObjectViewPrivate::init() +{ + // create pannable viewport + viewport = new DuiPannableViewport(controller); + + // create container widget for pannable viewport + container = new DuiWidget; + viewport->setWidget(container); + + // create layout for controller, make it pannable + QGraphicsLinearLayout *controllerLayout = new QGraphicsLinearLayout(); + controllerLayout->setContentsMargins(0, 0, 0, 0); + controllerLayout->addItem(viewport); + controller->setLayout(controllerLayout); + + // create layout policies for portrait & landscape orientation + layout = new DuiLayout(container); + linearPolicy = new DuiLinearLayoutPolicy(layout, Qt::Vertical); + linearPolicy->setContentsMargins(0, 0, 0, 0); + customPolicy = new DuiObjectMenuLayoutPolicy(layout); + customPolicy->setContentsMargins(0, 0, 0, 0); + + controller->installEventFilter(this); +} + +bool DuiMenuObjectViewPrivate::eventFilter(QObject *obj, QEvent *e) +{ + QActionEvent *actionEvent = dynamic_cast(e); + + if (actionEvent) { + QAction *action = actionEvent->action(); + switch (e->type()) { + case QEvent::ActionAdded: + addWidget(action); + refreshLayout(); + break; + case QEvent::ActionRemoved: + removeWidget(action); + break; + case QEvent::ActionChanged: + actionChanged(action); + break; + default: + break; + } + } + + return QObject::eventFilter(obj, e); +} + + +DuiMenuObjectView::DuiMenuObjectView(DuiApplicationMenu *controller) : + DuiSceneWindowView(* new DuiMenuObjectViewPrivate(controller), controller) +{ + Q_D(DuiMenuObjectView); + d->init(); +} + +DuiMenuObjectView::DuiMenuObjectView(DuiMenuObjectViewPrivate &dd, DuiApplicationMenu *controller) : + DuiSceneWindowView(dd, controller) +{ + Q_D(DuiMenuObjectView); + d->init(); +} + +DuiMenuObjectView::~DuiMenuObjectView() +{ +} + +void DuiMenuObjectView::applyStyle() +{ + Q_D(DuiMenuObjectView); + + DuiSceneWindowView::applyStyle(); + + d->refreshLayout(); + + // Fix item heights, according to style + QSize preferredSize(size().width() / 2, style()->itemHeight()); + foreach(DuiWidget * widget, d->widgets) { + widget->setPreferredSize(preferredSize); + widget->setMinimumHeight(style()->itemHeight()); + widget->setMaximumHeight(style()->itemHeight()); + } + + // Activate proper policy + Dui::Orientation orientation = Dui::Landscape; + if (d->controller->sceneManager()) { + orientation = d->controller->sceneManager()->orientation(); + } + (orientation == Dui::Landscape) ? + d->customPolicy->activate() : + d->linearPolicy->activate(); +} + +void DuiMenuObjectView::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + //Do not pass the events through the menu window + event->accept(); +} + +void DuiMenuObjectView::drawBackground(QPainter *painter, const QStyleOptionGraphicsItem *option) const +{ + DuiSceneWindowView::drawBackground(painter, option); + + Q_D(const DuiMenuObjectView); + + if (style()->canvasOpacity() > 0.0) { + // draw canvas + painter->setOpacity(d->controller->effectiveOpacity() * style()->canvasOpacity()); + + QRectF canvasRect(QPoint(0, 0), size()); + if (style()->canvasImage()) + style()->canvasImage()->draw(canvasRect.toRect(), painter); + else { + QColor color = style()->canvasColor(); + painter->fillRect(canvasRect, QBrush(color)); + } + } +} + +DUI_REGISTER_VIEW_NEW(DuiMenuObjectView, DuiApplicationMenu) diff --git a/src/widgets/views/duimenuobjectview.h b/src/widgets/views/duimenuobjectview.h new file mode 100644 index 000000000..062674771 --- /dev/null +++ b/src/widgets/views/duimenuobjectview.h @@ -0,0 +1,73 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIMENUOBJECTVIEW_H +#define DUIMENUOBJECTVIEW_H + +#include "duiscenewindowview.h" +#include +#include +#include + +class DuiApplicationMenu; +class DuiMenuObjectViewPrivate; + +/*! + * \class DuiMenuObjectView + * \brief DuiMenuObjectView implements an object view for the DuiMenu widget + */ + +class DUI_EXPORT DuiMenuObjectView : public DuiSceneWindowView +{ + Q_OBJECT + DUI_VIEW(DuiApplicationMenuModel, DuiApplicationMenuStyle) + +public: + /*! + * \brief Constructor + * \param controller Pointer to the DuiMenu + */ + DuiMenuObjectView(DuiApplicationMenu *controller); + + /*! + * \brief Destructor + */ + virtual ~DuiMenuObjectView(); + +protected: + + //! \reimp + virtual void applyStyle(); + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + virtual void drawBackground(QPainter *painter, const QStyleOptionGraphicsItem *option) const; + //! \reimp_end + + DuiMenuObjectView(DuiMenuObjectViewPrivate &dd, DuiApplicationMenu *controller); + +private: + Q_DISABLE_COPY(DuiMenuObjectView) + Q_DECLARE_PRIVATE(DuiMenuObjectView) + +#ifdef UNIT_TEST + friend class Pt_DuiMenu; +#endif + +}; + +#endif diff --git a/src/widgets/views/duimenuobjectview_p.h b/src/widgets/views/duimenuobjectview_p.h new file mode 100644 index 000000000..94cdb101e --- /dev/null +++ b/src/widgets/views/duimenuobjectview_p.h @@ -0,0 +1,85 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIMENUOBJECTVIEW_P_H +#define DUIMENUOBJECTVIEW_P_H + +#include "duiscenewindowview_p.h" +#include +#include "duiabstractlayoutpolicy.h" + +class DuiWidget; +class DuiApplicationMenu; +class DuiScalableImage; +class DuiButton; +class DuiLinearLayoutPolicy; +class DuiLayout; +class DuiPannableViewport; +class DuiFreestyleLayoutPolicy; +class DuiAction; +class DuiWidget; + +class DuiObjectMenuLayoutPolicy : public DuiAbstractLayoutPolicy +{ + +public: + DuiObjectMenuLayoutPolicy(DuiLayout *layout); + void setItemGeometry(QGraphicsLayoutItem *item, const QRectF &geom); + QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint) const; + void relayout(); + void removeAt(int index); + virtual void addItem(QGraphicsLayoutItem *item); + +private: + QHash geometries; +}; + +class DuiMenuObjectViewPrivate : public DuiSceneWindowViewPrivate, public QObject +{ + Q_DECLARE_PUBLIC(DuiMenuObjectView) + +public: + DuiMenuObjectViewPrivate(DuiApplicationMenu *menu); + + virtual ~DuiMenuObjectViewPrivate(); + + DuiApplicationMenu *controller; + DuiPannableViewport *viewport; + DuiWidget *container; + + QHash widgets; + QHash buttons; + + DuiLayout *layout; + DuiLinearLayoutPolicy *linearPolicy; + DuiObjectMenuLayoutPolicy *customPolicy; + + void addWidget(QAction *action); + void removeWidget(QAction *action); + void actionChanged(QAction *action); + + void init(); + void refreshLayout(); + +protected: + bool eventFilter(QObject *obj, QEvent *event); + +}; + +#endif diff --git a/src/widgets/views/duimessageboxview.cpp b/src/widgets/views/duimessageboxview.cpp new file mode 100644 index 000000000..190a52301 --- /dev/null +++ b/src/widgets/views/duimessageboxview.cpp @@ -0,0 +1,77 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duimessageboxview.h" +#include "duimessageboxview_p.h" + +#include "duimessagebox.h" +#include "duilabel.h" + +#include + +DuiMessageBoxViewPrivate::DuiMessageBoxViewPrivate() +{ +} + +DuiMessageBoxViewPrivate::~DuiMessageBoxViewPrivate() +{ +} + +DuiMessageBoxView::DuiMessageBoxView(DuiMessageBox *controller) : + DuiDialogView(*new DuiMessageBoxViewPrivate, controller) +{ + Q_D(DuiMessageBoxView); + d->label = new DuiLabel; + d->label->setAlignment(Qt::AlignCenter); + contentsLayout()->insertItem(0, d->label); +} + +DuiMessageBoxView::~DuiMessageBoxView() +{ +} + +void DuiMessageBoxView::updateData(const QList& modifications) +{ + DuiDialogView::updateData(modifications); + + Q_D(DuiMessageBoxView); + const char *member; + + foreach(member, modifications) { + if (member == DuiMessageBoxModel::Text) { + d->label->setText(model()->text()); + } + } + + updateGeometry(); +} + +void DuiMessageBoxView::setupModel() +{ + DuiDialogView::setupModel(); + + Q_D(DuiMessageBoxView); + + //update text + d->label->setText(model()->text()); + + updateGeometry(); +} + +DUI_REGISTER_VIEW_NEW(DuiMessageBoxView, DuiMessageBox) diff --git a/src/widgets/views/duimessageboxview.h b/src/widgets/views/duimessageboxview.h new file mode 100644 index 000000000..bf5475aaf --- /dev/null +++ b/src/widgets/views/duimessageboxview.h @@ -0,0 +1,52 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIMESSAGEBOXVIEW_H +#define DUIMESSAGEBOXVIEW_H + +#include "duidialogview.h" +#include "duimessageboxmodel.h" +#include + +class DuiMessageBox; +class DuiMessageBoxViewPrivate; + +class DUI_EXPORT DuiMessageBoxView : public DuiDialogView +{ + Q_OBJECT + DUI_VIEW(DuiMessageBoxModel, DuiMessageBoxStyle) + +public: + DuiMessageBoxView(DuiMessageBox *controller); + virtual ~DuiMessageBoxView(); + +protected: + //! \reimp + virtual void setupModel(); + //! \reimp_end + +protected Q_SLOTS: + virtual void updateData(const QList& modifications); + +private: + Q_DECLARE_PRIVATE(DuiMessageBoxView) +}; + +#endif + diff --git a/src/widgets/views/duimessageboxview_p.h b/src/widgets/views/duimessageboxview_p.h new file mode 100644 index 000000000..5db7e9219 --- /dev/null +++ b/src/widgets/views/duimessageboxview_p.h @@ -0,0 +1,38 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIMESSAGEBOXVIEW_P_H +#define DUIMESSAGEBOXVIEW_P_H + +#include "duidialogview_p.h" +#include "duimessageboxview.h" + +class DuiLabel; + +class DuiMessageBoxViewPrivate : public DuiDialogViewPrivate +{ +public: + DuiMessageBoxViewPrivate(); + virtual ~DuiMessageBoxViewPrivate(); + + DuiLabel *label; +}; + +#endif + diff --git a/src/widgets/views/duimodalscenewindowview.cpp b/src/widgets/views/duimodalscenewindowview.cpp new file mode 100644 index 000000000..c8768c2a7 --- /dev/null +++ b/src/widgets/views/duimodalscenewindowview.cpp @@ -0,0 +1,70 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duimodalscenewindowview.h" +#include "duimodalscenewindowview_p.h" + +#include "duimodalscenewindow.h" +#include "duimodalscenewindow_p.h" +#include "duiviewcreator.h" + +DuiModalSceneWindowViewPrivate::DuiModalSceneWindowViewPrivate() +{ +} + +DuiModalSceneWindowViewPrivate::~DuiModalSceneWindowViewPrivate() +{ +} + + +DuiModalSceneWindowView::DuiModalSceneWindowView(DuiModalSceneWindow *controller) : + DuiSceneWindowView(*new DuiModalSceneWindowViewPrivate, controller) +{ + Q_D(DuiModalSceneWindowView); + d->controller = controller; +} + +DuiModalSceneWindowView::DuiModalSceneWindowView(DuiModalSceneWindowViewPrivate &dd, DuiModalSceneWindow *controller) + : DuiSceneWindowView(dd, controller) +{ + Q_D(DuiModalSceneWindowView); + d->controller = controller; +} + + +DuiModalSceneWindowView::~DuiModalSceneWindowView() +{ +} + +void DuiModalSceneWindowView::applyStyle() +{ + DuiSceneWindowView::applyStyle(); +} + +void DuiModalSceneWindowView::setupModel() +{ + DuiSceneWindowView::setupModel(); +} + +void DuiModalSceneWindowView::updateData(const QList &modifications) +{ + DuiSceneWindowView::updateData(modifications); +} + +DUI_REGISTER_VIEW_NEW(DuiModalSceneWindowView, DuiModalSceneWindow) diff --git a/src/widgets/views/duimodalscenewindowview.h b/src/widgets/views/duimodalscenewindowview.h new file mode 100644 index 000000000..635dcd486 --- /dev/null +++ b/src/widgets/views/duimodalscenewindowview.h @@ -0,0 +1,58 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIMODALSCENEWINDOWVIEW_H +#define DUIMODALSCENEWINDOWVIEW_H + +#include +#include "duiscenewindowview.h" +#include "duimodalscenewindowmodel.h" + +class DuiModalSceneWindow; +class DuiModalSceneWindowViewPrivate; + +class DUI_EXPORT DuiModalSceneWindowView : public DuiSceneWindowView +{ + Q_OBJECT + DUI_VIEW(DuiModalSceneWindowModel, DuiModalSceneWindowStyle) + +public: + DuiModalSceneWindowView(DuiModalSceneWindow *controller); + virtual ~DuiModalSceneWindowView(); + +protected: + DuiModalSceneWindowView(DuiModalSceneWindowViewPrivate &dd, DuiModalSceneWindow *controller); + + //! \reimp + virtual void applyStyle(); + virtual void setupModel(); + +protected slots: + virtual void updateData(const QList& modifications); + //! \reimp_end + +private: + Q_DECLARE_PRIVATE(DuiModalSceneWindowView) + Q_DISABLE_COPY(DuiModalSceneWindowView) +#ifdef UNIT_TEST + friend class Ut_DuiModalSceneWindow; +#endif +}; + +#endif diff --git a/src/widgets/views/duimodalscenewindowview_p.h b/src/widgets/views/duimodalscenewindowview_p.h new file mode 100644 index 000000000..78d591c9a --- /dev/null +++ b/src/widgets/views/duimodalscenewindowview_p.h @@ -0,0 +1,41 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIMODALSCENEWINDOWVIEW_P_H +#define DUIMODALSCENEWINDOWVIEW_P_H + +#include "duimodalscenewindowview.h" +#include "duiscenewindowview_p.h" + +class DuiModalSceneWindow; +class DuiModalSceneWindowPrivate; + +class DuiModalSceneWindowViewPrivate : public DuiSceneWindowViewPrivate +{ + Q_DECLARE_PUBLIC(DuiModalSceneWindowView) + +public: + DuiModalSceneWindowViewPrivate(); + virtual ~DuiModalSceneWindowViewPrivate(); + + DuiModalSceneWindow *controller; +}; + +#endif + diff --git a/src/widgets/views/duinavigationbarview.cpp b/src/widgets/views/duinavigationbarview.cpp new file mode 100644 index 000000000..ca0f2f327 --- /dev/null +++ b/src/widgets/views/duinavigationbarview.cpp @@ -0,0 +1,182 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duinavigationbarview.h" +#include "duinavigationbarview_p.h" + +#include +#include +#include + +#include "duiapplication.h" +#include "duinavigationbar.h" +#include "duinavigationbar_p.h" +#include "duiapplicationmenubutton.h" +#include "duitoolbar.h" +#include "duiviewcreator.h" +#include "duideviceprofile.h" + +// -------------------------------------------------------------------------- +// DuiNavigationBarViewPrivate +// -------------------------------------------------------------------------- + +DuiNavigationBarViewPrivate::DuiNavigationBarViewPrivate() + : layout(new QGraphicsGridLayout()), + applicationMenuButton(0), + toolbarPlaceholder(0), + toolBar(0) +{ +} + +DuiNavigationBarViewPrivate::~DuiNavigationBarViewPrivate() +{ +} + +void DuiNavigationBarViewPrivate::init() +{ + layout->setContentsMargins(0, 0, 0, 0); + layout->setSpacing(0); + controller->setLayout(layout); + + applicationMenuButton = new DuiApplicationMenuButton(controller); + applicationMenuButton->setObjectName("NavigationBarMenuButton"); + + layout->addItem(applicationMenuButton, 0, 0); + layout->setAlignment(applicationMenuButton, Qt::AlignVCenter); + + // panel for placing toolbar + toolbarPlaceholder = new DuiWidget(controller); + layout->addItem(toolbarPlaceholder, 0, 1); + + toolbarPlaceholderLayout = new QGraphicsLinearLayout(toolbarPlaceholder); + toolbarPlaceholderLayout->setContentsMargins(0, 0, 0, 0); + toolbarPlaceholder->setLayout(toolbarPlaceholderLayout); + + // Connects button signals + QObject::connect(applicationMenuButton, SIGNAL(clicked()), controller, SIGNAL(viewmenuTriggered())); + +} + +void DuiNavigationBarViewPrivate::setMenuButtonwidth() +{ + Q_Q(DuiNavigationBarView); + + /* FIXME: Its there because the UI specs contains the following forumla: + width of view menu button = width of portrait view - width of home button - width of close button. + This needs to be removed when there exists support for reading CSS constants in the code + */ + int widthofPortraitMode = DuiDeviceProfile::instance()->resolution().height(); + qreal width = widthofPortraitMode - (qreal)q->style()->paddingLeft() - (qreal)q->style()->paddingRight(); + applicationMenuButton->setPreferredWidth(width); + applicationMenuButton->setMinimumWidth(width); + applicationMenuButton->setMaximumWidth(width); +} + +void DuiNavigationBarViewPrivate::notificationFlagChanged() +{ + // FIXME: Add notification support! +} + +void DuiNavigationBarViewPrivate::toolBarChanged() +{ + Q_Q(DuiNavigationBarView); + + DuiToolBar *nextToolBar = q->model()->toolBar(); + + // Make sure the last toolbar is deleted first... + if (toolBar) { + if (nextToolBar == toolBar) return; + + toolbarPlaceholderLayout->removeAt(0); + toolBar->setParentItem(NULL); + } + + if (nextToolBar) { + toolbarPlaceholderLayout->addItem(nextToolBar); + nextToolBar->show(); + } + toolBar = nextToolBar; +} + +// -------------------------------------------------------------------------- +// DuiNavigationBarView +// -------------------------------------------------------------------------- + +DuiNavigationBarView::DuiNavigationBarView(DuiNavigationBar *controller) : + DuiSceneWindowView(*(new DuiNavigationBarViewPrivate()), controller) +{ + Q_D(DuiNavigationBarView); + d->init(); +} + +DuiNavigationBarView::~DuiNavigationBarView() +{ +} + +void DuiNavigationBarView::updateData(const QList& modifications) +{ + Q_D(DuiNavigationBarView); + DuiSceneWindowView::updateData(modifications); + const char *member; + foreach(member, modifications) { + if (member == DuiNavigationBarModel::NotifyUser) { + d->notificationFlagChanged(); + } else if (member == DuiNavigationBarModel::ViewMenuDescription) { + d->applicationMenuButton->setText(model()->viewMenuDescription()); + } else if (member == DuiNavigationBarModel::ViewMenuIconID) { + d->applicationMenuButton->setIconID(model()->viewMenuIconID()); + } else if (member == DuiNavigationBarModel::ProgressIndicatorVisible) { + d->applicationMenuButton->setProgressIndicatorVisible(model()->progressIndicatorVisible()); + } else if (member == DuiNavigationBarModel::ArrowIconVisible) { + d->applicationMenuButton->setArrowIconVisible(model()->arrowIconVisible()); + } else if (member == DuiNavigationBarModel::ToolBar) { + d->toolBarChanged(); + } + } +} + +void DuiNavigationBarView::setupModel() +{ + DuiSceneWindowView::setupModel(); + + Q_D(DuiNavigationBarView); + d->setMenuButtonwidth(); + d->applicationMenuButton->setText(model()->viewMenuDescription()); + d->applicationMenuButton->setIconID(model()->viewMenuIconID()); + d->applicationMenuButton->setProgressIndicatorVisible(model()->progressIndicatorVisible()); + d->applicationMenuButton->setArrowIconVisible(model()->arrowIconVisible()); +} + +void DuiNavigationBarView::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + DuiWidgetView::mousePressEvent(event); + + // Don't let it propagate to widgets below + event->accept(); +} + +void DuiNavigationBarView::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + DuiWidgetView::mouseReleaseEvent(event); + + // Don't let it propagate to widgets below + event->accept(); +} + +DUI_REGISTER_VIEW_NEW(DuiNavigationBarView, DuiNavigationBar) diff --git a/src/widgets/views/duinavigationbarview.h b/src/widgets/views/duinavigationbarview.h new file mode 100644 index 000000000..0e43676a6 --- /dev/null +++ b/src/widgets/views/duinavigationbarview.h @@ -0,0 +1,57 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUINAVIGATIONBARVIEW_H +#define DUINAVIGATIONBARVIEW_H + +#include "duiscenewindowview.h" +#include "duinavigationbarmodel.h" +#include "duinavigationbarstyle.h" + +class DuiNavigationBarViewPrivate; +class DuiNavigationBar; + +class DUI_EXPORT DuiNavigationBarView : public DuiSceneWindowView +{ + Q_OBJECT + DUI_VIEW(DuiNavigationBarModel, DuiNavigationBarStyle) + +public: + DuiNavigationBarView(DuiNavigationBar *controller); + virtual ~DuiNavigationBarView(); + + +protected: + //! \reimp + virtual void setupModel(); + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + //! \reimp_end + +protected Q_SLOTS: + //! \reimp + virtual void updateData(const QList& modifications); + //! \reimp_end + +private: + Q_DISABLE_COPY(DuiNavigationBarView) + Q_DECLARE_PRIVATE(DuiNavigationBarView) +}; + +#endif diff --git a/src/widgets/views/duinavigationbarview_p.h b/src/widgets/views/duinavigationbarview_p.h new file mode 100644 index 000000000..11c0d5a93 --- /dev/null +++ b/src/widgets/views/duinavigationbarview_p.h @@ -0,0 +1,57 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUINAVIGATIONBARVIEW_P_H +#define DUINAVIGATIONBARVIEW_P_H + +#include "duiscenewindowview_p.h" + +class DuiNavigationBar; +class DuiApplicationMenuButton; +class DuiWidget; +class DuiToolBar; +class QGraphicsGridLayout; +class QGraphicsLinearLayout; + +class DuiNavigationBarViewPrivate : public DuiSceneWindowViewPrivate +{ + Q_DECLARE_PUBLIC(DuiNavigationBarView) +public: + DuiNavigationBarViewPrivate(); + virtual ~DuiNavigationBarViewPrivate(); + + void init(); + + void setMenuButtonwidth(); + + void finalizeEscapeButtonTransition(); + + void escapeModeChanged(); + void notificationFlagChanged(); + void toolBarChanged(); + + QGraphicsGridLayout *layout; + QGraphicsLinearLayout *toolbarPlaceholderLayout; + + DuiApplicationMenuButton *applicationMenuButton; + DuiWidget *toolbarPlaceholder; + DuiToolBar *toolBar; +}; + +#endif diff --git a/src/widgets/views/duiobjectmenuview.cpp b/src/widgets/views/duiobjectmenuview.cpp new file mode 100644 index 000000000..c97691592 --- /dev/null +++ b/src/widgets/views/duiobjectmenuview.cpp @@ -0,0 +1,240 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include + +#include "duiobjectmenuview_p.h" +#include "duibutton.h" +#include "duiviewcreator.h" +#include "duiobjectmenu.h" + +#include "duipannableviewport.h" +#include "duilayout.h" +#include "duilinearlayoutpolicy.h" +#include "duigridlayoutpolicy.h" +#include + +#include "duiwidgetaction.h" +#include "duiscenemanager.h" +#include "duiscalableimage.h" +#include "duiapplication.h" +#include "duiapplicationwindow.h" + +void DuiObjectMenuViewPrivate::init() +{ + // create pannable viewport + viewport = new DuiPannableViewport(); + + // create container widget for pannable viewport + container = new DuiWidget; + viewport->setWidget(container); + + // create layout for controller, make it pannable + QGraphicsLinearLayout *controllerLayout = new QGraphicsLinearLayout(); + controllerLayout->setContentsMargins(0, 0, 0, 0); + controllerLayout->addItem(viewport); + controller->setLayout(controllerLayout); + + // create layout policies for portrait & landscape orientation + layout = new DuiLayout(container); + portraitPolicy = new DuiLinearLayoutPolicy(layout, Qt::Vertical); + portraitPolicy->setContentsMargins(0, 0, 0, 0); + landscapePolicy = new DuiGridLayoutPolicy(layout); + landscapePolicy->setContentsMargins(0, 0, 0, 0); + + layout->setLandscapePolicy(landscapePolicy); + layout->setPortraitPolicy(portraitPolicy); +} + + +DuiObjectMenuView::DuiObjectMenuView(DuiObjectMenu *controller) : + DuiSceneWindowView(* new DuiObjectMenuViewPrivate, controller) +{ + Q_D(DuiObjectMenuView); + d->init(); +} + +DuiObjectMenuView::DuiObjectMenuView(DuiObjectMenuViewPrivate &dd, DuiObjectMenu *controller) : + DuiSceneWindowView(dd, controller) +{ + Q_D(DuiObjectMenuView); + d->init(); +} + +DuiObjectMenuView::~DuiObjectMenuView() +{ + DuiActionList actions = model()->actions(); + const int count = actions.count(); + for (int i = 0; i < count; ++i) { + actionRemoved(actions.at(i)); + } +} + +void DuiObjectMenuView::actionAdded(DuiAction *action) +{ + Q_D(DuiObjectMenuView); + + // show only if it is visible + if (action->isVisible()) { + + // create button for this action + DuiButton *button = new DuiButton(action->iconID(), action->text(), d->container); + + QObject::connect(button, SIGNAL(clicked(bool)), action, SIGNAL(triggered())); + d->controller->connect(button, SIGNAL(clicked(bool)), SLOT(dismiss())); + + button->setEnabled(action->isEnabled()); + d->portraitPolicy->addItem(button); + d->landscapePolicy->addItem(button, (d->buttons.count()) / 2, (d->buttons.count()) % 2); + + d->buttons.insert(action, button); + + QSize sceneSize; + if (d->controller->sceneManager()) + sceneSize = d->controller->sceneManager()->visibleSceneSize(); + else if (DuiApplication::activeWindow()) + sceneSize = DuiApplication::activeWindow()->visibleSceneSize(); + else if (!DuiApplication::windows().isEmpty()) + sceneSize = DuiApplication::windows().at(0)->visibleSceneSize(); + + d->portraitPolicy->setContentsMargins(0.0, 0.0, 0.0, 0.0); + qreal offset = (sceneSize.height() - d->portraitPolicy->sizeHint(Qt::PreferredSize).height()) / 2.0; + d->portraitPolicy->setContentsMargins(0.0, offset, 0.0, offset); + + d->landscapePolicy->setContentsMargins(0.0, 0.0, 0.0, 0.0); + offset = (sceneSize.height() - d->landscapePolicy->sizeHint(Qt::PreferredSize).height()) / 2.0; + d->landscapePolicy->setContentsMargins(0.0, offset, 0.0, offset); + } +} + +void DuiObjectMenuView::actionRemoved(DuiAction *action) +{ + Q_D(DuiObjectMenuView); + + DuiButton *button = d->buttons.value(action, NULL); + if (button) { + d->buttons.remove(action); + delete button; + } +} + +void DuiObjectMenuView::actionModified(DuiAction *action) +{ + Q_D(DuiObjectMenuView); + DuiButton *button = d->buttons.value(action, NULL); + if (button) { + if (!action->isVisible()) { + actionRemoved(action); + } else { + // update button data accordingly + button->setText(action->text()); + button->setIconID(action->iconID()); + button->setEnabled(action->isEnabled()); + } + } else { + // there is no button yet, action must've been invisible + actionAdded(action); + } +} + +void DuiObjectMenuView::updateData(const QList &modifications) +{ + Q_D(DuiObjectMenuView); + + foreach(const char * member, modifications) { + if (member == DuiObjectMenuModel::Actions) { + foreach(DuiAction * action, d->buttons.keys()) { + actionRemoved(action); + } + + DuiActionList actions = model()->actions(); + const int count = actions.count(); + for (int i = 0; i < count; ++i) { + actionAdded(actions.at(i)); + } + } + } +} + +void DuiObjectMenuView::setupModel() +{ + DuiSceneWindowView::setupModel(); + + Q_D(DuiObjectMenuView); + + foreach(DuiAction * action, d->buttons.keys()) { + actionRemoved(action); + } + + connect(model(), SIGNAL(actionAdded(DuiAction *)), + this, SLOT(actionAdded(DuiAction *))); + connect(model(), SIGNAL(actionRemoved(DuiAction *)), + this, SLOT(actionRemoved(DuiAction *))); + connect(model(), SIGNAL(actionModified(DuiAction *)), + this, SLOT(actionModified(DuiAction *))); + + DuiActionList actions = model()->actions(); + const int count = actions.count(); + for (int i = 0; i < count; ++i) { + actionAdded(actions.at(i)); + } +} + +void DuiObjectMenuView::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + //Do not pass the events through the menu window + event->accept(); +} + +void DuiObjectMenuView::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + Q_UNUSED(event); + Q_D(DuiObjectMenuView); + d->controller->dismiss(); +} + +void DuiObjectMenuView::drawBackground(QPainter *painter, const QStyleOptionGraphicsItem *option) const +{ + Q_D(const DuiObjectMenuView); + + if (d->controller->sceneManager() == 0) + return; + + Q_UNUSED(option); + painter->setOpacity(style()->backgroundOpacity() * effectiveOpacity()); + + QTransform oldTransform(painter->worldTransform()); + QTransform transform; + transform.translate(pos().x(), pos().y()); + painter->setWorldTransform(transform); + + QSizeF size = boundingRect().size(); + if (d->controller->sceneManager()->orientation() != Dui::Landscape) + size = QSizeF(size.height(), size.width()); + + if (style()->backgroundImage()) { + // TODO Use tiled bitmap drawing when it becomes available. + style()->backgroundImage()->draw(0, 0, size.width(), size.height(), painter); + painter->setWorldTransform(oldTransform); + } else if (style()->backgroundColor().isValid()) { + painter->fillRect(QRectF(QPointF(0, 0), size), QBrush(style()->backgroundColor())); + } +} + +DUI_REGISTER_VIEW_NEW(DuiObjectMenuView, DuiObjectMenu) diff --git a/src/widgets/views/duiobjectmenuview.h b/src/widgets/views/duiobjectmenuview.h new file mode 100644 index 000000000..1a1b3c2a9 --- /dev/null +++ b/src/widgets/views/duiobjectmenuview.h @@ -0,0 +1,75 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIOBJECTMENUVIEW_H +#define DUIOBJECTMENUVIEW_H + +#include "duiscenewindowview.h" +#include "duiobjectmenumodel.h" +#include "duiobjectmenustyle.h" +#include + +class DuiObjectMenu; +class QGraphicsSceneMouseEvent; +class DuiObjectMenuViewPrivate; + +/*! + * \class DuiObjectMenuView + * \brief DuiObjectMenuView implements an object view "frogfoot" for the DuiApplicationMenu widget + */ + +class DUI_EXPORT DuiObjectMenuView : public DuiSceneWindowView +{ + Q_OBJECT + Q_DISABLE_COPY(DuiObjectMenuView) + Q_DECLARE_PRIVATE(DuiObjectMenuView) + DUI_VIEW(DuiObjectMenuModel, DuiObjectMenuStyle) + +protected: + DuiObjectMenuView(DuiObjectMenuViewPrivate &dd, DuiObjectMenu *controller); + +public: + /*! + * \brief Constructor + * \param controller Pointer to the DuiObjectMenu + */ + DuiObjectMenuView(DuiObjectMenu *controller); + + /*! + * \brief Destructor + */ + virtual ~DuiObjectMenuView(); + +protected: + + //! \reimp + virtual void setupModel(); + virtual void updateData(const QList &modifications); + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + virtual void drawBackground(QPainter *painter, const QStyleOptionGraphicsItem *option) const; + //! \reimp_end + +protected slots: + void actionAdded(DuiAction *action); + void actionModified(DuiAction *action); + void actionRemoved(DuiAction *action); +}; + +#endif diff --git a/src/widgets/views/duiobjectmenuview_p.h b/src/widgets/views/duiobjectmenuview_p.h new file mode 100644 index 000000000..805d72c2a --- /dev/null +++ b/src/widgets/views/duiobjectmenuview_p.h @@ -0,0 +1,50 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIOBJECTMENUVIEW_P_H +#define DUIOBJECTMENUVIEW_P_H + +#include "duiscenewindowview_p.h" +#include "duiobjectmenuview.h" + +class DuiButton; +class DuiAction; +class DuiWidget; +class DuiLayout; +class DuiPannableViewport; +class DuiLinearLayoutPolicy; +class DuiGridLayoutPolicy; + +class DuiObjectMenuViewPrivate : public DuiSceneWindowViewPrivate +{ + Q_DECLARE_PUBLIC(DuiObjectMenuView) + + void init(); + + QHash buttons; + + DuiPannableViewport *viewport; + DuiWidget *container; + + DuiLayout *layout; + DuiLinearLayoutPolicy *portraitPolicy; + DuiGridLayoutPolicy *landscapePolicy; +}; + +#endif diff --git a/src/widgets/views/duioverlayview.cpp b/src/widgets/views/duioverlayview.cpp new file mode 100644 index 000000000..01e3923c7 --- /dev/null +++ b/src/widgets/views/duioverlayview.cpp @@ -0,0 +1,34 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include "duiviewcreator.h" +#include "duioverlay.h" +#include "duioverlayview.h" + +DuiOverlayView::DuiOverlayView(DuiOverlay *controller) : + DuiSceneWindowView(controller) +{ +} + +DuiOverlayView::~DuiOverlayView() +{ +} + +DUI_REGISTER_VIEW_NEW(DuiOverlayView, DuiOverlay) diff --git a/src/widgets/views/duioverlayview.h b/src/widgets/views/duioverlayview.h new file mode 100644 index 000000000..330b63d68 --- /dev/null +++ b/src/widgets/views/duioverlayview.h @@ -0,0 +1,44 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIOVERLAYVIEW_H +#define DUIOVERLAYVIEW_H + +#include +#include "duiscenewindowview.h" + +class DuiOverlay; + +class DUI_EXPORT DuiOverlayView : public DuiSceneWindowView +{ + Q_OBJECT + DUI_VIEW(DuiSceneWindowModel, DuiOverlayStyle) + +public: + DuiOverlayView(DuiOverlay *controller); + virtual ~DuiOverlayView(); + +private: + Q_DISABLE_COPY(DuiOverlayView) +#ifdef UNIT_TEST + friend class Ut_DuiOverlay; +#endif +}; + +#endif diff --git a/src/widgets/views/duipannablewidgetview.cpp b/src/widgets/views/duipannablewidgetview.cpp new file mode 100644 index 000000000..6623c8475 --- /dev/null +++ b/src/widgets/views/duipannablewidgetview.cpp @@ -0,0 +1,87 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duipannablewidgetview.h" + +#include +#include +#include + +#include "duitheme.h" +#include "duiwidgetview.h" +#include "duipannablewidget.h" +#include "duiviewcreator.h" + +class DuiPannableWidgetViewPrivate +{ +public: + + DuiPannableWidgetViewPrivate(); + virtual ~DuiPannableWidgetViewPrivate(); + + DuiPannableWidget *controller; +}; + +DuiPannableWidgetViewPrivate::DuiPannableWidgetViewPrivate() : + controller(0) +{ +} + +DuiPannableWidgetViewPrivate::~DuiPannableWidgetViewPrivate() +{ +} + +DuiPannableWidgetView::DuiPannableWidgetView(DuiPannableWidget *controller) : + DuiWidgetView(controller), + d_ptr(new DuiPannableWidgetViewPrivate) +{ + Q_D(DuiPannableWidgetView); + d->controller = controller; +} + +DuiPannableWidgetView::~DuiPannableWidgetView() +{ + delete d_ptr; +} + +void DuiPannableWidgetView::drawContents(QPainter *painter, const QStyleOptionGraphicsItem *option) const +{ + Q_UNUSED(painter); + Q_UNUSED(option); +} + +void DuiPannableWidgetView::applyStyle() +{ + Q_D(DuiPannableWidgetView); + // update panning parameters to pannable widget + model()->setPanThreshold(style()->panThreshold()); + model()->setPanClickThreshold(style()->panClickThreshold()); + + //FIXME Set physics parameters through model. + // update physics parameters to pannable widget + d->controller->physics()->setPointerSpringK(style()->pointerSpringK()); + d->controller->physics()->setFriction(style()->frictionC()); + d->controller->physics()->setSlidingFriction(style()->slidingFrictionC()); + d->controller->physics()->setBorderSpringK(style()->borderSpringK()); + d->controller->physics()->setBorderFriction(style()->borderFrictionC()); + + DuiWidgetView::applyStyle(); +} + +DUI_REGISTER_VIEW_NEW(DuiPannableWidgetView, DuiPannableWidget) diff --git a/src/widgets/views/duipannablewidgetview.h b/src/widgets/views/duipannablewidgetview.h new file mode 100644 index 000000000..cdb10a281 --- /dev/null +++ b/src/widgets/views/duipannablewidgetview.h @@ -0,0 +1,56 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIPANNABLEWIDGETVIEW_H +#define DUIPANNABLEWIDGETVIEW_H + +#include "duiwidgetview.h" +#include +#include + +class DuiPannableWidgetViewPrivate; +class DuiPannableWidget; + +/*! + * \class DuiPannableWidgetView + * \brief DuiPannableWidgetView implements the view for pannable widget + */ +class DUI_EXPORT DuiPannableWidgetView : public DuiWidgetView +{ + Q_OBJECT + DUI_VIEW(DuiPannableWidgetModel, DuiPannableWidgetStyle) + +public: + DuiPannableWidgetView(DuiPannableWidget *controller); + virtual ~DuiPannableWidgetView(); + +protected: + //! \reimp + virtual void drawContents(QPainter *painter, const QStyleOptionGraphicsItem *option) const; + virtual void applyStyle(); + //! \reimp_end + +protected: + DuiPannableWidgetViewPrivate *const d_ptr; +private: + Q_DECLARE_PRIVATE(DuiPannableWidgetView) + Q_DISABLE_COPY(DuiPannableWidgetView) +}; + +#endif diff --git a/src/widgets/views/duipopupheaderview_p.h b/src/widgets/views/duipopupheaderview_p.h new file mode 100644 index 000000000..3e5c12088 --- /dev/null +++ b/src/widgets/views/duipopupheaderview_p.h @@ -0,0 +1,49 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIPOPUPHEADERVIEW_P_H +#define DUIPOPUPHEADERVIEW_P_H + +#include "private/duiwidgetview_p.h" + +class QGraphicsGridLayout; +class DuiPopupHeader; +class DuiImage; +class DuiLabel; + +class DuiPopupHeaderViewPrivate : public DuiWidgetViewPrivate +{ + Q_DECLARE_PUBLIC(DuiPopupHeaderView) + +public: + DuiPopupHeaderViewPrivate(); + virtual ~DuiPopupHeaderViewPrivate(); + + virtual void init(); + + virtual void initLayout(); + + DuiPopupHeader *controller; + QGraphicsGridLayout *layout; + DuiLabel *title; + DuiLabel *subtitle; + DuiImage *thumbnail; +}; + +#endif diff --git a/src/widgets/views/duipopuplistview.cpp b/src/widgets/views/duipopuplistview.cpp new file mode 100644 index 000000000..4ac5bbe2f --- /dev/null +++ b/src/widgets/views/duipopuplistview.cpp @@ -0,0 +1,718 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duipopuplistview.h" +#include "duipopuplistview_p.h" + +#include "duipopuplist.h" +#include "duipopuplist_p.h" +#include "duilistnamespace.h" +#include "duipannableviewport.h" +#include "duitheme.h" +#include "duiviewcreator.h" +#include "duigriditem.h" +#include "duilabel.h" +#include "duiscenemanager.h" + +#include +#include +#include +#include +#include + +#include + + +DuiPopupListViewPrivate::DuiPopupListViewPrivate() + : controller(0), viewport(0), + layout(0), container(0), spacer(0), + itemModel(0), selectionModel(0), + itemDirty(0), singlePass(true), batchSize(0), gridItemMode(true), + itemStartIndex(0), itemHeight(0), arrangingWidget(false) +{ +} + +DuiPopupListViewPrivate::~DuiPopupListViewPrivate() +{ +} + +void DuiPopupListViewPrivate::init() +{ + Q_Q(DuiPopupListView); + + viewport = q->contentsViewport(); + + // container which contain the gridItems + container = new QGraphicsWidget(); + q->contentsLayout()->insertItem(0, container); + + layout = new QGraphicsLinearLayout(); + layout->setContentsMargins(0, 0, 0, 0); + layout->setSpacing(0); + layout->setOrientation(Qt::Vertical); + container->setLayout(layout); + + // add spacer + spacer = new QGraphicsWidget(); + layout->addItem(spacer); + + QObject::connect(controller, SIGNAL(itemModelChanged(QAbstractItemModel *)), + q, SLOT(setItemModel(QAbstractItemModel *))); + QObject::connect(controller, SIGNAL(selectionModelChanged(QItemSelectionModel *)), + q, SLOT(setSelectionModel(QItemSelectionModel *))); + QObject::connect(controller, SIGNAL(scrollToIndex(QModelIndex)), + q, SLOT(scrollTo(QModelIndex))); + + if (controller->itemModel() != NULL) { + q->setItemModel(controller->itemModel()); + q->setSelectionModel(controller->selectionModel()); + } + +} + +void DuiPopupListViewPrivate::_q_modelDestroyed() +{ + itemModel = duiEmptyModel(); +} + +void DuiPopupListViewPrivate::_q_modelReset() +{ + doItemsLayout(); +} + +void DuiPopupListViewPrivate::_q_layoutChanged() +{ + doItemsLayout(); +} + +void DuiPopupListViewPrivate::_q_arrangeWidget() +{ + int i; + int layoutItemCount = layout->count(); + int modelItemCount = itemModel->rowCount(); + + qreal spacerHeight = layout->itemAt(0)->geometry().height(); + qreal sum = spacerHeight; + + QGraphicsLayoutItem *item; + DuiWidget *widget; + + qreal y = pannedPos.y(); + + if (y - lastPosition.y() >= 0) { + // pan down + + // calculate viewport top skipped items + int removeItemNumber = 0; + qreal spacerAddHeight = 0; + for (i = 1; i < layoutItemCount; ++i) { + item = layout->itemAt(i); + + // save item Height + if (itemHeight == 0) + setViewportRange(item->geometry()); + + if (sum + itemHeight >= y) + break; + + removeItemNumber++; + spacerAddHeight += itemHeight; + sum += itemHeight; + + // stop moving canvas when batches overlap + if (removeItemNumber >= modelItemCount - batchSize) break; + } + + if (removeItemNumber > 0) { + + // append items to bottom, make widgetsList have batchSize items anytime + int start = itemStartIndex + batchSize; + if (start < modelItemCount) { + + // remove items from top + for (i = removeItemNumber; i > 0; --i) { + layout->removeAt(i); + + widget = widgetsList.takeFirst(); + recycleWidget(widget); + } + + setSpacerFixedHeight(spacerHeight + spacerAddHeight); + itemStartIndex += removeItemNumber; + + for (i = 0; i < removeItemNumber; ++i) { + if (i + start >= modelItemCount) break; + + QModelIndex index = itemModel->index(i + start, 0); + widget = buildItem(index); + + layout->addItem(widget); + widgetsList.append(widget); + } + } + } + + } else { + // pan up + y += viewportSize.height(); + + // calculate viewport bottom skipped items + int skip = 0; + for (i = 1; i < layoutItemCount; ++i) { + item = layout->itemAt(i); + + if (itemHeight == 0) + setViewportRange(item->geometry()); + + skip++; + if (sum + itemHeight >= y) + break; + + sum += itemHeight; + } + + int removeItemNumber = layoutItemCount - 1 - skip; + if (removeItemNumber > 0) { + + // insert items to top + qreal spacerRemoveHeight = 0; + int start = itemStartIndex - 1; + for (i = 0; i < removeItemNumber; ++i) { + if (start - i < 0) break; + + QModelIndex index = itemModel->index(start - i, 0); + widget = buildItem(index); + + layout->insertItem(1, widget); + widgetsList.prepend(widget); + + spacerRemoveHeight += itemHeight; + } + + // remove items from bottom, make widgetsList have batchSize items anytime + layoutItemCount = layout->count(); + for (i = layoutItemCount - 1; i > batchSize; --i) { + layout->removeAt(i); + widget = widgetsList.takeLast(); + recycleWidget(widget); + } + + itemStartIndex -= removeItemNumber; + if (itemStartIndex < 0) + itemStartIndex = 0; + + if (spacerHeight - spacerRemoveHeight < 0) + setSpacerFixedHeight(0); + else + setSpacerFixedHeight(spacerHeight - spacerRemoveHeight); + } + } + + lastPosition = pannedPos; + arrangingWidget = false; +} + +void DuiPopupListViewPrivate::setLayoutDirty() +{ + itemDirty = 1; + viewport->setEnabled(false); +} + +void DuiPopupListViewPrivate::setViewportRange(const QRectF &rect) const +{ + itemHeight = rect.height(); + viewport->setAutoRange(false); + + int modelItemCount = itemModel->rowCount(); + QRectF range = QRectF(0, 0, rect.width(), modelItemCount * itemHeight); + + viewport->setRange(range); +} + +void DuiPopupListViewPrivate::setSpacerFixedHeight(qreal height) const +{ + if (spacer == 0) return; + + spacer->setMaximumHeight(height); + spacer->setMinimumHeight(height); +} + +void DuiPopupListViewPrivate::doItemsLayout() const +{ + Q_Q(const DuiPopupListView); + + // remove old items + int i; + DuiWidget *widget; + for (i = layout->count() - 1; i > 0; --i) + layout->removeAt(i); + + for (i = widgetsList.count() - 1; i >= 0; --i) { + widget = widgetsList.takeAt(i); + recycleWidget(widget); + } + setSpacerFixedHeight(0); + gridItemMode = true; + + // decide item create mode + int count = 0; + if (itemModel) + count = itemModel->rowCount(); + + viewport->setAutoRange(true); + itemHeight = 0; + + QObject::disconnect(viewport, SIGNAL(sizePosChanged(QSizeF, QRectF, QPointF)), + q, SLOT(sizePosChanged(QSizeF, QRectF, QPointF))); + + if (count <= q->model()->batchSize()) { + singlePass = true; + batchSize = count; + } else { + singlePass = false; + batchSize = q->model()->batchSize(); + arrangingWidget = false; + + QObject::connect(viewport, SIGNAL(sizePosChanged(QSizeF, QRectF, QPointF)), + q, SLOT(sizePosChanged(QSizeF, QRectF, QPointF))); + } + + // create first batch items + if (itemModel) { + for (i = 0; i < batchSize; ++i) { + QModelIndex index = itemModel->index(i, 0); + + widget = buildItem(index); + layout->addItem(widget); + + widgetsList.append(widget); + } + } + + lastPosition = QPointF(0, 0); + viewport->setEnabled(true); + viewport->setPosition(QPointF(0, 0)); + + itemStartIndex = 0; + itemDirty = 0; +} + +DuiWidget *DuiPopupListViewPrivate::buildItem(const QModelIndex &index) const +{ + Q_UNUSED(index); + QVariant itemType = itemModel->data(index, DuiListNameSpace::ItemTypeRole); + // custom + if (itemType != QVariant()) { + gridItemMode = false; + int i = itemType.toInt(); + if (i == DuiListNameSpace::Custom) { + QVariant modelItem = itemModel->data(index, Qt::DisplayRole); + if (modelItem.canConvert()) { + DuiWidget *w = modelItem.value(); + if (selectionModel->isSelected(index)) + w->setSelected(true); + else + w->setSelected(false); + return w; + } + } + } + + // griditem + DuiGridItem *item; + if (objectsPool.count() == 0) { + item = new DuiGridItem(); + } else { + item = (DuiGridItem *)(objectsPool.takeLast()); + item->show(); + item->setSelected(false); + } + + QString title, image, subtitle; + QVariant value; + + value = itemModel->data(index, Qt::DisplayRole); + if (value != QVariant()) + title = value.toString(); + + value = itemModel->data(index, Qt::DecorationRole); + if (value != QVariant()) + image = value.toString(); + + value = itemModel->data(index, DuiListNameSpace::SubtitleRole); + if (value != QVariant()) + subtitle = value.toString(); + + if (image.isEmpty()) { + item->setTitle(title); + item->setTitleVisible(true); + item->setImageVisible(false); + item->setSubtitleVisible(false); + } else { + item->setImage(image); + item->setImageVisible(true); + item->setTitle(title); + item->setTitleVisible(true); + item->setSubtitle(subtitle); + item->setSubtitleVisible(true); + + if (title.isEmpty() && subtitle.isEmpty()) { + item->setTitleVisible(false); + item->setSubtitleVisible(false); + } else if (subtitle.isEmpty()) { + item->setSubtitleVisible(false); + } + } + + if (selectionModel->isSelected(index)) + item->setSelected(true); + + return item; +} + +void DuiPopupListViewPrivate::recycleWidget(DuiWidget *widget) const +{ + // Only provide recycle when use DuiGridItem + if (gridItemMode) { + objectsPool.append(widget); + widget->hide(); + } else + widget->deleteLater(); +} + +QModelIndex DuiPopupListViewPrivate::indexAt(const QPointF &pos) +{ + int count = widgetsList.count(); + + for (int i = 0; i < count; ++i) { + QRectF rect = widgetsList[i]->sceneBoundingRect(); + if (rect.contains(pos)) + return itemModel->index(itemStartIndex + i, 0); + } + + return QModelIndex(); +} + +DuiWidget *DuiPopupListViewPrivate::indexWidget(const QModelIndex &index) +{ + int row = index.row(); + + // not create yet + if (row < itemStartIndex || row >= itemStartIndex + batchSize) + return NULL; + + int i = row - itemStartIndex; + int count = widgetsList.count(); + if (count > 0 && count > i) + return widgetsList[i]; + + return NULL; +} + +DuiPopupListView::DuiPopupListView(DuiPopupList *controller) + : DuiDialogView(* new DuiPopupListViewPrivate, controller) +{ + Q_D(DuiPopupListView); + d->controller = controller; + + d->init(); +} + +DuiPopupListView::DuiPopupListView(DuiPopupListViewPrivate &dd, DuiPopupList *controller) : + DuiDialogView(dd, controller) +{ + Q_D(DuiPopupListView); + d->controller = controller; + + d->init(); +} + +DuiPopupListView::~DuiPopupListView() +{ +} + +void DuiPopupListView::setItemModel(QAbstractItemModel *itemModel) +{ + Q_D(DuiPopupListView); + + if (d->itemModel && d->itemModel != duiEmptyModel()) { + disconnect(d->itemModel, SIGNAL(destroyed()), this, SLOT(_q_modelDestroyed())); + disconnect(d->itemModel, SIGNAL(modelReset()), this, SLOT(_q_modelReset())); + disconnect(d->itemModel, SIGNAL(dataChanged(QModelIndex, QModelIndex)), + this, SLOT(dataChanged(QModelIndex, QModelIndex))); + + disconnect(d->itemModel, SIGNAL(layoutChanged()), this, SLOT(_q_layoutChanged())); + + disconnect(d->itemModel, SIGNAL(rowsInserted(QModelIndex, int, int)), + this, SLOT(rowsInserted(QModelIndex, int, int))); + + disconnect(d->itemModel, SIGNAL(rowsRemoved(QModelIndex, int, int)), + this, SLOT(rowsRemoved(QModelIndex, int, int))); + } + + d->itemModel = itemModel; + + if (d->itemModel && d->itemModel != duiEmptyModel()) { + connect(d->itemModel, SIGNAL(destroyed()), this, SLOT(_q_modelDestroyed())); + connect(d->itemModel, SIGNAL(modelReset()), this, SLOT(_q_modelReset())); + connect(d->itemModel, SIGNAL(dataChanged(QModelIndex, QModelIndex)), + this, SLOT(dataChanged(QModelIndex, QModelIndex))); + + // when sort in model will emit this signal + connect(d->itemModel, SIGNAL(layoutChanged()), this, SLOT(_q_layoutChanged())); + + connect(d->itemModel, SIGNAL(rowsInserted(QModelIndex, int, int)), + this, SLOT(rowsInserted(QModelIndex, int, int))); + + connect(d->itemModel, SIGNAL(rowsRemoved(QModelIndex, int, int)), + this, SLOT(rowsRemoved(QModelIndex, int, int))); + } + + // need rebuild layout + d->setLayoutDirty(); +} + +void DuiPopupListView::setSelectionModel(QItemSelectionModel *selectionModel) +{ + Q_D(DuiPopupListView); + + if (d->selectionModel) { + disconnect(d->selectionModel, SIGNAL(selectionChanged(QItemSelection, QItemSelection)), + this, SLOT(selectionChanged(QItemSelection, QItemSelection))); + } + + d->selectionModel = selectionModel; + + if (d->selectionModel) { + connect(d->selectionModel, SIGNAL(selectionChanged(QItemSelection, QItemSelection)), + this, SLOT(selectionChanged(QItemSelection, QItemSelection))); + } +} + +void DuiPopupListView::sizePosChanged(const QSizeF &viewportSize, const QRectF &pannedRange, const QPointF &pannedPos) +{ + Q_UNUSED(pannedRange); + + Q_D(DuiPopupListView); + if (d->itemDirty) return; + +// qDebug() << "pannedPos: " << pannedPos.y() << "lastPosition: " << d->lastPosition.y(); + if (qAbs(pannedPos.y() - d->lastPosition.y()) < 10.0) return; // skip little change to speed up + if (d->arrangingWidget) return; + + // In order to not block panning, use timer to arrange widget + d->viewportSize = viewportSize; + d->pannedPos = pannedPos; + d->arrangingWidget = true; + QTimer::singleShot(0, this, SLOT(_q_arrangeWidget())); +} + +void DuiPopupListView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) +{ + Q_D(DuiPopupListView); + + // test if the widgets have been created. + int count = d->layout->count(); + if (count == 1) + return; + + int top = topLeft.row(); + int bottom = bottomRight.row(); + + DuiWidget *widget; + for (int i = top; i <= bottom; ++i) { + if (i < d->itemStartIndex || i >= d->itemStartIndex + d->batchSize) + continue; + + // remove old widget + int offset = i - d->itemStartIndex; + d->layout->removeAt(offset + 1); + widget = d->widgetsList.takeAt(offset); + d->recycleWidget(widget); + + // create new widget and insert it into layout + QModelIndex index = d->itemModel->index(i, 0); + widget = d->buildItem(index); + + d->layout->insertItem(offset + 1, widget); + d->widgetsList.insert(offset, widget); + } +} + +void DuiPopupListView::rowsInserted(const QModelIndex &parent, int start, int end) +{ + Q_UNUSED(parent); + + Q_D(DuiPopupListView); + int i; + DuiWidget *widget; + + if (d->singlePass) { + + d->batchSize += end - start + 1; + if (d->batchSize > model()->batchSize()) { + d->setLayoutDirty(); + return; + } + + // insert new items into layout + for (i = end; i >= start; --i) { + QModelIndex index = d->itemModel->index(i, 0); + widget = d->buildItem(index); + + // +1 for skip spacer + d->layout->insertItem(start + 1, widget); + d->widgetsList.insert(i, widget); + } + + } else { + d->setLayoutDirty(); + } +} + +void DuiPopupListView::rowsRemoved(const QModelIndex &parent, int start, int end) +{ + Q_UNUSED(parent); + + Q_D(DuiPopupListView); + int i; + DuiWidget *widget; + + if (d->singlePass) { + + // test if the widgets have been created. + int count = d->layout->count(); + if (count == 1) + return; + + // remove items from layout + for (i = end; i >= start; --i) { + d->layout->removeAt(i + 1); + widget = d->widgetsList.takeAt(i); + d->recycleWidget(widget); + } + + d->batchSize -= end - start + 1; + + } else { + d->setLayoutDirty(); + } +} + +void DuiPopupListView::selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) +{ + Q_D(DuiPopupListView); + + int i; + QModelIndexList list = deselected.indexes(); + DuiWidget *w; + + int count = list.count(); + for (i = 0; i < count; ++i) { + w = d->indexWidget(list[i]); + if (w != NULL) + w->setSelected(false); + } + + list = selected.indexes(); + count = list.count(); + for (i = 0; i < count; ++i) { + w = d->indexWidget(list[i]); + if (w != NULL) + w->setSelected(true); + } +} + +void DuiPopupListView::drawBackground(QPainter *painter, const QStyleOptionGraphicsItem *option) const +{ + Q_D(const DuiPopupListView); + + if (d->itemDirty) + d->doItemsLayout(); + + DuiWidgetView::drawBackground(painter, option); +} + +void DuiPopupListView::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + Q_D(DuiPopupListView); + + QPersistentModelIndex index = d->indexAt(event->scenePos()); + d->pressedIndex = index; +} + +void DuiPopupListView::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + Q_D(DuiPopupListView); + + QPersistentModelIndex index = d->indexAt(event->scenePos()); + + if (!index.isValid()) + d->controller->accept(); + else if (index == d->pressedIndex) + d->controller->click(index); +} + +void DuiPopupListView::scrollTo(const QModelIndex &index) const +{ + Q_D(const DuiPopupListView); + + int modelItemCount = d->itemModel->rowCount(); + if (index.row() >= modelItemCount) return; + if (d->layout->count() == 0) return; + + QRectF rect = d->layout->itemAt(1)->geometry(); + qreal height = rect.height(); + + int offset = index.row() - d->itemStartIndex; + qreal y = rect.y() + offset * height; + + d->viewport->setPosition(QPointF(0, y)); +} + +void DuiPopupListView::updateData(const QList& modifications) +{ + Q_D(DuiPopupListView); + + DuiDialogView::updateData(modifications); + + const char *member; + const int count = modifications.count(); + for (int i = 0; i < count; ++i) { + member = modifications[i]; + + if (member == DuiPopupListModel::BatchSize) { + d->setLayoutDirty(); + } + } +} + +void DuiPopupListView::setupModel() +{ + Q_D(DuiPopupListView); + DuiDialogView::setupModel(); + + if (d->batchSize != model()->batchSize()) + d->setLayoutDirty(); +} + +DUI_REGISTER_VIEW_NEW(DuiPopupListView, DuiPopupList) + +#include "moc_duipopuplistview.cpp" + diff --git a/src/widgets/views/duipopuplistview.h b/src/widgets/views/duipopuplistview.h new file mode 100644 index 000000000..99dc56447 --- /dev/null +++ b/src/widgets/views/duipopuplistview.h @@ -0,0 +1,135 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIPOPUPLISTVIEW_H +#define DUIPOPUPLISTVIEW_H + +#include "duidialogview.h" +#include "duipopuplistmodel.h" +#include "duipopupliststyle.h" + +#include +#include + +class DuiPopupListViewPrivate; +class DuiPopupList; +class QAbstractItemModel; + +/*! + \class DuiPopupListView + \brief View class for standard DuiPopupList. + + \ingroup views + + DuiPopupListView is used to visualize popupList. + */ + +class DUI_EXPORT DuiPopupListView : public DuiDialogView +{ + Q_OBJECT + DUI_VIEW(DuiPopupListModel, DuiPopupListStyle) + +public: + /*! + \brief Constructor + \param controller Pointer to the button's controller + */ + DuiPopupListView(DuiPopupList *controller); + + /*! + \brief Destructor + */ + virtual ~DuiPopupListView(); + +protected Q_SLOTS: + + /*! + \brief Set the itemModel + */ + virtual void setItemModel(QAbstractItemModel *itemModel); + + /*! + \brief Set the selectionModel + */ + virtual void setSelectionModel(QItemSelectionModel *selectionModel); + + /*! + \brief Called when position of pannable viewport changes + */ + void sizePosChanged(const QSizeF &viewportSize, const QRectF &pannedRange, const QPointF &pannedPos); + + /*! + This slot is called when items are changed in the model. The + changed items are those from \a topLeft to \a bottomRight + inclusive. If just one item is changed \a topLeft == \a + bottomRight. + */ + virtual void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight); + + /*! + This slot is called when rows are inserted. + */ + void rowsInserted(const QModelIndex &parent, int start, int end); + + /*! + This slot is called when rows are removed. + */ + void rowsRemoved(const QModelIndex &parent, int start, int end); + + /*! + This slot is called when the selection is changed. The previous + selection (which may be empty), is specified by \a deselected, and the + new selection by \a selected. + */ + virtual void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected); + + /*! + Scrolls the view if necessary to ensure that the item at \a index is visible. + */ + virtual void scrollTo(const QModelIndex &index) const; + + //! \reimp + virtual void drawBackground(QPainter *painter, const QStyleOptionGraphicsItem *option) const; + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + virtual void updateData(const QList& modifications); + //! \reimp_end + +protected: + + //! \reimp + virtual void setupModel(); + //! \reimp_end + + //! \internal + DuiPopupListView(DuiPopupListViewPrivate &dd, DuiPopupList *controller); + //! \internal_end + +private: + Q_DISABLE_COPY(DuiPopupListView) + Q_DECLARE_PRIVATE(DuiPopupListView) + + Q_PRIVATE_SLOT(d_func(), void _q_modelDestroyed()) + Q_PRIVATE_SLOT(d_func(), void _q_modelReset()) + Q_PRIVATE_SLOT(d_func(), void _q_layoutChanged()) + Q_PRIVATE_SLOT(d_func(), void _q_arrangeWidget()) + +}; + +#endif diff --git a/src/widgets/views/duipopuplistview_p.h b/src/widgets/views/duipopuplistview_p.h new file mode 100644 index 000000000..34a4bfc8a --- /dev/null +++ b/src/widgets/views/duipopuplistview_p.h @@ -0,0 +1,90 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIBUTTONVIEW_P_H +#define DUIBUTTONVIEW_P_H + +#include "duidialogview_p.h" +#include +#include +#include + +class DuiPopupList; +class DuiPannableViewport; +class QGraphicsWidget; +class QAbstractItemModel; +class QItemSelectionModel; +class QGraphicsLinearLayout; + +class DuiPopupListViewPrivate : public DuiDialogViewPrivate +{ + Q_DECLARE_PUBLIC(DuiPopupListView) + +public: + DuiPopupListViewPrivate(); + ~DuiPopupListViewPrivate(); + + virtual void init(); + + void _q_modelDestroyed(); + void _q_modelReset(); + void _q_layoutChanged(); + void _q_arrangeWidget(); + + void setLayoutDirty(); + + void doItemsLayout() const; + inline void setSpacerFixedHeight(qreal height) const; + inline DuiWidget *buildItem(const QModelIndex &index) const; + inline void recycleWidget(DuiWidget *widget) const; + inline void setViewportRange(const QRectF &rect) const; + + QModelIndex indexAt(const QPointF &pos); + DuiWidget *indexWidget(const QModelIndex &index); + + DuiPopupList *controller; + + DuiPannableViewport *viewport; + QGraphicsLinearLayout *layout; + QGraphicsWidget *container; + QGraphicsWidget *spacer; + + QAbstractItemModel *itemModel; + QPointer selectionModel; + + mutable int itemDirty; + mutable bool singlePass; + mutable int batchSize; + mutable bool gridItemMode; + + mutable QPointF lastPosition; + mutable int itemStartIndex; + mutable qreal itemHeight; + mutable bool arrangingWidget; + + QSizeF viewportSize; + QPointF pannedPos; + + mutable QList widgetsList; + mutable QList objectsPool; + + QPersistentModelIndex pressedIndex; +}; + +#endif diff --git a/src/widgets/views/duipositionindicatorview.cpp b/src/widgets/views/duipositionindicatorview.cpp new file mode 100644 index 000000000..e017c8ae8 --- /dev/null +++ b/src/widgets/views/duipositionindicatorview.cpp @@ -0,0 +1,176 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duipositionindicatorview.h" +#include "duipositionindicatorview_p.h" + +#include +#include +#include + +#include "duipositionindicator_p.h" // For the member indexes of the model +#include "duitheme.h" +#include "duiviewcreator.h" +#include "duipositionindicator.h" +#include "duiabstractwidgetanimation.h" +#define NODEBUG + + +DuiPositionIndicatorViewPrivate::DuiPositionIndicatorViewPrivate() + : controller(0), + hideTimer(new QTimer()), + visible(false) +{ +} + +DuiPositionIndicatorViewPrivate::~DuiPositionIndicatorViewPrivate() +{ + delete this->hideTimer; +} + +DuiPositionIndicatorView::DuiPositionIndicatorView(DuiPositionIndicator *controller) : + DuiWidgetView(* new DuiPositionIndicatorViewPrivate, controller) +{ + Q_D(DuiPositionIndicatorView); + d->controller = controller; + + connect(d->hideTimer, SIGNAL(timeout()), this, SLOT(hide())); + d->hideTimer->setSingleShot(true); +} + +DuiPositionIndicatorView::~DuiPositionIndicatorView() +{ + Q_D(DuiPositionIndicatorView); + d->controller = 0; +} + +void DuiPositionIndicatorView::drawContents(QPainter *painter, const QStyleOptionGraphicsItem *option) const +{ + /* + Q_D(const DuiPositionIndicatorView); + */ + Q_UNUSED(option); + /* + if(d->visible) { + */ + int dotDist = style()->pixmapDistance(); + QSize dotSize = style()->onPixmap()->size(); + QSizeF vpSize = model()->viewportSize(); + QRectF pRange = model()->pannedRange(); + QPointF pPos = model()->pannedPos(); + const QPixmap *pixOff = style()->offPixmap(); + const QPixmap *pixOn = style()->onPixmap(); + + int dotsX = size().width() / dotDist; + int onDotsX = (2 * dotsX * vpSize.width() + pRange.width()) / pRange.width() / 2; + onDotsX = qMax(onDotsX, + style()->minIndicatorDots()); + int onPosX = (2 * dotsX * pPos.x() + pRange.width()) / pRange.width() / 2; + QPoint barPosH = QPoint(size().width() - dotsX * dotDist + (dotDist - dotSize.width()) / 2, + size().height() - dotDist + (dotDist - dotSize.height()) / 2); + + int dotsY = size().height() / dotDist; + int onDotsY = (2 * dotsY * vpSize.height() + pRange.height()) / pRange.height() / 2; + onDotsY = qMax(onDotsY, + style()->minIndicatorDots()); + int onPosY = (2 * dotsY * pPos.y() + pRange.height()) / pRange.height() / 2; + QPoint barPosV = QPoint(size().width() - dotDist + (dotDist - dotSize.width()) / 2, + size().height() - dotsY * dotDist + (dotDist - dotSize.height()) / 2); + + int effPosX = qMax(0, onPosX); + int effPosY = qMax(0, onPosY); + + if (pRange.width() > vpSize.width()) { + QPointF currPos(barPosH); + QPointF posAdd(dotDist, 0); + bool pixState; + + for (int i = 0; i < dotsX; ++i) { + pixState = (i < effPosX || i >= onPosX + onDotsX) ? false : true; + painter->drawPixmap(currPos, pixState ? *pixOn : *pixOff); + + currPos += posAdd; + } + } + + if (pRange.height() > vpSize.height()) { + QPointF currPos(barPosV); + QPointF posAdd(0, dotDist); + bool pixState; + + for (int i = 0; i < dotsY; ++i) { + pixState = (i < effPosY || i >= onPosY + onDotsY) ? false : true; + painter->drawPixmap(currPos, pixState ? *pixOn : *pixOff); + + currPos += posAdd; + } + } + /* + } + */ +} + +void DuiPositionIndicatorView::updateData(const QList& modifications) +{ + DuiWidgetView::updateData(modifications); + + resetHideTimer(); + update(); +} + +void DuiPositionIndicatorView::setupModel() +{ + DuiWidgetView::setupModel(); + + resetHideTimer(); + update(); +} + +void DuiPositionIndicatorView::resizeEvent(QGraphicsSceneResizeEvent *event) +{ + DuiWidgetView::resizeEvent(event); + update(); +} + +void DuiPositionIndicatorView::hide() +{ + Q_D(DuiPositionIndicatorView); + d->visible = false; + if (showAnimation()) + showAnimation()->stop(); + if (hideAnimation()) + hideAnimation()->start(); + update(); +} + +void DuiPositionIndicatorView::resetHideTimer() +{ + Q_D(DuiPositionIndicatorView); + if (!d->visible) { + if (hideAnimation()) + hideAnimation()->stop(); + if (showAnimation()) + showAnimation()->start(); + d->visible = true; + } + d->hideTimer->stop(); + d->hideTimer->start(style()->hideTimeout()); +} + +DUI_REGISTER_VIEW_NEW(DuiPositionIndicatorView, DuiPositionIndicator) diff --git a/src/widgets/views/duipositionindicatorview.h b/src/widgets/views/duipositionindicatorview.h new file mode 100644 index 000000000..f58d7ebcb --- /dev/null +++ b/src/widgets/views/duipositionindicatorview.h @@ -0,0 +1,94 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIPOSITIONINDICATORVIEW_H +#define DUIPOSITIONINDICATORVIEW_H + +#include "duiwidgetview.h" +#include +#include + +class DuiPositionIndicator; +class QGraphicsSceneResizeEvent; +class QRegion; +class DuiPositionIndicatorViewPrivate; + +/*! + \class DuiPositionIndicatorView + \brief DuiPositionIndicatorView implements a view for DuiPositionIndicator + + This class draws indicators on the right edge of a pannable viewport + (vertical panning), on the bottom edge (horizontal panning), or + both. Position indicators are drawn only when the panned widget is + moving, and the indicator hides itself when the panned widget stops + moving. + +*/ + +class DUI_EXPORT DuiPositionIndicatorView : public DuiWidgetView +{ + Q_OBJECT + DUI_VIEW(DuiPositionIndicatorModel, DuiPositionIndicatorStyle) + +public: + /*! + \brief Constructor + */ + DuiPositionIndicatorView(DuiPositionIndicator *controller); + + /*! + \brief Destructor + */ + virtual ~DuiPositionIndicatorView(); + + //! \reimp + virtual void resizeEvent(QGraphicsSceneResizeEvent *event); + //! \reimp_end + +protected: + //! \reimp + virtual void drawContents(QPainter *painter, const QStyleOptionGraphicsItem *option) const; + virtual void setupModel(); + //! \reimp_end + +protected Q_SLOTS: + //! \reimp + virtual void updateData(const QList& modifications); + //! \reimp_end + + +private Q_SLOTS: + /*! + \brief Hides the position indicator + */ + virtual void hide(); + +private: + /*! + \brief Restarts timer which is used to hide position indicator after pannable widget has stopped moving + */ + void resetHideTimer(); + + Q_DISABLE_COPY(DuiPositionIndicatorView) + Q_DECLARE_PRIVATE(DuiPositionIndicatorView) + + friend class Ut_DuiPositionIndicatorView; +}; + +#endif diff --git a/src/widgets/views/duipositionindicatorview_p.h b/src/widgets/views/duipositionindicatorview_p.h new file mode 100644 index 000000000..8e9df7253 --- /dev/null +++ b/src/widgets/views/duipositionindicatorview_p.h @@ -0,0 +1,40 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIPOSITIONINDICATORVIEW_P_H +#define DUIPOSITIONINDICATORVIEW_P_H + +#include "private/duiwidgetview_p.h" + +class DuiPositionIndicator; +class QPixmap; +class QPoint; + +class DuiPositionIndicatorViewPrivate : public DuiWidgetViewPrivate +{ +public: + DuiPositionIndicatorViewPrivate(); + virtual ~DuiPositionIndicatorViewPrivate(); + + DuiPositionIndicator *controller; + QTimer *hideTimer; + bool visible; +}; + +#endif diff --git a/src/widgets/views/duiprogressindicatorbarview.cpp b/src/widgets/views/duiprogressindicatorbarview.cpp new file mode 100644 index 000000000..d55e9f3c8 --- /dev/null +++ b/src/widgets/views/duiprogressindicatorbarview.cpp @@ -0,0 +1,228 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include +#include +#include + +#include "duiprogressindicatorbarview.h" +#include "duiprogressindicatorbarview_p.h" +#include "duiprogressindicator.h" +#include "duiviewcreator.h" +#include "duiprogressindicator_p.h" // For the member indexes of the model +#include "duiscalableimage.h" +#include "duitheme.h" +#include "duidebug.h" + +// 30 fps +const int ProgressBarUpdateInterval = 1000 / 30; + +DuiProgressIndicatorBarViewPrivate::DuiProgressIndicatorBarViewPrivate() + : controller(0), + position(0), + timer(0) +{ +} + + +DuiProgressIndicatorBarViewPrivate::~DuiProgressIndicatorBarViewPrivate() +{ + delete timer; +} + + +DuiProgressIndicatorBarView::DuiProgressIndicatorBarView(DuiProgressIndicator *controller) : + DuiWidgetView(* new DuiProgressIndicatorBarViewPrivate, controller) +{ + Q_D(DuiProgressIndicatorBarView); + + d->controller = controller; + connect(controller, SIGNAL(visibilityChanged(bool)), this, SLOT(visibilityChangedSlot(bool))); + +} + + +DuiProgressIndicatorBarView::~DuiProgressIndicatorBarView() +{ +} + +void DuiProgressIndicatorBarView::animationTimeout() +{ + Q_D(DuiProgressIndicatorBarView); + + if (model()->unknownDuration()) { + + // calculate interval in secs and add it to elapsed time + qreal elapsed = (qreal) d->timer->interval() / 1000.0; + + // calculate how many pixels to move + if (elapsed > 0) { + qreal distance = elapsed * (qreal) style()->speed(); + + // current position + qreal width = rect().width(); + + // increment + qreal current = d->position * width; + current += distance; + + // make sure it falls to range + int count = (int)(current / width); + current -= count * width; + d->position = current / width; + + // redraw + update(); + } + } +} + +void DuiProgressIndicatorBarView::updateData(const QList& modifications) +{ + DuiWidgetView::updateData(modifications); + + Q_D(DuiProgressIndicatorBarView); + + foreach(const char * member, modifications) { + if (member == DuiProgressIndicatorModel::UnknownDuration) { + if (model()->unknownDuration()) { + if (!d->timer) { + d->timer = new QTimer(this); + connect(d->timer, SIGNAL(timeout()), this, SLOT(animationTimeout())); + } + d->timer->start(ProgressBarUpdateInterval); + } else { + delete d->timer; + d->timer = NULL; + } + } + } + + update(); +} + +void DuiProgressIndicatorBarView::setupModel() +{ + DuiWidgetView::setupModel(); + + Q_D(DuiProgressIndicatorBarView); + + if (model()->unknownDuration()) { + if (!d->timer) { + d->timer = new QTimer(this); + connect(d->timer, SIGNAL(timeout()), this, SLOT(animationTimeout())); + } + d->timer->start(ProgressBarUpdateInterval); + } else { + delete d->timer; + d->timer = NULL; + } + + update(); +} + +void DuiProgressIndicatorBarView::drawContents(QPainter *painter, const QStyleOptionGraphicsItem *option) const +{ + Q_UNUSED(option); + Q_D(const DuiProgressIndicatorBarView); + + if (style()->activeImage() && style()->inactiveImage()) { + + bool reverse = qApp->isRightToLeft(); + + QRect r(rect().toRect()); + style()->inactiveImage()->draw(r, painter); + + int left, right; + style()->activeImage()->borders(&left, &right, NULL, NULL); + int minimumScalableWidth = left + right; + + if (!model()->unknownDuration()) { + qreal offset = (qreal)(model()->value() - model()->minimum()) / (qreal)(model()->maximum() - model()->minimum()); + if (offset > 0) { + if (!reverse) { + r.setRight(offset * r.width()); + if (r.width() < minimumScalableWidth) + r.setRight(r.left() + minimumScalableWidth); + } else { + r.setLeft((1.0 - offset) * r.width()); + if (r.width() < minimumScalableWidth) + r.setLeft(r.right() - minimumScalableWidth); + } + style()->activeImage()->draw(r, painter); + } + } else { + + qreal distance = d->position * (qreal) r.width(); + + // need to draw in 1 or 2 parts, depending if the indicator element goes across the ends + if ((distance + style()->elementSize()) > r.width()) { + // two draw calls + QRect r2(r); + if (!reverse) { + r.setLeft(distance); + r2.setRight(style()->elementSize() - r.width()); + } else { + r.setLeft(0); + r.setRight(r.width() - distance); + r2.setLeft(r2.width() - (style()->elementSize() - r.width())); + } + + if (r.width() >= minimumScalableWidth) + style()->activeImage()->draw(r, painter); + if (r2.width() >= minimumScalableWidth) + style()->activeImage()->draw(r2, painter); + } else { + + // one draw call + if (!reverse) { + r.setLeft(distance); + r.setRight(distance + style()->elementSize()); + if (r.width() < minimumScalableWidth) + r.setRight(r.left() + minimumScalableWidth); + } else { + r.setRight(r.width() - distance); + r.setLeft(r.right() - style()->elementSize()); + if (r.width() < minimumScalableWidth) + r.setLeft(r.right() - minimumScalableWidth); + } + style()->activeImage()->draw(r, painter); + } + } + } +} + +void DuiProgressIndicatorBarView::visibilityChangedSlot(bool visible) +{ + Q_D(DuiProgressIndicatorBarView); + if (d->timer) { + if (visible) { + d->timer->start(ProgressBarUpdateInterval); + } else { + d->timer->stop(); + } + } +} + + +// bind controller widget and view widget together by registration macro +DUI_REGISTER_VIEW_NEW(DuiProgressIndicatorBarView, DuiProgressIndicator) + diff --git a/src/widgets/views/duiprogressindicatorbarview.h b/src/widgets/views/duiprogressindicatorbarview.h new file mode 100644 index 000000000..0ef648a88 --- /dev/null +++ b/src/widgets/views/duiprogressindicatorbarview.h @@ -0,0 +1,108 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIPROGRESSINDICATORBARVIEW_H +#define DUIPROGRESSINDICATORBARVIEW_H + +#include "duiwidgetview.h" +#include +#include + +class DuiProgressIndicatorBarViewPrivate; +class DuiProgressIndicatorBarViewTest; +class DuiProgressIndicator; +class QGraphicsSceneResizeEvent; + +/*! + \class DuiProgressIndicatorBarView + \brief Progress bar view for DuiProgressIndicator. + + \ingroup views + + \tableofcontents + + \section ProgressIndicatorBarViewOverview Overview + Progress bars are used when duration of the process is (or will be) known. Progress bar with known + duration will give haptic feedback when operation is finished. It can be placed anywhere in UI and also + on top of other UI components to indicate ongoing processes. For the cases when duration is not + immediately known, the progress bar can be temporarily in unknown duration state until the duration + becomes known. Use to indicate e.g. uploading, downloading + + + + + + +
\image html progressbar1.png A progress bar in basic state, filled until 100% reached.
\image html progressbar2.png A progress bar in unknown duration state, animated indefinitely until duration becomes known.
+ + \section ProgressIndicatorBarViewInteractions Interactions + Progress bar is always non-interactive. + + \section ProgressIndicatorBarViewOpenIssues Open issues + \li Progress indicator shape, visualization, animation, size and possible subcomponents such + as label and error notification? Nothing yet decided by UI/Graphics team, so far only concepting + has been done. + \li Layout: where to display the current status (%, time, data bytes) of the progress indication? + \li Graphics + + \sa DuiProgressIndicator DuiProgressIndicatorModel DuiProgressIndicatorStyle +*/ + +class DUI_EXPORT DuiProgressIndicatorBarView : public DuiWidgetView +{ + Q_OBJECT + DUI_VIEW(DuiProgressIndicatorModel, DuiProgressIndicatorStyle) + +public: + /*! + \brief Constructor + \param controller Pointer to the progressindicator's controller + */ + DuiProgressIndicatorBarView(DuiProgressIndicator *controller); + + /*! + \brief Destructor + */ + virtual ~DuiProgressIndicatorBarView(); + +private Q_SLOTS: + void animationTimeout(); + void visibilityChangedSlot(bool); + +protected: + //! \cond + virtual void drawContents(QPainter *painter, const QStyleOptionGraphicsItem *option) const; + virtual void setupModel(); + //! \endcond + +protected Q_SLOTS: + //! \reimp + virtual void updateData(const QList& modifications); + //! \reimp_end + +private: + Q_DISABLE_COPY(DuiProgressIndicatorBarView) + Q_DECLARE_PRIVATE(DuiProgressIndicatorBarView) + +#ifdef DUI_TEST_CLASS + DUI_TEST_CLASS +#endif +}; + +#endif // DUIPROGRESSINDICATORBARVIEW_H diff --git a/src/widgets/views/duiprogressindicatorbarview_p.h b/src/widgets/views/duiprogressindicatorbarview_p.h new file mode 100644 index 000000000..49574c58a --- /dev/null +++ b/src/widgets/views/duiprogressindicatorbarview_p.h @@ -0,0 +1,50 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIPROGRESSINDICATORBARVIEW_P_H +#define DUIPROGRESSINDICATORBARVIEW_P_H + +#include +#include "private/duiwidgetview_p.h" + +class DuiStyle; +class DuiProgressIndicator; +class QPixmap; +class QTimer; + +class DuiProgressIndicatorBarViewPrivate : public DuiWidgetViewPrivate +{ +public: + DuiProgressIndicatorBarViewPrivate(); + virtual ~DuiProgressIndicatorBarViewPrivate(); + + DuiProgressIndicator *controller; + + float elementSize; + int activeElementCount; + int speed; + qreal position; + QTimer *timer; + +#ifdef DUI_UNIT_TEST + DUI_UNIT_TEST; +#endif +}; + +#endif // DUIPROGRESSINDICATORBARVIEW_P_H diff --git a/src/widgets/views/duiscenewindowview.cpp b/src/widgets/views/duiscenewindowview.cpp new file mode 100644 index 000000000..95aa43591 --- /dev/null +++ b/src/widgets/views/duiscenewindowview.cpp @@ -0,0 +1,124 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include "duiviewcreator.h" +#include "duiscenewindow.h" +#include "duiscenewindow_p.h" +#include "duiscenewindowview.h" +#include "duiscenewindowview_p.h" +#include "duiabstractwidgetanimation.h" +#include "duiclassfactory.h" + +DuiSceneWindowViewPrivate::DuiSceneWindowViewPrivate() : + dismissAnimation(0) +{ +} + +DuiSceneWindowViewPrivate::~DuiSceneWindowViewPrivate() +{ + delete dismissAnimation; +} + + +DuiSceneWindowView::DuiSceneWindowView(DuiSceneWindow *controller) : + DuiWidgetView(*new DuiSceneWindowViewPrivate, controller) +{ + Q_D(DuiSceneWindowView); + + d->controller = controller; + connect(this, SIGNAL(geometryAttributesChanged()), controller, SIGNAL(repositionNeeded())); +} + +DuiSceneWindowView::DuiSceneWindowView(DuiSceneWindowViewPrivate &dd, DuiSceneWindow *controller) : + DuiWidgetView(dd, controller) +{ + Q_D(DuiSceneWindowView); + + d->controller = controller; + connect(this, SIGNAL(geometryAttributesChanged()), controller, SIGNAL(repositionNeeded())); +} + +DuiSceneWindowView::~DuiSceneWindowView() +{ +} + +void DuiSceneWindowView::applyStyle() +{ + Q_D(DuiSceneWindowView); + + if (showAnimation()) { + disconnect(showAnimation(), SIGNAL(finished()), d->controller, SIGNAL(windowShown())); + } + + if (hideAnimation()) { + disconnect(hideAnimation(), SIGNAL(finished()), d->controller, SIGNAL(windowHidden())); + } + + DuiWidgetView::applyStyle(); + + if (style()->dismissAnimation() == "none") { + delete d->dismissAnimation; + d->dismissAnimation = NULL; + } else { + if (!d->dismissAnimation || style()->dismissAnimation() != d->dismissAnimation->metaObject()->className()) { + delete d->dismissAnimation; + d->dismissAnimation = dynamic_cast(DuiClassFactory::instance()->createAnimation(style()->dismissAnimation().toStdString().c_str())); + if (d->dismissAnimation) + d->dismissAnimation->setView(this); + } + } + + + if (showAnimation()) { + connect(showAnimation(), SIGNAL(finished()), d->controller, SIGNAL(windowShown())); + } + + if (hideAnimation()) { + connect(hideAnimation(), SIGNAL(finished()), d->controller, SIGNAL(windowHidden())); + } + + emit geometryAttributesChanged(); +} + +void DuiSceneWindowView::setupModel() +{ + DuiWidgetView::setupModel(); + emit geometryAttributesChanged(); +} + +Qt::Alignment DuiSceneWindowView::alignment() const +{ + Qt::Alignment verticalAlign = style()->verticalAlign() & Qt::AlignVertical_Mask; + Qt::Alignment horizontalAlign = style()->horizontalAlign() & Qt::AlignHorizontal_Mask; + + return verticalAlign | horizontalAlign; +} + +QPointF DuiSceneWindowView::offset() const +{ + return style()->offset(); +} + +DuiAbstractWidgetAnimation *DuiSceneWindowView::dismissAnimation() +{ + return NULL; +} + +DUI_REGISTER_VIEW_NEW(DuiSceneWindowView, DuiSceneWindow) diff --git a/src/widgets/views/duiscenewindowview.h b/src/widgets/views/duiscenewindowview.h new file mode 100644 index 000000000..1cf0884ff --- /dev/null +++ b/src/widgets/views/duiscenewindowview.h @@ -0,0 +1,95 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISCENEWINDOWVIEW_H +#define DUISCENEWINDOWVIEW_H + +#include "duiwidgetview.h" +#include "duiscenewindowmodel.h" +#include + +class DuiSceneWindow; +class DuiSceneWindowViewPrivate; + +/*! + * \class DuiSceneWindowView + * \brief This is a default view class for DuiSceneWindow. + * + * The DuiSceneWindowView provides an interface to notify + * the scene manager about changes in scene window's + * geometry-related style attributes. It is the preferred + * base class for views of all types of scene windows. + * Once its style changes, it emits a geometryAttributesChanged() + * signal, which is propagated to the DuiSceneManager instance, + * causing the window geometry and position to be recalculated. + */ +class DUI_EXPORT DuiSceneWindowView : public DuiWidgetView +{ + Q_OBJECT + DUI_VIEW(DuiSceneWindowModel, DuiSceneWindowStyle) + +public: + /*! + * \brief Creates a new instance of the view for the given /a controller. + */ + DuiSceneWindowView(DuiSceneWindow *controller); + /*! + * \brief A destructor. + */ + virtual ~DuiSceneWindowView(); + + /*! + * \brief Returns the current alignment. + * Alignment defines how scene manager will position the window on the screen. + * \returns The current alignment. + */ + Qt::Alignment alignment() const; + + /*! + * \brief Returns the current offset. + * \returns The current offset. + */ + QPointF offset() const; + +protected: + DuiSceneWindowView(DuiSceneWindowViewPrivate &dd, DuiSceneWindow *controller); + + //! \reimp + virtual void applyStyle(); + virtual void setupModel(); + //! \reimp_end + + /*! + \deprecated Since 0.18. + \brief Returns an animation which animates this view to hidden state with dismiss animation. + */ + DuiAbstractWidgetAnimation *Q_DECL_DEPRECATED dismissAnimation(); + +signals: + /*! + * \brief Emitted every time when the style of the scene window changes. + */ + void geometryAttributesChanged(); + +private: + Q_DECLARE_PRIVATE(DuiSceneWindowView) + Q_DISABLE_COPY(DuiSceneWindowView) +}; + +#endif diff --git a/src/widgets/views/duiscenewindowview_p.h b/src/widgets/views/duiscenewindowview_p.h new file mode 100644 index 000000000..2c40d60ab --- /dev/null +++ b/src/widgets/views/duiscenewindowview_p.h @@ -0,0 +1,41 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISCENEWINDOWVIEW_P_H +#define DUISCENEWINDOWVIEW_P_H + +#include "private/duiwidgetview_p.h" +#include "duiscenewindowview.h" + +class DuiSceneWindowViewPrivate : public DuiWidgetViewPrivate +{ + Q_DECLARE_PUBLIC(DuiSceneWindowView) + +public: + DuiSceneWindowViewPrivate(); + virtual ~DuiSceneWindowViewPrivate(); + + DuiSceneWindow *controller; + +private: + DuiAbstractWidgetAnimation *dismissAnimation; +}; + +#endif + diff --git a/src/widgets/views/duiseparatorview.cpp b/src/widgets/views/duiseparatorview.cpp new file mode 100644 index 000000000..08be5f3a0 --- /dev/null +++ b/src/widgets/views/duiseparatorview.cpp @@ -0,0 +1,73 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiseparatorview.h" +#include "duiseparatorview_p.h" +#include "duiseparator.h" +#include "duitheme.h" +#include "duiviewcreator.h" + +#include + +DuiSeparatorViewPrivate::DuiSeparatorViewPrivate() +{ +} + +DuiSeparatorViewPrivate::~DuiSeparatorViewPrivate() +{ +} + +DuiSeparatorView::DuiSeparatorView(DuiSeparator *controller) : + DuiWidgetView(* new DuiSeparatorViewPrivate, controller) +{ +} + +DuiSeparatorView::~DuiSeparatorView() +{ +} + +void DuiSeparatorView::updateData(const QList& modifications) +{ + DuiWidgetView::updateData(modifications); + + const char *member; + foreach(member, modifications) { + if (member == DuiSeparatorModel::Orientation) { + updateGeometry(); + } + } + update(); +} + +QSizeF DuiSeparatorView::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const +{ + QSizeF s = DuiWidgetView::sizeHint(which, constraint); + + if (which == Qt::PreferredSize || which == Qt::MaximumSize) { + if (model()->orientation() == Qt::Horizontal) + s.setHeight(style()->span()); + else + s.setWidth(style()->span()); + } + + return s; +} + +DUI_REGISTER_VIEW_NEW(DuiSeparatorView, DuiSeparator) + diff --git a/src/widgets/views/duiseparatorview.h b/src/widgets/views/duiseparatorview.h new file mode 100644 index 000000000..c9c9479bc --- /dev/null +++ b/src/widgets/views/duiseparatorview.h @@ -0,0 +1,68 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISEPARATORVIEW_H +#define DUISEPARATORVIEW_H + +#include +#include +#include + +class DuiSeparatorViewPrivate; +class DuiSeparator; + +/*! + \class DuiSeparatorView + \brief DuiSeparatorView implements a view for the DuiSeparator + */ + +class DUI_EXPORT DuiSeparatorView : public DuiWidgetView +{ + Q_OBJECT + DUI_VIEW(DuiSeparatorModel, DuiSeparatorStyle) + +public: + /*! + \brief Constructor + \param controller Pointer to the separator's controller + */ + DuiSeparatorView(DuiSeparator *controller); + + /*! + \brief Destructor. + */ + virtual ~DuiSeparatorView(); + +protected: + //! \reimp + virtual QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const; + //! \reimp_end + +protected slots: + //! \reimp + virtual void updateData(const QList& modifications); + //! \reimp_end + +private: + + Q_DISABLE_COPY(DuiSeparatorView) + Q_DECLARE_PRIVATE(DuiSeparatorView) +}; + +#endif // DUISEPARATORVIEW_H diff --git a/src/widgets/views/duiseparatorview_p.h b/src/widgets/views/duiseparatorview_p.h new file mode 100644 index 000000000..d2bf70484 --- /dev/null +++ b/src/widgets/views/duiseparatorview_p.h @@ -0,0 +1,34 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISEPARATORVIEW_P_H +#define DUISEPARATORVIEW_P_H + +#include "private/duiwidgetview_p.h" + +class DuiSeparatorViewPrivate : public DuiWidgetViewPrivate +{ + Q_DECLARE_PUBLIC(DuiSeparatorView) + +public: + DuiSeparatorViewPrivate(); + ~DuiSeparatorViewPrivate(); +}; + +#endif //DUISEPARATORVIEW_P_H diff --git a/src/widgets/views/duisliderview.cpp b/src/widgets/views/duisliderview.cpp new file mode 100644 index 000000000..7825c046f --- /dev/null +++ b/src/widgets/views/duisliderview.cpp @@ -0,0 +1,1148 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duisliderview.h" +#include "duisliderview_p.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "duitheme.h" +#include "duiscalableimage.h" +#include "duiwidgetview.h" +#include "duislider.h" +#include "duiseekbar.h" +#include "duislider_p.h" +#include "duiviewcreator.h" +#include "duilabel.h" +#include "duiimagewidget.h" +#include "duilayout.h" +#include "duilinearlayoutpolicy.h" + +DuiSliderHandle::DuiSliderHandle(QGraphicsItem *parent) : + DuiWidget(parent), + orientation(Qt::Horizontal), + handlePixmap(0), + handlePressedPixmap(0), + handleVerticalPixmap(0), + handleVerticalPressedPixmap(0), + sliderState(DuiSliderModel::Released) +{ +} + +DuiSliderHandle::~DuiSliderHandle() +{ +} + +void DuiSliderHandle::setOrientation(Qt::Orientation orientation) +{ + this->orientation = orientation; + updateGeometry(); +} + +void DuiSliderHandle::setPixmaps(const QPixmap *handle, + const QPixmap *handlePressed, + const QPixmap *handleVertical, + const QPixmap *handleVerticalPressed) +{ + handlePixmap = handle; + handlePressedPixmap = handlePressed; + handleVerticalPixmap = handleVertical; + handleVerticalPressedPixmap = handleVerticalPressed; + + updateGeometry(); +} + +void DuiSliderHandle::setSliderState(DuiSliderModel::SliderState state) +{ + sliderState = state; + updateGeometry(); +} + +void DuiSliderHandle::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + Q_UNUSED(option); + Q_UNUSED(widget); + + QRect handleRect = rect().toRect(); + + if (sliderState == DuiSliderModel::Pressed) { + if (orientation == Qt::Horizontal) + painter->drawPixmap((handleRect.width() - handlePressedPixmap->width()) / 2, + (handleRect.height() - handlePressedPixmap->height()) / 2, + *handlePressedPixmap); + if (orientation == Qt::Vertical) + painter->drawPixmap((handleRect.width() - handleVerticalPressedPixmap->width()) / 2, + (handleRect.height() - handleVerticalPressedPixmap->height()) / 2, + *handleVerticalPressedPixmap); + } + if (sliderState == DuiSliderModel::Released) { + if (orientation == Qt::Horizontal) + painter->drawPixmap((handleRect.width() - handlePixmap->width()) / 2, + (handleRect.height() - handlePixmap->height()) / 2, + *handlePixmap); + if (orientation == Qt::Vertical) + painter->drawPixmap((handleRect.width() - handleVerticalPixmap->width()) / 2, + (handleRect.height() - handleVerticalPixmap->height()) / 2, + *handleVerticalPixmap); + + } +} + +QSizeF DuiSliderHandle::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const +{ + Q_UNUSED(which); + Q_UNUSED(constraint); + + int width = 0; + int height = 0; + + if (orientation == Qt::Horizontal) { + if (sliderState == DuiSliderModel::Released) { + if (handlePixmap) { + width = qMax(width, handlePixmap->width()); + height = qMax(height, handlePixmap->height()); + } + } + + if (sliderState == DuiSliderModel::Pressed) { + if (handlePressedPixmap) { + width = qMax(width, handlePressedPixmap->width()); + height = qMax(height, handlePressedPixmap->height()); + } + } + } + + if (orientation == Qt::Vertical) { + if (sliderState == DuiSliderModel::Released) { + if (handleVerticalPixmap) { + width = qMax(width, handleVerticalPixmap->width()); + height = qMax(height, handleVerticalPixmap->height()); + } + } + + if (sliderState == DuiSliderModel::Pressed) { + if (handleVerticalPressedPixmap) { + width = qMax(width, handleVerticalPressedPixmap->width()); + height = qMax(height, handleVerticalPressedPixmap->height()); + } + } + } + + return QSizeF(width, height); +} + +DuiSliderIndicator::DuiSliderIndicator(bool isMinMax, QGraphicsItem *parent) : + DuiWidget(parent), + label(0), + image(0), + layout(0) +{ + layout = new QGraphicsAnchorLayout; + setLayout(layout); + + layout->setSpacing(0); + layout->setContentsMargins(0, 0, 0, 0); + + label = new DuiLabel; + if (isMinMax) + label->setObjectName("DuiSliderMinMaxLabel"); + else + label->setObjectName("DuiSliderHandleLabel"); + + image = new DuiImageWidget; + image->setObjectName("DuiSliderImage"); + + layout->addAnchor(layout, Qt::AnchorVerticalCenter, label, Qt::AnchorVerticalCenter); + layout->addAnchor(layout, Qt::AnchorVerticalCenter, image, Qt::AnchorVerticalCenter); + + label->resize(0, 0); + image->resize(0, 0); +} + +DuiSliderIndicator::~DuiSliderIndicator() +{ +} + +void DuiSliderIndicator::setText(const QString &text) +{ + label->setVisible(!text.isEmpty()); + + label->setText(text); + while (layout->count() > 0) + layout->removeAt(0); + + layout->addAnchor(layout, Qt::AnchorVerticalCenter, label, Qt::AnchorVerticalCenter); + layout->addAnchor(layout, Qt::AnchorVerticalCenter, image, Qt::AnchorVerticalCenter); + + if (text.isEmpty()) { + label->setMinimumSize(0, 0); + label->setPreferredSize(0, 0); + label->setMaximumSize(0, 0); + } else { + label->setMinimumSize(label->sizeHint(Qt::PreferredSize)); + label->setPreferredSize(label->sizeHint(Qt::PreferredSize)); + label->setMaximumSize(label->sizeHint(Qt::PreferredSize)); + } + + label->resize(label->sizeHint(Qt::PreferredSize)); + + updateGeometry(); +} + +void DuiSliderIndicator::setImage(const QString &id) +{ + image->setVisible(!id.isEmpty()); + + imageName = id; + + QPixmap *pixmap = 0; + if (!id.isEmpty()) { + pixmap = DuiTheme::pixmapCopy(id); + image->setPixmap(*pixmap); + } else { + pixmap = new QPixmap(); + image->setPixmap(*pixmap); + delete pixmap; + } + + while (layout->count() > 0) + layout->removeAt(0); + + layout->addAnchor(layout, Qt::AnchorVerticalCenter, label, Qt::AnchorVerticalCenter); + layout->addAnchor(layout, Qt::AnchorVerticalCenter, image, Qt::AnchorVerticalCenter); + + if (id.isEmpty()) { + image->setMinimumSize(0, 0); + image->setPreferredSize(0, 0); + image->setMaximumSize(0, 0); + } else { + image->setMinimumSize(image->sizeHint(Qt::PreferredSize)); + image->setPreferredSize(image->sizeHint(Qt::PreferredSize)); + image->setMaximumSize(image->sizeHint(Qt::PreferredSize)); + } + + image->resize(image->sizeHint(Qt::PreferredSize)); + + updateGeometry(); +} + +void DuiSliderIndicator::setVisible(bool visible) +{ + DuiWidget::setVisible(visible); + updateGeometry(); +} + +QSizeF DuiSliderIndicator::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const +{ + Q_UNUSED(which); + Q_UNUSED(constraint); + + qreal width = 0; + qreal height = 0; + + if (DuiWidget::isVisible()) { + if (image && !imageName.isEmpty()) { + width = qMax(width, image->sizeHint(Qt::PreferredSize).width()); + height = qMax(height, image->sizeHint(Qt::PreferredSize).height()); + } + + if (label && !label->text().isEmpty()) { + width = qMax(width, label->sizeHint(Qt::PreferredSize).width()); + height = qMax(height, label->sizeHint(Qt::PreferredSize).height()); + } + } + + return QSizeF(width, height); +} + +DuiSliderGroove::DuiSliderGroove(QGraphicsItem *parent) : + DuiWidget(parent), + controller(0), + orientation(Qt::Horizontal), + backgroundBaseImage(0), + backgroundElapsedImage(0), + backgroundReceivedImage(0), + backgroundVerticalBaseImage(0), + backgroundVerticalElapsedImage(0), + backgroundVerticalReceivedImage(0), + grooveThickness(0), + minimum(0), + maximum(0), + value(0), + loadedContentMinimum(0), + loadedContentMaximum(0), + showSeekBar(false), + sliderHandle(0), + sliderHandleIndicator(0), + preferredLength(0), + minimumLength(0), + maximumLength(0) +{ + sliderHandle = new DuiSliderHandle(this); + sliderHandleIndicator = new DuiSliderIndicator(false, this); +} + +DuiSliderGroove::~DuiSliderGroove() +{ + if (backgroundBaseImage) + DuiTheme::releaseScalableImage(backgroundBaseImage); + if (backgroundElapsedImage) + DuiTheme::releaseScalableImage(backgroundElapsedImage); + if (backgroundReceivedImage) + DuiTheme::releaseScalableImage(backgroundReceivedImage); + if (backgroundVerticalBaseImage) + DuiTheme::releaseScalableImage(backgroundVerticalBaseImage); + if (backgroundVerticalElapsedImage) + DuiTheme::releaseScalableImage(backgroundVerticalElapsedImage); + if (backgroundVerticalReceivedImage) + DuiTheme::releaseScalableImage(backgroundVerticalReceivedImage); + + ensureSafeClosing(); +} + +void DuiSliderGroove::init(DuiSlider *controller) +{ + this->controller = controller; +} + +void DuiSliderGroove::setOrientation(Qt::Orientation orientation) +{ + this->orientation = orientation; + sliderHandle->setOrientation(orientation); + + updateGeometry(); +} + +void DuiSliderGroove::setHandlePixmaps(const QPixmap *handle, + const QPixmap *handlePressed, + const QPixmap *handleVertical, + const QPixmap *handleVerticalPressed) +{ + sliderHandle->setPixmaps(handle, + handlePressed, + handleVertical, + handleVerticalPressed); + + updateGeometry(); +} + +void DuiSliderGroove::setImages(const DuiScalableImage *background, + const DuiScalableImage *backgroundElapsed, + const DuiScalableImage *backgroundReceived, + const DuiScalableImage *backgroundVertical, + const DuiScalableImage *backgroundVerticalElapsed, + const DuiScalableImage *backgroundVerticalReceived) +{ + backgroundBaseImage = background; + backgroundElapsedImage = backgroundElapsed; + backgroundReceivedImage = backgroundReceived; + backgroundVerticalBaseImage = backgroundVertical; + backgroundVerticalElapsedImage = backgroundVerticalElapsed; + backgroundVerticalReceivedImage = backgroundVerticalReceived; + + updateGeometry(); +} + +void DuiSliderGroove::setGrooveThickness(qreal thickness) +{ + grooveThickness = thickness; + + updateGeometry(); +} + +void DuiSliderGroove::setGrooveLength(qreal prefLength, qreal minLength, qreal maxLength) +{ + preferredLength = prefLength; + minimumLength = minLength; + maximumLength = maxLength; + + updateGeometry(); +} + +void DuiSliderGroove::setSliderValues(int min, int max, int val) +{ + if (min < max) { + minimum = min; + maximum = max; + } else { + minimum = max; + maximum = min; + } + + value = val; + value = qBound(minimum, value, maximum); + + QPointF handlePos; + + if (orientation == Qt::Horizontal) + handlePos.setX(valueToScreenCoordinate(value)); + else + handlePos.setY(valueToScreenCoordinate(value)); + updateHandlePos(handlePos); + + update(); +} + +void DuiSliderGroove::setSeekBarValues(bool show, int loadedContentMin, int loadedContentMax) +{ + showSeekBar = show; + + if (loadedContentMin < loadedContentMax) { + loadedContentMinimum = loadedContentMin; + loadedContentMaximum = loadedContentMax; + } else { + loadedContentMinimum = loadedContentMax; + loadedContentMaximum = loadedContentMin; + } + + loadedContentMinimum = qBound(minimum, loadedContentMinimum, maximum); + loadedContentMaximum = qBound(minimum, loadedContentMaximum, maximum); + + update(); +} + +void DuiSliderGroove::setSliderState(DuiSliderModel::SliderState state) +{ + sliderHandle->setSliderState(state); + updateHandleIndicatorPos(); +} + +void DuiSliderGroove::setIndicatorText(const QString &text) +{ + sliderHandleIndicator->setText(text); + updateHandleIndicatorPos(); +} + +void DuiSliderGroove::setIndicatorImage(const QString &id) +{ + sliderHandleIndicator->setImage(id); + updateHandleIndicatorPos(); +} + +void DuiSliderGroove::setIndicatorVisible(bool visible) +{ + sliderHandleIndicator->setVisible(visible); + updateHandleIndicatorPos(); +} + +//converts one of coordinates of point to slider value +int DuiSliderGroove::screenPointToValue(const QPointF &point) const +{ + bool reverse = qApp->isRightToLeft(); + QPointF handlePoint = point - pos(); + + qreal coordinate = 0; + + if (orientation == Qt::Horizontal) + coordinate = handlePoint.x(); + if (orientation == Qt::Vertical) + coordinate = handlePoint.y(); + + int offset = 0; + + if (minimum != maximum) { + if (orientation == Qt::Horizontal) { + coordinate = qBound(clickableArea().left(), coordinate, clickableArea().right()); + + if (!reverse) + offset = qRound(((coordinate - clickableArea().left()) * (maximum - minimum)) / clickableArea().width()); + else + offset = qRound(((clickableArea().right() - coordinate) * (maximum - minimum)) / clickableArea().width()); + } + + if (orientation == Qt::Vertical) { + coordinate = qBound(clickableArea().top(), coordinate, clickableArea().bottom()); + offset = qRound(((clickableArea().bottom() - coordinate) * (maximum - minimum)) / clickableArea().height()); + } + } + + return minimum + offset; +} + +//determines clickable area which is basically the +//exact area of slider groove +QRectF DuiSliderGroove::clickableArea() const +{ + QRectF grooveRect = rect(); + if (!grooveRect.isValid()) + return grooveRect; + + if (orientation == Qt::Horizontal) { + qreal hLeftAdjustment = sliderHandle->rect().width() / 2; + qreal hRightAdjustment = hLeftAdjustment; + + if (backgroundBaseImage) { + int left, right, top, bottom; + backgroundBaseImage->borders(&left, &right, &top, &bottom); + + hLeftAdjustment = qMax(hLeftAdjustment, qreal(left)); + hRightAdjustment = qMax(hRightAdjustment, qreal(right)); + } + grooveRect.adjust(hLeftAdjustment, 0, -hRightAdjustment, 0); + } + + if (orientation == Qt::Vertical) { + qreal vTopAdjustment = sliderHandle->rect().height() / 2; + qreal vBottomAdjustment = vTopAdjustment; + + if (backgroundVerticalBaseImage) { + int left, right, top, bottom; + backgroundVerticalBaseImage->borders(&left, &right, &top, &bottom); + + vTopAdjustment = qMax(vTopAdjustment, qreal(top)); + vBottomAdjustment = qMax(vBottomAdjustment, qreal(bottom)); + } + grooveRect.adjust(0, vTopAdjustment, 0, -vBottomAdjustment); + } + + return grooveRect; +} + +//area occupied by slider handle (user can) +//click both of them +QRectF DuiSliderGroove::clickableHandleArea() const +{ + QRectF handleRect = sliderHandle->rect(); + + handleRect.translate(sliderHandle->pos()); + return handleRect; +} + +QRectF DuiSliderGroove::boundingRect() const +{ + return sliderBoundingRect; +} + +void DuiSliderGroove::raiseHandleIndicator() +{ + QGraphicsItem *newParent = topLevelItem(); + if (newParent) + sliderHandleIndicator->setParentItem(newParent); + + updateHandleIndicatorPos(); +} + +void DuiSliderGroove::lowerHandleIndicator() +{ + sliderHandleIndicator->setParentItem(this); + updateHandleIndicatorPos(); +} + +void DuiSliderGroove::ensureSafeClosing() +{ + sliderHandleIndicator->setParentItem(this); +} + +void DuiSliderGroove::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + Q_UNUSED(option); + Q_UNUSED(widget); + + bool reverse = qApp->isRightToLeft(); + + QRectF grooveRect = rect(); + if (!grooveRect.isValid()) + return; + + int left, right, top, bottom; + + if (orientation == Qt::Horizontal) { + qreal hLeftAdjustment = 0; + qreal hRightAdjustment = 0; + + if (backgroundBaseImage) { + backgroundBaseImage->borders(&left, &right, &top, &bottom); + + qreal semiWidth = sliderHandle->rect().width() / 2; + + if (semiWidth > left) + hLeftAdjustment = semiWidth; + if (semiWidth > right) + hRightAdjustment = semiWidth; + } + + qreal vAdjustment = (grooveRect.height() - grooveThickness) / 2; + grooveRect.adjust(hLeftAdjustment, vAdjustment, -hRightAdjustment, -vAdjustment); + + if (backgroundBaseImage) { + if (grooveRect.width() >= qreal(backgroundBaseImage->pixmap()->width())) + backgroundBaseImage->draw(grooveRect.toRect(), painter); + } + + if (showSeekBar) { + if (backgroundReceivedImage) { + QRectF receivedRect = grooveRect; + + if (!reverse) { + receivedRect.setLeft(valueToScreenCoordinate(loadedContentMinimum)); + receivedRect.setRight(valueToScreenCoordinate(loadedContentMaximum)); + + if (loadedContentMinimum == minimum) + receivedRect.setLeft(grooveRect.left()); + if (loadedContentMaximum == maximum) + receivedRect.setRight(grooveRect.right()); + } else { + receivedRect.setLeft(valueToScreenCoordinate(loadedContentMaximum)); + receivedRect.setRight(valueToScreenCoordinate(loadedContentMinimum)); + + if (loadedContentMinimum == minimum) + receivedRect.setRight(grooveRect.right()); + if (loadedContentMaximum == maximum) + receivedRect.setLeft(grooveRect.left()); + } + + if (receivedRect.width() >= qreal(backgroundReceivedImage->pixmap()->width())) + backgroundReceivedImage->draw(receivedRect.toRect(), painter); + } + } + + if (backgroundElapsedImage) { + QRectF elapsedRect = grooveRect; + + if (!reverse) + elapsedRect.setRight(valueToScreenCoordinate(value)); + else + elapsedRect.setLeft(valueToScreenCoordinate(value)); + + if (elapsedRect.width() >= qreal(backgroundElapsedImage->pixmap()->width())) + backgroundElapsedImage->draw(elapsedRect.toRect(), painter); + } + } + + if (orientation == Qt::Vertical) { + qreal vTopAdjustment = 0; + qreal vBottomAdjustment = 0; + + if (backgroundVerticalBaseImage) { + backgroundVerticalBaseImage->borders(&left, &right, &top, &bottom); + + qreal semiHeight = sliderHandle->rect().height() / 2; + + if (semiHeight > top) + vTopAdjustment = semiHeight; + if (semiHeight > bottom) + vBottomAdjustment = semiHeight; + } + + qreal hAdjustment = (grooveRect.width() - grooveThickness) / 2; + grooveRect.adjust(hAdjustment, vTopAdjustment, -hAdjustment, -vBottomAdjustment); + + if (backgroundVerticalBaseImage) { + if (grooveRect.height() >= qreal(backgroundVerticalBaseImage->pixmap()->height())) + backgroundVerticalBaseImage->draw(grooveRect.toRect(), painter); + } + + if (showSeekBar) { + if (backgroundVerticalReceivedImage) { + QRectF receivedRect = grooveRect; + + receivedRect.setTop(valueToScreenCoordinate(loadedContentMaximum)); + receivedRect.setBottom(valueToScreenCoordinate(loadedContentMinimum)); + + if (loadedContentMinimum == minimum) + receivedRect.setBottom(grooveRect.bottom()); + if (loadedContentMaximum == maximum) + receivedRect.setTop(grooveRect.top()); + + if (receivedRect.height() >= qreal(backgroundVerticalReceivedImage->pixmap()->height())) + backgroundVerticalReceivedImage->draw(receivedRect.toRect(), painter); + } + } + + if (backgroundVerticalElapsedImage) { + QRectF elapsedRect = grooveRect; + + elapsedRect.setTop(valueToScreenCoordinate(value)); + + if (elapsedRect.height() >= qreal(backgroundVerticalElapsedImage->pixmap()->height())) + backgroundVerticalElapsedImage->draw(elapsedRect.toRect(), painter); + } + } +} + +//repositions slider handle (and slider handle indicator) +void DuiSliderGroove::resizeEvent(QGraphicsSceneResizeEvent *event) +{ + Q_UNUSED(event); + + QPointF handlePos; + + if (orientation == Qt::Horizontal) + handlePos.setX(valueToScreenCoordinate(value)); + if (orientation == Qt::Vertical) + handlePos.setY(valueToScreenCoordinate(value)); + + updateHandlePos(handlePos); +} + +QSizeF DuiSliderGroove::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const +{ + Q_UNUSED(constraint); + + switch (which) { + case Qt::MinimumSize: { + if (orientation == Qt::Horizontal) + return QSizeF(minimumLength, sliderHandle->sizeHint(Qt::PreferredSize).height()); + if (orientation == Qt::Vertical) + return QSizeF(sliderHandle->sizeHint(Qt::PreferredSize).width(), minimumLength); + } + case Qt::PreferredSize: { + if (orientation == Qt::Horizontal) + return QSizeF(preferredLength, sliderHandle->sizeHint(Qt::PreferredSize).height()); + if (orientation == Qt::Vertical) + return QSizeF(sliderHandle->sizeHint(Qt::PreferredSize).width(), preferredLength); + } + case Qt::MaximumSize: { + if (orientation == Qt::Horizontal) + return QSizeF(maximumLength, sliderHandle->sizeHint(Qt::PreferredSize).height()); + if (orientation == Qt::Vertical) + return QSizeF(sliderHandle->sizeHint(Qt::PreferredSize).width(), maximumLength); + } + default: + qWarning("DuiSliderView::sizeHint() don't know how to handle the value of 'which' "); + } + + return QSizeF(0, 0); +} + +//called when slider groove is repositioned or +//resized (overidden to reposition slider handle +//(and slider handle indicator)) +void DuiSliderGroove::setGeometry(const QRectF &rect) +{ + DuiWidget::setGeometry(rect); + + setSliderValues(minimum, maximum, value); + setSeekBarValues(showSeekBar, loadedContentMinimum, loadedContentMaximum); +} + +//sets middle point so that the whole rect occupied +//by handle remains inside rect occupied by groove +void DuiSliderGroove::updateHandlePos(const QPointF &position) +{ + if (orientation == Qt::Horizontal) { + qreal x = position.x(); + + x = qBound(sliderHandle->rect().width() / 2, x, rect().width() - (sliderHandle->rect().width() / 2)); + + sliderHandle->setPos(x - (sliderHandle->rect().width() / 2), (rect().height() - sliderHandle->rect().height()) / 2); + } + + if (orientation == Qt::Vertical) { + qreal y = position.y(); + + y = qBound(sliderHandle->rect().height() / 2, y, rect().height() - (sliderHandle->rect().height() / 2)); + + sliderHandle->setPos((rect().width() - sliderHandle->rect().width()) / 2, y - (sliderHandle->rect().height() / 2)); + } + updateHandleIndicatorPos(); +} + +//updates slider handle indicator accordingly to +//slider handle position, orientation and scene +//direction +void DuiSliderGroove::updateHandleIndicatorPos() +{ + if (!controller) + return; + + bool reverse = qApp->isRightToLeft(); + + QPointF handleIndicatorPos = sliderHandle->pos(); + + if (orientation == Qt::Horizontal) { + handleIndicatorPos.setX(handleIndicatorPos.x() + + (sliderHandle->rect().width() / 2) - (sliderHandleIndicator->rect().width() / 2)); + handleIndicatorPos.setY(handleIndicatorPos.y() - sliderHandleIndicator->rect().height()); + } + if (orientation == Qt::Vertical) { + if (!reverse) + handleIndicatorPos.setX(handleIndicatorPos.x() + sliderHandle->rect().width()); + else + handleIndicatorPos.setX(handleIndicatorPos.x() - sliderHandleIndicator->rect().width()); + + handleIndicatorPos.setY(handleIndicatorPos.y() + + (sliderHandle->rect().height() / 2) - (sliderHandleIndicator->rect().height() / 2)); + } + + QPointF groovePos = pos(); + sliderBoundingRect = controller->rect(); + sliderBoundingRect.translate(-groovePos); + + if (orientation == Qt::Horizontal) { + if (handleIndicatorPos.x() < sliderBoundingRect.left()) + handleIndicatorPos.setX(sliderBoundingRect.left()); + if (handleIndicatorPos.x() + sliderHandleIndicator->rect().width() > sliderBoundingRect.right() && + handleIndicatorPos.x() > sliderBoundingRect.left()) + handleIndicatorPos.setX(sliderBoundingRect.right() - sliderHandleIndicator->rect().width()); + } + if (orientation == Qt::Vertical) { + if (handleIndicatorPos.y() < sliderHandleIndicator->rect().top()) + handleIndicatorPos.setY(sliderBoundingRect.top()); + if (handleIndicatorPos.y() + sliderHandleIndicator->rect().height() > sliderBoundingRect.bottom() && + handleIndicatorPos.y() > sliderBoundingRect.top()) + handleIndicatorPos.setY(sliderBoundingRect.bottom() - sliderHandleIndicator->rect().height()); + } + + QGraphicsItem *sliderHandleIndicatorParent = sliderHandleIndicator->parentItem(); + QPointF grooveRelativePos; + if (sliderHandleIndicatorParent) + grooveRelativePos = mapFromScene(scenePos()) - mapFromScene(sliderHandleIndicatorParent->scenePos()); + + sliderHandleIndicator->setPos(grooveRelativePos + handleIndicatorPos); + + //recalculates bounding rect according to area occupied by handle indicator + //because that area still has to be redrawn whenever slider is redrawn + QRectF sliderHandleIndicatorRect = sliderHandleIndicator->rect(); + sliderHandleIndicatorRect.translate(sliderHandleIndicator->pos()); + + sliderBoundingRect.setLeft(qMin(sliderBoundingRect.left(), sliderHandleIndicatorRect.left())); + sliderBoundingRect.setTop(qMin(sliderBoundingRect.top(), sliderHandleIndicatorRect.top())); + sliderBoundingRect.setRight(qMax(sliderBoundingRect.right(), sliderHandleIndicatorRect.right())); + sliderBoundingRect.setBottom(qMax(sliderBoundingRect.bottom(), sliderHandleIndicatorRect.bottom())); + + prepareGeometryChange(); +} + +//converts value to scene coordinate (x coordinate for +//horizontal sliders and y coordinate for vertical sliders) +qreal DuiSliderGroove::valueToScreenCoordinate(int value) const +{ + bool reverse = qApp->isRightToLeft(); + qreal beginning = 0; + + if (orientation == Qt::Horizontal) + beginning = clickableArea().left(); + if (orientation == Qt::Vertical) + beginning = clickableArea().top(); + + qreal offset = 0; + if (minimum != maximum) { + if (orientation == Qt::Horizontal) { + if (!reverse) + offset = (value - minimum) * clickableArea().width() / (maximum - minimum); + else + offset = (maximum - value) * clickableArea().width() / (maximum - minimum); + } + + if (orientation == Qt::Vertical) { + offset = (maximum - value) * clickableArea().height() / (maximum - minimum); + } + } + + return beginning + offset; +} + +DuiSliderViewPrivate::DuiSliderViewPrivate() : + controller(0), + sliderGroove(0), + minIndicator(0), + maxIndicator(0), + horizontalPolicy(0), + verticalPolicy(0), + valueWhenPressed(0) +{ + sliderGroove = new DuiSliderGroove; + //these are minmax indicators + minIndicator = new DuiSliderIndicator(true); + maxIndicator = new DuiSliderIndicator(true); +} + +DuiSliderViewPrivate::~DuiSliderViewPrivate() +{ + sliderGroove->ensureSafeClosing(); +} + +//intializes main layout and layout policies +void DuiSliderViewPrivate::init(DuiSlider *controller) +{ + this->controller = controller; + sliderGroove->init(controller); + + bool reverse = qApp->isRightToLeft(); + + DuiLayout *mainLayout = new DuiLayout; + controller->setLayout(mainLayout); + + horizontalPolicy = new DuiLinearLayoutPolicy(mainLayout, Qt::Horizontal); + horizontalPolicy->setSpacing(0); + horizontalPolicy->setContentsMargins(0, 0, 0, 0); + + if (!reverse) { + horizontalPolicy->addItem(minIndicator, Qt::AlignCenter); + horizontalPolicy->setStretchFactor(minIndicator, 0); + horizontalPolicy->addItem(sliderGroove, Qt::AlignCenter); + horizontalPolicy->setStretchFactor(sliderGroove, 1); + horizontalPolicy->addItem(maxIndicator, Qt::AlignCenter); + horizontalPolicy->setStretchFactor(maxIndicator, 0); + } else { + horizontalPolicy->addItem(maxIndicator, Qt::AlignCenter); + horizontalPolicy->setStretchFactor(maxIndicator, 0); + horizontalPolicy->addItem(sliderGroove, Qt::AlignCenter); + horizontalPolicy->setStretchFactor(sliderGroove, 1); + horizontalPolicy->addItem(minIndicator, Qt::AlignCenter); + horizontalPolicy->setStretchFactor(minIndicator, 0); + } + + verticalPolicy = new DuiLinearLayoutPolicy(mainLayout, Qt::Vertical); + verticalPolicy->setSpacing(0); + verticalPolicy->setContentsMargins(0, 0, 0, 0); + + verticalPolicy->addItem(maxIndicator, Qt::AlignCenter); + verticalPolicy->setStretchFactor(maxIndicator, 0); + verticalPolicy->addItem(sliderGroove, Qt::AlignCenter); + verticalPolicy->setStretchFactor(sliderGroove, 1); + verticalPolicy->addItem(minIndicator, Qt::AlignCenter); + verticalPolicy->setStretchFactor(minIndicator, 0); +} + +//changes slider orientation by activating +//the corresponding layout policy and setting +//corresponding min, max and preferred sizes +void DuiSliderViewPrivate::updateOrientation() +{ + DuiLayout *mainLayout = dynamic_cast(controller->layout()); + if (!mainLayout || !horizontalPolicy || !verticalPolicy) { + qWarning("DuiSlider was not initialized properly"); + return; + } + + Q_Q(DuiSliderView); + if (q->model()->orientation() == Qt::Horizontal) { + if (mainLayout->policy() != horizontalPolicy) + mainLayout->setPolicy(horizontalPolicy); + } + //in case of vertical sliders width and height + //defined in css file will be simply swapped + if (q->model()->orientation() == Qt::Vertical) { + if (mainLayout->policy() != verticalPolicy) + mainLayout->setPolicy(verticalPolicy); + } + + sliderGroove->setOrientation(q->model()->orientation()); +} + +//returns true if user clicked on slider groove +//or slider handle area and false otherwise +bool DuiSliderViewPrivate::isCollision(QGraphicsSceneMouseEvent *event) const +{ + QRectF clickableRect = sliderGroove->clickableArea(); + clickableRect.translate(sliderGroove->pos()); + + QRectF clickableHandleRect = sliderGroove->clickableHandleArea(); + clickableHandleRect.translate(sliderGroove->pos()); + + return (clickableRect.contains(event->pos()) || clickableHandleRect.contains(event->pos())); +} + +//sets slider value to that one corresponding +//to mouse cursor position +void DuiSliderViewPrivate::updateValue(QGraphicsSceneMouseEvent *event) +{ + controller->setValue(sliderGroove->screenPointToValue(event->pos())); +} + +//refreshes slider groove (min, max and value, slider state) +void DuiSliderViewPrivate::updateSliderGroove() +{ + Q_Q(DuiSliderView); + sliderGroove->setSliderValues(q->model()->minimum(), q->model()->maximum(), q->model()->value()); + sliderGroove->setSliderState(q->model()->state()); +} + +//refreshes slider seekbar related values (just for seekbars) +void DuiSliderViewPrivate::updateSeekBar() +{ + Q_Q(DuiSliderView); + const DuiSeekBarModel *seekBarModel = qobject_cast(q->model()); + if (!seekBarModel) + sliderGroove->setSeekBarValues(false); + else + sliderGroove->setSeekBarValues(true, seekBarModel->loadedContentMin(), seekBarModel->loadedContentMax()); +} + +DuiSliderView::DuiSliderView(DuiSlider *controller): + DuiWidgetView(*new DuiSliderViewPrivate, controller) +{ + Q_D(DuiSliderView); + d->init(controller); +} + +DuiSliderView::~DuiSliderView() +{ +} + +void DuiSliderView::updateData(const QList& modifications) +{ + DuiWidgetView::updateData(modifications); + + Q_D(DuiSliderView); + const char *member; + + foreach(member, modifications) { + if (member == DuiSliderModel::Orientation) { + d->updateOrientation(); + updateGeometry(); + } + if (member == DuiSliderModel::State) + d->updateSliderGroove(); + else if (member == DuiSliderModel::Minimum) + d->updateSliderGroove(); + else if (member == DuiSliderModel::Maximum) + d->updateSliderGroove(); + else if (member == DuiSliderModel::Value) + d->updateSliderGroove(); + else if (member == DuiSliderModel::Steps) + d->updateSliderGroove(); + else if (member == DuiSeekBarModel::LoadedContentMin) + d->updateSeekBar(); + else if (member == DuiSeekBarModel::LoadedContentMax) + d->updateSeekBar(); + else if (member == DuiSliderModel::MinLabelText) + d->minIndicator->setText(model()->minLabelText()); + else if (member == DuiSliderModel::MaxLabelText) + d->maxIndicator->setText(model()->maxLabelText()); + else if (member == DuiSliderModel::HandleLabelText) + d->sliderGroove->setIndicatorText(model()->handleLabelText()); + else if (member == DuiSliderModel::MinLabelIcon) + d->minIndicator->setImage(model()->minLabelIcon()); + else if (member == DuiSliderModel::MaxLabelIcon) + d->maxIndicator->setImage(model()->maxLabelIcon()); + else if (member == DuiSliderModel::HandleLabelIcon) + d->sliderGroove->setIndicatorImage(model()->handleLabelIcon()); + else if (member == DuiSliderModel::MinLabelVisible) + d->minIndicator->setVisible(model()->minLabelVisible()); + else if (member == DuiSliderModel::MaxLabelVisible) + d->maxIndicator->setVisible(model()->maxLabelVisible()); + else if (member == DuiSliderModel::HandleLabelVisible) + d->sliderGroove->setIndicatorVisible(model()->handleLabelVisible()); + } +} + +void DuiSliderView::setupModel() +{ + DuiWidgetView::setupModel(); + + Q_D(DuiSliderView); + + d->minIndicator->setText(model()->minLabelText()); + d->maxIndicator->setText(model()->maxLabelText()); + d->sliderGroove->setIndicatorText(model()->handleLabelText()); + + d->minIndicator->setImage(model()->minLabelIcon()); + d->maxIndicator->setImage(model()->maxLabelIcon()); + d->sliderGroove->setIndicatorImage(model()->handleLabelIcon()); + + d->minIndicator->setVisible(model()->minLabelVisible()); + d->maxIndicator->setVisible(model()->maxLabelVisible()); + d->sliderGroove->setIndicatorVisible(model()->handleLabelVisible()); + + d->updateOrientation(); + d->updateSliderGroove(); + d->updateSeekBar(); + + updateGeometry(); +} + +void DuiSliderView::applyStyle() +{ + DuiWidgetView::applyStyle(); + + Q_D(DuiSliderView); + + d->sliderGroove->setHandlePixmaps(style()->handlePixmap(), + style()->handlePressedPixmap(), + style()->handleVerticalPixmap(), + style()->handleVerticalPressedPixmap()); + d->sliderGroove->setImages(style()->backgroundBaseImage(), + style()->backgroundElapsedImage(), + style()->backgroundReceivedImage(), + style()->backgroundVerticalBaseImage(), + style()->backgroundVerticalElapsedImage(), + style()->backgroundVerticalReceivedImage()); + + d->sliderGroove->setGrooveThickness(style()->grooveThickness()); + d->sliderGroove->setGrooveLength(style()->groovePreferredLength(), + style()->grooveMinimumLength(), + style()->grooveMaximumLength()); + + d->updateOrientation(); + + //only to reposition slider handle + d->updateSliderGroove(); + + updateGeometry(); +} + +void DuiSliderView::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + Q_D(DuiSliderView); + if (d->isCollision(event)) { + d->valueWhenPressed = model()->value(); + + d->controller->setState(DuiSliderModel::Pressed); + d->updateValue(event); + d->sliderGroove->raiseHandleIndicator(); + } +} + +void DuiSliderView::cancelEvent(DuiCancelEvent *event) +{ + Q_UNUSED(event); + Q_D(DuiSliderView); + d->controller->setState(DuiSliderModel::Released); + + model()->setValue(d->valueWhenPressed); + d->updateSliderGroove(); + d->sliderGroove->lowerHandleIndicator(); +} + +void DuiSliderView::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + Q_D(DuiSliderView); + if (d->isCollision(event) || model()->state() == DuiSliderModel::Pressed) { + d->controller->setState(DuiSliderModel::Released); + d->updateValue(event); + d->sliderGroove->lowerHandleIndicator(); + } +} + +void DuiSliderView::mouseMoveEvent(QGraphicsSceneMouseEvent *event) +{ + Q_D(DuiSliderView); + if (d->isCollision(event)) { + d->controller->setState(DuiSliderModel::Pressed); + d->updateValue(event); + d->sliderGroove->raiseHandleIndicator(); + } else if (model()->state() == DuiSliderModel::Pressed) { + d->controller->setState(DuiSliderModel::Released); + d->updateValue(event); + d->sliderGroove->lowerHandleIndicator(); + } +} + +DUI_REGISTER_VIEW_NEW(DuiSliderView, DuiSlider) diff --git a/src/widgets/views/duisliderview.h b/src/widgets/views/duisliderview.h new file mode 100644 index 000000000..676a5452c --- /dev/null +++ b/src/widgets/views/duisliderview.h @@ -0,0 +1,145 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISLIDERVIEW_H +#define DUISLIDERVIEW_H + +#include "duiwidgetview.h" +#include +#include + +class DuiSliderViewPrivate; +class DuiSlider; + +/*! + \class DuiLabelView + \brief Standard view is used to visualize sliders and seekbars. + + \ingroup views + + \section DuiSliderViewOverview Overview + Slider view class renders slider and seekbars. + + Outlook of sliders and seekbars can be changed using the styling + attributes defined in DuiSliderStyle and DuiWidgetStyle. + + \section DuiSliderViewInteractions Interactions + A slider (seekbar) can be in one of the following functional states: + - Released: default state. + - Pressed: when slider handle is tapped. + Tapping slider handle will catch it and then slider will fall into Pressed state. + In this state slider handle follows tapping point (is dragged). + Slider value is changed by draging slider handle to required place. + If slider groove is tapped, slider thumb will be moved to that place + and slider will fall into Pressed state. + + \section DuiSliderViewOpenIssues Open issues + - Animated slider handle moving (when dragging or tapping slider groove) not supported yet. + + \sa DuiSliderStyle DuiWidgetView +*/ + +class DUI_EXPORT DuiSliderView : public DuiWidgetView +{ + Q_OBJECT + DUI_VIEW(DuiSliderModel, DuiSliderStyle) + +public: + /*! + \brief Constructs toolbar view. + \param Pointer to the controller. + */ + DuiSliderView(DuiSlider *controller); + + /*! + \brief Destructs the view. + */ + virtual ~DuiSliderView(); + +protected: + /*! + \brief Updates DuiSliderView class instance when current style is changed. + + Called when DuiSliderStyle class instance is changed (usually) + during initialization. + */ + virtual void applyStyle(); + + /*! + \brief Mouse press event handler. + + Accepted when clicking onto slider groove. Ignored clicking outside + of slider groove. Slider falls into Pressed state and DuiSlider::sliderPressed() + signal is emitted. + */ + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + + /*! + \brief Mouse press event handler. + + Releases slider handle. Slider falls back into Released state and + DuiSlider::sliderReleased() signal is emitted. + */ + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + + /*! + \brief Mouse move event handler. + + If slider is in pressed State drags slider thumb. As slider handle is dragged + DuiSlider::valueChanged(int) signal is emitted. + */ + virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event); + + /*! + \brief Cancel event handler. + + Sets slider back to Released state. + */ + virtual void cancelEvent(DuiCancelEvent *event); + + /*! + \brief Updates DuiSliderView class instance when current model is changed. + + Called when DuiSliderModel (DuiSeekBarModel) class instance is changed + (usually) during initialization. + */ + virtual void setupModel(); + + /*! + \brief Updates DuiSliderView class instance when some component + of underlying model is modified. + \param List containing the names of modified model components. + + Called when some field of underlying DuiSliderModel (DuiSeekBarModel) + class instance is modified and view shuold reflect that modification. + */ + virtual void updateData(const QList& modifications); + +private: + Q_DISABLE_COPY(DuiSliderView) + Q_DECLARE_PRIVATE(DuiSliderView) + +#ifdef UNIT_TEST + //! Test unit is defined as a friend of production code to access private members + friend class Ut_DuiSliderView; +#endif // UNIT_TEST + +}; + +#endif diff --git a/src/widgets/views/duisliderview_p.h b/src/widgets/views/duisliderview_p.h new file mode 100644 index 000000000..d27c8c240 --- /dev/null +++ b/src/widgets/views/duisliderview_p.h @@ -0,0 +1,224 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISLIDERVIEW_P_H +#define DUISLIDERVIEW_P_H + +#include "duisliderview.h" +#include "private/duiwidgetview_p.h" + +#include +#include "duislidermodel.h" + +class DuiSlider; +class QPixmap; +class DuiScalableImage; +class DuiLabel; +class DuiImageWidget; +class QGraphicsAnchorLayout; +class DuiLinearLayoutPolicy; +class DuiSliderView; + +class DuiSliderHandle : public DuiWidget +{ +public: + DuiSliderHandle(QGraphicsItem *parent = 0); + virtual ~DuiSliderHandle(); + + void setOrientation(Qt::Orientation); + void setPixmaps(const QPixmap *handle, + const QPixmap *handlePressed, + const QPixmap *handleVertical, + const QPixmap *handleVerticalPressed); + + void setSliderState(DuiSliderModel::SliderState state); + + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0); + + virtual QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const; + +private: + Qt::Orientation orientation; + + const QPixmap *handlePixmap; + const QPixmap *handlePressedPixmap; + const QPixmap *handleVerticalPixmap; + const QPixmap *handleVerticalPressedPixmap; + + DuiSliderModel::SliderState sliderState; + +#ifdef UNIT_TEST + friend class Ut_DuiSliderView; +#endif // UNIT_TEST +}; + +class DuiSliderIndicator : public DuiWidget +{ + Q_OBJECT +public: + DuiSliderIndicator(bool isMinMax, QGraphicsItem *parent = 0); + virtual ~DuiSliderIndicator(); + + void setText(const QString &text); + void setImage(const QString &id); + void setVisible(bool visible); + +protected: + virtual QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const; + +private: + DuiLabel *label; + DuiImageWidget *image; + QString imageName; + + QGraphicsAnchorLayout *layout; + +#ifdef UNIT_TEST + friend class Ut_DuiSliderView; +#endif // UNIT_TEST +}; + +class DuiSliderGroove : public DuiWidget +{ + Q_OBJECT +public: + DuiSliderGroove(QGraphicsItem *parent = 0); + virtual ~DuiSliderGroove(); + + void init(DuiSlider *controller); + + void setOrientation(Qt::Orientation); + + void setHandlePixmaps(const QPixmap *handle, + const QPixmap *handlePressed, + const QPixmap *handleVertical, + const QPixmap *handleVerticalPressed); + void setImages(const DuiScalableImage *background, + const DuiScalableImage *backgroundElapsed, + const DuiScalableImage *backgroundReceived, + const DuiScalableImage *backgroundVertical, + const DuiScalableImage *backgroundVerticalElapsed, + const DuiScalableImage *backgroundVerticalReceived); + void setGrooveThickness(qreal thickness); + void setGrooveLength(qreal prefLength, qreal minLength, qreal maxLength); + + void setSliderValues(int min, int max, int val); + void setSeekBarValues(bool show, int loadedContentMin = 0, int loadedContentMax = 0); + void setSliderState(DuiSliderModel::SliderState state); + + void setIndicatorText(const QString &text); + void setIndicatorImage(const QString &id); + void setIndicatorVisible(bool visible); + + int screenPointToValue(const QPointF &point) const; + + QRectF clickableArea() const; + QRectF clickableHandleArea() const; + + QRectF boundingRect() const; + + void raiseHandleIndicator(); + void lowerHandleIndicator(); + + void ensureSafeClosing(); + + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0); + +protected: + virtual QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const; + + void setGeometry(const QRectF &rect); + virtual void resizeEvent(QGraphicsSceneResizeEvent *event); + +private: + void updateHandlePos(const QPointF &position); + void updateHandleIndicatorPos(); + + DuiSlider *controller; + + Qt::Orientation orientation; + + qreal valueToScreenCoordinate(int value) const; + + const DuiScalableImage *backgroundBaseImage; + const DuiScalableImage *backgroundElapsedImage; + const DuiScalableImage *backgroundReceivedImage; + const DuiScalableImage *backgroundVerticalBaseImage; + const DuiScalableImage *backgroundVerticalElapsedImage; + const DuiScalableImage *backgroundVerticalReceivedImage; + + qreal grooveThickness; + + int minimum; + int maximum; + int value; + + int loadedContentMinimum; + int loadedContentMaximum; + bool showSeekBar; + + + DuiSliderHandle *sliderHandle; + DuiSliderIndicator *sliderHandleIndicator; + + QRectF sliderBoundingRect; + + qreal preferredLength; + qreal minimumLength; + qreal maximumLength; + +#ifdef UNIT_TEST + friend class Ut_DuiSliderView; +#endif // UNIT_TEST +}; + +class DuiSliderViewPrivate : public DuiWidgetViewPrivate +{ + Q_DECLARE_PUBLIC(DuiSliderView) + +public: + DuiSliderViewPrivate(); + virtual ~DuiSliderViewPrivate(); + + DuiSlider *controller; + + DuiSliderGroove *sliderGroove; + + DuiSliderIndicator *minIndicator; + DuiSliderIndicator *maxIndicator; + + DuiLinearLayoutPolicy *horizontalPolicy; + DuiLinearLayoutPolicy *verticalPolicy; + + int valueWhenPressed; + + void init(DuiSlider *contoller); + + void updateOrientation(); + bool isCollision(QGraphicsSceneMouseEvent *event) const; + void updateValue(QGraphicsSceneMouseEvent *event); + void updateSliderGroove(); + void updateSeekBar(); + +#ifdef UNIT_TEST + friend class Ut_DuiSliderView; +#endif // UNIT_TEST +}; + +#endif diff --git a/src/widgets/views/duispinnerview.cpp b/src/widgets/views/duispinnerview.cpp new file mode 100644 index 000000000..a4d5e1bfd --- /dev/null +++ b/src/widgets/views/duispinnerview.cpp @@ -0,0 +1,255 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include +#include +#include + +#include "duispinnerview.h" +#include "duispinnerview_p.h" + +#include "duiprogressindicator.h" +#include "duiprogressindicator_p.h" +#include "duiviewcreator.h" + +#include "duitheme.h" +#include "duiscalableimage.h" +#include "duidebug.h" + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +const int SpinnerRefreshRate = 30; + +DuiSpinnerViewPrivate::DuiSpinnerViewPrivate() + : controller(0), + inactiveElement(0), + activeElement(0), + position(0), + elapsed(0), + timer(0) +{ +} + + +DuiSpinnerViewPrivate::~DuiSpinnerViewPrivate() +{ + DuiTheme::releasePixmap(activeElement); + DuiTheme::releasePixmap(inactiveElement); + + delete timer; +} + + +DuiSpinnerView::DuiSpinnerView(DuiProgressIndicator *controller) : + DuiWidgetView(* new DuiSpinnerViewPrivate, controller) +{ + Q_D(DuiSpinnerView); + d->controller = controller; + connect(controller, SIGNAL(visibilityChanged(bool)), this, SLOT(visibilityChanged(bool))); +} + + +DuiSpinnerView::~DuiSpinnerView() +{ +} + +void DuiSpinnerViewPrivate::animationTimeout() +{ + Q_Q(DuiSpinnerView); + + if (q->model()->unknownDuration()) { + + // calculate interval in secs and add it to elapsed time + qreal interval = (qreal) timer->interval() / 1000.0; + elapsed += interval; + + // calculate how many steps we should take + int steps = (int)(elapsed * (qreal) q->style()->speed()); + if (steps > 0) { + // subtract the amount we will step from the elapsed time + elapsed -= steps * (1.0 / (qreal) q->style()->speed()); + // and perform the stepping + position = (position + steps) % elements.count(); + // redraw + q->update(); + } + } +} + +void DuiSpinnerView::updateData(const QList& modifications) +{ + DuiWidgetView::updateData(modifications); + + Q_D(DuiSpinnerView); + + foreach(const char * member, modifications) { + if (member == DuiProgressIndicatorModel::UnknownDuration) { + if (model()->unknownDuration()) { + if (!d->timer) { + d->timer = new QTimer(this); + connect(d->timer, SIGNAL(timeout()), this, SLOT(animationTimeout())); + } + d->timer->start(SpinnerRefreshRate); + } else { + delete d->timer; + d->timer = NULL; + } + } + } + + update(); +} + +void DuiSpinnerView::setupModel() +{ + DuiWidgetView::setupModel(); + + Q_D(DuiSpinnerView); + + if (model()->unknownDuration()) { + if (!d->timer) { + d->timer = new QTimer(this); + connect(d->timer, SIGNAL(timeout()), this, SLOT(animationTimeout())); + } + d->timer->start(SpinnerRefreshRate); + } else { + delete d->timer; + d->timer = NULL; + } + + update(); +} + + +void DuiSpinnerView::drawContents(QPainter *painter, const QStyleOptionGraphicsItem *option) const +{ + Q_UNUSED(option); + + Q_D(const DuiSpinnerView); + + const int elementsCount = d->elements.count(); + if (style()->inactiveImage() && style()->activeImage()) { + + // size of an element + QSize size(style()->elementSize(), style()->elementSize()); + + if (model()->unknownDuration()) { + // every n'th should be active + int span = (d->elements.count() / style()->activeElementCount()); + // this tells the active index within the span + int activeIndexInSpan = d->position % span; + + // draw all elements with proper image + for (int i = 0; i < elementsCount; ++i) { + if ((i % span) == activeIndexInSpan) { + painter->drawPixmap(QRect(d->elements[i], size), *style()->activeImage()); + } else { + painter->drawPixmap(QRect(d->elements[i], size), *style()->inactiveImage()); + } + } + } else { + // active element count + int active = (model()->value() - model()->minimum()) * d->elements.count() / + qMax(model()->maximum() - model()->minimum(), 1); + + // draw active elements + for (int i = 0; i < active; ++i) { + painter->drawPixmap(QRect(d->elements[i], size), *style()->activeImage()); + } + + // draw inactive elements + for (int i = active; i < elementsCount; ++i) { + painter->drawPixmap(QRect(d->elements[i], size), *style()->inactiveImage()); + } + } + } +} + +void DuiSpinnerViewPrivate::calculateShape(QSizeF size) +{ + Q_Q(DuiSpinnerView); + + QSizeF s = size - QSizeF(q->style()->elementSize(), q->style()->elementSize()); + + qreal diameter = qMin(s.width(), s.height()); + + // clear existing elements + elements.clear(); + + if (q->style()->elementCount() > 0) { + // center point + QPoint center(size.width() * 0.5, size.height() * 0.5); + + // radius for the spinner + qreal radius = diameter * 0.5f; + + // half element size + qreal halfElementSize = q->style()->elementSize() * 0.5; + + qreal angle = 0; + qreal span = (M_PI * 2.0) / q->style()->elementCount(); + + // calculate spherical shape and store points where the item should be drawn + const int elementsCount = q->style()->elementCount(); + for (int i = 0; i < elementsCount; ++i) { + + QPoint position; + position.setX(center.x() + (sinf(angle) * radius) - halfElementSize); + position.setY(center.y() - (cosf(angle) * radius) - halfElementSize); + + elements.append(position); + + angle += span; + } + } +} + +void DuiSpinnerView::resizeEvent(QGraphicsSceneResizeEvent *event) +{ + Q_D(DuiSpinnerView); + d->calculateShape(event->newSize()); +} + +void DuiSpinnerView::applyStyle() +{ + Q_D(DuiSpinnerView); + DuiWidgetView::applyStyle(); + d->calculateShape(size()); +} + + +void DuiSpinnerViewPrivate::visibilityChanged(bool visible) +{ + if (timer) { + if (visible) { + timer->start(SpinnerRefreshRate); + } else { + timer->stop(); + } + } +} + +#include "moc_duispinnerview.cpp" + +// bind controller widget and view widget together by registration macro +DUI_REGISTER_VIEW_NEW(DuiSpinnerView, DuiProgressIndicator) diff --git a/src/widgets/views/duispinnerview.h b/src/widgets/views/duispinnerview.h new file mode 100644 index 000000000..f22a699ae --- /dev/null +++ b/src/widgets/views/duispinnerview.h @@ -0,0 +1,103 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISPINNERVIEW_H +#define DUISPINNERVIEW_H + +#include "duiwidgetview.h" +#include +#include + +class DuiSpinnerViewPrivate; +class DuiProgressIndicator; +class QGraphicsSceneResizeEvent; +class QTimerEvent; + +/*! + \class DuiSpinnerView + \brief Spinner view for DuiProgressIndicator. + + \ingroup views + + \tableofcontents + + \section SpinnerOverview Overview + Spinner rotates clockwise indefinitely until the process is finished or interrupted. Spinner is + used only for unknown durations. It can can be placed anywhere in UI and also on top of other UI + components to indicate ongoing processes. It should be used when the available space is limited. + It can be used to indicate e.g. scanning or refreshing + + + + +
\image html circular_progress.png Progress indicator with spinner view.
+ + \section SpinnerInteractions Interactions + Spinner is always non-interactive. + + \section SpinnerOpenIssues Open issues + \li Progress indicator shape, visualization, animation, size and possible subcomponents such + as label and error notification? Nothing yet decided by UI/Graphics team, so far only concepting + has been done. + \li Layout: where to display the current status (%, time, data bytes) of the progress indication? + \li Graphics + + \sa DuiProgressIndicator DuiProgressIndicatorModel DuiSpinnerStyle +*/ + +class DUI_EXPORT DuiSpinnerView : public DuiWidgetView +{ + Q_OBJECT + DUI_VIEW(DuiProgressIndicatorModel, DuiSpinnerStyle) + +public: + /*! + * \brief Constructor + * + * \param controller Pointer to the progressindicator's controller + */ + DuiSpinnerView(DuiProgressIndicator *controller); + + /*! + * \brief Destructor + */ + virtual ~DuiSpinnerView(); + +protected: + //! \cond + virtual void drawContents(QPainter *painter, const QStyleOptionGraphicsItem *option) const; + void resizeEvent(QGraphicsSceneResizeEvent *event); + virtual void setupModel(); + virtual void applyStyle(); + //! \endcond + +protected slots: + //! \reimp + virtual void updateData(const QList& modifications); + //! \reimp_end + +private: + Q_DISABLE_COPY(DuiSpinnerView) + Q_DECLARE_PRIVATE(DuiSpinnerView) + + Q_PRIVATE_SLOT(d_func(), void visibilityChanged(bool)) + Q_PRIVATE_SLOT(d_func(), void animationTimeout()) +}; + +#endif // DUISPINNERVIEW_H diff --git a/src/widgets/views/duispinnerview_p.h b/src/widgets/views/duispinnerview_p.h new file mode 100644 index 000000000..49401e066 --- /dev/null +++ b/src/widgets/views/duispinnerview_p.h @@ -0,0 +1,59 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISPINNERVIEW_P_H +#define DUISPINNERVIEW_P_H + +#include +#include +#include "private/duiwidgetview_p.h" + +class DuiStyle; +class DuiProgressIndicator; +class QPixmap; +class QTimer; + +class DuiSpinnerViewPrivate : public DuiWidgetViewPrivate +{ +public: + Q_DECLARE_PUBLIC(DuiSpinnerView) + + DuiSpinnerViewPrivate(); + virtual ~DuiSpinnerViewPrivate(); + + void animationTimeout(); + void visibilityChanged(bool); + void calculateShape(QSizeF size); + + DuiProgressIndicator *controller; + + const QPixmap *inactiveElement; + const QPixmap *activeElement; + int position; + qreal elapsed; + + QTimer *timer; + QVector elements; + +#ifdef DUI_UNIT_TEST + DUI_UNIT_TEST; +#endif +}; + +#endif // DUISPINNERVIEW_P_H diff --git a/src/widgets/views/duistylablewidgetview.cpp b/src/widgets/views/duistylablewidgetview.cpp new file mode 100644 index 000000000..fb56f36f9 --- /dev/null +++ b/src/widgets/views/duistylablewidgetview.cpp @@ -0,0 +1,70 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duistylablewidgetview_p.h" +#include "duistylablewidget.h" +#include "duitheme.h" +#include "duiviewcreator.h" +#include "private/duiwidgetview_p.h" + +DuiStylableWidgetView::DuiStylableWidgetView(DuiStylableWidget *_controller) : + DuiWidgetView(* new DuiWidgetViewPrivate, _controller) +{ + controller = _controller; +} + +DuiStylableWidgetView::~DuiStylableWidgetView() +{ +} + +DuiWidgetStyleContainer *DuiStylableWidgetView::createStyleContainer() const +{ + // returns Style Container stored in the controller side. + return controller->createStyleContainer(); +} + +void DuiStylableWidgetView::drawBackground(QPainter *painter, const QStyleOptionGraphicsItem *option) const +{ + //Rerouting the call to the controller to allow implementation of this + //method in a simple widget class. + controller->drawBackground(painter, option); +} + +void DuiStylableWidgetView::drawContents(QPainter *painter, const QStyleOptionGraphicsItem *option) const +{ + //Rerouting the call to the controller to allow implementation of this + //method in a simple widget class. + controller->drawContents(painter, option); +} + +void DuiStylableWidgetView::drawForeground(QPainter *painter, const QStyleOptionGraphicsItem *option) const +{ + //Rerouting the call to the controller to allow implementation of this + //method in a simple widget class. + controller->drawForeground(painter, option); +} + +void DuiStylableWidgetView::applyStyle() +{ + //Rerouting the call to the controller to allow implementation of this + //method in a simple widget class. + controller->applyStyle(); +} +DUI_REGISTER_VIEW_NEW(DuiStylableWidgetView, DuiStylableWidget) + diff --git a/src/widgets/views/duistylablewidgetview_p.h b/src/widgets/views/duistylablewidgetview_p.h new file mode 100644 index 000000000..d0f0cea68 --- /dev/null +++ b/src/widgets/views/duistylablewidgetview_p.h @@ -0,0 +1,91 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISTYLABLEWIDGETVIEW_H +#define DUISTYLABLEWIDGETVIEW_H + +#include + +class DuiStylableWidget; + +/*! + \class DuiStylableWidgetView + + \brief DuiStylableWidgetView is a specialised view to be used within simple non-MVC widgets. + + DuiStylableWidget class is a specialised view to be used only withing DuiStylableWidget class. + It allows the DuiStylableWidget to provide style attributes information to child widgets. + */ +class DuiStylableWidgetView : public DuiWidgetView +{ + Q_OBJECT + +public: + /*! + * \brief Constructor + * \param controller Pointer to the stylable widget controller + */ + DuiStylableWidgetView(DuiStylableWidget *controller); + + /*! + \brief Destructor. + */ + virtual ~DuiStylableWidgetView(); + +protected: + virtual DuiWidgetStyleContainer *createStyleContainer() const; + + /*! + * Draws the background for this view. + */ + virtual void drawBackground(QPainter *painter, const QStyleOptionGraphicsItem *option) const; + + /*! + * Draws the contents for this view. + */ + virtual void drawContents(QPainter *painter, const QStyleOptionGraphicsItem *option) const; + + /*! + * Draws the foreground for this view. + */ + virtual void drawForeground(QPainter *painter, const QStyleOptionGraphicsItem *option) const; + + /*! + Notification for derived classes. This method gets called when a new style is applied for this view. + This happens e.g. when the object is constructed and when a new object name is given to the widget. + This method routes the call back to the simple widget controller. + */ + virtual void applyStyle(); + +private: + + // This is a private class, we can store it inside. + DuiStylableWidget *controller; + + inline DuiWidgetModel *model() { + return DuiWidgetView::model(); + } + inline const DuiWidgetModel *model() const { + return DuiWidgetView::model(); + } + + Q_DISABLE_COPY(DuiStylableWidgetView) +}; + +#endif // DUISTYLABLEWIDGETVIEW_H diff --git a/src/widgets/views/duitexteditview.cpp b/src/widgets/views/duitexteditview.cpp new file mode 100644 index 000000000..d7e59d352 --- /dev/null +++ b/src/widgets/views/duitexteditview.cpp @@ -0,0 +1,1141 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duitexteditview.h" +#include "duitexteditview_p.h" +#include "duicompleter.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "duifeedback.h" +#include "duitextedit.h" +#include "duitheme.h" +#include "duitexteditviewzoom.h" +#include "duiviewcreator.h" +#include "duiinfobanner.h" +#include "duilocale.h" +#include "duiscenemanager.h" +#include "duitimestamp.h" + +namespace +{ + const int ZoomTimeInterval = 600; //! how long to wait in tap&hold to start zooming + const int ScrollMargin = 20; // distance from the edge to start scrolling + const int ScrollingTimeDuration = 100; + const int ScrollStep = 10; // pixels to scroll at once + + //! how long before character becomes masked + const int MaskedTimeInterval = 1000; + + const int InternalMargin = 4; + + const QChar DefaultMaskCharacter('*'); + + // Default icon name for informational banner about failed paste + const char *const DefaultPasteBannerIcon = "Icon-close"; + + // How long notification will stay visible + const int NotificationDuration = 3000; +} + + +/*! + * \brief Constructor + * \param control DuiTextEdit widget which this view shows + */ +DuiTextEditViewPrivate::DuiTextEditViewPrivate(DuiTextEdit *control, DuiTextEditView *q) + : q_ptr(q), + controller(control), + focused(false), + textDocument(control->document()), + maskedTextDocument(0), + promptTextDocument(new QTextDocument(this)), + unmaskPosition(-1), + unmaskLength(0), + selectionThreshold(15), + maskCharacter(DefaultMaskCharacter), + hscroll(0.0), + vscroll(0.0), + scrollSpeedVertical(0), + zoomTimer(new QTimer(this)), + scrollTimer(new QTimer(this)), + maskTimer(new QTimer(this)), + selecting(false), + ignoreSelection(false), + startCursorPos(-1), + documentHeight(0.0), + mouseTarget(0, 0), + zoomable(true), + inAutoSelectionClick(false), + infoBanner(0), + editActive(false) +{ + // copy text options from actual document to prompt + QTextOption option = textDocument->defaultTextOption(); + promptTextDocument->setDefaultTextOption(option); + + selectionFormat.setForeground(Qt::white); + selectionFormat.setBackground(Qt::black); + + zoomTimer->setSingleShot(true); + maskTimer->setSingleShot(true); + maskTimer->setInterval(MaskedTimeInterval); + + QObject::connect(zoomTimer, SIGNAL(timeout()), this, SLOT(createZoomView())); + QObject::connect(scrollTimer, SIGNAL(timeout()), this, SLOT(scrolling())); + QObject::connect(maskTimer, SIGNAL(timeout()), this, SLOT(hideUnmaskedText())); +} + + +/*! + * Destructor + */ +DuiTextEditViewPrivate::~DuiTextEditViewPrivate() +{ + delete maskedTextDocument; +} + + +/*! + * \brief Returns cursor position from a mouse position + * \param event mouse event information (like position) + * \return cursor position as characters from start of document + */ +int DuiTextEditViewPrivate::cursorPosition(QGraphicsSceneMouseEvent *event) +{ + QPointF hitPoint = event->pos(); + return cursorPosition(hitPoint); +} + + +/*! + * \brief Returns cursor position from a mouse position + * \param hitPoint mouse position + * \return cursor position as characters from start of document + */ +int DuiTextEditViewPrivate::cursorPosition(QPointF hitPoint) +{ + Q_Q(DuiTextEditView); + + // adjust widget position to textdocument position + hitPoint.rx() += hscroll; + hitPoint.ry() += vscroll; + hitPoint.rx() -= q->style()->paddingLeft(); + hitPoint.ry() -= q->style()->paddingTop(); + + // limit the area inside the text document. + // otherwise up from it equals start index, and below end index. + if (hitPoint.x() < 0) { + hitPoint.setX(0); + + } else if (hitPoint.x() > activeDocument()->size().width()) { + hitPoint.setX(activeDocument()->size().width()); + } + + // on a few lowest pixels, the hitTest returns position on the end. + // a limitor before the real lower edge is used to avoid this. + const int MaxYLimitor = 4; + int maxY = activeDocument()->size().height() + - MaxYLimitor - 2 * activeDocument()->documentMargin(); + + if (hitPoint.y() < activeDocument()->documentMargin()) { + hitPoint.setY(activeDocument()->documentMargin()); + + } else if (hitPoint.y() > maxY) { + hitPoint.setY(maxY); + } + + return activeDocument()->documentLayout()->hitTest(hitPoint, Qt::FuzzyHit); +} + + +/*! + * \brief Scrolling slot, do the auto scrolling when cursor moves to the scroll area + */ +void DuiTextEditViewPrivate::scrolling() +{ + Q_Q(DuiTextEditView); + + int maxScroll = activeDocument()->size().width() + 2 * activeDocument()->documentMargin() + - q->geometry().width(); + + hscroll += scrollSpeedVertical; + + // test if we reach scrolling limits and stop if it happens + if (hscroll < 0) { + hscroll = 0; + scrollTimer->stop(); + + } else if (hscroll > maxScroll) { + hscroll = maxScroll; + scrollTimer->stop(); + } + + // update cursor to the edge of visible content + // NOTE: doesn't limit to text document + int cursorIndex = cursorPosition(mouseTarget); + + if (q->model()->edit() == DuiTextEditModel::EditModeBasic) { + controller->setCursorPosition(cursorIndex); + + } else if (q->model()->edit() == DuiTextEditModel::EditModeSelect) { + controller->setSelection(startCursorPos, cursorIndex - startCursorPos, true); + } + + doUpdate(); // need to redraw, widget supposedly changed. +} + + +/*! + * \brief checks if event is on text entry edge and sets scrolling speed accordingly. + * actual scrolling happens in scrolling() + */ +void DuiTextEditViewPrivate::scrollingTestAndStart(QGraphicsSceneMouseEvent *event) +{ + Q_Q(DuiTextEditView); + + QRectF rect = q->geometry(); + + // event inside scrolling margin creates constant speed scrolling. + // this could be changed to determine some scrolling speed depending on the position. + if (event->pos().x() < (ScrollMargin + q->style()->paddingLeft()) && hscroll > 0) { + scrollSpeedVertical = -ScrollStep; + + } else if (event->pos().x() > (rect.width() - (ScrollMargin + q->style()->paddingRight())) + && hscroll < (activeDocument()->size().width() - rect.width())) { + scrollSpeedVertical = ScrollStep; + } else { + scrollSpeedVertical = 0; + } + + if (scrollSpeedVertical != 0) { + // will do actual scrolling on timer interval + if (scrollTimer->isActive() == false) { + scrollTimer->start(ScrollingTimeDuration); + } + } else { + scrollTimer->stop(); + } +} + + +/*! + * \brief handle mouse move in zooming. called from DuiTextViewZoom. + * \param event the move event + */ +void DuiTextEditViewPrivate::mouseMoveInZooming(QGraphicsSceneMouseEvent *event) +{ + // only move cursor if left mouse button is pressed + if ((event->buttons() & Qt::LeftButton) == 0) { + return; + } + + setMouseTarget(event->pos()); + int cursor = cursorPosition(event); + + if (cursor >= 0) { + controller->setCursorPosition(cursor); + } + + // also scroll in zoom. + // known issue: scrolling zoom view with mouse on a spot + // requires one another mouse move to start text scrolling + scrollingTestAndStart(event); +} + + +// stops text scrolling. Called from DuiTextEditViewZoom when mouse is released +void DuiTextEditViewPrivate::stopScrolling() +{ + scrollTimer->stop(); +} + + +//! validates hscroll and vscroll values so cursor stays visible +void DuiTextEditViewPrivate::checkScroll() +{ + Q_Q(DuiTextEditView); + + // Selection doesn't currently change scrolling. + // rationale: user initiated selection can only happen on visible part + // and change in scrolling here would conflict with scrolling on the edges + if (q->model()->edit() == DuiTextEditModel::EditModeSelect) { + return; + } + + // TODO: vscroll possibly at some point + + qreal currentX = cursorX(); + bool scrolled = false; + + // check that cursor isn't before the widget + if (hscroll > currentX) { + hscroll = currentX; + scrolled = true; + + } else if (activeDocument()->textWidth() != -1) { + // checking scrolling with respect to size only if the size is set + + if (currentX > (activeDocument()->textWidth() + hscroll + - 2 * activeDocument()->documentMargin())) { + // ...or after widget (if the widget size is set) + // FIXME: margins seem to be a bit funny. this avoids having cursor outside + // visible area. + hscroll = currentX - activeDocument()->textWidth() + + 2 * activeDocument()->documentMargin(); + scrolled = true; + } + } + + if (scrolled) { + doUpdate(); + } +} + + +//! sets the mouse target point making sure it's inside the widget +void DuiTextEditViewPrivate::setMouseTarget(const QPointF &point) +{ + Q_Q(DuiTextEditView); + + mouseTarget.setX(qBound(0.0, q->geometry().width(), point.x())); + mouseTarget.setY(qBound(0.0, q->geometry().height(), point.y())); +} + + +QAbstractTextDocumentLayout::PaintContext DuiTextEditViewPrivate::paintContext() const +{ + Q_Q(const DuiTextEditView); + + QAbstractTextDocumentLayout::PaintContext paintContext; + paintContext.palette.setColor(QPalette::Text, q->style()->textColor()); + QTextCursor cursor = controller->textCursor(); + DuiTextEditModel::EchoMode echoMode = q->model()->echo(); + + if (echoMode == DuiTextEditModel::NoEcho) { + if (focused == true) { + paintContext.cursorPosition = 0; + } + + } else if (q->model()->edit() == DuiTextEditModel::EditModeSelect) { + // add selection formatting + QAbstractTextDocumentLayout::Selection selection; + selection.cursor = cursor; + selection.format = selectionFormat; + paintContext.selections.append(selection); + + } else if ((focused == true) && (q->model()->edit() == DuiTextEditModel::EditModeBasic)) { + paintContext.cursorPosition = cursor.position(); + } + + return paintContext; +} + + +// returns cursor's x position on textdocument +qreal DuiTextEditViewPrivate::cursorX() const +{ + Q_Q(const DuiTextEditView); + + qreal currentX = 0.0; + + if (q->model()->echo() == DuiTextEditModel::NoEcho) { + return currentX; + } + + QTextCursor activeCursor(activeDocument()); + activeCursor.setPosition(controller->textCursor().position()); + + if (activeCursor.atStart() == false && activeCursor.atBlockStart() == false) { + + QTextBlock currentBlock = activeCursor.block(); + if (!currentBlock.isValid()) { + return currentX; + } + + QTextLayout *layout = currentBlock.layout(); + int relativePos = activeCursor.position() - currentBlock.position(); + QTextLine line = layout->lineForTextPosition(relativePos); + + if (!line.isValid()) + line = layout->lineAt(0); + + currentX = line.cursorToX(relativePos); + } + + return currentX; +} + + +void DuiTextEditViewPrivate::initMaskedDocument() +{ + Q_Q(DuiTextEditView); + + maskTimer->stop(); + + int textLength = 0; + + if (q->model()->echo() != DuiTextEditModel::NoEcho) { + QString text = textDocument->toPlainText(); + textLength = text.length(); + } + + QString maskedText(textLength, maskCharacter); + + if (maskedTextDocument == 0) { + maskedTextDocument = new QTextDocument(maskedText, this); + } else { + maskedTextDocument->setPlainText(maskedText); + } + + // copy the settings + maskedTextDocument->setDocumentMargin(textDocument->documentMargin()); + maskedTextDocument->setDefaultFont(textDocument->defaultFont()); + maskedTextDocument->setTextWidth(textDocument->textWidth()); + + // no word wrapping in masked mode + QTextOption option = document()->defaultTextOption(); + option.setWrapMode(QTextOption::NoWrap); + maskedTextDocument->setDefaultTextOption(option); +} + + +// returns the textdocument that is currently used for displaying text +QTextDocument *DuiTextEditViewPrivate::activeDocument() const +{ + Q_Q(const DuiTextEditView); + + DuiTextEditModel::EchoMode echoMode = q->model()->echo(); + + if (echoMode == DuiTextEditModel::Normal || + (echoMode == DuiTextEditModel::PasswordEchoOnEdit && editActive == true) || + maskedTextDocument == 0) { + return textDocument; + + } else { + return maskedTextDocument; + } +} + + +// notifies this and the possible zoom view about update +void DuiTextEditViewPrivate::doUpdate() +{ + Q_Q(DuiTextEditView); + q->update(); + + if (zoomView) { + zoomView->update(); + } +} + + +void DuiTextEditViewPrivate::hideUnmaskedText() +{ + if (unmaskPosition >= 0 && maskedTextDocument) { + // remove unmasked characters + QTextCursor maskCursor(maskedTextDocument); + maskCursor.setPosition(unmaskPosition); + maskCursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, unmaskLength); + maskCursor.removeSelectedText(); + + // insert mask characters + QString maskedText(unmaskLength, maskCharacter); + maskCursor.insertText(maskedText); + + unmaskPosition = -1; + unmaskLength = 0; + + doUpdate(); + } +} + + +/*! Updates cached size and calls updateGeometry() for the view + */ +void DuiTextEditViewPrivate::checkSize() +{ + Q_Q(DuiTextEditView); + // note: as of Qt documentation, the size of newly created empty document is + // configuration dependent. in practice it seems to match the selected font size. + // possibly as a side effect of setDefaultFont() + qreal docHeight = activeDocument()->size().height(); + + if (documentHeight != docHeight) { + documentHeight = docHeight; + q->updateGeometry(); + } +} + + +void DuiTextEditViewPrivate::createZoomView() +{ + Q_Q(DuiTextEditView); + + delete zoomView; + zoomView = new DuiTextEditViewZoom(q, mouseTarget); + // assuming the zoom view receives the rest of mouse events + inAutoSelectionClick = false; + q->updateMicroFocus(); // visualization priority gained + // hide completer if there is active one + if (controller->completer() && controller->completer()->isActive()) { + controller->completer()->hideCompleter(); + } + + // destroying the zoom removes visualization priority + connect(zoomView, SIGNAL(destroyed()), q, SLOT(updateMicroFocus())); +} + + +// handles text document updates +void DuiTextEditViewPrivate::handleDocumentUpdate(int position, int charsRemoved, int charsAdded) +{ + Q_Q(DuiTextEditView); + + if (focused) { + editActive = true; // PasswordEchoOnEdit mode only becomes visible after doing editing + } + + if (q->model()->echo() == DuiTextEditModel::NoEcho) { + // early bail out, nothing is really done on no echo mode + return; + } + + // for echo modes using masking, we should update masked content + if (maskedTextDocument != 0) { + // first hide already visible text + hideUnmaskedText(); + + QTextCursor maskCursor = QTextCursor(maskedTextDocument); + maskCursor.setPosition(position); + // remove the same amount of chars from masked document + maskCursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, charsRemoved); + maskCursor.removeSelectedText(); + + // append new chars as unmasked or masked + QTextCursor newTextCursor(controller->textCursor()); + newTextCursor.setPosition(position); + newTextCursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, charsAdded); + QString newText = newTextCursor.selectedText(); + + if (q->model()->echo() == DuiTextEditModel::Password) { + maskCursor.insertText(newText); + unmaskPosition = position; + unmaskLength = charsAdded; + maskTimer->start(); + + } else { // PasswordEchoOnEdit, do immediate masking + QString maskedText(newText.length(), maskCharacter); + maskCursor.insertText(maskedText); + } + } + + doUpdate(); +} + + +// handles size change signals from QAbstractTextDocumentLayout +void DuiTextEditViewPrivate::handleDocumentSizeChange(const QSizeF &newSize) +{ + Q_UNUSED(newSize); + // do the checks separately and ignore new size, we might be using a different active document. + // having the size change signal from main document should be enough anyway. + checkSize(); + checkScroll(); +} + + +/*! + * \brief Method to start text selection + * \param event mouse event information (like position) + */ +void DuiTextEditViewPrivate::startSelection(QGraphicsSceneMouseEvent *event) +{ + if (activeDocument() != maskedTextDocument) { + selecting = true; + + int currentPos = cursorPosition(event); + startCursorPos = cursorPosition(event->buttonDownPos(Qt::LeftButton)); + controller->setSelection(startCursorPos, currentPos - startCursorPos, true); + + } else { + // with masked input we just select all + selecting = false; + inAutoSelectionClick = true; + controller->selectAll(); + } + + // selection won zooming timer in mouse press contest, we should stop it + zoomTimer->stop(); +} + + +/*! + * \brief Method to update text selection when mouse is moved + * \param pos mouse position + */ +void DuiTextEditViewPrivate::updateSelection(const QPointF &pos) +{ + if (ignoreSelection) + return; + + controller->setSelection(startCursorPos, cursorPosition(pos) - startCursorPos, true); +} + + +/*! + * \brief This is the overloaded function created for the convenience + * \param event mouse event information (like position) + */ +void DuiTextEditViewPrivate::updateSelection(QGraphicsSceneMouseEvent *event) +{ + updateSelection(event->pos()); +} + + +/*! + * \brief Method to handle mouse movement + * \param event mouse event information (like position) + */ +void DuiTextEditViewPrivate::checkStartOfSelection(QGraphicsSceneMouseEvent *event) +{ + // sanity check, should only happen when left button is held down + if ((event->buttons() & Qt::LeftButton) == 0) { + return; + } + + if (ignoreSelection) + return; + + qreal dx = qAbs(event->buttonDownPos(Qt::LeftButton).x() - event->pos().x()); + qreal dy = qAbs(event->buttonDownPos(Qt::LeftButton).y() - event->pos().y()); + + // approximates sqrt(dx^2 + dy^2) + if (0.7 *(dx + dy) < selectionThreshold) + return; + + // if movement is more vertical than horizontal we handle this movement as scrolling + if (dx < dy) { + ignoreSelection = true; + return; + } + + startSelection(event); + + return; +} + + +QRect DuiTextEditViewPrivate::preeditRectangle() const +{ + QRect rect; + + if (controller->mode() == DuiTextEditModel::EditModeActive) { + + // Find QTextLine for the current selection. + QTextCursor textCursor = controller->textCursor(); + QTextBlock block = textCursor.block(); + QTextLayout *layout = block.layout(); + + int start = textCursor.selectionStart() - block.position(); + int end = textCursor.selectionEnd() - block.position(); + QTextLine line = layout->lineForTextPosition(start); + + if (!line.isValid()) { + line = layout->lineAt(0); + } + + // Get local x coordinate for beginning and end of the selection. + int x1 = line.cursorToX(start); + int x2 = line.cursorToX(end); + + // Calculate offset from widget origin, having the current hscroll + // and possibly positive line.y() value for multiline text edits. + QPointF offset = layout->position() + QPointF(x1 - hscroll, line.y()); + + rect.setRect(0, 0, x2 - x1, line.height()); + rect.translate(offset.toPoint()); + } + + return rect; +} + + +QRect DuiTextEditViewPrivate::cursorRect() const +{ + QRect rect; + int position = controller->cursorPosition(); + const QTextBlock currentBlock = textDocument->findBlock(position); + if (!currentBlock.isValid()) + return rect; + + const QTextLayout *layout = currentBlock.layout(); + const QPointF layoutPos = textDocument->documentLayout()->blockBoundingRect(currentBlock).topLeft(); + int relativePos = position - currentBlock.position(); + QTextLine currentLine = layout->lineForTextPosition(relativePos); + if (!currentLine.isValid()) + currentLine = layout->lineAt(0); + + if (!currentLine.isValid()) + return rect; + + int cursorWidth, cursorHeight; + bool ok = false; + + cursorWidth = textDocument->documentLayout()->property("cursorWidth").toInt(&ok); + if (!ok) + cursorWidth = 1; + //cursor occupies one space + cursorWidth += QFontMetrics(currentBlock.layout()->font()).width(QLatin1Char(' ')); + + cursorHeight = currentLine.height(); + qreal x = currentLine.cursorToX(relativePos); + + rect = QRect((layoutPos.x() + x - hscroll), (layoutPos.y() + currentLine.y() - vscroll), + cursorWidth, cursorHeight); + + return rect; +} + + +////////////////////// +//// Actual class //// +////////////////////// + + +DuiTextEditView::DuiTextEditView(DuiTextEdit *controller) + : DuiWidgetView(controller), + d_ptr(new DuiTextEditViewPrivate(controller, this)) +{ + QObject::connect(controller, SIGNAL(gainedFocus(Qt::FocusReason)), + SLOT(setFocused(Qt::FocusReason))); + QObject::connect(controller, SIGNAL(lostFocus(Qt::FocusReason)), + SLOT(removeFocus(Qt::FocusReason))); + QObject::connect(controller, SIGNAL(pasteFailed()), + SLOT(informPasteFailed())); +} + + +DuiTextEditView::~DuiTextEditView() +{ + delete d_ptr; +} + + +void DuiTextEditView::drawContents(QPainter *painter, const QStyleOptionGraphicsItem *option) const +{ + Q_UNUSED(option); + Q_D(const DuiTextEditView); + + duiTimestamp("DuiTextEditView", QString("start text=%1").arg(d->document()->toPlainText())); + painter->save(); + + // set clipping rectangle to draw text inside the border + QRectF clipping(boundingRect().left() + style()->paddingLeft(), + boundingRect().top() + style()->paddingTop(), + boundingRect().width() - style()->paddingLeft() - style()->paddingRight(), + boundingRect().height() - style()->paddingTop() - style()->paddingBottom()); + painter->setClipRect(clipping); + + // If text does not fit inside widget, it may have to be scrolled + painter->translate(-d->hscroll + style()->paddingLeft(), -d->vscroll + style()->paddingTop()); + + // draw actual text to the screen + if (d->focused == false && d->activeDocument()->isEmpty() == true) { + // with no focus and content we show the prompt text + QAbstractTextDocumentLayout::PaintContext paintContext; + QColor promptColor = style()->promptColor(); + paintContext.palette.setColor(QPalette::Text, promptColor); + + d->promptDocument()->documentLayout()->draw(painter, paintContext); + + } else { + // normal painting + QAbstractTextDocumentLayout::PaintContext paintContext = d->paintContext(); + d->activeDocument()->documentLayout()->draw(painter, paintContext); + } + + painter->restore(); + duiTimestamp("DuiTextEditView", QString("end text=%1").arg(d->document()->toPlainText())); +} + + +void DuiTextEditView::resizeEvent(QGraphicsSceneResizeEvent *event) +{ + Q_D(DuiTextEditView); + int textWidth = event->newSize().width() - style()->paddingLeft() - style()->paddingRight(); + + d->textDocument->setTextWidth(textWidth); + d->promptTextDocument->setTextWidth(textWidth); + + if (d->maskedTextDocument != 0) { + d->maskedTextDocument->setTextWidth(textWidth); + } + + d->checkScroll(); +} + + +QRectF DuiTextEditView::boundingRect() const +{ + return QRectF(QPointF(0, 0), geometry().size()); +} + + +void DuiTextEditView::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + Q_D(DuiTextEditView); + + int cursor = d->cursorPosition(event); + d->setMouseTarget(event->pos()); + + if (d->zoomable) { + // start timer to check if still holding mouse after a while + d->zoomTimer->start(ZoomTimeInterval); + } + + event->accept(); + + // whether mouse movement should initiate selection at all + if (d->inAutoSelectionClick == true) { + d->ignoreSelection = true; + } else { + d->ignoreSelection = !d->controller->isSelectionEnabled(); + } + + if (model()->textInteractionFlags() != Qt::NoTextInteraction) { + style()->pressFeedback().play(); + } + + // let the controller react on click on a cursor index + d->controller->handleMousePress(cursor, event); +} + + +void DuiTextEditView::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + Q_D(DuiTextEditView); + + event->accept(); + + // controller shouldn't do anything for selection ending mouse release + if (d->selecting == false) { + // don't send either focus gaining mouse click with autoselect + if (d->inAutoSelectionClick == false) { + int cursor = d->cursorPosition(event); + + if (model()->textInteractionFlags() != Qt::NoTextInteraction) { + style()->releaseFeedback().play(); + } + + d->controller->handleMouseRelease(cursor, event); + } + } + + d->selecting = false; + d->inAutoSelectionClick = false; + d->zoomTimer->stop(); + d->scrollTimer->stop(); +} + + +void DuiTextEditView::mouseMoveEvent(QGraphicsSceneMouseEvent *event) +{ + Q_D(DuiTextEditView); + + int cursor = d->cursorPosition(event); + + d->setMouseTarget(event->pos()); + event->accept(); + + if (d->selecting) { + d->updateSelection(event); + + } else { + d->checkStartOfSelection(event); + d->controller->handleMouseMove(cursor, event); + } + + d->scrollingTestAndStart(event); +} + + +QSizeF DuiTextEditView::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const +{ + Q_D(const DuiTextEditView); + + QSizeF hint = DuiWidgetView::sizeHint(which, constraint); + qreal minHeight = d->documentHeight + style()->paddingTop() + style()->paddingBottom(); + + if (hint.height() < minHeight || model()->line() == DuiTextEditModel::SingleLine) { + hint.setHeight(minHeight); + } + + // FIXME: apply constraint? + return hint; +} + + +void DuiTextEditView::changeEvent(QEvent *event) +{ + Q_D(DuiTextEditView); + + if (event->type() == QEvent::LayoutDirectionChange) { + // controller takes care of adjusting layout of the model, we need to update + // our own QTextDocument instances + if (d->maskedTextDocument != 0) { + QTextOption option = d->maskedTextDocument->defaultTextOption(); + option.setTextDirection(d->controller->layoutDirection()); + d->maskedTextDocument->setDefaultTextOption(option); + } + + QTextOption option = d->promptTextDocument->defaultTextOption(); + option.setTextDirection(d->controller->layoutDirection()); + d->promptTextDocument->setDefaultTextOption(option); + } +} + + +void DuiTextEditView::cancelEvent(DuiCancelEvent *event) +{ + Q_UNUSED(event); + + // restore state before as before mouse press + Q_D(DuiTextEditView); + d->selecting = false; + d->inAutoSelectionClick = false; + d->zoomTimer->stop(); + d->scrollTimer->stop(); +} + + +QVariant DuiTextEditView::inputMethodQuery(Qt::InputMethodQuery query) const +{ + Q_D(const DuiTextEditView); + + if (query == Qt::ImFont) { + return QVariant(); // FIXME: return currently used font + + } else if (query == Qt::ImMicroFocus) { + return QVariant(d->cursorRect()); + + } else if (static_cast(query) == Dui::VisualizationPriorityQuery) { + return QVariant(d->zoomView.isNull() == false); + + } else if (static_cast(query) == Dui::PreeditRectangleQuery) { + return QVariant(d->preeditRectangle()); + } else { + return QVariant(); + } +} + + +void DuiTextEditView::updateData(const QList &modifications) +{ + Q_D(DuiTextEditView); + bool viewChanged = false; + + // check if the modifications might affect the visual appearance + foreach(const char * member, modifications) { + if (member == DuiTextEditModel::Edit || member == DuiTextEditModel::Cursor) { + viewChanged = true; + + } else if (member == DuiTextEditModel::Echo) { + viewChanged = true; + + // create or delete masked document here if needed + if (model()->echo() != DuiTextEditModel::Normal) { + d->initMaskedDocument(); + } else { + delete d->maskedTextDocument; + d->maskedTextDocument = 0; + } + + } else if (member == DuiTextEditModel::Prompt) { + d->promptTextDocument->setPlainText(model()->prompt()); + + if (d->textDocument->isEmpty() == true) { + viewChanged = true; + } + } else if (member == DuiTextEditModel::Document) { + // this shouldn't really be happening + qWarning("DuiTextEditView doesn't support changing the model's document member"); + } + } + + if (viewChanged) { + d->checkSize(); + d->checkScroll(); + d->doUpdate(); + } + + DuiWidgetView::updateData(modifications); +} + + +void DuiTextEditView::informPasteFailed() +{ + Q_D(DuiTextEditView); + + QString iconName = style()->pasteFailedIcon(); + int duration = style()->pasteFailedDuration(); + + if (iconName.isEmpty()) + iconName = DefaultPasteBannerIcon; + + if (duration <= 0) + duration = NotificationDuration; + + d->infoBanner = new DuiInfoBanner(DuiInfoBanner::Information); + d->infoBanner->setImageID(iconName); + d->infoBanner->setBodyText( + //~ uispec-document DirectUI_Virtual_Keyboard_UI_Specification_0.30.doc + //: Information banner to indicate that no + //: characters could be pasted from the + //: clipboard to this text field. + //: Is shown when user tries to paste + //: non-numeric text to a numeric or phone + //: number text field. + //% "Cannot paste text here" + qtTrId("qtn_vkb_cantpaste")); + + d->controller->sceneManager()->showWindow(d->infoBanner, DuiSceneWindow::DestroyWhenDone); + QTimer::singleShot(duration, this, SLOT(hideInfoBanner())); +} + +void DuiTextEditView::hideInfoBanner() +{ + Q_D(DuiTextEditView); + + if (d->infoBanner) + d->infoBanner->dismiss(); + d->infoBanner = 0; +} + +void DuiTextEditView::setupModel() +{ + Q_D(DuiTextEditView); + + delete d->maskedTextDocument; + d->maskedTextDocument = 0; + + if (model()->echo() != DuiTextEditModel::Normal) { + d->initMaskedDocument(); + } + + d->promptDocument()->setPlainText(model()->prompt()); + + // directly connect text document contents changing to separate handler + // note: qtextdocument signal is emitted before it does it layout updates + connect(model()->document(), SIGNAL(contentsChange(int, int, int)), + d, SLOT(handleDocumentUpdate(int, int, int))); + + // handle size changes separately + connect(model()->document()->documentLayout(), SIGNAL(documentSizeChanged(QSizeF)), + d, SLOT(handleDocumentSizeChange(QSizeF))); + + d->checkSize(); + d->checkScroll(); + + DuiWidgetView::setupModel(); +} + + +void DuiTextEditView::setFocused(Qt::FocusReason reason) +{ + Q_D(DuiTextEditView); + DuiTextEdit *textEdit = qobject_cast(sender()); + + style().setModeSelected(); + if (reason == Qt::MouseFocusReason && + textEdit != 0 && textEdit->isAutoSelectionEnabled() == true) { + // assuming the selection got made since the autoselection is enabled and focus was + // gained. This click gets handled a bit differently because selection is already made + // when the mouse press arrives. + d->inAutoSelectionClick = true; + } + + d->focused = true; + d->doUpdate(); +} + + +void DuiTextEditView::removeFocus(Qt::FocusReason reason) +{ + Q_D(DuiTextEditView); + Q_UNUSED(reason); + + style().setModeDefault(); + d->focused = false; + d->editActive = false; + d->doUpdate(); +} + + +void DuiTextEditView::applyStyle() +{ + Q_D(DuiTextEditView); + + d->maskTimer->setInterval(style()->maskingDelay()); + + d->selectionFormat.setForeground(style()->selectionTextColor()); + d->selectionFormat.setBackground(style()->selectionBackgroundColor()); + + // movement threshold for selection start + qreal threshold = style()->selectionThreshold(); + if (threshold > 0) { + d->selectionThreshold = threshold; + } + + d->zoomable = style()->zoomable(); + + QString maskString = style()->maskString(); + if (maskString.isEmpty() == false) { + d->maskCharacter = maskString.at(0); // use only the first character + } + + // Set document font + d->textDocument->setDefaultFont(style()->font()); + d->promptTextDocument->setDefaultFont(style()->font()); + + // Note: currently using fixed internal margin + d->textDocument->setDocumentMargin(InternalMargin); + d->promptTextDocument->setDocumentMargin(InternalMargin); + + if (d->maskedTextDocument != 0) { + d->maskedTextDocument->setDefaultFont(style()->font()); + d->maskedTextDocument->setDocumentMargin(InternalMargin); + } + + // font etc might affect size + d->checkSize(); + + DuiWidgetView::applyStyle(); +} + + +DUI_REGISTER_VIEW_NEW(DuiTextEditView, DuiTextEdit) diff --git a/src/widgets/views/duitexteditview.h b/src/widgets/views/duitexteditview.h new file mode 100644 index 000000000..603a39734 --- /dev/null +++ b/src/widgets/views/duitexteditview.h @@ -0,0 +1,107 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUITEXTEDITVIEW_H +#define DUITEXTEDITVIEW_H + +#include "duiwidgetview.h" +#include +#include + +class DuiTextEdit; +class DuiTextEditViewPrivate; + + +/*! +* \class DuiTextEditView +* \brief Standard view for DuiTextEdit widget +*/ +class DUI_EXPORT DuiTextEditView : public DuiWidgetView +{ + Q_OBJECT + DUI_VIEW(DuiTextEditModel, DuiTextEditStyle) + +public: + /*! + * \brief Constructor + * \param controller DuiTextEdit widget which this view shows + */ + DuiTextEditView(DuiTextEdit *controller); + + /*! + * \brief Destructor + */ + virtual ~DuiTextEditView(); + + //! \reimp + virtual QRectF boundingRect() const; + virtual void resizeEvent(QGraphicsSceneResizeEvent *event); + virtual QVariant inputMethodQuery(Qt::InputMethodQuery query) const; + //! \reimp_end + +protected: + //! \reimp + virtual void drawContents(QPainter *painter, const QStyleOptionGraphicsItem *option) const; + virtual void applyStyle(); + virtual void setupModel(); + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event); + virtual QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const; + virtual void changeEvent(QEvent *event); + virtual void cancelEvent(DuiCancelEvent *event); + //! \reimp_end + +protected Q_SLOTS: + /*! + * \brief Set view focused + */ + void setFocused(Qt::FocusReason reason); + + /*! + * \brief Remove focus from view + */ + void removeFocus(Qt::FocusReason reason); + + //! \reimp + virtual void updateData(const QList &modifications); + //! \reimp_end + + /*! + * \brief Show informational banner about failed text paste + */ + virtual void informPasteFailed(); + + void hideInfoBanner(); + +private : + Q_DISABLE_COPY(DuiTextEditView) + Q_DECLARE_PRIVATE(DuiTextEditView) + + DuiTextEditViewPrivate *const d_ptr; + +#ifdef UNIT_TEST + friend class Ut_DuiTextEditView; + friend class Ut_DuiTextEdit; +#endif + + friend class DuiTextEditViewZoom; +}; + +#endif diff --git a/src/widgets/views/duitexteditview_p.h b/src/widgets/views/duitexteditview_p.h new file mode 100644 index 000000000..07721602b --- /dev/null +++ b/src/widgets/views/duitexteditview_p.h @@ -0,0 +1,155 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUITEXTEDITVIEW_P_H +#define DUITEXTEDITVIEW_P_H + +#include +#include +#include +#include + +#include "duitexteditview.h" + +class DuiTextEdit; +class QGraphicsSceneMouseEvent; +class QColor; +class QTextDocument; +class QTimer; +class QTimeLine; +class DuiTextEditViewZoom; +class DuiInfoBanner; + + +//! \internal +class DuiTextEditViewPrivate : public QObject +{ + Q_OBJECT + Q_DECLARE_PUBLIC(DuiTextEditView) + +public: + DuiTextEditViewPrivate(DuiTextEdit *controller, DuiTextEditView *q); + virtual ~DuiTextEditViewPrivate(); + + int cursorPosition(QGraphicsSceneMouseEvent *event); + int cursorPosition(QPointF event); + + const QTextDocument *document() const { + return textDocument; + } + QTextDocument *promptDocument() const { + return promptTextDocument; + } + + void mouseMoveInZooming(QGraphicsSceneMouseEvent *event); + void stopScrolling(); + + void checkScroll(); + + void setMouseTarget(const QPointF &point); + + // returns a paint context for drawing. Includes selection formatting + QAbstractTextDocumentLayout::PaintContext paintContext() const; + + qreal cursorX() const; + + void initMaskedDocument(); + + QTextDocument *activeDocument() const; + + void doUpdate(); + +protected slots: + void scrolling(); + void hideUnmaskedText(); + void checkSize(); + void createZoomView(); + void handleDocumentUpdate(int position, int charsRemoved, int charsAdded); + void handleDocumentSizeChange(const QSizeF &newSize); + +private: + void scrollingTestAndStart(QGraphicsSceneMouseEvent *event); + + void checkStartOfSelection(QGraphicsSceneMouseEvent *event); + void startSelection(QGraphicsSceneMouseEvent *event); + void updateSelection(const QPointF &pos); + void updateSelection(QGraphicsSceneMouseEvent *event); + + //! Returns a rectangle covering preedit text in item space + QRect preeditRectangle() const; + + //! Returns a rectangle of the cursor + QRect cursorRect() const; + +protected: + DuiTextEditView *q_ptr; + + DuiTextEdit *controller; + + bool focused; + + QTextDocument *textDocument; + QTextDocument *maskedTextDocument; + QTextDocument *promptTextDocument; + + int unmaskPosition; // position where unmask in masked mode starts + int unmaskLength; // lenght of unmasked text + + // styling + qreal selectionThreshold; + QChar maskCharacter; // what characters are replaced with in masked mode + QTextCharFormat selectionFormat; + + qreal hscroll; // horizontal offset of text + qreal vscroll; // vertical offset + + int scrollSpeedVertical; + int scrollSpeedHorizontal; + + QTimer *zoomTimer; + QTimer *scrollTimer; + QTimer *maskTimer; + + bool selecting; // separate from controller mode because the selection there doesn't tell + // this view initiated the selection by mouse press + bool ignoreSelection; + int startCursorPos; + + qreal documentHeight; + QPointF mouseTarget; // known mouse position inside widget + + bool zoomable; + QPointer zoomView; + + bool inAutoSelectionClick; + + DuiInfoBanner *infoBanner; + + bool editActive; // true if editing started and having focus + +#ifdef UNIT_TEST + friend class Ut_DuiTextEditView; + friend class Ut_DuiTextEdit; +#endif + + friend class DuiTextEditViewZoom; +}; +//! \internal_end + +#endif diff --git a/src/widgets/views/duitexteditviewzoom.cpp b/src/widgets/views/duitexteditviewzoom.cpp new file mode 100644 index 000000000..bb7013847 --- /dev/null +++ b/src/widgets/views/duitexteditviewzoom.cpp @@ -0,0 +1,321 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duitexteditviewzoom.h" + +#include +#include +#include +#include +#include + +#include "duitextedit.h" +#include "duitexteditview.h" +#include "duitexteditview_p.h" +#include "duideviceprofile.h" +#include "duiapplication.h" +#include "duiapplicationwindow.h" +#include "duiscenemanager.h" +#include + +namespace +{ + const int ZoomTimeDuration = 500; // zooming time in msecs + const int MaxZoomTimeFrames = 50; // maximum frames to use for zooming + const int ZoomZValue = 100000; // Z value for the zoom view + const int MaxZoomingFactor = 2; // size where to zoom + const int VerticalZoomOffset = 15; // zooming target is viewed a little higher + + const int ScrollMargin = 20; // number of pixels on the edges where to scroll in + const int ScrollInterval = 100; // interval between scrolling steps + const int ScrollStep = 15; // size of step in duitexteditview coordinates +} + + +DuiTextEditViewZoom::DuiTextEditViewZoom(DuiTextEditView *textEditView, const QPointF &start) + : zoomableView(textEditView), + zoomFactor(1.0), + zoomInTimeLine(ZoomTimeDuration), + zoomOutTimeLine(ZoomTimeDuration), + parent(new DuiOverlay) +{ + QPointF startPoint(start); + + // kludge + DuiTextEditViewPrivate *const textEditViewD = textEditView->d_func(); + //set the parent to a toplevel duiscenewindow + + // FIXME - verify if it's the correct scene manager + textEditViewD->controller->sceneManager()->showWindow(parent); + this->setParentItem(parent); + + // set zoom target lower if possible -> currently focused point goes up a bit + startPoint.ry() += VerticalZoomOffset; + if (startPoint.y() > textEditView->geometry().height()) { + startPoint.setY(textEditView->geometry().height()); + } + + zoomTarget = startPoint; + + // get the mouse events until mouse is released + grabMouse(); + setZValue(ZoomZValue); + + // initialize timers + connect(&zoomInTimeLine, SIGNAL(frameChanged(int)), this, SLOT(zoom(int))); + zoomInTimeLine.setFrameRange(0, MaxZoomTimeFrames); + zoomInTimeLine.setLoopCount(1); + zoomInTimeLine.setCurveShape(QTimeLine::LinearCurve); + + connect(&zoomOutTimeLine, SIGNAL(frameChanged(int)), this, SLOT(zoom(int))); + zoomOutTimeLine.setFrameRange(0, MaxZoomTimeFrames); + zoomOutTimeLine.setLoopCount(1); + zoomOutTimeLine.setCurveShape(QTimeLine::LinearCurve); + zoomOutTimeLine.setDirection(QTimeLine::Backward); + + // when zoomed out, we are done with this widget + connect(&zoomOutTimeLine, SIGNAL(finished()), this, SLOT(deleteLater())); + + scrollTimer.setInterval(ScrollInterval); + connect(&scrollTimer, SIGNAL(timeout()), this, SLOT(scroll())); + + zoomInTimeLine.start(); + + // because the zoomingview is a graphicsitem, and not added to layout, so we have to calculate + // the initial pos here manually. The position is a relative pos, the relative x, y + // coordinates come from the comparing of its parent's scenePos and contoller(textedit)'s + // scenePos + QPointF viewPos = textEditViewD->controller->scenePos(); + viewPos = this->parentItem()->mapFromScene(viewPos); + setPos(viewPos); +} + + +DuiTextEditViewZoom::~DuiTextEditViewZoom() +{ + if (scene() && scene()->items().contains(parent)) { + this->setParentItem(0); + delete parent; + parent = 0; + } +} + + +QRectF DuiTextEditViewZoom::boundingRect() const +{ + return zoomableView->boundingRect(); +} + + +void DuiTextEditViewZoom::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, + QWidget *widget) +{ + zoomableView->paint(painter, option, widget); +} + + +void DuiTextEditViewZoom::mouseMoveEvent(QGraphicsSceneMouseEvent *event) +{ + QWidget *widget = event->widget(); + + if (widget == 0) { + return; + } + + // map screen position to window position + QPoint windowPos = widget->mapFromGlobal(event->screenPos()); + + DuiDeviceProfile *deviceProfile = DuiDeviceProfile::instance(); + + // scroll near the window edges + if (windowPos.x() < ScrollMargin + || windowPos.x() > deviceProfile->resolution().width() - ScrollMargin + || windowPos.y() < ScrollMargin + || windowPos.y() > deviceProfile->resolution().height() - ScrollMargin) { + + if (scrollTimer.isActive() == false) { + scrollTimer.start(); + } + + } else { + scrollTimer.stop(); + } + + // shamelessly using Qt's internal API to adjust the event point for vertical offset + QPointF pos = event->pos(); + pos.ry() -= VerticalZoomOffset; + event->setPos(pos); + + DuiTextEditViewPrivate *const textEditViewD = zoomableView->d_func(); + textEditViewD->mouseMoveInZooming(event); + + mousePoint = windowPos; +} + + +void DuiTextEditViewZoom::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + Q_UNUSED(event); + grabMouse(); + + // change back to zoom in if we caught press when zooming out + if (zoomOutTimeLine.state() == QTimeLine::Running) { + zoomOutTimeLine.stop(); + zoomInTimeLine.setCurrentTime(zoomOutTimeLine.currentTime()); + zoomInTimeLine.start(); + } + + // FIXME: should do scrolling? kindof corner case +} + + +void DuiTextEditViewZoom::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + Q_UNUSED(event); + ungrabMouse(); + + // shouldn't scroll anymore + scrollTimer.stop(); + + // shouldn't either scroll the text inside the view + DuiTextEditViewPrivate *const textEditViewD = zoomableView->d_func(); + textEditViewD->stopScrolling(); + + // start zooming out + if (zoomInTimeLine.state() == QTimeLine::Running) { + // if currently zooming in, start zoom out at the same position + zoomInTimeLine.stop(); + zoomOutTimeLine.setCurrentTime(zoomInTimeLine.currentTime()); + zoomOutTimeLine.resume(); + } else { + zoomOutTimeLine.start(); + } + +} + + +void DuiTextEditViewZoom::zoom(int frame) +{ + Q_UNUSED(frame); + zoomFactor = static_cast(frame) / MaxZoomTimeFrames * (MaxZoomingFactor - 1) + 1; + updateTransform(); +} + + +// Really do scrolling. +void DuiTextEditViewZoom::scroll() +{ + // This currently relies on scene coordinates corresponding the resolution + // of the device. + + // TODO: FIXME - provide a private class to be able to use d->controller->scene() + DuiWindow *window = DuiApplication::activeWindow(); + if (window == 0) + return; + + + DuiDeviceProfile *deviceProfile = DuiDeviceProfile::instance(); + + if (mousePoint.x() < ScrollMargin) { + // if left is outside view + if (sceneBoundingRect().left() < 0) { + switch (window->orientationAngle()) { + case Dui::Angle90: + zoomTarget.ry() += ScrollStep; + break; + case Dui::Angle180: + zoomTarget.rx() += ScrollStep; + break; + case Dui::Angle270: + zoomTarget.ry() -= ScrollStep; + break; + case Dui::Angle0: + default: + zoomTarget.rx() -= ScrollStep; + break; + } + } + + } else if (mousePoint.x() > (deviceProfile->resolution().width() - ScrollMargin)) { + // map widget height to scene and check if it goes past right edge + if (sceneBoundingRect().right() > deviceProfile->resolution().width()) { + switch (window->orientationAngle()) { + case Dui::Angle90: + zoomTarget.ry() -= ScrollStep; + break; + case Dui::Angle180: + zoomTarget.rx() -= ScrollStep; + break; + case Dui::Angle270: + zoomTarget.ry() += ScrollStep; + break; + case Dui::Angle0: + default: + zoomTarget.rx() += ScrollStep; + break; + } + } + } + + if (mousePoint.y() < ScrollMargin) { + if (sceneBoundingRect().top() < 0) { + switch (window->orientationAngle()) { + case Dui::Angle90: + zoomTarget.rx() -= ScrollStep; + break; + case Dui::Angle180: + zoomTarget.ry() += ScrollStep; + break; + case Dui::Angle270: + zoomTarget.rx() += ScrollStep; + break; + case Dui::Angle0: + default: + zoomTarget.ry() -= ScrollStep; + break; + } + } + + } else if (mousePoint.y() > deviceProfile->resolution().height() - ScrollMargin) { + if (sceneBoundingRect().bottom() > deviceProfile->resolution().height()) { + switch (window->orientationAngle()) { + case Dui::Angle90: + zoomTarget.rx() += ScrollStep; + break; + case Dui::Angle180: + zoomTarget.ry() -= ScrollStep; + break; + case Dui::Angle270: + zoomTarget.rx() -= ScrollStep; + break; + case Dui::Angle0: + default: + zoomTarget.ry() += ScrollStep; + break; + } + } + } + + updateTransform(); +} + + +void DuiTextEditViewZoom::updateTransform() +{ +} diff --git a/src/widgets/views/duitexteditviewzoom.h b/src/widgets/views/duitexteditviewzoom.h new file mode 100644 index 000000000..3effc1a8a --- /dev/null +++ b/src/widgets/views/duitexteditviewzoom.h @@ -0,0 +1,68 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUITEXTEDITVIEWZOOM_H +#define DUITEXTEDITVIEWZOOM_H + +#include +#include +#include +#include + +#include "duitexteditview.h" + +class DuiSceneWindow; +// NOT A PUBLIC CLASS + +class DuiTextEditViewZoom: public QObject, public QGraphicsItem +{ + Q_OBJECT + +public: + DuiTextEditViewZoom(DuiTextEditView *textEditView, const QPointF &startPoint); + virtual ~DuiTextEditViewZoom(); + + //! \reimp + virtual QRectF boundingRect() const; + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, + QWidget *widget = 0); + + virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event); + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + //! \reimp_end + +private slots: + void zoom(int frame); + void scroll(); + +private: + void updateTransform(); + + DuiTextEditView *zoomableView; + QPointF mousePoint; + QPointF zoomTarget; + qreal zoomFactor; + QTimeLine zoomInTimeLine; + QTimeLine zoomOutTimeLine; + QTimer scrollTimer; + DuiSceneWindow *parent; +}; + +#endif diff --git a/src/widgets/views/duitoolbarview.cpp b/src/widgets/views/duitoolbarview.cpp new file mode 100644 index 000000000..04fa250db --- /dev/null +++ b/src/widgets/views/duitoolbarview.cpp @@ -0,0 +1,570 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include + +#include "duitoolbar.h" +#include "duitoolbar_p.h" + +#include "duitheme.h" +#include "duibutton.h" +#include "duiviewcreator.h" +#include "duiwidgetaction.h" +#include "private/duiwidgetview_p.h" +#include "duiapplication.h" +#include "duiapplicationwindow.h" + +#include "duilayout.h" +#include "duilinearlayoutpolicy.h" +#include "duitextedit.h" +#include "duitoolbarview.h" +#include "duitoolbarview_p.h" + +const int DuiToolBarViewPrivate::maxWidgets = 4; + +DuiToolBarViewPrivate::DuiToolBarViewPrivate(DuiToolBar *controller) + : DuiWidgetViewPrivate(), + QObject(), + widgetsContainer(0), + layout(0), + landscapePolicy(0), + portraitPolicy(0), + leasedWidgets(), + buttons() +{ + this->controller = controller; + controller->installEventFilter(this); +} + + +DuiToolBarViewPrivate::~DuiToolBarViewPrivate() +{ + clearWidgets(leasedWidgets); + clearWidgets(buttons); + removeEventFilter(controller); +} + +void DuiToolBarViewPrivate::init() +{ + widgetsContainer = new DuiWidget(); + widgetsContainer->setObjectName("toolbarContainer"); + + layout = new DuiLayout(widgetsContainer); + layout->setAnimation(NULL); + layout->setContentsMargins(0, 0, 0, 0); + + createPolicy(Dui::Landscape); + createPolicy(Dui::Portrait); + + QGraphicsLinearLayout *layout = (QGraphicsLinearLayout *)(controller->layout()); + layout->addItem(widgetsContainer); + + addActions(); +} + +void DuiToolBarViewPrivate::createPolicy(Dui::Orientation orientation) +{ + DuiLinearLayoutPolicy *policy = new DuiLinearLayoutPolicy(layout, Qt::Horizontal); + policy->setSpacing(0); + policy->setContentsMargins(0, 0, 0, 0); + if (orientation == Dui::Landscape) { + landscapePolicy = policy; + layout->setLandscapePolicy(landscapePolicy); + landscapeData.reset(); + } else { + portraitPolicy = policy; + layout->setPortraitPolicy(portraitPolicy); + portraitData.reset(); + } +} + +void DuiToolBarViewPrivate::add(QAction *action, QAction *before, bool refreshSpacer) +{ + bool validLocation = (isLocationValid(action, DuiAction::ToolBarLandscapeLocation) || + isLocationValid(action, DuiAction::ToolBarPortraitLocation)); + if (!action || !validLocation || + (hasWidget(action) && !isWidgetUsable(action))) { + return; + } + + bool added = false; + DuiWidget *w = createWidget(action); + // add to policies only if the action is visible + if (action->isVisible()) { + bool addToLandscape = refreshPolicyData(action, + DuiAction::ToolBarLandscapeLocation, + landscapeData); + bool addToPortrait = refreshPolicyData(action, + DuiAction::ToolBarPortraitLocation, + portraitData); + if (addToLandscape || addToPortrait) { + if (addToLandscape) { + landscapePolicy->insertItem(getItemIndex(landscapePolicy, before), w); + } + if (addToPortrait) { + portraitPolicy->insertItem(getItemIndex(portraitPolicy, before), w); + } + if (refreshSpacer) { + refreshSpacers(); + } + added = true; + } + } + + if (!added && w) { + w->setVisible(false); + } +} + +void DuiToolBarViewPrivate::remove(QAction *action, bool refreshPolicies) +{ + DuiWidget *button = buttons.value(action); + DuiWidget *leased = leasedWidgets.value(action); + DuiWidget *widget = (button != 0) ? button : leased; + + if (widget) { + removeAction(landscapePolicy, landscapeData, action, widget); + removeAction(portraitPolicy, portraitData, action, widget); + layout->removeItem(widget); + } + + if (button) { + buttons.remove(action); + delete button; + } else if (leased) { + releaseWidget(action, leased); + leasedWidgets.remove(action); + } + if (refreshPolicies) { + clearPolicy(landscapePolicy, landscapeData); + clearPolicy(portraitPolicy, portraitData); + addActions(); + } +} + +void DuiToolBarViewPrivate::change(QAction *action) +{ + if (changeLocation(action) || changeVisibility(action)) { + clearPolicy(landscapePolicy, landscapeData); + clearPolicy(portraitPolicy, portraitData); + addActions(); + } + changeData(action); +} + +bool DuiToolBarViewPrivate::eventFilter(QObject *obj, QEvent *e) +{ + QActionEvent *actionEvent = dynamic_cast(e); + + if (actionEvent) { + switch (e->type()) { + case QEvent::ActionRemoved: { + remove(actionEvent->action(), true); + break; + } + case QEvent::ActionAdded: { + add(actionEvent->action(), actionEvent->before(), true); + break; + } + case QEvent::ActionChanged: { + change(actionEvent->action()); + break; + } + default: { + break; + } + } + } + + return QObject::eventFilter(obj, e); +} + +void DuiToolBarViewPrivate::addActions() +{ + QList acts = controller->actions(); + int count = acts.count(); + for (int i = 0; i < count; ++i) { + add(acts.at(i), 0, false); + } + refreshSpacers(); +} + +DuiWidget *DuiToolBarViewPrivate::createWidget(QAction *action) +{ + // If widget is not already created then create it + DuiWidget *widget = buttons.value(action); + if (!widget) { + widget = leasedWidgets.value(action); + } + if (!widget) { + DuiWidgetAction *widgetAction = qobject_cast(action); + if (widgetAction) { + widget = requestWidget(widgetAction); + leasedWidgets.insert(action, widget); + } else { + widget = createButton(action); + buttons.insert(action, widget); + } + } + widget->setVisible(true); + widget->setEnabled(action->isEnabled()); + return widget; +} + +DuiButton *DuiToolBarViewPrivate::createButton(QAction *action) +{ + DuiButton *button = new DuiButton(action->text()); + DuiAction *duiAction = qobject_cast(action); + if (duiAction) { + button->setIconID(duiAction->iconID()); + } + connect(button, SIGNAL(clicked(bool)), action, SIGNAL(triggered())); + button->setViewType("toolbar"); + return button; +} + +bool DuiToolBarViewPrivate::isLocationValid(QAction *action, DuiAction::Location loc) +{ + bool valid = true; //any QAction is valid to place on toolbar + DuiAction *duiAction = qobject_cast(action); + if (duiAction) { + valid = duiAction->location().testFlag(loc); + } + return valid; +} + +bool DuiToolBarViewPrivate::isVisible(QAction *action) +{ + return action && + action->isVisible(); +} + +void DuiToolBarViewPrivate::clearWidgets(QHash& widgets) +{ + QHashIterator iterator(widgets); + while (iterator.hasNext()) { + iterator.next(); + deleteWidget(iterator.key(), iterator.value()); + } + widgets.clear(); +} + +void DuiToolBarViewPrivate::deleteWidget(QAction *action, DuiWidget *widget) +{ + if (!releaseWidget(action, widget)) { + delete widget; + } +} + +bool DuiToolBarViewPrivate::releaseWidget(QAction *action, DuiWidget *widget) +{ + DuiWidgetAction *widgetAction = qobject_cast(action); + if (widgetAction) { + widgetAction->releaseWidget(widget); + } + return (widgetAction != 0); +} + +DuiWidget *DuiToolBarViewPrivate::requestWidget(DuiAction *action) +{ + DuiWidget *widget = 0; + DuiWidgetAction *widgetAction = qobject_cast(action); + if (widgetAction) { + widget = widgetAction->requestWidget(widgetsContainer); + } + return widget; +} + +bool DuiToolBarViewPrivate::isWidgetInUseByView(DuiWidgetAction *widgetAction) +{ + return (buttons.contains(widgetAction) || leasedWidgets.contains(widgetAction)); +} + +bool DuiToolBarViewPrivate::isWidgetUsable(QAction *action) +{ + DuiWidgetAction *widgetAction = qobject_cast(action); + return(widgetAction && isWidgetUsable(widgetAction)); +} + +bool DuiToolBarViewPrivate::hasWidget(QAction *action) +{ + DuiWidgetAction *widgetAction = qobject_cast(action); + return(widgetAction && widgetAction->widget()); +} + +bool DuiToolBarViewPrivate::hasTextEditWidget(QAction *action) +{ + DuiTextEdit *textEditWidget = 0; + DuiWidgetAction *widgetAction = qobject_cast(action); + if (widgetAction) { + textEditWidget = qobject_cast(widgetAction->widget()); + } + return (textEditWidget != 0); +} + +void DuiToolBarViewPrivate::removeAction(DuiLinearLayoutPolicy *policy, + ActionPlacementData &policyData, + QAction *action) +{ + DuiWidget *button = buttons.value(action); + DuiWidget *leased = leasedWidgets.value(action); + DuiWidget *widget = (button != 0) ? button : leased; + + removeAction(policy, policyData, action, widget); +} + +void DuiToolBarViewPrivate::removeAction(DuiLinearLayoutPolicy *policy, + ActionPlacementData &policyData, + QAction *action, + DuiWidget *widget) +{ + bool hasTextEdit = hasTextEditWidget(action); + int index = policy->indexOf(widget); + if (index >= 0) { + policyData.placedActions--; + if (hasTextEdit) { + policyData.hasTextEditor = false; + policyData.placedActions--; + } + policy->removeAt(index); + } +} + +bool DuiToolBarViewPrivate::isWidgetUsable(DuiWidgetAction *widgetAction) +{ + return (!widgetAction->isWidgetInUse() || isWidgetInUseByView(widgetAction)); +} + +bool DuiToolBarViewPrivate::hasAction(QAction *action) +{ + return (buttons.contains(action) || leasedWidgets.contains(action)); +} + +int DuiToolBarViewPrivate::getItemIndex(DuiLinearLayoutPolicy *policy, QAction *before) +{ + int index = policy->count(); + DuiWidget *w = getWidget(before); + if (w) { + int beforeIndex = -1; + if ((beforeIndex = policy->indexOf(w)) >= 0) { + index = beforeIndex; + } + } + return index; +} + +DuiWidget *DuiToolBarViewPrivate::getWidget(QAction *action) +{ + DuiWidget *button = buttons.value(action); + DuiWidget *leased = leasedWidgets.value(action); + return (button != 0) ? button : leased; +} + +bool DuiToolBarViewPrivate::changeLocation(QAction *action) +{ + // If the location of an action gets changed, then remove it from the toolbar + bool validInLandscape = isLocationValid(action, DuiAction::ToolBarLandscapeLocation); + bool validInPortrait = isLocationValid(action, DuiAction::ToolBarPortraitLocation); + if (!validInLandscape && !validInPortrait) { + remove(action, false); + } + + return true; +} + +void DuiToolBarViewPrivate::changeData(QAction *action) +{ + DuiWidget *widget = buttons.value(action); + DuiButton *button = qobject_cast(widget); + if (button) { + // Update button data accordingly + button->setText(action->text()); + button->setEnabled(action->isEnabled()); + button->setCheckable(action->isCheckable()); + button->setChecked(action->isChecked()); + DuiAction *duiAction = qobject_cast(action); + if (duiAction) { + button->setIconID(duiAction->iconID()); + } + } +} + +bool DuiToolBarViewPrivate::changeVisibility(QAction *action) +{ + DuiWidget *widget = getWidget(action); + if (widget) { + bool wasVisible = (landscapePolicy->indexOf(widget) >= 0) || + (portraitPolicy->indexOf(widget) >= 0); + //Check if visibility has been changed + return (!action->isVisible() && wasVisible) || + (action->isVisible() && !wasVisible); + } + return false; +} + +void DuiToolBarViewPrivate::clearPolicy(DuiLinearLayoutPolicy *policy, + ActionPlacementData &policyData) +{ + while (policy->count()) { + policy->removeAt(0); + } + policyData.reset(); +} + +void DuiToolBarViewPrivate::refreshSpacers() +{ + retrieveSpacers(landscapePolicy, landscapeData); + retrieveSpacers(portraitPolicy, portraitData); + + insertSpacers(landscapePolicy, landscapeData); + insertSpacers(portraitPolicy, portraitData); +} + +void DuiToolBarViewPrivate::retrieveSpacers(DuiLinearLayoutPolicy *policy, + ActionPlacementData &policyData) +{ + policyData.mode = Managed; + QGraphicsLayoutItem *item = 0; + int count = policy->count(); + for (int i = count - 1; i >= 0; --i) { + item = policy->itemAt(i); + if (isItemSpacer(item)) { + policy->removeAt(i); + freeSpacers.append((QGraphicsWidget *)item); + } else { + DuiWidget *widget = (DuiWidget *)item; + QAction *action = leasedWidgets.key(widget); + if (action && !hasTextEditWidget(action)) { + policyData.mode = Unmanaged; + } + } + } +} + +void DuiToolBarViewPrivate::insertSpacers(DuiLinearLayoutPolicy *policy, + const ActionPlacementData &policyData) +{ + // Add spacer(s) only if there is no text-editor action placed or + // the widgets are not placed in unmanaged way or there are some + // actions in the policy + int count = policy->count(); + if (policyData.mode == Unmanaged || policyData.hasTextEditor || count <= 0) + return; + + // In landscape, spacer need to be added for right alignment + if (policy == landscapePolicy) { + if (count < maxWidgets) + insertSpacer(policy, 0); + return; + } + + // In portrait, spacer(s) need to be added if portrait actions + // are less then max actions OR in case of maximum actions, + // no spacers in the start and in the end + int spacersCount = count + 1; + for (int i = 0; i < spacersCount; ++i) { + if (count < maxWidgets) { + insertSpacer(policy, i << 1); //indices are multiples of 2 i.e 0,2,4,6(if max=4) + } else if ((i >= 0) && (i < (count - 1))) { + insertSpacer(policy, (i << 1) + 1); //indices are 1,3,5 (if max=4) + } + } + +} + +void DuiToolBarViewPrivate::insertSpacer(DuiLinearLayoutPolicy *policy, + int insertIndex) +{ + QGraphicsWidget *item = 0; + if (freeSpacers.count() > 0) { //use existing spacer, if any + item = freeSpacers.at(0); + freeSpacers.removeAt(0); + } else { + item = createSpacer(); + } + policy->insertItem(insertIndex, item); +} + +QGraphicsWidget *DuiToolBarViewPrivate::createSpacer() +{ + QGraphicsWidget *spacer = new QGraphicsWidget(widgetsContainer); + spacer->setMinimumSize(0, 0); + spacer->setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); + return spacer; +} + +bool DuiToolBarViewPrivate::isItemSpacer(QGraphicsLayoutItem *item) +{ + // Since spacers are QGraphicsWidget object and if casting of widget + // to DuiWidget fails, then its a policy specific spacer. + QGraphicsWidget *widget = (QGraphicsWidget *)item; + DuiWidget *duiWidget = qobject_cast(widget); + return (!duiWidget && (widget->parentItem() == widgetsContainer)); +} + +bool DuiToolBarViewPrivate::refreshPolicyData(QAction *action, + DuiAction::Location location, + ActionPlacementData &policyData) +{ + bool add = false; + if ((policyData.placedActions < maxWidgets) && isLocationValid(action, location)) { + bool hasTextEdit = hasTextEditWidget(action); + // The action is not added if it has a text-edit widget and the toolbar location + // has already a text-edit widget placed or there is no space for new text-edit widget + // as text-edit widget takes space of two buttons + if (!hasTextEdit || (!policyData.hasTextEditor && (policyData.placedActions < maxWidgets - 1))) { + add = true; + if (hasTextEdit) { + //one text-edit widget takes space of two buttons + policyData.placedActions++; + policyData.hasTextEditor = true; + } + // If there is a widget that is usable and is not text-entry widget, then the widgets + // are placed as it is i.e. in unmanaged way. + if (hasWidget(action) && !hasTextEdit) { + policyData.mode = Unmanaged; + } + } + } + policyData.placedActions += add; + return add; +} + +DuiToolBarView::DuiToolBarView(DuiToolBar *controller) : + DuiWidgetView(* new DuiToolBarViewPrivate(controller), controller) +{ + Q_D(DuiToolBarView); + d->init(); +} + +DuiToolBarView::DuiToolBarView(DuiToolBarViewPrivate &dd, DuiToolBar *controller) : + DuiWidgetView(dd, controller) +{ + Q_D(DuiToolBarView); + d->init(); +} + +DuiToolBarView::~DuiToolBarView() +{ +} + +// bind view and controller together +DUI_REGISTER_VIEW_NEW(DuiToolBarView, DuiToolBar) + +#include "moc_duitoolbarview.cpp" diff --git a/src/widgets/views/duitoolbarview.h b/src/widgets/views/duitoolbarview.h new file mode 100644 index 000000000..545e2e2cf --- /dev/null +++ b/src/widgets/views/duitoolbarview.h @@ -0,0 +1,92 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUITOOLBARVIEW_H +#define DUITOOLBARVIEW_H + +#include "duiwidgetview.h" +#include +#include +#include + +class DuiToolBar; +class DuiToolBarViewPrivate; + +/*! + \class DuiToolBarView + \brief View class for DuiToolBar widget. + + \ingroup views + + \section DuiToolBarViewOverview Overview + DuiToolBarView is used to visualize actions placed into the DuiToolBar. + + The outlook of toolbar can be changed using the styling attributes defined + in DuiToolbarStyle and DuiWidgetStyle. + + \section DuiToolBarInteractions Interactions + - The toolbar has currently no interactions by itself: the interactions are + determined by the UI controls that are placed inside the toolbar. + - The toolbar can be affected by possible interactions of going to and from the + full screen mode; this would set the visibility of the toolbar on and off. + - Setting the visibility of the toolbar on/off should be accompanied by a + (sliding) transition, hiding and revealing the toolbar. + + \section DuiToolBarOpenIssues Open issues + - Sliding transitions for hiding and revealing the toolbar are not supported yet. + + \sa DuiToolBar DuiToolbarStyle +*/ + +class DUI_EXPORT DuiToolBarView : public DuiWidgetView +{ + Q_OBJECT + DUI_VIEW(DuiWidgetModel, DuiToolbarStyle) + +public: + + /*! + \brief Constructs toolbar view. + \param Pointer to the controller. + */ + DuiToolBarView(DuiToolBar *controller); + + /*! + \brief Destructs the view. + */ + virtual ~DuiToolBarView(); + +protected: + /*! + \brief protected constructor + \param dd Shared private class + \param controller The controller associated with the view. + */ + DuiToolBarView(DuiToolBarViewPrivate &dd, DuiToolBar *controller); + +private: + Q_DISABLE_COPY(DuiToolBarView) + Q_DECLARE_PRIVATE(DuiToolBarView) + +#ifdef UNIT_TEST + friend class Ut_DuiToolBarView; +#endif +}; + +#endif diff --git a/src/widgets/views/duitoolbarview_p.h b/src/widgets/views/duitoolbarview_p.h new file mode 100644 index 000000000..d22a6d772 --- /dev/null +++ b/src/widgets/views/duitoolbarview_p.h @@ -0,0 +1,132 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUITOOLBARVIEW_P_H +#define DUITOOLBARVIEW_P_H + +#include +#include + +#include "private/duiwidgetview_p.h" +#include "duiaction.h" +#include "duinamespace.h" + +class DuiToolBar; +class DuiWidget; +class DuiLinearLayoutPolicy; +class QEvent; +class DuiToolBarView; +class QAction; +class DuiButton; +class DuiWidgetAction; +class DuiLayout; +class QGraphicsLayoutItem; +class QGraphicsWidget; + +class DuiToolBarViewPrivate : public DuiWidgetViewPrivate, public QObject +{ + Q_DECLARE_PUBLIC(DuiToolBarView) + +public: + DuiToolBarViewPrivate(DuiToolBar *controller); + virtual ~DuiToolBarViewPrivate(); + + virtual void init(); + virtual void createPolicy(Dui::Orientation o); + + virtual void add(QAction *action, QAction *before, bool refreshSpacer); + virtual void remove(QAction *action, bool refreshPolicies); + virtual void change(QAction *action); + +protected: + virtual bool eventFilter(QObject *obj, QEvent *event); + virtual void addActions(); + DuiWidget *createWidget(QAction *action); + DuiButton *createButton(QAction *action); + bool isLocationValid(QAction *action, DuiAction::Location loc); + bool isVisible(QAction *action); + void clearWidgets(QHash& widgets); + void deleteWidget(QAction *action, DuiWidget *widget); + bool releaseWidget(QAction *action, DuiWidget *widget); + DuiWidget *requestWidget(DuiAction *action); + bool isWidgetInUseByView(DuiWidgetAction *widgetAction); + bool hasWidget(QAction *action); + bool hasTextEditWidget(QAction *action); + bool isWidgetUsable(QAction *action); + bool isWidgetUsable(DuiWidgetAction *widgetAction); + bool hasAction(QAction *action); + int getItemIndex(DuiLinearLayoutPolicy *policy, QAction *before); + DuiWidget *getWidget(QAction *action); + bool changeLocation(QAction *action); + void changeData(QAction *action); + bool changeVisibility(QAction *action); + void refreshSpacers(); + +protected: + DuiWidget *widgetsContainer; + DuiLayout *layout; + DuiLinearLayoutPolicy *landscapePolicy; + DuiLinearLayoutPolicy *portraitPolicy; + QHash leasedWidgets; + QHash buttons; + QList freeSpacers; + + static const int maxWidgets; + +private: + enum PlacementMode { + Managed = 0, + Unmanaged + }; + + class ActionPlacementData + { + public: + void reset() { + mode = Managed; + hasTextEditor = false; + placedActions = 0; + } + PlacementMode mode; + bool hasTextEditor; + int placedActions; + }; + + ActionPlacementData landscapeData; + ActionPlacementData portraitData; + + void removeAction(DuiLinearLayoutPolicy *policy, + ActionPlacementData &policyData, + QAction *action); + void removeAction(DuiLinearLayoutPolicy *policy, + ActionPlacementData &policyData, + QAction *action, + DuiWidget *widget); + void clearPolicy(DuiLinearLayoutPolicy *policy, ActionPlacementData &policyData); + void retrieveSpacers(DuiLinearLayoutPolicy *policy, ActionPlacementData &policyData); + void insertSpacers(DuiLinearLayoutPolicy *policy, const ActionPlacementData &policyData); + void insertSpacer(DuiLinearLayoutPolicy *policy, int insertIndex); + QGraphicsWidget *createSpacer(); + bool isItemSpacer(QGraphicsLayoutItem *item); + bool refreshPolicyData(QAction *action, + DuiAction::Location location, + ActionPlacementData &policyData); +}; + +#endif diff --git a/src/widgets/views/views.pri b/src/widgets/views/views.pri new file mode 100644 index 000000000..d0f40ce11 --- /dev/null +++ b/src/widgets/views/views.pri @@ -0,0 +1,109 @@ +############################################################################### +# DuiWidget/Views module +# This module contains all classes implemeting widget views. +############################################################################### + +WIDGETS_VIEWS_SRC_DIR=./widgets/views +INCLUDEPATH+=./widgets/views + +PUBLIC_HEADERS += \ + $$WIDGETS_VIEWS_SRC_DIR/duiapplicationpageview.h \ + $$WIDGETS_VIEWS_SRC_DIR/duibuttoniconview.h \ + $$WIDGETS_VIEWS_SRC_DIR/duibuttonview.h \ + $$WIDGETS_VIEWS_SRC_DIR/duibuttonswitchview.h \ + $$WIDGETS_VIEWS_SRC_DIR/duicheckboxview.h \ + $$WIDGETS_VIEWS_SRC_DIR/duicomboboxview.h \ + $$WIDGETS_VIEWS_SRC_DIR/duicontainerview.h \ + $$WIDGETS_VIEWS_SRC_DIR/duidialogview.h \ + $$WIDGETS_VIEWS_SRC_DIR/duimodalscenewindowview.h \ + $$WIDGETS_VIEWS_SRC_DIR/duidockwidgetview.h \ + $$WIDGETS_VIEWS_SRC_DIR/duiextendingbackgroundview.h \ + $$WIDGETS_VIEWS_SRC_DIR/duiescapebuttonpanelview.h \ + $$WIDGETS_VIEWS_SRC_DIR/duihomebuttonpanelview.h \ + $$WIDGETS_VIEWS_SRC_DIR/duiimagewidgetview.h \ + $$WIDGETS_VIEWS_SRC_DIR/duiinfobannereventview.h \ + $$WIDGETS_VIEWS_SRC_DIR/duiinfobannerinformationview.h \ + $$WIDGETS_VIEWS_SRC_DIR/duilabelview.h \ + $$WIDGETS_VIEWS_SRC_DIR/duigriditemview.h \ + $$WIDGETS_VIEWS_SRC_DIR/duiapplicationmenuview.h \ + $$WIDGETS_VIEWS_SRC_DIR/duiapplicationmenubuttonview.h \ + $$WIDGETS_VIEWS_SRC_DIR/duimenuobjectview.h \ + $$WIDGETS_VIEWS_SRC_DIR/duimessageboxview.h \ + $$WIDGETS_VIEWS_SRC_DIR/duinavigationbarview.h \ + $$WIDGETS_VIEWS_SRC_DIR/duioverlayview.h \ + $$WIDGETS_VIEWS_SRC_DIR/duiobjectmenuview.h \ + $$WIDGETS_VIEWS_SRC_DIR/duipannablewidgetview.h \ + $$WIDGETS_VIEWS_SRC_DIR/duipopuplistview.h \ + $$WIDGETS_VIEWS_SRC_DIR/duipositionindicatorview.h \ + $$WIDGETS_VIEWS_SRC_DIR/duiprogressindicatorbarview.h \ + $$WIDGETS_VIEWS_SRC_DIR/duiscenewindowview.h \ + $$WIDGETS_VIEWS_SRC_DIR/duisliderview.h \ + $$WIDGETS_VIEWS_SRC_DIR/duispinnerview.h \ + $$WIDGETS_VIEWS_SRC_DIR/duitexteditview.h \ + $$WIDGETS_VIEWS_SRC_DIR/duitoolbarview.h \ + $$WIDGETS_VIEWS_SRC_DIR/duiseparatorview.h \ + $$WIDGETS_VIEWS_SRC_DIR/duitexteditviewzoom.h \ + $$WIDGETS_VIEWS_SRC_DIR/duicompleterview.h \ + $$WIDGETS_VIEWS_SRC_DIR/duifastlistview.h \ + $$WIDGETS_VIEWS_SRC_DIR/duicontentitemview.h \ + + +PRIVATE_HEADERS += \ + $$WIDGETS_VIEWS_SRC_DIR/duistylablewidgetview_p.h \ + $$WIDGETS_VIEWS_SRC_DIR/duiextendingbackgroundview_p.h \ + $$WIDGETS_VIEWS_SRC_DIR/duitexteditview_p.h \ + $$WIDGETS_VIEWS_SRC_DIR/duiapplicationmenuview_p.h \ + $$WIDGETS_VIEWS_SRC_DIR/duiobjectmenuview_p.h \ + $$WIDGETS_VIEWS_SRC_DIR/duicompleterview_p.h \ + $$WIDGETS_VIEWS_SRC_DIR/duisliderview_p.h \ + $$WIDGETS_VIEWS_SRC_DIR/duispinnerview_p.h \ + $$WIDGETS_VIEWS_SRC_DIR/duifastlistview_p.h \ + $$WIDGETS_VIEWS_SRC_DIR/duicontentitemview_p.h \ + $$WIDGETS_VIEWS_SRC_DIR/duibuttongrouplayoutpolicy_p.h \ + + +SOURCES += \ + $$WIDGETS_VIEWS_SRC_DIR/duiapplicationpageview.cpp \ + $$WIDGETS_VIEWS_SRC_DIR/duibuttoniconview.cpp \ + $$WIDGETS_VIEWS_SRC_DIR/duibuttonview.cpp \ + $$WIDGETS_VIEWS_SRC_DIR/duibuttonswitchview.cpp \ + $$WIDGETS_VIEWS_SRC_DIR/duicheckboxview.cpp \ + $$WIDGETS_VIEWS_SRC_DIR/duicomboboxview.cpp \ + $$WIDGETS_VIEWS_SRC_DIR/duicontainerview.cpp \ + $$WIDGETS_VIEWS_SRC_DIR/duidialogview.cpp \ + $$WIDGETS_VIEWS_SRC_DIR/duimodalscenewindowview.cpp \ + $$WIDGETS_VIEWS_SRC_DIR/duidockwidgetview.cpp \ + $$WIDGETS_VIEWS_SRC_DIR/duiextendingbackgroundview.cpp \ + $$WIDGETS_VIEWS_SRC_DIR/duiescapebuttonpanelview.cpp \ + $$WIDGETS_VIEWS_SRC_DIR/duihomebuttonpanelview.cpp \ + $$WIDGETS_VIEWS_SRC_DIR/duiimagewidgetview.cpp \ + $$WIDGETS_VIEWS_SRC_DIR/duiinfobannereventview.cpp \ + $$WIDGETS_VIEWS_SRC_DIR/duiinfobannerinformationview.cpp \ + $$WIDGETS_VIEWS_SRC_DIR/duilabelview.cpp \ + $$WIDGETS_VIEWS_SRC_DIR/duilabelview_simple.cpp \ + $$WIDGETS_VIEWS_SRC_DIR/duilabelview_rich.cpp \ + $$WIDGETS_VIEWS_SRC_DIR/duigriditemview.cpp \ + $$WIDGETS_VIEWS_SRC_DIR/duiapplicationmenuview.cpp \ + $$WIDGETS_VIEWS_SRC_DIR/duiapplicationmenubuttonview.cpp \ + $$WIDGETS_VIEWS_SRC_DIR/duimenuobjectview.cpp \ + $$WIDGETS_VIEWS_SRC_DIR/duimessageboxview.cpp \ + $$WIDGETS_VIEWS_SRC_DIR/duinavigationbarview.cpp \ + $$WIDGETS_VIEWS_SRC_DIR/duioverlayview.cpp \ + $$WIDGETS_VIEWS_SRC_DIR/duiobjectmenuview.cpp \ + $$WIDGETS_VIEWS_SRC_DIR/duipannablewidgetview.cpp \ + $$WIDGETS_VIEWS_SRC_DIR/duipopuplistview.cpp \ + $$WIDGETS_VIEWS_SRC_DIR/duipositionindicatorview.cpp \ + $$WIDGETS_VIEWS_SRC_DIR/duiprogressindicatorbarview.cpp \ + $$WIDGETS_VIEWS_SRC_DIR/duiscenewindowview.cpp \ + $$WIDGETS_VIEWS_SRC_DIR/duisliderview.cpp \ + $$WIDGETS_VIEWS_SRC_DIR/duispinnerview.cpp \ + $$WIDGETS_VIEWS_SRC_DIR/duitexteditview.cpp \ + $$WIDGETS_VIEWS_SRC_DIR/duitexteditviewzoom.cpp \ + $$WIDGETS_VIEWS_SRC_DIR/duitoolbarview.cpp \ + $$WIDGETS_VIEWS_SRC_DIR/duiseparatorview.cpp \ + $$WIDGETS_VIEWS_SRC_DIR/duistylablewidgetview.cpp \ + $$WIDGETS_VIEWS_SRC_DIR/duicompleterview.cpp \ + $$WIDGETS_VIEWS_SRC_DIR/duifastlistview.cpp \ + $$WIDGETS_VIEWS_SRC_DIR/duifastlistview_p.cpp \ + $$WIDGETS_VIEWS_SRC_DIR/duicontentitemview.cpp \ + $$WIDGETS_VIEWS_SRC_DIR/duibuttongrouplayoutpolicy_p.cpp \ diff --git a/src/widgets/widgets.pri b/src/widgets/widgets.pri new file mode 100644 index 000000000..d07fc60d6 --- /dev/null +++ b/src/widgets/widgets.pri @@ -0,0 +1,165 @@ +############################################################################### +# DuiWidget module +# This module contains all classes that represent widgets. +############################################################################### + +WIDGETS_SRC_DIR=./widgets +INCLUDEPATH+=./widgets + +duigen_model.name = duigenerator model +duigen_model.input = WIDGET_MODEL_HEADERS +duigen_model.depends = ../duigen/duigen +duigen_model.output = $$GEN_DIR/gen_${QMAKE_FILE_BASE}data.cpp +duigen_model.commands += ../duigen/duigen --model ${QMAKE_FILE_NAME} $$GEN_DIR/ +duigen_model.clean += $$GEN_DIR/gen_* +duigen_model.CONFIG = target_predeps no_link +duigen_model.variable_out = GENERATED_SOURCES +QMAKE_EXTRA_COMPILERS += duigen_model + +include(core/core.pri) +include(views/views.pri) + +PUBLIC_HEADERS += \ + $$WIDGETS_SRC_DIR/duiapplicationpage.h \ + $$WIDGETS_SRC_DIR/duiapplicationmenu.h \ + $$WIDGETS_SRC_DIR/duiapplicationmenubutton.h \ + $$WIDGETS_SRC_DIR/duiapplicationwindow.h \ + $$WIDGETS_SRC_DIR/duibutton.h \ + $$WIDGETS_SRC_DIR/duibuttongroup.h \ + $$WIDGETS_SRC_DIR/duicombobox.h \ + $$WIDGETS_SRC_DIR/duicontainer.h \ + $$WIDGETS_SRC_DIR/duidialog.h \ + $$WIDGETS_SRC_DIR/duimodalscenewindow.h \ + $$WIDGETS_SRC_DIR/duidockwidget.h \ + $$WIDGETS_SRC_DIR/duiescapebuttonpanel.h \ + $$WIDGETS_SRC_DIR/duihomebuttonpanel.h \ + $$WIDGETS_SRC_DIR/duiimagewidget.h \ + $$WIDGETS_SRC_DIR/duiinfobanner.h \ + $$WIDGETS_SRC_DIR/duilabel.h \ + $$WIDGETS_SRC_DIR/duilabelhighlighter.h \ + $$WIDGETS_SRC_DIR/duilist.h \ + $$WIDGETS_SRC_DIR/duigriditem.h \ + $$WIDGETS_SRC_DIR/duimessagebox.h \ + $$WIDGETS_SRC_DIR/duinavigationbar.h \ + $$WIDGETS_SRC_DIR/duioverlay.h \ + $$WIDGETS_SRC_DIR/duipannablewidget.h \ + $$WIDGETS_SRC_DIR/duiphysics2dpanning.h \ + $$WIDGETS_SRC_DIR/duipopuplist.h \ + $$WIDGETS_SRC_DIR/duipopuplist_p.h \ + $$WIDGETS_SRC_DIR/duipositionindicator.h \ + $$WIDGETS_SRC_DIR/duiprogressindicator.h \ + $$WIDGETS_SRC_DIR/duiscenewindow.h \ + $$WIDGETS_SRC_DIR/duiseekbar.h \ + $$WIDGETS_SRC_DIR/duislider.h \ + $$WIDGETS_SRC_DIR/duitextedit.h \ + $$WIDGETS_SRC_DIR/duicompleter.h \ + $$WIDGETS_SRC_DIR/duicompleter_p.h \ + $$WIDGETS_SRC_DIR/duitoolbar.h \ + $$WIDGETS_SRC_DIR/duiviewcreator.h \ + $$WIDGETS_SRC_DIR/duiwindow.h \ + $$WIDGETS_SRC_DIR/duiseparator.h \ + $$WIDGETS_SRC_DIR/duistylablewidget.h \ + $$WIDGETS_SRC_DIR/duipannableviewport.h \ + $$WIDGETS_SRC_DIR/duiwidgetrecycler.h \ + $$WIDGETS_SRC_DIR/duiabstractcellcreator.h \ + $$WIDGETS_SRC_DIR/duicontentitem.h \ + + +WIDGET_MODEL_HEADERS += \ + $$WIDGETS_SRC_DIR/duiwidgetmodel.h \ + $$WIDGETS_SRC_DIR/duibuttonmodel.h \ + $$WIDGETS_SRC_DIR/duicomboboxmodel.h \ + $$WIDGETS_SRC_DIR/duilabelmodel.h \ + $$WIDGETS_SRC_DIR/duidialogmodel.h \ + $$WIDGETS_SRC_DIR/duimodalscenewindowmodel.h \ + $$WIDGETS_SRC_DIR/duidockwidgetmodel.h \ + $$WIDGETS_SRC_DIR/duiescapebuttonpanelmodel.h \ + $$WIDGETS_SRC_DIR/duiimagewidgetmodel.h \ + $$WIDGETS_SRC_DIR/duiinfobannermodel.h \ + $$WIDGETS_SRC_DIR/duiapplicationmenumodel.h \ + $$WIDGETS_SRC_DIR/duiapplicationmenubuttonmodel.h \ + $$WIDGETS_SRC_DIR/duimessageboxmodel.h \ + $$WIDGETS_SRC_DIR/duinavigationbarmodel.h \ + $$WIDGETS_SRC_DIR/duiobjectmenumodel.h \ + $$WIDGETS_SRC_DIR/duiapplicationpagemodel.h \ + $$WIDGETS_SRC_DIR/duiscenewindowmodel.h \ + $$WIDGETS_SRC_DIR/duiscenelayereffectmodel.h \ + $$WIDGETS_SRC_DIR/duilistmodel.h \ + $$WIDGETS_SRC_DIR/duigriditemmodel.h \ + $$WIDGETS_SRC_DIR/duipopuplistmodel.h \ + $$WIDGETS_SRC_DIR/duipositionindicatormodel.h \ + $$WIDGETS_SRC_DIR/duiprogressindicatormodel.h \ + $$WIDGETS_SRC_DIR/duiseparatormodel.h \ + $$WIDGETS_SRC_DIR/duislidermodel.h \ + $$WIDGETS_SRC_DIR/duiseekbarmodel.h \ + $$WIDGETS_SRC_DIR/duitexteditmodel.h \ + $$WIDGETS_SRC_DIR/duipannablewidgetmodel.h \ + $$WIDGETS_SRC_DIR/duipannableviewportmodel.h \ + $$WIDGETS_SRC_DIR/duicontainermodel.h \ + $$WIDGETS_SRC_DIR/duicompletermodel.h \ + $$WIDGETS_SRC_DIR/duicontentitemmodel.h \ + + +PRIVATE_HEADERS += \ + $$WIDGETS_SRC_DIR/duiobjectmenu.h \ + $$WIDGETS_SRC_DIR/duipannableviewportlayout.h \ + $$WIDGETS_SRC_DIR/duicontainerheader_p.h \ + $$WIDGETS_SRC_DIR/duicontentitem_p.h \ + $$WIDGETS_SRC_DIR/duibuttongroup_p.h \ + +HEADERS += \ + $$WIDGET_MODEL_HEADERS \ + +SOURCES += \ + $$WIDGETS_SRC_DIR/duiwidgetmodel.cpp \ + $$WIDGETS_SRC_DIR/duiapplicationpage.cpp \ + $$WIDGETS_SRC_DIR/duiapplicationwindow.cpp \ + $$WIDGETS_SRC_DIR/duibutton.cpp \ + $$WIDGETS_SRC_DIR/duibuttongroup.cpp \ + $$WIDGETS_SRC_DIR/duicombobox.cpp \ + $$WIDGETS_SRC_DIR/duicontainer.cpp \ + $$WIDGETS_SRC_DIR/duidialog.cpp \ + $$WIDGETS_SRC_DIR/duidialogmodel.cpp \ + $$WIDGETS_SRC_DIR/duimodalscenewindow.cpp \ + $$WIDGETS_SRC_DIR/duidockwidget.cpp \ + $$WIDGETS_SRC_DIR/duiescapebuttonpanel.cpp \ + $$WIDGETS_SRC_DIR/duihomebuttonpanel.cpp \ + $$WIDGETS_SRC_DIR/duiimagewidget.cpp \ + $$WIDGETS_SRC_DIR/duiinfobanner.cpp \ + $$WIDGETS_SRC_DIR/duilabel.cpp \ + $$WIDGETS_SRC_DIR/duilabelmodel.cpp \ + $$WIDGETS_SRC_DIR/duilabelhighlighter.cpp \ + $$WIDGETS_SRC_DIR/duilist.cpp \ + $$WIDGETS_SRC_DIR/duigriditem.cpp \ + $$WIDGETS_SRC_DIR/duiinfobannermodel.cpp \ + $$WIDGETS_SRC_DIR/duiapplicationmenu.cpp \ + $$WIDGETS_SRC_DIR/duiapplicationmenubutton.cpp \ + $$WIDGETS_SRC_DIR/duimessagebox.cpp \ + $$WIDGETS_SRC_DIR/duinavigationbar.cpp \ + $$WIDGETS_SRC_DIR/duiobjectmenu.cpp \ + $$WIDGETS_SRC_DIR/duiobjectmenumodel.cpp \ + $$WIDGETS_SRC_DIR/duioverlay.cpp \ + $$WIDGETS_SRC_DIR/duipannablewidget.cpp \ + $$WIDGETS_SRC_DIR/duipannableviewport.cpp \ + $$WIDGETS_SRC_DIR/duipannableviewportlayout.cpp \ + $$WIDGETS_SRC_DIR/duiphysics2dpanning.cpp \ + $$WIDGETS_SRC_DIR/duipopuplist.cpp \ + $$WIDGETS_SRC_DIR/duipositionindicator.cpp \ + $$WIDGETS_SRC_DIR/duiprogressindicator.cpp \ + $$WIDGETS_SRC_DIR/duiscenewindow.cpp \ + $$WIDGETS_SRC_DIR/duiseekbar.cpp \ + $$WIDGETS_SRC_DIR/duislider.cpp \ + $$WIDGETS_SRC_DIR/duislidermodel.cpp \ + $$WIDGETS_SRC_DIR/duitextedit.cpp \ + $$WIDGETS_SRC_DIR/duicompleter.cpp \ + $$WIDGETS_SRC_DIR/duitoolbar.cpp \ + $$WIDGETS_SRC_DIR/duiviewcreator.cpp \ + $$WIDGETS_SRC_DIR/duiwindow.cpp \ + $$WIDGETS_SRC_DIR/duiseparator.cpp \ + $$WIDGETS_SRC_DIR/duistylablewidget.cpp \ + $$WIDGETS_SRC_DIR/duiwidgetrecycler.cpp \ + $$WIDGETS_SRC_DIR/duicontainerheader.cpp \ + $$WIDGETS_SRC_DIR/duiabstractcellcreator.cpp \ + $$WIDGETS_SRC_DIR/duicontentitem.cpp \ + $$WIDGETS_SRC_DIR/duicontentitemmodel.cpp \ + $$WIDGETS_SRC_DIR/duilistmodel.cpp \ diff --git a/src/workspace/duideviceprofile.cpp b/src/workspace/duideviceprofile.cpp new file mode 100644 index 000000000..2e5715891 --- /dev/null +++ b/src/workspace/duideviceprofile.cpp @@ -0,0 +1,94 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include + +#include "duidebug.h" +#include "duideviceprofile.h" +#include "duideviceprofile_p.h" +#include "duidevicestyle.h" +#include "duitheme.h" + +#include "duiapplication.h" +#include "duicomponentdata.h" +#include "duicomponentdata_p.h" + +DuiDeviceProfilePrivate::DuiDeviceProfilePrivate() + : style(0) +{ + style = static_cast(DuiTheme::style("DuiDeviceStyle", DuiApplication::deviceName())); +} + +DuiDeviceProfilePrivate::~DuiDeviceProfilePrivate() +{ + if (style) { + //DuiTheme::releaseStyle(style); + style = 0; + } +} + +/* + * @return pointer to the singleton DuiDeviceProfile instance + */ +DuiDeviceProfile *DuiDeviceProfile::instance() +{ + DuiComponentData *data = DuiComponentData::instance(); + if (!data) + qFatal("There is no instance of DuiDeviceProfile. Please create DuiComponentData first."); + return data->d_ptr->deviceProfile; +} + +DuiDeviceProfile::DuiDeviceProfile(QObject *parent) + : QObject(parent), + d_ptr(new DuiDeviceProfilePrivate) +{ + Q_D(DuiDeviceProfile); + d->q_ptr = this; + + if (!DuiComponentData::instance()) + qFatal("There is no instance of DuiComponentData. Please create DuiApplication first."); + if (DuiComponentData::instance()->d_ptr->deviceProfile) + qFatal("Device profile is already created. Please use DuiDeviceProfile::instance()"); +} + +DuiDeviceProfile::~DuiDeviceProfile() +{ + delete d_ptr; +} + +QSize DuiDeviceProfile::resolution() const +{ + Q_D(const DuiDeviceProfile); + + if (d->style) + return d->style->resolution(); + else + return QSize(); +} + +QSize DuiDeviceProfile::pixelsPerInch() const +{ + Q_D(const DuiDeviceProfile); + + if (d->style) + return d->style->pixelsPerInch(); + else + return QSize(); +} diff --git a/src/workspace/duideviceprofile.h b/src/workspace/duideviceprofile.h new file mode 100644 index 000000000..2b11c16ee --- /dev/null +++ b/src/workspace/duideviceprofile.h @@ -0,0 +1,63 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIDEVICEPROFILE_H +#define DUIDEVICEPROFILE_H + +#include "duiexport.h" +#include "duinamespace.h" +#include + +class QSize; +class DuiDeviceProfilePrivate; + +/*! \brief The DuiDeviceProfile class holds physical and simulated properties of the target device + + Target device properties are specified in CSS as part of the DirectUI theme, through the attributes of the DuiDeviceStyle class. + */ +class DUI_EXPORT DuiDeviceProfile : public QObject +{ + Q_OBJECT + +public: + //! Default constructor. Only used by DuiApplication class. + //! Client classes should be using DuiDeviceProfile::instance() method. + DuiDeviceProfile(QObject *parent = 0); + + //! Default destructor. + virtual ~DuiDeviceProfile(); + + //! Returns the global DuiDeviceProfile instance + static DuiDeviceProfile *instance(); + + //! Return the target device resolution + QSize resolution() const; + + //! Return the target device pixels per inch + QSize pixelsPerInch() const; + +protected: + DuiDeviceProfilePrivate *const d_ptr; + +private: + Q_DISABLE_COPY(DuiDeviceProfile) + Q_DECLARE_PRIVATE(DuiDeviceProfile) +}; + +#endif diff --git a/src/workspace/duideviceprofile_p.h b/src/workspace/duideviceprofile_p.h new file mode 100644 index 000000000..3f9c81df0 --- /dev/null +++ b/src/workspace/duideviceprofile_p.h @@ -0,0 +1,41 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIDEVICEPROFILE_P_H +#define DUIDEVICEPROFILE_P_H + +#include "duideviceprofile.h" + +class DuiDeviceStyle; + +class DuiDeviceProfilePrivate +{ + Q_DECLARE_PUBLIC(DuiDeviceProfile) + +public: + DuiDeviceProfilePrivate(); + virtual ~DuiDeviceProfilePrivate(); + + const DuiDeviceStyle *style; + +protected: + DuiDeviceProfile *q_ptr; +}; + +#endif diff --git a/src/workspace/workspace.pri b/src/workspace/workspace.pri new file mode 100644 index 000000000..393ba3978 --- /dev/null +++ b/src/workspace/workspace.pri @@ -0,0 +1,10 @@ +############################################################################### +# DuiWorkspace module +# This module contains all classes that rather deal with the workspace +# management. +############################################################################### +WORKSPACE_SRC_DIR=./workspace +INCLUDEPATH+=./workspace +HEADERS += $$WORKSPACE_SRC_DIR/duideviceprofile.h +SOURCES += $$WORKSPACE_SRC_DIR/duideviceprofile.cpp + \ No newline at end of file diff --git a/tests/.gitignore b/tests/.gitignore new file mode 100644 index 000000000..bf692e0d5 --- /dev/null +++ b/tests/.gitignore @@ -0,0 +1,2 @@ +tests.xml +*/gen_* diff --git a/tests/check.pri b/tests/check.pri new file mode 100644 index 000000000..7ca04edb3 --- /dev/null +++ b/tests/check.pri @@ -0,0 +1,9 @@ +CONFIG += link_prl +QMAKE_EXTRA_TARGETS += check +check.depends = $$TARGET +check.commands = @LD_LIBRARY_PATH=../../lib:$$(LD_LIBRARY_PATH) ./$$TARGET + + +QMAKE_EXTRA_TARGETS += check-xml +check-xml.depends = $$TARGET +check-xml.commands = @../rt.sh ./$$TARGET diff --git a/tests/common_bot.pri b/tests/common_bot.pri new file mode 100644 index 000000000..23fb5cbfc --- /dev/null +++ b/tests/common_bot.pri @@ -0,0 +1,8 @@ +DEPENDS= +contains( DUI_BUILD_FEATURES, coverage ) { + include(coverage.pri) +} + +QMAKE_CLEAN += \ + *.gcda \ + *.gcno \ diff --git a/tests/common_top.pri b/tests/common_top.pri new file mode 100644 index 000000000..943b7964b --- /dev/null +++ b/tests/common_top.pri @@ -0,0 +1,34 @@ +include(check.pri) + +# for defines +include(../mkspecs/common.pri) + +DUISRCDIR = ../../src +STUBSDIR = ../stubs +INCLUDEPATH += . $$DUISRCDIR $$STUBSDIR $$DUISRCDIR/include +DEPENDPATH = $$INCLUDEPATH +QMAKE_LIBDIR += ../../lib /usr/local/lib +CONFIG += debug +CONFIG -= app_bundle +QT += testlib dbus svg network +TEMPLATE = app +# DEFINES += QT_NO_DEBUG_OUTPUT +DEFINES += UNIT_TEST +target.path = $$[QT_INSTALL_LIBS]/libdui-tests +INSTALLS += target + +win32|macx { + macx { + QMAKE_LFLAGS += -F../../lib + LIBS += -framework dui + } + win32:LIBS += -L../../lib -ldui0 +} else { + LIBS += ../../lib/libdui.so +} + +QMAKE_CXXFLAGS += -Werror + +support_files.files = +support_files.path = $$[QT_INSTALL_LIBS]/libdui-tests +INSTALLS += support_files diff --git a/tests/coverage.pri b/tests/coverage.pri new file mode 100644 index 000000000..f5526181b --- /dev/null +++ b/tests/coverage.pri @@ -0,0 +1,26 @@ +defineReplace(srcList) { + LIST=$$1 + for(item,LIST) { + ITEMLIST=$$item,$${ITEMLIST} + } + return($${ITEMLIST}) +} + +QMAKE_CXXFLAGS += -ftest-coverage -fprofile-arcs +LIBS += -lgcov + +# OBJECTS_DIR = .obj +MOC_DIR = .moc + +QMAKE_EXTRA_TARGETS += coverage +coverage.depends = check-xml +coverage.commands = @../coverage.py $$srcList($$TEST_SOURCES) .obj 90 + + +QMAKE_EXTRA_TARGETS += coverage-xml +coverage-xml.depends = check-xml +coverage-xml.commands = @../coverage.py $$srcList($$TEST_SOURCES) .obj 90 + + +QMAKE_CLEAN += *.gcda *.gcno *.gcov *.log *.xml +QMAKE_DISTCLEAN += *.gcda *.gcno *.gcov *.log *.xml diff --git a/tests/coverage.py b/tests/coverage.py new file mode 100755 index 000000000..5b00c53d7 --- /dev/null +++ b/tests/coverage.py @@ -0,0 +1,123 @@ +#!/usr/bin/python2.5 +import sys,commands,re,os + + +def printxml(list,percentage): + + output = open('./coverage.log.xml','w') + + tests = len(list) + fails = 0 + + + print >>output, '' + + for row in list: + (file,coveredp,coveredl,uncovered,excluded,reason) = row + if coveredp < percentage: + fails = fails + 1 + + print >>output, '' % (tests,fails), + + for row in list: + (file,coveredp,coveredl,uncovered,excluded,reason) = row + print >>output + print >>output, '>output, '>' + if reason != None: + msg = '0%% Coverage, Reason: %s' % (reason) + else: + msg = 'Coverage: %s%% out of %s , (%d covered lines, %d uncovered, %d excluded)' % ( str(coveredp), str(percentage),coveredl,uncovered,excluded ) + + print >>output, ' ' % ( msg ) + print >>output, '', + + else: + print >>output, '/>', + + print >>output,"" + print >>output, '' + + return fails + + +def main(argv): + if len(sys.argv) != 4: + print "I need 3 arguments, " + str(len(sys.argv) - 1) + " given. " + usage() + + # parse through arguments + fileList = sys.argv[1].split(",") + + objectDirectory = sys.argv[2] + + + results = [] + + percentage = sys.argv[3] + (t,y,exc) = (0,0,0) + curdir = commands.getoutput("pwd")+"/" + # run gcov for file1,file2,... + results = [] + for singleFile in fileList: + if singleFile != "": + # singleFile = "../" + singleFile; + singleFileWithoutPath = os.path.basename(singleFile) + # print("cd .obj ; gcov --object-directory . " + singleFile ); + print ("gcov --object-directory .obj " + singleFile ); + commands.getoutput("gcov --object-directory . " + singleFile ); + #commands.getoutput("cd "+sd+";gcov --object-directory " +curdir+ objectDirectory +" "+ singleFile) + try: + #h= open(sd+i+".gcov","r") + h= open(singleFileWithoutPath + ".gcov","r"); + except: + msg = "Unable to open file " + singleFileWithoutPath + ".gcov for reading" + results.append( [singleFileWithoutPath,0,0,0,0,msg] ) + else: + (e,r,o) = parse(h) + + name = singleFileWithoutPath + coveredp = round(float(r)/(e+r)*100,2) + coveredl = r + uncovered = e + excluded = o + + results.append( [singleFileWithoutPath,coveredp,coveredl,uncovered,excluded,None] ) + print singleFileWithoutPath + " covered "+str(round(float(r)/(e+r)*100,2))+" % ("+str(e)+" uncovered lines, "+str(r)+" covered lines, " + str(o) +" excluded lines, "+str(e+r+o)+" in total)" # print per-file coverage + #(t,y,exc) = (t+e, r+y, exc+o) # sum up line counts + + ret = printxml(results,float(percentage)) + + + #print "Average coverage: " + str(round(float(y)/(t+y)*100,2))+" %" + #print "Total line coverage: "+str(t)+" uncovered lines, "+str(y)+" covered lines, " + str(exc) +" excluded lines, "+str(t+y+exc)+" in total)" # print per-file coverage + # ret = (float(percentage)/100*(y+t) > y) + if ret>0: + print "error: code coverage below set limit" + return 0 + +def usage(): + print "Usage: coverage.py file1,file2,... sourcedirect objectdirectory percentage" + print + print "Return values:" + print " 0 check successful, coverage sufficient" + print " 1 check successful, coverage insufficient" + print " 2 check failed" + sys.exit(2) + +def parse (f): + a = 0 + b = 0 + c = 0 + for i in f: # parse through the file + s = i.split(":")[0]; + if s[-1]=="#": + a += 1 + elif s[-1] != "-": + b += 1 + else: + c += 1 + return (a,b,c); # return (uncovered lines, covered lines count) + +sys.exit(main(sys.argv)) diff --git a/tests/duifastlistviewcommon/myindexedmodel.cpp b/tests/duifastlistviewcommon/myindexedmodel.cpp new file mode 100644 index 000000000..2859bfa9d --- /dev/null +++ b/tests/duifastlistviewcommon/myindexedmodel.cpp @@ -0,0 +1,86 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "myindexedmodel.h" + +MyIndexedModel::MyIndexedModel(QObject *r) : root(r) +{ +} + +MyIndexedModel::~MyIndexedModel() +{ + delete root; +} + +QModelIndex MyIndexedModel::index(int row, int column, const QModelIndex &parent) const +{ + QObject *parentObject; + + if (!parent.isValid()) + parentObject = root; + else + parentObject = static_cast(parent.internalPointer()); + + if (row >= 0 && row < parentObject->children().size()) + return createIndex(row, column, parentObject->children().at(row)); + else + return QModelIndex(); +} + +QModelIndex MyIndexedModel::parent(const QModelIndex &child) const +{ + if (child == QModelIndex() || !child.isValid()) + return QModelIndex(); + + QObject *object = static_cast(child.internalPointer()); + QObject *parent = object->parent(); + + if (parent == root) + return QModelIndex(); + + QObject *grandParent = parent->parent(); + + return createIndex(grandParent->children().indexOf(parent), 0, parent); +} + +int MyIndexedModel::rowCount(const QModelIndex &parent) const +{ + if (!parent.isValid()) + return root->children().size(); + + QObject *parentObject = static_cast(parent.internalPointer()); + return parentObject->children().size(); +} + +int MyIndexedModel::columnCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent); + return 1; +} + +QVariant MyIndexedModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + if (role == Qt::DisplayRole) + return (static_cast(index.internalPointer()))->objectName(); + + return QVariant(); +} diff --git a/tests/duifastlistviewcommon/myindexedmodel.h b/tests/duifastlistviewcommon/myindexedmodel.h new file mode 100644 index 000000000..c48e2dd96 --- /dev/null +++ b/tests/duifastlistviewcommon/myindexedmodel.h @@ -0,0 +1,41 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef MYINDEXEDMODEL_H +#define MYINDEXEDMODEL_H + +#include + +class MyIndexedModel : public QAbstractItemModel +{ +public: + MyIndexedModel(QObject *root); + virtual ~MyIndexedModel(); + + virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; + virtual QModelIndex parent(const QModelIndex &child) const; + virtual int rowCount(const QModelIndex &parent = QModelIndex()) const; + virtual int columnCount(const QModelIndex &parent = QModelIndex()) const; + virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + +private: + QObject *root; +}; + +#endif // MYINDEXEDMODEL_H diff --git a/tests/ft_breakiterator/.gitignore b/tests/ft_breakiterator/.gitignore new file mode 100644 index 000000000..7fe983aa3 --- /dev/null +++ b/tests/ft_breakiterator/.gitignore @@ -0,0 +1 @@ +ft_breakiterator diff --git a/tests/ft_breakiterator/ft_breakiterator.cpp b/tests/ft_breakiterator/ft_breakiterator.cpp new file mode 100644 index 000000000..90f154906 --- /dev/null +++ b/tests/ft_breakiterator/ft_breakiterator.cpp @@ -0,0 +1,225 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include + +#include +#include + +#include "ft_breakiterator.h" + + +void Ft_BreakIterator::initTestCase() +{ + static int argc = 0; + static char *argv[1] = { (char *) "" }; + qap = new QCoreApplication(argc, argv); + QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8")); +} + +void Ft_BreakIterator::cleanupTestCase() +{ + delete qap; +} + +void Ft_BreakIterator::init() +{ +} +void Ft_BreakIterator::cleanup() +{ +} + +void defaultData() +{ + QTest::addColumn("locale_name"); + QTest::addColumn("sourceString"); + QTest::addColumn >("correctBoundaries"); + + // an empty locale_name should be equivalent to the locale_name "en_US_POSIX" + QList correctBoundaries_empty_locale_name; + correctBoundaries_empty_locale_name + << 0 << 4 << 5 << 7 << 8 << 9 << 10 << 16 << 17 << 25 << 26 << 27 << 31 << 32; + QTest::newRow("") + << QString("") + << "This is a simple sentence. Täst." + << correctBoundaries_empty_locale_name; + + QList correctBoundaries_fi_FI; + correctBoundaries_fi_FI + << 0 << 8 << 9 << 17 << 18 << 23 << 24 << 29 << 30 << 39 << 40 << 43 << 44 << 47; + QTest::newRow("fi_FI") + << QString("fi_FI") + << "fiksusta boksista esiin astui despootti ges ces" + << correctBoundaries_fi_FI; + + // results for Japanese are apparently not completely correct + // it breaks only between kanji and kana, i.e. はいい is counted as one word. + // But that is better than nothing. + QList correctBoundaries_ja_JP; + correctBoundaries_ja_JP + << 0 << 4 << 7 << 9 << 10 << 11 << 12 << 13; + QTest::newRow("ja_JP") + << QString("ja_JP") + << "睡眠不足はいい仕事の敵だ。" + << correctBoundaries_ja_JP; + + // For Thai, ICU does a "GraphemeClusterBreak". not really a word break: + QList correctBoundaries_th_TH; + correctBoundaries_th_TH + << 0 << 3 << 5 << 8 << 17 << 20 << 21 << 27 << 28 << 31 << 34 << 39 << 43 << 46 << 50 << 53 << 54 << 60 << 61 << 66 << 68; + QTest::newRow("th_TH") + << QString("th_TH") + << "ฉันจะใช้ไดเรกทอรีของ Google แทนการค้นหาเว็บตามปกติของ Google เมื่อใด" + << correctBoundaries_th_TH; + + // For Chinese, ICU breaks after every Chinese character: + QList correctBoundaries_zh_CN; + correctBoundaries_zh_CN + << 0 << 1 << 2 << 3 << 4 << 5 << 6 << 7 << 8 << 14 << 15 << 16 << 17 << 18 << 19 << 20 << 21 << 22 << 23 << 24 << 25 << 26 << 27; + QTest::newRow("zh_CN") + << QString("zh_CN") + << "什么时候该选用 Google 目录查询而非网络查询呢?" + << correctBoundaries_zh_CN; + + QList correctBoundaries_de_DE; + correctBoundaries_de_DE + << 0 << 4 << 5 << 11 << 12 << 15 << 16 << 19 << 20 << 26 << 27 << 38 << 39 << 47 << 48 << 51 << 52 << 61 << 62 << 70 << 71 << 74 << 75 << 81 << 82 << 91 << 92; + QTest::newRow("de_DE") + << QString("de_DE") + << "Wann sollte ich das Google Verzeichnis anstelle der regulären Websuche von Google verwenden?" + << correctBoundaries_de_DE; +} + +void Ft_BreakIterator::forward_data() +{ + defaultData(); +} + +void Ft_BreakIterator::forward() +{ + QFETCH(QString, locale_name); + QFETCH(QString, sourceString); + QFETCH(QList, correctBoundaries); + + DuiLocale loc(locale_name); + DuiBreakIterator it(loc, sourceString, DuiBreakIterator::WordIterator); + QListIterator correctIt(correctBoundaries); + + while (it.hasNext()) { + QVERIFY(correctIt.hasNext()); + int result = it.next(); + int nextCorrect = correctIt.next(); + // qDebug() << __PRETTY_FUNCTION__ << result << nextCorrect; + QCOMPARE(result, nextCorrect); + } + QVERIFY(!correctIt.hasNext()); +} + +void Ft_BreakIterator::backward_data() +{ + defaultData(); +} + +void Ft_BreakIterator::backward() +{ + QFETCH(QString, locale_name); + QFETCH(QString, sourceString); + QFETCH(QList, correctBoundaries); + + DuiLocale locale(locale_name); + DuiBreakIterator it(locale, sourceString, DuiBreakIterator::WordIterator); + QListIterator correctIt(correctBoundaries); + + it.toBack(); + correctIt.toBack(); + + while (it.hasPrevious()) { + QVERIFY(correctIt.hasPrevious()); + int result = it.previous(); + int previousCorrect = correctIt.previous(); + // qDebug() << __PRETTY_FUNCTION__ << result << previousCorrect; + QCOMPARE(result, previousCorrect); + } + QVERIFY(!correctIt.hasPrevious()); +} + +void Ft_BreakIterator::aroundIndex_data() +{ + defaultData(); +} + +void Ft_BreakIterator::aroundIndex() +{ + QFETCH(QString, locale_name); + QFETCH(QString, sourceString); + QFETCH(QList, correctBoundaries); + + DuiLocale locale(locale_name); + DuiBreakIterator it(locale, sourceString, DuiBreakIterator::WordIterator); + QListIterator correctIt(correctBoundaries); + + // look for boundaries around an explicit index "fromIndex": + for (int fromIndex = 0; fromIndex <= sourceString.size(); ++fromIndex) { + correctIt.toFront(); + bool fromIndexIsBoundary = correctIt.findNext(fromIndex); + int previous = it.previous(fromIndex); + int next = it.next(fromIndex); + // qDebug() << __PRETTY_FUNCTION__ + // << "previous, fromIndex, next" << previous << fromIndex << next; + if (previous != -1 && next != -1) { + QVERIFY(previous < fromIndex); + QVERIFY(next > fromIndex); + correctIt.toFront(); + QVERIFY(correctIt.findNext(previous)); + if (fromIndexIsBoundary) + correctIt.next(); + QCOMPARE(correctIt.next(), next); + } + } +} + +void Ft_BreakIterator::peek_data() +{ + defaultData(); +} + +void Ft_BreakIterator::peek() +{ + QFETCH(QString, locale_name); + QFETCH(QString, sourceString); + QFETCH(QList, correctBoundaries); + + DuiLocale locale(locale_name); + DuiBreakIterator it(locale, sourceString, DuiBreakIterator::WordIterator); + QListIterator correctIt(correctBoundaries); + + // check that two peeks return the same value and that it is a correct value + int next = it.peekNext(); + QCOMPARE(next, it.peekNext()); + QCOMPARE(next, correctIt.next()); + it.next(); + it.next(); + + int prev = it.peekPrevious(); + QCOMPARE(prev, next); +} + + +QTEST_APPLESS_MAIN(Ft_BreakIterator); diff --git a/tests/ft_breakiterator/ft_breakiterator.h b/tests/ft_breakiterator/ft_breakiterator.h new file mode 100644 index 000000000..08d155a0a --- /dev/null +++ b/tests/ft_breakiterator/ft_breakiterator.h @@ -0,0 +1,59 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef FT_BREAKITERATOR_H +#define FT_BREAKITERATOR_H + +#include +#include +#include +#include + +#include + + +#define MAX_PARAMS 10 + +Q_DECLARE_METATYPE(QList); + + +class Ft_BreakIterator : public QObject +{ + Q_OBJECT + +private: + QCoreApplication *qap; + +private slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + + void forward_data(); + void forward(); + void backward_data(); + void backward(); + void aroundIndex_data(); + void aroundIndex(); + void peek_data(); + void peek(); +}; + +#endif diff --git a/tests/ft_breakiterator/ft_breakiterator.pro b/tests/ft_breakiterator/ft_breakiterator.pro new file mode 100644 index 000000000..e019074f9 --- /dev/null +++ b/tests/ft_breakiterator/ft_breakiterator.pro @@ -0,0 +1,12 @@ +include(../common_top.pri) + +TARGET = ft_breakiterator + +# unit +TEST_SOURCES = \ + +# Input +HEADERS += ft_breakiterator.h +SOURCES += ft_breakiterator.cpp + +include(../common_bot.pri) diff --git a/tests/ft_duibutton/.gitignore b/tests/ft_duibutton/.gitignore new file mode 100644 index 000000000..0f6ded5f9 --- /dev/null +++ b/tests/ft_duibutton/.gitignore @@ -0,0 +1 @@ +ft_duibutton diff --git a/tests/ft_duibutton/ft_duibutton.cpp b/tests/ft_duibutton/ft_duibutton.cpp new file mode 100644 index 000000000..dc7535d13 --- /dev/null +++ b/tests/ft_duibutton/ft_duibutton.cpp @@ -0,0 +1,272 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ft_duibutton.h" +#include "duitheme.h" +#include +#include +#include "duitheme.h" +#include "duibutton.h" +#include "duibuttonview.h" +#include "duiapplication.h" + + + + + +Ft_DuiButton::Ft_DuiButton() +{ +} + +void Ft_DuiButton::initTestCase() +{ + int argc = 1; + char *argv = (char *) "./ft_duibutton"; + app = new DuiApplication(argc, &argv); + qDebug() << "loadCSS " << DuiTheme::loadCSS("ft_duibutton.css"); +} + + +void Ft_DuiButton::cleanupTestCase() +{ + delete app; +} + +void Ft_DuiButton::buttonPaint() +{ + // Allocate button, rename, resize and check. + DuiButton *b = new DuiButton(); + setObjectName("ft_test_button"); + b->resize(125, 85); + QVERIFY(b->size() == QSizeF(125, 85)); + + // Allocate two pixmaps. + QPixmap *p = new QPixmap(500, 500); + p->fill(QColor(0, 0, 0, 0)); + QPixmap *orig = new QPixmap(500, 500); + orig->fill(QColor(0, 0, 0, 0)); + + // Allocate painter, convert pixmaps to image and check are they the same. + QPainter *painter = new QPainter(p); + b->paint(painter, 0, 0); + QImage pi = p->toImage(); + QImage origi = orig->toImage(); + QVERIFY(pi != origi); + + for (int x = 125; x < 500; x++) { + for (int y = 0; y < 500; y++) { + QVERIFY(pi.pixel(x, y) == origi.pixel(x, y)); + } + } + + for (int y = 85; y < 500; y++) { + for (int x = 0; x < 500; x++) { + QVERIFY(pi.pixel(x, y) == origi.pixel(x, y)); + } + } + + // Clean. + delete orig; + delete b; + delete p; +} + +void Ft_DuiButton::buttonSetObjectName() +{ + // Allocate button, resize and check. + DuiButton *b1 = new DuiButton(); + b1->resize(125, 85); + QVERIFY(b1->size() == QSizeF(125, 85)); + + // Allocate button, rename, resize and check. + DuiButton *b2 = new DuiButton(); + b2->setObjectName("button2"); + QVERIFY(b2->objectName() == "button2"); + b2->resize(125, 85); + QVERIFY(b2->size() == QSizeF(125, 85)); + + // Allocate two pixmaps. + QPixmap *p1 = new QPixmap(125, 85); + p1->fill(QColor(0, 0, 0, 0)); + QPixmap *p2 = new QPixmap(125, 85); + p2->fill(QColor(0, 0, 0, 0)); + + // Init painters and paint. + QPainter painter1(p1); + QPainter painter2(p2); + b1->paint(&painter1, 0, 0); + b2->paint(&painter2, 0, 0); + + // Convert pixmaps to QT image. Check that images are not the same. + QImage i1 = p1->toImage(); + QImage i2 = p2->toImage(); + QVERIFY(i1 != i2); + + // Clean. + delete b1; + delete b2; +} + + +void Ft_DuiButton::buttonSetValues() +{ + // Set some values and check that they are ok. + DuiButton b; + b.setIconID(QString("test_button_id")); + QVERIFY(b.iconID() == QString("test_button_id")); + + b.setToggledIconID(QString("test_button_toggled_id")); + QVERIFY(b.toggledIconID() == QString("test_button_toggled_id")); + + b.setText(QString("test_button_text")); + QVERIFY(b.text() == QString("test_button_text")); + + b.setTextVisible(true); + QVERIFY(b.isTextVisible() == true); + b.setTextVisible(false); + QVERIFY(b.isTextVisible() == false); + + b.setIconVisible(true); + QVERIFY(b.isIconVisible() == true); + b.setIconVisible(false); + QVERIFY(b.isIconVisible() == false); + + b.setCheckable(true); + QVERIFY(b.isCheckable() == true); + b.setCheckable(false); + QVERIFY(b.isCheckable() == false); + + b.setState(DuiButtonModel::Pressed); + QVERIFY(b.state() == DuiButtonModel::Pressed); + b.setState(DuiButtonModel::Released); + QVERIFY(b.state() == DuiButtonModel::Released); + + b.setCheckable(true); + b.setChecked(true); + QVERIFY(b.isChecked() == true); + b.setChecked(false); + QVERIFY(b.isChecked() == false); +} + + +void Ft_DuiButton::testSignalClicked() +{ + DuiButton b; + const int CLICK_COUNT = 50; + b.setCheckable(false); + b.setChecked(false); + QSignalSpy spy(&b, SIGNAL(clicked(bool))); + for (int i = 0; i < CLICK_COUNT; i++) + b.click(); + QVERIFY(spy.count() == CLICK_COUNT); +} + + +void Ft_DuiButton::testSignalToggled() +{ + DuiButton b; + const int TOGGLE_COUNT = 55; + b.setCheckable(true); + b.setChecked(false); + QSignalSpy spy(&b, SIGNAL(toggled(bool))); + for (int i = 0; i < TOGGLE_COUNT; i++) + b.toggle(); + QVERIFY(spy.count() == TOGGLE_COUNT); +} + +void Ft_DuiButton::testSignalPressed() +{ + DuiButton b; + const int PRESS_COUNT = 60; + QSignalSpy spy(&b, SIGNAL(pressed())); + for (int i = 0; i < PRESS_COUNT; i++) { + b.setState(DuiButtonModel::Released); + b.setState(DuiButtonModel::Pressed); + } + QVERIFY(spy.count() == PRESS_COUNT); +} + +void Ft_DuiButton::testSignalReleased() +{ + DuiButton b; + const int RELEASE_COUNT = 65; + QSignalSpy spy(&b, SIGNAL(released())); + for (int i = 0; i < RELEASE_COUNT; i++) { + b.setState(DuiButtonModel::Pressed); + b.setState(DuiButtonModel::Released); + } + QVERIFY(spy.count() == RELEASE_COUNT); +} + + + +// Horizontal box edge percent no more in css style sheet. Implemented in scalable image. +// +// void Ft_DuiButton::buttonBoxed() +// { +// // Allocate and name a new button. +// DuiButton* b1 = new DuiButton(); +// b1->setObjectName("buttonNotBoxed"); + +// // Resize and check. +// qDebug() << b1->effectiveSizeHint(Qt::MaximumSize); +// b1->resize(150, 95); +// QVERIFY(b1->size() == QSizeF(150, 95)); + +// // Allocate and name a new button. +// DuiButton* b2 = new DuiButton(); +// b2->setObjectName("buttonBoxed"); + +// // Resize and check. +// b2->resize(150, 95); +// QVERIFY(b2->size() == QSizeF(150, 95)); + +// // Allocate two pixmaps. +// QPixmap* p1 = new QPixmap(150, 95); +// p1->fill(QColor(0, 0, 0, 0)); +// QPixmap* p2 = new QPixmap(150, 95); +// p2->fill(QColor(0, 0, 0, 0)); + +// // Init painters and paint. +// QPainter painter1(p1); +// QPainter painter2(p2); +// b1->paint(&painter1, 0, 0); +// b2->paint(&painter2, 0, 0); + +// // Convert pixmaps to QT image. Check that images are not the same. +// QImage i1 = p1->toImage(); +// QImage i2 = p2->toImage(); +// QVERIFY(i1 != i2); + +// // Check that pixels on one vertical line are the same. +// for(int y = 0; y < 95; y++) { +// QVERIFY(i1.pixel(75, y) == i2.pixel(75, y)); +// } + +// // Clean. +// delete b1; +// delete b2; +// delete p1; +// delete p2; +// } + + +QTEST_APPLESS_MAIN(Ft_DuiButton) + + diff --git a/tests/ft_duibutton/ft_duibutton.css b/tests/ft_duibutton/ft_duibutton.css new file mode 100644 index 000000000..a835b0330 --- /dev/null +++ b/tests/ft_duibutton/ft_duibutton.css @@ -0,0 +1,52 @@ +DuiButtonStyle { + minimum-size: size(20, 20); + maximum-size: size(400, 400); + preferred-size: size(100, 100); + normal-background-image: scalable(SB-normal, 40, 40, 0, 0); + pressed-background-image: scalable(SB-press, 40, 40, 0, 0); +} + +.DuiButtonStyle#ft_test_button { + minimum-size: size(20, 20); + maximum-size: size(400, 400); + preferred-size: size(100, 100); +} + +.DuiButtonStyle#button2 { + normal-background-image: scalable(SB-press, 40, 40, 0, 0); + pressed-background-image: scalable(SB-press, 40, 40, 0, 0); +} + +DuiButtonStyle#buttonNotBoxed { + horizontal-box-edge-percent: 0; +} + +DuiButtonStyle#buttonBoxed { + horizontal-box-edge-percent: 10; +} + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/ft_duibutton/ft_duibutton.h b/tests/ft_duibutton/ft_duibutton.h new file mode 100644 index 000000000..04e99384c --- /dev/null +++ b/tests/ft_duibutton/ft_duibutton.h @@ -0,0 +1,59 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef FT_DUIBUTTON_H +#define FT_DUIBUTTON_H + +#include +#include +#include +#include "duitheme.h" +#include "duiapplication.h" + +class Ft_DuiButton : public QObject +{ + Q_OBJECT; + +public: + Ft_DuiButton(); + +private slots: + void initTestCase(); + void cleanupTestCase(); + + + void buttonPaint(); + void buttonSetObjectName(); + void buttonSetValues(); + void testSignalClicked(); + void testSignalToggled(); + void testSignalPressed(); + void testSignalReleased(); + + + /* void buttonBoxed(); */ + +private: + DuiApplication *app; + + +}; + +#endif + diff --git a/tests/ft_duibutton/ft_duibutton.pro b/tests/ft_duibutton/ft_duibutton.pro new file mode 100644 index 000000000..29fd4f139 --- /dev/null +++ b/tests/ft_duibutton/ft_duibutton.pro @@ -0,0 +1,12 @@ +include(../common_top.pri) +TARGET = ft_duibutton +QT += dbus svg network +LIBRARYPATH += $$DUISRCDIR + +SOURCES += \ + ft_duibutton.cpp \ + +HEADERS += \ + ft_duibutton.h \ + +include(../common_bot.pri) diff --git a/tests/ft_duidialog/.gitignore b/tests/ft_duidialog/.gitignore new file mode 100644 index 000000000..e144eab84 --- /dev/null +++ b/tests/ft_duidialog/.gitignore @@ -0,0 +1 @@ +ft_duidialog diff --git a/tests/ft_duidialog/ft_duidialog.cpp b/tests/ft_duidialog/ft_duidialog.cpp new file mode 100644 index 000000000..874d6cad4 --- /dev/null +++ b/tests/ft_duidialog/ft_duidialog.cpp @@ -0,0 +1,150 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ft_duidialog.h" +#include "duidialog.h" +#include +#include +#include +#include + +DuiApplication *app; +DuiApplicationWindow *appWindow; + +void Ft_DuiDialog::init() +{ + m_subject = new DuiDialog(); +} + +void Ft_DuiDialog::cleanup() +{ + delete m_subject; +} + +void Ft_DuiDialog::initTestCase() +{ + static int argc = 1; + static char *argv[1] = { (char *) "./ft_duidialog" }; + app = new DuiApplication(argc, argv); + appWindow = new DuiApplicationWindow; +} + +void Ft_DuiDialog::cleanupTestCase() +{ + delete appWindow; + // Disabled for now since there is bug in qemu and/or QFileSystemWatcher code .. + // delete app; +} + +void Ft_DuiDialog::test_signals() +{ + QSignalSpy spy_accept(m_subject, SIGNAL(accepted())); + QSignalSpy spy_reject(m_subject, SIGNAL(rejected())); + QSignalSpy spy_finish(m_subject, SIGNAL(finished(int))); + + // test accept signal, use spy to check that it was signalled + m_subject->accept(); + QCOMPARE(spy_accept.count(), 1); + + // test reject signal, use spy to check that it was signalled + m_subject->reject(); + QCOMPARE(spy_reject.count(), 1); + + // test done signal with accepted param, use spy to check that accept was signalled + m_subject->done(DuiDialog::Accepted); + QCOMPARE(spy_accept.count(), 2); + + // test done signal with rejected param, use spy to check that reject was signalled + m_subject->done(DuiDialog::Rejected); + QCOMPARE(spy_reject.count(), 2); + + // we should get finish signal in all of the cases above + QCOMPARE(spy_finish.count(), 4); +} + +void Ft_DuiDialog::test_eventloop() +{ + //QVERIFY(false); //This test fails, and hangs - John Tapsell + // It was hanging for me as well when I had my scratchbox env + // pointing its DBUS_SESSION_BUS_ADDRESS to my Ubuntu host D-Bus. + // When I started using the D-Bus from scratchbox itself the hanging issues + // disappeared. + // $ dui-sb-session start + // $ source /tmp/session_bus_address.user + // - Daniel d'Andrada + + // use timer to cancel the event loop when we get back into the message pump + // another way to do this would involve creating another thread or something similar... + QTimer::singleShot(0, this, SLOT(timer())); + + // launch the dialog, it will start event loop and block here + int result = m_subject->exec(); + + // The exec will return standard button id or NoStandardButton if no button + // was clicked as in this case. + QCOMPARE(result, (int)Dui::NoStandardButton); + + // result() will return the result set in timer() method. + QCOMPARE(99, m_subject->result()); +} + +void Ft_DuiDialog::test_other() +{ + m_subject->setResult(99); + QCOMPARE(99, m_subject->result()); + m_subject->setResult(99); + QCOMPARE(99, m_subject->result()); +} + +void Ft_DuiDialog::timer() +{ + // timer signalled timeout, cancel eventloop here with some result value + m_subject->done(99); +} + +void Ft_DuiDialog::testDismissDialogInEventLoop() +{ + //QVERIFY(false); //This test hangs - John Tapsell + // It was hanging for me as well when I had my scratchbox env + // pointing its DBUS_SESSION_BUS_ADDRESS to my Ubuntu host D-Bus. + // When I started using the D-Bus from scratchbox itself the hanging issues + // disappeared. + // $ dui-sb-session start + // $ source /tmp/session_bus_address.user + // - Daniel d'Andrada + + QSignalSpy spyAccepted(m_subject, SIGNAL(accepted())); + QSignalSpy spyRejected(m_subject, SIGNAL(rejected())); + QSignalSpy spyFinished(m_subject, SIGNAL(finished(int))); + + // ABI FREEZE: Release this: + //QTimer::singleShot(500, m_subject, SLOT(dismiss())); + QTimer::singleShot(500, m_subject, SLOT(close())); + + // bail out after 5 seconds if the dismiss() is not successful + QTimer::singleShot(5000, QCoreApplication::instance(), SLOT(quit())); + + m_subject->exec(appWindow); + + QCOMPARE(spyAccepted.count(), 0); + QCOMPARE(spyRejected.count(), 1); + QCOMPARE(spyFinished.count(), 1); +} + +QTEST_APPLESS_MAIN(Ft_DuiDialog) diff --git a/tests/ft_duidialog/ft_duidialog.h b/tests/ft_duidialog/ft_duidialog.h new file mode 100644 index 000000000..f5f852f14 --- /dev/null +++ b/tests/ft_duidialog/ft_duidialog.h @@ -0,0 +1,52 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef FT_DUIDIALOG_H +#define FT_DUIDIALOG_H + +#include +#include +#include + +class DuiDialog; + +class Ft_DuiDialog : public QObject +{ + Q_OBJECT + +public slots: + void timer(); + +private slots: + void init(); + void cleanup(); + void initTestCase(); + void cleanupTestCase(); + + void test_signals(); + void test_eventloop(); + void test_other(); + void testDismissDialogInEventLoop(); +private: + + DuiDialog *m_subject; +}; + +#endif + diff --git a/tests/ft_duidialog/ft_duidialog.pro b/tests/ft_duidialog/ft_duidialog.pro new file mode 100644 index 000000000..7aec17c82 --- /dev/null +++ b/tests/ft_duidialog/ft_duidialog.pro @@ -0,0 +1,12 @@ +include(../common_top.pri) +TARGET = ft_duidialog +QT += dbus svg network +LIBRARYPATH += $$DUISRCDIR + +SOURCES += \ + ft_duidialog.cpp \ + +HEADERS += \ + ft_duidialog.h \ + +include(../common_bot.pri) diff --git a/tests/ft_duigconfitem/.gitignore b/tests/ft_duigconfitem/.gitignore new file mode 100644 index 000000000..e52d25955 --- /dev/null +++ b/tests/ft_duigconfitem/.gitignore @@ -0,0 +1 @@ +ft_duigconfitem_exec diff --git a/tests/ft_duigconfitem/ft_duigconfitem b/tests/ft_duigconfitem/ft_duigconfitem new file mode 100755 index 000000000..a7c5d7a46 --- /dev/null +++ b/tests/ft_duigconfitem/ft_duigconfitem @@ -0,0 +1,95 @@ +#!/bin/sh + +emptylog() { + FILENAME=$1 + TESTCASE=$2 + REASON=$3 + + cat< $FILENAME + + + + 4.5.2 + 4.5.2 + + + + + + + + + + + + + + + + + + + + +EOF + +} + +# please make sure that the en_US.UTF-8 locale is available! +# installing the “libdui-tests” package should create the en_US.UTF-8 locale +# automatically. Manually it can be done like this: +# - apt-get install locales +# - make sure /etc/locale.gen contains the line "en_US.UTF-8 UTF-8" +# - run /usr/sbin/locale-gen +LC_ALL=en_US.UTF-8 +export LC_ALL + +CHARMAP=$(locale charmap) +if [ "$CHARMAP" != "UTF-8" ]; then + echo "UTF-8 locale is missing, skipping all tests" + echo "Installing the libdui-tests package should have created the en_US.UTF-8 locale" + echo "but for some reason it appears to be missing." + emptylog "ft_duigconfitem.log" "ft_duigconfitem" "UTF-8 locale is missing, skipping all tests. Installing the libdui-tests package should have created the en_US.UTF-8 locale but for some reason it appears to be missing." + exit 0 +fi + +# Setup values expected by the external_values() test. + +gconftool-2 -s -t bool /Test/Bool true +VALUE=$(gconftool-2 -g /Test/Bool) +if [ "$VALUE" != "true" ]; then + emptylog "ft_duigconfitem.log" "ft_duigconfitem" "GConf is not running, skipping all tests" + exit 0 +fi +gconftool-2 -s -t int /Test/Int 123 +gconftool-2 -s -t string /Test/String "Hello GConf" +gconftool-2 -s -t float /Test/Double 3.5 +gconftool-2 -s -t list --list-type string /Test/StringList "[Hello,GConf,ÄÖÜ]" +gconftool-2 -s -t list --list-type int /Test/IntList "[1,2,3,4]" +gconftool-2 -s -t list --list-type float /Test/DoubleList "[3.5,3.5,3.5]" +gconftool-2 -s -t list --list-type bool /Test/BoolList "[false,true,true,false]" +gconftool-2 -u /Test/UnsetBefore +gconftool-2 -s -t int /Test/UnsetAfter 100 +gconftool-2 -s -t int /Test/Dir/Entry 200 + +$(dirname $0)/ft_duigconfitem_exec $* + +# Check what set_external() has left behind. + +compare() { + if [ "$1" != "$2" ]; then +# Echo to stderr, our output seems to confuse some tools. + echo >&2 "FAIL: '$1' != '$2'" + exit 1 + fi +} + +compare "`gconftool-2 -g /Test/Bool`" false +compare "`gconftool-2 -g /Test/Int`" 54321 +compare "`gconftool-2 -g /Test/String`" "Good bye GConf" +compare "`gconftool-2 -g /Test/Double`" -2.5 +compare "`gconftool-2 -g /Test/StringList`" "[Good,bye,GConf,äöü]" +compare "`gconftool-2 -g /Test/IntList`" "[5,4,3,2,1]" +compare "`gconftool-2 -g /Test/DoubleList`" "[-2.5,-2.5]" +compare "`gconftool-2 -g /Test/BoolList`" "[false,false,true,true]" +compare "`gconftool-2 -g /Test/UnsetAfter 2>&1`" 'No value set for `/Test/UnsetAfter'"'" diff --git a/tests/ft_duigconfitem/ft_duigconfitem.pro b/tests/ft_duigconfitem/ft_duigconfitem.pro new file mode 100644 index 000000000..01cc4f229 --- /dev/null +++ b/tests/ft_duigconfitem/ft_duigconfitem.pro @@ -0,0 +1,14 @@ +include(../common_top.pri) + +CONFIG += link_pkgconfig +TARGET = ft_duigconfitem_exec +PKGCONFIG += gconf-2.0 + +# Input +HEADERS += ft_duigconfitem_exec.h +SOURCES += ft_duigconfitem_exec.cpp + +support_files.files += \ + ft_duigconfitem \ + +include(../common_bot.pri) diff --git a/tests/ft_duigconfitem/ft_duigconfitem_exec.cpp b/tests/ft_duigconfitem/ft_duigconfitem_exec.cpp new file mode 100644 index 000000000..c1dc8c436 --- /dev/null +++ b/tests/ft_duigconfitem/ft_duigconfitem_exec.cpp @@ -0,0 +1,320 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ft_duigconfitem_exec.h" + +#define MYLOGLEVEL 2 +void myMessageOutput(QtMsgType type, const char *msg) +{ + switch (type) { + case QtDebugMsg: + if (MYLOGLEVEL <= 0) + fprintf(stderr, "Debug: %s\n", msg); + break; + case QtWarningMsg: + if (MYLOGLEVEL <= 1) + fprintf(stderr, "Warning: %s\n", msg); + break; + case QtCriticalMsg: + if (MYLOGLEVEL <= 2) + fprintf(stderr, "Critical: %s\n", msg); + break; + case QtFatalMsg: + if (MYLOGLEVEL <= 3) + fprintf(stderr, "Fatal: %s\n", msg); + abort(); + } +} + +// +// Definition of testcases: Normal tests +// + +void DuiGConfItemTests::timeout() +{ + timed_out = true; + timer.stop(); +} + +// Before all tests +void DuiGConfItemTests::initTestCase() +{ + connect(&timer, SIGNAL(timeout()), + this, SLOT(timeout())); +} + +// After all tests +void DuiGConfItemTests::cleanupTestCase() +{ +} + +// Before each test +void DuiGConfItemTests::init() +{ + boolItem = new DuiGConfItem("/Test/Bool"); + intItem = new DuiGConfItem("/Test/Int"); + stringItem = new DuiGConfItem("/Test/String"); + doubleItem = new DuiGConfItem("/Test/Double"); + stringListItem = new DuiGConfItem("/Test/StringList"); + intListItem = new DuiGConfItem("/Test/IntList"); + doubleListItem = new DuiGConfItem("/Test/DoubleList"); + boolListItem = new DuiGConfItem("/Test/BoolList"); + unsetBeforeItem = new DuiGConfItem("/Test/UnsetBefore"); + unsetAfterItem = new DuiGConfItem("/Test/UnsetAfter"); + signalSpy = new SignalListener(); + QObject::connect(boolItem, SIGNAL(valueChanged()), signalSpy, SLOT(valueChanged())); + QObject::connect(intItem, SIGNAL(valueChanged()), signalSpy, SLOT(valueChanged())); + QObject::connect(stringItem, SIGNAL(valueChanged()), signalSpy, SLOT(valueChanged())); + QObject::connect(doubleItem, SIGNAL(valueChanged()), signalSpy, SLOT(valueChanged())); + QObject::connect(stringListItem, SIGNAL(valueChanged()), signalSpy, SLOT(valueChanged())); + QObject::connect(intListItem, SIGNAL(valueChanged()), signalSpy, SLOT(valueChanged())); + QObject::connect(doubleListItem, SIGNAL(valueChanged()), signalSpy, SLOT(valueChanged())); + QObject::connect(boolListItem, SIGNAL(valueChanged()), signalSpy, SLOT(valueChanged())); + // wait a bit do give the gconf daemon time to do whatever he wants to do: + QTest::qWait(500); +} + +// After each test +void DuiGConfItemTests::cleanup() +{ + QObject::disconnect(boolItem, SIGNAL(valueChanged()), signalSpy, SLOT(valueChanged())); + QObject::disconnect(intItem, SIGNAL(valueChanged()), signalSpy, SLOT(valueChanged())); + QObject::disconnect(stringItem, SIGNAL(valueChanged()), signalSpy, SLOT(valueChanged())); + QObject::disconnect(doubleItem, SIGNAL(valueChanged()), signalSpy, SLOT(valueChanged())); + QObject::disconnect(stringListItem, SIGNAL(valueChanged()), signalSpy, SLOT(valueChanged())); + QObject::disconnect(intListItem, SIGNAL(valueChanged()), signalSpy, SLOT(valueChanged())); + QObject::disconnect(doubleListItem, SIGNAL(valueChanged()), signalSpy, SLOT(valueChanged())); + QObject::disconnect(boolListItem, SIGNAL(valueChanged()), signalSpy, SLOT(valueChanged())); + delete signalSpy; + delete boolItem; + delete intItem; + delete stringItem; + delete doubleItem; + delete stringListItem; + delete intListItem; + delete doubleListItem; + delete boolListItem; + delete unsetBeforeItem; + delete unsetAfterItem; + + timer.stop(); +} + +void DuiGConfItemTests::path() +{ + QCOMPARE(boolItem->key(), QString("/Test/Bool")); + QCOMPARE(intItem->key(), QString("/Test/Int")); + QCOMPARE(stringItem->key(), QString("/Test/String")); + QCOMPARE(doubleItem->key(), QString("/Test/Double")); + QCOMPARE(stringListItem->key(), QString("/Test/StringList")); + QCOMPARE(intListItem->key(), QString("/Test/IntList")); + QCOMPARE(doubleListItem->key(), QString("/Test/DoubleList")); + QCOMPARE(boolListItem->key(), QString("/Test/BoolList")); + QCOMPARE(unsetBeforeItem->key(), QString("/Test/UnsetBefore")); + QCOMPARE(unsetAfterItem->key(), QString("/Test/UnsetAfter")); +} + +void DuiGConfItemTests::external_values() +{ + // These values are set before this program starts. + QCOMPARE(boolItem->value().toBool(), true); + QCOMPARE(intItem->value().toInt(), 123); + QCOMPARE(stringItem->value().toString(), QString("Hello GConf")); + QCOMPARE(doubleItem->value().toDouble(), 3.5); + QCOMPARE(stringListItem->value().toStringList(), QStringList() << "Hello" << "GConf" << QString::fromUtf8("ÄÖÜ")); + QCOMPARE(intListItem->value().toList(), QList() << 1 << 2 << 3 << 4); + QCOMPARE(doubleListItem->value().toList(), QList() << 3.5 << 3.5 << 3.5); + QCOMPARE(boolListItem->value().toList(), QList() << false << true << true << false); + QCOMPARE(unsetBeforeItem->value().isValid(), false); + QCOMPARE(unsetAfterItem->value().isValid(), true); +} + +void DuiGConfItemTests::set_bool() +{ + signalSpy->numberOfCalls = 0; + + boolItem->set(false); + QCOMPARE(boolItem->value().toBool(), false); + boolItem->set(true); + QCOMPARE(boolItem->value().toBool(), true); + + QCOMPARE(signalSpy->numberOfCalls, 2); +} + +void DuiGConfItemTests::set_int() +{ + signalSpy->numberOfCalls = 0; + + intItem->set(12); + QCOMPARE(intItem->value().toInt(), 12); + intItem->set(-5); + QCOMPARE(intItem->value().toInt(), -5); + + QCOMPARE(signalSpy->numberOfCalls, 2); +} + +void DuiGConfItemTests::set_string() +{ + signalSpy->numberOfCalls = 0; + + stringItem->set("Hi"); + QCOMPARE(stringItem->value().toString(), QString("Hi")); + + QCOMPARE(signalSpy->numberOfCalls, 1); +} + +void DuiGConfItemTests::set_unicode_string() +{ + signalSpy->numberOfCalls = 0; + + stringItem->set(QString::fromUtf8("Höäü")); + QCOMPARE(stringItem->value().toString(), QString::fromUtf8("Höäü")); + + QCOMPARE(signalSpy->numberOfCalls, 1); +} + +void DuiGConfItemTests::set_double() +{ + signalSpy->numberOfCalls = 0; + + doubleItem->set(1.2345); + QCOMPARE(doubleItem->value().toDouble(), 1.2345); + + QCOMPARE(signalSpy->numberOfCalls, 1); +} + +void DuiGConfItemTests::set_string_list() +{ + signalSpy->numberOfCalls = 0; + + stringListItem->set(QStringList() << "one" << "two" << "three"); + QCOMPARE(stringListItem->value().toStringList(), QStringList() << "one" << "two" << "three"); + + QCOMPARE(signalSpy->numberOfCalls, 1); +} + +void DuiGConfItemTests::set_int_list() +{ + signalSpy->numberOfCalls = 0; + + intListItem->set(QList() << 10 << 11 << 12); + QCOMPARE(intListItem->value().toList(), QList() << 10 << 11 << 12); + + QCOMPARE(signalSpy->numberOfCalls, 1); +} + +void DuiGConfItemTests::set_double_list() +{ + signalSpy->numberOfCalls = 0; + + doubleListItem->set(QList() << 1.1 << 2.2 << 3.3); + QCOMPARE(doubleListItem->value().toList(), QList() << 1.1 << 2.2 << 3.3); + + QCOMPARE(signalSpy->numberOfCalls, 1); +} + +void DuiGConfItemTests::set_bool_list() +{ + signalSpy->numberOfCalls = 0; + + boolListItem->set(QList() << true << true << false); + QCOMPARE(boolListItem->value().toList(), QList() << true << true << false); + + QCOMPARE(signalSpy->numberOfCalls, 1); +} + +void DuiGConfItemTests::unset() +{ + signalSpy->numberOfCalls = 0; + + boolItem->unset(); + QCOMPARE(boolItem->value().isValid(), false); + + QCOMPARE(signalSpy->numberOfCalls, 1); +} + +void DuiGConfItemTests::list_dirs() +{ + DuiGConfItem test("/Test"); + QStringList dirs = test.listDirs(); + + QVERIFY(!dirs.contains("/Test/Bool")); + QVERIFY(!dirs.contains("/Test/Int")); + QVERIFY(!dirs.contains("/Test/String")); + QVERIFY(!dirs.contains("/Test/Double")); + QVERIFY(!dirs.contains("/Test/StringList")); + QVERIFY(!dirs.contains("/Test/IntList")); + QVERIFY(!dirs.contains("/Test/DoubleList")); + QVERIFY(!dirs.contains("/Test/BoolList")); + QVERIFY(!dirs.contains("/Test/UnsetBefore")); + QVERIFY(!dirs.contains("/Test/UnsetAfter")); + QVERIFY(dirs.contains("/Test/Dir")); +} + +void DuiGConfItemTests::list_entries() +{ + DuiGConfItem test("/Test"); + QStringList entries = test.listEntries(); + + QVERIFY(!entries.contains("/Test/Bool")); // has been unset above! + QVERIFY(entries.contains("/Test/Int")); + QVERIFY(entries.contains("/Test/String")); + QVERIFY(entries.contains("/Test/Double")); + QVERIFY(entries.contains("/Test/StringList")); + QVERIFY(entries.contains("/Test/IntList")); + QVERIFY(entries.contains("/Test/DoubleList")); + QVERIFY(entries.contains("/Test/BoolList")); + QVERIFY(!entries.contains("/Test/UnsetBefore")); + QVERIFY(entries.contains("/Test/UnsetAfter")); + QVERIFY(!entries.contains("/Test/Dir")); +} + +void DuiGConfItemTests::get_default() +{ + intItem->unset(); + QCOMPARE(intItem->value(123).toInt(), 123); + intItem->set(234); + QCOMPARE(intItem->value(123).toInt(), 234); +} + +void DuiGConfItemTests::propagate() +{ + DuiGConfItem secondIntItem("/Test/Int"); + secondIntItem.set(3000); + QVERIFY_TIMEOUT(2000, intItem->value() == secondIntItem.value()); + QCOMPARE(signalSpy->numberOfCalls, 1); +} + +void DuiGConfItemTests::set_external() +{ + // This must be the last test case. The values that are set here + // are checked after this program exits. + + boolItem->set(false); + intItem->set(54321); + stringItem->set("Good bye GConf"); + doubleItem->set(-2.5); + stringListItem->set(QStringList() << "Good" << "bye" << "GConf" << QString::fromUtf8("äöü")); + intListItem->set(QList() << 5 << 4 << 3 << 2 << 1); + doubleListItem->set(QList() << -2.5 << -2.5); + boolListItem->set(QList() << false << false << true << true); + unsetAfterItem->set(QVariant()); +} + +QTEST_MAIN(DuiGConfItemTests); diff --git a/tests/ft_duigconfitem/ft_duigconfitem_exec.h b/tests/ft_duigconfitem/ft_duigconfitem_exec.h new file mode 100644 index 000000000..6aeafa8f3 --- /dev/null +++ b/tests/ft_duigconfitem/ft_duigconfitem_exec.h @@ -0,0 +1,104 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include + +#include +#include + +// Helper class for listening to signals +class SignalListener : public QObject +{ + Q_OBJECT +public: + int numberOfCalls; + SignalListener() : numberOfCalls(0) { + } + +public slots: + void valueChanged() { + numberOfCalls++; + } +}; + +// Tests for the public API +class DuiGConfItemTests : public QObject +{ + Q_OBJECT + + // Stored pointers etc. +private: + DuiGConfItem *boolItem; + DuiGConfItem *intItem; + DuiGConfItem *stringItem; + DuiGConfItem *doubleItem; + DuiGConfItem *stringListItem; + DuiGConfItem *intListItem; + DuiGConfItem *doubleListItem; + DuiGConfItem *boolListItem; + DuiGConfItem *unsetBeforeItem; + DuiGConfItem *unsetAfterItem; + + SignalListener *signalSpy; + + QTimer timer; + bool timed_out; + + // Tests +private slots: + // Init and cleanup helper functions + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + void timeout(); + + // Public API + void path(); + void external_values(); + void set_bool(); + void set_int(); + void set_string(); + void set_unicode_string(); + void set_double(); + void set_string_list(); + void set_int_list(); + void set_double_list(); + void set_bool_list(); + void unset(); + void get_default(); + void list_dirs(); + void list_entries(); + void propagate(); + void set_external(); +}; + +// Useful if you need to process some events until a condition becomes +// true. + +#define QVERIFY_TIMEOUT(msecs, expr) \ + do { \ + timed_out = false; \ + timer.start(msecs); \ + while (!timed_out && !(expr)) { \ + QApplication::processEvents(QEventLoop::WaitForMoreEvents); \ + } \ + QVERIFY((expr)); \ + } while(0) diff --git a/tests/ft_duiprogressindicator/.gitignore b/tests/ft_duiprogressindicator/.gitignore new file mode 100644 index 000000000..ab6acc362 --- /dev/null +++ b/tests/ft_duiprogressindicator/.gitignore @@ -0,0 +1,2 @@ +ft_duiprogressindicator + diff --git a/tests/ft_duiprogressindicator/ft_duiprogressindicator.cpp b/tests/ft_duiprogressindicator/ft_duiprogressindicator.cpp new file mode 100644 index 000000000..d70b6ebc3 --- /dev/null +++ b/tests/ft_duiprogressindicator/ft_duiprogressindicator.cpp @@ -0,0 +1,154 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ft_duiprogressindicator.h" +#include +#include +#include "duiapplication.h" +#include "duiprogressindicator.h" + +#define DEBUG + +DuiApplication *app; + +void Ft_DuiProgressIndicator::initTestCase() +{ + static int argc = 1; + static char *argv[1] = { (char *) "./ft_duislider" }; + app = new DuiApplication(argc, argv); +} + +void Ft_DuiProgressIndicator::cleanupTestCase() +{ + delete app; +} + +void Ft_DuiProgressIndicator::init() +{ + m_subject = new DuiProgressIndicator(); +} + +void Ft_DuiProgressIndicator::cleanup() +{ + delete m_subject; +} + +void Ft_DuiProgressIndicator::setValue() +{ + // init + m_subject->setMinimum(2); + m_subject->setMaximum(7); + m_subject->setValue(5); + + // set same value, it shouln't change and it shouldn't emit signal + QSignalSpy spy(m_subject, SIGNAL(valueChanged(int))); + m_subject->setValue(5); + QCOMPARE(spy.count(), 0); + QCOMPARE(m_subject->value(), 5); + + // set different value, it should change and it should emit signal + m_subject->setValue(6); + QCOMPARE(m_subject->value(), 6); + QCOMPARE(spy.count(), 1); + + // set value over the range, it shouldn't change and it shouldn't emit signal + m_subject->setValue(8); + QCOMPARE(m_subject->value(), 6); + QCOMPARE(spy.count(), 1); + + // set value below the range, it shouldn't change and it shouldn't emit signal + m_subject->setValue(1); + QCOMPARE(m_subject->value(), 6); + QCOMPARE(spy.count(), 1); +} + +void Ft_DuiProgressIndicator::setMinimum() +{ + // init + m_subject->setMinimum(2); + m_subject->setMaximum(7); + m_subject->setValue(5); + + // set minimum range so, that the value is not in the range anymore + // it should reset it to minimum value + m_subject->setMinimum(6); + QCOMPARE(m_subject->minimum(), 6); + QCOMPARE(m_subject->value(), m_subject->minimum()); + + // set minimum so, that it's over the maximum + // it should set the maximum so that the range is valid and it should reset the indicator + m_subject->setMinimum(8); + QCOMPARE(m_subject->minimum(), 8); + QCOMPARE(m_subject->maximum(), m_subject->minimum()); + QCOMPARE(m_subject->value(), m_subject->minimum()); +} + +void Ft_DuiProgressIndicator::setMaximum() +{ + // init + m_subject->setMinimum(2); + m_subject->setMaximum(7); + m_subject->setValue(5); + + // set maximum range so, that the value is not in the range anymore + // it should reset it to maximum value + m_subject->setMaximum(4); + QCOMPARE(m_subject->maximum(), 4); + QCOMPARE(m_subject->value(), m_subject->minimum()); + + // set maximum so, that it's above minimum + // it should set the minimum so that the range is valid and it should reset the indicator + m_subject->setMaximum(1); + QCOMPARE(m_subject->maximum(), 1); + QCOMPARE(m_subject->minimum(), m_subject->maximum()); + QCOMPARE(m_subject->value(), m_subject->minimum()); +} + +void Ft_DuiProgressIndicator::unknown() +{ + // enable unknown mode and check that it was enabled + m_subject->setUnknownDuration(true); + QCOMPARE(m_subject->unknownDuration(), true); + + // disable unknown mode and check that it was disable + m_subject->setUnknownDuration(false); + QCOMPARE(m_subject->unknownDuration(), false); +} + +void Ft_DuiProgressIndicator::reset() +{ + // set some values to the progress indicator + m_subject->setMinimum(2); + m_subject->setMaximum(7); + m_subject->setValue(5); + m_subject->setUnknownDuration(true); + + // reset it + m_subject->reset(); + + // check that it was reset properly, value should equal minimum + QCOMPARE(m_subject->minimum(), 2); + QCOMPARE(m_subject->maximum(), 7); + QCOMPARE(m_subject->value(), m_subject->minimum()); + QCOMPARE(m_subject->unknownDuration(), false); +} + + +QTEST_APPLESS_MAIN(Ft_DuiProgressIndicator) + diff --git a/tests/ft_duiprogressindicator/ft_duiprogressindicator.h b/tests/ft_duiprogressindicator/ft_duiprogressindicator.h new file mode 100644 index 000000000..582212880 --- /dev/null +++ b/tests/ft_duiprogressindicator/ft_duiprogressindicator.h @@ -0,0 +1,50 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef FT_DUIPROGRESSINDICATOR_H +#define FT_DUIPROGRESSINDICATOR_H + +#include +#include +#include + +class DuiProgressIndicator; + +class Ft_DuiProgressIndicator : public QObject +{ + Q_OBJECT + +private: + DuiProgressIndicator *m_subject; + +private slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + + void setValue(); + void setMinimum(); + void setMaximum(); + void unknown(); + void reset(); +}; + +#endif + diff --git a/tests/ft_duiprogressindicator/ft_duiprogressindicator.pro b/tests/ft_duiprogressindicator/ft_duiprogressindicator.pro new file mode 100644 index 000000000..fca694e3a --- /dev/null +++ b/tests/ft_duiprogressindicator/ft_duiprogressindicator.pro @@ -0,0 +1,12 @@ +include(../common_top.pri) +TARGET = ft_duiprogressindicator +QT += svg +LIBRARYPATH += $$DUISRCDIR + +SOURCES += \ + ft_duiprogressindicator.cpp \ + +HEADERS += \ + ft_duiprogressindicator.h \ + +include(../common_bot.pri) diff --git a/tests/ft_duiscalableimage/.gitignore b/tests/ft_duiscalableimage/.gitignore new file mode 100644 index 000000000..702c5f0df --- /dev/null +++ b/tests/ft_duiscalableimage/.gitignore @@ -0,0 +1,3 @@ +ft_duiscalableimage +test1.png +test2.png diff --git a/tests/ft_duiscalableimage/ft_duiscalableimage.cpp b/tests/ft_duiscalableimage/ft_duiscalableimage.cpp new file mode 100644 index 000000000..2a0b37347 --- /dev/null +++ b/tests/ft_duiscalableimage/ft_duiscalableimage.cpp @@ -0,0 +1,171 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ft_duiscalableimage.h" +#include "duiapplication.h" +#include +#include +#include +#include + +QVector pixmaps; + +const int BLOCK_SIZE = 10; +QString COLOR_TOPLEFT("#00ff00"); +QString COLOR_TOP("#ff0000"); +QString COLOR_TOPRIGHT("#00ff00"); +QString COLOR_LEFT("#ff0000"); +QString COLOR_CENTER("#0000ff"); +QString COLOR_RIGHT("#ff0000"); +QString COLOR_BOTTOMLEFT("#00ff00"); +QString COLOR_BOTTOM("#ff0000"); +QString COLOR_BOTTOMRIGHT("#00ff00"); + +// Override duitheme pixmap, to provide our own test pixmaps +const QPixmap *createPixmap(const QString &id, const QSize &size) +{ + if (id == "single_image") { + QSize image_size = size.isValid() ? size : QSize(512, 512); + QPixmap *pixmap = new QPixmap(image_size); + + int center_width = image_size.width() - 2 * BLOCK_SIZE; + int center_height = image_size.height() - 2 * BLOCK_SIZE; + + QPainter painter(pixmap); + painter.setRenderHint(QPainter::SmoothPixmapTransform, false); + painter.fillRect(0, 0, BLOCK_SIZE, BLOCK_SIZE, QColor(COLOR_TOPLEFT)); + painter.fillRect(BLOCK_SIZE, 0, center_width, BLOCK_SIZE, QColor(COLOR_TOP)); + painter.fillRect(BLOCK_SIZE + center_width, 0, BLOCK_SIZE, BLOCK_SIZE, QColor(COLOR_TOPRIGHT)); + painter.fillRect(0, BLOCK_SIZE, BLOCK_SIZE, center_height, QColor(COLOR_LEFT)); + painter.fillRect(BLOCK_SIZE, BLOCK_SIZE, center_width, center_height, QColor(COLOR_CENTER)); + painter.fillRect(BLOCK_SIZE + center_width, BLOCK_SIZE, BLOCK_SIZE, center_height, QColor(COLOR_RIGHT)); + painter.fillRect(0, BLOCK_SIZE + center_height, BLOCK_SIZE, BLOCK_SIZE, QColor(COLOR_BOTTOMLEFT)); + painter.fillRect(BLOCK_SIZE, BLOCK_SIZE + center_height, center_width, BLOCK_SIZE, QColor(COLOR_BOTTOM)); + painter.fillRect(BLOCK_SIZE + center_width, BLOCK_SIZE + center_height, BLOCK_SIZE, BLOCK_SIZE, QColor(COLOR_BOTTOMRIGHT)); + + // debug + //pixmap->save("test2.png"); + return pixmap; + } else { + QPixmap *pixmap = new QPixmap(size.isValid() ? size : QSize(BLOCK_SIZE, BLOCK_SIZE)); + pixmap->fill(QColor(id)); + pixmaps.push_back(pixmap); + return pixmap; + } +} + +Ft_DuiScalableImage::Ft_DuiScalableImage() +{ +} + +void Ft_DuiScalableImage::init() +{ + m_subject = new DuiScalableImage(); +} + +void Ft_DuiScalableImage::cleanup() +{ + for (int i = 0; i < pixmaps.size(); i++) { + delete pixmaps[i]; + } + pixmaps.clear(); + + delete m_subject; +} + +DuiApplication *app; + +void Ft_DuiScalableImage::initTestCase() +{ + static int argc = 1; + static char *app_name[1] = { (char *) "./Ft_DuiScalableImage" }; + app = new DuiApplication(argc, app_name); +} + +void Ft_DuiScalableImage::cleanupTestCase() +{ + delete app; +} + +bool isImageBlockColor(const QImage &image, const QRect &rect, const QString &colorid) +{ + QColor color(colorid); + QImage copy = image.copy(rect); + for (int y = 0; y < copy.height(); y++) { + for (int x = 0; x < copy.width(); x++) { + if (copy.pixel(x, y) != color.rgb()) { + return false; + } + } + } + + return true; +} + +void Ft_DuiScalableImage::test_construction() +{ + // topleft, topright, bottomleft, bottomright, top, left, bottom, right, center + const QPixmap *pm = createPixmap("single_image", QSize(-1, -1)); + + m_subject->setPixmap(pm); + m_subject->setBorders(BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE); + + // adjust these to draw different size images to different location + QSize image_size = QSize(512, 512); + + QPoint paint_offset = QPoint(6, 6); + QSize paint_size = QSize(256, 256); + + QPixmap canvas(image_size); + canvas.fill(Qt::black); + + QPainter painter(&canvas); + painter.setRenderHint(QPainter::SmoothPixmapTransform, false); + + // draw from image-offset to the edge of the canvas + m_subject->draw(paint_offset, paint_size, &painter); + // save, debug + //canvas.save("/tmp/test.png"); + + // check that the image looks proper, + // clip only the part that should contain the drawn data + QRect fillRegion(paint_offset, paint_size); + QImage image = canvas.toImage().copy(fillRegion); + + // calculate the size for the center block + int center_width = paint_size.width() - 2 * BLOCK_SIZE; + int center_height = paint_size.height() - 2 * BLOCK_SIZE; + + // corners + QCOMPARE(isImageBlockColor(image, QRect(0, 0, BLOCK_SIZE, BLOCK_SIZE), COLOR_TOPLEFT), true); + QCOMPARE(isImageBlockColor(image, QRect(BLOCK_SIZE + center_width, 0, BLOCK_SIZE, BLOCK_SIZE), COLOR_TOPRIGHT), true); + QCOMPARE(isImageBlockColor(image, QRect(0, BLOCK_SIZE + center_height, BLOCK_SIZE, BLOCK_SIZE), COLOR_BOTTOMLEFT), true); + QCOMPARE(isImageBlockColor(image, QRect(BLOCK_SIZE + center_width, BLOCK_SIZE + center_height, BLOCK_SIZE, BLOCK_SIZE), COLOR_BOTTOMRIGHT), true); + + // edges + QCOMPARE(isImageBlockColor(image, QRect(BLOCK_SIZE, 0, center_width, BLOCK_SIZE), COLOR_TOP), true); + QCOMPARE(isImageBlockColor(image, QRect(0, BLOCK_SIZE, BLOCK_SIZE, center_height), COLOR_LEFT), true); + QCOMPARE(isImageBlockColor(image, QRect(BLOCK_SIZE, BLOCK_SIZE + center_height, center_width, BLOCK_SIZE), COLOR_BOTTOM), true); + QCOMPARE(isImageBlockColor(image, QRect(BLOCK_SIZE + center_width, BLOCK_SIZE, BLOCK_SIZE, center_height), COLOR_RIGHT), true); + + // center + QCOMPARE(isImageBlockColor(image, QRect(BLOCK_SIZE, BLOCK_SIZE, center_width, center_height), COLOR_CENTER), true); +} + +QTEST_APPLESS_MAIN(Ft_DuiScalableImage) diff --git a/tests/ft_duiscalableimage/ft_duiscalableimage.h b/tests/ft_duiscalableimage/ft_duiscalableimage.h new file mode 100644 index 000000000..7423a80ec --- /dev/null +++ b/tests/ft_duiscalableimage/ft_duiscalableimage.h @@ -0,0 +1,46 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef FT_DUISCALABLEIMAGE_H +#define FT_DUISCALABLEIMAGE_H + +#include +#include +#include + +class Ft_DuiScalableImage : public QObject +{ + Q_OBJECT +public: + Ft_DuiScalableImage(); + +private slots: + void init(); + void cleanup(); + void initTestCase(); + void cleanupTestCase(); + void test_construction(); + +private: + + class DuiScalableImage *m_subject; +}; + +#endif + diff --git a/tests/ft_duiscalableimage/ft_duiscalableimage.pro b/tests/ft_duiscalableimage/ft_duiscalableimage.pro new file mode 100644 index 000000000..d01002444 --- /dev/null +++ b/tests/ft_duiscalableimage/ft_duiscalableimage.pro @@ -0,0 +1,14 @@ +include(../common_top.pri) +TARGET = ft_duiscalableimage +QT += dbus svg network +LIBRARYPATH += $$DUISRCDIR + +SOURCES += \ + ft_duiscalableimage.cpp \ + +HEADERS += \ + ft_duiscalableimage.h \ + +QMAKE_CLEAN += test2.png + +include(../common_bot.pri) diff --git a/tests/ft_duiscenemanager/.gitignore b/tests/ft_duiscenemanager/.gitignore new file mode 100644 index 000000000..297e93ceb --- /dev/null +++ b/tests/ft_duiscenemanager/.gitignore @@ -0,0 +1 @@ +ft_duiscenemanager diff --git a/tests/ft_duiscenemanager/ft_duiscenemanager.cpp b/tests/ft_duiscenemanager/ft_duiscenemanager.cpp new file mode 100644 index 000000000..509bd4aa6 --- /dev/null +++ b/tests/ft_duiscenemanager/ft_duiscenemanager.cpp @@ -0,0 +1,60 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ft_duiscenemanager.h" +#include +#include +#include +#include +#include + +DuiApplication *app; +DuiApplicationWindow *w; + +void Ft_DuiSceneManager::init() +{ + m_subject = DuiApplication::activeApplicationWindow()->sceneManager(); + QVERIFY(m_subject != NULL); +} + +void Ft_DuiSceneManager::cleanup() +{ +} + +void Ft_DuiSceneManager::initTestCase() +{ + static int argc = 1; + static char *argv[1] = { (char *) "./ft_duiscenemanager" }; + app = new DuiApplication(argc, argv); + w = new DuiApplicationWindow(); +} + +void Ft_DuiSceneManager::cleanupTestCase() +{ + delete w; + delete app; +} + +void Ft_DuiSceneManager::test_scene() +{ + DuiScene *scene = m_subject->scene(); + QVERIFY(scene != 0); +} + +QTEST_APPLESS_MAIN(Ft_DuiSceneManager) diff --git a/tests/ft_duiscenemanager/ft_duiscenemanager.h b/tests/ft_duiscenemanager/ft_duiscenemanager.h new file mode 100644 index 000000000..f17876284 --- /dev/null +++ b/tests/ft_duiscenemanager/ft_duiscenemanager.h @@ -0,0 +1,46 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef FT_DUIDIALOG_H +#define FT_DUIDIALOG_H + +#include +#include +#include + +class DuiSceneManager; + +class Ft_DuiSceneManager : public QObject +{ + Q_OBJECT + +private slots: + void init(); + void cleanup(); + void initTestCase(); + void cleanupTestCase(); + + void test_scene(); +private: + + DuiSceneManager *m_subject; +}; + +#endif + diff --git a/tests/ft_duiscenemanager/ft_duiscenemanager.pro b/tests/ft_duiscenemanager/ft_duiscenemanager.pro new file mode 100644 index 000000000..787ff7038 --- /dev/null +++ b/tests/ft_duiscenemanager/ft_duiscenemanager.pro @@ -0,0 +1,12 @@ +include(../common_top.pri) +TARGET = ft_duiscenemanager +QT += dbus svg network +LIBRARYPATH += $$DUISRCDIR + +SOURCES += \ + ft_duiscenemanager.cpp \ + +HEADERS += \ + ft_duiscenemanager.h \ + +include(../common_bot.pri) diff --git a/tests/ft_duiservicefwgen/.gitignore b/tests/ft_duiservicefwgen/.gitignore new file mode 100644 index 000000000..d6abca12b --- /dev/null +++ b/tests/ft_duiservicefwgen/.gitignore @@ -0,0 +1,13 @@ +ft_duiservicefwgen +fakegalleryinterfaceproxy.h +fakegalleryinterfaceproxy.cpp +fakegalleryinterface.h +fakegalleryinterface.cpp +fakegalleryinterfaceadaptor.h +fakegalleryinterfaceadaptor.cpp +fakegalleryinterfacedocproxy.h +fakegalleryinterfacedocproxy.cpp +fakegalleryinterfacedoc.h +fakegalleryinterfacedoc.cpp +fakegalleryinterfacedocadaptor.h +fakegalleryinterfacedocadaptor.cpp diff --git a/tests/ft_duiservicefwgen/com.nokia.FtDuiServiceFwGen1.xml b/tests/ft_duiservicefwgen/com.nokia.FtDuiServiceFwGen1.xml new file mode 100644 index 000000000..d85a79248 --- /dev/null +++ b/tests/ft_duiservicefwgen/com.nokia.FtDuiServiceFwGen1.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/ft_duiservicefwgen/com.nokia.FtDuiServiceFwGen2.xml b/tests/ft_duiservicefwgen/com.nokia.FtDuiServiceFwGen2.xml new file mode 100644 index 000000000..ce84dcfe0 --- /dev/null +++ b/tests/ft_duiservicefwgen/com.nokia.FtDuiServiceFwGen2.xml @@ -0,0 +1,59 @@ + + + + + + /* main documentation for the interface + main documentation for the interface2 */ + + + + /* documentation for showPage() method */ + /* documentation for showPage() method2 */ + + + + + + + + + /* documentation for showImage(0) method */ + /* documentation for showImage(0) method2 */ + + + + + + + + + + /* documentation for showImage(1) method */ + /* documentation for showImage(1) method2 */ + + + + + + + + /* documentation for showGridWithCapturedContent() method */ + /* documentation for showGridWithCapturedContent() method2 */ + + + + + + + + /* documentation for showSettings() method */ + /* documentation for showSettings() method2 */ + + + + + + + diff --git a/tests/ft_duiservicefwgen/ft_duiservicefwgen.cpp b/tests/ft_duiservicefwgen/ft_duiservicefwgen.cpp new file mode 100644 index 000000000..790cef2a4 --- /dev/null +++ b/tests/ft_duiservicefwgen/ft_duiservicefwgen.cpp @@ -0,0 +1,228 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ft_duiservicefwgen.h" + +#include +#include +#include +#include +#include +#include + +namespace +{ + const QString scriptName("dui-servicefwgen"); + const QString qdbusxml2cpp("/usr/bin/qdbusxml2cpp"); +}; + +void Ft_DuiServiceFwGen::runDuiServiceFwGen(const QStringList ¶ms) +{ + QProcess duiServiceFwGen; + duiServiceFwGen.setWorkingDirectory(cwd); + + QString devTreePath(cwd + "/../../tools/" + scriptName); + QString fullPathToScript(QFileInfo(devTreePath).canonicalFilePath()); + + if (!QFileInfo(fullPathToScript).exists()) { + qDebug() << devTreePath << "does not exist; trying to use installed one"; + fullPathToScript = "/usr/bin/" + scriptName; + if (!QFileInfo(fullPathToScript).exists()) { + qDebug() << fullPathToScript << "does not exist"; + skipTests = true; + } + } + + qDebug() << "running " << fullPathToScript + " " + params.join(" "); + duiServiceFwGen.start(fullPathToScript, params); + if (!duiServiceFwGen.waitForStarted()) { + qCritical() << "starting failed:" << duiServiceFwGen.error(); + skipTests = true; + } + if (!duiServiceFwGen.waitForFinished()) { + qCritical() << "did not finish"; + skipTests = true; + } +} + +void Ft_DuiServiceFwGen::initTestCase() +{ + skipTests = false; + bool qdbusxml2cppNotExist = !QFileInfo(qdbusxml2cpp).exists(); + bool scriptNotExist = !QFileInfo("/usr/bin/" + scriptName).exists(); + + if (qdbusxml2cppNotExist) { + qCritical() << qdbusxml2cpp << "is missing."; + skipTests = true; + return; + } + + if (scriptNotExist) { + qCritical() << "/usr/bin/" + scriptName << "is missing."; + skipTests = true; + return; + } + + // had big trouble getting correct application path on arm + // so don't delete this lightly + QString argv0 = QCoreApplication::arguments().at(0); + bool absolutePath = argv0.split("/").at(0).isEmpty(); + if (absolutePath) { + cwd = QFileInfo(argv0).canonicalPath(); + } else { + // relative path + QString pwdEnv = QProcess::systemEnvironment().filter(QRegExp("^PWD=")).at(0).split("=").at(1); + qDebug() << "pwdEnv=" << pwdEnv; + qDebug() << "argv0=" << argv0; + cwd = QFileInfo(pwdEnv + "/" + argv0).canonicalPath(); + } + qDebug() << "cwd=" << cwd; + + // get list of xml files in the current working directory + QStringList xmlFiles(QDir(cwd).entryList(QStringList("com.nokia.FtDuiServiceFwGen[0-9].xml"))); + + if (xmlFiles.size() == 0) { + qCritical() << "Could not find any xml files."; + } + + // convert them to interface names + QStringList interfaces; + for (int i = 0; i < xmlFiles.size(); ++i) { + QString interfaceName = QFileInfo(xmlFiles.at(i)).completeBaseName();; + interfaces << cwd + "/" + interfaceName; + } + + // generate proxy and adaptor files + for (int i = 0; i < interfaces.size(); ++i) { + QString thisInterface = interfaces.at(i); + runDuiServiceFwGen(QStringList() << "-p" << thisInterface); + runDuiServiceFwGen(QStringList() << "-a" << thisInterface); + + QString lowerBase = thisInterface.split(".").last().toLower(); + + QString adaptorCpp = cwd + "/" + lowerBase + "adaptor.cpp"; + QString adaptorH = cwd + "/" + lowerBase + "adaptor.h"; + QString proxyCpp = cwd + "/" + lowerBase + "proxy.cpp"; + QString proxyH = cwd + "/" + lowerBase + "proxy.h"; + QString wrapperCpp = cwd + "/" + lowerBase + ".cpp"; + QString wrapperH = cwd + "/" + lowerBase + ".h"; + + filesToCompare + << adaptorCpp + << adaptorH + << proxyCpp + << proxyH + << wrapperCpp + << wrapperH; + } +} + +void Ft_DuiServiceFwGen::cleanupTestCase() +{ +} + +void Ft_DuiServiceFwGen::compareFiles_data() +{ + QTest::addColumn("filename"); + + for (int i = 0; i < filesToCompare.size(); ++i) { + QString thisFilename = filesToCompare.at(i); + QTest::newRow(qPrintable(thisFilename)) << thisFilename; + } +} + +void Ft_DuiServiceFwGen::compareFiles() +{ + if (skipTests) { + QSKIP("Something wrong with the environment - skipping", SkipAll); + } else { + QFETCH(QString, filename); + QString correctFilename(filename + ".correct"); + + if (!filesAreTheSame(filename, correctFilename)) { + QStringList errorMessage; + errorMessage + << "These files differ :" + << filename + << correctFilename; + QWARN(qPrintable(errorMessage.join(" "))); + QFAIL("Verify new file contents against correct file and if they are correct, overwrite the correct file with the new one."); + } else { + QString thisFilename(filename); + QFile thisFile(thisFilename); + if (!thisFile.remove()) { + qWarning() << "Could not remove" << thisFilename; + } + } + } +} + +bool Ft_DuiServiceFwGen::filesAreTheSame(const QString &filename, const QString &correctFilename) const +{ + bool filesAreTheSame = true; + + QFile newFile(filename); + if (!newFile.open(QIODevice::ReadOnly | QIODevice::Text)) { + qDebug() << "Could not open" << filename; + return false; + } + QTextStream newIn(&newFile); + + QFile correctFile(correctFilename); + if (!correctFile.open(QIODevice::ReadOnly | QIODevice::Text)) { + qDebug() << "Could not open" << filename; + return false; + } + QTextStream correctIn(&correctFile); + + do { + if (newIn.atEnd() || correctIn.atEnd()) { + bool oneFileFinishedBeforeOther = (!newIn.atEnd() || !correctIn.atEnd()); + if (oneFileFinishedBeforeOther) { + filesAreTheSame = false; + } + break; + } + + QString newLine = newIn.readLine(); + QString correctLine = correctIn.readLine(); + + // skip exceptional lines + QString headerGuard(QFileInfo(filename).fileName().toUpper().replace(".", "_")); + bool lineIsExceptional = + newLine.contains(headerGuard) || + newLine.contains("qdbusxml2cpp") || + newLine.contains("ft_duiservicefwgen") || + newLine.contains(scriptName); + if (lineIsExceptional) { + continue; + } + + bool linesAreIdentical = (newLine == correctLine); + filesAreTheSame = linesAreIdentical; + } while (filesAreTheSame); + + correctFile.close(); + newFile.close(); + + return filesAreTheSame; +} + + +QTEST_MAIN(Ft_DuiServiceFwGen) diff --git a/tests/ft_duiservicefwgen/ft_duiservicefwgen.h b/tests/ft_duiservicefwgen/ft_duiservicefwgen.h new file mode 100644 index 000000000..63cd8eab6 --- /dev/null +++ b/tests/ft_duiservicefwgen/ft_duiservicefwgen.h @@ -0,0 +1,48 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef FT_DUISERVICEFWGEN_H +#define FT_DUISERVICEFWGEN_H + +#include +#include + +class Ft_DuiServiceFwGen : public QObject +{ + Q_OBJECT +public: + +private slots: + void initTestCase(); + void cleanupTestCase(); + + void compareFiles_data(); + void compareFiles(); + +private: + void runDuiServiceFwGen(const QStringList ¶ms); + bool filesAreTheSame(const QString &filename, const QString &correctFilename) const; + + QStringList filesToCompare; + QString cwd; + bool skipTests; +}; + +#endif + diff --git a/tests/ft_duiservicefwgen/ft_duiservicefwgen.pro b/tests/ft_duiservicefwgen/ft_duiservicefwgen.pro new file mode 100644 index 000000000..338b1907b --- /dev/null +++ b/tests/ft_duiservicefwgen/ft_duiservicefwgen.pro @@ -0,0 +1,43 @@ +include(../common_top.pri) +LIBS = +QT -= gui + +TARGET = ft_duiservicefwgen + +SOURCES += \ + ft_duiservicefwgen.cpp \ + +HEADERS += \ + ft_duiservicefwgen.h \ + +QMAKE_CLEAN += \ + ftduiservicefwgen1adaptor.cpp \ + ftduiservicefwgen1adaptor.h \ + ftduiservicefwgen1.cpp \ + ftduiservicefwgen1.h \ + ftduiservicefwgen1proxy.cpp \ + ftduiservicefwgen1proxy.h \ + ftduiservicefwgen2adaptor.cpp \ + ftduiservicefwgen2adaptor.h \ + ftduiservicefwgen2.cpp \ + ftduiservicefwgen2.h \ + ftduiservicefwgen2proxy.cpp \ + ftduiservicefwgen2proxy.h \ + +support_files.files += \ + com.nokia.FtDuiServiceFwGen1.xml \ + com.nokia.FtDuiServiceFwGen2.xml \ + ftduiservicefwgen1adaptor.cpp.correct \ + ftduiservicefwgen1adaptor.h.correct \ + ftduiservicefwgen1.cpp.correct \ + ftduiservicefwgen1.h.correct \ + ftduiservicefwgen1proxy.cpp.correct \ + ftduiservicefwgen1proxy.h.correct \ + ftduiservicefwgen2adaptor.cpp.correct \ + ftduiservicefwgen2adaptor.h.correct \ + ftduiservicefwgen2.cpp.correct \ + ftduiservicefwgen2.h.correct \ + ftduiservicefwgen2proxy.cpp.correct \ + ftduiservicefwgen2proxy.h.correct \ + +include(../common_bot.pri) diff --git a/tests/ft_duiservicefwgen/ftduiservicefwgen1.cpp.correct b/tests/ft_duiservicefwgen/ftduiservicefwgen1.cpp.correct new file mode 100644 index 000000000..fd2c545f1 --- /dev/null +++ b/tests/ft_duiservicefwgen/ftduiservicefwgen1.cpp.correct @@ -0,0 +1,66 @@ +/* + * automatically generated with the command line : + * /home/davidmaxwaterman/z/hi386/libdui/tools/dui-servicefwgen -p /home/davidmaxwaterman/z/hi386/libdui/tests/ft_duiservicefwgen/com.nokia.FtDuiServiceFwGen1 + */ + +#include "ftduiservicefwgen1.h" + +bool FtDuiServiceFwGen1::showGridWithCapturedContent( int limit ) +{ + return qobject_cast(interfaceProxy)->showGridWithCapturedContent( limit ).value(); +} + +void FtDuiServiceFwGen1::showImage( const QString &uri, const QStringList &uriList ) +{ + static_cast(interfaceProxy)->showImage( uri, uriList ); +} + +bool FtDuiServiceFwGen1::showImage( const QString &uri, const QString &playlistName, const QString &defaultBackPage ) +{ + return qobject_cast(interfaceProxy)->showImage( uri, playlistName, defaultBackPage ).value(); +} + +bool FtDuiServiceFwGen1::showPage( const QString &targetPage, const QString &previousPage ) +{ + return qobject_cast(interfaceProxy)->showPage( targetPage, previousPage ).value(); +} + +bool FtDuiServiceFwGen1::showSettings( ) +{ + return qobject_cast(interfaceProxy)->showSettings( ).value(); +} + +FtDuiServiceFwGen1::FtDuiServiceFwGen1( const QString& preferredService, QObject* parent ) + : DuiServiceFwBaseIf( FtDuiServiceFwGen1Proxy::staticInterfaceName(), parent ) +{ + // Resolve the provider service name + service = resolveServiceName( interface, preferredService ); + + bool serviceNameInvalid = service.contains( " " ); // "not provided" - when the service wouldn't run + if ( serviceNameInvalid ) { + service.clear(); + } + + if (!service.isEmpty()) { + // Construct the D-Bus proxy + interfaceProxy = new FtDuiServiceFwGen1Proxy( service, "/", QDBusConnection::sessionBus(), this ); + // allConnectSignals go here (empty block if none) + + } +} + +void FtDuiServiceFwGen1::setService(const QString & service) +{ + if (service.isEmpty()) return; + + this->service = service; + + if ( interfaceProxy ) { + delete interfaceProxy; + interfaceProxy = 0; + } + interfaceProxy = new FtDuiServiceFwGen1Proxy( service, "/", QDBusConnection::sessionBus(), this ); + { + + } +} diff --git a/tests/ft_duiservicefwgen/ftduiservicefwgen1.h.correct b/tests/ft_duiservicefwgen/ftduiservicefwgen1.h.correct new file mode 100644 index 000000000..f0b4ac487 --- /dev/null +++ b/tests/ft_duiservicefwgen/ftduiservicefwgen1.h.correct @@ -0,0 +1,46 @@ +#ifndef FTDUISERVICEFWGEN1_H +#define FTDUISERVICEFWGEN1_H + +/* + * automatically generated with the command line : + * /home/davidmaxwaterman/z/hi386/libdui/tools/dui-servicefwgen -p /home/davidmaxwaterman/z/hi386/libdui/tests/ft_duiservicefwgen/com.nokia.FtDuiServiceFwGen1 + */ + +#include + +#include +#include + +class FtDuiServiceFwGen1 : public DuiServiceFwBaseIf +{ +Q_OBJECT + +public: + bool showGridWithCapturedContent( int limit ); + void showImage( const QString &uri, const QStringList &uriList ); + bool showImage( const QString &uri, const QString &playlistName, const QString &defaultBackPage ); + bool showPage( const QString &targetPage, const QString &previousPage ); + bool showSettings( ); + +public: + /*! + * @brief Constructs a base interface + * @param preferredService, define the preferred service provider. Leave + empty if no preferred provider. In most cases, this should be left + empty. + * @param parent Parent object + */ + + FtDuiServiceFwGen1( const QString& preferredService = "", QObject* parent = 0 ); + + /*! + * @brief Set the service name + * @param service Name of the desired service + */ + + void setService(const QString & service); +Q_SIGNALS: + + +}; +#endif diff --git a/tests/ft_duiservicefwgen/ftduiservicefwgen1adaptor.cpp.correct b/tests/ft_duiservicefwgen/ftduiservicefwgen1adaptor.cpp.correct new file mode 100644 index 000000000..780963fed --- /dev/null +++ b/tests/ft_duiservicefwgen/ftduiservicefwgen1adaptor.cpp.correct @@ -0,0 +1,146 @@ +/* + * This file was generated by qdbusxml2cpp version 0.7 + * Command line was: qdbusxml2cpp -c FtDuiServiceFwGen1Adaptor -a ftduiservicefwgen1adaptor com.nokia.FtDuiServiceFwGen1.xml + * + * qdbusxml2cpp is Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#include "ftduiservicefwgen1adaptor.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +/* + * Implementation of adaptor class FtDuiServiceFwGen1Adaptor + */ + +FtDuiServiceFwGen1Adaptor::FtDuiServiceFwGen1Adaptor(QObject *parent) + : QDBusAbstractAdaptor(parent), + backServiceName(), + windowId(-1) +{ + // constructor + setAutoRelaySignals(true); +} + +FtDuiServiceFwGen1Adaptor::~FtDuiServiceFwGen1Adaptor() +{ + // destructor +} + +bool FtDuiServiceFwGen1Adaptor::showGridWithCapturedContent(int limit) +{ + // handle method call com.nokia.fakegalleryserviceinterface.showGridWithCapturedContent + bool out0; + QMetaObject::invokeMethod(parent(), "showGridWithCapturedContent", Q_RETURN_ARG(bool, out0), Q_ARG(int, limit)); + return out0; +} + +void FtDuiServiceFwGen1Adaptor::showImage(const QString &backServiceName, const QString &windowTitle, const uint windowId, const QString &uri, const QStringList &uriList) +{ + this->windowId = windowId; + this->backServiceName = backServiceName; + + // handle method call com.nokia.fakegalleryserviceinterface.showImage + QMetaObject::invokeMethod(parent(), "showImage", Q_ARG(QString, uri), Q_ARG(QStringList, uriList)); + + DuiApplication::instance()->activeWindow()->setWindowTitle( windowTitle ); + DuiApplicationWindow *appWindow = DuiApplication::activeApplicationWindow(); + if (appWindow != 0) { + appWindow->currentPage()->setEscapeButtonMode( DuiEscapeButtonPanelModel::BackMode ); + // connect to the back button - assumes the above 'showImage' opens a + // new window and so the window referred to below is already the top one + connect(appWindow->currentPage(), SIGNAL(backButtonClicked()), + this, SLOT(goBack())); + } + + // update the X server + { + XPropertyEvent p; + p.send_event = True; + p.display = QX11Info::display(); + p.type = PropertyNotify; + p.window = RootWindow(p.display, 0); + p.atom = XInternAtom(p.display, "_NET_CLIENT_LIST", False); + p.state = PropertyNewValue; + p.time = CurrentTime; + XSendEvent(p.display, p.window, False, PropertyChangeMask, + (XEvent*)&p); + + XSync(QX11Info::display(), False); + } + +} + +bool FtDuiServiceFwGen1Adaptor::showImage(const QString &uri, const QString &playlistName, const QString &defaultBackPage) +{ + // handle method call com.nokia.fakegalleryserviceinterface.showImage + bool out0; + QMetaObject::invokeMethod(parent(), "showImage", Q_RETURN_ARG(bool, out0), Q_ARG(QString, uri), Q_ARG(QString, playlistName), Q_ARG(QString, defaultBackPage)); + return out0; +} + +bool FtDuiServiceFwGen1Adaptor::showPage(const QString &targetPage, const QString &previousPage) +{ + // handle method call com.nokia.fakegalleryserviceinterface.showPage + bool out0; + QMetaObject::invokeMethod(parent(), "showPage", Q_RETURN_ARG(bool, out0), Q_ARG(QString, targetPage), Q_ARG(QString, previousPage)); + return out0; +} + +bool FtDuiServiceFwGen1Adaptor::showSettings() +{ + // handle method call com.nokia.fakegalleryserviceinterface.showSettings + bool out0; + QMetaObject::invokeMethod(parent(), "showSettings", Q_RETURN_ARG(bool, out0)); + return out0; +} + +void FtDuiServiceFwGen1Adaptor::goBack() +{ + qDebug() << __PRETTY_FUNCTION__; + + bool backServiceRegistered = ( windowId != -1 ); + if ( backServiceRegistered ) { + DuiApplicationIfProxy duiApplicationIfProxy(backServiceName, this); + + if (duiApplicationIfProxy.connection().isConnected()) { + qDebug() << "Launching " << backServiceName; + duiApplicationIfProxy.launch(); + } else { + qWarning() << "Could not launch" << backServiceName; + qWarning() << "DBus not connected?"; + } + + // unhide the chain parent's window + { + // Tell the window to not to be shown in the switcher + XDeleteProperty(QX11Info::display(), windowId, XInternAtom(QX11Info::display(), "_NET_WM_STATE", False)); + XSync(QX11Info::display(), False); + } + + qWarning() << "quitting - bye bye"; + QTimer::singleShot( 0, QApplication::instance(), SLOT( quit() ) ); + } else { + qWarning() << "backService is not registered: not going back"; + } +} diff --git a/tests/ft_duiservicefwgen/ftduiservicefwgen1adaptor.h.correct b/tests/ft_duiservicefwgen/ftduiservicefwgen1adaptor.h.correct new file mode 100644 index 000000000..0d1c8d8c9 --- /dev/null +++ b/tests/ft_duiservicefwgen/ftduiservicefwgen1adaptor.h.correct @@ -0,0 +1,80 @@ +/* + * This file was generated by qdbusxml2cpp version 0.7 + * Command line was: qdbusxml2cpp -c FtDuiServiceFwGen1Adaptor -a ftduiservicefwgen1adaptor com.nokia.FtDuiServiceFwGen1-11378.xml + * + * qdbusxml2cpp is Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#ifndef FTDUISERVICEFWGEN1ADAPTOR_H_1264070554 +#define FTDUISERVICEFWGEN1ADAPTOR_H_1264070554 + +#include +#include +class QByteArray; +template class QList; +template class QMap; +class QString; +class QStringList; +class QVariant; + +/* + * Adaptor class for interface com.nokia.fakegalleryserviceinterface + */ +class FtDuiServiceFwGen1Adaptor: public QDBusAbstractAdaptor +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "com.nokia.fakegalleryserviceinterface") + Q_CLASSINFO("D-Bus Introspection", "" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" + "") +public: + FtDuiServiceFwGen1Adaptor(QObject *parent); + virtual ~FtDuiServiceFwGen1Adaptor(); + +public: // PROPERTIES +public Q_SLOTS: // METHODS + bool showGridWithCapturedContent(int limit); + Q_NOREPLY void showImage(const QString &backServiceName, const QString &windowTitle, const uint windowId, const QString &uri, const QStringList &uriList); + bool showImage(const QString &uri, const QString &playlistName, const QString &defaultBackPage); + bool showPage(const QString &targetPage, const QString &previousPage); + bool showSettings(); + void goBack(); + +private: + QString backServiceName; + int windowId; + +Q_SIGNALS: // SIGNALS +}; + +#endif diff --git a/tests/ft_duiservicefwgen/ftduiservicefwgen1proxy.cpp.correct b/tests/ft_duiservicefwgen/ftduiservicefwgen1proxy.cpp.correct new file mode 100644 index 000000000..84b79a9e5 --- /dev/null +++ b/tests/ft_duiservicefwgen/ftduiservicefwgen1proxy.cpp.correct @@ -0,0 +1,26 @@ +/* + * This file was generated by qdbusxml2cpp version 0.7 + * Command line was: qdbusxml2cpp -c FtDuiServiceFwGen1Proxy -p ftduiservicefwgen1proxy com.nokia.FtDuiServiceFwGen1-9399.xml + * + * qdbusxml2cpp is Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#include "ftduiservicefwgen1proxy.h" + +/* + * Implementation of interface class FtDuiServiceFwGen1Proxy + */ + +FtDuiServiceFwGen1Proxy::FtDuiServiceFwGen1Proxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) + : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) +{ +} + +FtDuiServiceFwGen1Proxy::~FtDuiServiceFwGen1Proxy() +{ +} + diff --git a/tests/ft_duiservicefwgen/ftduiservicefwgen1proxy.h.correct b/tests/ft_duiservicefwgen/ftduiservicefwgen1proxy.h.correct new file mode 100644 index 000000000..be2150315 --- /dev/null +++ b/tests/ft_duiservicefwgen/ftduiservicefwgen1proxy.h.correct @@ -0,0 +1,111 @@ +/* + * This file was generated by qdbusxml2cpp version 0.7 + * Command line was: qdbusxml2cpp -c FtDuiServiceFwGen1Proxy -p ftduiservicefwgen1proxy com.nokia.FtDuiServiceFwGen1.xml + * + * qdbusxml2cpp is Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#ifndef FTDUISERVICEFWGEN1PROXY_H_1264070554 +#define FTDUISERVICEFWGEN1PROXY_H_1264070554 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Proxy class for interface com.nokia.fakegalleryserviceinterface + */ +class FtDuiServiceFwGen1Proxy: public QDBusAbstractInterface +{ + Q_OBJECT +public: + static inline const char *staticInterfaceName() + { return "com.nokia.fakegalleryserviceinterface"; } + +public: + FtDuiServiceFwGen1Proxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0); + + ~FtDuiServiceFwGen1Proxy(); + +public Q_SLOTS: // METHODS + inline QDBusPendingReply showGridWithCapturedContent(int limit) + { + QList argumentList; + argumentList << qVariantFromValue(limit); + return asyncCallWithArgumentList(QLatin1String("showGridWithCapturedContent"), argumentList); + } + + inline QDBusPendingReply<> showImage(const QString &uri, const QStringList &uriList) + { + Qt::HANDLE windowId = DuiApplication::instance()->activeWindow()->winId(); + QString windowTitle = DuiApplication::instance()->activeWindow()->windowTitle(); + QString goBackServiceName = DuiComponentData::instance()->serviceName(); + + QList argumentList; + argumentList << qVariantFromValue(goBackServiceName); + argumentList << qVariantFromValue(windowTitle); + argumentList << qVariantFromValue((uint)windowId); + argumentList << qVariantFromValue(uri) << qVariantFromValue(uriList); + + // hide this window + { + // Tell the window to not to be shown in the switcher + Atom skipTaskbarAtom = XInternAtom(QX11Info::display(), "_NET_WM_STATE_SKIP_TASKBAR", False); + + Atom netWmStateAtom = XInternAtom(QX11Info::display(), "_NET_WM_STATE", False); + QVector atoms; + atoms.append(skipTaskbarAtom); + XChangeProperty(QX11Info::display(), windowId, netWmStateAtom, XA_ATOM, 32, PropModeReplace, (unsigned char *)atoms.data(), atoms.count()); + XSync(QX11Info::display(), False); + } + + return asyncCallWithArgumentList(QLatin1String("showImage"), argumentList); + } + + inline QDBusPendingReply showImage(const QString &uri, const QString &playlistName, const QString &defaultBackPage) + { + QList argumentList; + argumentList << qVariantFromValue(uri) << qVariantFromValue(playlistName) << qVariantFromValue(defaultBackPage); + return asyncCallWithArgumentList(QLatin1String("showImage"), argumentList); + } + + inline QDBusPendingReply showPage(const QString &targetPage, const QString &previousPage) + { + QList argumentList; + argumentList << qVariantFromValue(targetPage) << qVariantFromValue(previousPage); + return asyncCallWithArgumentList(QLatin1String("showPage"), argumentList); + } + + inline QDBusPendingReply showSettings() + { + QList argumentList; + return asyncCallWithArgumentList(QLatin1String("showSettings"), argumentList); + } + +Q_SIGNALS: // SIGNALS +}; + +namespace com { + namespace nokia { + typedef ::FtDuiServiceFwGen1Proxy fakegalleryserviceinterface; + } +} +#endif diff --git a/tests/ft_duiservicefwgen/ftduiservicefwgen2.cpp.correct b/tests/ft_duiservicefwgen/ftduiservicefwgen2.cpp.correct new file mode 100644 index 000000000..22d4b0322 --- /dev/null +++ b/tests/ft_duiservicefwgen/ftduiservicefwgen2.cpp.correct @@ -0,0 +1,66 @@ +/* + * automatically generated with the command line : + * /home/davidmaxwaterman/z/hi386/libdui/tools/dui-servicefwgen -p /home/davidmaxwaterman/z/hi386/libdui/tests/ft_duiservicefwgen/com.nokia.FtDuiServiceFwGen2 + */ + +#include "ftduiservicefwgen2.h" + +bool FtDuiServiceFwGen2::showGridWithCapturedContent( int limit ) +{ + return qobject_cast(interfaceProxy)->showGridWithCapturedContent( limit ).value(); +} + +void FtDuiServiceFwGen2::showImage( const QString &uri, const QStringList &uriList ) +{ + static_cast(interfaceProxy)->showImage( uri, uriList ); +} + +bool FtDuiServiceFwGen2::showImage( const QString &uri, const QString &playlistName, const QString &defaultBackPage ) +{ + return qobject_cast(interfaceProxy)->showImage( uri, playlistName, defaultBackPage ).value(); +} + +bool FtDuiServiceFwGen2::showPage( const QString &targetPage, const QString &previousPage ) +{ + return qobject_cast(interfaceProxy)->showPage( targetPage, previousPage ).value(); +} + +bool FtDuiServiceFwGen2::showSettings( ) +{ + return qobject_cast(interfaceProxy)->showSettings( ).value(); +} + +FtDuiServiceFwGen2::FtDuiServiceFwGen2( const QString& preferredService, QObject* parent ) + : DuiServiceFwBaseIf( FtDuiServiceFwGen2Proxy::staticInterfaceName(), parent ) +{ + // Resolve the provider service name + service = resolveServiceName( interface, preferredService ); + + bool serviceNameInvalid = service.contains( " " ); // "not provided" - when the service wouldn't run + if ( serviceNameInvalid ) { + service.clear(); + } + + if (!service.isEmpty()) { + // Construct the D-Bus proxy + interfaceProxy = new FtDuiServiceFwGen2Proxy( service, "/", QDBusConnection::sessionBus(), this ); + // allConnectSignals go here (empty block if none) + + } +} + +void FtDuiServiceFwGen2::setService(const QString & service) +{ + if (service.isEmpty()) return; + + this->service = service; + + if ( interfaceProxy ) { + delete interfaceProxy; + interfaceProxy = 0; + } + interfaceProxy = new FtDuiServiceFwGen2Proxy( service, "/", QDBusConnection::sessionBus(), this ); + { + + } +} diff --git a/tests/ft_duiservicefwgen/ftduiservicefwgen2.h.correct b/tests/ft_duiservicefwgen/ftduiservicefwgen2.h.correct new file mode 100644 index 000000000..611669ac4 --- /dev/null +++ b/tests/ft_duiservicefwgen/ftduiservicefwgen2.h.correct @@ -0,0 +1,63 @@ +#ifndef FTDUISERVICEFWGEN2_H +#define FTDUISERVICEFWGEN2_H + +/* + * automatically generated with the command line : + * /home/davidmaxwaterman/z/hi386/libdui/tests/ft_duiservicefwgen/../../tools/dui-servicefwgen -p /home/davidmaxwaterman/z/hi386/libdui/tests/ft_duiservicefwgen/com.nokia.FtDuiServiceFwGen2 + */ + +#include + +#include +#include + +/* main documentation for the interface + main documentation for the interface2 */ +class FtDuiServiceFwGen2 : public DuiServiceFwBaseIf +{ +Q_OBJECT + +public: + + /* documentation for showGridWithCapturedContent() method */ + /* documentation for showGridWithCapturedContent() method2 */ + bool showGridWithCapturedContent( int limit ); + + /* documentation for showImage(1) method */ + /* documentation for showImage(1) method2 */ + void showImage( const QString &uri, const QStringList &uriList ); + + /* documentation for showImage(0) method */ + /* documentation for showImage(0) method2 */ + bool showImage( const QString &uri, const QString &playlistName, const QString &defaultBackPage ); + + /* documentation for showPage() method */ + /* documentation for showPage() method2 */ + bool showPage( const QString &targetPage, const QString &previousPage ); + + /* documentation for showSettings() method */ + /* documentation for showSettings() method2 */ + bool showSettings( ); + +public: + /*! + * @brief Constructs a base interface + * @param preferredService, define the preferred service provider. Leave + empty if no preferred provider. In most cases, this should be left + empty. + * @param parent Parent object + */ + + FtDuiServiceFwGen2( const QString& preferredService = "", QObject* parent = 0 ); + + /*! + * @brief Set the service name + * @param service Name of the desired service + */ + + void setService(const QString & service); +Q_SIGNALS: + + +}; +#endif diff --git a/tests/ft_duiservicefwgen/ftduiservicefwgen2adaptor.cpp.correct b/tests/ft_duiservicefwgen/ftduiservicefwgen2adaptor.cpp.correct new file mode 100644 index 000000000..d30389adc --- /dev/null +++ b/tests/ft_duiservicefwgen/ftduiservicefwgen2adaptor.cpp.correct @@ -0,0 +1,146 @@ +/* + * This file was generated by qdbusxml2cpp version 0.7 + * Command line was: qdbusxml2cpp -c FtDuiServiceFwGen2Adaptor -a ftduiservicefwgen2adaptor com.nokia.FtDuiServiceFwGen2.xml + * + * qdbusxml2cpp is Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#include "ftduiservicefwgen2adaptor.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +/* + * Implementation of adaptor class FtDuiServiceFwGen2Adaptor + */ + +FtDuiServiceFwGen2Adaptor::FtDuiServiceFwGen2Adaptor(QObject *parent) + : QDBusAbstractAdaptor(parent), + backServiceName(), + windowId(-1) +{ + // constructor + setAutoRelaySignals(true); +} + +FtDuiServiceFwGen2Adaptor::~FtDuiServiceFwGen2Adaptor() +{ + // destructor +} + +bool FtDuiServiceFwGen2Adaptor::showGridWithCapturedContent(int limit) +{ + // handle method call com.nokia.fakegalleryserviceinterface.showGridWithCapturedContent + bool out0; + QMetaObject::invokeMethod(parent(), "showGridWithCapturedContent", Q_RETURN_ARG(bool, out0), Q_ARG(int, limit)); + return out0; +} + +void FtDuiServiceFwGen2Adaptor::showImage(const QString &backServiceName, const QString &windowTitle, const uint windowId, const QString &uri, const QStringList &uriList) +{ + this->windowId = windowId; + this->backServiceName = backServiceName; + + // handle method call com.nokia.fakegalleryserviceinterface.showImage + QMetaObject::invokeMethod(parent(), "showImage", Q_ARG(QString, uri), Q_ARG(QStringList, uriList)); + + DuiApplication::instance()->activeWindow()->setWindowTitle( windowTitle ); + DuiApplicationWindow *appWindow = DuiApplication::activeApplicationWindow(); + if (appWindow != 0) { + appWindow->currentPage()->setEscapeButtonMode( DuiEscapeButtonPanelModel::BackMode ); + // connect to the back button - assumes the above 'showImage' opens a + // new window and so the window referred to below is already the top one + connect(appWindow->currentPage(), SIGNAL(backButtonClicked()), + this, SLOT(goBack())); + } + + // update the X server + { + XPropertyEvent p; + p.send_event = True; + p.display = QX11Info::display(); + p.type = PropertyNotify; + p.window = RootWindow(p.display, 0); + p.atom = XInternAtom(p.display, "_NET_CLIENT_LIST", False); + p.state = PropertyNewValue; + p.time = CurrentTime; + XSendEvent(p.display, p.window, False, PropertyChangeMask, + (XEvent*)&p); + + XSync(QX11Info::display(), False); + } + +} + +bool FtDuiServiceFwGen2Adaptor::showImage(const QString &uri, const QString &playlistName, const QString &defaultBackPage) +{ + // handle method call com.nokia.fakegalleryserviceinterface.showImage + bool out0; + QMetaObject::invokeMethod(parent(), "showImage", Q_RETURN_ARG(bool, out0), Q_ARG(QString, uri), Q_ARG(QString, playlistName), Q_ARG(QString, defaultBackPage)); + return out0; +} + +bool FtDuiServiceFwGen2Adaptor::showPage(const QString &targetPage, const QString &previousPage) +{ + // handle method call com.nokia.fakegalleryserviceinterface.showPage + bool out0; + QMetaObject::invokeMethod(parent(), "showPage", Q_RETURN_ARG(bool, out0), Q_ARG(QString, targetPage), Q_ARG(QString, previousPage)); + return out0; +} + +bool FtDuiServiceFwGen2Adaptor::showSettings() +{ + // handle method call com.nokia.fakegalleryserviceinterface.showSettings + bool out0; + QMetaObject::invokeMethod(parent(), "showSettings", Q_RETURN_ARG(bool, out0)); + return out0; +} + +void FtDuiServiceFwGen2Adaptor::goBack() +{ + qDebug() << __PRETTY_FUNCTION__; + + bool backServiceRegistered = ( windowId != -1 ); + if ( backServiceRegistered ) { + DuiApplicationIfProxy duiApplicationIfProxy(backServiceName, this); + + if (duiApplicationIfProxy.connection().isConnected()) { + qDebug() << "Launching " << backServiceName; + duiApplicationIfProxy.launch(); + } else { + qWarning() << "Could not launch" << backServiceName; + qWarning() << "DBus not connected?"; + } + + // unhide the chain parent's window + { + // Tell the window to not to be shown in the switcher + XDeleteProperty(QX11Info::display(), windowId, XInternAtom(QX11Info::display(), "_NET_WM_STATE", False)); + XSync(QX11Info::display(), False); + } + + qWarning() << "quitting - bye bye"; + QTimer::singleShot( 0, QApplication::instance(), SLOT( quit() ) ); + } else { + qWarning() << "backService is not registered: not going back"; + } +} diff --git a/tests/ft_duiservicefwgen/ftduiservicefwgen2adaptor.h.correct b/tests/ft_duiservicefwgen/ftduiservicefwgen2adaptor.h.correct new file mode 100644 index 000000000..cc3c6f99d --- /dev/null +++ b/tests/ft_duiservicefwgen/ftduiservicefwgen2adaptor.h.correct @@ -0,0 +1,80 @@ +/* + * This file was generated by qdbusxml2cpp version 0.7 + * Command line was: qdbusxml2cpp -c FtDuiServiceFwGen2Adaptor -a ftduiservicefwgen2adaptor com.nokia.FtDuiServiceFwGen2-11382.xml + * + * qdbusxml2cpp is Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#ifndef FTDUISERVICEFWGEN2ADAPTOR_H_1264070554 +#define FTDUISERVICEFWGEN2ADAPTOR_H_1264070554 + +#include +#include +class QByteArray; +template class QList; +template class QMap; +class QString; +class QStringList; +class QVariant; + +/* + * Adaptor class for interface com.nokia.fakegalleryserviceinterface + */ +class FtDuiServiceFwGen2Adaptor: public QDBusAbstractAdaptor +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "com.nokia.fakegalleryserviceinterface") + Q_CLASSINFO("D-Bus Introspection", "" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" + "") +public: + FtDuiServiceFwGen2Adaptor(QObject *parent); + virtual ~FtDuiServiceFwGen2Adaptor(); + +public: // PROPERTIES +public Q_SLOTS: // METHODS + bool showGridWithCapturedContent(int limit); + Q_NOREPLY void showImage(const QString &backServiceName, const QString &windowTitle, const uint windowId, const QString &uri, const QStringList &uriList); + bool showImage(const QString &uri, const QString &playlistName, const QString &defaultBackPage); + bool showPage(const QString &targetPage, const QString &previousPage); + bool showSettings(); + void goBack(); + +private: + QString backServiceName; + int windowId; + +Q_SIGNALS: // SIGNALS +}; + +#endif diff --git a/tests/ft_duiservicefwgen/ftduiservicefwgen2proxy.cpp.correct b/tests/ft_duiservicefwgen/ftduiservicefwgen2proxy.cpp.correct new file mode 100644 index 000000000..aa33a4e4d --- /dev/null +++ b/tests/ft_duiservicefwgen/ftduiservicefwgen2proxy.cpp.correct @@ -0,0 +1,26 @@ +/* + * This file was generated by qdbusxml2cpp version 0.7 + * Command line was: qdbusxml2cpp -c FtDuiServiceFwGen2Proxy -p ftduiservicefwgen2proxy com.nokia.FtDuiServiceFwGen2-11380.xml + * + * qdbusxml2cpp is Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#include "ftduiservicefwgen2proxy.h" + +/* + * Implementation of interface class FtDuiServiceFwGen2Proxy + */ + +FtDuiServiceFwGen2Proxy::FtDuiServiceFwGen2Proxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) + : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) +{ +} + +FtDuiServiceFwGen2Proxy::~FtDuiServiceFwGen2Proxy() +{ +} + diff --git a/tests/ft_duiservicefwgen/ftduiservicefwgen2proxy.h.correct b/tests/ft_duiservicefwgen/ftduiservicefwgen2proxy.h.correct new file mode 100644 index 000000000..8976038d6 --- /dev/null +++ b/tests/ft_duiservicefwgen/ftduiservicefwgen2proxy.h.correct @@ -0,0 +1,111 @@ +/* + * This file was generated by qdbusxml2cpp version 0.7 + * Command line was: qdbusxml2cpp -c FtDuiServiceFwGen2Proxy -p ftduiservicefwgen2proxy com.nokia.FtDuiServiceFwGen2.xml + * + * qdbusxml2cpp is Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#ifndef FTDUISERVICEFWGEN2PROXY_H_1264070554 +#define FTDUISERVICEFWGEN2PROXY_H_1264070554 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Proxy class for interface com.nokia.fakegalleryserviceinterface + */ +class FtDuiServiceFwGen2Proxy: public QDBusAbstractInterface +{ + Q_OBJECT +public: + static inline const char *staticInterfaceName() + { return "com.nokia.fakegalleryserviceinterface"; } + +public: + FtDuiServiceFwGen2Proxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0); + + ~FtDuiServiceFwGen2Proxy(); + +public Q_SLOTS: // METHODS + inline QDBusPendingReply showGridWithCapturedContent(int limit) + { + QList argumentList; + argumentList << qVariantFromValue(limit); + return asyncCallWithArgumentList(QLatin1String("showGridWithCapturedContent"), argumentList); + } + + inline QDBusPendingReply<> showImage(const QString &uri, const QStringList &uriList) + { + Qt::HANDLE windowId = DuiApplication::instance()->activeWindow()->winId(); + QString windowTitle = DuiApplication::instance()->activeWindow()->windowTitle(); + QString goBackServiceName = DuiComponentData::instance()->serviceName(); + + QList argumentList; + argumentList << qVariantFromValue(goBackServiceName); + argumentList << qVariantFromValue(windowTitle); + argumentList << qVariantFromValue((uint)windowId); + argumentList << qVariantFromValue(uri) << qVariantFromValue(uriList); + + // hide this window + { + // Tell the window to not to be shown in the switcher + Atom skipTaskbarAtom = XInternAtom(QX11Info::display(), "_NET_WM_STATE_SKIP_TASKBAR", False); + + Atom netWmStateAtom = XInternAtom(QX11Info::display(), "_NET_WM_STATE", False); + QVector atoms; + atoms.append(skipTaskbarAtom); + XChangeProperty(QX11Info::display(), windowId, netWmStateAtom, XA_ATOM, 32, PropModeReplace, (unsigned char *)atoms.data(), atoms.count()); + XSync(QX11Info::display(), False); + } + + return asyncCallWithArgumentList(QLatin1String("showImage"), argumentList); + } + + inline QDBusPendingReply showImage(const QString &uri, const QString &playlistName, const QString &defaultBackPage) + { + QList argumentList; + argumentList << qVariantFromValue(uri) << qVariantFromValue(playlistName) << qVariantFromValue(defaultBackPage); + return asyncCallWithArgumentList(QLatin1String("showImage"), argumentList); + } + + inline QDBusPendingReply showPage(const QString &targetPage, const QString &previousPage) + { + QList argumentList; + argumentList << qVariantFromValue(targetPage) << qVariantFromValue(previousPage); + return asyncCallWithArgumentList(QLatin1String("showPage"), argumentList); + } + + inline QDBusPendingReply showSettings() + { + QList argumentList; + return asyncCallWithArgumentList(QLatin1String("showSettings"), argumentList); + } + +Q_SIGNALS: // SIGNALS +}; + +namespace com { + namespace nokia { + typedef ::FtDuiServiceFwGen2Proxy fakegalleryserviceinterface; + } +} +#endif diff --git a/tests/ft_duislider/.gitignore b/tests/ft_duislider/.gitignore new file mode 100644 index 000000000..98d7cf585 --- /dev/null +++ b/tests/ft_duislider/.gitignore @@ -0,0 +1,2 @@ +ft_duislider +*.png diff --git a/tests/ft_duislider/duiimagestyle.css b/tests/ft_duislider/duiimagestyle.css new file mode 100644 index 000000000..b8645ea94 --- /dev/null +++ b/tests/ft_duislider/duiimagestyle.css @@ -0,0 +1,14 @@ +/* DuiImageStyle : DuiWidgetStyle */ +DuiImageStyle { + border-top: 0; + border-left: 0; + border-bottom: 0; + border-right: 0; + border-color: #FFFFFF; + border-opacity: 1.0; + + /* inherited from DuiWidgetStyle */ + background-color: #000000; + background-opacity: 0.0; +} + diff --git a/tests/ft_duislider/duilabelstyle.css b/tests/ft_duislider/duilabelstyle.css new file mode 100644 index 000000000..865ea7dc3 --- /dev/null +++ b/tests/ft_duislider/duilabelstyle.css @@ -0,0 +1,8 @@ +/* DuiLabelStyle : DuiWidgetStyle */ +DuiLabelStyle { + color: #FFFFFF; + font: "Nokia Sans" 2.4mm; + + /* inherited from DuiWidgetStyle */ +} + diff --git a/tests/ft_duislider/duislider.svg b/tests/ft_duislider/duislider.svg new file mode 100644 index 000000000..998286c00 --- /dev/null +++ b/tests/ft_duislider/duislider.svg @@ -0,0 +1,12438 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + DEPRECATED + DEPRECATED + + duislider + + Slider-row-normal + Slider-row-normal-press + Slider-row-selected + Slider-row-selected-press-big + Slider-row-selected-press + Slider-dot-normal + Slider-dot-selected + Slider-row-empty + progress, with online content loading + smooth one dot blink animation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + example: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/ft_duislider/duisliderstyle.css b/tests/ft_duislider/duisliderstyle.css new file mode 100644 index 000000000..333e2291f --- /dev/null +++ b/tests/ft_duislider/duisliderstyle.css @@ -0,0 +1,37 @@ +/* DuiSliderStyle : DuiWidgetStyle */ +DuiSliderStyle { + thumb-pixmap: "duislider-handle" 8.8mm 8.8mm; + thumb-pressed-pixmap: "duislider-handle-pressed" 8.8mm 8.8mm; + thumb-vertical-pixmap: "duislider-vertical-handle" 8.8mm 8.8mm; + thumb-vertical-pressed-pixmap: "duislider-vertical-handle-pressed" 8.8mm 8.8mm; + + handle-pixmap: "duislider-handle" 8.8mm 8.8mm; + handle-pressed-pixmap: "duislider-handle-pressed" 8.8mm 8.8mm; + handle-vertical-pixmap: "duislider-vertical-handle" 8.8mm 8.8mm; + handle-vertical-pressed-pixmap: "duislider-vertical-handle-pressed" 8.8mm 8.8mm; + + background-base-image: "duislider-background" 9px 9px 9px 9px; + background-elapsed-image: "duislider-background-elapsed" 9px 9px 9px 9px; + background-received-image: "duislider-background-received" 9px 9px 9px 9px; + + background-vertical-base-image: "duislider-vertical-background" 9px 9px 9px 9px; + background-vertical-elapsed-image: "duislider-vertical-background-elapsed" 9px 9px 9px 9px; + background-vertical-received-image: "duislider-vertical-background-received" 9px 9px 9px 9px; + + rail-thickness: 2mm; + groove-thickness: 2mm; + + rail-end-padding: 0mm; + + /* inherited from DuiWidgetStyle */ + preferred-size: 60mm 12mm; + minimum-size: 40mm 12mm; + maximum-size: 200mm 12mm; +} + +#DuiSliderLabel { +} + +#DuiSliderImage { +} + diff --git a/tests/ft_duislider/ft_duislider.cpp b/tests/ft_duislider/ft_duislider.cpp new file mode 100644 index 000000000..87e81eef1 --- /dev/null +++ b/tests/ft_duislider/ft_duislider.cpp @@ -0,0 +1,64 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ft_duislider.h" +#include +#include +#include "duiapplication.h" +#include "duislider.h" +#include "duitheme.h" + +DuiApplication *app; + +void Ft_DuiSlider::initTestCase() +{ + static int argc = 1; + static char *argv[1] = { (char *) "./ft_duislider" }; + app = new DuiApplication(argc, argv); + + DuiTheme::loadCSS("duisliderstyle.css"); +} + +void Ft_DuiSlider::cleanupTestCase() +{ + delete app; +} + +void Ft_DuiSlider::sliderResize() +{ + DuiSlider *s = new DuiSlider(); + + s->setMinimumSize(310, 70); + s->resize(310, 70); + QCOMPARE(s->size(), QSizeF(310, 70)); + + s->setMinimumSize(100, 400); + s->resize(100, 400); + QCOMPARE(s->size(), QSizeF(100, 400)); + + s->setMinimumSize(310, 70); + s->resize(310, 70); + QCOMPARE(s->size(), QSizeF(310, 70)); + + delete s; +} + +QTEST_APPLESS_MAIN(Ft_DuiSlider) + + diff --git a/tests/ft_duislider/ft_duislider.css b/tests/ft_duislider/ft_duislider.css new file mode 100644 index 000000000..ad6581b38 --- /dev/null +++ b/tests/ft_duislider/ft_duislider.css @@ -0,0 +1,16 @@ +DuiSliderDotStyle { + handle-mid-pixmap: "Slider-row-selected-press-big" 8mm 3mm; + handle-bottom-pixmap: "Slider-row-selected-press" 5mm 2mm; + handle-top-pixmap: "Slider-row-normal-press" 5mm 2mm; + + active-tile-pixmap: "Slider-row-selected" 5mm 1mm; + inactive-tile-pixmap: "Slider-row-normal" 5mm 1mm; + active-root-pixmap: "Slider-dot-selected" 1mm 1mm; + inactive-root-pixmap: "Slider-dot-normal" 1mm 1mm; + + /* inherited from DuiWidgetStyle */ + preferred-size: 12mm 90%; + minimum-size: 7mm 10mm; + maximum-size: 90% 90%; +} + diff --git a/tests/ft_duislider/ft_duislider.h b/tests/ft_duislider/ft_duislider.h new file mode 100644 index 000000000..3dd5a0b69 --- /dev/null +++ b/tests/ft_duislider/ft_duislider.h @@ -0,0 +1,38 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef FT_DUISLIDER_H +#define FT_DUISLIDER_H + +#include +#include +#include + +class Ft_DuiSlider : public QObject +{ + Q_OBJECT + +private slots: + void cleanupTestCase(); + void initTestCase(); + void sliderResize(); +}; + +#endif + diff --git a/tests/ft_duislider/ft_duislider.pro b/tests/ft_duislider/ft_duislider.pro new file mode 100644 index 000000000..c327c3472 --- /dev/null +++ b/tests/ft_duislider/ft_duislider.pro @@ -0,0 +1,18 @@ +include(../common_top.pri) +TARGET = ft_duislider +QT += dbus svg network +LIBRARYPATH += $$DUISRCDIR + +SOURCES += \ + ft_duislider.cpp \ + +HEADERS += \ + ft_duislider.h \ + +support_files.files += \ + duisliderstyle.css \ + duiimagestyle.css \ + duilabelstyle.css \ + duislider.svg + +include(../common_bot.pri) diff --git a/tests/ft_duistylesheet/.gitignore b/tests/ft_duistylesheet/.gitignore new file mode 100644 index 000000000..06d2d8488 --- /dev/null +++ b/tests/ft_duistylesheet/.gitignore @@ -0,0 +1,2 @@ +ft_duistylesheet +gen_* diff --git a/tests/ft_duistylesheet/ft_duistylesheet.cpp b/tests/ft_duistylesheet/ft_duistylesheet.cpp new file mode 100644 index 000000000..69dcf4c21 --- /dev/null +++ b/tests/ft_duistylesheet/ft_duistylesheet.cpp @@ -0,0 +1,385 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ft_duistylesheet.h" +#include "duiapplication.h" +#include "duiapplicationwindow.h" +#include "duiscenemanager.h" +#include +#include +#include "testobjectstyle.h" +#include "testobject2style.h" +#include "testobject3style.h" +#include "duiscalableimage.h" +#include "testwidget.h" +#include "testwidget2.h" +#include "testwidget3.h" + +// include this to get theme profiling support +//#include "../../src/theme/duitheme_p.h" + + +Ft_DuiStyleSheet::Ft_DuiStyleSheet() +{ +} + +void Ft_DuiStyleSheet::init() +{ + m_subject = new DuiStyleSheet(); +} + +void Ft_DuiStyleSheet::cleanup() +{ + DuiStyleSheet::cleanup(false); + delete m_subject; +} + +DuiApplication *app; + +void Ft_DuiStyleSheet::initTestCase() +{ + static int argc = 1; + static char *app_name[1] = { (char *) "./ft_css" }; + app = new DuiApplication(argc, app_name); +} + +void Ft_DuiStyleSheet::cleanupTestCase() +{ + delete app; +} + +void Ft_DuiStyleSheet::test_supported_attribute_types() +{ + m_subject->setBinaryFileGenerationEnabled(false); + + // Open test file + QCOMPARE(m_subject->load(qApp->applicationDirPath() + "/ft_duistylesheet_testobject.css"), true); + + QList sheets; + sheets.append(m_subject); + TestObjectStyle *style = (TestObjectStyle *) DuiStyleSheet::style(sheets, "TestObjectStyle", "", "", "", Dui::Landscape, NULL); + + QFont font("sans"); + font.setPixelSize(10); + + // Check that attributes match to the ones in .css file + QCOMPARE(style->attributeInteger(), 10); + QCOMPARE(style->attributeReal(), 2.5); + QCOMPARE(style->attributeString(), QString("string")); + QCOMPARE(style->attributeChar(), QChar('x')); + QCOMPARE(style->attributeBool(), true); + QCOMPARE(style->attributePoint(), QPoint(10, 10)); + QCOMPARE(style->attributePointF(), QPointF(15.5, 21.5)); + QCOMPARE(style->attributeFont(), font); + QCOMPARE(style->attributeSize(), QSize(12, 15)); + QCOMPARE(style->attributeSizeF(), QSizeF(22.5, 27.75)); + QCOMPARE(style->attributeColor(), QColor("#ffffff")); +#if QT_VERSION >= 0x040600 +// QEasingCurve curve; +// curve.setType(QEasingCurve::Linear); +// curve.setAmplitude(0.5); +// curve.setOvershoot(1.5); +// curve.setPeriod(1.0); +// QCOMPARE(style.attributeEasingCurve(), curve); +#endif + QCOMPARE(style->attributeAlignment(), Qt::AlignLeft); + QCOMPARE(style->attributeOrientation(), Qt::Horizontal); + QCOMPARE(style->attributeUnderlineStyle(), QTextCharFormat::NoUnderline); + QCOMPARE(style->attributePenStyle(), Qt::NoPen); + QCOMPARE(style->attributeAxis(), Qt::XAxis); + + QVERIFY(style->attributePixmap()); + QVERIFY(style->attributePixmap2()); + QVERIFY(style->attributePixmap3()); + QVERIFY(style->attributePixmap4()); + QVERIFY(style->attributePixmap() == style->attributePixmap2()); + QVERIFY(style->attributePixmap3() == style->attributePixmap4()); + QCOMPARE(style->attributePixmap()->size(), QSize(30, 30)); + + QVERIFY(style->attributeScalable()); + QVERIFY(style->attributeScalable2()); + QVERIFY(style->attributeScalable3()); + QVERIFY(style->attributeScalable4()); + + QVERIFY(style->attributeScalable() == style->attributeScalable2()); + QVERIFY(style->attributeScalable3() == style->attributeScalable4()); + + int left, right, top, bottom; + style->attributeScalable()->borders(&left, &right, &top, &bottom); + QCOMPARE(left, 20); + QCOMPARE(right, 20); + QCOMPARE(top, 20); + QCOMPARE(bottom, 20); + + DuiStyleSheet::releaseStyle(style); +} + +void Ft_DuiStyleSheet::test_inheritance() +{ + m_subject->setBinaryFileGenerationEnabled(false); + + // Open test file + QCOMPARE(m_subject->load(qApp->applicationDirPath() + "/ft_duistylesheet_testobject.css"), true); + + QList sheets; + sheets.append(m_subject); + TestObject2Style *style2 = (TestObject2Style *) DuiStyleSheet::style(sheets, "TestObject2Style", "", "", "", Dui::Landscape, NULL); + + QFont font("sans"); + font.setPixelSize(10); + + // Check that attributes match to the ones in .css file + QCOMPARE(style2->attributeInteger(), 5); + QCOMPARE(style2->attributeInteger2(), 50); + QCOMPARE(style2->attributeReal(), 2.5); + QCOMPARE(style2->attributeString(), QString("stringi")); + QCOMPARE(style2->attributeString2(), QString("string2")); + QCOMPARE(style2->attributeBool(), true); + QCOMPARE(style2->attributePoint(), QPoint(10, 10)); + QCOMPARE(style2->attributePointF(), QPointF(15.5, 21.5)); + QCOMPARE(style2->attributeFont(), font); + QCOMPARE(style2->attributeSize(), QSize(12, 15)); + QCOMPARE(style2->attributeSizeF(), QSizeF(22.5, 27.75)); + QCOMPARE(style2->attributeColor(), QColor("#ffffff")); + + QCOMPARE(style2->attributeAlignment(), Qt::AlignLeft); + QCOMPARE(style2->attributeOrientation(), Qt::Horizontal); + QCOMPARE(style2->attributeUnderlineStyle(), QTextCharFormat::NoUnderline); + QCOMPARE(style2->attributePenStyle(), Qt::NoPen); + QCOMPARE(style2->attributeAxis(), Qt::XAxis); + + QVERIFY(style2->attributePixmap()); + QCOMPARE(style2->attributePixmap()->size(), QSize(30, 30)); + + QVERIFY(style2->attributeScalable()); + int left, right, top, bottom; + style2->attributeScalable()->borders(&left, &right, &top, &bottom); + QCOMPARE(left, 20); + QCOMPARE(right, 20); + QCOMPARE(top, 20); + QCOMPARE(bottom, 20); + DuiStyleSheet::releaseStyle(style2); + + TestObject3Style *style3 = (TestObject3Style *) DuiStyleSheet::style(sheets, "TestObject3Style", "", "", "", Dui::Landscape, NULL); + QCOMPARE(style3->attributeInteger(), 3); + QCOMPARE(style3->attributeInteger2(), 50); + QCOMPARE(style3->attributeString2(), QString("string3")); + QCOMPARE(style3->attributeBool(), true); + DuiStyleSheet::releaseStyle(style3); +} + +void Ft_DuiStyleSheet::test_objectnames() +{ + m_subject->setBinaryFileGenerationEnabled(false); + + // Open test file + QCOMPARE(m_subject->load(qApp->applicationDirPath() + "/ft_duistylesheet_testobject.css"), true); + + QList sheets; + sheets.append(m_subject); + + TestObjectStyle *style = (TestObjectStyle *) DuiStyleSheet::style(sheets, "TestObjectStyle", "Specialized", "", "", Dui::Landscape, NULL); + QCOMPARE(style->attributeInteger(), 100); + QCOMPARE(style->attributeReal(), 100.0); + QCOMPARE(style->attributeString(), QString("specialized string")); + DuiStyleSheet::releaseStyle(style); + + TestObject2Style *style2 = (TestObject2Style *) DuiStyleSheet::style(sheets, "TestObject2Style", "Specialized", "", "", Dui::Landscape, NULL); + QCOMPARE(style2->attributeInteger(), 100); + QCOMPARE(style2->attributeInteger2(), 7); + QCOMPARE(style2->attributeReal(), 12.0); + QCOMPARE(style2->attributeString2(), QString("specialized string2")); + DuiStyleSheet::releaseStyle(style2); +} + +void Ft_DuiStyleSheet::test_orientations() +{ + m_subject->setBinaryFileGenerationEnabled(false); + + // Open test file + QCOMPARE(m_subject->load(qApp->applicationDirPath() + "/ft_duistylesheet_testobject.css"), true); + + QList sheets; + sheets.append(m_subject); + + TestObjectStyle *style = (TestObjectStyle *) DuiStyleSheet::style(sheets, "TestObjectStyle", "", "", "", Dui::Portrait, NULL); + QCOMPARE(style->attributeOrientation(), Qt::Vertical); + DuiStyleSheet::releaseStyle(style); + + style = (TestObjectStyle *) DuiStyleSheet::style(sheets, "TestObjectStyle", "", "", "", Dui::Landscape, NULL); + QCOMPARE(style->attributeOrientation(), Qt::Horizontal); + DuiStyleSheet::releaseStyle(style); + + TestObject2Style *style2 = (TestObject2Style *) DuiStyleSheet::style(sheets, "TestObject2Style", "", "", "", Dui::Portrait, NULL); + QCOMPARE(style2->attributeOrientation(), Qt::Vertical); + DuiStyleSheet::releaseStyle(style2); + + style2 = (TestObject2Style *) DuiStyleSheet::style(sheets, "TestObject2Style", "", "", "", Dui::Landscape, NULL); + QCOMPARE(style2->attributeOrientation(), Qt::Horizontal); + DuiStyleSheet::releaseStyle(style2); +} + +void Ft_DuiStyleSheet::test_modes() +{ + m_subject->setBinaryFileGenerationEnabled(false); + + // Open test file + QCOMPARE(m_subject->load(qApp->applicationDirPath() + "/ft_duistylesheet_testobject.css"), true); + + QList sheets; + sheets.append(m_subject); + + TestObjectStyle *style = (TestObjectStyle *) DuiStyleSheet::style(sheets, "TestObjectStyle", "", "Disabled", "", Dui::Landscape, NULL); + QCOMPARE(style->attributeColor(), QColor("#aaaaaa")); + DuiStyleSheet::releaseStyle(style); + + style = (TestObjectStyle *) DuiStyleSheet::style(sheets, "TestObjectStyle", "", "Active", "", Dui::Landscape, NULL); + QCOMPARE(style->attributeColor(), QColor("#ff0000")); + DuiStyleSheet::releaseStyle(style); + + style = (TestObjectStyle *) DuiStyleSheet::style(sheets, "TestObjectStyle", "Specialized", "Active", "", Dui::Landscape, NULL); + QCOMPARE(style->attributeColor(), QColor("#00ff00")); + DuiStyleSheet::releaseStyle(style); + + style = (TestObjectStyle *) DuiStyleSheet::style(sheets, "TestObjectStyle", "Specialized", "Active", "", Dui::Portrait, NULL); + QCOMPARE(style->attributeColor(), QColor("#ff00ff")); + QCOMPARE(style->attributeOrientation(), Qt::Vertical); + QCOMPARE(style->attributeString(), QString("specialiazed portrait active")); + DuiStyleSheet::releaseStyle(style); + + TestObject2Style *style2 = (TestObject2Style *) DuiStyleSheet::style(sheets, "TestObject2Style", "Specialized", "Active", "", Dui::Portrait, NULL); + QCOMPARE(style2->attributeColor(), QColor("#f0000f")); + QCOMPARE(style2->attributeOrientation(), Qt::Vertical); + QCOMPARE(style2->attributeString(), QString("specialiazed portrait active 2")); + DuiStyleSheet::releaseStyle(style2); +} + +void Ft_DuiStyleSheet::test_types() +{ + m_subject->setBinaryFileGenerationEnabled(false); + + // Open test file + QCOMPARE(m_subject->load(qApp->applicationDirPath() + "/ft_duistylesheet_testobject.css"), true); + QList sheets; + sheets.append(m_subject); + + TestObjectStyle *style = (TestObjectStyle *) DuiStyleSheet::style(sheets, "TestObjectStyle", "", "", "icon", Dui::Landscape, NULL); + QCOMPARE(style->attributeColor(), QColor("#aaaaaa")); + DuiStyleSheet::releaseStyle(style); + + style = (TestObjectStyle *) DuiStyleSheet::style(sheets, "TestObjectStyle", "", "", "fancy", Dui::Landscape, NULL); + QCOMPARE(style->attributeColor(), QColor("#ff0000")); + DuiStyleSheet::releaseStyle(style); + + style = (TestObjectStyle *) DuiStyleSheet::style(sheets, "TestObjectStyle", "Specialized", "", "icon", Dui::Landscape, NULL); + QCOMPARE(style->attributeColor(), QColor("#00ff00")); + DuiStyleSheet::releaseStyle(style); + + style = (TestObjectStyle *) DuiStyleSheet::style(sheets, "TestObjectStyle", "Specialized", "", "fancy", Dui::Landscape, NULL); + QCOMPARE(style->attributeColor(), QColor("#0abba0")); + DuiStyleSheet::releaseStyle(style); + + style = (TestObjectStyle *) DuiStyleSheet::style(sheets, "TestObjectStyle", "Specialized", "Active", "fancy", Dui::Landscape, NULL); + QCOMPARE(style->attributeColor(), QColor("#0f0f0f")); + DuiStyleSheet::releaseStyle(style); + + style = (TestObjectStyle *) DuiStyleSheet::style(sheets, "TestObjectStyle", "Specialized", "Disabled", "fancy", Dui::Landscape, NULL); + QCOMPARE(style->attributeColor(), QColor("#f0f0f0")); + DuiStyleSheet::releaseStyle(style); + + TestObject2Style *style2 = (TestObject2Style *) DuiStyleSheet::style(sheets, "TestObject2Style", "", "", "fancy", Dui::Landscape, NULL); + QCOMPARE(style2->attributeColor(), QColor("#0000ff")); + DuiStyleSheet::releaseStyle(style2); +} + +void Ft_DuiStyleSheet::test_parent() +{ + m_subject->setBinaryFileGenerationEnabled(false); + + // Open test file + QCOMPARE(m_subject->load(qApp->applicationDirPath() + "/ft_duistylesheet_testobject.css"), true); + QList sheets; + sheets.append(m_subject); + + TestWidget w; + TestWidget3 w2; + TestWidget2 w3; + + w2.setParentItem(&w); + w3.setParentItem(&w2); + + TestObjectStyle *style = (TestObjectStyle *) DuiStyleSheet::style(sheets, "TestObjectStyle", "", "", "", Dui::Landscape, &w); + QCOMPARE(style->attributeColor(), QColor("#000001")); + DuiStyleSheet::releaseStyle(style); + + style = (TestObjectStyle *) DuiStyleSheet::style(sheets, "TestObjectStyle", "", "", "", Dui::Landscape, &w2); + QCOMPARE(style->attributeColor(), QColor("#000010")); + DuiStyleSheet::releaseStyle(style); + + style = (TestObjectStyle *) DuiStyleSheet::style(sheets, "TestObjectStyle", "", "", "", Dui::Landscape, &w3); + QCOMPARE(style->attributeColor(), QColor("#000020")); + DuiStyleSheet::releaseStyle(style); +} +/* +void Ft_CSS::test_cache_size() +{ + m_subject->setBinaryFileGenerationEnabled(false); + + // get current size of the cache, should be zero + QCOMPARE(0, DuiThemePrivate::getProfilingInfo().cacheSize); + qDebug() << "Cache size is:" << DuiThemePrivate::getProfilingInfo().cacheSize; + +// DuiTheme::instance()->prepareThemeChange("green"); + + // load css file + DuiTheme::loadCSS(qApp->applicationDirPath() + "/ft_duistylesheet_test.css"); + +// DuiTheme::instance()->changeTheme(); + + // should still be zero + QCOMPARE(0, DuiThemePrivate::getProfilingInfo().cacheSize); + + TestObject testObject; + + // just get something from the style system + DuiStyle* style = DuiTheme::style(&testObject, m_styleDescription); + + // ensure that it was cached + int cacheSizeInMemory = DuiThemePrivate::getProfilingInfo().cacheSize; + qDebug() << "Cache size is:" << DuiThemePrivate::getProfilingInfo().cacheSize; + QVERIFY(cacheSizeInMemory > 0); + + // get something different + testObject.setObjectName("Specialized"); + style = DuiTheme::style(&testObject, m_styleDescription); + + // check that the cache is bigger now, it should be + int cacheSizeInMemory2 = DuiThemePrivate::getProfilingInfo().cacheSize; + qDebug() << "Cache size is:" << DuiThemePrivate::getProfilingInfo().cacheSize; + QVERIFY(cacheSizeInMemory2 > cacheSizeInMemory); + + // get same data once again, the cache size should remain same + style = DuiTheme::style(&testObject, m_styleDescription); + qDebug() << "Cache size is:" << DuiThemePrivate::getProfilingInfo().cacheSize; + QVERIFY(cacheSizeInMemory2 == DuiThemePrivate::getProfilingInfo().cacheSize); +} +*/ + + +QTEST_APPLESS_MAIN(Ft_DuiStyleSheet) diff --git a/tests/ft_duistylesheet/ft_duistylesheet.h b/tests/ft_duistylesheet/ft_duistylesheet.h new file mode 100644 index 000000000..1990d0654 --- /dev/null +++ b/tests/ft_duistylesheet/ft_duistylesheet.h @@ -0,0 +1,78 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef FT_DUISTYLESHEET_H +#define FT_DUISTYLESHEET_H + +#include +#include +#include +#include +#include +#include + +// Test class, derives QObject->TestObject +class TestObject : public QObject +{ + Q_OBJECT + +public: + TestObject(QObject *parent = 0) : QObject(parent) {}; +}; + +// Test class, derives QObject->TestObject->TestObject2 +class TestObject2 : public TestObject +{ + Q_OBJECT + +public: + TestObject2(QObject *parent = 0) : TestObject(parent) {}; +}; + + +class Ft_DuiStyleSheet : public QObject +{ + Q_OBJECT +public: + Ft_DuiStyleSheet(); + +private slots: + void init(); + void cleanup(); + void initTestCase(); + void cleanupTestCase(); + + void test_supported_attribute_types(); + void test_inheritance(); + void test_objectnames(); + void test_orientations(); + void test_modes(); + void test_types(); + void test_parent(); + + //void test_cache_size(); + +private: + + DuiStyleSheet *m_subject; + //DuiStyleDescription m_styleDescription; +}; + +#endif + diff --git a/tests/ft_duistylesheet/ft_duistylesheet.pro b/tests/ft_duistylesheet/ft_duistylesheet.pro new file mode 100644 index 000000000..d15c9fa95 --- /dev/null +++ b/tests/ft_duistylesheet/ft_duistylesheet.pro @@ -0,0 +1,45 @@ +include(../common_top.pri) +TARGET = ft_duistylesheet +QT += dbus svg network +LIBRARYPATH += $$DUISRCDIR + +win32 { + QMAKE_MOC = perl $${IN_PWD}\..\..\duimoc\duimoc +} else { + PRE_TARGETDEPS += ../../duigen/duigen + QMAKE_MOC = PATH=../../duigen:$$(PATH) $${IN_PWD}/../../duimoc/duimoc +} + +DUIGEN_OUTDIR = . +duigenerator_style.name = duigenerator style +duigenerator_style.input = STYLE_HEADERS +duigenerator_style.depends = ../../duigen/duigen +duigenerator_style.output = $$DUIGEN_OUTDIR/gen_${QMAKE_FILE_BASE}data.cpp +duigenerator_style.commands += ../../duigen/duigen --style ${QMAKE_FILE_NAME} $$DUIGEN_OUTDIR +duigenerator_style.clean += $$DUIGEN_OUTDIR/gen_* +duigenerator_style.CONFIG = target_predeps no_link +duigenerator_style.variable_out = GENERATED_SOURCES +QMAKE_EXTRA_COMPILERS += duigenerator_style + +STYLE_HEADERS += testobjectstyle.h testobject2style.h testobject3style.h + +SOURCES += \ + ft_duistylesheet.cpp \ + ../../src/theme/duilogicalvalues.cpp \ + ../../src/style/duistylesheetattribute.cpp + +HEADERS += \ + ft_duistylesheet.h \ + testobjectstyle.h \ + testobject2style.h \ + testobject3style.h \ + testwidget.h \ + testwidget2.h \ + testwidget3.h \ + ../../src/theme/duilogicalvalues.h \ + ../../src/style/duistylesheetattribute.h + +support_files.files += \ + *.css + +include(../common_bot.pri) diff --git a/tests/ft_duistylesheet/ft_duistylesheet_constants.css b/tests/ft_duistylesheet/ft_duistylesheet_constants.css new file mode 100644 index 000000000..32586f56c --- /dev/null +++ b/tests/ft_duistylesheet/ft_duistylesheet_constants.css @@ -0,0 +1,33 @@ +// This is a test file for Direct UI CSS parser. + +@import "ft_duistylesheet_constants2.css"; + +//define constants +@const cInt: 10; +@const cReal: 1.0; +@const cName: "name"; +@const cColor: #0dead0; +@const cBool: true; +@const cPoint: 17px 11px; +@const cFont: arial 10px; +@const cInvalid1 Invalid; +@const : Invalid + +//define selector and use the constants +TestObject +{ + object-name: "test object"; + + attr-int: $cInt; + attr-string1: $cName; + attr-string2: "this is a string with constant $cName"; + attr-bool: $cBool; + attr-pos1: $cWidth $cHeight; + attr-pos2: $cPoint; + attr-font1: $cFontFamily $cFontSize; + attr-font2: $cFont; + attr-color: $cColor; + attr-invalid: $cInvalid1; + attr-void: $cVoid; +} + diff --git a/tests/ft_duistylesheet/ft_duistylesheet_constants2.css b/tests/ft_duistylesheet/ft_duistylesheet_constants2.css new file mode 100644 index 000000000..f69a6f929 --- /dev/null +++ b/tests/ft_duistylesheet/ft_duistylesheet_constants2.css @@ -0,0 +1,8 @@ +// This is a test file for Direct UI CSS parser. + +//define constants +@const cWidth: 10px; +@const cHeight: 15px; +@const cFontFamily: sans; +@const cFontSize: 12px; +@const cColor:#0abba0; diff --git a/tests/ft_duistylesheet/ft_duistylesheet_object.css b/tests/ft_duistylesheet/ft_duistylesheet_object.css new file mode 100644 index 000000000..c62dbb4d4 --- /dev/null +++ b/tests/ft_duistylesheet/ft_duistylesheet_object.css @@ -0,0 +1,27 @@ +/* + * This file contains style definitions for Object + */ + +// General purpose style definitions for Qbject +QObject +{ + object-name: "object"; + + attribute-size: 100px 100px; + attribute-integer: 1; + attribute-real: 1.0; + attribute-font: "system" 10px; +} + +.QObject +{ + private-string-attribute: "private string"; +} + +#Specialized +{ + object-name: "specialized object"; + specialized-object: 1; +} + + diff --git a/tests/ft_duistylesheet/ft_duistylesheet_test.css b/tests/ft_duistylesheet/ft_duistylesheet_test.css new file mode 100644 index 000000000..84e4431cc --- /dev/null +++ b/tests/ft_duistylesheet/ft_duistylesheet_test.css @@ -0,0 +1,7 @@ +// This is a test file for DirectUI CSS parser. + +// Include other .css files +@import "ft_duistylesheet_object.css"; +@import url("ft_duistylesheet_testobject.css"); + + diff --git a/tests/ft_duistylesheet/ft_duistylesheet_testobject.css b/tests/ft_duistylesheet/ft_duistylesheet_testobject.css new file mode 100644 index 000000000..bd713455d --- /dev/null +++ b/tests/ft_duistylesheet/ft_duistylesheet_testobject.css @@ -0,0 +1,167 @@ +/* + * This file contains style definitions for TestObject + * class which is inherited from QObject + */ + +// General purpose style definitions for Test object +TestObjectStyle +{ + attribute-integer: 10; + attribute-real: 2.5; + attribute-string: "string"; + attribute-char: 'x'; + attribute-bool: true; + attribute-point: 10px 10px; + attribute-point-f: 15.5 21.5; + attribute-font: sans 10px; + attribute-size: 12px 15px; + attribute-size-f: 22.5 27.75; + attribute-color: #ffffff; + //attribute-easing-curve: linear, 0.5, 1.5, 1.0; + + attribute-alignment: left; + attribute-orientation: horizontal; + attribute-underline-style: nounderline; + attribute-pen-style: nopen; + attribute-axis: x; + + attribute-pixmap: "duibutton_background" 30 30; + attribute-pixmap2: duibutton_background 30 30; + attribute-pixmap3: "duibutton_background"; + attribute-pixmap4: duibutton_background; + attribute-scalable: "C1-container-background" 20 20 20 20; + attribute-scalable2: C1-container-background 20 20 20 20; + attribute-scalable3: "C1-container-background"; + attribute-scalable4: C1-container-background; +} + +TestObject2Style +{ + attribute-integer: 5; + attribute-string: "stringi"; + + attribute-integer2: 50; + // Last attribute doesn't need ';' + attribute-string2: "string2" +} + +TestObject3Style +{ + attribute-integer: 3; + // Last attribute doesn't need ';' and the bracket can be in the same row + attribute-string2: "string3" } + +TestObjectStyle#Specialized +{ + attribute-integer: 100; + attribute-real: 100.0; + attribute-string: "specialized string"; +} + +TestObject2Style#Specialized +{ + attribute-integer2: 7; + attribute-real: 12.0; + attribute-string2: "specialized string2"; +} + +TestObjectStyle:Disabled +{ + attribute-color: #aaaaaa; +} + +TestObjectStyle:Active +{ + attribute-color: #ff0000; +} + +TestObjectStyle#Specialized:Active +{ + attribute-color: #00ff00; +} + +TestObjectStyle.Portrait +{ + attribute-orientation: vertical; +} + +TestObjectStyle.Landscape +{ + attribute-orientation: horizontal; +} + +TestObject2Style.Portrait +{ + attribute-orientation: vertical; +} + +TestObject2Style.Landscape +{ + attribute-orientation: horizontal; +} + +TestObjectStyle#Specialized.Portrait:Active +{ + attribute-string: "specialiazed portrait active"; + attribute-orientation: vertical; + attribute-color: #ff00ff; +} + +TestObject2Style#Specialized.Portrait:Active +{ + attribute-string: "specialiazed portrait active 2"; + attribute-orientation: vertical; + attribute-color: #f0000f; +} + + +TestObjectStyle[icon] +{ + attribute-color: #aaaaaa; +} + +TestObjectStyle[fancy] +{ + attribute-color: #ff0000; +} + +TestObject2Style[fancy] +{ + attribute-color: #0000ff; +} + +TestObjectStyle[icon]#Specialized +{ + attribute-color: #00ff00; +} + +TestObjectStyle[fancy]#Specialized +{ + attribute-color: #0abba0; +} + +TestObjectStyle[fancy]#Specialized:Active +{ + attribute-color: #0f0f0f; +} + +TestObjectStyle[fancy]#Specialized:Disabled +{ + attribute-color: #f0f0f0; +} + +TestWidget > TestObjectStyle +{ + attribute-color: #000001; +} + +TestWidget TestObjectStyle +{ + attribute-color: #000010; +} + +TestWidget2 TestObjectStyle +{ + attribute-color: #000020; +} + diff --git a/tests/ft_duistylesheet/testobject2style.h b/tests/ft_duistylesheet/testobject2style.h new file mode 100644 index 000000000..f8e84b988 --- /dev/null +++ b/tests/ft_duistylesheet/testobject2style.h @@ -0,0 +1,47 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef TESTOBJECT2STYLE_H +#define TESTOBJECT2STYLE_H + +#include +#include +#include + +#include "testobjectstyle.h" + +class QPixmap; +class DuiScalableImage; + +class TestObject2Style : public TestObjectStyle +{ + Q_OBJECT + DUI_STYLE(TestObject2Style) + + DUI_STYLE_ATTRIBUTE(int, attributeInteger2, AttributeInteger2) + DUI_STYLE_ATTRIBUTE(QString, attributeString2, AttributeString2) +}; + +class TestObject2StyleContainer : public TestObjectStyleContainer +{ + DUI_STYLE_CONTAINER(TestObject2Style) +}; + +#endif + diff --git a/tests/ft_duistylesheet/testobject3style.h b/tests/ft_duistylesheet/testobject3style.h new file mode 100644 index 000000000..a874d691c --- /dev/null +++ b/tests/ft_duistylesheet/testobject3style.h @@ -0,0 +1,44 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef TESTOBJECT3STYLE_H +#define TESTOBJECT3STYLE_H + +#include +#include +#include + +#include "testobject2style.h" + +class QPixmap; +class DuiScalableImage; + +class TestObject3Style : public TestObject2Style +{ + Q_OBJECT + DUI_STYLE(TestObject3Style) +}; + +class TestObject3StyleContainer : public TestObject2StyleContainer +{ + DUI_STYLE_CONTAINER(TestObject3Style) +}; + +#endif + diff --git a/tests/ft_duistylesheet/testobjectstyle.h b/tests/ft_duistylesheet/testobjectstyle.h new file mode 100644 index 000000000..246b1c3cb --- /dev/null +++ b/tests/ft_duistylesheet/testobjectstyle.h @@ -0,0 +1,75 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef TESTOBJECTSTYLE_H +#define TESTOBJECTSTYLE_H + +#include + +#include +#include +#include + +#if QT_VERSION >= 0x040600 +#include +#endif + +class QPixmap; +class DuiScalableImage; + +class TestObjectStyle : public DuiStyle +{ + Q_OBJECT + DUI_STYLE(TestObjectStyle) + + DUI_STYLE_ATTRIBUTE(int, attributeInteger, AttributeInteger) + DUI_STYLE_ATTRIBUTE(qreal, attributeReal, AttributeReal) + DUI_STYLE_ATTRIBUTE(QString, attributeString, AttributeString) + DUI_STYLE_ATTRIBUTE(QChar, attributeChar, AttributeChar) + DUI_STYLE_ATTRIBUTE(bool, attributeBool, AttributeBool) + DUI_STYLE_ATTRIBUTE(QPoint, attributePoint, AttributePoint) + DUI_STYLE_ATTRIBUTE(QPointF, attributePointF, AttributePointF) + DUI_STYLE_ATTRIBUTE(QFont, attributeFont, AttributeFont) + DUI_STYLE_ATTRIBUTE(QSize, attributeSize, AttributeSize) + DUI_STYLE_ATTRIBUTE(QSizeF, attributeSizeF, AttributeSizeF) + DUI_STYLE_ATTRIBUTE(QColor, attributeColor, AttributeColor) + //DUI_STYLE_ATTRIBUTE(QEasingCurve, attributeEasingCurve, AttributeEasingCurve) + DUI_STYLE_ATTRIBUTE(Qt::Alignment, attributeAlignment, AttributeAlignment) + DUI_STYLE_ATTRIBUTE(Qt::Orientation, attributeOrientation, AttributeOrientation) + DUI_STYLE_ATTRIBUTE(QTextCharFormat::UnderlineStyle, attributeUnderlineStyle, AttributeUnderlineStyle) + DUI_STYLE_ATTRIBUTE(Qt::PenStyle, attributePenStyle, AttributePenStyle) + DUI_STYLE_ATTRIBUTE(Qt::Axis, attributeAxis, AttributeAxis) + + DUI_STYLE_PTR_ATTRIBUTE(QPixmap *, attributePixmap, AttributePixmap) + DUI_STYLE_PTR_ATTRIBUTE(QPixmap *, attributePixmap2, AttributePixmap2) + DUI_STYLE_PTR_ATTRIBUTE(QPixmap *, attributePixmap3, AttributePixmap3) + DUI_STYLE_PTR_ATTRIBUTE(QPixmap *, attributePixmap4, AttributePixmap4) + DUI_STYLE_PTR_ATTRIBUTE(DuiScalableImage *, attributeScalable, AttributeScalable) + DUI_STYLE_PTR_ATTRIBUTE(DuiScalableImage *, attributeScalable2, AttributeScalable2) + DUI_STYLE_PTR_ATTRIBUTE(DuiScalableImage *, attributeScalable3, AttributeScalable3) + DUI_STYLE_PTR_ATTRIBUTE(DuiScalableImage *, attributeScalable4, AttributeScalable4) +}; + +class TestObjectStyleContainer : public DuiStyleContainer +{ + DUI_STYLE_CONTAINER(TestObjectStyle) +}; + +#endif + diff --git a/tests/ft_duistylesheet/testwidget.h b/tests/ft_duistylesheet/testwidget.h new file mode 100644 index 000000000..161822fde --- /dev/null +++ b/tests/ft_duistylesheet/testwidget.h @@ -0,0 +1,31 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef TESTWIDGET_H +#define TESTWIDGET_H + +#include + +class TestWidget : public DuiWidgetController +{ + Q_OBJECT; +}; + +#endif + diff --git a/tests/ft_duistylesheet/testwidget2.h b/tests/ft_duistylesheet/testwidget2.h new file mode 100644 index 000000000..d19bfe5d9 --- /dev/null +++ b/tests/ft_duistylesheet/testwidget2.h @@ -0,0 +1,31 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef TESTWIDGET2_H +#define TESTWIDGET2_H + +#include + +class TestWidget2 : public DuiWidgetController +{ + Q_OBJECT; +}; + +#endif + diff --git a/tests/ft_duistylesheet/testwidget3.h b/tests/ft_duistylesheet/testwidget3.h new file mode 100644 index 000000000..307600153 --- /dev/null +++ b/tests/ft_duistylesheet/testwidget3.h @@ -0,0 +1,31 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef TESTWIDGET3_H +#define TESTWIDGET3_H + +#include + +class TestWidget3 : public DuiWidgetController +{ + Q_OBJECT; +}; + +#endif + diff --git a/tests/ft_duistylesheetparser/.gitignore b/tests/ft_duistylesheetparser/.gitignore new file mode 100644 index 000000000..6e29174ee --- /dev/null +++ b/tests/ft_duistylesheetparser/.gitignore @@ -0,0 +1,2 @@ +ft_duistylesheetparser + diff --git a/tests/ft_duistylesheetparser/ft_duistylesheetparser.cpp b/tests/ft_duistylesheetparser/ft_duistylesheetparser.cpp new file mode 100644 index 000000000..9085809e7 --- /dev/null +++ b/tests/ft_duistylesheetparser/ft_duistylesheetparser.cpp @@ -0,0 +1,667 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ft_duistylesheetparser.h" +#include "duiapplication.h" +#include +#include +#include +#include "../../src/style/duistylesheetattribute.h" +#include "../../src/theme/duilogicalvalues.h" + +// include this to get theme profiling support +//#include "../../src/theme/duitheme_p.h" + +const int NUMBER_OF_LOOPS = 100; + +Ft_DuiStyleSheetParser::Ft_DuiStyleSheetParser() +{ +} + +void Ft_DuiStyleSheetParser::init() +{ + m_logicalValues = new DuiLogicalValues; + m_logicalValues->append(qApp->applicationDirPath() + QDir::separator() + "ft_duistylesheetparser_logicalvalues.ini"); + m_subject = new DuiStyleSheetParser(m_logicalValues); +} + +void Ft_DuiStyleSheetParser::cleanup() +{ + delete m_subject; + delete m_logicalValues; +} + +DuiApplication *app; + +void Ft_DuiStyleSheetParser::initTestCase() +{ + static int argc = 1; + static char *app_name[1] = { (char *) "./ft_duistylesheetparser" }; + app = new DuiApplication(argc, app_name); +} + +void Ft_DuiStyleSheetParser::cleanupTestCase() +{ + delete app; +} + +const int SELECTOR_COUNT = 23; + + +void Ft_DuiStyleSheetParser::test_load() +{ + QMap attributes; + attributes.insert("attribute-integer", "10"); + attributes.insert("attribute-real", "10.0"); + attributes.insert("attribute-string", "\"string;\""); + attributes.insert("attribute-bool", "true"); + attributes.insert("attribute-point", "10px 10px"); + attributes.insert("attribute-font", "sans 10px"); + attributes.insert("attribute-color", "#ffffff"); + + QMap parentAttributes; + parentAttributes.insert("attribute-integer", "10"); + parentAttributes.insert("attribute-real", "10.0"); + parentAttributes.insert("attribute-string", "\"string\""); + parentAttributes.insert("attribute-bool", "true"); + parentAttributes.insert("attribute-point", "10px 10px"); + parentAttributes.insert("attribute-font", "sans 10px"); + parentAttributes.insert("attribute-color", "#ffffff"); + + m_subject->setBinaryFileGenerationEnabled(false); + + // Test that the load fails if file doesn't exist + QCOMPARE(m_subject->load("non-existing-file.css"), false); + + // Open test file + QCOMPARE(m_subject->load(qApp->applicationDirPath() + "/ft_duistylesheetparser_test.css"), true); + QCOMPARE(m_subject->fileInfoList().count(), 1); + + DuiStyleSheetParser::StylesheetFileInfo *fi = m_subject->fileInfoList().value(0); + + + + + // Check that there's correct amount of selectors + QCOMPARE(fi->selectors.count() + fi->parentSelectors.count(), SELECTOR_COUNT); + int selectorId = 0; + int parentSelectorId = 0; + + QCOMPARE(fi->selectors[selectorId]->parentName(), QString("")); + QCOMPARE(fi->selectors[selectorId]->className(), QString("TestObject")); + QCOMPARE(fi->selectors[selectorId]->objectName(), QString("")); + QCOMPARE(fi->selectors[selectorId]->classType(), QString("")); + QCOMPARE(fi->selectors[selectorId]->orientation(), QString("")); + QCOMPARE(fi->selectors[selectorId]->mode(), QString("")); + QCOMPARE(fi->selectors[selectorId++]->attributes()->count(), 7); + //check that the attributes contain right values + DuiAttributeList::const_iterator i; + for (i = fi->selectors[0]->attributes()->constBegin(); i != fi->selectors[0]->attributes()->constEnd(); ++i) { + QVERIFY(attributes.contains((*i)->name)); + QCOMPARE((*i)->value, attributes.value((*i)->name)); + } + + QCOMPARE(fi->parentSelectors[parentSelectorId]->parentName(), QString("ParentName")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->className(), QString("TestObject")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->objectName(), QString("")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->classType(), QString("")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->orientation(), QString("")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->mode(), QString("")); + QCOMPARE(fi->parentSelectors[parentSelectorId++]->attributes()->count(), 7); + //check that the attributes contain right values + for (i = fi->parentSelectors[0]->attributes()->constBegin(); i != fi->parentSelectors[0]->attributes()->constEnd(); ++i) { + QVERIFY(parentAttributes.contains((*i)->name)); + QCOMPARE((*i)->value, parentAttributes.value((*i)->name)); + } + + + + QCOMPARE(fi->selectors[selectorId]->parentName(), QString("")); + QCOMPARE(fi->selectors[selectorId]->className(), QString("TestObject")); + QCOMPARE(fi->selectors[selectorId]->objectName(), QString("Specialized")); + QCOMPARE(fi->selectors[selectorId]->classType(), QString("")); + QCOMPARE(fi->selectors[selectorId]->orientation(), QString("")); + QCOMPARE(fi->selectors[selectorId]->mode(), QString("")); + QVERIFY((fi->selectors[selectorId]->flags() & DuiStyleSheetSelector::Child) == 0); + QCOMPARE(fi->selectors[selectorId++]->attributes()->count(), 3); + + QCOMPARE(fi->parentSelectors[parentSelectorId]->parentName(), QString("ParentName")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->className(), QString("TestObject")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->objectName(), QString("Specialized")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->classType(), QString("")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->orientation(), QString("")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->mode(), QString("")); + QVERIFY((fi->parentSelectors[parentSelectorId]->flags() & DuiStyleSheetSelector::Child) == 0); + QCOMPARE(fi->parentSelectors[parentSelectorId++]->attributes()->count(), 3); + + + + QCOMPARE(fi->selectors[selectorId]->parentName(), QString("")); + QCOMPARE(fi->selectors[selectorId]->className(), QString("TestObject")); + QCOMPARE(fi->selectors[selectorId]->objectName(), QString("")); + QCOMPARE(fi->selectors[selectorId]->classType(), QString("")); + QCOMPARE(fi->selectors[selectorId]->orientation(), QString("")); + QCOMPARE(fi->selectors[selectorId]->mode(), QString("Disabled")); + QCOMPARE(fi->selectors[selectorId++]->attributes()->count(), 1); + + QCOMPARE(fi->parentSelectors[parentSelectorId]->parentName(), QString("ParentName")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->className(), QString("TestObject")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->objectName(), QString("")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->classType(), QString("")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->orientation(), QString("")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->mode(), QString("Disabled")); + QCOMPARE(fi->parentSelectors[parentSelectorId++]->attributes()->count(), 1); + + + + QCOMPARE(fi->selectors[selectorId]->parentName(), QString("")); + QCOMPARE(fi->selectors[selectorId]->className(), QString("TestObject")); + QCOMPARE(fi->selectors[selectorId]->objectName(), QString("")); + QCOMPARE(fi->selectors[selectorId]->classType(), QString("")); + QCOMPARE(fi->selectors[selectorId]->orientation(), QString("")); + QCOMPARE(fi->selectors[selectorId]->mode(), QString("Active")); + QCOMPARE(fi->selectors[selectorId++]->attributes()->count(), 1); + + QCOMPARE(fi->parentSelectors[parentSelectorId]->parentName(), QString("ParentName")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->className(), QString("TestObject")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->objectName(), QString("")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->classType(), QString("")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->orientation(), QString("")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->mode(), QString("Active")); + QCOMPARE(fi->parentSelectors[parentSelectorId++]->attributes()->count(), 1); + + + + QCOMPARE(fi->selectors[selectorId]->parentName(), QString("")); + QCOMPARE(fi->selectors[selectorId]->className(), QString("TestObject")); + QCOMPARE(fi->selectors[selectorId]->objectName(), QString("Specialized")); + QCOMPARE(fi->selectors[selectorId]->classType(), QString("")); + QCOMPARE(fi->selectors[selectorId]->orientation(), QString("")); + QCOMPARE(fi->selectors[selectorId]->mode(), QString("Active")); + QCOMPARE(fi->selectors[selectorId++]->attributes()->count(), 1); + + QCOMPARE(fi->parentSelectors[parentSelectorId]->parentName(), QString("ParentName")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->className(), QString("TestObject")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->objectName(), QString("Specialized")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->classType(), QString("")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->orientation(), QString("")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->mode(), QString("Active")); + QCOMPARE(fi->parentSelectors[parentSelectorId++]->attributes()->count(), 1); + + + + QCOMPARE(fi->selectors[selectorId]->parentName(), QString("")); + QCOMPARE(fi->selectors[selectorId]->className(), QString("TestObject")); + QCOMPARE(fi->selectors[selectorId]->objectName(), QString("")); + QCOMPARE(fi->selectors[selectorId]->classType(), QString("")); + QCOMPARE(fi->selectors[selectorId]->orientation(), QString("Portrait")); + QCOMPARE(fi->selectors[selectorId]->mode(), QString("")); + QCOMPARE(fi->selectors[selectorId++]->attributes()->count(), 1); + + QCOMPARE(fi->parentSelectors[parentSelectorId]->parentName(), QString("ParentName")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->className(), QString("TestObject")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->objectName(), QString("")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->classType(), QString("")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->orientation(), QString("Portrait")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->mode(), QString("")); + QCOMPARE(fi->parentSelectors[parentSelectorId++]->attributes()->count(), 1); + + + + QCOMPARE(fi->selectors[selectorId]->parentName(), QString("")); + QCOMPARE(fi->selectors[selectorId]->className(), QString("TestObject")); + QCOMPARE(fi->selectors[selectorId]->objectName(), QString("")); + QCOMPARE(fi->selectors[selectorId]->classType(), QString("")); + QCOMPARE(fi->selectors[selectorId]->orientation(), QString("Landscape")); + QCOMPARE(fi->selectors[selectorId]->mode(), QString("")); + QCOMPARE(fi->selectors[selectorId++]->attributes()->count(), 1); + + QCOMPARE(fi->parentSelectors[parentSelectorId]->parentName(), QString("ParentName")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->className(), QString("TestObject")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->objectName(), QString("")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->classType(), QString("")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->orientation(), QString("Landscape")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->mode(), QString("")); + QCOMPARE(fi->parentSelectors[parentSelectorId++]->attributes()->count(), 1); + + + + QCOMPARE(fi->selectors[selectorId]->parentName(), QString("")); + QCOMPARE(fi->selectors[selectorId]->className(), QString("TestObject")); + QCOMPARE(fi->selectors[selectorId]->objectName(), QString("Specialized")); + QCOMPARE(fi->selectors[selectorId]->classType(), QString("")); + QCOMPARE(fi->selectors[selectorId]->orientation(), QString("Portrait")); + QCOMPARE(fi->selectors[selectorId]->mode(), QString("Active")); + QCOMPARE(fi->selectors[selectorId++]->attributes()->count(), 2); + + QCOMPARE(fi->parentSelectors[parentSelectorId]->parentName(), QString("ParentName")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->className(), QString("TestObject")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->objectName(), QString("Specialized")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->classType(), QString("")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->orientation(), QString("Portrait")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->mode(), QString("Active")); + QCOMPARE(fi->parentSelectors[parentSelectorId++]->attributes()->count(), 2); + + + + QCOMPARE(fi->selectors[selectorId]->parentName(), QString("")); + QCOMPARE(fi->selectors[selectorId]->className(), QString("TestObject")); + QCOMPARE(fi->selectors[selectorId]->objectName(), QString("")); + QCOMPARE(fi->selectors[selectorId]->classType(), QString("icon")); + QCOMPARE(fi->selectors[selectorId]->orientation(), QString("")); + QCOMPARE(fi->selectors[selectorId]->mode(), QString("")); + QCOMPARE(fi->selectors[selectorId++]->attributes()->count(), 1); + + QCOMPARE(fi->parentSelectors[parentSelectorId]->parentName(), QString("ParentName")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->className(), QString("TestObject")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->objectName(), QString("")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->classType(), QString("icon")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->orientation(), QString("")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->mode(), QString("")); + QCOMPARE(fi->parentSelectors[parentSelectorId++]->attributes()->count(), 1); + + + + QCOMPARE(fi->selectors[selectorId]->parentName(), QString("")); + QCOMPARE(fi->selectors[selectorId]->className(), QString("TestObject")); + QCOMPARE(fi->selectors[selectorId]->objectName(), QString("")); + QCOMPARE(fi->selectors[selectorId]->classType(), QString("fancy")); + QCOMPARE(fi->selectors[selectorId]->orientation(), QString("")); + QCOMPARE(fi->selectors[selectorId]->mode(), QString("")); + QCOMPARE(fi->selectors[selectorId++]->attributes()->count(), 1); + + QCOMPARE(fi->parentSelectors[parentSelectorId]->parentName(), QString("ParentName")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->className(), QString("TestObject")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->objectName(), QString("")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->classType(), QString("fancy")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->orientation(), QString("")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->mode(), QString("")); + QCOMPARE(fi->parentSelectors[parentSelectorId++]->attributes()->count(), 1); + + + + QCOMPARE(fi->selectors[selectorId]->parentName(), QString("")); + QCOMPARE(fi->selectors[selectorId]->className(), QString("TestObject")); + QCOMPARE(fi->selectors[selectorId]->objectName(), QString("Specialized")); + QCOMPARE(fi->selectors[selectorId]->classType(), QString("icon")); + QCOMPARE(fi->selectors[selectorId]->orientation(), QString("")); + QCOMPARE(fi->selectors[selectorId]->mode(), QString("")); + QCOMPARE(fi->selectors[selectorId++]->attributes()->count(), 1); + + QCOMPARE(fi->parentSelectors[parentSelectorId]->parentName(), QString("ParentName")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->className(), QString("TestObject")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->objectName(), QString("Specialized")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->classType(), QString("icon")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->orientation(), QString("")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->mode(), QString("")); + QCOMPARE(fi->parentSelectors[parentSelectorId++]->attributes()->count(), 1); + + QCOMPARE(fi->parentSelectors[parentSelectorId]->parentName(), QString("ParentName")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->className(), QString("TestObject")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->objectName(), QString("Specialized")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->classType(), QString("icon")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->orientation(), QString("")); + QCOMPARE(fi->parentSelectors[parentSelectorId]->mode(), QString("")); + QVERIFY((fi->parentSelectors[parentSelectorId]->flags() & DuiStyleSheetSelector::Child) != 0); + QCOMPARE(fi->parentSelectors[parentSelectorId++]->attributes()->count(), 1); +} + +void Ft_DuiStyleSheetParser::test_import() +{ + m_subject->setBinaryFileGenerationEnabled(false); + + QList importedFiles; + importedFiles.append("ft_duistylesheetparser_import.css"); + importedFiles.append("ft_duistylesheetparser_import1.css"); + importedFiles.append("ft_duistylesheetparser_import2.css"); + importedFiles.append("ft_duistylesheetparser_constants1.css"); + importedFiles.append("ft_duistylesheetparser_test.css"); + + QCOMPARE(m_subject->load(qApp->applicationDirPath() + "/ft_duistylesheetparser_import.css"), true); + QCOMPARE(m_subject->fileInfoList().count(), 5); + int numberOfSelectors = 0; + for (QList::iterator fi = m_subject->fileInfoList().begin(); + fi != m_subject->fileInfoList().end(); + fi++) { + QFileInfo fileinfo((*fi)->filename); + QVERIFY(importedFiles.indexOf(fileinfo.fileName()) != -1); + numberOfSelectors += (*fi)->selectors.count(); + numberOfSelectors += (*fi)->parentSelectors.count(); + } + QCOMPARE(numberOfSelectors, SELECTOR_COUNT); +} + +void Ft_DuiStyleSheetParser::test_constants() +{ + m_subject->setBinaryFileGenerationEnabled(false); + + // Open test file + QCOMPARE(m_subject->load(qApp->applicationDirPath() + "/ft_duistylesheetparser_constants.css"), true); + + //check that file count is correct + QCOMPARE(m_subject->fileInfoList().count(), 3); + + DuiStyleSheetParser::StylesheetFileInfo *info = m_subject->fileInfoList()[0]; + QCOMPARE(info->constants.count(), 5); + QCOMPARE(info->constants["cWidth"], QString("10px")); + QCOMPARE(info->constants["cHeight"], QString("15px")); + QCOMPARE(info->constants["cFontFamily"], QString("sans")); + QCOMPARE(info->constants["cFontSize"], QString("12px")); + QCOMPARE(info->constants["cColor"], QString("#0abba0")); + info = m_subject->fileInfoList()[1]; + QCOMPARE(info->constants.count(), 0); + info = m_subject->fileInfoList()[2]; + QCOMPARE(info->constants.count(), 7); + QCOMPARE(info->constants["cInt"], QString("10")); + QCOMPARE(info->constants["cReal"], QString("1.0")); + QCOMPARE(info->constants["cName"], QString("\"name\"")); + QCOMPARE(info->constants["cColor"], QString("#0dead0")); + QCOMPARE(info->constants["cBool"], QString("true")); + QCOMPARE(info->constants["cPoint"], QString("17px 11px")); + QCOMPARE(info->constants["cFont"], QString("arial 10px")); + + //check that there are right number of attributes + info = m_subject->fileInfoList()[0]; + QCOMPARE(info->selectors.count(), 0); + info = m_subject->fileInfoList()[1]; + QCOMPARE(info->selectors.count(), 1); + QCOMPARE(info->selectors[0]->attributes()->count(), 1); + QVERIFY(info->selectors[0]->attributes()->value("attr-width", NULL)); + QCOMPARE(info->selectors[0]->attributes()->value("attr-width")->name, QString("attr-width")); + QCOMPARE(info->selectors[0]->attributes()->value("attr-width")->value, QString("10px")); + info = m_subject->fileInfoList()[2]; + QCOMPARE(info->selectors.count(), 1); + QCOMPARE(info->selectors[0]->attributes()->count(), 13); + QVERIFY(info->selectors[0]->attributes()->value("attr-int", NULL)); + QCOMPARE(info->selectors[0]->attributes()->value("attr-int")->name, QString("attr-int")); + QCOMPARE(info->selectors[0]->attributes()->value("attr-int")->value, QString("10")); + QVERIFY(info->selectors[0]->attributes()->value("attr-string1", NULL)); + QCOMPARE(info->selectors[0]->attributes()->value("attr-string1")->name, QString("attr-string1")); + QCOMPARE(info->selectors[0]->attributes()->value("attr-string1")->value, QString("\"name\"")); + QVERIFY(info->selectors[0]->attributes()->value("attr-string2", NULL)); + QCOMPARE(info->selectors[0]->attributes()->value("attr-string2")->name, QString("attr-string2")); + QCOMPARE(info->selectors[0]->attributes()->value("attr-string2")->value, QString("\"this is a string with constant $cName\"")); + QVERIFY(info->selectors[0]->attributes()->value("attr-bool", NULL)); + QCOMPARE(info->selectors[0]->attributes()->value("attr-bool")->name, QString("attr-bool")); + QCOMPARE(info->selectors[0]->attributes()->value("attr-bool")->value, QString("true")); + QVERIFY(info->selectors[0]->attributes()->value("attr-pos1", NULL)); + QCOMPARE(info->selectors[0]->attributes()->value("attr-pos1")->name, QString("attr-pos1")); + QCOMPARE(info->selectors[0]->attributes()->value("attr-pos1")->value, QString("10px 15px")); + QVERIFY(info->selectors[0]->attributes()->value("attr-pos2", NULL)); + QCOMPARE(info->selectors[0]->attributes()->value("attr-pos2")->name, QString("attr-pos2")); + QCOMPARE(info->selectors[0]->attributes()->value("attr-pos2")->value, QString("17px 11px")); + QVERIFY(info->selectors[0]->attributes()->value("attr-font1", NULL)); + QCOMPARE(info->selectors[0]->attributes()->value("attr-font1")->name, QString("attr-font1")); + QCOMPARE(info->selectors[0]->attributes()->value("attr-font1")->value, QString("sans 12px")); + QVERIFY(info->selectors[0]->attributes()->value("attr-font2", NULL)); + QCOMPARE(info->selectors[0]->attributes()->value("attr-font2")->name, QString("attr-font2")); + QCOMPARE(info->selectors[0]->attributes()->value("attr-font2")->value, QString("arial 10px")); + QVERIFY(info->selectors[0]->attributes()->value("attr-color", NULL)); + QCOMPARE(info->selectors[0]->attributes()->value("attr-color")->name, QString("attr-color")); + QCOMPARE(info->selectors[0]->attributes()->value("attr-color")->value, QString("#0abba0")); + QVERIFY(info->selectors[0]->attributes()->value("attr-invalid", NULL)); + QCOMPARE(info->selectors[0]->attributes()->value("attr-invalid")->name, QString("attr-invalid")); + QCOMPARE(info->selectors[0]->attributes()->value("attr-invalid")->value, QString("")); + QVERIFY(info->selectors[0]->attributes()->value("attr-void", NULL)); + QCOMPARE(info->selectors[0]->attributes()->value("attr-void")->name, QString("attr-void")); + QCOMPARE(info->selectors[0]->attributes()->value("attr-void")->value, QString("")); + QCOMPARE(info->selectors[0]->attributes()->value("attr-logical-black")->name, QString("attr-logical-black")); + QCOMPARE(info->selectors[0]->attributes()->value("attr-logical-black")->value, QString("#000000")); + QCOMPARE(info->selectors[0]->attributes()->value("attr-logical-green")->name, QString("attr-logical-green")); + QCOMPARE(info->selectors[0]->attributes()->value("attr-logical-green")->value, QString("#00ff00")); +} + +void Ft_DuiStyleSheetParser::test_constants_binary() +{ + //read css from binary + m_subject->setBinaryFileGenerationEnabled(true); + QCOMPARE(m_subject->load(qApp->applicationDirPath() + "/ft_duistylesheetparser_constants.css"), true); + delete m_subject; + + m_subject = new DuiStyleSheetParser(m_logicalValues); + QCOMPARE(m_subject->load(qApp->applicationDirPath() + "/ft_duistylesheetparser_constants.css"), true); + + //check that file count is correct + QCOMPARE(m_subject->fileInfoList().count(), 3); + + DuiStyleSheetParser::StylesheetFileInfo *info = m_subject->fileInfoList()[0]; + QCOMPARE(info->constants.count(), 5); + QCOMPARE(info->constants["cWidth"], QString("10px")); + QCOMPARE(info->constants["cHeight"], QString("15px")); + QCOMPARE(info->constants["cFontFamily"], QString("sans")); + QCOMPARE(info->constants["cFontSize"], QString("12px")); + QCOMPARE(info->constants["cColor"], QString("#0abba0")); + info = m_subject->fileInfoList()[1]; + QCOMPARE(info->constants.count(), 0); + info = m_subject->fileInfoList()[2]; + QCOMPARE(info->constants.count(), 7); + QCOMPARE(info->constants["cInt"], QString("10")); + QCOMPARE(info->constants["cReal"], QString("1.0")); + QCOMPARE(info->constants["cName"], QString("\"name\"")); + QCOMPARE(info->constants["cColor"], QString("#0dead0")); + QCOMPARE(info->constants["cBool"], QString("true")); + QCOMPARE(info->constants["cPoint"], QString("17px 11px")); + QCOMPARE(info->constants["cFont"], QString("arial 10px")); + + //check that there are right number of attributes + info = m_subject->fileInfoList()[0]; + QCOMPARE(info->selectors.count(), 0); + info = m_subject->fileInfoList()[1]; + QCOMPARE(info->selectors.count(), 1); + QCOMPARE(info->selectors[0]->attributes()->count(), 1); + QVERIFY(info->selectors[0]->attributes()->value("attr-width", NULL)); + QCOMPARE(info->selectors[0]->attributes()->value("attr-width")->name, QString("attr-width")); + QCOMPARE(info->selectors[0]->attributes()->value("attr-width")->value, QString("10px")); + info = m_subject->fileInfoList()[2]; + QCOMPARE(info->selectors.count(), 1); + QCOMPARE(info->selectors[0]->attributes()->count(), 13); + QVERIFY(info->selectors[0]->attributes()->value("attr-int", NULL)); + QCOMPARE(info->selectors[0]->attributes()->value("attr-int")->name, QString("attr-int")); + QCOMPARE(info->selectors[0]->attributes()->value("attr-int")->value, QString("10")); + QVERIFY(info->selectors[0]->attributes()->value("attr-string1", NULL)); + QCOMPARE(info->selectors[0]->attributes()->value("attr-string1")->name, QString("attr-string1")); + QCOMPARE(info->selectors[0]->attributes()->value("attr-string1")->value, QString("\"name\"")); + QVERIFY(info->selectors[0]->attributes()->value("attr-string2", NULL)); + QCOMPARE(info->selectors[0]->attributes()->value("attr-string2")->name, QString("attr-string2")); + QCOMPARE(info->selectors[0]->attributes()->value("attr-string2")->value, QString("\"this is a string with constant $cName\"")); + QVERIFY(info->selectors[0]->attributes()->value("attr-bool", NULL)); + QCOMPARE(info->selectors[0]->attributes()->value("attr-bool")->name, QString("attr-bool")); + QCOMPARE(info->selectors[0]->attributes()->value("attr-bool")->value, QString("true")); + QVERIFY(info->selectors[0]->attributes()->value("attr-pos1", NULL)); + QCOMPARE(info->selectors[0]->attributes()->value("attr-pos1")->name, QString("attr-pos1")); + QCOMPARE(info->selectors[0]->attributes()->value("attr-pos1")->value, QString("10px 15px")); + QVERIFY(info->selectors[0]->attributes()->value("attr-pos2", NULL)); + QCOMPARE(info->selectors[0]->attributes()->value("attr-pos2")->name, QString("attr-pos2")); + QCOMPARE(info->selectors[0]->attributes()->value("attr-pos2")->value, QString("17px 11px")); + QVERIFY(info->selectors[0]->attributes()->value("attr-font1", NULL)); + QCOMPARE(info->selectors[0]->attributes()->value("attr-font1")->name, QString("attr-font1")); + QCOMPARE(info->selectors[0]->attributes()->value("attr-font1")->value, QString("sans 12px")); + QVERIFY(info->selectors[0]->attributes()->value("attr-font2", NULL)); + QCOMPARE(info->selectors[0]->attributes()->value("attr-font2")->name, QString("attr-font2")); + QCOMPARE(info->selectors[0]->attributes()->value("attr-font2")->value, QString("arial 10px")); + QVERIFY(info->selectors[0]->attributes()->value("attr-color", NULL)); + QCOMPARE(info->selectors[0]->attributes()->value("attr-color")->name, QString("attr-color")); + QCOMPARE(info->selectors[0]->attributes()->value("attr-color")->value, QString("#0abba0")); + QVERIFY(info->selectors[0]->attributes()->value("attr-invalid", NULL)); + QCOMPARE(info->selectors[0]->attributes()->value("attr-invalid")->name, QString("attr-invalid")); + QCOMPARE(info->selectors[0]->attributes()->value("attr-invalid")->value, QString("")); + QVERIFY(info->selectors[0]->attributes()->value("attr-void", NULL)); + QCOMPARE(info->selectors[0]->attributes()->value("attr-void")->name, QString("attr-void")); + QCOMPARE(info->selectors[0]->attributes()->value("attr-void")->value, QString("")); + QCOMPARE(info->selectors[0]->attributes()->value("attr-logical-black")->name, QString("attr-logical-black")); + QCOMPARE(info->selectors[0]->attributes()->value("attr-logical-black")->value, QString("#000000")); + QCOMPARE(info->selectors[0]->attributes()->value("attr-logical-green")->name, QString("attr-logical-green")); + QCOMPARE(info->selectors[0]->attributes()->value("attr-logical-green")->value, QString("#00ff00")); +} + +void Ft_DuiStyleSheetParser::test_binary_equality() +{ + // parse test css file, dumping it to file + DuiStyleSheetParser *parser = new DuiStyleSheetParser(); + parser->setBinaryFileGenerationEnabled(true); + QCOMPARE(parser->load(qApp->applicationDirPath() + "/ft_duistylesheetparser_test.css"), true); + +// // load binary file, see that it exists +// QVERIFY(QFile::exists(QDir::tempPath() + QDir::separator() + "ft_duistylesheetparser_test.css.bin")); + + DuiStyleSheetParser *binary = new DuiStyleSheetParser(); + QCOMPARE(binary->load(qApp->applicationDirPath() + "/ft_duistylesheetparser_test.css"), true); + + // check that there is equal count of file infos + QCOMPARE(parser->fileInfoList().count(), binary->fileInfoList().count()); + + QList::iterator parserFi = parser->fileInfoList().begin(); + QList::iterator binaryFi = binary->fileInfoList().begin(); + + for (int i = 0; i < parser->fileInfoList().count(); i++) { + // check that there is equal count of constants + QCOMPARE((*parserFi)->constants.count(), (*binaryFi)->constants.count()); + + // check that there is equal count of selectors + QCOMPARE((*parserFi)->selectors.count(), (*binaryFi)->selectors.count()); + + QList::iterator parserSelectors = (*parserFi)->selectors.begin(); + QList::iterator binarySelectors = (*binaryFi)->selectors.begin(); + + // loop through all the selectors, check that they are equal + for (int i = 0; i < (*parserFi)->selectors.count(); i++) { + // Get selectors + DuiStyleSheetSelector *selector0 = *parserSelectors; + DuiStyleSheetSelector *selector1 = *binarySelectors; + + // check that selector properties are equal + QCOMPARE(selector0->parentName(), selector1->parentName()); + QCOMPARE(selector0->objectName(), selector1->objectName()); + QCOMPARE(selector0->className(), selector1->className()); + QCOMPARE(selector0->orientation(), selector1->orientation()); + QCOMPARE(selector0->mode(), selector1->mode()); + + // check that amount of attributes is equal + QCOMPARE(selector0->attributes()->count(), selector1->attributes()->count()); + + // loop through all attributes, check that they are equal + DuiAttributeList::iterator selector0Attributes = selector0->attributes()->begin(); + DuiAttributeList::iterator selector1Attributes = selector1->attributes()->begin(); + for (int attributeIndex = 0; attributeIndex < selector0->attributes()->count(); attributeIndex++) { + QCOMPARE(selector0Attributes.key(), selector1Attributes.key()); + QCOMPARE(selector0Attributes.value()->name, selector1Attributes.value()->name); + QCOMPARE(selector0Attributes.value()->value, selector1Attributes.value()->value); + + selector0Attributes++; + selector1Attributes++; + } + + parserSelectors++; + binarySelectors++; + } + + parserFi++; + binaryFi++; + } + delete parser; + delete binary; +} + +void Ft_DuiStyleSheetParser::test_parser_speed() +{ + unsigned long int TIMERS[NUMBER_OF_LOOPS]; + unsigned long int TOTAL_TIME = 0; + + clock_t test_start, time_start; + clock_t time_end; + + qDebug() << "Testing speed of CSS parser, reading ft_duistylesheetparser_test.css" << NUMBER_OF_LOOPS << "times"; + + test_start = clock(); + + for (int i = 0; i < NUMBER_OF_LOOPS; i++) { + DuiStyleSheetParser *p = new DuiStyleSheetParser(); + p->setBinaryFileGenerationEnabled(false); + + // Start clocking + time_start = clock(); + // Open test file + QCOMPARE(p->load(qApp->applicationDirPath() + "/ft_duistylesheetparser_test.css"), true); + // End clocking + time_end = clock(); + + // Store result & cleanup + TIMERS[i] = time_end - time_start; + delete p; + } + + TOTAL_TIME = time_end - test_start; + + long average = 0; + for (int i = 0; i < NUMBER_OF_LOOPS; i++) { + average += TIMERS[i]; + } + average /= NUMBER_OF_LOOPS; + + qDebug() << "Average reading time:" << average << "microseconds (" << average / 1000000.0 << "seconds)"; + qDebug() << "Total reading time:" << TOTAL_TIME << "microseconds (" << TOTAL_TIME / 1000000.0 << "seconds)"; +} + +void Ft_DuiStyleSheetParser::test_binary_speed() +{ + unsigned long int TIMERS[NUMBER_OF_LOOPS]; + unsigned long int TOTAL_TIME = 0; + + clock_t test_start, time_start; + clock_t time_end; + + // create binary file, if it doesn't exist + DuiStyleSheetParser *tmp = new DuiStyleSheetParser(); + tmp->setBinaryFileGenerationEnabled(true); + QCOMPARE(tmp->load(qApp->applicationDirPath() + "/ft_duistylesheetparser_test.css"), true); + delete tmp; + + qDebug() << "Testing speed of binary css files, reading ft_duistylesheetparser_test.css" << NUMBER_OF_LOOPS << "times"; + + test_start = clock(); + + for (int i = 0; i < NUMBER_OF_LOOPS; i++) { + DuiStyleSheetParser *p = new DuiStyleSheetParser(); + p->setBinaryFileGenerationEnabled(true); + + // Start clocking + time_start = clock(); + // Open test file + QCOMPARE(p->load(qApp->applicationDirPath() + "/ft_duistylesheetparser_test.css"), true); + // End clocking + time_end = clock(); + + // Store result & cleanup + TIMERS[i] = time_end - time_start; + delete p; + } + + TOTAL_TIME = time_end - test_start; + + long average = 0; + for (int i = 0; i < NUMBER_OF_LOOPS; i++) { + average += TIMERS[i]; + } + average /= NUMBER_OF_LOOPS; + + qDebug() << "Average reading time:" << average << "microseconds (" << average / 1000000.0 << "seconds)"; + qDebug() << "Total reading time:" << TOTAL_TIME << "microseconds (" << TOTAL_TIME / 1000000.0 << "seconds)"; +} + +QTEST_APPLESS_MAIN(Ft_DuiStyleSheetParser) diff --git a/tests/ft_duistylesheetparser/ft_duistylesheetparser.h b/tests/ft_duistylesheetparser/ft_duistylesheetparser.h new file mode 100644 index 000000000..55b30ef92 --- /dev/null +++ b/tests/ft_duistylesheetparser/ft_duistylesheetparser.h @@ -0,0 +1,69 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef FT_CSS_H +#define FT_CSS_H + +#include +#include +#include +#include +#include +#include + +class DuiLogicalValues; + +class Ft_DuiStyleSheetParser : public QObject +{ + Q_OBJECT +public: + Ft_DuiStyleSheetParser(); + +private slots: + void init(); + void cleanup(); + void initTestCase(); + void cleanupTestCase(); + void test_load(); + void test_import(); + void test_constants(); + void test_constants_binary(); + void test_binary_equality(); + void test_parser_speed(); + void test_binary_speed(); + + /*void test_inheritance(); + void test_objectnames(); + void test_orientations(); + void test_modes(); + void test_types(); + void test_complex(); + + + void test_cache_size(); + */ + +private: + + DuiLogicalValues *m_logicalValues; + DuiStyleSheetParser *m_subject; +}; + +#endif + diff --git a/tests/ft_duistylesheetparser/ft_duistylesheetparser.pro b/tests/ft_duistylesheetparser/ft_duistylesheetparser.pro new file mode 100644 index 000000000..54c166f57 --- /dev/null +++ b/tests/ft_duistylesheetparser/ft_duistylesheetparser.pro @@ -0,0 +1,21 @@ +include(../common_top.pri) +TARGET = ft_duistylesheetparser +QT += dbus svg network +LIBRARYPATH += $$DUISRCDIR + +SOURCES += \ + ft_duistylesheetparser.cpp \ + ../../src/theme/duilogicalvalues.cpp \ + ../../src/style/duistylesheetattribute.cpp + + +HEADERS += \ + ft_duistylesheetparser.h \ + ../../src/theme/duilogicalvalues.h \ + ../../src/style/duistylesheetattribute.h + +support_files.files += \ + *.css \ + *.ini + +include(../common_bot.pri) diff --git a/tests/ft_duistylesheetparser/ft_duistylesheetparser_constants.css b/tests/ft_duistylesheetparser/ft_duistylesheetparser_constants.css new file mode 100644 index 000000000..9adc7ea4a --- /dev/null +++ b/tests/ft_duistylesheetparser/ft_duistylesheetparser_constants.css @@ -0,0 +1,39 @@ +// This is a test file for Direct UI CSS parser. + +@import "ft_duistylesheetparser_constants1.css"; +@import "ft_duistylesheetparser_constants2.css"; + +//define constants +@const cInt: 10; +@const cReal: 1.0; +@const cName: "name"; +@const cColor: #0dead0; +@const cBool: true; +@const cPoint: 17px 11px; +@const cFont: arial 10px; +@const cInvalid1 Invalid; +@const : Invalid + +//define selector and use the constants +TestObject +{ + attr-int: $cInt; + attr-string1: "name"; + attr-string2: "this is a string with constant $cName"; + attr-bool: $cBool; + attr-pos1: $cWidth $cHeight; /* comment after the attribute */ + attr-pos2: $cPoint; + attr-font1: $cFontFamily $cFontSize; // comment after the attribute + attr-font2: $cFont; /* multi-line + comment after the attribute + */ + attr-color: $cColor; + attr-invalid: $cInvalid1; + attr-void: $cVoid; + attr-logical-black: $COLOR_BLACK; + attr-logical-green: $COLOR_GREEN; +} /* this is a comment in end of file */ +// another end-of-file-comment +/* and still another one + which is spread into multiple lines */ + diff --git a/tests/ft_duistylesheetparser/ft_duistylesheetparser_constants1.css b/tests/ft_duistylesheetparser/ft_duistylesheetparser_constants1.css new file mode 100644 index 000000000..f69a6f929 --- /dev/null +++ b/tests/ft_duistylesheetparser/ft_duistylesheetparser_constants1.css @@ -0,0 +1,8 @@ +// This is a test file for Direct UI CSS parser. + +//define constants +@const cWidth: 10px; +@const cHeight: 15px; +@const cFontFamily: sans; +@const cFontSize: 12px; +@const cColor:#0abba0; diff --git a/tests/ft_duistylesheetparser/ft_duistylesheetparser_constants2.css b/tests/ft_duistylesheetparser/ft_duistylesheetparser_constants2.css new file mode 100644 index 000000000..82ea0a352 --- /dev/null +++ b/tests/ft_duistylesheetparser/ft_duistylesheetparser_constants2.css @@ -0,0 +1,4 @@ +TestObject2 +{ + attr-width: $cWidth; +} diff --git a/tests/ft_duistylesheetparser/ft_duistylesheetparser_import.css b/tests/ft_duistylesheetparser/ft_duistylesheetparser_import.css new file mode 100644 index 000000000..ecec3e3cf --- /dev/null +++ b/tests/ft_duistylesheetparser/ft_duistylesheetparser_import.css @@ -0,0 +1,8 @@ +// This is a test file for DirectUI CSS parser. + +// import other .css files +@import "ft_duistylesheetparser_import1.css"; +@import url("ft_duistylesheetparser_import2.css"); +@import url("ft_duistylesheetparser_import21.css"); + + diff --git a/tests/ft_duistylesheetparser/ft_duistylesheetparser_import1.css b/tests/ft_duistylesheetparser/ft_duistylesheetparser_import1.css new file mode 100644 index 000000000..71ef13d19 --- /dev/null +++ b/tests/ft_duistylesheetparser/ft_duistylesheetparser_import1.css @@ -0,0 +1,5 @@ +// This is a test file for DirectUI CSS parser. + +// import other .css files +@import "ft_duistylesheetparser_constants1.css"; + diff --git a/tests/ft_duistylesheetparser/ft_duistylesheetparser_import2.css b/tests/ft_duistylesheetparser/ft_duistylesheetparser_import2.css new file mode 100644 index 000000000..cc4c8d87d --- /dev/null +++ b/tests/ft_duistylesheetparser/ft_duistylesheetparser_import2.css @@ -0,0 +1,5 @@ +// This is a test file for DirectUI CSS parser. + +// import other .css files +@import "ft_duistylesheetparser_test.css"; + diff --git a/tests/ft_duistylesheetparser/ft_duistylesheetparser_logicalvalues.ini b/tests/ft_duistylesheetparser/ft_duistylesheetparser_logicalvalues.ini new file mode 100644 index 000000000..5d31ba9f8 --- /dev/null +++ b/tests/ft_duistylesheetparser/ft_duistylesheetparser_logicalvalues.ini @@ -0,0 +1,3 @@ +[Palette] +COLOR_BLACK = #000000 +COLOR_GREEN = #00ff00 diff --git a/tests/ft_duistylesheetparser/ft_duistylesheetparser_test.css b/tests/ft_duistylesheetparser/ft_duistylesheetparser_test.css new file mode 100644 index 000000000..696d9d510 --- /dev/null +++ b/tests/ft_duistylesheetparser/ft_duistylesheetparser_test.css @@ -0,0 +1,149 @@ +/* + * This file contains style definitions for TestObject + * class which is inherited from QObject + */ + +// test constants inside the constants +@const color: #ff00ff; +@const constColor: $color; +@const constConstColor: $constColor; + +// General purpose style definitions for Test object +TestObject +{ + //attribute integer + attribute-integer:10; + /*attribute-real*/ + attribute-real: 10.0; + attribute/*interesting*/-string: + "string;"; //string comment + attribute-bool: true;attribute-point: 10px 10px; + attribute-font: /*this is a font*/sans 10px; + attribute-color: #fff/*hmm...*/fff; +} + + +// General purpose style definitions for Test object with parent +ParentName TestObject +{ + //attribute integer + attribute-integer:10; + /*attribute-real*/ + attribute-real: 10.0; + attribute/*interesting*/-string: + "string"; //string comment + attribute-bool: true;attribute-point: 10px 10px; + attribute-font: /*this is a font*/sans 10px; + attribute-color: #fff/*hmm...*/fff; +} + + +// Specialised style definitions +TestObject#Specialized{ + attribute-integer: 100; + attribute-real: 100.0; + attribute-string: "specialized string"; +} + +// Specialised style definitions +ParentName TestObject#Specialized{ + attribute-integer: 100; + attribute-real: 100.0; + attribute-string: "specialized string"; +} + + +TestObject:Disabled +{attribute-color: #aaaaaa;} + +ParentName TestObject:Disabled +{attribute-color: #aaaaaa;} + + +TestObject:Active +{ + attribute-color: #ff0000; +} + +ParentName TestObject:Active +{ + attribute-color: #ff0000; +} + + +TestObject#Specialized:Active +{ + attribute-color: #00ff00; +} + +ParentName TestObject#Specialized:Active +{ + attribute-color: #00ff00; +} + + +TestObject.Portrait{attribute-orientation: 90;} + +ParentName TestObject.Portrait{attribute-orientation: 90;} + + +TestObject./*blaah*/Landscape +{ + attribute-orientation: 0; +} + +ParentName TestObject./*blaah*/Landscape +{ + attribute-orientation: 0; +} + + +TestObject#Specialized.Portrait:Active +{ + attribute-orientation: 270; + attribute-color: constConstColor; +} + +ParentName TestObject#Specialized.Portrait:Active +{ + attribute-orientation: 270; + attribute-color: constColor; +} + + +TestObject[ icon ] +{ + attribute-color: #aaaaaa; +} + +ParentName TestObject[ icon ] +{ + attribute-color: #aaaaaa; +} + + +TestObject[fancy] +{ + attribute-color: #ff0000; +} + +ParentName TestObject[fancy] +{ + attribute-color: #ff0000; +} + + +TestObject[icon]#Specialized +{ + attribute-color: #00ff00; +} + +ParentName TestObject[icon]#Specialized +{ + attribute-color: #00ff00; +} + +ParentName > TestObject[icon]#Specialized +{ + attribute-color: #00ff00; +} diff --git a/tests/ft_duivideowidget/.gitignore b/tests/ft_duivideowidget/.gitignore new file mode 100644 index 000000000..bad9ba2c6 --- /dev/null +++ b/tests/ft_duivideowidget/.gitignore @@ -0,0 +1 @@ +ft_duivideowidget diff --git a/tests/ft_duivideowidget/ft_duivideowidget.cpp b/tests/ft_duivideowidget/ft_duivideowidget.cpp new file mode 100644 index 000000000..dc4280ed3 --- /dev/null +++ b/tests/ft_duivideowidget/ft_duivideowidget.cpp @@ -0,0 +1,198 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ft_duivideowidget.h" +#include "duivideowidget.h" + +#include + +ft_duivideowidget::ft_duivideowidget() +{ + gst_init(NULL, NULL); +} + +ft_duivideowidget::~ft_duivideowidget() +{ + gst_deinit(); +} + +void ft_duivideowidget::init() +{ + m_subject = new DuiVideoWidget(); +} + +void ft_duivideowidget::cleanup() +{ + delete m_subject; +} + +void ft_duivideowidget::initTestCase() +{ +#define MAX_PARAMS 8 + char *argv[MAX_PARAMS]; + int argc = 2; + + argv[0] = strdup("./ut_duibutton"); + argv[1] = strdup("-software"); + + app = new DuiApplication(argc, argv); + + free(argv[0]); + free(argv[1]); +} + +void ft_duivideowidget::cleanupTestCase() +{ + delete app; +} + +void ft_duivideowidget::testInitialState() +{ + QCOMPARE(m_subject->isPlaying(), false); +} + +void ft_duivideowidget::testBogusOpen() +{ + QCOMPARE(m_subject->open(QString("bogusdata")), false); +} + +void ft_duivideowidget::testOpen() +{ + QCOMPARE(m_subject->open(QString("test.avi")), true); +} + +void ft_duivideowidget::testPause() +{ + // disable sounds, we don't want to hear those during the test + m_subject->mute(true); + + QCOMPARE(m_subject->open(QString("test.avi"), true), true); + +QTest: qSleep(1000); + QCOMPARE(m_subject->isPlaying(), true); + + m_subject->pause(); +QTest: qSleep(1000); + QCOMPARE(m_subject->isPlaying(), false); + + m_subject->play(); +QTest: qSleep(1000); + QCOMPARE(m_subject->isPlaying(), true); +} + +void ft_duivideowidget::testVolume() +{ + m_subject->open(QString("test.avi")); + + // setVolume(-0.1); + QCOMPARE(m_subject->volume(), 0.0); + + // >max + m_subject->setVolume(1000); + QCOMPARE(m_subject->volume(), 1.0); +} + +void ft_duivideowidget::testSeek() +{ + m_subject->open(QString("test.avi")); + + // wait for gstreamer machinery +QTest: qSleep(1000); + + // working seek + QCOMPARE(m_subject->seek(10), true); + + // not working seek + QCOMPARE(m_subject->seek(-1), false); +} + +void ft_duivideowidget::testCurrentPos() +{ +} + +void ft_duivideowidget::testMute() +{ + m_subject->open(QString("test.avi")); + + QVERIFY(m_subject->muted() == false); + + // wait for gstreamer machinery +QTest: qSleep(1000); + + m_subject->mute(true); + QVERIFY(m_subject->muted() == true); +} + +void ft_duivideowidget::testCurrentFrame() +{ + m_subject->open(QString("test.avi")); + + // wait for gstreamer machinery +QTest: qSleep(1000); + + QImage test = m_subject->currentFrame(); + QVERIFY(test.isNull() != true); +} + +void ft_duivideowidget::testScaling() +{ + QVERIFY(m_subject->scaling() == true); + m_subject->setScaling(false); + QVERIFY(m_subject->scaling() == false); +} + +void ft_duivideowidget::testKeepAspectRatio() +{ + QVERIFY(m_subject->keepAspectRatio() == true); + m_subject->setKeepAspectRatio(false); + QVERIFY(m_subject->keepAspectRatio() == false); +} + +void ft_duivideowidget::testBackgroundFill() +{ + QVERIFY(m_subject->backgroundFill() == false); + m_subject->setBackgroundFill(true); + QVERIFY(m_subject->backgroundFill() == true); +} + +void ft_duivideowidget::testBackgroundColor() +{ + QColor red("#ff0000"); + QVERIFY(m_subject->backgroundColor() == QColor(Qt::black)); + m_subject->setBackgroundColor(red); + QVERIFY(m_subject->backgroundColor() == red); +} + +void ft_duivideowidget::testRepeat() +{ + QVERIFY(m_subject->repeat() == false); + m_subject->setRepeat(true); + QVERIFY(m_subject->repeat() == true); +} + +void ft_duivideowidget::testVideoFilename() +{ + QFileInfo info("test.avi"); + m_subject->open(QString("test.avi")); + QCOMPARE(m_subject->videoFilename(), info.absoluteFilePath()); +} + + +QTEST_APPLESS_MAIN(ft_duivideowidget) diff --git a/tests/ft_duivideowidget/ft_duivideowidget.h b/tests/ft_duivideowidget/ft_duivideowidget.h new file mode 100644 index 000000000..3c4dad092 --- /dev/null +++ b/tests/ft_duivideowidget/ft_duivideowidget.h @@ -0,0 +1,67 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef _FT_DUIVIDEOWIDGET_ +#define _FT_DUIVIDEOWIDGET_ + +#include +#include + +#include +#include + +Q_DECLARE_METATYPE(DuiVideoWidget *); + +class ft_duivideowidget: public QObject +{ + Q_OBJECT; + +public: + ft_duivideowidget(); + virtual ~ft_duivideowidget(); + +private: + + DuiVideoWidget *m_subject; + DuiApplication *app; + +private slots: + void init(); + void cleanup(); + void initTestCase(); + void cleanupTestCase(); + + void testInitialState(); + void testBogusOpen(); + void testOpen(); + void testPause(); + void testVolume(); + void testSeek(); + void testCurrentPos(); + void testMute(); + void testCurrentFrame(); + void testScaling(); + void testKeepAspectRatio(); + void testBackgroundFill(); + void testBackgroundColor(); + void testRepeat(); + void testVideoFilename(); + +}; +#endif diff --git a/tests/ft_duivideowidget/ft_duivideowidget.pro b/tests/ft_duivideowidget/ft_duivideowidget.pro new file mode 100644 index 000000000..3d76d5c21 --- /dev/null +++ b/tests/ft_duivideowidget/ft_duivideowidget.pro @@ -0,0 +1,17 @@ +include(../common_top.pri) + +SOURCES += ft_duivideowidget.cpp \ +#$$DUISRCDIR/video/duivideowidget.cpp \ +#$$DUISRCDIR/video/duisink.c + +HEADERS += ft_duivideowidget.h \ +$$DUISRCDIR/video/duivideowidget.h \ +$$DUISRCDIR/video/duisink.h + +QT += testlib + +CONFIG += link_pkgconfig +PKGCONFIG += gstreamer-0.10 +INCLUDEPATH += $$DUISRCDIR/video + +include(../common_bot.pri) diff --git a/tests/ft_duivideowidget/test.avi b/tests/ft_duivideowidget/test.avi new file mode 100644 index 000000000..238bb688a Binary files /dev/null and b/tests/ft_duivideowidget/test.avi differ diff --git a/tests/ft_duiwidget/conf_ft_duiwidget.css b/tests/ft_duiwidget/conf_ft_duiwidget.css new file mode 100644 index 000000000..90f022df6 --- /dev/null +++ b/tests/ft_duiwidget/conf_ft_duiwidget.css @@ -0,0 +1,33 @@ +.DuiButton#ft_test_button { + minsize: size(40, 40); + maxsize: size(1000, 1000); + preferredsize: size(100, 100); + +} + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/ft_duiwidget/ft_duiwidget.cpp b/tests/ft_duiwidget/ft_duiwidget.cpp new file mode 100644 index 000000000..7dbe908ad --- /dev/null +++ b/tests/ft_duiwidget/ft_duiwidget.cpp @@ -0,0 +1,276 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ft_duiwidget.h" +#include +#include +#include "duiapplication.h" +#include "duislider.h" +#include "duibutton.h" +#include "duitheme.h" +#include "duitextedit.h" +#include "duinavigationbar.h" +#include "duitime.h" +#include +#include +#include +#include +#include "duiimage.h" +#include "duiimagelabel.h" +#include "duiimagewidget.h" +#include "duilabel.h" +#include "duipannablewidget.h" +#include "duipositionindicator.h" +#include "duitoolbar.h" +#include "duipannableviewport.h" +#include + + +//#define DEBUG + +Ft_DuiWidget::Ft_DuiWidget() +{ + +} + +void Ft_DuiWidget::paintWidgetWithForcedResize() +{ + createWidgetsUnderTest(); + int numPass = 0; + + for (int i = 0; i < widgetsUnderTest.size(); ++i) { + widgetsUnderTest.at(i)->resize(92, 92); + QSizeF s = QSizeF(92, 92); + QSizeF ps = paintedSize(widgetsUnderTest.at(i)); + QSizeF limit = 0.95 * s; + + if (ps.height() <= s.height() + && ps.width() <= s.width() + && ps.height() >= limit.height() + && ps.width() >= limit.height()) { + + ++numPass; + + qDebug() << "## paintWidgetWithForcedResize ok ##" << widgetsUnderTest.at(i)->metaObject()->className() << ps.width() << + ps.height(); + } else { + qDebug() << "## paintWidgetWithForcedResize fail ##" << widgetsUnderTest.at(i)->metaObject()->className() << ps.width() << + ps.height(); + } + + } + + qDebug() << "---- paintWidgetWithForcedResize, numPass" << numPass << "/" << widgetsUnderTest.size(); + QVERIFY(numPass == widgetsUnderTest.size()); +} + + +void Ft_DuiWidget::constructAndDeleteWidgets() +{ + createWidgetsUnderTest(); + + for (int i = 0; i < widgetsUnderTest.size(); ++i) { + delete widgetsUnderTest.at(i); + } +} + +void Ft_DuiWidget::paintWidgetWithoutForcedResize() +{ + createWidgetsUnderTest(); + int numPass = 0; + + for (int i = 0; i < widgetsUnderTest.size(); ++i) { + QSizeF s = widgetsUnderTest.at(i)->size(); + if (s.height() <= 0 && s.width() <= 0) { + widgetsUnderTest.at(i)->resize(83, 83); + s = QSizeF(83, 83); + } + + QSizeF ps = paintedSize(widgetsUnderTest.at(i)); + QSizeF limit = 0.95 * s; + + if (ps.height() <= s.height() + && ps.width() <= s.width() + && ps.height() >= limit.height() + && ps.width() >= limit.height()) { + + ++numPass; + + qDebug() << "## paintWidgetWithoutForcedResize ok" << widgetsUnderTest.at(i)->metaObject()->className() << ps.width() << + ps.height(); + } else { + qDebug() << "## paintWidgetWithoutForcedResize fail " << widgetsUnderTest.at(i)->metaObject()->className() << ps.width() << + ps.height(); + } + } + + qDebug() << "---- paintWidgetWithoutForcedResize, numPass" << numPass << "/" << widgetsUnderTest.size(); + QVERIFY(numPass == widgetsUnderTest.size()); +} + +void Ft_DuiWidget::initialSize() +{ + createWidgetsUnderTest(); + int numPass = 0; + + for (int i = 0; i < widgetsUnderTest.size(); ++i) { + QSizeF s = widgetsUnderTest.at(i)->size(); + + if (s.height() < 10 || s.width() < 10) { + qDebug() << "## initialSize fail" << widgetsUnderTest.at(i)->metaObject()->className() << " initial size " << s; + } else { + qDebug() << "## initialSize ok" << widgetsUnderTest.at(i)->metaObject()->className() << " initial size " << s; + ++numPass; + } + } + + qDebug() << "---- initialSize, numPass" << numPass << "/" << widgetsUnderTest.size(); + QVERIFY(numPass == widgetsUnderTest.size()); +} + +void Ft_DuiWidget::resizeAndSizeLookup() +{ + createWidgetsUnderTest(); + + int numPass = 0; + for (int i = 0; i < widgetsUnderTest.size(); ++i) { + widgetsUnderTest.at(i)->resize(99, 99); + QSizeF s = widgetsUnderTest.at(i)->size(); + if (s.height() != 99 || s.width() != 99) { + qDebug() << " ## resizeAndSizeLookup fail " << widgetsUnderTest.at(i)->metaObject()->className() << " size " << s; + } else { + qDebug() << " ## resizeAndSizeLookup ok " << widgetsUnderTest.at(i)->metaObject()->className() << " size " << s; + ++numPass; + } + } + + qDebug() << "---- resizeWidget, numPass" << numPass << "/" << widgetsUnderTest.size(); + QVERIFY(numPass == widgetsUnderTest.size()); +} + + +QSizeF Ft_DuiWidget::paintedSize(QGraphicsWidget *widget) +{ + QPixmap *p = new QPixmap(500, 500); + p->fill(QColor(0, 0, 0, 0)); + + QPixmap *orig = new QPixmap(500, 500); + orig->fill(QColor(0, 0, 0, 0)); + + QPainter *painter = new QPainter(p); + QStyleOptionGraphicsItem style; + + style.exposedRect = QRect(0, 0, 500, 500); + widget->paint(painter, &style, 0); + + QImage origi = orig->toImage(); + QImage pi = p->toImage(); + + int width = 0; + int height = 0; + + for (int y = 0; y < 500; y++) { + for (int x = 0; x < 500; x++) { + if (pi.pixel(x, y) != origi.pixel(x, y) && x + 1 > width) { + width = x + 1; + } + } + } + + for (int x = 0; x < 500; x++) { + for (int y = 0; y < 500; y++) { + if (pi.pixel(x, y) != origi.pixel(x, y) && y + 1 > height) { + height = y + 1; + } + } + } + +#ifdef DEBUG + QString className(widget->metaObject()->className()); + p->save(className + ".png", "PNG"); +#endif + + QSizeF retval(width, height); + return retval; +} + +void Ft_DuiWidget::initTestCase() +{ + int i = 0; + app = new DuiApplication(i, (char **)0); + DuiTheme::loadCSS("conf_ft_duiwidget.css"); + +} + +void Ft_DuiWidget::createWidgetsUnderTest() +{ + widgetsUnderTest.clear(); + + //TODO: initialize widgets correctly here + + QPushButton *pb = new QPushButton; + QGraphicsProxyWidget *proxy = new QGraphicsProxyWidget; + proxy->setWidget(pb); + + widgetsUnderTest.append(proxy); + + DuiButton *b = new DuiButton(); + b->setObjectName("ft_test_button"); + widgetsUnderTest.append(b); + + DuiTextEdit *t = new DuiTextEdit; + widgetsUnderTest.append(t); + + DuiTime *time = new DuiTime; + widgetsUnderTest.append(time); + + widgetsUnderTest.append(new DuiToolbar); + widgetsUnderTest.append(new DuiSlider); + widgetsUnderTest.append(new DuiPositionIndicator(Qt::Horizontal)); + + DuiButton *b3 = new DuiButton(); + b3->setObjectName("ft_test_button"); + + widgetsUnderTest.append(new DuiNavigationBar); + widgetsUnderTest.append(new DuiLabel); + + for (int i = 0; i < widgetsUnderTest.size(); ++i) { + widgetsUnderTest.at(i)->setMinimumSize(0, 0); + widgetsUnderTest.at(i)->setMaximumSize(999, 999); + } + return; + + //segfaulting widgets below + DuiPannableViewport *vp = new DuiPannableViewport(Qt::Vertical); + vp->setWidget(vp); + widgetsUnderTest.append(vp); + + widgetsUnderTest.append(new DuiImageWidget); + widgetsUnderTest.append(new DuiImageLabel); + + + + + +} + + +QTEST_APPLESS_MAIN(Ft_DuiWidget) + + diff --git a/tests/ft_duiwidget/ft_duiwidget.h b/tests/ft_duiwidget/ft_duiwidget.h new file mode 100644 index 000000000..5be307245 --- /dev/null +++ b/tests/ft_duiwidget/ft_duiwidget.h @@ -0,0 +1,55 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef FT_DUIWIDGET_H +#define FT_DUIWIDGET_H + +#include +#include +#include +#include "duiapplication.h" +#include +#include "duiwidget.h" +#include + +class Ft_DuiWidget : public QObject +{ + Q_OBJECT; + +public: + Ft_DuiWidget(); + +private slots: + void initTestCase(); + void resizeAndSizeLookup(); + void paintWidgetWithoutForcedResize(); + void paintWidgetWithForcedResize(); + void constructAndDeleteWidgets(); + void initialSize(); + +private: + DuiApplication *app; + void createWidgetsUnderTest(); + QList widgetsUnderTest; + QSizeF paintedSize(QGraphicsWidget *widget); + +}; + +#endif + diff --git a/tests/ft_duiwidget/ft_duiwidget.pro b/tests/ft_duiwidget/ft_duiwidget.pro new file mode 100644 index 000000000..b1053515f --- /dev/null +++ b/tests/ft_duiwidget/ft_duiwidget.pro @@ -0,0 +1,12 @@ +include(../common_top.pri) +TARGET = ft_duiwidget +QT += dbus svg network +LIBRARYPATH += $$DUISRCDIR + +SOURCES += \ + ft_duiwidget.cpp \ + +HEADERS += \ + ft_duiwidget.h \ + +include(../common_bot.pri) diff --git a/tests/ft_localedata/.gitignore b/tests/ft_localedata/.gitignore new file mode 100644 index 000000000..4292d8908 --- /dev/null +++ b/tests/ft_localedata/.gitignore @@ -0,0 +1,2 @@ +ft_localedata +icudt*/*.res diff --git a/tests/ft_localedata/fi_FI.txt b/tests/ft_localedata/fi_FI.txt new file mode 100644 index 000000000..7a656b933 --- /dev/null +++ b/tests/ft_localedata/fi_FI.txt @@ -0,0 +1,23 @@ +fi_FI{ + NumberElements{ + "--", + " ", + ";", + "%", + "0", + "#", + "-", + "E", + "‰", + "∞", + "epäluku", + "+", + } + + NumberPatterns{ + "#,##0.###", + "#,##0.00 ¤", + "#,##0 %", + "#E0", + } +} diff --git a/tests/ft_localedata/ft_localedata.cpp b/tests/ft_localedata/ft_localedata.cpp new file mode 100644 index 000000000..1837f58cf --- /dev/null +++ b/tests/ft_localedata/ft_localedata.cpp @@ -0,0 +1,98 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ft_localedata.h" + +void Ft_LocaleData::initTestCase() +{ + static int argc = 0; + static char *argv[1] = { (char *) "" }; + app = new QCoreApplication(argc, argv); + QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8")); + DuiLocale::setDataPath(qApp->applicationDirPath()); +} + +void Ft_LocaleData::cleanup() +{ +} + +/* + * Test whether standard number formatting of ICU can be overridden + * for a certain language by loading a special resource file. + * + * The path to the resource file loaded here is of the form + * + * /icudt/.res + * + * is set above in initTestCase() by DuiLocale::setDataPath("."), + * i.e. this test application looks for the file starting from the current + * directory. + * + * indicates the icu version, for libicu42 this is 42 + * + * is 'l' for Little Endian, ASCII, 'b' for Big Endian, ASCII, + * 'e' for Big Endian, EBCDIC. + * + * is the name of the locale this resource file is intended for. + * For the test below we use "fi_FI" as the locale name. + * + * Therefore, the full path name of the file loaded by the test below is + * ./icudt42l/fi_FI.res (for libicu42). + * + * fi_FI.res is generated from a the plain text file fi_FI.txt using + * the "genrb" tool (See the rules in the ft_localedata.pro file). + * + * For more details see http://userguide.icu-project.org/icudata + */ + +void Ft_LocaleData::testNumberData_data() +{ + QTest::addColumn("locale_name"); + QTest::addColumn("value"); + QTest::addColumn("result"); + + // for en_US_POSIX locale, we don’t override anything, i.e. + // the expected result below is what ICU does by default: + QTest::newRow("en_US_POSIX") + << QString("en_US_POSIX") + << (double) 1234567.123456789 + << QString("1234567.123457"); + // For fi_FI locale, we override the formatting of a double number using the + // the file ./icudt42l/fi_FI.res as explained above. + // Therefore we expect a weird result below, the point here + // is only to check whether we can override the default if this should + // be necessary: + QTest::newRow("fi_FI") + << QString("fi_FI") + << (double) 1234567.123456789 + << QString("1 234 567--123"); +} + +void Ft_LocaleData::testNumberData() +{ + QFETCH(QString, locale_name); + QFETCH(double, value); + QFETCH(QString, result); + + DuiLocale locale(locale_name); + QVERIFY(locale.isValid()); + QCOMPARE(locale.formatNumber(value), result); +} + +QTEST_APPLESS_MAIN(Ft_LocaleData); diff --git a/tests/ft_localedata/ft_localedata.h b/tests/ft_localedata/ft_localedata.h new file mode 100644 index 000000000..2c816a985 --- /dev/null +++ b/tests/ft_localedata/ft_localedata.h @@ -0,0 +1,52 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef FT_LOCALEDATA_H +#define FT_LOCALEDATA_H + +#include +#include +#include + +Q_DECLARE_METATYPE(DuiLocale::Calendar); +Q_DECLARE_METATYPE(DuiLocale); + + +#define MAX_PARAMS 10 +class Ft_LocaleData : public QObject +{ + Q_OBJECT + +private: + QCoreApplication *app; + +private slots: + void initTestCase(); + + void cleanup(); + + void testNumberData_data(); + void testNumberData(); + // void testDuiFoo(); + // void testDuiBar_data(); + // void testDuiBar(); +}; + + +#endif diff --git a/tests/ft_localedata/ft_localedata.pro b/tests/ft_localedata/ft_localedata.pro new file mode 100644 index 000000000..80c44f14b --- /dev/null +++ b/tests/ft_localedata/ft_localedata.pro @@ -0,0 +1,31 @@ +include(../common_top.pri) + +TARGET = ft_localedata +LIBS += -lgcov +QMAKE_CXXFLAGS += -ftest-coverage -fprofile-arcs + +# For gcov testing, disabled currently. Add -lgcov to LIBS if +# this is enabled +# QMAKE_CXXFLAGS += -ftest-coverage -fprofile-arcs + +# unit +TEST_SOURCES = \ +# $$DUISRCDIR/duilocale.cpp \ + +# Input +HEADERS += ft_localedata.h +SOURCES += ft_localedata.cpp + +GENRB_FILES = fi_FI.txt +ICUDATADIR = icudt42l +genrb.name = generating resource bundle files +genrb.input = GENRB_FILES +genrb.output = ${QMAKE_FILE_PATH}/$${ICUDATADIR}/${QMAKE_FILE_BASE}.res +genrb.commands = mkdir -p $${ICUDATADIR}; +genrb.commands += genrb -e UTF-8 -d $${ICUDATADIR} ${QMAKE_FILE_IN}; +genrb.CONFIG += no_link target_predeps +QMAKE_EXTRA_COMPILERS += genrb + +support_files.files += $$ICUDATADIR + +include(../common_bot.pri) diff --git a/tests/ft_locales/.gitignore b/tests/ft_locales/.gitignore new file mode 100644 index 000000000..f42366a1c --- /dev/null +++ b/tests/ft_locales/.gitignore @@ -0,0 +1 @@ +ft_locales diff --git a/tests/ft_locales/ft_locales.cpp b/tests/ft_locales/ft_locales.cpp new file mode 100644 index 000000000..decf052db --- /dev/null +++ b/tests/ft_locales/ft_locales.cpp @@ -0,0 +1,629 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ft_locales.h" + +void Ft_Locales::initTestCase() +{ + static int dummyArgc = 1; + static char *dummyArgv[1] = { (char *) "ft_locales" }; + qap = new DuiApplication(dummyArgc, dummyArgv, "test"); + QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8")); +} + +void Ft_Locales::cleanupTestCase() +{ + delete qap; +} + +void Ft_Locales::init() +{ +} + +void Ft_Locales::cleanup() +{ +} + +void Ft_Locales::testDuiLocaleConstructor() +{ + DuiLocale *z = 0; + z = new DuiLocale(); + QVERIFY2(z->isValid(), "new DuiLocale()"); +} + +void Ft_Locales::testCreateSystemLocale_data() +{ + QTest::addColumn("conf"); + QTest::addColumn("env"); + QTest::addColumn("locale"); + + // Test the ultimate fallback to POSIX + QTest::newRow("posix") << QString("") << QString("") << QString("en_US_POSIX"); + // Test the fallback to the LANG environment variable. If the string + // found via gconf is empty, the value of LANG is used as a fallback + QTest::newRow("fi") << QString("") << QString("fi") << QString("fi"); + QTest::newRow("fi") << QString("") << QString("fi.UTF-8") << QString("fi"); + QTest::newRow("fi") << QString("") << QString("fi_FI") << QString("fi_FI"); + QTest::newRow("fi") << QString("") << QString("fi_FI.UTF-8") << QString("fi_FI"); + QTest::newRow("snd") << QString("") << QString("snd@Arab") << QString("snd_Arab"); + QTest::newRow("snd") << QString("") << QString("snd_AF@Arab") << QString("snd_Arab_AF"); + QTest::newRow("snd") << QString("") << QString("snd_AF.UTF-8@Arab") << QString("snd_Arab_AF"); + // with bad data + QTest::newRow("snd") << QString("") << QString("+2eio") << QString("en_US_POSIX"); + // Test values found via gconf and check that LANG is ignored: + QTest::newRow("fi") << QString("fi") << QString("en") << QString("fi"); +} + +bool confIsDown() +{ + DuiGConfItem languageItem("/Dui/i18n/Language"); + QString originalValue = languageItem.value().toString(); + int skipConf = 0; + + if (originalValue.isEmpty()) { + languageItem.set("xx"); + //GConf is not running here, so skip it + if (languageItem.value().toString() != "xx") { + skipConf = 1; + } else { + languageItem.set(originalValue); + } + } + + return skipConf == 1; +} + +void Ft_Locales::testSettingsChanged() +{ + if (confIsDown()) { + QSKIP("SettingsChanged is skipped", SkipSingle); + return; + } + DuiGConfItem languageItem("/Dui/i18n/Language"); + QString originalValue = languageItem.value().toString(); + + // Test within DuiLocale + DuiLocale z; + QSignalSpy spy(&z, SIGNAL(settingsChanged())); + QCOMPARE(spy.count(), 0); + + // Changes in languageItem should not trigger the signal + // settingsChanged() as long as the locale settings are + // disconnected: + languageItem.set(originalValue + "something"); + QTest::qWait(100); + QCOMPARE(spy.count(), 0); + + // After connecting, changes in languageItem should trigger the + // signal settingsChanged() + z.connectSettings(); + languageItem.set("fr"); + for (int i = 0; i < 100; ++i) { + QTest::qWait(50); + if (spy.count() != 0) + break; + } + QCOMPARE(spy.count(), 1); + + languageItem.set("fi"); + for (int i = 0; i < 100; ++i) { + QTest::qWait(50); + if (spy.count() != 1) + break; + } + QCOMPARE(spy.count(), 2); + + // After disconnecting, the signal should not be triggered anymore: + z.disconnectSettings(); + languageItem.set("en"); + QTest::qWait(100); + QCOMPARE(spy.count(), 2); + + // Test the signal localeSettingsChanged in DuiApplication + QSignalSpy spyapp(qap, SIGNAL(localeSettingsChanged())); + QCOMPARE(spyapp.count(), 0); + + languageItem.set(originalValue + "something else"); + for (int i = 0; i < 100; ++i) { + QTest::qWait(50); + if (spyapp.count() != 0) + break; + } + QCOMPARE(spyapp.count(), 1); + + languageItem.set("fi"); + for (int i = 0; i < 100; ++i) { + QTest::qWait(50); + if (spyapp.count() != 1) + break; + } + QCOMPARE(spyapp.count(), 2); + + languageItem.set(originalValue); +} + +void Ft_Locales::testCreateSystemLocale() +{ + DuiGConfItem languageItem("/Dui/i18n/Language"); + QString originalValue = languageItem.value().toString(); + + QFETCH(QString, conf); + QFETCH(QString, env); + QFETCH(QString, locale); + + setenv("LANG", env.toAscii().data(), 1); + + languageItem.set(conf); + DuiLocale *z = DuiLocale::createSystemDuiLocale(); + + if (!originalValue.isEmpty()) { + languageItem.set(originalValue); + } + + if (confIsDown() && ! conf.isEmpty()) { + QSKIP("CreateSystemLocale is skipped", SkipSingle); + } else { + QCOMPARE(z->name(), locale); + } + + delete z; +} + +void Ft_Locales::testDuiLocaleLanguage_data() +{ + QTest::addColumn("locale_name"); + QTest::addColumn("language"); + + QTest::newRow("fi") << QString("fi_FI") << QString("fi"); + QTest::newRow("snd") << QString("snd_AF_Arab") << QString("snd"); + QTest::newRow("en") << QString("en") << QString("en"); +} + +void Ft_Locales::testDuiLocaleLanguage() +{ + QFETCH(QString, locale_name); + QFETCH(QString, language); + + DuiLocale *z = new DuiLocale(locale_name); + QCOMPARE(z->language(), language); + delete z; +} + +void Ft_Locales::testDuiLocaleCountry_data() +{ + QTest::addColumn("locale_name"); + QTest::addColumn("country"); + + QTest::newRow("fi") << QString("fi_FI") << QString("FI"); + QTest::newRow("snd") << QString("snd_Arab_AF") << QString("AF"); + QTest::newRow("snd") << QString("snd_Arab") << QString(""); + // this isn't a valid country, or is it?: + // should we refuse to accept something like this? + QTest::newRow("snd") << QString("snd_Arab_Egypt") << QString("Egypt"); + QTest::newRow("en") << QString("en") << QString(""); +} + +void Ft_Locales::testDuiLocaleCountry() +{ + QFETCH(QString, locale_name); + QFETCH(QString, country); + + DuiLocale *z = new DuiLocale(locale_name); + + QCOMPARE(z->country(), country); + delete z; +} + +void Ft_Locales::testDuiLocaleScript_data() +{ + QTest::addColumn("locale"); + QTest::addColumn("script"); + + QTest::newRow("fi") << QString("fi_FI") << QString("Latn"); + QTest::newRow("snd") << QString("snd_Arab_AF") << QString("Arab"); + QTest::newRow("snd") << QString("snd_Deva") << QString("Deva"); + QTest::newRow("en") << QString("en") << QString("Latn"); + QTest::newRow("en") << QString("en_Arab") << QString("Arab"); +} + +void Ft_Locales::testDuiLocaleScript() +{ + QFETCH(QString, locale); + QFETCH(QString, script); + + DuiLocale *z = new DuiLocale(locale); + QCOMPARE(z->script(), script); + delete z; +} + +void Ft_Locales::testDuiLocaleVariant_data() +{ + QTest::addColumn("locale"); + QTest::addColumn("variant"); + + QTest::newRow("fi") << QString("fi_FI") << QString(""); + QTest::newRow("snd") << QString("snd_AF_XXX") << QString("XXX"); + QTest::newRow("snd") << QString("snd_Arab_AF_XXX") << QString("XXX"); + QTest::newRow("en") << QString("en") << QString(""); +} + +void Ft_Locales::testDuiLocaleVariant() +{ + QFETCH(QString, locale); + QFETCH(QString, variant); + + DuiLocale *z = new DuiLocale(locale); + QCOMPARE(z->variant(), variant); + delete z; +} + +void Ft_Locales::testDuiLocaleTextDirection_data() +{ + QTest::addColumn("locale"); + QTest::addColumn("direction"); + + QTest::newRow("fi") << QString("fi") << (int) Qt::LeftToRight; + QTest::newRow("ar") << QString("ar") << (int) Qt::RightToLeft; + QTest::newRow("he") << QString("he") << (int) Qt::RightToLeft; + QTest::newRow("ur") << QString("ur") << (int) Qt::RightToLeft; + QTest::newRow("fa") << QString("fa") << (int) Qt::RightToLeft; + QTest::newRow("am") << QString("am") << (int) Qt::RightToLeft; + QTest::newRow("ps") << QString("ps") << (int) Qt::RightToLeft; + QTest::newRow("snd") << QString("snd_Arab_AF") << (int) Qt::RightToLeft; + QTest::newRow("snd") << QString("snd_Arab_AF_XXX") << (int) Qt::RightToLeft; + QTest::newRow("snd") << QString("snd_Deva_AF_XXX") << (int) Qt::LeftToRight; +} + +void Ft_Locales::testDuiLocaleTextDirection() +{ + QFETCH(QString, locale); + QFETCH(int, direction); + + DuiLocale *z = new DuiLocale(locale); + QCOMPARE((int)z->textDirection(), direction); + delete z; +} + +void Ft_Locales::testDuiLocaleConstructorWithParams_data() +{ + QTest::addColumn("language"); + QTest::addColumn("country"); + QTest::addColumn("name"); + + QTest::newRow("fi_FI") << QString("fi") << QString("FI") << QString("fi_FI"); + QTest::newRow("ar_SA") << QString("ar") << QString("SA") << QString("ar_SA"); + QTest::newRow("xx_YY") << QString("xx") << QString("YY") << QString("xx_YY"); +} + +void Ft_Locales::testDuiLocaleConstructorWithParams() +{ + QFETCH(QString, language); + QFETCH(QString, country); + QFETCH(QString, name); + + DuiLocale *z = new DuiLocale(language + '_' + country); + QVERIFY2(z->isValid(), + "new DuiLocale(language + '_' + country)"); + QVERIFY2(z->name() == name, "z->name() differs from name"); + delete z; + + z = new DuiLocale(name); + QVERIFY2(z->isValid(), "new DuiLocale(name)"); + QVERIFY2(z->name() == name, "z->name() differs from name"); + delete z; +} + +void Ft_Locales::testDuiLocaleConstructorAndCategoryWithParams_data() +{ + QTest::addColumn("default_language"); + QTest::addColumn("default_country"); + QTest::addColumn("default_name"); + + QTest::addColumn("category_language"); + QTest::addColumn("category_country"); + QTest::addColumn("category_name"); + + QTest::newRow("fi_FI") + << QString("fi") << QString("FI") << QString("fi_FI") + << QString("en") << QString("GB") << QString("en_GB"); + QTest::newRow("ar_SA") + << QString("ar") << QString("SA") << QString("ar_SA") + << QString("en") << QString("GB") << QString("en_GB"); + QTest::newRow("xx_YY") + << QString("xx") << QString("YY") << QString("xx_YY") + << QString("aa") << QString("BB") << QString("aa_BB"); +} + +void Ft_Locales::testDuiLocaleConstructorAndCategoryWithParams() +{ + QFETCH(QString, default_language); + QFETCH(QString, default_country); + QFETCH(QString, default_name); + + QFETCH(QString, category_language); + QFETCH(QString, category_country); + QFETCH(QString, category_name); + + DuiLocale *z = 0; + + z = new DuiLocale(default_language + '_' + default_country); + + QVERIFY2(z->isValid(), + "new DuiLocale(default_language + '_' + default_country)"); + QVERIFY2(z->name() == default_name, "z->name() differs from default_name"); + + QVERIFY2(z->categoryName(DuiLocale::DuiLcTime) == default_name, + "TIME: category name does not point to default category"); + z->setCategoryLocale(DuiLocale::DuiLcTime, category_language + '_' + category_country); + QVERIFY2(z->categoryName(DuiLocale::DuiLcTime) == category_name, + "TIME: category name does not point to category_name"); + + QVERIFY2(z->categoryName(DuiLocale::DuiLcCollate) == default_name, + "COLLATE: category name does not point to default category"); + + z->setCategoryLocale(DuiLocale::DuiLcCollate, category_language + '_' + category_country); + QVERIFY2(z->categoryName(DuiLocale::DuiLcCollate) == category_name, + "COLLATE: category name does not point to category_name"); + + QVERIFY2(z->categoryName(DuiLocale::DuiLcNumeric) == default_name, + "NUMERIC: category name does not point to default category"); + + z->setCategoryLocale(DuiLocale::DuiLcNumeric, category_language + '_' + category_country); + QVERIFY2(z->categoryName(DuiLocale::DuiLcNumeric) == category_name, + "NUMERIC: category name does not point to category_name"); + delete z; +} + +void Ft_Locales::testDuiLocaleLanguageEndonum_data() +{ + QTest::addColumn("locale_name"); + QTest::addColumn("endonym_result"); + + QTest::newRow("fi_FI") + << QString("fi_FI") + << QString("suomi"); + QTest::newRow("de_DE") + << QString("de_DE") + << QString("Deutsch"); + QTest::newRow("ja_JP") + << QString("ja_JP") + << QString("日本語"); + QTest::newRow("zh_CN") + << QString("zh_CN") + << QString("中文"); +} + +void Ft_Locales::testDuiLocaleLanguageEndonum() +{ + QFETCH(QString, locale_name); + QFETCH(QString, endonym_result); + DuiLocale locale(locale_name); + QCOMPARE(locale.languageEndonym(), endonym_result); +} + +void Ft_Locales::testDuiLocaleCountryEndonum_data() +{ + QTest::addColumn("locale_name"); + QTest::addColumn("endonym_result"); + + QTest::newRow("fi_FI") + << QString("fi_FI") + << QString("Suomi"); + QTest::newRow("de_DE") + << QString("de_DE") + << QString("Deutschland"); + QTest::newRow("ja_JP") + << QString("ja_JP") + << QString("日本"); + QTest::newRow("zh_CN") + << QString("zh_CN") + << QString("中国"); +} + +void Ft_Locales::testDuiLocaleCountryEndonum() +{ + QFETCH(QString, locale_name); + QFETCH(QString, endonym_result); + DuiLocale locale(locale_name); + QCOMPARE(locale.countryEndonym(), endonym_result); +} + +/* + * To reduce the size of libicu, we customize the locale data included in + * our package of libicu and include only what needs to be there. + * + * This test checks whether our package of libicu still has all the + * locales which need to be supported to make sure we did not omit too + * much accidentally. + * + */ +void Ft_Locales::checkAvailableLocales() +{ + // For the list of locales which need to be supported see, the list + // in i18n.dox + QList requiredLocaleNames; + requiredLocaleNames << "ar"; // "Arabic" + requiredLocaleNames << "ar_AE"; // "Arabic (United Arab Emirates)" + requiredLocaleNames << "ar_BH"; // "Arabic (Bahrain)" + requiredLocaleNames << "ar_DZ"; // "Arabic (Algeria)" + requiredLocaleNames << "ar_EG"; // "Arabic (Egypt)" + requiredLocaleNames << "ar_IQ"; // "Arabic (Iraq)" + requiredLocaleNames << "ar_JO"; // "Arabic (Jordan)" + requiredLocaleNames << "ar_KW"; // "Arabic (Kuwait)" + requiredLocaleNames << "ar_LB"; // "Arabic (Lebanon)" + requiredLocaleNames << "ar_LY"; // "Arabic (Libya)" + requiredLocaleNames << "ar_MA"; // "Arabic (Morocco)" + requiredLocaleNames << "ar_OM"; // "Arabic (Oman)" + requiredLocaleNames << "ar_QA"; // "Arabic (Qatar)" + requiredLocaleNames << "ar_SA"; // "Arabic (Saudi Arabia)" + requiredLocaleNames << "ar_SD"; // "Arabic (Sudan)" + requiredLocaleNames << "ar_SY"; // "Arabic (Syria)" + requiredLocaleNames << "ar_TN"; // "Arabic (Tunisia)" + requiredLocaleNames << "ar_YE"; // "Arabic (Yemen)" + requiredLocaleNames << "ca"; // "Catalan" + requiredLocaleNames << "ca_ES"; // "Catalan (Spain)" + requiredLocaleNames << "da"; // "Danish" + requiredLocaleNames << "da_DK"; // "Danish (Denmark)" + requiredLocaleNames << "de"; // "German" + requiredLocaleNames << "de_AT"; // "German (Austria)" + requiredLocaleNames << "de_BE"; // "German (Belgium)" + requiredLocaleNames << "de_CH"; // "German (Switzerland)" + requiredLocaleNames << "de_DE"; // "German (Germany)" + requiredLocaleNames << "de_LI"; // "German (Liechtenstein)" + requiredLocaleNames << "de_LU"; // "German (Luxembourg)" + requiredLocaleNames << "el"; // "Greek" + requiredLocaleNames << "el_CY"; // "Greek (Cyprus)" + requiredLocaleNames << "el_GR"; // "Greek (Greece)" + requiredLocaleNames << "en"; // "English" + requiredLocaleNames << "en_AU"; // "English (Australia)" + requiredLocaleNames << "en_BE"; // "English (Belgium)" + requiredLocaleNames << "en_BW"; // "English (Botswana)" + requiredLocaleNames << "en_BZ"; // "English (Belize)" + requiredLocaleNames << "en_CA"; // "English (Canada)" + requiredLocaleNames << "en_GB"; // "English (United Kingdom)" + requiredLocaleNames << "en_HK"; // "English (Hong Kong SAR China)" + requiredLocaleNames << "en_IE"; // "English (Ireland)" + requiredLocaleNames << "en_IN"; // "English (India)" + requiredLocaleNames << "en_JM"; // "English (Jamaica)" + requiredLocaleNames << "en_MH"; // "English (Marshall Islands)" + requiredLocaleNames << "en_MT"; // "English (Malta)" + requiredLocaleNames << "en_NA"; // "English (Namibia)" + requiredLocaleNames << "en_NZ"; // "English (New Zealand)" + requiredLocaleNames << "en_PH"; // "English (Philippines)" + requiredLocaleNames << "en_PK"; // "English (Pakistan)" + requiredLocaleNames << "en_SG"; // "English (Singapore)" + requiredLocaleNames << "en_TT"; // "English (Trinidad and Tobago)" + requiredLocaleNames << "en_US"; // "English (United States)" + requiredLocaleNames << "en_US_POSIX"; // "English (United States, Computer)" + requiredLocaleNames << "en_VI"; // "English (U.S. Virgin Islands)" + requiredLocaleNames << "en_ZA"; // "English (South Africa)" + requiredLocaleNames << "en_ZW"; // "English (Zimbabwe)" + requiredLocaleNames << "es"; // "Spanish" + requiredLocaleNames << "es_AR"; // "Spanish (Argentina)" + requiredLocaleNames << "es_BO"; // "Spanish (Bolivia)" + requiredLocaleNames << "es_CL"; // "Spanish (Chile)" + requiredLocaleNames << "es_CO"; // "Spanish (Colombia)" + requiredLocaleNames << "es_CR"; // "Spanish (Costa Rica)" + requiredLocaleNames << "es_DO"; // "Spanish (Dominican Republic)" + requiredLocaleNames << "es_EC"; // "Spanish (Ecuador)" + requiredLocaleNames << "es_ES"; // "Spanish (Spain)" + requiredLocaleNames << "es_GT"; // "Spanish (Guatemala)" + requiredLocaleNames << "es_HN"; // "Spanish (Honduras)" + requiredLocaleNames << "es_MX"; // "Spanish (Mexico)" + requiredLocaleNames << "es_NI"; // "Spanish (Nicaragua)" + requiredLocaleNames << "es_PA"; // "Spanish (Panama)" + requiredLocaleNames << "es_PE"; // "Spanish (Peru)" + requiredLocaleNames << "es_PR"; // "Spanish (Puerto Rico)" + requiredLocaleNames << "es_PY"; // "Spanish (Paraguay)" + requiredLocaleNames << "es_SV"; // "Spanish (El Salvador)" + requiredLocaleNames << "es_US"; // "Spanish (United States)" + requiredLocaleNames << "es_UY"; // "Spanish (Uruguay)" + requiredLocaleNames << "es_VE"; // "Spanish (Venezuela)" + requiredLocaleNames << "eu"; // "Basque" + requiredLocaleNames << "eu_ES"; // "Basque (Spain)" + requiredLocaleNames << "fa"; // "Persian" + requiredLocaleNames << "fa_AF"; // "Persian (Afghanistan)" + requiredLocaleNames << "fa_IR"; // "Persian (Iran)" + requiredLocaleNames << "fi"; // "Finnish" + requiredLocaleNames << "fi_FI"; // "Finnish (Finland)" + requiredLocaleNames << "fr"; // "French" + requiredLocaleNames << "fr_BE"; // "French (Belgium)" + requiredLocaleNames << "fr_CA"; // "French (Canada)" + requiredLocaleNames << "fr_CH"; // "French (Switzerland)" + requiredLocaleNames << "fr_FR"; // "French (France)" + requiredLocaleNames << "fr_LU"; // "French (Luxembourg)" + requiredLocaleNames << "fr_MC"; // "French (Monaco)" + requiredLocaleNames << "fr_SN"; // "French (Senegal)" + requiredLocaleNames << "gl"; // "Galician" + requiredLocaleNames << "gl_ES"; // "Galician (Spain)" + requiredLocaleNames << "hi"; // "Hindi" + requiredLocaleNames << "hi_IN"; // "Hindi (India)" + requiredLocaleNames << "it"; // "Italian" + requiredLocaleNames << "it_CH"; // "Italian (Switzerland)" + requiredLocaleNames << "it_IT"; // "Italian (Italy)" + requiredLocaleNames << "ja"; // "Japanese" + requiredLocaleNames << "ja_JP"; // "Japanese (Japan)" + requiredLocaleNames << "nb"; // "Norwegian Bokml" + requiredLocaleNames << "nb_NO"; // "Norwegian Bokml (Norway)" + requiredLocaleNames << "nl"; // "Dutch" + requiredLocaleNames << "nl_BE"; // "Dutch (Belgium)" + requiredLocaleNames << "nl_NL"; // "Dutch (Netherlands)" + requiredLocaleNames << "nn"; // "Norwegian Nynorsk" + requiredLocaleNames << "nn_NO"; // "Norwegian Nynorsk (Norway)" + requiredLocaleNames << "pt"; // "Portuguese" + requiredLocaleNames << "pt_BR"; // "Portuguese (Brazil)" + requiredLocaleNames << "pt_PT"; // "Portuguese (Portugal)" + requiredLocaleNames << "ru"; // "Russian" + requiredLocaleNames << "ru_RU"; // "Russian (Russia)" + requiredLocaleNames << "ru_UA"; // "Russian (Ukraine)" + requiredLocaleNames << "sv"; // "Swedish" + requiredLocaleNames << "sv_FI"; // "Swedish (Finland)" + requiredLocaleNames << "sv_SE"; // "Swedish (Sweden)" + requiredLocaleNames << "th"; // "Thai" + requiredLocaleNames << "th_TH"; // "Thai (Thailand)" + requiredLocaleNames << "tr"; // "Turkish" + requiredLocaleNames << "tr_TR"; // "Turkish (Turkey)" + requiredLocaleNames << "uk"; // "Ukrainian" + requiredLocaleNames << "uk_UA"; // "Ukrainian (Ukraine)" + requiredLocaleNames << "ur"; // "Urdu" + requiredLocaleNames << "ur_IN"; // "Urdu (India)" + requiredLocaleNames << "ur_PK"; // "Urdu (Pakistan)" + requiredLocaleNames << "zh"; // "Chinese" + requiredLocaleNames << "zh_Hans" ; // "Chinese (Simplified Han)" + requiredLocaleNames << "zh_Hans_CN"; // "Chinese (Simplified Han, China)" + requiredLocaleNames << "zh_Hans_HK"; // "Chinese (Simplified Han, Hong Kong SAR China)" + requiredLocaleNames << "zh_Hans_MO"; // "Chinese (Simplified Han, Macau SAR China)" + requiredLocaleNames << "zh_Hans_SG"; // "Chinese (Simplified Han, Singapore)" + requiredLocaleNames << "zh_Hant"; // "Chinese (Traditional Han)" + requiredLocaleNames << "zh_Hant_HK"; // "Chinese (Traditional Han, Hong Kong SAR China)" + requiredLocaleNames << "zh_Hant_MO"; // "Chinese (Traditional Han, Macau SAR China)" + requiredLocaleNames << "zh_Hant_TW"; // "Chinese (Traditional Han, Taiwan)" + + QList availableLocaleNames; + QList availableDisplayNames; + int numberOfAvailableLocales = uloc_countAvailable(); + + for (int i = 0; i < numberOfAvailableLocales; ++i) { + int maxresultsize = 100; + UChar result[maxresultsize]; + UErrorCode status = U_ZERO_ERROR; + availableLocaleNames << QString::fromUtf8(uloc_getAvailable(i)); + uloc_getDisplayName(availableLocaleNames[i].toUtf8().constData(), + "en_US", result, maxresultsize, &status); + if (U_SUCCESS(status)) + availableDisplayNames << QString::fromUtf16(result); + else + availableDisplayNames << QString("What kind of locale is this?"); + } + foreach(QString requiredLocaleName, requiredLocaleNames) { + // if (availableLocaleNames.contains(requiredLocaleName)) + // qDebug() << "available: " + // << requiredLocaleName + // << availableDisplayNames[availableLocaleNames.indexOf(requiredLocaleName)]; + // else { + // qDebug() << "missing: " << requiredLocaleName; + // } + QVERIFY2(availableLocaleNames.contains(requiredLocaleName), + QString("The following required locale is missing: " + + requiredLocaleName).toUtf8().constData()); + } +} + +QTEST_APPLESS_MAIN(Ft_Locales); + diff --git a/tests/ft_locales/ft_locales.h b/tests/ft_locales/ft_locales.h new file mode 100644 index 000000000..9eecba9cf --- /dev/null +++ b/tests/ft_locales/ft_locales.h @@ -0,0 +1,96 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef FT_LOCALES_H +#define FT_LOCALES_H + +#include +#include +#include + +#include +#include +#include + +#ifdef HAVE_ICU +#include +#include +#include +#include +#include +#include +#include // SimpleDateFormat +#include +#include +#include // date format symbols +#include // u_setDataDirectory +#endif + +Q_DECLARE_METATYPE(DuiLocale::Calendar); +Q_DECLARE_METATYPE(DuiLocale); + + +class Ft_Locales : public QObject +{ + Q_OBJECT + +private: + DuiApplication *qap; + +private slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + + // these from ut_misc + void testSettingsChanged(); // Must be the first test + void testDuiLocaleConstructor(); + + void testDuiLocaleConstructorWithParams_data(); + void testDuiLocaleConstructorWithParams(); + + void testDuiLocaleConstructorAndCategoryWithParams_data(); + void testDuiLocaleConstructorAndCategoryWithParams(); + + void testCreateSystemLocale_data(); + void testCreateSystemLocale(); + void testDuiLocaleLanguage_data(); + void testDuiLocaleLanguage(); + void testDuiLocaleCountry_data(); + void testDuiLocaleCountry(); + void testDuiLocaleScript_data(); + void testDuiLocaleScript(); + + void testDuiLocaleVariant_data(); + void testDuiLocaleVariant(); + + void testDuiLocaleTextDirection_data(); + void testDuiLocaleTextDirection(); + + void testDuiLocaleLanguageEndonum_data(); + void testDuiLocaleLanguageEndonum(); + void testDuiLocaleCountryEndonum_data(); + void testDuiLocaleCountryEndonum(); + + void checkAvailableLocales(); +}; + + +#endif diff --git a/tests/ft_locales/ft_locales.pro b/tests/ft_locales/ft_locales.pro new file mode 100644 index 000000000..f0f6d8d59 --- /dev/null +++ b/tests/ft_locales/ft_locales.pro @@ -0,0 +1,15 @@ +include(../common_top.pri) + +CONFIG += link_pkgconfig +TARGET = ft_locales +PKGCONFIG += gconf-2.0 + +# unit +TEST_SOURCES = \ +# $$DUISRCDIR/duilocale.cpp \ + +# Input +HEADERS += ft_locales.h +SOURCES += ft_locales.cpp + +include(../common_bot.pri) diff --git a/tests/ft_numbers/.gitignore b/tests/ft_numbers/.gitignore new file mode 100644 index 000000000..be183945f --- /dev/null +++ b/tests/ft_numbers/.gitignore @@ -0,0 +1 @@ +ft_numbers diff --git a/tests/ft_numbers/ft_numbers.cpp b/tests/ft_numbers/ft_numbers.cpp new file mode 100644 index 000000000..1946cdaf6 --- /dev/null +++ b/tests/ft_numbers/ft_numbers.cpp @@ -0,0 +1,843 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ft_numbers.h" + +void Ft_Numbers::initTestCase() +{ + static int argc = 0; + static char *argv[1] = { (char *) "" }; + qap = new QCoreApplication(argc, argv); + QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8")); +} + +void Ft_Numbers::cleanup() +{ +} + +void Ft_Numbers::testQLongLongs_data() +{ + QTest::addColumn("locale_name"); + QTest::addColumn("val"); + QTest::addColumn("formatted"); + QTest::newRow("0_fi_FI") + << QString("fi_FI") + << (qlonglong) 1542678073 + << QString("1 542 678 073"); + QTest::newRow("0_en_GB") + << QString("en_GB") + << (qlonglong) 1542678073 + << QString("1,542,678,073"); + QTest::newRow("0_de_DE") + << QString("de_DE") + << (qlonglong) 1542678073 + << QString("1.542.678.073"); + QTest::newRow("0_de_CH") + << QString("de_CH") + << (qlonglong) 1542678073 + << QString("1'542'678'073"); + QTest::newRow("0_fr_FR") + << QString("fr_FR") + << (qlonglong) 1542678073 + << QString("1 542 678 073"); + QTest::newRow("0_ar_EG") + << QString("ar_EG") + << (qlonglong) 1542678073 + << QString("١٬٥٤٢٬٦٧٨٬٠٧٣"); + QTest::newRow("0_zh_CN") + << QString("zh_CN") + << (qlonglong) 1542678073 + << QString("1,542,678,073"); + QTest::newRow("0_ja_JP") + << QString("ja_JP") + << (qlonglong) 1542678073 + << QString("1,542,678,073"); + QTest::newRow("1_fi_FI") + << QString("fi_FI") + << (qlonglong) 1238242553 + << QString("1 238 242 553"); + QTest::newRow("1_en_GB") + << QString("en_GB") + << (qlonglong) 1238242553 + << QString("1,238,242,553"); + QTest::newRow("2_fi_FI") + << QString("fi_FI") + << (qlonglong) 1806969279 + << QString("1 806 969 279"); + QTest::newRow("2_en_GB") + << QString("en_GB") + << (qlonglong) 1806969279 + << QString("1,806,969,279"); + QTest::newRow("3_fi_FI") + << QString("fi_FI") + << (qlonglong) 942184991 + << QString("942 184 991"); + QTest::newRow("3_en_GB") + << QString("en_GB") + << (qlonglong) 942184991 + << QString("942,184,991"); + QTest::newRow("4_fi_FI") + << QString("fi_FI") + << (qlonglong) 1917307773 + << QString("1 917 307 773"); + QTest::newRow("4_en_GB") + << QString("en_GB") + << (qlonglong) 1917307773 + << QString("1,917,307,773"); + QTest::newRow("5_fi_FI") + << QString("fi_FI") + << (qlonglong) 1009760633 + << QString("1 009 760 633"); + QTest::newRow("5_en_GB") + << QString("en_GB") + << (qlonglong) 1009760633 + << QString("1,009,760,633"); + QTest::newRow("6_fi_FI") + << QString("fi_FI") + << (qlonglong) 258244588 + << QString("258 244 588"); + QTest::newRow("6_en_GB") + << QString("en_GB") + << (qlonglong) 258244588 + << QString("258,244,588"); + QTest::newRow("7_fi_FI") + << QString("fi_FI") + << (qlonglong) 1664066775 + << QString("1 664 066 775"); + QTest::newRow("7_en_GB") + << QString("en_GB") + << (qlonglong) 1664066775 + << QString("1,664,066,775"); + QTest::newRow("8_fi_FI") + << QString("fi_FI") + << (qlonglong) 816301636 + << QString("816 301 636"); + QTest::newRow("8_en_GB") + << QString("en_GB") + << (qlonglong) 816301636 + << QString("816,301,636"); + QTest::newRow("9_fi_FI") + << QString("fi_FI") + << (qlonglong) 1537479491 + << QString("1 537 479 491"); + QTest::newRow("9_en_GB") + << QString("en_GB") + << (qlonglong) 1537479491 + << QString("1,537,479,491"); +} + +void Ft_Numbers::testQLongLongs() +{ + QFETCH(QString, locale_name); + QFETCH(qlonglong, val); + QFETCH(QString, formatted); + DuiLocale loc(locale_name); +// printf("%s\n", loc.formatNumber(val).toUtf8().constData()); + QCOMPARE(loc.formatNumber(val), formatted); +} + +void Ft_Numbers::testShorts_data() +{ + QTest::addColumn("locale_name"); + QTest::addColumn("val"); + QTest::addColumn("formatted"); + QTest::newRow("0_fi") + << QString("fi_FI") + << (short) 632 + << QString("632"); + QTest::newRow("0_en") + << QString("en_GB") + << (short) 632 + << QString("632"); + QTest::newRow("1_fi") + << QString("fi_FI") + << (short) 21131 + << QString("21 131"); + QTest::newRow("1_en") + << QString("en_GB") + << (short) 21131 + << QString("21,131"); + QTest::newRow("2_fi") + << QString("fi_FI") + << (short) 28515 + << QString("28 515"); + QTest::newRow("2_en") + << QString("en_GB") + << (short) 28515 + << QString("28,515"); + QTest::newRow("3_fi") + << QString("fi_FI") + << (short) 6822 + << QString("6 822"); + QTest::newRow("3_en") + << QString("en_GB") + << (short) 6822 + << QString("6,822"); + QTest::newRow("4_fi") + << QString("fi_FI") + << (short) - 1824 + << QString("-1 824"); + QTest::newRow("4_en") + << QString("en_GB") + << (short) - 1824 + << QString("-1,824"); + QTest::newRow("5_fi") + << QString("fi_FI") + << (short) 11741 + << QString("11 741"); + QTest::newRow("5_en") + << QString("en_GB") + << (short) 11741 + << QString("11,741"); + QTest::newRow("6_fi") + << QString("fi_FI") + << (short) 13490 + << QString("13 490"); + QTest::newRow("6_en") + << QString("en_GB") + << (short) 13490 + << QString("13,490"); + QTest::newRow("7_fi") + << QString("fi_FI") + << (short) - 7886 + << QString("-7 886"); + QTest::newRow("7_en") + << QString("en_GB") + << (short) - 7886 + << QString("-7,886"); + QTest::newRow("8_fi") + << QString("fi_FI") + << (short) - 27117 + << QString("-27 117"); + QTest::newRow("8_en") + << QString("en_GB") + << (short) - 27117 + << QString("-27,117"); + QTest::newRow("9_fi") + << QString("fi_FI") + << (short) 27627 + << QString("27 627"); + QTest::newRow("9_en") + << QString("en_GB") + << (short) 27627 + << QString("27,627"); +} + +void Ft_Numbers::testShorts() +{ + QFETCH(QString, locale_name); + QFETCH(short, val); + DuiLocale loc(locale_name); + QTEST(loc.formatNumber(val), "formatted"); +} + +void Ft_Numbers::testInts_data() +{ + QTest::addColumn("locale_name"); + QTest::addColumn("val"); + QTest::addColumn("formatted"); + QTest::newRow("0_fi") + << QString("fi_FI") + << (int) 1369430476 + << QString("1 369 430 476"); + QTest::newRow("0_en") + << QString("en_GB") + << (int) 1369430476 + << QString("1,369,430,476"); + QTest::newRow("1_fi") + << QString("fi_FI") + << (int) 1536207176 + << QString("1 536 207 176"); + QTest::newRow("1_en") + << QString("en_GB") + << (int) 1536207176 + << QString("1,536,207,176"); + QTest::newRow("2_fi") + << QString("fi_FI") + << (int) 1320475240 + << QString("1 320 475 240"); + QTest::newRow("2_en") + << QString("en_GB") + << (int) 1320475240 + << QString("1,320,475,240"); + QTest::newRow("3_fi") + << QString("fi_FI") + << (int) 2135623067 + << QString("2 135 623 067"); + QTest::newRow("3_en") + << QString("en_GB") + << (int) 2135623067 + << QString("2,135,623,067"); + QTest::newRow("4_fi") + << QString("fi_FI") + << (int) 1868779941 + << QString("1 868 779 941"); + QTest::newRow("4_en") + << QString("en_GB") + << (int) 1868779941 + << QString("1,868,779,941"); + QTest::newRow("5_fi") + << QString("fi_FI") + << (int) 885469168 + << QString("885 469 168"); + QTest::newRow("5_en") + << QString("en_GB") + << (int) 885469168 + << QString("885,469,168"); + QTest::newRow("6_fi") + << QString("fi_FI") + << (int) 948672826 + << QString("948 672 826"); + QTest::newRow("6_en") + << QString("en_GB") + << (int) 948672826 + << QString("948,672,826"); + QTest::newRow("7_fi") + << QString("fi_FI") + << (int) 242845572 + << QString("242 845 572"); + QTest::newRow("7_en") + << QString("en_GB") + << (int) 242845572 + << QString("242,845,572"); + QTest::newRow("8_fi") + << QString("fi_FI") + << (int) 1469851943 + << QString("1 469 851 943"); + QTest::newRow("8_en") + << QString("en_GB") + << (int) 1469851943 + << QString("1,469,851,943"); + QTest::newRow("9_fi") + << QString("fi_FI") + << (int) 1970611277 + << QString("1 970 611 277"); + QTest::newRow("9_en") + << QString("en_GB") + << (int) 1970611277 + << QString("1,970,611,277"); +} + +void Ft_Numbers::testInts() +{ + QFETCH(QString, locale_name); + QFETCH(int, val); + QFETCH(QString, formatted); + DuiLocale loc(locale_name); + QCOMPARE(loc.formatNumber(val), formatted); +} + +void Ft_Numbers::testDoubles_data() +{ + QTest::addColumn("locale_name"); + QTest::addColumn("val"); + QTest::addColumn("formatted"); + QTest::newRow("0_fi") + << QString("fi_FI") + << (double) 0 + << QString("0"); + QTest::newRow("0_en") + << QString("en_GB") + << (double) 0 + << QString("0"); + QTest::newRow("1_fi") + << QString("fi_FI") + << (double) 0.1 + << QString("0,1"); + QTest::newRow("1_en") + << QString("en_GB") + << (double) 0.1 + << QString("0.1"); + QTest::newRow("2_fi") + << QString("fi_FI") + << (double) 0.12 + << QString("0,12"); + QTest::newRow("2_en") + << QString("en_GB") + << (double) 0.12 + << QString("0.12"); + QTest::newRow("3_fi") + << QString("fi_FI") + << (double) 0.123 + << QString("0,123"); + QTest::newRow("3_en") + << QString("en_GB") + << (double) 0.123 + << QString("0.123"); + QTest::newRow("4_fi") + << QString("fi_FI") + << (double) 0.1234 + << QString("0,123"); + QTest::newRow("4_en") + << QString("en_GB") + << (double) 0.1234 + << QString("0.123"); + QTest::newRow("5_fi") + << QString("fi_FI") + << (double) 0.12345 + << QString("0,123"); + QTest::newRow("5_en") + << QString("en_GB") + << (double) 0.12345 + << QString("0.123"); + QTest::newRow("6_fi") + << QString("fi_FI") + << (double) 0.123456 + << QString("0,123"); + QTest::newRow("6_en") + << QString("en_GB") + << (double) 0.123456 + << QString("0.123"); + QTest::newRow("7_fi") + << QString("fi_FI") + << (double) 0.1234567 + << QString("0,123"); + QTest::newRow("7_en") + << QString("en_GB") + << (double) 0.1234567 + << QString("0.123"); + QTest::newRow("8_fi") + << QString("fi_FI") + << (double) 1.1234567 + << QString("1,123"); + QTest::newRow("8_en") + << QString("en_GB") + << (double) 1.1234567 + << QString("1.123"); + QTest::newRow("9_fi") + << QString("fi_FI") + << (double) 12.1234567 + << QString("12,123"); + QTest::newRow("9_en") + << QString("en_GB") + << (double) 12.1234567 + << QString("12.123"); + QTest::newRow("10_fi") + << QString("fi_FI") + << (double) 123.1234567 + << QString("123,123"); + QTest::newRow("10_en") + << QString("en_GB") + << (double) 123.1234567 + << QString("123.123"); + QTest::newRow("11_fi") + << QString("fi_FI") + << (double) 1234.1234567 + << QString("1 234,123"); + QTest::newRow("11_en") + << QString("en_GB") + << (double) 1234.1234567 + << QString("1,234.123"); + QTest::newRow("12_fi") + << QString("fi_FI") + << (double) 12345.1234567 + << QString("12 345,123"); + QTest::newRow("12_en") + << QString("en_GB") + << (double) 12345.1234567 + << QString("12,345.123"); + QTest::newRow("13_fi") + << QString("fi_FI") + << (double) 123456.1234567 + << QString("123 456,123"); + QTest::newRow("13_en") + << QString("en_GB") + << (double) 123456.1234567 + << QString("123,456.123"); + QTest::newRow("14_fi") + << QString("fi_FI") + << (double) 1234567.1234567 + << QString("1 234 567,123"); + QTest::newRow("14_en") + << QString("en_GB") + << (double) 1234567.1234567 + << QString("1,234,567.123"); +} + +void Ft_Numbers::testDoubles() +{ + QFETCH(QString, locale_name); + QFETCH(double, val); + QFETCH(QString, formatted); + DuiLocale loc(locale_name); + QCOMPARE(loc.formatNumber(val), formatted); +} + +void Ft_Numbers::testFloats_data() +{ + QTest::addColumn("locale_name"); + QTest::addColumn("val"); + QTest::addColumn("formatted"); + QTest::newRow("0_fi") + << QString("fi_FI") + << (float) 0 + << QString("0"); + QTest::newRow("0_en") + << QString("en_GB") + << (float) 0 + << QString("0"); + QTest::newRow("1_fi") + << QString("fi_FI") + << (float) 0.1 + << QString("0,1"); + QTest::newRow("1_en") + << QString("en_GB") + << (float) 0.1 + << QString("0.1"); + QTest::newRow("2_fi") + << QString("fi_FI") + << (float) 0.12 + << QString("0,12"); + QTest::newRow("2_en") + << QString("en_GB") + << (float) 0.12 + << QString("0.12"); + QTest::newRow("3_fi") + << QString("fi_FI") + << (float) 0.123 + << QString("0,123"); + QTest::newRow("3_en") + << QString("en_GB") + << (float) 0.123 + << QString("0.123"); + QTest::newRow("4_fi") + << QString("fi_FI") + << (float) 0.1234 + << QString("0,123"); + QTest::newRow("4_en") + << QString("en_GB") + << (float) 0.1234 + << QString("0.123"); + QTest::newRow("5_fi") + << QString("fi_FI") + << (float) 0.12345 + << QString("0,123"); + QTest::newRow("5_en") + << QString("en_GB") + << (float) 0.12345 + << QString("0.123"); + QTest::newRow("6_fi") + << QString("fi_FI") + << (float) 0.123456 + << QString("0,123"); + QTest::newRow("6_en") + << QString("en_GB") + << (float) 0.123456 + << QString("0.123"); + QTest::newRow("7_fi") + << QString("fi_FI") + << (float) 0.1234567 + << QString("0,123"); + QTest::newRow("7_en") + << QString("en_GB") + << (float) 0.1234567 + << QString("0.123"); + QTest::newRow("8_fi") + << QString("fi_FI") + << (float) 1.1234567 + << QString("1,123"); + QTest::newRow("8_en") + << QString("en_GB") + << (float) 1.1234567 + << QString("1.123"); + QTest::newRow("9_fi") + << QString("fi_FI") + << (float) 12.1234567 + << QString("12,123"); + QTest::newRow("9_en") + << QString("en_GB") + << (float) 12.1234567 + << QString("12.123"); + QTest::newRow("10_fi") + << QString("fi_FI") + << (float) 123.1234567 + << QString("123,123"); + QTest::newRow("10_en") + << QString("en_GB") + << (float) 123.1234567 + << QString("123.123"); + QTest::newRow("11_fi") + << QString("fi_FI") + << (float) 1234.1234567 + << QString("1 234,123"); + QTest::newRow("11_en") + << QString("en_GB") + << (float) 1234.1234567 + << QString("1,234.123"); + QTest::newRow("12_fi") + << QString("fi_FI") + << (float) 12345.1234567 + << QString("12 345,123"); + QTest::newRow("12_en") + << QString("en_GB") + << (float) 12345.1234567 + << QString("12,345.123"); + QTest::newRow("13_fi") + << QString("fi_FI") + << (float) 123456.1234567 + << QString("123 456,125"); + QTest::newRow("13_en") + << QString("en_GB") + << (float) 123456.1234567 + << QString("123,456.125"); + QTest::newRow("14_fi") + << QString("fi_FI") + << (float) 1234567.1234567 + << QString("1 234 567,125"); + QTest::newRow("14_en") + << QString("en_GB") + << (float) 1234567.1234567 + << QString("1,234,567.125"); +} + +void Ft_Numbers::testFloats() +{ + QFETCH(QString, locale_name); + QFETCH(float, val); + QFETCH(QString, formatted); + DuiLocale loc(locale_name); + QCOMPARE(loc.formatNumber(val), formatted); +} + +void Ft_Numbers::testDoublesWithFormatting_data() +{ + QTest::addColumn("locale_name"); + QTest::addColumn("val"); + QTest::addColumn("prec"); + QTest::addColumn("formatted"); + + double defaultNumber = 1234567.1234567; + + QTest::newRow("0_fi") + << QString("fi_FI") + << defaultNumber + << 0 << QString("1 234 567"); + QTest::newRow("0_en") + << QString("en_GB") + << defaultNumber + << 0 << QString("1,234,567"); + QTest::newRow("1_fi") + << QString("fi_FI") + << defaultNumber + << 1 << QString("1 234 567,1"); + QTest::newRow("1_en") + << QString("en_GB") + << defaultNumber + << 1 << QString("1,234,567.1"); + QTest::newRow("2_fi") + << QString("fi_FI") + << defaultNumber + << 2 << QString("1 234 567,12"); + QTest::newRow("2_en") + << QString("en_GB") + << defaultNumber + << 2 << QString("1,234,567.12"); + QTest::newRow("3_fi") + << QString("fi_FI") + << defaultNumber + << 3 << QString("1 234 567,123"); + QTest::newRow("3_en") + << QString("en_GB") + << defaultNumber + << 3 << QString("1,234,567.123"); + QTest::newRow("4_fi") + << QString("fi_FI") + << defaultNumber + << 4 << QString("1 234 567,1235"); + QTest::newRow("4_en") + << QString("en_GB") + << defaultNumber + << 4 << QString("1,234,567.1235"); + QTest::newRow("5_fi") + << QString("fi_FI") + << defaultNumber + << 5 << QString("1 234 567,12346"); + QTest::newRow("5_en") + << QString("en_GB") + << defaultNumber + << 5 << QString("1,234,567.12346"); + QTest::newRow("6_fi") + << QString("fi_FI") + << defaultNumber + << 6 << QString("1 234 567,123457"); + QTest::newRow("6_en") + << QString("en_GB") + << defaultNumber + << 6 << QString("1,234,567.123457"); +} + +void Ft_Numbers::testDoublesWithFormatting() +{ + QFETCH(QString, locale_name); + QFETCH(double, val); + QFETCH(int, prec); + DuiLocale loc(locale_name); + QTEST(loc.formatNumber(val, prec), "formatted"); +} + +void Ft_Numbers::testPercents_data() +{ + QTest::addColumn("locale_name"); + QTest::addColumn("val"); + QTest::addColumn("decimals"); + QTest::addColumn("formatted"); + + QTest::newRow("0_fi") + << QString("fi_FI") + << 0.123456 + << 0 + << QString("12 %"); + QTest::newRow("1_fi") + << QString("fi_FI") + << 0.123456 + << 1 + << QString("12,3 %"); + QTest::newRow("2_fi") + << QString("fi_FI") + << 0.123456 + << 2 + << QString("12,35 %"); + QTest::newRow("3_fi") + << QString("fi_FI") + << 0.123456 + << 3 + << QString("12,346 %"); + QTest::newRow("4_fi") + << QString("fi_FI") + << 0.123456 + << 4 + << QString("12,3456 %"); + QTest::newRow("0_en") + << QString("en_GB") + << 0.123456 + << 0 + << QString("12%"); + QTest::newRow("1_en") + << QString("en_GB") + << 0.123456 + << 1 + << QString("12.3%"); + QTest::newRow("2_en") + << QString("en_GB") + << 0.123456 + << 2 + << QString("12.35%"); + QTest::newRow("3_en") + << QString("en_GB") + << 0.123456 + << 3 + << QString("12.346%"); + QTest::newRow("4_en") + << QString("en_GB") + << 0.123456 + << 4 + << QString("12.3456%"); +} + +void Ft_Numbers::testPercents() +{ + QFETCH(QString, locale_name); + QFETCH(int, decimals); + QFETCH(double, val); + DuiLocale loc(locale_name); + QTEST(loc.formatPercent(val, decimals), "formatted"); +} + +void Ft_Numbers::testCurrencies_data() +{ + QTest::addColumn("locale_name"); + QTest::addColumn("val"); + QTest::addColumn("currency"); + QTest::addColumn("formatted"); + + QTest::newRow("0_fi") + << QString("fi_FI") + << 1234.56 + << "EUR" + << QString("1 234,56 €"); + QTest::newRow("1_fi") + << QString("fi_FI") + << 1234.56 + << "USD" + << QString("1 234,56 $"); + QTest::newRow("2_fi") + << QString("fi_FI") + << 1234.56 + << "GBP" + << QString("1 234,56 £"); + QTest::newRow("3_fi") + << QString("fi_FI") + << 1234.56 + << "XYZ" + << QString("1 234,56 XYZ"); + + QTest::newRow("0_en") + << QString("en_GB") + << 1234.56 + << "EUR" + << QString("€1,234.56"); + QTest::newRow("1_en") + << QString("en_GB") + << 1234.56 + << "USD" + << QString("$1,234.56"); + QTest::newRow("2_en") + << QString("en_GB") + << 1234.56 + << "GBP" + << QString("£1,234.56"); + QTest::newRow("3_en") + << QString("en_GB") + << 1234.56 + << "XYZ" + << QString("XYZ1,234.56"); + + QTest::newRow("0_de") + << QString("de_DE") + << 1234.56 + << "EUR" + << QString("1.234,56 €"); + QTest::newRow("1_de") + << QString("de_DE") + << 1234.56 + << "USD" + << QString("1.234,56 $"); + QTest::newRow("2_de") + << QString("de_DE") + << 1234.56 + << "GBP" + << QString("1.234,56 £"); + QTest::newRow("3_de") + << QString("de_DE") + << 1234.56 + << "XYZ" + << QString("1.234,56 XYZ"); +} + +void Ft_Numbers::testCurrencies() +{ + QFETCH(QString, locale_name); + QFETCH(double, val); + QFETCH(QString, currency); + DuiLocale loc(locale_name); + QTEST(loc.formatCurrency(val, currency), "formatted"); +} + +QTEST_APPLESS_MAIN(Ft_Numbers); + diff --git a/tests/ft_numbers/ft_numbers.h b/tests/ft_numbers/ft_numbers.h new file mode 100644 index 000000000..c75d2b045 --- /dev/null +++ b/tests/ft_numbers/ft_numbers.h @@ -0,0 +1,71 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef FT_NUMBERS_H +#define FT_NUMBERS_H + + +#include +#include +#include + + +Q_DECLARE_METATYPE(DuiLocale); +Q_DECLARE_METATYPE(qlonglong); + +#define MAX_PARAMS 10 +class Ft_Numbers : public QObject +{ + Q_OBJECT + +private: + QCoreApplication *qap; + +private slots: + void initTestCase(); + void cleanup(); + + void testFloats_data(); + void testFloats(); + + void testShorts_data(); + void testShorts(); + + void testQLongLongs_data(); + void testQLongLongs(); + + void testInts_data(); + void testInts(); + + void testDoubles_data(); + void testDoubles(); + + void testDoublesWithFormatting_data(); + + void testDoublesWithFormatting(); + + void testPercents_data(); + void testPercents(); + + void testCurrencies_data(); + void testCurrencies(); +}; + + +#endif diff --git a/tests/ft_numbers/ft_numbers.pro b/tests/ft_numbers/ft_numbers.pro new file mode 100644 index 000000000..9527c66f2 --- /dev/null +++ b/tests/ft_numbers/ft_numbers.pro @@ -0,0 +1,9 @@ +include(../common_top.pri) + +TARGET = ft_numbers + +# Input +HEADERS += ft_numbers.h +SOURCES += ft_numbers.cpp + +include(../common_bot.pri) diff --git a/tests/ft_prestart/.gitignore b/tests/ft_prestart/.gitignore new file mode 100644 index 000000000..d209c2e15 --- /dev/null +++ b/tests/ft_prestart/.gitignore @@ -0,0 +1 @@ +ft_prestart diff --git a/tests/ft_prestart/ft_prestart.cpp b/tests/ft_prestart/ft_prestart.cpp new file mode 100644 index 000000000..485bcb710 --- /dev/null +++ b/tests/ft_prestart/ft_prestart.cpp @@ -0,0 +1,414 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include "duiapplicationservice_p.h" +#include +#include + +#include "ft_prestart.h" + +// has to be included last +#include "duiapplication_p.h" + +char *Ft_Prestart::argv[MAX_PARAMS]; +int Ft_Prestart::argc; +bool Ft_Prestart::programArgsCorrect = false; +bool Ft_Prestart::programStarted = false; +bool Ft_Prestart::allowRegisterService = true; +bool Ft_Prestart::allowRegisterService2 = true; +int Ft_Prestart::failRegisterServiceTimes = 1; +int Ft_Prestart::failRegisterServiceCounter = 0; +QString Ft_Prestart::registeredService("notSet"); +bool Ft_Prestart::applicationExited = false; +bool Ft_Prestart::activeWindowSet = false; +bool Ft_Prestart::windowActivated = false; +bool Ft_Prestart::windowRaised = false; +bool Ft_Prestart::windowClosed = false; +bool Ft_Prestart::windowShown = false; + +QDBusPendingReply<> DuiApplicationIfProxy::launch() +{ + return QDBusPendingReply<>(); +} + +bool DuiApplicationServicePrivate::registerService(const QString &name) +{ + bool retVal = false; + + if (Ft_Prestart::allowRegisterService) { + retVal = true; + Ft_Prestart::registeredService = name; + } else { + if (Ft_Prestart::allowRegisterService2) { + if (Ft_Prestart::failRegisterServiceCounter < + Ft_Prestart::failRegisterServiceTimes) { + Ft_Prestart::failRegisterServiceCounter++; + } else { + retVal = true; + Ft_Prestart::registeredService = name; + Ft_Prestart::failRegisterServiceCounter = 0; + } + } + } + + qDebug() << "DuiApplicationServicePrivate::registerService() returning " << retVal; + return retVal; +} + +void QWidget::activateWindow() +{ + Ft_Prestart::windowActivated = true; +} + +void QWidget::raise() +{ + Ft_Prestart::windowRaised = true; +} + +void QApplication::closeAllWindows() +{ + Ft_Prestart::windowClosed = true; +} + +void QWidget::setVisible(bool visible) +{ + Ft_Prestart::windowShown = visible; +} + +void DuiApplicationPrivate::stdExit(int status) +{ + Ft_Prestart::applicationExited = true; + Q_UNUSED(status); + // don't exit - need to carry on to complete other tests +} + +void Ft_Prestart::initGlobals() +{ + programArgsCorrect = false; + programStarted = false; + allowRegisterService = true; + allowRegisterService2 = true; + failRegisterServiceTimes = 1; + failRegisterServiceCounter = 0; + registeredService = QString("notSet"); + applicationExited = false; + activeWindowSet = false; + windowActivated = false; + windowRaised = false; + windowClosed = false; + windowShown = false; +} + +void Ft_Prestart::init() +{ + argc = 2; + argv[0] = strdup("ft_prestart"); + argv[1] = strdup("-software"); + m_duiApp = 0; + initGlobals(); +} + +void Ft_Prestart::cleanup() +{ + delete m_duiApp; + m_duiApp = 0; + for (int i = 0; i < argc; i++) { + free(argv[i]); + } +} + +void Ft_Prestart::initTestCase() +{ +} + +void Ft_Prestart::cleanupTestCase() +{ +} + +void Ft_Prestart::buildPrestartedApp() +{ + m_subject = new DuiApplicationService("ft_prestart"); + if (argc < MAX_PARAMS) { + argv[argc] = strdup("-prestart"); + argc++; + } + m_duiApp = new DuiApplication(argc, argv, m_subject); + windowRaised = false; + windowActivated = false; + windowShown = false; + windowClosed = false; + applicationExited = false; +} + +void Ft_Prestart::PrestartLaunchTerminateOnClose() +{ + Ft_Prestart::allowRegisterService = true; + Ft_Prestart::allowRegisterService2 = true; + buildPrestartedApp(); + m_duiApp->setPrestartMode(Dui::TerminateOnClose); + + DuiApplicationWindow *window = new DuiApplicationWindow(); + + // window.show should not have any effect in prestarted mode + window->show(); + + // Application in prestarted state, no window visible + QCOMPARE(Ft_Prestart::windowRaised, false); + QCOMPARE(Ft_Prestart::windowActivated, false); + QCOMPARE(Ft_Prestart::windowShown, false); + + // dbus launch, window should be activated + m_subject->launch(); + QCOMPARE(Ft_Prestart::windowRaised, true); + QCOMPARE(Ft_Prestart::windowActivated, true); + QCOMPARE(Ft_Prestart::windowShown, true); +} + +void Ft_Prestart::closePrestartedLazyShutdownApplication() +{ + Ft_Prestart::allowRegisterService = false; + buildPrestartedApp(); + m_duiApp->setPrestartMode(Dui::LazyShutdown); + + DuiApplicationWindow *window = new DuiApplicationWindow(); + window->show(); + + // Launch prestarted application + m_subject->launch(); + QCOMPARE(Ft_Prestart::windowShown, true); + + // Close prestarted application, window should be hidden and application still in prestarted-mode + m_subject->close(); + QCOMPARE(Ft_Prestart::windowShown, false); + QCOMPARE(m_duiApp->isPrestarted(), true); + + // Re-launch application, window should be shown + m_subject->launch(); + QCOMPARE(Ft_Prestart::windowShown, true); +} + +void Ft_Prestart::exitPrestartedLazyShutdownApplication() +{ + Ft_Prestart::allowRegisterService = false; + buildPrestartedApp(); + m_duiApp->setPrestartMode(Dui::LazyShutdown); + + DuiApplicationWindow *window = new DuiApplicationWindow(); + window->show(); + + // Launch prestarted application + m_subject->launch(); + QCOMPARE(Ft_Prestart::windowShown, true); + + // Close prestarted application, window should be hidden and application still in prestarted-mode + m_subject->exit(); + QCOMPARE(Ft_Prestart::windowShown, false); + QCOMPARE(m_duiApp->isPrestarted(), true); + + // Re-launch application, window should be shown + m_subject->launch(); + QCOMPARE(Ft_Prestart::windowShown, true); +} + +void Ft_Prestart::closePrestartedNoPrestartApplication() +{ + Ft_Prestart::allowRegisterService = false; + buildPrestartedApp(); + QCOMPARE(m_duiApp->prestartMode(), Dui::NoPrestart); + + DuiApplicationWindow window; + window.show(); + // Launch prestarted application without prestartmode set + m_subject->launch(); + + QCOMPARE(Ft_Prestart::windowRaised, true); + QCOMPARE(Ft_Prestart::windowShown, true); + QCOMPARE(Ft_Prestart::windowClosed, false); + + // Close prestarted application, window should be hidden and application still in prestarted-mode + m_subject->close(); + QCOMPARE(Ft_Prestart::windowClosed, true); + QCOMPARE(m_duiApp->isPrestarted(), false); +} + +void Ft_Prestart::exitPrestartedNoPrestartApplication() +{ + Ft_Prestart::allowRegisterService = false; + buildPrestartedApp(); + QCOMPARE(m_duiApp->prestartMode(), Dui::NoPrestart); + + DuiApplicationWindow window; + window.show(); + // Launch prestarted application without prestartmode set + m_subject->launch(); + + QCOMPARE(Ft_Prestart::windowRaised, true); + QCOMPARE(Ft_Prestart::windowShown, true); + QCOMPARE(Ft_Prestart::applicationExited, false); + + // Exit prestarted application, window should be hidden and application still in prestarted-mode + m_subject->exit(); + QCOMPARE(Ft_Prestart::applicationExited, true); + QCOMPARE(m_duiApp->isPrestarted(), false); +} + +void Ft_Prestart::closePrestartedTerminateOnCloseApplication() +{ + Ft_Prestart::allowRegisterService = false; + buildPrestartedApp(); + m_duiApp->setPrestartMode(Dui::TerminateOnClose); + + DuiApplicationWindow window; + window.show(); + // Launch prestarted application without prestartmode set + m_subject->launch(); + + QCOMPARE(Ft_Prestart::windowRaised, true); + QCOMPARE(Ft_Prestart::windowShown, true); + QCOMPARE(Ft_Prestart::windowClosed, false); + + // Close prestarted application, window should be hidden and application still in prestarted-mode + m_subject->close(); + QCOMPARE(Ft_Prestart::windowClosed, true); + QCOMPARE(m_duiApp->isPrestarted(), false); +} + +void Ft_Prestart::exitPrestartedTerminateOnCloseApplication() +{ + Ft_Prestart::allowRegisterService = false; + buildPrestartedApp(); + m_duiApp->setPrestartMode(Dui::TerminateOnClose); + + DuiApplicationWindow window; + window.show(); + // Launch prestarted application without prestartmode set + m_subject->launch(); + + QCOMPARE(Ft_Prestart::windowRaised, true); + QCOMPARE(Ft_Prestart::windowShown, true); + QCOMPARE(Ft_Prestart::applicationExited, false); + + // Exit prestarted application, window should be hidden and application still in prestarted-mode + m_subject->exit(); + QCOMPARE(Ft_Prestart::applicationExited, true); + QCOMPARE(m_duiApp->isPrestarted(), false); +} + + + +// IMPORTED FROM UT_DUIAPPLICATIONWINDOW + +void Ft_Prestart::testPrestartedLazyShutdownShow() +{ + buildPrestartedApp(); + m_duiApp->setPrestartMode(Dui::LazyShutdown); + QCOMPARE(Ft_Prestart::windowShown, false); + m_duiWin->show(); + // Show should not be enough to show application which is in prestarted state + QCOMPARE(Ft_Prestart::windowShown, false); +} + +void Ft_Prestart::testPrestartedTerminateOnCloseShow() +{ + buildPrestartedApp(); + m_duiApp->setPrestartMode(Dui::TerminateOnClose); + QCOMPARE(Ft_Prestart::windowShown, false); + m_duiWin->show(); + // Show should not be enough to show application which is in prestarted state + QCOMPARE(Ft_Prestart::windowShown, false); +} + +void Ft_Prestart::testPrestartedNoPrestartShow() +{ + buildPrestartedApp(); + m_duiApp->setPrestartMode(Dui::NoPrestart); + QCOMPARE(Ft_Prestart::windowShown, false); + m_duiWin->show(); + QCOMPARE(Ft_Prestart::windowShown, true); +} + +void Ft_Prestart::testPrestartedNoPrestartClose() +{ + buildPrestartedApp(); + m_duiApp->setPrestartMode(Dui::NoPrestart); + QCOMPARE(Ft_Prestart::windowShown, false); + + m_duiWin->show(); + QCOMPARE(Ft_Prestart::windowShown, true); + QCOMPARE(Ft_Prestart::windowClosed, false); + + m_subject->close(); + QCOMPARE(Ft_Prestart::windowClosed, true); + QCOMPARE(m_duiApp->isPrestarted(), false); +} + +void Ft_Prestart::testPrestartedLazyShutdownClose() +{ + DuiApplicationService *m_subject = new DuiApplicationService("com.nokia.myApp"); + buildPrestartedApp(); + m_duiApp->setPrestartMode(Dui::LazyShutdown); + + // Simulate launch using D-Bus + m_subject->launch(); + + QCOMPARE(Ft_Prestart::windowShown, true); + + // Close the window + m_subject->close(); + + // Window should not be really closed after close if LazyShutdown + QCOMPARE(Ft_Prestart::windowClosed, false); + QCOMPARE(Ft_Prestart::windowShown, false); + QCOMPARE(m_duiApp->isPrestarted(), true); + + // Simulate launch using D-Bus + m_subject->launch(); + + QCOMPARE(Ft_Prestart::windowShown, true); +} + +void Ft_Prestart::testPrestartedTerminateOnCloseClose() +{ + DuiApplicationService *m_subject = new DuiApplicationService("com.nokia.myApp"); + buildPrestartedApp(); + m_duiApp->setPrestartMode(Dui::TerminateOnClose); + + // Simulate launch using D-Bus + m_subject->launch(); + QCOMPARE(Ft_Prestart::windowShown, true); + + // Close the window + m_subject->close(); + + QCOMPARE(Ft_Prestart::windowClosed, true); + QCOMPARE(m_duiApp->isPrestarted(), false); +} + + + +QTEST_APPLESS_MAIN(Ft_Prestart) diff --git a/tests/ft_prestart/ft_prestart.h b/tests/ft_prestart/ft_prestart.h new file mode 100644 index 000000000..da3b6b646 --- /dev/null +++ b/tests/ft_prestart/ft_prestart.h @@ -0,0 +1,85 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef FT_PRESTART_H +#define FT_PRESTART_H + +#include +#include + +#include + +Q_DECLARE_METATYPE(DuiApplicationService *); + +class DuiApplication; +class DuiApplicationWindow; + +#define MAX_PARAMS 10 + +class Ft_Prestart : public QObject +{ + Q_OBJECT + +public: + // mock control/report variables + static bool activeWindowSet; + static bool windowRaised; + static bool windowActivated; + static bool windowShown; + static bool windowClosed; + static bool applicationExited; + static bool allowRegisterService; + static bool allowRegisterService2; + static int failRegisterServiceTimes; + static int failRegisterServiceCounter; + static bool programStarted; + static bool programArgsCorrect; + static QString registeredService; + static char *argv[MAX_PARAMS]; + static int argc; + +private slots: + void init(); + void cleanup(); + void initTestCase(); + void cleanupTestCase(); + void PrestartLaunchTerminateOnClose(); + void closePrestartedLazyShutdownApplication(); + void exitPrestartedLazyShutdownApplication(); + void closePrestartedNoPrestartApplication(); + void exitPrestartedNoPrestartApplication(); + void closePrestartedTerminateOnCloseApplication(); + void exitPrestartedTerminateOnCloseApplication(); + + void testPrestartedNoPrestartShow(); + void testPrestartedLazyShutdownShow(); + void testPrestartedTerminateOnCloseShow(); + void testPrestartedNoPrestartClose(); + void testPrestartedLazyShutdownClose(); + void testPrestartedTerminateOnCloseClose(); + +private: + void initGlobals(); + void buildPrestartedApp(); + DuiApplicationWindow *m_duiWin; + DuiApplicationService *m_subject; + DuiApplication *m_duiApp; +}; + +#endif diff --git a/tests/ft_prestart/ft_prestart.pro b/tests/ft_prestart/ft_prestart.pro new file mode 100644 index 000000000..9e51e6289 --- /dev/null +++ b/tests/ft_prestart/ft_prestart.pro @@ -0,0 +1,13 @@ +include(../common_top.pri) +INCLUDEPATH += $$DUISRCDIR/core +TARGET = ft_prestart + +# unit test and unit +SOURCES += \ + ft_prestart.cpp \ + +# unit test and unit +HEADERS += \ + ft_prestart.h \ + +include(../common_bot.pri) diff --git a/tests/ft_sorting/.gitignore b/tests/ft_sorting/.gitignore new file mode 100644 index 000000000..162a70cf7 --- /dev/null +++ b/tests/ft_sorting/.gitignore @@ -0,0 +1 @@ +ft_sorting diff --git a/tests/ft_sorting/ft_sorting.cpp b/tests/ft_sorting/ft_sorting.cpp new file mode 100644 index 000000000..897213c2e --- /dev/null +++ b/tests/ft_sorting/ft_sorting.cpp @@ -0,0 +1,386 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ft_sorting.h" +#include +#include +#include +#include +#include + +void Ft_Sorting::initTestCase() +{ + static int argc = 0; + static char *argv[1] = { (char *) "" }; + qap = new QCoreApplication(argc, argv); + QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8")); + QProcess process; + process.start("sh -c \"dpkg -s libicu42 | grep Version | perl -pe 's/^Version:[[:space:]]*([^[[:space:]]+)$/$1/g'\""); + if (!process.waitForFinished()) { + qDebug() << "cannot run process to check libicu42 package version , exiting ..."; + exit(1); + } + icuPackageVersion = process.readAllStandardOutput(); + icuPackageVersion.replace("\n", ""); + qDebug() << "libicu42 package version is:" << icuPackageVersion; +} + +void Ft_Sorting::cleanup() +{ +} + +void Ft_Sorting::testDuiLocaleSorting_data() +{ + QTest::addColumn("locale_name"); + QTest::addColumn("source1"); + QTest::addColumn("source2"); + QTest::addColumn("source3"); + QTest::addColumn("source4"); + QTest::addColumn("source5"); + QTest::addColumn("target1"); + QTest::addColumn("target2"); + QTest::addColumn("target3"); + QTest::addColumn("target4"); + QTest::addColumn("target5"); + + QTest::newRow("Sorting_fi_FI") + << QString("fi_FI") + << QString("z3zz") + << QString("åtgh") + << QString("b2bb") + << QString("ähjj") + << QString("abcd") + + << QString("abcd") + << QString("b2bb") + << QString("z3zz") + << QString("åtgh") + << QString("ähjj"); + + QTest::newRow("Sorting_nn_NO") + << QString("nn_NO") + << QString("å") + << QString("ø") + << QString("z") + << QString("a") + << QString("f") + + << QString("a") + << QString("f") + << QString("z") + << QString("ø") + << QString("å"); + + if (icuPackageVersion < "4.2.1-0maemo3") { + qDebug() << "NB#154449 not yet fixed, sort order must be wrong."; + QTest::newRow("Sorting_nb_NO") + << QString("nb_NO") + << QString("å") + << QString("ø") + << QString("z") + << QString("a") + << QString("f") + + << QString("a") + << QString("å") + << QString("f") + << QString("ø") + << QString("z"); + } else { + qDebug() << "NB#154449 fixed, sort order must be correct."; + QTest::newRow("Sorting_nb_NO") + << QString("nb_NO") + << QString("å") + << QString("ø") + << QString("z") + << QString("a") + << QString("f") + + << QString("a") + << QString("f") + << QString("z") + << QString("ø") + << QString("å"); + } + + if (icuPackageVersion < "4.2.1-0maemo3") { + qDebug() << "NB#154449 not yet fixed, sort order must be wrong."; + QTest::newRow("Sorting_no_NO") + << QString("no_NO") + << QString("å") + << QString("ø") + << QString("z") + << QString("a") + << QString("f") + + << QString("a") + << QString("å") + << QString("f") + << QString("ø") + << QString("z"); + } else { + qDebug() << "NB#154449 fixed, sort order must be correct."; + QTest::newRow("Sorting_no_NO") + << QString("no_NO") + << QString("å") + << QString("ø") + << QString("z") + << QString("a") + << QString("f") + + << QString("a") + << QString("f") + << QString("z") + << QString("ø") + << QString("å"); + } + + QTest::newRow("Sorting_en_GB") + << QString("en_EN") + << QString("z3zz") + << QString("åtgh") + << QString("b2bb") + << QString("ähjj") + << QString("abcd") + + << QString("abcd") + << QString("ähjj") + << QString("åtgh") + << QString("b2bb") + << QString("z3zz"); + + QTest::newRow("Sorting_de_DE") + << QString("de_DE") + << QString("z3zz") + << QString("oegh") + << QString("b2bb") + << QString("öfgh") + << QString("abcd") + + << QString("abcd") + << QString("b2bb") + << QString("oegh") + << QString("öfgh") + << QString("z3zz"); + + QTest::newRow("Sorting_de_DE@collation=phonebook") + << QString("de_DE@collation=phonebook") + << QString("z3zz") + << QString("oegh") + << QString("b2bb") + << QString("öfgh") + << QString("abcd") + + << QString("abcd") + << QString("b2bb") + << QString("öfgh") + << QString("oegh") + << QString("z3zz"); + + QTest::newRow("Sorting_ja_JP@collation=standard") + << QString("ja_JP@collation=standard") + << QString("哀") // U+54C0 + << QString("娃") // U+5A03 + << QString("唖") // U+5516 + << QString("阿") // U+963F + << QString("亜") // U+4E9C + + << QString("亜") // U+4E9C + << QString("唖") // U+5516 + << QString("娃") // U+5A03 + << QString("阿") // U+963F + << QString("哀"); // U+54C0 + + QTest::newRow("Sorting_ja_JP@collation=unihan") + << QString("ja_JP@collation=unihan") + << QString("哀") // U+54C0 + << QString("娃") // U+5A03 + << QString("唖") // U+5516 + << QString("阿") // U+963F + << QString("亜") // U+4E9C + + << QString("亜") // U+4E9C + << QString("哀") // U+54C0 + << QString("唖") // U+5516 + << QString("娃") // U+5A03 + << QString("阿"); // U+963F + + QTest::newRow("Sorting_zh_CN@collation=pinyin") + << QString("zh_CN@collation=pinyin") + << QString("俄") + << QString("得") + << QString("此") + << QString("播") + << QString("爱") + + << QString("爱") + << QString("播") + << QString("此") + << QString("得") + << QString("俄"); + + QTest::newRow("Sorting_zh_CN@collation=stroke") + << QString("zh_CN@collation=stroke") + << QString("二") + << QString("三") + << QString("一") + << QString("正") + << QString("中") + + << QString("一") + << QString("二") + << QString("三") + << QString("中") + << QString("正"); +} + +void Ft_Sorting::testDuiLocaleSorting() +{ + QFETCH(QString, locale_name); + QFETCH(QString, source1); + QFETCH(QString, source2); + QFETCH(QString, source3); + QFETCH(QString, source4); + QFETCH(QString, source5); + + QFETCH(QString, target1); + QFETCH(QString, target2); + QFETCH(QString, target3); + QFETCH(QString, target4); + QFETCH(QString, target5); + + DuiLocale loc(locale_name); + DuiCollator comp = loc.collator(); + QStringList sl; + sl << source1 << source2 << source3 << source4 << source5; + // printf("%s %s %s %s %s\n", sl[0].toUtf8().data(), sl[1].toUtf8().data(), sl[2].toUtf8().data(), sl[3].toUtf8().data(), sl[4].toUtf8().data()); + qSort(sl.begin(), sl.end(), comp); + // printf("%s %s %s %s %s\n", sl[0].toUtf8().data(), sl[1].toUtf8().data(), sl[2].toUtf8().data(), sl[3].toUtf8().data(), sl[4].toUtf8().data()); + + QCOMPARE(sl[0], target1); + QCOMPARE(sl[1], target2); + QCOMPARE(sl[2], target3); + QCOMPARE(sl[3], target4); + QCOMPARE(sl[4], target5); +} + +void Ft_Sorting::testDefaultCompare_data() +{ + QTest::addColumn("locale_name"); + QTest::addColumn("str1"); + QTest::addColumn("str2"); + QTest::addColumn("result"); + + QTest::newRow("fi_FI-LessThan") + << QString("fi_FI") + << QString("AAA") + << QString("BBB") + << DuiLocale::LessThan; + QTest::newRow("fi_FI-GreaterThan") + << QString("fi_FI") + << QString("BBB") + << QString("AAA") + << DuiLocale::GreaterThan; + QTest::newRow("fi_FI-Equal") + << QString("fi_FI") + << QString("AAA") + << QString("AAA") + << DuiLocale::Equal; + QTest::newRow("de_DE-LessThan") + << QString("de_DE") + << QString("oegh") + << QString("öfgh") + << DuiLocale::LessThan; + QTest::newRow("de_DE@collation=phonebook-GreaterThan") + << QString("de_DE@collation=phonebook") + << QString("oegh") + << QString("öfgh") + << DuiLocale::GreaterThan; +} + +void Ft_Sorting::testDefaultCompare() +{ + QFETCH(QString, locale_name); + QFETCH(QString, str1); + QFETCH(QString, str2); + QFETCH(DuiLocale::Comparison, result); + + DuiLocale loc(locale_name); + DuiCollator duicomp = loc.collator(); + DuiLocale::setDefault(loc); + QCOMPARE(duicomp.compare(str1, str2), result); +} + +void Ft_Sorting::testCompareWithLocale_data() +{ + QTest::addColumn("locale_name1"); + QTest::addColumn("locale_name2"); + QTest::addColumn("str1"); + QTest::addColumn("str2"); + QTest::addColumn("result"); + + QTest::newRow("fi_FI-LessThan") + << QString("en_EN") + << QString("fi_FI") + << QString("AAA") + << QString("BBB") + << DuiLocale::LessThan; + QTest::newRow("fi_FI-GreaterThan") + << QString("en_EN") + << QString("fi_FI") + << QString("BBB") + << QString("AAA") + << DuiLocale::GreaterThan; + QTest::newRow("fi_FI-Equal") + << QString("en_EN") + << QString("fi_FI") + << QString("AAA") + << QString("AAA") + << DuiLocale::Equal; + QTest::newRow("de_DE-LessThan") + << QString("de_DE@collation=phonebook") + << QString("de_DE") + << QString("oegh") + << QString("öfgh") + << DuiLocale::LessThan; + QTest::newRow("de_DE@collation=phonebook-GreaterThan") + << QString("de_DE") + << QString("de_DE@collation=phonebook") + << QString("oegh") + << QString("öfgh") + << DuiLocale::GreaterThan; +} + +void Ft_Sorting::testCompareWithLocale() +{ + QFETCH(QString, locale_name1); + QFETCH(QString, locale_name2); + QFETCH(QString, str1); + QFETCH(QString, str2); + QFETCH(DuiLocale::Comparison, result); + + DuiLocale loc1(locale_name1); + DuiCollator duicomp = loc1.collator(); + DuiLocale::setDefault(loc1); + + DuiLocale loc2(locale_name2); + QVERIFY2(duicomp.compare(loc2, str1, str2) == result, "Compare failed"); +} + +QTEST_APPLESS_MAIN(Ft_Sorting); diff --git a/tests/ft_sorting/ft_sorting.h b/tests/ft_sorting/ft_sorting.h new file mode 100644 index 000000000..7573108d9 --- /dev/null +++ b/tests/ft_sorting/ft_sorting.h @@ -0,0 +1,56 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef FT_SORTING_H +#define FT_SORTING_H + + +#include +#include +#include +#include + +Q_DECLARE_METATYPE(DuiLocale); +Q_DECLARE_METATYPE(DuiLocale::Comparison); + +#define MAX_PARAMS 10 +class Ft_Sorting : public QObject +{ + Q_OBJECT + +private: + QCoreApplication *qap; + QString icuPackageVersion; + +private slots: + void initTestCase(); + void cleanup(); + + void testDuiLocaleSorting_data(); + void testDuiLocaleSorting(); + + void testDefaultCompare_data(); + void testDefaultCompare(); + + void testCompareWithLocale_data(); + void testCompareWithLocale(); +}; + + +#endif diff --git a/tests/ft_sorting/ft_sorting.pro b/tests/ft_sorting/ft_sorting.pro new file mode 100644 index 000000000..c55060eb3 --- /dev/null +++ b/tests/ft_sorting/ft_sorting.pro @@ -0,0 +1,21 @@ +include(../common_top.pri) + +TARGET = ft_sorting + +TEST_SOURCES = \ +# $$DUISRCDIR/duilocale.cpp + +# Input +HEADERS += \ + ft_sorting.h \ + +SOURCES += \ + ft_sorting.cpp \ + $$TEST_SOURCES \ + +# service classes +SOURCES += \ +# $$STUBSDIR/stubbase.cpp \ + + +include(../common_bot.pri) diff --git a/tests/ft_theme/.gitignore b/tests/ft_theme/.gitignore new file mode 100644 index 000000000..a0988478d --- /dev/null +++ b/tests/ft_theme/.gitignore @@ -0,0 +1 @@ +ft_theme diff --git a/tests/ft_theme/ft_theme.cpp b/tests/ft_theme/ft_theme.cpp new file mode 100644 index 000000000..5b5ac7c89 --- /dev/null +++ b/tests/ft_theme/ft_theme.cpp @@ -0,0 +1,456 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ft_theme.h" +#include "duitheme.h" +#include +#include +#include +#include +#include +#include + +#include "duicomponentdata.h" +#include "../../src/theme/duitheme_p.h" +#include "testthemedaemon.h" +#include "ft_theme_data.h" + +static QString languageGConfValue = "en"; + +QVariant DuiGConfItem::value() const +{ + return languageGConfValue; +} + +void removeDirectoryRecursive(const QString &path) +{ + QDir root(path); + if (root.exists()) { + QFileInfoList entries = root.entryInfoList(QDir::NoDotAndDotDot | QDir::Dirs | QDir::Files); + for (int i = 0; i < entries.count(); i++) { + if (entries[i].isDir()) { + removeDirectoryRecursive(entries[i].filePath()); + root.rmdir(entries[i].absoluteFilePath()); + } else { + root.remove(entries[i].absoluteFilePath()); + } + } + } +} + +void makeFile(const QString &path, const QString &content) +{ + QFile file(QDir::tempPath() + QDir::separator() + QString("Ft_Theme") + QDir::separator() + path); + if (file.open(QIODevice::WriteOnly)) { + QTextStream stream(&file); + stream << content; + file.close(); + } else { + qWarning() << "Failed to create file:" << path; + } +} + +void Ft_Theme::init() +{ + QStringList paths; + paths << QString("Ft_Theme") + QDir::separator() + "theme1" + QDir::separator() + "dui" + QDir::separator() + "libdui" + QDir::separator() + "style"; + paths << QString("Ft_Theme") + QDir::separator() + "theme2" + QDir::separator() + "dui" + QDir::separator() + "libdui" + QDir::separator() + "style"; + paths << QString("Ft_Theme") + QDir::separator() + "theme2" + QDir::separator() + "dui" + QDir::separator() + "Ft_Theme" + QDir::separator() + "style"; + paths << QString("Ft_Theme") + QDir::separator() + "theme1" + QDir::separator() + "dui" + QDir::separator() + "locale" + QDir::separator() + "fi"; + + foreach(QString path, paths) { + // create test theme to tmp/ + if (!QDir::temp().mkpath(path)) + qWarning() << "Failed to create path:" << path; + } + + // create constant declarations + makeFile(QString("theme1") + QDir::separator() + QString("dui") + QDir::separator() + QString("constants.ini"), THEME_1_CONSTANTS_INI); + makeFile(QString("theme2") + QDir::separator() + QString("dui") + QDir::separator() + QString("constants.ini"), THEME_2_CONSTANTS_INI); + + makeFile(QString("theme1") + QDir::separator() + QString("dui") + QDir::separator() + QString("locale") + QDir::separator() + QString("fi") + QDir::separator() + QString("constants.ini"), FINNISH_CONSTANTS_INI); + + // create view configuration files + makeFile(QString("theme1") + QDir::separator() + QString("dui") + QDir::separator() + QString("libdui") + QDir::separator() + QString("libdui.conf"), LIBDUI_THEME_1_VIEW_CONFIGURATION); + makeFile(QString("theme2") + QDir::separator() + QString("dui") + QDir::separator() + QString("libdui") + QDir::separator() + QString("libdui.conf"), LIBDUI_THEME_2_VIEW_CONFIGURATION); + makeFile(QString("theme2") + QDir::separator() + QString("dui") + QDir::separator() + QString("Ft_Theme") + QDir::separator() + QString("Ft_Theme.conf"), TESTAPP_VIEW_CONFIGURATION); + + // create stylesheets + makeFile(QString("theme1") + QDir::separator() + QString("dui") + QDir::separator() + QString("libdui") + QDir::separator() + QString("style") + QDir::separator() + QString("libdui.css"), THEME_1_LIBDUI_CSS); + makeFile(QString("theme2") + QDir::separator() + QString("dui") + QDir::separator() + QString("libdui") + QDir::separator() + QString("style") + QDir::separator() + QString("libdui.css"), THEME_2_LIBDUI_CSS); + makeFile(QString("theme2") + QDir::separator() + QString("dui") + QDir::separator() + QString("Ft_Theme") + QDir::separator() + QString("style") + QDir::separator() + QString("Ft_Theme.css"), THEME_2_APP_CSS); +} + +void Ft_Theme::cleanup() +{ + // remove test theme from tmp/ + removeDirectoryRecursive(QDir::tempPath() + QDir::separator() + "Ft_Theme"); + QDir::temp().rmdir("Ft_Theme"); +} + +void Ft_Theme::initTestCase() +{ + int argc = 1; + const char *argv = "./Ft_Theme"; + + componentData = new DuiComponentData(argc, (char **) &argv, NULL); + + // store the "original" themedaemon + daemon = DuiTheme::instance()->d_ptr->themeDaemon; + + // replace themedaemon with our own implementation + testDaemon = new TestThemeDaemon; + DuiTheme::instance()->d_ptr->themeDaemon = testDaemon; + // a bit hackish, but connect the signals + connect(testDaemon, SIGNAL(themeChanged(QStringList)), + DuiTheme::instance(), SLOT(themeChangedSlot(QStringList))); + + connect(testDaemon, SIGNAL(pixmapChanged(QString, QSize, Qt::HANDLE)), + DuiTheme::instance(), SLOT(pixmapChangedSlot(QString, QSize, Qt::HANDLE))); + + connect(testDaemon, SIGNAL(pixmapCreated(QString, QSize, Qt::HANDLE)), + DuiTheme::instance(), SLOT(pixmapCreatedSlot(QString, QSize, Qt::HANDLE))); +} + +void Ft_Theme::cleanupTestCase() +{ + // restore the original daemon we replaced + DuiTheme::instance()->d_ptr->themeDaemon = daemon; + delete testDaemon; + + delete componentData; +} + +void Ft_Theme::testViews_data() +{ + QTest::addColumn("theme"); + QTest::addColumn("viewType"); + QTest::addColumn("viewClass"); + + QTest::newRow("dui library, theme 1") << "theme 1" << "" << "DuiWidgetView"; + QTest::newRow("application, theme 2") << "theme 2" << "" << "TestView"; + QTest::newRow("dui library, theme 2") << "theme 2" << "test" << "TestView2"; +} + +void Ft_Theme::testViews() +{ + QFETCH(QString, theme); + QFETCH(QString, viewType); + QFETCH(QString, viewClass); + + testDaemon->changeTheme(theme); + testDaemon->emitThemeChange(); + + DuiWidgetController widget; + widget.setViewType(viewType); + + // Create view for a simple widget + DuiWidgetView *view = DuiTheme::view(&widget); + + // Make sure that we got view at the first place + if (!viewClass.isEmpty()) { + QVERIFY(view); + // Make sure it's correct type + QCOMPARE(QString(view->metaObject()->className()), viewClass); + } +} + +void Ft_Theme::testStyles_data() +{ + QTest::addColumn("theme"); + QTest::addColumn("styleClass"); + QTest::addColumn("backgroundColor"); + + QTest::newRow("test library, theme 1") << "theme 1" << "DuiWidgetStyle" << QColor("#ffffff"); + QTest::newRow("test library, theme 2 (custom css)") << "theme 2" << "DuiWidgetStyle" << QColor("#f0f0f0"); +} + +void Ft_Theme::testStyles() +{ + QFETCH(QString, theme); + QFETCH(QString, styleClass); + QFETCH(QColor, backgroundColor); + + testDaemon->changeTheme(theme); + testDaemon->emitThemeChange(); + + const DuiWidgetStyle *style = dynamic_cast(DuiTheme::style(styleClass.toStdString().c_str(), QString())); + QVERIFY(style); + + QCOMPARE(style->backgroundColor(), backgroundColor); + + DuiTheme::releaseStyle(style); +} + +void Ft_Theme::testPixmaps_data() +{ + QTest::addColumn("pixmaps"); + + QStringList unique; + unique << "id0,64,64" << "id1,32,32" << "id2,16,16" << "id3,8,8" << "id4,4,4" << "id5,2,2" << "id6,1,1"; + QTest::newRow("unique") << unique; + + QStringList duplicates; + duplicates << "id0,64,64" << "id0,64,64" << "id2,16,16" << "id2,16,16" << "id4,4,4" << "id4,4,4"; + QTest::newRow("duplicates") << duplicates; + +} + +void Ft_Theme::testPixmaps() +{ + // this keeps track what we have requested + QSet unique; + QList allocated; + + // reset test theme daemon + testDaemon->reset(); + + // get test data + QFETCH(QStringList, pixmaps); + + // allocate pixmap resources + foreach(QString string, pixmaps) { + + // resolve parameters + QStringList parameters = string.split(","); + + // request pixmap + const QPixmap *pixmap = DuiTheme::pixmap(parameters[0], QSize(parameters[1].toInt(), parameters[2].toInt())); + QVERIFY(pixmap != NULL); + unique.insert(string); + allocated.append(pixmap); + } + + // verify that the pixmaps were requested only once if there are duplicates + QCOMPARE(testDaemon->pixmapCount(), unique.count()); + + foreach(const QPixmap * pixmap, allocated) { + // release pixmap + DuiTheme::releasePixmap(pixmap); + } + + // verify that all pixmaps were released + QCOMPARE(testDaemon->pixmapCount(), 0); +} + +void Ft_Theme::testScalables_data() +{ + QTest::addColumn("scalables"); + + QStringList unique; + unique << "id0,0,0,0,0" << "id1,1,1,1,1" << "id2,2,2,2,2" << "id3,3,3,3,3" << "id4,4,4,4,4" << "id5,5,5,5,5" << "id6,6,6,6,6"; + QTest::newRow("unique") << unique; + + QStringList duplicates; + duplicates << "id0,0,0,0,0" << "id0,0,0,0,0" << "id2,0,0,0,0" << "id2,0,0,0,0" << "id4,0,0,0,0" << "id4,0,0,0,0"; + QTest::newRow("duplicates") << duplicates; + +} +void Ft_Theme::testScalables() +{ + // this keeps track what we have requested + QSet unique; + QSet uniquePixmaps; + QList allocated; + + // reset test theme daemon + testDaemon->reset(); + + // get test data + QFETCH(QStringList, scalables); + + // allocate scalable image resources + foreach(QString string, scalables) { + + // resolve parameters + QStringList parameters = string.split(","); + + // request scalable image + const DuiScalableImage *scalable = DuiTheme::scalableImage(parameters[0], parameters[1].toInt(), + parameters[2].toInt(), parameters[3].toInt(), parameters[4].toInt()); + + QVERIFY(scalable != NULL); + + // check whether this is a duplicate, which is alredy requested + if (unique.contains(string)) { + // this should already exist in allocated list + QVERIFY(allocated.contains(scalable)); + } else { + unique.insert(string); + } + uniquePixmaps.insert(parameters[0]); + allocated.append(scalable); + } + + // verify that the pixmaps were requested only once if there are duplicates + QCOMPARE(testDaemon->pixmapCount(), uniquePixmaps.count()); + + foreach(const DuiScalableImage * scalable, allocated) { + // release scalable image + DuiTheme::releaseScalableImage(scalable); + } + + // verify that all pixmaps were released + QCOMPARE(testDaemon->pixmapCount(), 0); +} + +void Ft_Theme::testPalette_data() +{ + QTest::addColumn("theme"); + QTest::addColumn("foregroundColor"); + QTest::addColumn("secondaryForegroundColor"); + QTest::addColumn("backgroundColor"); + QTest::addColumn("invertedForegroundColor"); + QTest::addColumn("invertedSecondaryForegroundColor"); + QTest::addColumn("invertedBackgroundColor"); + QTest::addColumn("selectionColor"); + QTest::addColumn("warningColor"); + QTest::addColumn("attentionColor"); + QTest::addColumn("notificationColor"); + QTest::addColumn("linkColor"); + QTest::addColumn("activeLinkColor"); + QTest::addColumn("firstAccentColor"); + QTest::addColumn("secondAccentColor"); + QTest::addColumn("thirdAccentColor"); + QTest::addColumn("fourthAccentColor"); + QTest::addColumn("fifthAccentColor"); + + + QTest::newRow("theme 1") << "theme 1" << QColor("#000000") << QColor("#666666") << QColor("#000000") << + QColor("#ffffff") << QColor("#cccccc") << QColor("#FFFFFF") << + QColor("#f5bf00") << QColor("#CC0000") << QColor("#CC9900") << + QColor("#C3F500") << QColor("#3465a4") << QColor("#f5bf00") << + QColor("#aad400") << QColor("#69bfde") << QColor("#ff9955") << + QColor("#de87cd") << QColor("#d8b427"); + + QTest::newRow("theme 2") << "theme 2" << QColor("#ffffff") << QColor("#666666") << QColor("#000000") << + QColor("#ffffff") << QColor("#dddddd") << QColor("#FFFFFF") << + QColor("#f5bf00") << QColor("#CC0000") << QColor("#CC9900") << + QColor("#C3F500") << QColor("#3465a4") << QColor("#f5bf00") << + QColor("#aad400") << QColor("#69bfde") << QColor("#ff9955") << + QColor("#de87cd") << QColor("#d8b427"); +} + +void Ft_Theme::testPalette() +{ + QFETCH(QString, theme); + testDaemon->changeTheme(theme); + testDaemon->emitThemeChange(); + + // create palette object + const DuiPalette &palette = DuiTheme::palette(); + + // check all values against palette + QFETCH(QColor, foregroundColor); + QFETCH(QColor, secondaryForegroundColor); + QFETCH(QColor, backgroundColor); + QFETCH(QColor, invertedForegroundColor); + QFETCH(QColor, invertedSecondaryForegroundColor); + QFETCH(QColor, invertedBackgroundColor); + QFETCH(QColor, selectionColor); + QFETCH(QColor, warningColor); + QFETCH(QColor, attentionColor); + QFETCH(QColor, notificationColor); + QFETCH(QColor, linkColor); + QFETCH(QColor, activeLinkColor); + QFETCH(QColor, firstAccentColor); + QFETCH(QColor, secondAccentColor); + QFETCH(QColor, thirdAccentColor); + QFETCH(QColor, fourthAccentColor); + QFETCH(QColor, fifthAccentColor); + + QCOMPARE(palette.foregroundColor(), foregroundColor); + QCOMPARE(palette.secondaryForegroundColor(), secondaryForegroundColor); + QCOMPARE(palette.backgroundColor(), backgroundColor); + QCOMPARE(palette.invertedForegroundColor(), invertedForegroundColor); + QCOMPARE(palette.invertedSecondaryForegroundColor(), invertedSecondaryForegroundColor); + QCOMPARE(palette.invertedBackgroundColor(), invertedBackgroundColor); + QCOMPARE(palette.selectionColor(), selectionColor); + QCOMPARE(palette.warningColor(), warningColor); + QCOMPARE(palette.attentionColor(), attentionColor); + QCOMPARE(palette.notificationColor(), notificationColor); + QCOMPARE(palette.linkColor(), linkColor); + QCOMPARE(palette.activeLinkColor(), activeLinkColor); + QCOMPARE(palette.firstAccentColor(), firstAccentColor); + QCOMPARE(palette.secondAccentColor(), secondAccentColor); + QCOMPARE(palette.thirdAccentColor(), thirdAccentColor); + QCOMPARE(palette.fourthAccentColor(), fourthAccentColor); + QCOMPARE(palette.fifthAccentColor(), fifthAccentColor); +} + +void Ft_Theme::testFonts_data() +{ + QTest::addColumn("theme"); + QTest::addColumn("language"); + QTest::addColumn("extraLargeFont"); + QTest::addColumn("largeFont"); + QTest::addColumn("defaultFont"); + QTest::addColumn("smallFont"); + QTest::addColumn("extraSmallFont"); + + QFont extraLargeFont("Arial"); + extraLargeFont.setPixelSize(32); + QFont largeFont("Arial"); + largeFont.setPixelSize(28); + QFont defaultFont("Arial"); + defaultFont.setPixelSize(24); + QFont smallFont("Arial"); + smallFont.setPixelSize(20); + QFont extraSmallFont("Arial"); + extraSmallFont.setPixelSize(16); + + QTest::newRow("theme 1, en") << "theme 1" << "en" << extraLargeFont << largeFont << defaultFont << smallFont << extraSmallFont; + + defaultFont.setFamily("Courier"); + QTest::newRow("theme 2, en") << "theme 2" << "en" << extraLargeFont << largeFont << defaultFont << smallFont << extraSmallFont; + +#ifdef HAVE_GCONF + defaultFont.setFamily("System"); + QTest::newRow("theme 1, fi") << "theme 1" << "fi" << extraLargeFont << largeFont << defaultFont << smallFont << extraSmallFont; +#endif +} +void Ft_Theme::testFonts() +{ + QFETCH(QString, theme); + QFETCH(QString, language); + + testDaemon->changeTheme(theme); + +#ifdef HAVE_GCONF + languageGConfValue = language; +#endif + + testDaemon->emitThemeChange(); + + const DuiDefaultFonts &fonts = DuiTheme::fonts(); + + QFETCH(QFont, extraLargeFont); + QFETCH(QFont, largeFont); + QFETCH(QFont, defaultFont); + QFETCH(QFont, smallFont); + QFETCH(QFont, extraSmallFont); + + QCOMPARE(fonts.extraLargeFont(), extraLargeFont); + QCOMPARE(fonts.largeFont(), largeFont); + QCOMPARE(fonts.defaultFont(), defaultFont); + QCOMPARE(fonts.smallFont(), smallFont); + QCOMPARE(fonts.extraSmallFont(), extraSmallFont); +} + +QTEST_MAIN(Ft_Theme) diff --git a/tests/ft_theme/ft_theme.h b/tests/ft_theme/ft_theme.h new file mode 100644 index 000000000..dfe6e50a1 --- /dev/null +++ b/tests/ft_theme/ft_theme.h @@ -0,0 +1,72 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef FT_THEME_H +#define FT_THEME_H + +#include +#include +#include + +class IDuiThemeDaemon; +class DuiComponentData; +class TestThemeDaemon; + +class Ft_Theme : public QObject +{ + Q_OBJECT; + +private slots: + void init(); + void cleanup(); + void initTestCase(); + void cleanupTestCase(); + + // test view creation + void testViews_data(); + void testViews(); + + // test style creation + void testStyles_data(); + void testStyles(); + + // test pixmap loading + void testPixmaps_data(); + void testPixmaps(); + + // test scalable image loading + void testScalables_data(); + void testScalables(); + + // test palette + void testPalette_data(); + void testPalette(); + + // test default fonts + void testFonts_data(); + void testFonts(); + +private: + DuiComponentData *componentData; + IDuiThemeDaemon *daemon; + TestThemeDaemon *testDaemon; +}; + +#endif + diff --git a/tests/ft_theme/ft_theme.pro b/tests/ft_theme/ft_theme.pro new file mode 100644 index 000000000..e49c4d998 --- /dev/null +++ b/tests/ft_theme/ft_theme.pro @@ -0,0 +1,19 @@ +include(../common_top.pri) +TARGET = ft_theme +QT += dbus svg network +LIBRARYPATH += $$DUISRCDIR + +SOURCES += \ + ft_theme.cpp \ + testthemedaemon.cpp \ + testview.cpp \ + testview2.cpp + +HEADERS += \ + ft_theme.h \ + testthemedaemon.h \ + testview.h \ + testview2.h \ + $$DUISRCDIR/theme/iduithemedaemon.h + +include(../common_bot.pri) diff --git a/tests/ft_theme/ft_theme_data.h b/tests/ft_theme/ft_theme_data.h new file mode 100644 index 000000000..11319c28d --- /dev/null +++ b/tests/ft_theme/ft_theme_data.h @@ -0,0 +1,105 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +const QString THEME_1_LIBDUI_CSS = \ + "DuiWidgetStyle {\n"\ + " show-animation: \"none\";\n"\ + " hide-animation: \"none\";\n"\ + " margin-left: 0;\n"\ + " margin-top: 0;\n"\ + " margin-right: 0;\n"\ + " margin-bottom: 0;\n"\ + " padding-left: 0;\n"\ + " padding-top: 0;\n"\ + " padding-right: 0;\n"\ + " padding-bottom: 0;\n"\ + " reactive-margin-left: 0;\n"\ + " reactive-margin-top: 0;\n"\ + " reactive-margin-right: 0;\n"\ + " reactive-margin-bottom: 0;\n"\ + " background-image:;\n"\ + " background-color: #ffffff;\n"\ + " background-boxed-percent: 0;\n"\ + " background-opacity: 1.0;\n"\ + " preferred-size: -1 -1;\n"\ + " minimum-size: -1 -1;\n"\ + " maximum-size: -1 -1;\n"\ + " press-feedback:;\n"\ + " release-feedback:;\n"\ + "}\n"; + +const QString THEME_2_LIBDUI_CSS = \ + "DuiWidgetStyle {\n"\ + " backgroundColor: #000000;\n"\ + "}\n"; + +const QString THEME_2_APP_CSS = \ + "DuiWidgetStyle {\n"\ + " backgroundColor: #f0f0f0;\n"\ + "}\n"; + +const QString LIBDUI_THEME_1_VIEW_CONFIGURATION = \ + "[DuiWidgetController]\n"\ + "default = DuiWidgetView\n"; + +const QString LIBDUI_THEME_2_VIEW_CONFIGURATION = \ + "[DuiWidgetController]\n"\ + "test = TestView2\n"; + +const QString TESTAPP_VIEW_CONFIGURATION = \ + "[DuiWidgetController]\n"\ + "default = TestView\n"; + +const QString THEME_1_CONSTANTS_INI = \ + "[Palette]\n"\ + "COLOR_FOREGROUND = #000000\n"\ + "COLOR_SECONDARY_FOREGROUND = #666666\n"\ + "COLOR_BACKGROUND = #000000\n"\ + "COLOR_INVERTED_FOREGROUND = #ffffff\n"\ + "COLOR_INVERTED_SECONDARY_FOREGROUND = #cccccc\n"\ + "COLOR_INVERTED_BACKGROUND = #FFFFFF\n"\ + "COLOR_SELECT = #f5bf00\n"\ + "COLOR_WARNING = #CC0000\n"\ + "COLOR_ATTENTION = #CC9900\n"\ + "COLOR_NOTIFICATION = #C3F500\n"\ + "COLOR_LINK = #3465a4\n"\ + "COLOR_LINK_ACTIVE = #f5bf00\n"\ + "COLOR_ACCENT1 = #aad400\n"\ + "COLOR_ACCENT2 = #69bfde\n"\ + "COLOR_ACCENT3 = #ff9955\n"\ + "COLOR_ACCENT4 = #de87cd\n"\ + "COLOR_ACCENT5 = #d8b427\n"\ + "[Fonts]\n"\ + "FONT_XLARGE = Arial 32px\n"\ + "FONT_LARGE = Arial 28px\n"\ + "FONT_DEFAULT = Arial 24px\n"\ + "FONT_SMALL = Arial 20px\n"\ + "FONT_XSMALL = Arial 16px\n"; + + +const QString THEME_2_CONSTANTS_INI = \ + "[Palette]\n"\ + "COLOR_FOREGROUND = #ffffff\n"\ + "COLOR_INVERTED_SECONDARY_FOREGROUND = #dddddd\n"\ + "[Fonts]\n"\ + "FONT_DEFAULT = Courier 24px\n"; + +const QString FINNISH_CONSTANTS_INI = \ + "[Fonts]\n"\ + "FONT_DEFAULT = System 24px\n"; diff --git a/tests/ft_theme/images1/DUI_template_161208.svg b/tests/ft_theme/images1/DUI_template_161208.svg new file mode 100644 index 000000000..9877c93bd --- /dev/null +++ b/tests/ft_theme/images1/DUI_template_161208.svg @@ -0,0 +1,19466 @@ + + +image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/ft_theme/testthemedaemon.cpp b/tests/ft_theme/testthemedaemon.cpp new file mode 100644 index 000000000..774fd2cea --- /dev/null +++ b/tests/ft_theme/testthemedaemon.cpp @@ -0,0 +1,128 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include +#include "testthemedaemon.h" +#include + +TestThemeDaemon::TestThemeDaemon() +{ + current = ""; +} + +void TestThemeDaemon::addDirectoryToPixmapSearchList(const QString &directoryName, Dui::RecursionMode recursive) +{ + Q_UNUSED(directoryName); + Q_UNUSED(recursive); +} + +void TestThemeDaemon::clearPixmapSearchList() +{ +} + +void TestThemeDaemon::pixmapHandleSync(const QString &imageId, const QSize &size) +{ + QString identifier = imageId + ',' + QString::number(size.width()) + ',' + QString::number(size.height()); + // store + int pixmapWidth = size.width() < 0 ? 128 : size.width(); + int pixmapHeight = size.height() < 0 ? 128 : size.height(); + + QPixmap *pixmap = new QPixmap(pixmapWidth, pixmapHeight); + pixmaps.insert(identifier, pixmap); + + // emit signal + emit pixmapCreated(imageId, size, pixmap->handle()); +} + +void TestThemeDaemon::pixmapHandle(const QString &imageId, const QSize &size) +{ + // use sync loading always + pixmapHandleSync(imageId, size); +} + +void TestThemeDaemon::releasePixmap(const QString &imageId, const QSize &size) +{ + QString identifier = imageId + ',' + QString::number(size.width()) + ',' + QString::number(size.height()); + + // find from list + QPixmap *pixmap = pixmaps.value(identifier, NULL); + if (pixmap) { + // remove & delete + pixmaps.remove(identifier); + delete pixmap; + } +} + +QString TestThemeDaemon::currentTheme() +{ + return current; +} + +QStringList TestThemeDaemon::findAvailableThemes() +{ + QStringList list; + list << "theme 1"; + list << "theme 2"; + return list; +} + +void TestThemeDaemon::changeTheme(const QString &theme_id) +{ + if (theme_id == "theme 1") { + current = theme_id; + } else if (theme_id == "theme 2") { + current = theme_id; + } +} + +void TestThemeDaemon::emitThemeChange() +{ + emit themeChanged(themeInheritanceChain()); +} + +QStringList TestThemeDaemon::themeInheritanceChain() +{ + QString themeDirectory = QDir::tempPath() + QDir::separator() + QString("Ft_Theme") + QDir::separator(); + + QStringList themeInheritance; + if (current == "theme 2") { + themeInheritance << themeDirectory + "theme2" + QDir::separator(); + } + themeInheritance << themeDirectory + "theme1" + QDir::separator(); + return themeInheritance; +} + +bool TestThemeDaemon::hasPendingRequests() const +{ + return false; +} + +int TestThemeDaemon::pixmapCount() const +{ + return pixmaps.count(); +} + +void TestThemeDaemon::reset() +{ + pixmaps.clear(); +} + + diff --git a/tests/ft_theme/testthemedaemon.h b/tests/ft_theme/testthemedaemon.h new file mode 100644 index 000000000..c44ce6ac7 --- /dev/null +++ b/tests/ft_theme/testthemedaemon.h @@ -0,0 +1,55 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef TESTTHEMEDAEMON_H +#define TESTTHEMEDAEMON_H + +#include +#include "../../src/theme/iduithemedaemon.h" + +class QPixmap; + +class TestThemeDaemon : public IDuiThemeDaemon +{ + Q_OBJECT +public: + + TestThemeDaemon(); + + virtual void addDirectoryToPixmapSearchList(const QString &directoryName, Dui::RecursionMode recursive); + virtual void clearPixmapSearchList(); + virtual void pixmapHandleSync(const QString &imageId, const QSize &size); + virtual void pixmapHandle(const QString &imageId, const QSize &size); + virtual void releasePixmap(const QString &imageId, const QSize &size); + virtual QString currentTheme(); + virtual QStringList findAvailableThemes(); + virtual void changeTheme(const QString &theme_id); + void emitThemeChange(); + virtual QStringList themeInheritanceChain(); + virtual bool hasPendingRequests() const; + + + int pixmapCount() const; + void reset(); +private: + QMultiMap pixmaps; + QString current; +}; + +#endif diff --git a/tests/ft_theme/testview.cpp b/tests/ft_theme/testview.cpp new file mode 100644 index 000000000..1f7751066 --- /dev/null +++ b/tests/ft_theme/testview.cpp @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "testview.h" +DUI_REGISTER_VIEW(TestView, DuiWidgetController) diff --git a/tests/ft_theme/testview.h b/tests/ft_theme/testview.h new file mode 100644 index 000000000..f6eba628c --- /dev/null +++ b/tests/ft_theme/testview.h @@ -0,0 +1,34 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef TESTVIEW_H +#define TESTVIEW_H + +#include + +class TestView : public DuiWidgetView +{ + Q_OBJECT + DUI_VIEW(DuiWidgetModel, DuiWidgetStyle); + +public: + TestView(DuiWidgetController *controller) : DuiWidgetView(controller) {} +}; + +#endif diff --git a/tests/ft_theme/testview2.cpp b/tests/ft_theme/testview2.cpp new file mode 100644 index 000000000..6f0221910 --- /dev/null +++ b/tests/ft_theme/testview2.cpp @@ -0,0 +1,21 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "testview2.h" +DUI_REGISTER_VIEW(TestView2, DuiWidgetController) diff --git a/tests/ft_theme/testview2.h b/tests/ft_theme/testview2.h new file mode 100644 index 000000000..52d8db91b --- /dev/null +++ b/tests/ft_theme/testview2.h @@ -0,0 +1,34 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef TESTVIEW2_H +#define TESTVIEW2_H + +#include + +class TestView2 : public DuiWidgetView +{ + Q_OBJECT + DUI_VIEW(DuiWidgetModel, DuiWidgetStyle); + +public: + TestView2(DuiWidgetController *controller) : DuiWidgetView(controller) {} +}; + +#endif diff --git a/tests/gen-tests-xml.sh b/tests/gen-tests-xml.sh new file mode 100755 index 000000000..2d69b921a --- /dev/null +++ b/tests/gen-tests-xml.sh @@ -0,0 +1,54 @@ +#!/bin/bash + +DOMAIN="Application Framework" +FEATURE="Direct UI Framework" +TYPE="Functional" +LEVEL="Component" + +UT_TESTCASES="" +FT_TESTCASES="" + +for TEST in `ls -d ?t_*`; do + if [ -x $TEST/$TEST -o -x $TEST/$TEST_exec ]; then + +TESTCASE_TEMPLATE=" + /usr/lib/libdui-tests/$TEST + + " + + if [ -n "`echo $TEST | egrep '^u'`" ]; then + UT_TESTCASES="${UT_TESTCASES}${TESTCASE_TEMPLATE}" + else + FT_TESTCASES="${FT_TESTCASES}${TESTCASE_TEMPLATE}" + fi + fi +done + +TESTSUITE_TEMPLATE=" + + + + + $UT_TESTCASES + + + false + true + + + + + + $FT_TESTCASES + + + false + true + + + + +" + +echo "$TESTSUITE_TEMPLATE" + diff --git a/tests/mkUt b/tests/mkUt new file mode 100755 index 000000000..cc02e0d0d --- /dev/null +++ b/tests/mkUt @@ -0,0 +1,113 @@ +#! /usr/bin/perl +# usage : +# $1 class name - ie in upper camel case - no 'ut_' prepended + +$duisrcdir="../src"; + +# catch wrong usage +if ( "$ARGV[0]" eq "" || "$ARGV[0]" =~ "^ut_" ) { + print "usage: $0 \n"; + exit -1; +} + +$camelClassName="$ARGV[0]"; +$lowerClassName=lc( $camelClassName ); +$upperClassName=uc( $camelClassName ); + +$camelMkUtClassName="MkUtClassName"; +$lowerMkUtClassName=lc( $camelMkUtClassName ); +$upperMkUtClassName=uc( $camelMkUtClassName ); + +$srcDir="../src"; +$unitH="$srcDir/${lowerClassName}.h"; +$unitCpp="$srcDir/${lowerClassName}.cpp"; +$targetDir="ut_$lowerClassName"; + +if ( -e "$targetDir" ) { + print "$targetDir/ already exists - too risky to overwrite, please delete manually\n"; + exit -1; +} + +@bases = (); +$thisFile=$unitH; +$thisBase=getBase( $thisFile, $camelClassName ); +while ( "$thisBase" ne "" ) { + push @bases, $thisBase; + $thisFile="../src/".lc( $thisBase ).".h"; + $thisBase=getBase( $thisFile, $thisBase ); +} + +foreach $duiWidget (@bases) { + $lowerDuiWidget=lc($duiWidget); + $newBaseSource="\$\$DUISRCDIR\/${lowerDuiWidget}.cpp \\"; + $newBaseHeader="\$\$DUISRCDIR\/${lowerDuiWidget}.h \\"; + push @baseSources, $newBaseSource; + push @baseHeaders, $newBaseHeader; +} +#$newServiceHeader="\$\$DUISRCDIR\/${lowerDuiWidget}.h \$\$STUBSDIR\/${lowerDuiWidget}_stub.h \\"; + +$allBaseSources = ""; +$allBaseHeaders = ""; + +$allBaseSources = "\t".join( "\n\t", @baseSources ) if ( @baseSources ); +$allBaseHeaders = "\t".join( "\n\t", @baseHeaders ) if ( @baseHeaders ); + +# make the directory +if ( ! -e "$targetDir" ) { + mkdir $targetDir; +} + +$classHeader = "${lowerClassName}.h"; +$classHeaderP = "${lowerClassName}_p.h"; +$classInclude = "#include <$classHeader>"; +$classIncludeP = ""; +if ( -e "$duisrcdir/$classHeaderP" ) { + $classIncludeP = "#include <$classHeaderP>"; +} + +## copy template +foreach $file ( glob( "template/*" ) ) { + $base=basename($file); + $targetFile="$targetDir/$base"; + $targetFile=~s/template/$lowerClassName/; + open INFILE, "<$file" || die( "Could not read from $file:$!" ); + open OUTFILE, ">$targetFile" || die( "Could not write to $targetFile:$!" ); + while () { + $_ =~ s/^\s*mkutserviceheaders//g; + $_ =~ s/^\s*mkutbasesources/$allBaseSources/g; + $_ =~ s/^\s*mkutbaseheaders/$allBaseHeaders/g; + $_ =~ s/$camelMkUtClassName/$camelClassName/g; + $_ =~ s/$lowerMkUtClassName/$lowerClassName/g; + $_ =~ s/$upperMkUtClassName/$upperClassName/g; + $_ =~ s/^mkutclassinclude$/$classInclude/g; + $_ =~ s/^mkutclassinclude_p$/$classIncludeP/g; + $_ =~ s/MKUTCLASSMEMBERS//g; + print OUTFILE "$_"; + } + close OUTFILE; + close INFILE; +} + +sub getBase +{ + my ($thisFile, $thisBase)=@_; + my $retVal=""; + + open THISFILE, "<$thisFile"; + while () { + if ( /class\s+$thisBase\s*:\s*\S+\s+(Dui\S+)/ ) { + $retVal=$1; + last; + } + } + close THISFILE; + return $retVal; +} + +sub basename +{ + my ($filename)=@_; + my @bits=split( /\//, $filename ); + + return $bits[ @bits-1 ]; +} diff --git a/tests/processmeta.pl b/tests/processmeta.pl new file mode 100755 index 000000000..4e83165f2 --- /dev/null +++ b/tests/processmeta.pl @@ -0,0 +1,36 @@ +#!/usr/bin/perl +# + +print "XB-Testing-metadata:\n"; +print " \n"; +print ' ' . "\n"; +open(META,"meta"); +$closetag = ""; +$counter = 0; + +my $command = 'DISPLAY=:1 LD_LIBRARY_PATH=~/nokia/dui/lib find . -type f -perm +100 -name "?t_*" -print -exec {} -functions \;'; +@buffer = qx($command 2>&1); + +foreach $row (@buffer) { + chomp $row; + if ( $row =~ /^\./) { + ($a,$b,$c) = split(/\//,$row); + if ($counter > 0) { + printf(" \n"); + print " \n"; + } + printf(" \n",$b); + printf(" \n"); + $counter ++; + # print "RIVI: " . $b. "\n"; + } else { + chop $row; chop $row; + printf(" \n",$row); + } + +} +if ($counter>0) { + printf(" \n"); + print " \n"; +} +printf(" \n"); diff --git a/tests/qtestlib2junitxml.xsl b/tests/qtestlib2junitxml.xsl new file mode 100644 index 000000000..aab2d0f39 --- /dev/null +++ b/tests/qtestlib2junitxml.xsl @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Standard + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/rt.sh b/tests/rt.sh new file mode 100755 index 000000000..0c256beea --- /dev/null +++ b/tests/rt.sh @@ -0,0 +1,69 @@ +#!/bin/bash +# this is just small wrapper to automate the unit testcases + + + +function emptylog() { + FILENAME=$1 + TESTCASE=$2 + REASON=$3 + + cat< $FILENAME + + + + + + + + + + + + Current testsuite crashes or wasnt in shape to be executed in development environment and this error message is placeholder. Fix your tests! + + +EOF + +} + +TEST=$1 +CURDIR=`pwd` +DIRNAME=`dirname $TEST` +BASENAME=`basename $TEST` +QTESTLOG=./$BASENAME.log +JUNITLOG=./$BASENAME.log.xml + +# cd $DIRNAME +if [ ! -f ./$BASENAME ]; then + EXIT_CODE=255 + +else + LD_LIBRARY_PATH=../../lib ./$BASENAME -xml -o ./$BASENAME.log + xsltproc --nonet ../qtestlib2junitxml.xsl $QTESTLOG > $JUNITLOG + EXIT_CODE=$? +fi + +if [ ! -f $JUNITLOG ]; then + EXIT_CODE=254 +fi + +case "$EXIT_CODE" in + "0") + echo success + ;; + "254") + echo error: unittest $BASENAME failed with $EXIT_CODE errors + emptylog $JUNITLOG $BASENAME "unittest crashed or exited with fatal error" + ;; + "255") + echo error: unittest $BASENAME is not compiled + emptylog $JUNITLOG $BASENAME "unittest doesnt exist" + ;; + *) + echo error: unittest $BASENAME failed with $EXIT_CODE errors + emptylog $JUNITLOG $BASENAME "unittest crashed or exited with fatal error" + ;; +esac +cd $CURDIR +exit 0 diff --git a/tests/runsingletest.sh b/tests/runsingletest.sh new file mode 100755 index 000000000..6ecf7c88a --- /dev/null +++ b/tests/runsingletest.sh @@ -0,0 +1,51 @@ +#!/bin/bash +# this is just small wrapper to automate the unit testcases + + + +function emptylog() { + FILENAME=$1 + TESTCASE=$2 + + cat< $FILENAME + + + + + + + + + + + + Current testsuite crashes or wasnt in shape to be executed in development environment and this error message is placeholder. Fix your tests! + + +EOF + +} + +TEST=$1 +CURDIR=`pwd` +DIRNAME=`dirname $TEST` +BASENAME=`basename $TEST` +QTESTLOG=./$BASENAME.log +JUNITLOG=./$BASENAME.log.xml + +cd $DIRNAME +LD_LIBRARY_PATH=../../lib ./$BASENAME -xml -o ./$BASENAME.log + +xsltproc --nonet ../qtestlib2junitxml.xsl $QTESTLOG > $JUNITLOG +EXIT_CODE=$? +case "$EXIT_CODE" in + "0") + echo success + ;; + *) + echo error: unittest $BASENAME failed with $EXIT_CODE errors + emptylog $JUNITLOG $BASENAME + ;; +esac +cd $CURDIR +exit $EXIT_CODE diff --git a/tests/runtests.pri b/tests/runtests.pri new file mode 100644 index 000000000..92990f695 --- /dev/null +++ b/tests/runtests.pri @@ -0,0 +1,19 @@ +# QMAKE_EXTRA_UNIX_TARGETS += runtests +# QMAKE_EXTRA_UNIX_TARGETS += coverage + +# runtests.target = runtests +# runtests.commands = @find . -type f -perm +100 -name \"?t_*\" -exec ./runsingletest.sh {} \\; +# runtests.depends = FORCE + +#coverage.target = coverage +#coverage.commands = @./coverage.py ../src/ ../src/.obj/ 50 ; +#coverage.depends = FORCE + + +coverage.target = coverage +# coverage.CONFIG = recursive +QMAKE_EXTRA_TARGETS += coverage + +coverage-xml.target = coverage-xml +# coverage-xml.CONFIG = recursive +QMAKE_EXTRA_TARGETS += coverage-xml diff --git a/tests/runtests.py b/tests/runtests.py new file mode 100644 index 000000000..02ea49380 --- /dev/null +++ b/tests/runtests.py @@ -0,0 +1,249 @@ +#!/usr/bin/python + +import sys +import os +import time +import signal +import subprocess +import commands as cmd +import datetime +import time +from _xmlplus.dom.NodeFilter import NodeFilter +from _xmlplus.dom import ext +from _xmlplus.dom import minidom +from datetime import datetime + +def build_results(result, buffer): + # Builds a results.xml by parsing xml logs in QTestLib xml format and + # combining their output into check xml format. + + + + # Then add those to the doc structure + + #testElement.setAttributeNS(checkns,"result","Success") + + #x = 0 + #for line in buffer.split("\n"): + # print "LINE " + str(x) + ": " + line + # x=x+1 + + tmpdoc = minidom.parseString(buffer) + + e_testcase = tmpdoc.getElementsByTagName("TestCase") + title = e_testcase[0].attributes.item(0).nodeValue + + suiteElement = doc.createElementNS(checkns,"suite") + titleElement = doc.createElementNS(checkns,"title") + + + node = doc.createTextNode(title) + titleElement.appendChild(node) + + rootElement.appendChild(suiteElement) + suiteElement.appendChild(titleElement) + + + suites = tmpdoc.getElementsByTagName("TestFunction") + + for elem in tmpdoc.getElementsByTagName("TestFunction"): + testElement = doc.createElementNS(checkns,"test") + + pathElement = doc.createElementNS(checkns,"path") + fnElement = doc.createElementNS(checkns,"fn") + idElement = doc.createElementNS(checkns,"id") + descriptionElement = doc.createElementNS(checkns,"description") + messageElement = doc.createElementNS(checkns,"message") + + node = doc.createTextNode( elem.attributes.item(0).nodeValue ) + idElement.appendChild(node) + + node = doc.createTextNode(".") + pathElement.appendChild(node) + + testElement.appendChild(pathElement) + testElement.appendChild(fnElement) + testElement.appendChild(idElement) + testElement.appendChild(descriptionElement) + testElement.appendChild(messageElement) + + suiteElement.appendChild(testElement) + + incident = elem.getElementsByTagName("Incident") + if incident != None: + incident_type = incident[0].getAttribute("type") + incident_file = incident[0].getAttribute("file") + incident_row = incident[0].getAttribute("line") + + if (incident_type == "pass"): + testElement.setAttributeNS(checkns,"result","success") + elif (incident_type == "fail"): + testElement.setAttributeNS(checkns,"result","failure") + else: + testElement.setAttributeNS(checkns,"result","error") + + if incident_file != None and incident_file != "": + node = doc.createTextNode(incident_file + ":" + str(incident_row)) + else: + node = doc.createTextNode("n/a:0") + + fnElement.appendChild(node) + + + description = incident[0].getElementsByTagName("DataTag") + if description != None and description.length>0 and description[0].firstChild != None: + node = doc.createTextNode(str(description[0].firstChild.data)+" ") + descriptionElement.appendChild(node) + + description = incident[0].getElementsByTagName("Description") + if description != None and description.length>0 and description[0].firstChild != None: + node = doc.createTextNode(str(description[0].firstChild.data)+" ") + descriptionElement.appendChild(node) + + #for binary in binariestorun: + # filename = "/tmp/" + binary + ".log" + # file = open(filename,"r") + # buffer = file.read() + # print binary + + return + +def init_env(binariestorun): + + global doc + global checkns + global rootElement + global datetimeElement + global durationElement + global startTime + + doc = minidom.Document() + doc = minidom.Document() + checkns = "http://check.sourceforge.net/ns" + rootElement = doc.createElementNS(checkns, "testsuites") + datetimeElement = doc.createElementNS(checkns,"datetime") + + doc.appendChild(rootElement) + rootElement.appendChild(datetimeElement) + node = doc.createTextNode(datetime.today().strftime("%m.%d.%Y %H:%M:%S")) + datetimeElement.appendChild(node) + durationElement = doc.createElementNS(checkns,"duration") + + # If the binaries require different environments, which are not + # mutually compatible, init_env and deinit_env need to be called + # between running the binaries. Another option is to run the whole + # script several times with different arguments. + + processes = [] + + # Return a list of system processes that need to be closed after the + # tests are ran. + + startTime = time.clock() + return processes + +def deinit_env(binariestorun, processes): + + endTime = time.clock() + time.sleep(1) + + print "stop the daemonized processes", processes + for process in processes: + os.kill(process, signal.SIGTERM) + os.waitpid(process, 0) + + rootElement.appendChild(durationElement) + node = doc.createTextNode(str ( endTime - startTime) ) + durationElement.appendChild(node) + + file_object = open("/tmp/result.xml", "w") + ext.PrettyPrint(doc, file_object) + file_object.close() + +def init_maps(): + + # The test cases for test binaries. This might be automatically + # generated? + + test_gprs = [ "test_connect" ] + + # Map the binary name keys to test case values ... + casedict = { "test_gprs" : test_gprs } + + # ... and the other way around. There might be multiple binaries + # linked to one test case, so we need to have test binary lists for + # the test cases. Binarydict has test case names as keys, lists of + # corresponding binaries as values. + + binarydict = {} + + for key in casedict.keys(): + for test in casedict[key]: + if binarydict.has_key(test): + binarylist = binarydict[test] + binarylist.append(key) + else: + binarydict[test] = [key] + + return casedict, binarydict + +def main(): + + # 1. Initialize the mappings between the test cases and test + # binaries. This is needed if the test system wants to only specify + # test cases to be run. + + casedict, binarydict = init_maps() + + # FIXME: temporary + # The testmode variable changes the input handling behavior. If the + # variable is True, the input parameters are test case names. It + # the parameter is False, the input parameters are test binary + # names. + + testmode = False + # testmode = True + + binariestorun = [] + + if testmode: + # if input is test cases, see which binaries need to be run + print "test cases: ", sys.argv[1:] + for testcase in sys.argv[1:]: + binarylist = binarydict[testcase] + for binaryname in binarylist: + if binariestorun.count(binaryname) == 0: + binariestorun.append(binaryname) + + else: + # else if input is binary names, do nothing + binariestorun = sys.argv[1:] + + + # 2. Initialize the testing environment according to the binaries + # that are to be run. All system settings that differ from the + # basic boot-up state need to be defined here. + + processes = init_env(binariestorun) + + # 3. Run the test binaries. It is assumed (for now) that they are + # in the same directory as the test script. + + dirname = os.path.dirname(sys.argv[0]) + print "test binaries to run: ", binariestorun + for binary in binariestorun: + command = dirname + "/" + binary + " -xml" + # print command + (status, output) = cmd.getstatusoutput(command) + cmdpipe = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=None, universal_newlines=True) + status = cmdpipe.wait() + output = cmdpipe.stdout.read() + build_results(status,output) + + # 5. Clean up the testing environment. + + deinit_env(binariestorun, processes) + +if __name__ == "__main__": + sys.exit(main()) + diff --git a/tests/runtests.sh b/tests/runtests.sh new file mode 100755 index 000000000..2603b7404 --- /dev/null +++ b/tests/runtests.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +export DISPLAY=:0 + +TESTSDIR=/usr/lib/libdui-tests +OUTDIR=/tmp/libdui-tests + +mkdir -p ${OUTDIR} + +EXIT_CODE=0 +for TEST in `ls ${TESTSDIR}/?t_*`; do + $TEST -xml -o "${OUTDIR}/$(basename $TEST)".xml + if [ $? -ne 0 ]; then + EXIT_CODE=$((EXIT_CODE+1)) + fi +done +exit $EXIT_CODE diff --git a/tests/shell.pri b/tests/shell.pri new file mode 100644 index 000000000..9fb83f752 --- /dev/null +++ b/tests/shell.pri @@ -0,0 +1,13 @@ +shell_scripts.commands += $$PWD/gen-tests-xml.sh > $$OUT_PWD/tests.xml +shell_scripts.files += $$OUT_PWD/tests.xml +shell_scripts.CONFIG += no_check_exist + +include(../mkspecs/common.pri) + +# fixed path required by TATAM +# You mean hardcoding /usr instead of using $$DUI_INSTALL_DATA? Why? murrayc +shell_scripts.path += $$DUI_INSTALL_DATA/libdui-tests +shell_scripts.depends = FORCE + +INSTALLS += \ + shell_scripts diff --git a/tests/stubs/duiaction_stub.h b/tests/stubs/duiaction_stub.h new file mode 100644 index 000000000..b7d9e4e5f --- /dev/null +++ b/tests/stubs/duiaction_stub.h @@ -0,0 +1,178 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIACTION_STUB +#define DUIACTION_STUB + +#include "duiaction.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiActionStub : public StubBase +{ +public: + virtual void DuiActionConstructor(QObject *parent); + virtual void DuiActionConstructor(const QString &text, QObject *parent); + virtual void DuiActionConstructor(const QString &iconID, const QString &text, QObject *parent); + virtual void DuiActionDestructor(); + virtual const QString &iconID() const; + virtual void setIconID(const QString &id); + virtual DuiAction::Locations location() const; + virtual void setLocation(DuiAction::Locations location); + virtual void setStyleAction(bool styleAction); + virtual bool isStyleAction() const; + DuiActionPrivate *d_ptr ; + virtual void DuiActionConstructor(DuiActionPrivate &dd, QObject *parent); +}; + +// 2. IMPLEMENT STUB +void DuiActionStub::DuiActionConstructor(QObject *parent) +{ + Q_UNUSED(parent); + +} +void DuiActionStub::DuiActionConstructor(const QString &text, QObject *parent) +{ + Q_UNUSED(text); + Q_UNUSED(parent); + +} +void DuiActionStub::DuiActionConstructor(const QString &iconID, const QString &text, QObject *parent) +{ + Q_UNUSED(iconID); + Q_UNUSED(text); + Q_UNUSED(parent); + +} +void DuiActionStub::DuiActionDestructor() +{ + +} +const QString &DuiActionStub::iconID() const +{ + stubMethodEntered("iconID"); + return stubReturnValue("iconID"); +} + +void DuiActionStub::setIconID(const QString &id) +{ + QList params; + params.append(new Parameter(id)); + stubMethodEntered("setIconID", params); +} + +DuiAction::Locations DuiActionStub::location() const +{ + stubMethodEntered("location"); + return stubReturnValue("location"); +} + +void DuiActionStub::setLocation(DuiAction::Locations location) +{ + QList params; + params.append(new Parameter(location)); + stubMethodEntered("setLocation", params); +} + +void DuiActionStub::setStyleAction(bool styleAction) +{ + QList params; + params.append(new Parameter(styleAction)); + stubMethodEntered("setStyleAction", params); +} + +bool DuiActionStub::isStyleAction() const +{ + stubMethodEntered("isStyleAction"); + return stubReturnValue("isStyleAction"); +} + +void DuiActionStub::DuiActionConstructor(DuiActionPrivate &dd, QObject *parent) +{ + Q_UNUSED(dd); + Q_UNUSED(parent); + +} + + +// 3. CREATE A STUB INSTANCE +DuiActionStub gDefaultDuiActionStub; +DuiActionStub *gDuiActionStub = &gDefaultDuiActionStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiAction::DuiAction(QObject *parent) : QAction(parent), d_ptr(NULL) +{ + gDuiActionStub->DuiActionConstructor(parent); +} + +DuiAction::DuiAction(const QString &text, QObject *parent) : QAction(parent), d_ptr(NULL) +{ + gDuiActionStub->DuiActionConstructor(text, parent); +} + +DuiAction::DuiAction(const QString &iconID, const QString &text, QObject *parent) : QAction(parent), d_ptr(NULL) +{ + gDuiActionStub->DuiActionConstructor(iconID, text, parent); +} + +DuiAction::~DuiAction() +{ + gDuiActionStub->DuiActionDestructor(); +} + +QString DuiAction::iconID() const +{ + return gDuiActionStub->iconID(); +} + +void DuiAction::setIconID(const QString &id) +{ + gDuiActionStub->setIconID(id); +} + +DuiAction::Locations DuiAction::location() const +{ + return gDuiActionStub->location(); +} + +void DuiAction::setLocation(DuiAction::Locations location) +{ + gDuiActionStub->setLocation(location); +} + +void DuiAction::setStyleAction(bool styleAction) +{ + gDuiActionStub->setStyleAction(styleAction); +} + +bool DuiAction::isStyleAction() const +{ + return gDuiActionStub->isStyleAction(); +} + +DuiAction::DuiAction(DuiActionPrivate &dd, QObject *parent) : QAction(parent), d_ptr(&dd) +{ + gDuiActionStub->DuiActionConstructor(dd, parent); +} + + +#endif diff --git a/tests/stubs/duiappletbutton_stub.h b/tests/stubs/duiappletbutton_stub.h new file mode 100644 index 000000000..c5259f881 --- /dev/null +++ b/tests/stubs/duiappletbutton_stub.h @@ -0,0 +1,93 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETBUTTON_STUB +#define DUIAPPLETBUTTON_STUB + +#include "duiappletbutton.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiAppletButtonStub : public StubBase +{ +public: + virtual void DuiAppletButtonConstructor(QGraphicsItem *parent, const QString &type); + virtual void DuiAppletButtonDestructor(); + virtual bool initialize(const DuiAppletMetaData &data); + virtual QString metadataFilename() const; +}; + +// 2. IMPLEMENT STUB +void DuiAppletButtonStub::DuiAppletButtonConstructor(QGraphicsItem *parent, const QString &type) +{ + Q_UNUSED(parent); + Q_UNUSED(type); + +} +void DuiAppletButtonStub::DuiAppletButtonDestructor() +{ + +} +bool DuiAppletButtonStub::initialize(const DuiAppletMetaData &data) +{ + QList params; + params.append(new Parameter(data)); + stubMethodEntered("initialize", params); + return stubReturnValue("initialize"); +} + +QString DuiAppletButtonStub::metadataFilename() const +{ + stubMethodEntered("metadataFilename"); + return stubReturnValue("metadataFilename"); +} + + + +// 3. CREATE A STUB INSTANCE +DuiAppletButtonStub gDefaultDuiAppletButtonStub; +DuiAppletButtonStub *gDuiAppletButtonStub = &gDefaultDuiAppletButtonStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiAppletButton::DuiAppletButton(QGraphicsItem *parent, const QString &type) +{ + gDuiAppletButtonStub->DuiAppletButtonConstructor(parent, type); +} + +DuiAppletButton::~DuiAppletButton() +{ + gDuiAppletButtonStub->DuiAppletButtonDestructor(); +} + +bool DuiAppletButton::initialize(const DuiAppletMetaData &data) +{ + metadataFile = data.fileName(); + return gDuiAppletButtonStub->initialize(data); +} + +QString DuiAppletButton::metadataFilename() const +{ + return gDuiAppletButtonStub->metadataFilename().isEmpty() ? metadataFile : gDuiAppletButtonStub->metadataFilename(); +} + + +#endif diff --git a/tests/stubs/duiapplethandle_stub.h b/tests/stubs/duiapplethandle_stub.h new file mode 100644 index 000000000..7d585e039 --- /dev/null +++ b/tests/stubs/duiapplethandle_stub.h @@ -0,0 +1,582 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETHANDLE_STUB +#define DUIAPPLETHANDLE_STUB + +#include "duiapplethandle.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiAppletHandleStub : public StubBase +{ +public: + virtual void DuiAppletHandleConstructor(DuiAppletHandle *handle); + virtual void DuiAppletHandleDestructor(); + virtual void init(const QString &runnerBinary, const QString &appletInstanceFileDataPath, const QString &metaDataFileName, const DuiAppletId &appletId); + virtual void initPlaceHolder(const DuiAppletId &appletId, const QString &packageName, const QString &installationError); + virtual void kill(); + virtual void reinit(); + virtual void setAliveResponseTimeout(uint timeout); + virtual void sendGeometryMessage(QRectF appletRect, Qt::HANDLE pixmapHandle); + virtual void removeApplet(); + virtual void stopCommunication(); + virtual void setAppletSpecificActions(QList items); + virtual DuiAppletHandleModel::AppletState state() const; + virtual void setAppletIcon(const QString &newIcon); + virtual void setAppletTitle(const QString &newTitle); + virtual void setAppletText(const QString &newText); + virtual QString appletIcon() const; + virtual QString appletTitle() const; + virtual QString appletText() const; + virtual void setSizeHints(const QVector &sizeHints); + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event); + virtual void cancelEvent(DuiCancelEvent *event); + virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent *event); + virtual void enterDisplayEvent(); + virtual void exitDisplayEvent(); + virtual void connectionEstablished(); + virtual void run(); + virtual void messageReceived(const DuiAppletMessage &message); + virtual void communicationTimerTimeout(); + virtual void sendAliveMessageRequest(); + virtual void visibilityEvent(bool visible); + virtual void orientationEvent(const Dui::Orientation &); + virtual void processStdErrorReady(); + virtual void processStdOutputReady(); + virtual void processError(QProcess::ProcessError error); + virtual void processFinished(int exitCode, QProcess::ExitStatus exitStatus); + virtual void appletSpecificActionTriggered(); + virtual void appletRemovalRequested(DuiAppletId appletId); + virtual void appletIconChanged(const QString &newIcon); + virtual void appletTitleChanged(const QString &newTitle); + virtual void appletTextChanged(const QString &newText); + virtual void pixmapTakenIntoUse(Qt::HANDLE pixmapHandle); + virtual void appletPixmapModified(const QRectF &rect); + virtual void setAppletBrokenState(); + virtual void displayContextMenu(QList actions); +}; + +// 2. IMPLEMENT STUB +void DuiAppletHandleStub::DuiAppletHandleConstructor(DuiAppletHandle *handle) +{ + QList params; + params.append(new Parameter(handle)); + stubMethodEntered("constructor", params); +} +void DuiAppletHandleStub::DuiAppletHandleDestructor() +{ + stubMethodEntered("destructor"); +} +void DuiAppletHandleStub::init(const QString &runnerBinary, const QString &appletInstanceFileDataPath, const QString &metaDataFileName, const DuiAppletId &appletId) +{ + QList params; + params.append(new Parameter(runnerBinary)); + params.append(new Parameter(appletInstanceFileDataPath)); + params.append(new Parameter(metaDataFileName)); + params.append(new Parameter(appletId)); + stubMethodEntered("init", params); +} + +void DuiAppletHandleStub::initPlaceHolder(const DuiAppletId &appletId, const QString &packageName, const QString &installationError) +{ + QList params; + params.append(new Parameter(appletId)); + params.append(new Parameter(packageName)); + params.append(new Parameter(installationError)); + stubMethodEntered("initPlaceHolder", params); +} + +void DuiAppletHandleStub::kill() +{ + stubMethodEntered("kill"); +} + +void DuiAppletHandleStub::reinit() +{ + stubMethodEntered("reinit"); +} + +void DuiAppletHandleStub::setAliveResponseTimeout(uint timeout) +{ + QList params; + params.append(new Parameter(timeout)); + stubMethodEntered("setAliveResponseTimeout", params); +} + +void DuiAppletHandleStub::sendGeometryMessage(QRectF appletRect, Qt::HANDLE pixmapHandle) +{ + QList params; + params.append(new Parameter(appletRect)); + params.append(new Parameter(pixmapHandle)); + stubMethodEntered("sendGeometryMessage", params); +} + +void DuiAppletHandleStub::removeApplet() +{ + stubMethodEntered("removeApplet"); +} + +void DuiAppletHandleStub::stopCommunication() +{ + stubMethodEntered("stopCommunication"); +} + +void DuiAppletHandleStub::setAppletSpecificActions(QList items) +{ + QList params; + params.append(new Parameter >(items)); + stubMethodEntered("setAppletSpecificActions", params); +} + +DuiAppletHandleModel::AppletState DuiAppletHandleStub::state() const +{ + stubMethodEntered("state"); + return stubReturnValue("state"); +} + +void DuiAppletHandleStub::setAppletIcon(const QString &newIcon) +{ + QList params; + params.append(new Parameter(newIcon)); + stubMethodEntered("setAppletIcon", params); +} + +void DuiAppletHandleStub::setAppletTitle(const QString &newTitle) +{ + QList params; + params.append(new Parameter(newTitle)); + stubMethodEntered("setAppletTitle", params); +} + +void DuiAppletHandleStub::setAppletText(const QString &newText) +{ + QList params; + params.append(new Parameter(newText)); + stubMethodEntered("setAppletText", params); +} + +QString DuiAppletHandleStub::appletIcon() const +{ + stubMethodEntered("appletIcon"); + return stubReturnValue("appletIcon"); +} + +QString DuiAppletHandleStub::appletTitle() const +{ + stubMethodEntered("appletTitle"); + return stubReturnValue("appletTitle"); +} + +QString DuiAppletHandleStub::appletText() const +{ + stubMethodEntered("appletText"); + return stubReturnValue("appletText"); +} + +void DuiAppletHandleStub::setSizeHints(const QVector &sizeHints) +{ + QList params; + params.append(new Parameter >(sizeHints)); + stubMethodEntered("setSizeHints", params); +} + +void DuiAppletHandleStub::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + QList params; + params.append(new Parameter(event)); + stubMethodEntered("mousePressEvent", params); +} + +void DuiAppletHandleStub::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + QList params; + params.append(new Parameter(event)); + stubMethodEntered("mouseReleaseEvent", params); +} + +void DuiAppletHandleStub::mouseMoveEvent(QGraphicsSceneMouseEvent *event) +{ + QList params; + params.append(new Parameter(event)); + stubMethodEntered("mouseMoveEvent", params); +} + +void DuiAppletHandleStub::cancelEvent(DuiCancelEvent *event) +{ + QList params; + params.append(new Parameter(event)); + stubMethodEntered("cancelEvent", params); +} + +void DuiAppletHandleStub::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) +{ + QList params; + params.append(new Parameter(event)); + stubMethodEntered("contextMenuEvent", params); +} + +void DuiAppletHandleStub::enterDisplayEvent() +{ + stubMethodEntered("enterDisplayEvent"); +} + +void DuiAppletHandleStub::exitDisplayEvent() +{ + stubMethodEntered("exitDisplayEvent"); +} + +void DuiAppletHandleStub::connectionEstablished() +{ + stubMethodEntered("connectionEstablished"); +} + +void DuiAppletHandleStub::run() +{ + stubMethodEntered("run"); +} + +void DuiAppletHandleStub::messageReceived(const DuiAppletMessage &message) +{ + QList params; + params.append(new Parameter(message)); + stubMethodEntered("messageReceived", params); +} + +void DuiAppletHandleStub::communicationTimerTimeout() +{ + stubMethodEntered("communicationTimerTimeout"); +} + +void DuiAppletHandleStub::sendAliveMessageRequest() +{ + stubMethodEntered("sendAliveMessageRequest"); +} + +void DuiAppletHandleStub::visibilityEvent(bool visible) +{ + QList params; + params.append(new Parameter(visible)); + stubMethodEntered("visibilityEvent", params); +} + +void DuiAppletHandleStub::orientationEvent(const Dui::Orientation &orientation) +{ + QList params; + params.append(new Parameter(orientation)); + stubMethodEntered("orientationEvent", params); +} + +void DuiAppletHandleStub::processStdErrorReady() +{ + stubMethodEntered("processStdErrorReady"); +} + +void DuiAppletHandleStub::processStdOutputReady() +{ + stubMethodEntered("processStdOutputReady"); +} + +void DuiAppletHandleStub::processError(QProcess::ProcessError error) +{ + QList params; + params.append(new Parameter(error)); + stubMethodEntered("processError", params); +} + +void DuiAppletHandleStub::processFinished(int exitCode, QProcess::ExitStatus exitStatus) +{ + QList params; + params.append(new Parameter(exitCode)); + params.append(new Parameter(exitStatus)); + stubMethodEntered("processFinished", params); +} + +void DuiAppletHandleStub::appletSpecificActionTriggered() +{ + stubMethodEntered("appletSpecificActionTriggered"); +} + +void DuiAppletHandleStub::appletRemovalRequested(DuiAppletId appletId) +{ + QList params; + params.append(new Parameter(appletId)); + stubMethodEntered("appletRemovalRequested", params); +} + +void DuiAppletHandleStub::appletIconChanged(const QString &newIcon) +{ + QList params; + params.append(new Parameter(newIcon)); + stubMethodEntered("appletIconChanged", params); +} + +void DuiAppletHandleStub::appletTitleChanged(const QString &newTitle) +{ + QList params; + params.append(new Parameter(newTitle)); + stubMethodEntered("appletTitleChanged", params); +} + +void DuiAppletHandleStub::appletTextChanged(const QString &newText) +{ + QList params; + params.append(new Parameter(newText)); + stubMethodEntered("appletTextChanged", params); +} + +void DuiAppletHandleStub::pixmapTakenIntoUse(Qt::HANDLE pixmapHandle) +{ + QList params; + params.append(new Parameter(pixmapHandle)); + stubMethodEntered("pixmapTakenIntoUse", params); +} + +void DuiAppletHandleStub::appletPixmapModified(const QRectF &rect) +{ + QList params; + params.append(new Parameter(rect)); + stubMethodEntered("appletPixmapModified", params); +} + +void DuiAppletHandleStub::setAppletBrokenState() +{ + stubMethodEntered("setAppletBrokenState"); +} + +void DuiAppletHandleStub::displayContextMenu(QList actions) +{ + QList params; + params.append(new Parameter >(actions)); + stubMethodEntered("displayContextMenu", params); +} + + + +// 3. CREATE A STUB INSTANCE +DuiAppletHandleStub gDefaultDuiAppletHandleStub; +DuiAppletHandleStub *gDuiAppletHandleStub = &gDefaultDuiAppletHandleStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiAppletHandle::DuiAppletHandle() +{ + gDuiAppletHandleStub->DuiAppletHandleConstructor(this); +} + +DuiAppletHandle::~DuiAppletHandle() +{ + gDuiAppletHandleStub->DuiAppletHandleDestructor(); +} + +void DuiAppletHandle::init(const QString &runnerBinary, const QString &appletInstanceFileDataPath, const QString &metaDataFileName, const DuiAppletId &appletId) +{ + gDuiAppletHandleStub->init(runnerBinary, appletInstanceFileDataPath, metaDataFileName, appletId); +} + +void DuiAppletHandle::initPlaceHolder(const DuiAppletId &appletId, const QString &packageName, const QString &installationError) +{ + gDuiAppletHandleStub->initPlaceHolder(appletId, packageName, installationError); +} + +void DuiAppletHandle::kill() +{ + gDuiAppletHandleStub->kill(); +} + +void DuiAppletHandle::reinit() +{ + gDuiAppletHandleStub->reinit(); +} + +void DuiAppletHandle::setAliveResponseTimeout(uint timeout) +{ + gDuiAppletHandleStub->setAliveResponseTimeout(timeout); +} + +void DuiAppletHandle::sendGeometryMessage(QRectF appletRect, Qt::HANDLE pixmapHandle) +{ + gDuiAppletHandleStub->sendGeometryMessage(appletRect, pixmapHandle); +} + +void DuiAppletHandle::removeApplet() +{ + gDuiAppletHandleStub->removeApplet(); +} + +void DuiAppletHandle::stopCommunication() +{ + gDuiAppletHandleStub->stopCommunication(); +} + +void DuiAppletHandle::setAppletSpecificActions(QList items) +{ + gDuiAppletHandleStub->setAppletSpecificActions(items); +} + +DuiAppletHandleModel::AppletState DuiAppletHandle::state() const +{ + return gDuiAppletHandleStub->state(); +} + +void DuiAppletHandle::setAppletIcon(const QString &newIcon) +{ + gDuiAppletHandleStub->setAppletIcon(newIcon); +} + +void DuiAppletHandle::setAppletTitle(const QString &newTitle) +{ + gDuiAppletHandleStub->setAppletTitle(newTitle); +} + +void DuiAppletHandle::setAppletText(const QString &newText) +{ + gDuiAppletHandleStub->setAppletText(newText); +} + +QString DuiAppletHandle::appletIcon() const +{ + return gDuiAppletHandleStub->appletIcon(); +} + +QString DuiAppletHandle::appletTitle() const +{ + return gDuiAppletHandleStub->appletTitle(); +} + +QString DuiAppletHandle::appletText() const +{ + return gDuiAppletHandleStub->appletText(); +} + +void DuiAppletHandle::setSizeHints(const QVector &sizeHints) +{ + gDuiAppletHandleStub->setSizeHints(sizeHints); +} + +void DuiAppletHandle::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + gDuiAppletHandleStub->mousePressEvent(event); +} + +void DuiAppletHandle::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + gDuiAppletHandleStub->mouseReleaseEvent(event); +} + +void DuiAppletHandle::mouseMoveEvent(QGraphicsSceneMouseEvent *event) +{ + gDuiAppletHandleStub->mouseMoveEvent(event); +} + +void DuiAppletHandle::cancelEvent(DuiCancelEvent *event) +{ + gDuiAppletHandleStub->cancelEvent(event); +} + +void DuiAppletHandle::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) +{ + gDuiAppletHandleStub->contextMenuEvent(event); +} + +void DuiAppletHandle::enterDisplayEvent() +{ + gDuiAppletHandleStub->enterDisplayEvent(); +} + +void DuiAppletHandle::exitDisplayEvent() +{ + gDuiAppletHandleStub->exitDisplayEvent(); +} + +void DuiAppletHandle::connectionEstablished() +{ + gDuiAppletHandleStub->connectionEstablished(); +} + +void DuiAppletHandle::run() +{ + gDuiAppletHandleStub->run(); +} + +void DuiAppletHandle::messageReceived(const DuiAppletMessage &message) +{ + gDuiAppletHandleStub->messageReceived(message); +} + +void DuiAppletHandle::communicationTimerTimeout() +{ + gDuiAppletHandleStub->communicationTimerTimeout(); +} + +void DuiAppletHandle::sendAliveMessageRequest() +{ + gDuiAppletHandleStub->sendAliveMessageRequest(); +} + +void DuiAppletHandle::visibilityEvent(bool visible) +{ + gDuiAppletHandleStub->visibilityEvent(visible); +} + +void DuiAppletHandle::orientationEvent(const Dui::Orientation &orientation) +{ + gDuiAppletHandleStub->orientationEvent(orientation); +} + +void DuiAppletHandle::processStdErrorReady() +{ + gDuiAppletHandleStub->processStdErrorReady(); +} + +void DuiAppletHandle::processStdOutputReady() +{ + gDuiAppletHandleStub->processStdOutputReady(); +} + +void DuiAppletHandle::processError(QProcess::ProcessError error) +{ + gDuiAppletHandleStub->processError(error); +} + +void DuiAppletHandle::processFinished(int exitCode, QProcess::ExitStatus exitStatus) +{ + gDuiAppletHandleStub->processFinished(exitCode, exitStatus); +} + +void DuiAppletHandle::appletSpecificActionTriggered() +{ + gDuiAppletHandleStub->appletSpecificActionTriggered(); +} + +void DuiAppletHandle::setAppletBrokenState() +{ + gDuiAppletHandleStub->setAppletBrokenState(); +} + +void DuiAppletHandle::displayContextMenu(QList actions) +{ + gDuiAppletHandleStub->displayContextMenu(actions); +} + +#endif diff --git a/tests/stubs/duiappletid_stub.h b/tests/stubs/duiappletid_stub.h new file mode 100644 index 000000000..f981a6179 --- /dev/null +++ b/tests/stubs/duiappletid_stub.h @@ -0,0 +1,101 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETID_STUB +#define DUIAPPLETID_STUB + +#include "duiappletid.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiAppletIdStub : public StubBase +{ +public: + virtual void DuiAppletIdConstructor(); + virtual void DuiAppletIdConstructor(const QString &applicationName, const QString &mashupCanvasName, const DuiAppletId::AppletInstanceID &instanceId); + virtual void DuiAppletIdDestructor(); + virtual QString toString() const; + virtual DuiAppletId::AppletInstanceID instanceId() const; +}; + +// 2. IMPLEMENT STUB +void DuiAppletIdStub::DuiAppletIdConstructor() +{ + +} +void DuiAppletIdStub::DuiAppletIdConstructor(const QString &applicationName, const QString &mashupCanvasName, const DuiAppletId::AppletInstanceID &instanceId) +{ + Q_UNUSED(applicationName); + Q_UNUSED(mashupCanvasName); + Q_UNUSED(instanceId); + +} +void DuiAppletIdStub::DuiAppletIdDestructor() +{ + +} +QString DuiAppletIdStub::toString() const +{ + stubMethodEntered("toString"); + return stubReturnValue("toString"); +} + +DuiAppletId::AppletInstanceID DuiAppletIdStub::instanceId() const +{ + stubMethodEntered("instanceId"); + return stubReturnValue("instanceId"); +} + + + +// 3. CREATE A STUB INSTANCE +DuiAppletIdStub gDefaultDuiAppletIdStub; +DuiAppletIdStub *gDuiAppletIdStub = &gDefaultDuiAppletIdStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiAppletId::DuiAppletId() +{ + gDuiAppletIdStub->DuiAppletIdConstructor(); +} + +DuiAppletId::DuiAppletId(const QString &applicationName, const QString &mashupCanvasName, const AppletInstanceID &instanceId) +{ + gDuiAppletIdStub->DuiAppletIdConstructor(applicationName, mashupCanvasName, instanceId); +} + +DuiAppletId::~DuiAppletId() +{ + gDuiAppletIdStub->DuiAppletIdDestructor(); +} + +QString DuiAppletId::toString() const +{ + return gDuiAppletIdStub->toString(); +} + +DuiAppletId::AppletInstanceID DuiAppletId::instanceId() const +{ + return gDuiAppletIdStub->instanceId(); +} + + +#endif diff --git a/tests/stubs/duiappletinstancedata_stub.h b/tests/stubs/duiappletinstancedata_stub.h new file mode 100644 index 000000000..3d77cfdb0 --- /dev/null +++ b/tests/stubs/duiappletinstancedata_stub.h @@ -0,0 +1,149 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETINSTANCEDATA_STUB +#define DUIAPPLETINSTANCEDATA_STUB + +#include "duiappletinstancedata.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiAppletInstanceDataStub : public StubBase +{ +public: + virtual void DuiAppletInstanceDataConstructor(DuiDataStore &baseDataStore, DuiAppletId id, const QString &desktopFile, const QString &instanceDataFilePath); + virtual void DuiAppletInstanceDataDestructor(); + virtual DuiWidget *instantiateApplet(); + virtual DuiWidget *instantiateAppletPlaceHolder(const QString &packageName, const QMap &metaData); + virtual void storeData(DuiDataStore &store); + virtual QString createKey(int type) const; + virtual void setAppletHandleSizeHints(DuiAppletHandle &handle); + virtual QSizeF qStringToQSizeF(const QString &string); +}; + +// 2. IMPLEMENT STUB +void DuiAppletInstanceDataStub::DuiAppletInstanceDataConstructor(DuiDataStore &baseDataStore, DuiAppletId id, const QString &desktopFile, const QString &instanceDataFilePath) +{ + Q_UNUSED(baseDataStore); + Q_UNUSED(id); + Q_UNUSED(desktopFile); + Q_UNUSED(instanceDataFilePath); + +} +void DuiAppletInstanceDataStub::DuiAppletInstanceDataDestructor() +{ + +} +DuiWidget *DuiAppletInstanceDataStub::instantiateApplet() +{ + stubMethodEntered("instantiateApplet"); + return stubReturnValue("instantiateApplet"); +} + +DuiWidget *DuiAppletInstanceDataStub::instantiateAppletPlaceHolder(const QString &packageName, const QMap &metaData) +{ + QList params; + params.append(new Parameter(packageName)); + params.append(new Parameter & >(metaData)); + stubMethodEntered("instantiateAppletPlaceHolder", params); + return stubReturnValue("instantiateAppletPlaceHolder"); +} + +void DuiAppletInstanceDataStub::storeData(DuiDataStore &store) +{ + QList params; + params.append(new Parameter(store)); + stubMethodEntered("storeData", params); +} + +QString DuiAppletInstanceDataStub::createKey(int type) const +{ + QList params; + params.append(new Parameter(type)); + stubMethodEntered("createKey", params); + return stubReturnValue("createKey"); +} + +void DuiAppletInstanceDataStub::setAppletHandleSizeHints(DuiAppletHandle &handle) +{ + QList params; + params.append(new Parameter(handle)); + stubMethodEntered("setAppletHandleSizeHints", params); +} + +QSizeF DuiAppletInstanceDataStub::qStringToQSizeF(const QString &string) +{ + QList params; + params.append(new Parameter(string)); + stubMethodEntered("qStringToQSizeF", params); + return stubReturnValue("qStringToQSizeF"); +} + + + +// 3. CREATE A STUB INSTANCE +DuiAppletInstanceDataStub gDefaultDuiAppletInstanceDataStub; +DuiAppletInstanceDataStub *gDuiAppletInstanceDataStub = &gDefaultDuiAppletInstanceDataStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiAppletInstanceData::DuiAppletInstanceData(DuiDataStore &baseDataStore, DuiAppletId id, const QString &desktopFile, const QString &instanceDataFilePath) +{ + gDuiAppletInstanceDataStub->DuiAppletInstanceDataConstructor(baseDataStore, id, desktopFile, instanceDataFilePath); +} + +DuiAppletInstanceData::~DuiAppletInstanceData() +{ + gDuiAppletInstanceDataStub->DuiAppletInstanceDataDestructor(); +} + +DuiWidget *DuiAppletInstanceData::instantiateApplet() +{ + return gDuiAppletInstanceDataStub->instantiateApplet(); +} + +DuiWidget *DuiAppletInstanceData::instantiateAppletPlaceHolder(const QString &packageName, const QMap &metaData) +{ + return gDuiAppletInstanceDataStub->instantiateAppletPlaceHolder(packageName, metaData); +} + +void DuiAppletInstanceData::storeData(DuiDataStore &store) +{ + gDuiAppletInstanceDataStub->storeData(store); +} + +QString DuiAppletInstanceData::createKey(KeyType type) const +{ + return gDuiAppletInstanceDataStub->createKey((int)type); +} + +void DuiAppletInstanceData::setAppletHandleSizeHints(DuiAppletHandle &handle) +{ + gDuiAppletInstanceDataStub->setAppletHandleSizeHints(handle); +} + +QSizeF DuiAppletInstanceData::qStringToQSizeF(const QString &string) +{ + return gDuiAppletInstanceDataStub->qStringToQSizeF(string); +} + + +#endif diff --git a/tests/stubs/duiappletinstancemanager_stub.h b/tests/stubs/duiappletinstancemanager_stub.h new file mode 100644 index 000000000..3731677e3 --- /dev/null +++ b/tests/stubs/duiappletinstancemanager_stub.h @@ -0,0 +1,528 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETINSTANCEMANAGER_STUB +#define DUIAPPLETINSTANCEMANAGER_STUB + +#include "duiappletinstancemanager.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiAppletInstanceManagerStub : public StubBase +{ +public: + virtual void DuiAppletInstanceManagerConstructor(const QString &identifier, DuiDataStore *dataStore); + virtual void DuiAppletInstanceManagerDestructor(); + virtual bool restoreApplets(); + virtual bool instantiateApplet(const QString &metadataFile); + virtual void instantiateAppletFromPackage(const QString &packageName, const QMap &metaData); + virtual void removeActionTriggered(bool checked); + virtual void appletUninstalled(const QString &desktopFile); + virtual bool removeApplet(DuiAppletId appletId); + virtual void operationComplete(const QString &operation, const QString &pkg, const QString &error); + virtual void setAppletTitle(const QString &title); + virtual void receiveOperation(QDBusPendingCallWatcher *watcher); + virtual void init(const QString &mashupCanvasName, DuiDataStore *dataStore); + virtual bool instantiateApplet(DuiAppletId appletId); + virtual bool instantiateOutOfProcessApplet(DuiAppletInstanceData *data, const DuiAppletMetaData &metadata); + virtual bool instantiateInProcessApplet(DuiAppletInstanceData *data, const DuiAppletMetaData &metadata); + virtual void instantiateAppletPlaceHolder(DuiAppletInstanceData *data); + virtual void queryInstallationStatus(DuiAppletInstanceData *data); + virtual void createDataStore(); + virtual void readAppletData(); + virtual DuiAppletInstanceData *createAppletInstanceDataFromInstantiationData(const DuiAppletId &appletId, const QMap &appletInstantiationData); + virtual DuiAppletInstanceData *createAppletInstanceDataFromPackageMetaData(const DuiAppletId &appletId, const QMap &packageMetaData); + virtual void setAppletHandleSizeHints(DuiAppletHandle &handle, DuiAppletInstanceData &data); + virtual QSizeF qStringToQSizeF(const QString &string); + virtual QString dataPath() const; + virtual QString createAppletInstanceDataFileName(DuiAppletId id) const; + virtual void freeAppletInstanceID(DuiAppletId id); + virtual DuiAppletId appletIDForWidget(DuiWidget *widget) const; + virtual DuiAppletId appletIDForPackageName(const QString &packageName) const; + virtual DuiAppletId::AppletInstanceID appletInstanceIDFromKey(const QString &key); + virtual void removeAppletInstanceData(DuiAppletId appletId); + virtual DuiAppletId getUnusedAppletID(); + virtual bool isValidKey(const QString &key); + virtual QString getParameterName(const QString &key); + virtual QString createKey(const DuiAppletId &appletId, int type); + virtual void storeData(DuiAppletInstanceData *data); + virtual DuiAppletId createAppletId(DuiAppletId::AppletInstanceID instanceId) const; +}; + +// 2. IMPLEMENT STUB +void DuiAppletInstanceManagerStub::DuiAppletInstanceManagerConstructor(const QString &identifier, DuiDataStore *dataStore) +{ + QList params; + params.append(new Parameter(identifier)); + params.append(new Parameter(dataStore)); + stubMethodEntered("constructor", params); +} +void DuiAppletInstanceManagerStub::DuiAppletInstanceManagerDestructor() +{ + +} +bool DuiAppletInstanceManagerStub::restoreApplets() +{ + stubMethodEntered("restoreApplets"); + return stubReturnValue("restoreApplets"); +} + +bool DuiAppletInstanceManagerStub::instantiateApplet(const QString &metadataFile) +{ + QList params; + params.append(new Parameter(metadataFile)); + stubMethodEntered("instantiateApplet", params); + return stubReturnValue("instantiateApplet"); +} + +void DuiAppletInstanceManagerStub::instantiateAppletFromPackage(const QString &packageName, const QMap &metaData) +{ + QList params; + params.append(new Parameter(packageName)); + params.append(new Parameter & >(metaData)); + stubMethodEntered("instantiateAppletFromPackage", params); +} + +void DuiAppletInstanceManagerStub::removeActionTriggered(bool checked) +{ + QList params; + params.append(new Parameter(checked)); + stubMethodEntered("removeActionTriggered", params); +} + +void DuiAppletInstanceManagerStub::appletUninstalled(const QString &desktopFile) +{ + QList params; + params.append(new Parameter(desktopFile)); + stubMethodEntered("appletUninstalled", params); +} + +bool DuiAppletInstanceManagerStub::removeApplet(DuiAppletId appletId) +{ + QList params; + params.append(new Parameter(appletId)); + stubMethodEntered("removeApplet", params); + return stubReturnValue("removeApplet"); +} + +void DuiAppletInstanceManagerStub::operationComplete(const QString &operation, const QString &pkg, const QString &error) +{ + QList params; + params.append(new Parameter(operation)); + params.append(new Parameter(pkg)); + params.append(new Parameter(error)); + stubMethodEntered("operationComplete", params); +} + +void DuiAppletInstanceManagerStub::setAppletTitle(const QString &title) +{ + QList params; + params.append(new Parameter(title)); + stubMethodEntered("setAppletTitle", params); +} + +void DuiAppletInstanceManagerStub::receiveOperation(QDBusPendingCallWatcher *watcher) +{ + QList params; + params.append(new Parameter(watcher)); + stubMethodEntered("receiveOperation", params); +} + +void DuiAppletInstanceManagerStub::init(const QString &mashupCanvasName, DuiDataStore *dataStore) +{ + QList params; + params.append(new Parameter(mashupCanvasName)); + params.append(new Parameter(dataStore)); + stubMethodEntered("init", params); +} + +bool DuiAppletInstanceManagerStub::instantiateApplet(DuiAppletId appletId) +{ + QList params; + params.append(new Parameter(appletId)); + stubMethodEntered("instantiateApplet", params); + return stubReturnValue("instantiateApplet"); +} + +bool DuiAppletInstanceManagerStub::instantiateOutOfProcessApplet(DuiAppletInstanceData *data, const DuiAppletMetaData &metadata) +{ + QList params; + params.append(new Parameter(data)); + params.append(new Parameter(metadata)); + stubMethodEntered("instantiateOutOfProcessApplet", params); + return stubReturnValue("instantiateOutOfProcessApplet"); +} + +bool DuiAppletInstanceManagerStub::instantiateInProcessApplet(DuiAppletInstanceData *data, const DuiAppletMetaData &metadata) +{ + QList params; + params.append(new Parameter(data)); + params.append(new Parameter(metadata)); + stubMethodEntered("instantiateInProcessApplet", params); + return stubReturnValue("instantiateInProcessApplet"); +} + +void DuiAppletInstanceManagerStub::instantiateAppletPlaceHolder(DuiAppletInstanceData *data) +{ + QList params; + params.append(new Parameter(data)); + stubMethodEntered("instantiateAppletPlaceHolder", params); +} + +void DuiAppletInstanceManagerStub::queryInstallationStatus(DuiAppletInstanceData *data) +{ + QList params; + params.append(new Parameter(data)); + stubMethodEntered("queryInstallationStatus", params); +} + +void DuiAppletInstanceManagerStub::createDataStore() +{ + stubMethodEntered("createDataStore"); +} + +void DuiAppletInstanceManagerStub::readAppletData() +{ + stubMethodEntered("readAppletData"); +} + +DuiAppletInstanceData *DuiAppletInstanceManagerStub::createAppletInstanceDataFromInstantiationData(const DuiAppletId &appletId, const QMap &appletInstantiationData) +{ + QList params; + params.append(new Parameter(appletId)); + params.append(new Parameter & >(appletInstantiationData)); + stubMethodEntered("createAppletInstanceDataFromInstantiationData", params); + return stubReturnValue("createAppletInstanceDataFromInstantiationData"); +} + +DuiAppletInstanceData *DuiAppletInstanceManagerStub::createAppletInstanceDataFromPackageMetaData(const DuiAppletId &appletId, const QMap &packageMetaData) +{ + QList params; + params.append(new Parameter(appletId)); + params.append(new Parameter & >(packageMetaData)); + stubMethodEntered("createAppletInstanceDataFromPackageMetaData", params); + return stubReturnValue("createAppletInstanceDataFromPackageMetaData"); +} + +void DuiAppletInstanceManagerStub::setAppletHandleSizeHints(DuiAppletHandle &handle, DuiAppletInstanceData &data) +{ + QList params; + params.append(new Parameter(handle)); + params.append(new Parameter(data)); + stubMethodEntered("setAppletHandleSizeHints", params); +} + +QSizeF DuiAppletInstanceManagerStub::qStringToQSizeF(const QString &string) +{ + QList params; + params.append(new Parameter(string)); + stubMethodEntered("qStringToQSizeF", params); + return stubReturnValue("qStringToQSizeF"); +} + +QString DuiAppletInstanceManagerStub::dataPath() const +{ + stubMethodEntered("dataPath"); + return stubReturnValue("dataPath"); +} + +QString DuiAppletInstanceManagerStub::createAppletInstanceDataFileName(DuiAppletId id) const +{ + QList params; + params.append(new Parameter(id)); + stubMethodEntered("createAppletInstanceDataFileName", params); + return stubReturnValue("createAppletInstanceDataFileName"); +} + +void DuiAppletInstanceManagerStub::freeAppletInstanceID(DuiAppletId id) +{ + QList params; + params.append(new Parameter(id)); + stubMethodEntered("freeAppletInstanceID", params); +} + +DuiAppletId DuiAppletInstanceManagerStub::appletIDForWidget(DuiWidget *widget) const +{ + QList params; + params.append(new Parameter(widget)); + stubMethodEntered("appletIDForWidget", params); + return stubReturnValue("appletIDForWidget"); +} + +DuiAppletId DuiAppletInstanceManagerStub::appletIDForPackageName(const QString &packageName) const +{ + QList params; + params.append(new Parameter(packageName)); + stubMethodEntered("appletIDForPackageName", params); + return stubReturnValue("appletIDForPackageName"); +} + +DuiAppletId::AppletInstanceID DuiAppletInstanceManagerStub::appletInstanceIDFromKey(const QString &key) +{ + QList params; + params.append(new Parameter(key)); + stubMethodEntered("appletInstanceIDFromKey", params); + return stubReturnValue("appletInstanceIDFromKey"); +} + +void DuiAppletInstanceManagerStub::removeAppletInstanceData(DuiAppletId appletId) +{ + QList params; + params.append(new Parameter(appletId)); + stubMethodEntered("removeAppletInstanceData", params); +} + +DuiAppletId DuiAppletInstanceManagerStub::getUnusedAppletID() +{ + stubMethodEntered("getUnusedAppletID"); + return stubReturnValue("getUnusedAppletID"); +} + +bool DuiAppletInstanceManagerStub::isValidKey(const QString &key) +{ + QList params; + params.append(new Parameter(key)); + stubMethodEntered("isValidKey", params); + return stubReturnValue("isValidKey"); +} + +QString DuiAppletInstanceManagerStub::getParameterName(const QString &key) +{ + QList params; + params.append(new Parameter(key)); + stubMethodEntered("getParameterName", params); + return stubReturnValue("getParameterName"); +} + +QString DuiAppletInstanceManagerStub::createKey(const DuiAppletId &appletId, int type) +{ + QList params; + params.append(new Parameter(appletId)); + params.append(new Parameter(type)); + stubMethodEntered("createKey", params); + return stubReturnValue("createKey"); +} + +void DuiAppletInstanceManagerStub::storeData(DuiAppletInstanceData *data) +{ + QList params; + params.append(new Parameter(data)); + stubMethodEntered("storeData", params); +} + +DuiAppletId DuiAppletInstanceManagerStub::createAppletId(DuiAppletId::AppletInstanceID instanceId) const +{ + QList params; + params.append(new Parameter(instanceId)); + stubMethodEntered("createAppletId", params); + return stubReturnValue("createAppletId"); +} + + + +// 3. CREATE A STUB INSTANCE +DuiAppletInstanceManagerStub gDefaultDuiAppletInstanceManagerStub; +DuiAppletInstanceManagerStub *gDuiAppletInstanceManagerStub = &gDefaultDuiAppletInstanceManagerStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiAppletInstanceManager::DuiAppletInstanceManager(const QString &identifier, DuiDataStore *dataStore) +{ + gDuiAppletInstanceManagerStub->DuiAppletInstanceManagerConstructor(identifier, dataStore); +} + +DuiAppletInstanceManager::~DuiAppletInstanceManager() +{ + gDuiAppletInstanceManagerStub->DuiAppletInstanceManagerDestructor(); +} + +bool DuiAppletInstanceManager::restoreApplets() +{ + return gDuiAppletInstanceManagerStub->restoreApplets(); +} + +bool DuiAppletInstanceManager::instantiateApplet(const QString &metadataFile) +{ + return gDuiAppletInstanceManagerStub->instantiateApplet(metadataFile); +} + +void DuiAppletInstanceManager::instantiateAppletFromPackage(const QString &packageName, const QMap &metaData) +{ + gDuiAppletInstanceManagerStub->instantiateAppletFromPackage(packageName, metaData); +} + +void DuiAppletInstanceManager::removeActionTriggered(bool checked) +{ + gDuiAppletInstanceManagerStub->removeActionTriggered(checked); +} + +void DuiAppletInstanceManager::appletUninstalled(const QString &desktopFile) +{ + gDuiAppletInstanceManagerStub->appletUninstalled(desktopFile); +} + +bool DuiAppletInstanceManager::removeApplet(DuiAppletId appletId) +{ + return gDuiAppletInstanceManagerStub->removeApplet(appletId); +} + +void DuiAppletInstanceManager::operationComplete(const QString &operation, const QString &pkg, const QString &error) +{ + gDuiAppletInstanceManagerStub->operationComplete(operation, pkg, error); +} + +void DuiAppletInstanceManager::setAppletTitle(const QString &title) +{ + gDuiAppletInstanceManagerStub->setAppletTitle(title); +} + +void DuiAppletInstanceManager::receiveOperation(QDBusPendingCallWatcher *watcher) +{ + gDuiAppletInstanceManagerStub->receiveOperation(watcher); +} + +void DuiAppletInstanceManager::init(const QString &mashupCanvasName, DuiDataStore *dataStore) +{ + gDuiAppletInstanceManagerStub->init(mashupCanvasName, dataStore); +} + +bool DuiAppletInstanceManager::instantiateApplet(DuiAppletId appletId) +{ + return gDuiAppletInstanceManagerStub->instantiateApplet(appletId); +} + +bool DuiAppletInstanceManager::instantiateOutOfProcessApplet(DuiAppletInstanceData *data, const DuiAppletMetaData &metadata) +{ + return gDuiAppletInstanceManagerStub->instantiateOutOfProcessApplet(data, metadata); +} + +bool DuiAppletInstanceManager::instantiateInProcessApplet(DuiAppletInstanceData *data, const DuiAppletMetaData &metadata) +{ + return gDuiAppletInstanceManagerStub->instantiateInProcessApplet(data, metadata); +} + +void DuiAppletInstanceManager::instantiateAppletPlaceHolder(DuiAppletInstanceData *data) +{ + gDuiAppletInstanceManagerStub->instantiateAppletPlaceHolder(data); +} + +void DuiAppletInstanceManager::queryInstallationStatus(DuiAppletInstanceData *data) +{ + gDuiAppletInstanceManagerStub->queryInstallationStatus(data); +} + +void DuiAppletInstanceManager::createDataStore() +{ + gDuiAppletInstanceManagerStub->createDataStore(); +} + +void DuiAppletInstanceManager::readAppletData() +{ + gDuiAppletInstanceManagerStub->readAppletData(); +} + +DuiAppletInstanceData *DuiAppletInstanceManager::createAppletInstanceDataFromInstantiationData(const DuiAppletId &appletId, const QMap &appletInstantiationData) +{ + return gDuiAppletInstanceManagerStub->createAppletInstanceDataFromInstantiationData(appletId, appletInstantiationData); +} + +DuiAppletInstanceData *DuiAppletInstanceManager::createAppletInstanceDataFromPackageMetaData(const DuiAppletId &appletId, const QMap &packageMetaData) +{ + return gDuiAppletInstanceManagerStub->createAppletInstanceDataFromPackageMetaData(appletId, packageMetaData); +} + +void DuiAppletInstanceManager::setAppletHandleSizeHints(DuiAppletHandle &handle, DuiAppletInstanceData &data) +{ + gDuiAppletInstanceManagerStub->setAppletHandleSizeHints(handle, data); +} + +QSizeF DuiAppletInstanceManager::qStringToQSizeF(const QString &string) +{ + return gDuiAppletInstanceManagerStub->qStringToQSizeF(string); +} + +QString DuiAppletInstanceManager::dataPath() const +{ + return gDuiAppletInstanceManagerStub->dataPath(); +} + +QString DuiAppletInstanceManager::createAppletInstanceDataFileName(DuiAppletId id) const +{ + return gDuiAppletInstanceManagerStub->createAppletInstanceDataFileName(id); +} + +void DuiAppletInstanceManager::freeAppletInstanceID(DuiAppletId id) +{ + gDuiAppletInstanceManagerStub->freeAppletInstanceID(id); +} + +DuiAppletId DuiAppletInstanceManager::appletIDForWidget(DuiWidget *widget) const +{ + return gDuiAppletInstanceManagerStub->appletIDForWidget(widget); +} + +DuiAppletId DuiAppletInstanceManager::appletIDForPackageName(const QString &packageName) const +{ + return gDuiAppletInstanceManagerStub->appletIDForPackageName(packageName); +} + +DuiAppletId::AppletInstanceID DuiAppletInstanceManager::appletInstanceIDFromKey(const QString &key) +{ + return gDuiAppletInstanceManagerStub->appletInstanceIDFromKey(key); +} + +void DuiAppletInstanceManager::removeAppletInstanceData(DuiAppletId appletId) +{ + gDuiAppletInstanceManagerStub->removeAppletInstanceData(appletId); +} + +DuiAppletId DuiAppletInstanceManager::getUnusedAppletID() +{ + return gDuiAppletInstanceManagerStub->getUnusedAppletID(); +} + +bool DuiAppletInstanceManager::isValidKey(const QString &key) +{ + return gDuiAppletInstanceManagerStub->isValidKey(key); +} + +QString DuiAppletInstanceManager::getParameterName(const QString &key) +{ + return gDuiAppletInstanceManagerStub->getParameterName(key); +} + +QString DuiAppletInstanceManager::createKey(const DuiAppletId &appletId, KeyType type) +{ + return gDuiAppletInstanceManagerStub->createKey(appletId, type); +} + +void DuiAppletInstanceManager::storeData(DuiAppletInstanceData *data) +{ + gDuiAppletInstanceManagerStub->storeData(data); +} + +DuiAppletId DuiAppletInstanceManager::createAppletId(DuiAppletId::AppletInstanceID instanceId) const +{ + return gDuiAppletInstanceManagerStub->createAppletId(instanceId); +} + + +#endif diff --git a/tests/stubs/duiappletloader_stub.h b/tests/stubs/duiappletloader_stub.h new file mode 100644 index 000000000..4a7677d6c --- /dev/null +++ b/tests/stubs/duiappletloader_stub.h @@ -0,0 +1,70 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETLOADER_STUB +#define DUIAPPLETLOADER_STUB + +#include "duiappletloader.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiAppletLoaderStub : public StubBase +{ +public: + virtual DuiWidget *loadApplet(const DuiAppletMetaData &metadata, DuiDataStore &dataStore, DuiDataAccess &settings); + virtual void DuiAppletLoaderConstructor(); +}; + +// 2. IMPLEMENT STUB +DuiWidget *DuiAppletLoaderStub::loadApplet(const DuiAppletMetaData &metadata, DuiDataStore &dataStore, DuiDataAccess &settings) +{ + QList params; + params.append(new Parameter(metadata.fileName())); + params.append(new Parameter(dataStore)); + params.append(new Parameter(settings)); + stubMethodEntered("loadApplet", params); + return stubReturnValue("loadApplet"); +} + +void DuiAppletLoaderStub::DuiAppletLoaderConstructor() +{ + +} + + +// 3. CREATE A STUB INSTANCE +DuiAppletLoaderStub gDefaultDuiAppletLoaderStub; +DuiAppletLoaderStub *gDuiAppletLoaderStub = &gDefaultDuiAppletLoaderStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiWidget *DuiAppletLoader::loadApplet(const DuiAppletMetaData &metadata, DuiDataStore &dataStore, DuiDataAccess &settings) +{ + return gDuiAppletLoaderStub->loadApplet(metadata, dataStore, settings); +} + +DuiAppletLoader::DuiAppletLoader() +{ + gDuiAppletLoaderStub->DuiAppletLoaderConstructor(); +} + + +#endif diff --git a/tests/stubs/duiappletmetadata_stub.h b/tests/stubs/duiappletmetadata_stub.h new file mode 100644 index 000000000..f1e6afb59 --- /dev/null +++ b/tests/stubs/duiappletmetadata_stub.h @@ -0,0 +1,127 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETMETADATA_STUB +#define DUIAPPLETMETADATA_STUB + +#include "duiappletmetadata.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiAppletMetaDataStub : public StubBase +{ +public: + virtual void DuiAppletMetaDataConstructor(const QString &filename); + virtual void DuiAppletMetaDataDestructor(); + virtual bool isValid() const; + virtual QString runnerBinary() const; + virtual QString appletBinary() const; + virtual QString resourceIdentifier() const; + virtual QString extractLibraryName(const QString &libFileName); +}; + +// 2. IMPLEMENT STUB +void DuiAppletMetaDataStub::DuiAppletMetaDataConstructor(const QString &filename) +{ + Q_UNUSED(filename); + +} +void DuiAppletMetaDataStub::DuiAppletMetaDataDestructor() +{ + +} +bool DuiAppletMetaDataStub::isValid() const +{ + stubMethodEntered("isValid"); + return stubReturnValue("isValid"); +} + +QString DuiAppletMetaDataStub::runnerBinary() const +{ + stubMethodEntered("runnerBinary"); + return stubReturnValue("runnerBinary"); +} + +QString DuiAppletMetaDataStub::appletBinary() const +{ + stubMethodEntered("appletBinary"); + return stubReturnValue("appletBinary"); +} + +QString DuiAppletMetaDataStub::resourceIdentifier() const +{ + stubMethodEntered("resourceIdentifier"); + return stubReturnValue("resourceIdentifier"); +} + +QString DuiAppletMetaDataStub::extractLibraryName(const QString &libFileName) +{ + QList params; + params.append(new Parameter(libFileName)); + stubMethodEntered("extractLibraryName", params); + return stubReturnValue("extractLibraryName"); +} + + + +// 3. CREATE A STUB INSTANCE +DuiAppletMetaDataStub gDefaultDuiAppletMetaDataStub; +DuiAppletMetaDataStub *gDuiAppletMetaDataStub = &gDefaultDuiAppletMetaDataStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiAppletMetaData::DuiAppletMetaData(const QString &filename) : DuiDesktopEntry(filename) +{ + gDuiAppletMetaDataStub->DuiAppletMetaDataConstructor(filename); +} + +DuiAppletMetaData::~DuiAppletMetaData() +{ + gDuiAppletMetaDataStub->DuiAppletMetaDataDestructor(); +} + +bool DuiAppletMetaData::isValid() const +{ + return gDuiAppletMetaDataStub->isValid(); +} + +QString DuiAppletMetaData::runnerBinary() const +{ + return gDuiAppletMetaDataStub->runnerBinary(); +} + +QString DuiAppletMetaData::appletBinary() const +{ + return gDuiAppletMetaDataStub->appletBinary(); +} + +QString DuiAppletMetaData::resourceIdentifier() const +{ + return gDuiAppletMetaDataStub->resourceIdentifier(); +} + +QString DuiAppletMetaData::extractLibraryName(const QString &libFileName) +{ + return gDuiAppletMetaDataStub->extractLibraryName(libFileName); +} + + +#endif diff --git a/tests/stubs/duiappletsettings_stub.h b/tests/stubs/duiappletsettings_stub.h new file mode 100644 index 000000000..707fb4cc5 --- /dev/null +++ b/tests/stubs/duiappletsettings_stub.h @@ -0,0 +1,179 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETSETTINGSSTUB_H +#define DUIAPPLETSETTINGSSTUB_H + +#include +#include +#include +#include +#include +#include +#include +#include + + +class DuiAppletSettingsStub : public StubBase +{ +public: + virtual void duiAppletSettingsConstructor(const QString &metaDataFileName, const DuiAppletId &appletId); + virtual void duiAppletSettingsConstructor(const QString &metaDataFileName, const QString &appletId); + virtual void duiAppletSettingsDestructor(); + virtual const DuiSettingsLanguageBinary *instanceSettingsBinary() const; + virtual const DuiSettingsLanguageBinary *globalSettingsBinary() const; + virtual bool hasSettings() const; + virtual DuiDataStore *instanceDataStore() const; + virtual DuiDataStore *globalDataStore() const; + virtual DuiDataAccess *dataAccess() const; + virtual void removeInstanceSettingValues() const; +}; + +void DuiAppletSettingsStub::duiAppletSettingsConstructor(const QString &metaDataFileName, const DuiAppletId &appletId) +{ + QList params; + params.append(new Parameter(metaDataFileName)); + params.append(new Parameter(appletId)); + stubMethodEntered("duiAppletSettingsConstructor", params); +} + +void DuiAppletSettingsStub::duiAppletSettingsConstructor(const QString &metaDataFileName, const QString &appletId) +{ + QList params; + params.append(new Parameter(metaDataFileName)); + params.append(new Parameter(appletId)); + stubMethodEntered("duiAppletSettingsConstructor", params); +} + +void DuiAppletSettingsStub::duiAppletSettingsDestructor() +{ + stubMethodEntered("duiAppletSettingsDestructor"); +} + +const DuiSettingsLanguageBinary *DuiAppletSettingsStub::instanceSettingsBinary() const +{ + stubMethodEntered("instanceSettingsBinary"); + return stubReturnValue("instanceSettingsBinary"); +} + +const DuiSettingsLanguageBinary *DuiAppletSettingsStub::globalSettingsBinary() const +{ + stubMethodEntered("globalSettingsBinary"); + return stubReturnValue("globalSettingsBinary"); +} + +bool DuiAppletSettingsStub::hasSettings() const +{ + stubMethodEntered("hasSettings"); + return stubReturnValue("hasSettings"); +} + +DuiDataStore *DuiAppletSettingsStub::instanceDataStore() const +{ + stubMethodEntered("instanceDataStore"); + return stubReturnValue("instanceDataStore"); +} + +DuiDataStore *DuiAppletSettingsStub::globalDataStore() const +{ + stubMethodEntered("globalDataStore"); + return stubReturnValue("globalDataStore"); +} + +DuiDataAccess *DuiAppletSettingsStub::dataAccess() const +{ + stubMethodEntered("dataAccess"); + return stubReturnValue("dataAccess"); +} + +void DuiAppletSettingsStub::removeInstanceSettingValues() const +{ + stubMethodEntered("removeInstanceSettingValues"); +} + + +DuiAppletSettingsStub gDefaultDuiAppletSettingsStub; +DuiAppletSettingsStub *gDuiAppletSettingsStub = &gDefaultDuiAppletSettingsStub; + +DuiAppletSettings::DuiAppletSettings(const QString &metaDataFileName, const DuiAppletId &appletId) +{ + gDuiAppletSettingsStub->duiAppletSettingsConstructor(metaDataFileName, appletId); +} + +DuiAppletSettings::DuiAppletSettings(const QString &metaDataFileName, const QString &appletId) +{ + gDuiAppletSettingsStub->duiAppletSettingsConstructor(metaDataFileName, appletId); +} + + +DuiAppletSettings::~DuiAppletSettings() +{ + gDuiAppletSettingsStub->duiAppletSettingsDestructor(); +} + + +const DuiSettingsLanguageBinary * +DuiAppletSettings::instanceSettingsBinary() const +{ + return gDuiAppletSettingsStub->instanceSettingsBinary(); +} + + +const DuiSettingsLanguageBinary * +DuiAppletSettings::globalSettingsBinary() const +{ + return gDuiAppletSettingsStub->globalSettingsBinary(); +} + + +bool +DuiAppletSettings::hasSettings() const +{ + return gDuiAppletSettingsStub->hasSettings(); +} + + +DuiDataStore * +DuiAppletSettings::instanceDataStore() const +{ + return gDuiAppletSettingsStub->instanceDataStore(); +} + + +DuiDataStore * +DuiAppletSettings::globalDataStore() const +{ + return gDuiAppletSettingsStub->globalDataStore(); +} + + +DuiDataAccess * +DuiAppletSettings::dataAccess() const +{ + return gDuiAppletSettingsStub->dataAccess(); +} + + +void +DuiAppletSettings::removeInstanceSettingValues() const +{ + gDuiAppletSettingsStub->removeInstanceSettingValues(); +} + +#endif diff --git a/tests/stubs/duiappletsharedmutex_stub.h b/tests/stubs/duiappletsharedmutex_stub.h new file mode 100644 index 000000000..e06c56a06 --- /dev/null +++ b/tests/stubs/duiappletsharedmutex_stub.h @@ -0,0 +1,121 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETSHAREDMUTEXSTUB_H +#define DUIAPPLETSHAREDMUTEXSTUB_H + +#include +#include + +class DuiAppletSharedMutexStub : public StubBase +{ +public: + virtual void duiAppletSharedMutexStubConstructor(); + virtual void duiAppletSharedMutexStubDestructor(); + virtual bool init(const QString &key); + virtual bool lock(); + virtual bool unlock(); + virtual bool tryLock(); +}; + +void DuiAppletSharedMutexStub::duiAppletSharedMutexStubConstructor() +{ + stubMethodEntered("duiAppletSharedMutexStubConstructor"); +} + +void DuiAppletSharedMutexStub::duiAppletSharedMutexStubDestructor() +{ + stubMethodEntered("duiAppletSharedMutexStubDestructor"); +} + +bool +DuiAppletSharedMutexStub::init(const QString &key) +{ + QList params; + params.append(new Parameter(key)); + stubMethodEntered("init", params); + return stubReturnValue("init"); +} + + +bool +DuiAppletSharedMutexStub::lock() +{ + stubMethodEntered("lock"); + return stubReturnValue("lock"); +} + + +bool +DuiAppletSharedMutexStub::unlock() +{ + stubMethodEntered("unlock"); + return stubReturnValue("unlock"); +} + + +bool +DuiAppletSharedMutexStub::tryLock() +{ + stubMethodEntered("tryLock"); + return stubReturnValue("tryLock"); +} + +DuiAppletSharedMutexStub gDefaultDuiAppletSharedMutexStub; +DuiAppletSharedMutexStub *gDuiAppletSharedMutexStub = &gDefaultDuiAppletSharedMutexStub; + +DuiAppletSharedMutex::DuiAppletSharedMutex() +{ + gDuiAppletSharedMutexStub->duiAppletSharedMutexStubConstructor(); +} + +DuiAppletSharedMutex::~DuiAppletSharedMutex() +{ + gDuiAppletSharedMutexStub->duiAppletSharedMutexStubDestructor(); +} + + +bool +DuiAppletSharedMutex::init(const QString &key) +{ + return gDuiAppletSharedMutexStub->init(key); +} + + +bool +DuiAppletSharedMutex::lock() +{ + return gDuiAppletSharedMutexStub->lock(); +} + + +bool +DuiAppletSharedMutex::unlock() +{ + return gDuiAppletSharedMutexStub->unlock(); +} + + +bool +DuiAppletSharedMutex::tryLock() +{ + return gDuiAppletSharedMutexStub->tryLock(); +} + +#endif diff --git a/tests/stubs/duiapplication_stub.h b/tests/stubs/duiapplication_stub.h new file mode 100644 index 000000000..eb05d0d7c --- /dev/null +++ b/tests/stubs/duiapplication_stub.h @@ -0,0 +1,200 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLICATION_STUB +#define DUIAPPLICATION_STUB + +#include "duiapplication.h" +#include +#include + + +class DuiFeedbackPlayer; + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiApplicationStub : public StubBase +{ +public: + virtual void DuiApplicationConstructor(int &argc, char **argv); + virtual void DuiApplicationDestructor(); + virtual bool softwareRendering(); + virtual bool fullScreen(); + virtual bool showBoundingRect(); + virtual bool showFps(); + virtual bool showSize(); + virtual bool showPosition(); + virtual DuiApplicationWindow *applicationWindow(); + virtual void setApplicationWindow(DuiApplicationWindow *); + virtual DuiFeedbackPlayer *feedbackPlayer(); + +}; + +// 2. IMPLEMENT STUB +void DuiApplicationStub::DuiApplicationConstructor(int &argc, char **argv) +{ + Q_UNUSED(argc); + Q_UNUSED(argv); + +} +void DuiApplicationStub::DuiApplicationDestructor() +{ + +} +bool DuiApplicationStub::softwareRendering() +{ + /* + stubMethodEntered("softwareRendering"); + return stubReturnValue("softwareRendering"); + */ + return false; +} + +bool DuiApplicationStub::fullScreen() +{ + /* + stubMethodEntered("fullScreen"); + return stubReturnValue("fullScreen"); + */ + return false; +} + +bool DuiApplicationStub::showBoundingRect() +{ + /* + stubMethodEntered("showBoundingRect"); + return stubReturnValue("showBoundingRect"); + */ + return false; +} + +bool DuiApplicationStub::showFps() +{ + /* + stubMethodEntered("showFps"); + return stubReturnValue("showFps"); + */ + return false; +} + +bool DuiApplicationStub::showSize() +{ + /* + stubMethodEntered("showSize"); + return stubReturnValue("showSize"); + */ + return false; +} + +bool DuiApplicationStub::showPosition() +{ + /* + stubMethodEntered("showPosition"); + return stubReturnValue("showPosition"); + */ + return false; +} + +DuiApplicationWindow *DuiApplicationStub::applicationWindow() +{ + stubMethodEntered("applicationWindow"); + return stubReturnValue("applicationWindow"); +} + +void DuiApplicationStub::setApplicationWindow(DuiApplicationWindow *appWindow) +{ + QList params; + params.append(new Parameter(appWindow)); + stubMethodEntered("setApplicationWindow", params); +} + +DuiFeedbackPlayer *DuiApplicationStub::feedbackPlayer() +{ + stubMethodEntered("feedbackPlayer"); + return (DuiFeedbackPlayer *) NULL; +} + + +// 3. CREATE A STUB INSTANCE +DuiApplicationStub gDefaultDuiApplicationStub; +DuiApplicationStub *gDuiApplicationStub = &gDefaultDuiApplicationStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +// + +DuiFeedbackPlayer *DuiApplication::feedbackPlayer() +{ + return gDuiApplicationStub->feedbackPlayer(); +} + +DuiApplication::DuiApplication(int &argc, char **argv) + : QApplication(argc, argv), d_ptr(0) +{ + gDuiApplicationStub->DuiApplicationConstructor(argc, argv); +} + +DuiApplication::~DuiApplication() +{ + gDuiApplicationStub->DuiApplicationDestructor(); +} + +bool DuiApplication::softwareRendering() +{ + return gDuiApplicationStub->softwareRendering(); +} + +bool DuiApplication::fullScreen() +{ + return gDuiApplicationStub->fullScreen(); +} + +bool DuiApplication::showBoundingRect() +{ + return gDuiApplicationStub->showBoundingRect(); +} + +bool DuiApplication::showSize() +{ + return gDuiApplicationStub->showSize(); +} + + +bool DuiApplication::showPosition() +{ + return gDuiApplicationStub->showPosition(); +} + +bool DuiApplication::showFps() +{ + return gDuiApplicationStub->showFps(); +} + + +DuiApplicationWindow *DuiApplication::applicationWindow() +{ + return gDuiApplicationStub->applicationWindow(); +} + +void DuiApplication::setApplicationWindow(DuiApplicationWindow *appWin) +{ + gDuiApplicationStub->setApplicationWindow(appWin); +} + +#endif diff --git a/tests/stubs/duiapplicationmenu_stub.h b/tests/stubs/duiapplicationmenu_stub.h new file mode 100644 index 000000000..add1f439d --- /dev/null +++ b/tests/stubs/duiapplicationmenu_stub.h @@ -0,0 +1,55 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLICATIONMENU_STUB_H +#define DUIAPPLICATIONMENU_STUB_H + +#include +#include + +class DuiApplicationMenuStub : public StubBase +{ +public: + virtual void duiApplicationMenuConstructor(DuiWidgetController *parent = 0); + virtual void duiApplicationMenuDestructor(); +}; + +void DuiApplicationMenuStub::duiApplicationMenuConstructor(DuiWidgetController *parent) +{ + Q_UNUSED(parent); +} + +void DuiApplicationMenuStub::duiApplicationMenuDestructor() +{ +} + +DuiApplicationMenuStub gDefaultDuiApplicationMenuStub; +DuiApplicationMenuStub *gDuiApplicationMenuStub = &gDefaultDuiApplicationMenuStub; + +DuiApplicationMenu::DuiApplicationMenu(DuiWidgetController *parent) +{ + gDuiApplicationMenuStub->duiApplicationMenuConstructor(parent); +} + +DuiApplicationMenu::~DuiApplicationMenu() +{ + gDuiApplicationMenuStub->duiApplicationMenuDestructor(); +} + +#endif diff --git a/tests/stubs/duiapplicationmenuview_stub.h b/tests/stubs/duiapplicationmenuview_stub.h new file mode 100644 index 000000000..8cafb9f78 --- /dev/null +++ b/tests/stubs/duiapplicationmenuview_stub.h @@ -0,0 +1,131 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLICATIONMENUVIEW_STUB +#define DUIAPPLICATIONMENUVIEW_STUB + +#include "duiapplicationmenuview.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiApplicationMenuViewStub : public StubBase +{ +public: + virtual void DuiApplicationMenuViewConstructor(DuiApplicationMenu *controller); + virtual void DuiApplicationMenuViewDestructor(); + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + virtual QRectF boundingRect() const; + virtual void updateStyle(); + virtual void setGeometry(const QRectF &rect); + virtual QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint); + DuiApplicationMenuViewPrivate *d_ptr ; +}; + +// 2. IMPLEMENT STUB +void DuiApplicationMenuViewStub::DuiApplicationMenuViewConstructor(DuiApplicationMenu *controller) +{ + Q_UNUSED(controller); + +} +void DuiApplicationMenuViewStub::DuiApplicationMenuViewDestructor() +{ + +} +void DuiApplicationMenuViewStub::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + QList params; + params.append(new Parameter(painter)); + params.append(new Parameter(option)); + params.append(new Parameter(widget)); + stubMethodEntered("paint", params); +} + +QRectF DuiApplicationMenuViewStub::boundingRect() const +{ + stubMethodEntered("boundingRect"); + return stubReturnValue("boundingRect"); +} + +void DuiApplicationMenuViewStub::updateStyle() +{ + stubMethodEntered("updateStyle"); +} + +void DuiApplicationMenuViewStub::setGeometry(const QRectF &rect) +{ + QList params; + params.append(new Parameter(rect)); + stubMethodEntered("setGeometry", params); +} + +QSizeF DuiApplicationMenuViewStub::sizeHint(Qt::SizeHint which, const QSizeF &constraint) +{ + QList params; + params.append(new Parameter(which)); + params.append(new Parameter(constraint)); + stubMethodEntered("sizeHint", params); + return stubReturnValue(QString("sizeHint")); +} + + +// 3. CREATE A STUB INSTANCE +DuiApplicationMenuViewStub gDefaultDuiApplicationMenuViewStub; +DuiApplicationMenuViewStub *gDuiApplicationMenuViewStub = &gDefaultDuiApplicationMenuViewStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiApplicationMenuView::DuiApplicationMenuView(DuiApplicationMenu *controller) +{ + gDuiApplicationMenuViewStub->DuiApplicationMenuViewConstructor(controller); +} + +DuiApplicationMenuView::~DuiApplicationMenuView() +{ + gDuiApplicationMenuViewStub->DuiApplicationMenuViewDestructor(); +} + +void DuiApplicationMenuView::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + gDuiApplicationMenuViewStub->paint(painter, option, widget); +} + +QRectF DuiApplicationMenuView::boundingRect() const +{ + return gDuiApplicationMenuViewStub->boundingRect(); +} + +void DuiApplicationMenuView::updateStyle() +{ + gDuiApplicationMenuViewStub->updateStyle(); +} + +void DuiApplicationMenuView::setGeometry(const QRectF &rect) +{ + gDuiApplicationMenuViewStub->setGeometry(rect); +} + +QSizeF DuiApplicationMenuView::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const +{ + return gDuiApplicationMenuViewStub->sizeHint(which, constraint); +} + + +#endif diff --git a/tests/stubs/duiapplicationview_stub.h b/tests/stubs/duiapplicationview_stub.h new file mode 100644 index 000000000..8abcef6d7 --- /dev/null +++ b/tests/stubs/duiapplicationview_stub.h @@ -0,0 +1,123 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLICATIONVIEW_STUB_H +#define DUIAPPLICATIONVIEW_STUB_H + +#include +#include + +class DuiApplicationViewStub : public StubBase +{ +public: + virtual void duiApplicationViewConstructor(QGraphicsWidget *parent = 0); + virtual void duiApplicationViewDestructor(); + virtual void setWidget(QGraphicsWidget *widget); + virtual QGraphicsWidget *widget() const; + virtual QRectF boundingRect() const; + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0); +}; + +void DuiApplicationViewStub::duiApplicationViewConstructor(QGraphicsWidget *parent) +{ + Q_UNUSED(parent); +} + +void DuiApplicationViewStub::duiApplicationViewDestructor() +{ +} + +void DuiApplicationViewStub::setWidget(QGraphicsWidget *widget) +{ + Q_UNUSED(widget); + /* + QList params; + params.append( new Parameter(widget) ); + stubMethodEntered("setWidget", params); + */ +} + +QGraphicsWidget *DuiApplicationViewStub::widget() const +{ + /* + QList params; + stubMethodEntered("widget", params); + return stubReturnValue(QString("widget")); + */ + return new QGraphicsWidget(); +} + +QRectF DuiApplicationViewStub::boundingRect() const +{ + /* + QList params; + stubMethodEntered("boundingRect", params); + return stubReturnValue(QString("boundingRect")); + */ + return QRectF(0, 0, 0, 0); +} + +void DuiApplicationViewStub::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + Q_UNUSED(painter); + Q_UNUSED(option); + Q_UNUSED(widget); + /* + QList params; + params.append( new Parameter(painter) ); + params.append( new Parameter(option) ); + params.append( new Parameter(widget) ); + stubMethodEntered("paint", params); + */ +} + +DuiApplicationViewStub gDefaultDuiApplicationViewStub; +DuiApplicationViewStub *gDuiApplicationViewStub = &gDefaultDuiApplicationViewStub; + +DuiApplicationView::DuiApplicationView(QGraphicsWidget *parent) +{ + gDuiApplicationViewStub->duiApplicationViewConstructor(parent); +} + +DuiApplicationView::~DuiApplicationView() +{ + gDuiApplicationViewStub->duiApplicationViewDestructor(); +} + +void DuiApplicationView::setWidget(QGraphicsWidget *widget) +{ + gDuiApplicationViewStub->setWidget(widget); +} + +QGraphicsWidget *DuiApplicationView::widget() const +{ + return gDuiApplicationViewStub->widget(); +} + +QRectF DuiApplicationView::boundingRect() const +{ + return gDuiApplicationViewStub->boundingRect(); +} + +void DuiApplicationView::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + gDuiApplicationViewStub->paint(painter, option, widget); +} + +#endif diff --git a/tests/stubs/duibutton_stub.h b/tests/stubs/duibutton_stub.h new file mode 100644 index 000000000..dd12902b3 --- /dev/null +++ b/tests/stubs/duibutton_stub.h @@ -0,0 +1,282 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIBUTTON_STUB_H +#define DUIBUTTON_STUB_H + +#include +#include +#include +class DuiButtonStub + : public StubBase +{ +public: + virtual void duiButtonConstructor(DuiWidget *parent, const QString &viewType); + virtual void duiButtonDestructor(); + virtual void setIconID(const QString &iconID); + virtual const QString &iconID() const; + virtual void setToggledIconID(const QString &toggledIconID); + virtual const QString &toggledIconID() const; + virtual void setText(const QString &text); + virtual const QString &text() const; + virtual bool isTextVisible() const; + virtual void setTextVisible(bool textVisible); + virtual bool isIconVisible() const; + virtual void setIconVisible(bool iconVisible); + virtual void setView(DuiWidgetView *view); + virtual bool isCheckable() const; + virtual void setCheckable(bool buttonCheckable); + virtual bool isChecked() const; + virtual void setChecked(bool buttonChecked); + virtual void toggleStateChanged(); + virtual DuiButtonGroup *group() const; +}; + +void DuiButtonStub::duiButtonConstructor(DuiWidget *parent, const QString &viewType) +{ + Q_UNUSED(parent); + Q_UNUSED(viewType); +} + +void DuiButtonStub::duiButtonDestructor() +{ +} + +void DuiButtonStub::setIconID(const QString &iconID) +{ + QList params; + params.append(new Parameter(iconID)); + stubMethodEntered("setIconID", params); + Q_UNUSED(iconID); +} + +const QString &DuiButtonStub::iconID() const +{ + QList params; + stubMethodEntered("iconID", params); + return stubReturnValue(QString("iconID")); + QString *myIconID = new QString("iconID"); + return *myIconID; +} + +void DuiButtonStub::setToggledIconID(const QString &toggledIconID) +{ + QList params; + params.append(new Parameter(toggledIconID)); + stubMethodEntered("setToggledIconID", params); + Q_UNUSED(toggledIconID); + +} + +const QString &DuiButtonStub::toggledIconID() const +{ + QList params; + stubMethodEntered("toggledIconID", params); + return stubReturnValue(QString("toggledIconID")); + QString *myToggledIconID = new QString("toggledIconID"); + return *myToggledIconID; +} + +void DuiButtonStub::setText(const QString &text) +{ + QList params; + params.append(new Parameter(text)); + stubMethodEntered("setText", params); + Q_UNUSED(text); +} + +const QString &DuiButtonStub::text() const +{ + QList params; + stubMethodEntered("text", params); + return stubReturnValue(QString("text")); +} + +bool DuiButtonStub::isTextVisible() const +{ + QList params; + stubMethodEntered("isTextVisible", params); + return stubReturnValue(QString("isTextVisible")); +} + +void DuiButtonStub::setTextVisible(bool textVisible) +{ + QList params; + params.append(new Parameter(textVisible)); + stubMethodEntered("setTextVisible", params); + Q_UNUSED(textVisible); +} + +bool DuiButtonStub::isIconVisible() const +{ + QList params; + stubMethodEntered("isIconVisible", params); + return stubReturnValue(QString("isIconVisible")); +} + +void DuiButtonStub::setIconVisible(bool iconVisible) +{ + QList params; + params.append(new Parameter(iconVisible)); + stubMethodEntered("setIconVisible", params); + Q_UNUSED(iconVisible); +} +void DuiButtonStub::setView(DuiWidgetView *view) +{ + QList params; + params.append(new Parameter(view)); + stubMethodEntered("setView", params); + Q_UNUSED(view); +} + +bool DuiButtonStub::isCheckable() const +{ + QList params; + stubMethodEntered("isCheckable", params); + return stubReturnValue(QString("isCheckable")); +} + +void DuiButtonStub::setCheckable(bool buttonCheckable) +{ + QList params; + params.append(new Parameter(buttonCheckable)); + stubMethodEntered("setCheckable", params); + Q_UNUSED(buttonCheckable); +} + +bool DuiButtonStub::isChecked() const +{ + QList params; + stubMethodEntered("isChecked", params); + return stubReturnValue(QString("isChecked")); +} + +void DuiButtonStub::setChecked(bool buttonChecked) +{ + QList params; + params.append(new Parameter(buttonChecked)); + stubMethodEntered("setChecked", params); + Q_UNUSED(buttonChecked); +} + +void DuiButtonStub::toggleStateChanged() +{ + stubMethodEntered("toggleStateChanged"); +} +DuiButtonGroup *DuiButtonStub::group() const +{ + stubMethodEntered("group"); + return stubReturnValue("group"); +} +DuiButtonStub gDefaultDuiButtonStub; +DuiButtonStub *gDuiButtonStub = &gDefaultDuiButtonStub; + +DuiButton::DuiButton(DuiWidget *parent, const QString &viewType) +{ + gDuiButtonStub->duiButtonConstructor(parent, ""); + Q_UNUSED(viewType); +} + +DuiButton::~DuiButton() +{ + gDuiButtonStub->duiButtonDestructor(); +} + +void DuiButton::setIconID(const QString &iconID) +{ + gDuiButtonStub->setIconID(iconID); +} + +const QString &DuiButton::iconID() const +{ + return gDuiButtonStub->iconID(); +} + +void DuiButton::setToggledIconID(const QString &toggledIconID) +{ + gDuiButtonStub->setToggledIconID(toggledIconID); +} + +const QString &DuiButton::toggledIconID() const +{ + return gDuiButtonStub->toggledIconID(); +} + +void DuiButton::setText(const QString &text) +{ + gDuiButtonStub->setText(text); +} + +const QString &DuiButton::text() const +{ + return gDuiButtonStub->text(); +} + +void DuiButton::setView(DuiWidgetView *view) +{ + gDuiButtonStub->setView(view); +} + +bool DuiButton::isTextVisible() const +{ + return gDuiButtonStub->isTextVisible(); +} + +void DuiButton::setTextVisible(bool textVisible) +{ + gDuiButtonStub->setTextVisible(textVisible); +} + +bool DuiButton::isIconVisible() const +{ + return gDuiButtonStub->isIconVisible(); +} + +void DuiButton::setIconVisible(bool iconVisible) +{ + gDuiButtonStub->setIconVisible(iconVisible); +} +bool DuiButton::isCheckable() const +{ + return gDuiButtonStub->isCheckable(); +} + +void DuiButton::setCheckable(bool buttonCheckable) +{ + gDuiButtonStub->setCheckable(buttonCheckable); +} + +bool DuiButton::isChecked() const +{ + return gDuiButtonStub->isChecked(); +} + +void DuiButton::setChecked(bool buttonChecked) +{ + gDuiButtonStub->setChecked(buttonChecked); +} +void DuiButton::toggleStateChanged() +{ + gDuiButtonStub->toggleStateChanged(); +} +DuiButtonGroup *DuiButton::group() const +{ + return gDuiButtonStub->group(); +} +#endif diff --git a/tests/stubs/duibuttoniconview_stub.h b/tests/stubs/duibuttoniconview_stub.h new file mode 100644 index 000000000..f0164cfcf --- /dev/null +++ b/tests/stubs/duibuttoniconview_stub.h @@ -0,0 +1,166 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIBUTTONICONVIEW_STUB_H +#define DUIBUTTONICONVIEW_STUB_H + +#include +#include + +class DuiButtonIconViewStub : public StubBase +{ +public: + virtual void duiButtonIconViewConstructor(DuiButton *controller); + virtual void duiButtonIconViewDestructor(); + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0); + virtual void setGeometry(const QRectF &rect); + virtual QRectF boundingRect() const; + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + virtual void updateData(const int index); + virtual void timelineValueChanged(qreal value); + virtual void registerStyleAttributes(DuiStyleDescription &description); + +}; + +void DuiButtonIconViewStub::duiButtonIconViewConstructor(DuiButton *controller) +{ + Q_UNUSED(controller); +} + +void DuiButtonIconViewStub::duiButtonIconViewDestructor() +{ +} + +void DuiButtonIconViewStub::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + QList params; + params.append(new Parameter(painter)); + params.append(new Parameter(option)); + params.append(new Parameter(widget)); + stubMethodEntered("paint", params); +} + +void DuiButtonIconViewStub::setGeometry(const QRectF &rect) +{ + QList params; + params.append(new Parameter(rect)); + stubMethodEntered("setGeometry", params); +} + +QRectF DuiButtonIconViewStub::boundingRect() const +{ + QList params; + stubMethodEntered("boundingRect", params); + return stubReturnValue(QString("boundingRect")); +} + +void DuiButtonIconViewStub::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + QList params; + params.append(new Parameter(event)); + stubMethodEntered("mousePressEvent", params); +} + +void DuiButtonIconViewStub::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + QList params; + params.append(new Parameter(event)); + stubMethodEntered("mouseReleaseEvent", params); +} + +void DuiButtonIconViewStub::updateData(const int index) +{ + QList params; + params.append(new Parameter(index)); + stubMethodEntered("updateData", params); +} + +void DuiButtonIconViewStub::timelineValueChanged(qreal value) +{ + QList params; + params.append(new Parameter(value)); + stubMethodEntered("timelineValueChanged", params); +} + +void DuiButtonIconViewStub::registerStyleAttributes(DuiStyleDescription &description) +{ + QList params; + params.append(new Parameter(description)); + stubMethodEntered("registerStyleAttributes", params); +} + +DuiButtonIconViewStub gDefaultDuiButtonIconViewStub; +DuiButtonIconViewStub *gDuiButtonIconViewStub = &gDefaultDuiButtonIconViewStub; + +DuiButtonIconView::DuiButtonIconView(DuiButton *controller) +{ + gDuiButtonIconViewStub->duiButtonIconViewConstructor(controller); +} + +DuiButtonIconView::~DuiButtonIconView() +{ + gDuiButtonIconViewStub->duiButtonIconViewDestructor(); +} + +void DuiButtonIconView::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + gDuiButtonIconViewStub->paint(painter, option, widget); +} + +void DuiButtonIconView::setGeometry(const QRectF &rect) +{ + gDuiButtonIconViewStub->setGeometry(rect); +} + +QRectF DuiButtonIconView::boundingRect() const +{ + return gDuiButtonIconViewStub->boundingRect(); +} + +void DuiButtonIconView::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + gDuiButtonIconViewStub->mousePressEvent(event); +} + +void DuiButtonIconView::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + gDuiButtonIconViewStub->mouseReleaseEvent(event); +} + +void DuiButtonIconView::updateData(const int index) +{ + gDuiButtonIconViewStub->updateData(index); +} + +void DuiButtonIconView::timelineValueChanged(qreal value) +{ + gDuiButtonIconViewStub->timelineValueChanged(value); +} + +void DuiButtonIconView::registerStyleAttributes(DuiStyleDescription &description) +{ + gDuiButtonIconViewStub->registerStyleAttributes(description); +} + +void DuiButtonIconView::styleUpdated() +{ +} + +#endif diff --git a/tests/stubs/duibuttonview_stub.h b/tests/stubs/duibuttonview_stub.h new file mode 100644 index 000000000..ab4439207 --- /dev/null +++ b/tests/stubs/duibuttonview_stub.h @@ -0,0 +1,204 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIBUTTONVIEW_STUB +#define DUIBUTTONVIEW_STUB + +#include "duibuttonview.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiButtonViewStub : public StubBase +{ +public: + virtual void DuiButtonViewConstructor(DuiButton *controller); + virtual void DuiButtonViewDestructor(); + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + virtual void setGeometry(const QRectF &rect); + virtual QRectF boundingRect() const; + virtual QPainterPath shape() const; + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + virtual void updateData(const int index); + virtual void timelineValueChanged(qreal value); + virtual void registerStyleAttributes(DuiStyleDescription &description); + + DuiButtonViewPrivate *d_ptr ; +}; + +// 2. IMPLEMENT STUB +void DuiButtonViewStub::DuiButtonViewConstructor(DuiButton *controller) +{ + Q_UNUSED(controller); + +} +void DuiButtonViewStub::DuiButtonViewDestructor() +{ + +} +void DuiButtonViewStub::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + QList params; + params.append(new Parameter(painter)); + params.append(new Parameter(option)); + params.append(new Parameter(widget)); + stubMethodEntered("paint", params); +} + +void DuiButtonViewStub::setGeometry(const QRectF &rect) +{ + QList params; + params.append(new Parameter(rect)); + stubMethodEntered("setGeometry", params); +} + +QRectF DuiButtonViewStub::boundingRect() const +{ + stubMethodEntered("boundingRect"); + return stubReturnValue("boundingRect"); +} + +QPainterPath DuiButtonViewStub::shape() const +{ + stubMethodEntered("shape"); + return stubReturnValue("shape"); +} + +void DuiButtonViewStub::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + QList params; + params.append(new Parameter(event)); + stubMethodEntered("mousePressEvent", params); +} + +void DuiButtonViewStub::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + QList params; + params.append(new Parameter(event)); + stubMethodEntered("mouseReleaseEvent", params); +} + +void DuiButtonViewStub::updateData(const int index) +{ + QList params; + params.append(new Parameter(index)); + stubMethodEntered("updateData", params); +} + +void DuiButtonViewStub::timelineValueChanged(qreal value) +{ + QList params; + params.append(new Parameter(value)); + stubMethodEntered("timelineValueChanged", params); +} + +void DuiButtonViewStub::registerStyleAttributes(DuiStyleDescription &description) +{ + QList params; + params.append(new Parameter(description)); + stubMethodEntered("registerStyleAttributes", params); +} + + + +// 3. CREATE A STUB INSTANCE +DuiButtonViewStub gDefaultDuiButtonViewStub; +DuiButtonViewStub *gDuiButtonViewStub = &gDefaultDuiButtonViewStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiButtonView::DuiButtonView(DuiButton *controller) +{ + gDuiButtonViewStub->DuiButtonViewConstructor(controller); +} + +DuiButtonView::~DuiButtonView() +{ + gDuiButtonViewStub->DuiButtonViewDestructor(); +} + +void DuiButtonView::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + gDuiButtonViewStub->paint(painter, option, widget); +} + +void DuiButtonView::setGeometry(const QRectF &rect) +{ + gDuiButtonViewStub->setGeometry(rect); +} + +QRectF DuiButtonView::boundingRect() const +{ + return gDuiButtonViewStub->boundingRect(); +} + +QPainterPath DuiButtonView::shape() const +{ + return gDuiButtonViewStub->shape(); +} + +void DuiButtonView::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + gDuiButtonViewStub->mousePressEvent(event); +} + +void DuiButtonView::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + gDuiButtonViewStub->mouseReleaseEvent(event); +} + +void DuiButtonView::updateData(const int index) +{ + gDuiButtonViewStub->updateData(index); +} + +void DuiButtonView::timelineValueChanged(qreal value) +{ + gDuiButtonViewStub->timelineValueChanged(value); +} + + +void DuiButtonView::resizeEvent(QGraphicsSceneResizeEvent *) +{ +} + +void DuiButtonView::scalePNGMode() +{ +} + +void DuiButtonView::updateSize() +{ +} + +void DuiButtonView::resize(qreal, qreal) +{ +} + +void DuiButtonView::registerStyleAttributes(DuiStyleDescription &description) +{ + Q_UNUSED(description); +} + +void DuiButtonView::styleUpdated() +{ +} + +#endif diff --git a/tests/stubs/duicasketgridlayout_stub.h b/tests/stubs/duicasketgridlayout_stub.h new file mode 100644 index 000000000..f81a0851f --- /dev/null +++ b/tests/stubs/duicasketgridlayout_stub.h @@ -0,0 +1,288 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUICASKETGRIDLAYOUT_STUB +#define DUICASKETGRIDLAYOUT_STUB + +#include "duicasketgridlayout.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiCasketGridLayoutStub : public StubBase +{ +public: + virtual void DuiCasketGridLayoutConstructor(QGraphicsLayoutItem *parent); + virtual void DuiCasketGridLayoutDestructor(); + virtual void insertAt(QGraphicsLayoutItem *item, int index); + virtual void insertAt(QGraphicsLayoutItem *item, int row, int column); + virtual QGraphicsLayoutItem *removeAndCompressAt(int index); + virtual QGraphicsLayoutItem *removeAndCompressAt(int row, int column); + virtual QGraphicsLayoutItem *replaceAt(int index, QGraphicsLayoutItem *item); + virtual QGraphicsLayoutItem *replaceAt(int row, int column, QGraphicsLayoutItem *item); + virtual void moveItem(int from, int to); + virtual void moveItem(int fromRow, int fromColumn, int toRow, int toColumn); + virtual void setColumnCount(int count); + virtual void setRowCount(int count); + virtual void DuiCasketGridLayoutConstructor(const DuiCasketGridLayout &); + virtual void updateStyle(); + virtual void addItemsToLayout(QList const &items); + virtual QList layoutParameters(); + virtual QSizeF layoutSizeHint(Qt::SizeHint which, const QSizeF &constraint) const; + +}; + +// 2. IMPLEMENT STUB +void DuiCasketGridLayoutStub::DuiCasketGridLayoutConstructor(QGraphicsLayoutItem *parent) +{ + Q_UNUSED(parent); + +} +void DuiCasketGridLayoutStub::DuiCasketGridLayoutDestructor() +{ + +} + +void DuiCasketGridLayoutStub::insertAt(QGraphicsLayoutItem *item, int index) +{ + QList params; + params.append(new Parameter(item)); + params.append(new Parameter(index)); + stubMethodEntered("insertAt", params); +} + +void DuiCasketGridLayoutStub::insertAt(QGraphicsLayoutItem *item, int row, int column) +{ + QList params; + params.append(new Parameter(item)); + params.append(new Parameter(row)); + params.append(new Parameter(column)); + stubMethodEntered("insertAt", params); +} + +QGraphicsLayoutItem *DuiCasketGridLayoutStub::removeAndCompressAt(int index) +{ + QList params; + params.append(new Parameter(index)); + stubMethodEntered("removeAndCompressAt", params); + return stubReturnValue("removeAndCompressAt"); +} + +QGraphicsLayoutItem *DuiCasketGridLayoutStub::removeAndCompressAt(int row, int column) +{ + QList params; + params.append(new Parameter(row)); + params.append(new Parameter(column)); + stubMethodEntered("removeAndCompressAt", params); + return stubReturnValue("removeAndCompressAt"); +} + +QGraphicsLayoutItem *DuiCasketGridLayoutStub::replaceAt(int index, QGraphicsLayoutItem *item) +{ + QList params; + params.append(new Parameter(index)); + params.append(new Parameter(item)); + stubMethodEntered("replaceAt", params); + return stubReturnValue("replaceAt"); +} + +QGraphicsLayoutItem *DuiCasketGridLayoutStub::replaceAt(int row, int column, QGraphicsLayoutItem *item) +{ + QList params; + params.append(new Parameter(row)); + params.append(new Parameter(column)); + params.append(new Parameter(item)); + stubMethodEntered("replaceAt", params); + return stubReturnValue("replaceAt"); +} + +void DuiCasketGridLayoutStub::moveItem(int from, int to) +{ + QList params; + params.append(new Parameter(from)); + params.append(new Parameter(to)); + stubMethodEntered("moveItem", params); +} + +void DuiCasketGridLayoutStub::moveItem(int fromRow, int fromColumn, int toRow, int toColumn) +{ + QList params; + params.append(new Parameter(fromRow)); + params.append(new Parameter(fromColumn)); + params.append(new Parameter(toRow)); + params.append(new Parameter(toColumn)); + stubMethodEntered("moveItem", params); +} + +void DuiCasketGridLayoutStub::setColumnCount(int count) +{ + QList params; + params.append(new Parameter(count)); + stubMethodEntered("setColumnCount", params); +} + +void DuiCasketGridLayoutStub::setRowCount(int count) +{ + QList params; + params.append(new Parameter(count)); + stubMethodEntered("setRowCount", params); +} + + + +void DuiCasketGridLayoutStub::updateStyle() +{ + stubMethodEntered("updateStyle"); +} + +void DuiCasketGridLayoutStub::addItemsToLayout(QList const &items) +{ + QList params; + params.append(new Parameter< QList >(items)); + stubMethodEntered("addItemsToLayout", params); +} + +QList DuiCasketGridLayoutStub::layoutParameters() +{ + stubMethodEntered("layoutParameters"); + return stubReturnValue >(QString("layoutParameters")); +} + +QSizeF DuiCasketGridLayoutStub::layoutSizeHint(Qt::SizeHint which, const QSizeF &constraint) const +{ + QList params; + params.append(new Parameter(which)); + params.append(new Parameter(constraint)); + stubMethodEntered("layoutSizeHint", params); + return stubReturnValue(QString("layoutSizeHint")); +} + +void DuiCasketGridLayoutStub::DuiCasketGridLayoutConstructor(const DuiCasketGridLayout &) +{ + +} + +// 3. CREATE A STUB INSTANCE +DuiCasketGridLayoutStub gDefaultDuiCasketGridLayoutStub; +DuiCasketGridLayoutStub *gDuiCasketGridLayoutStub = &gDefaultDuiCasketGridLayoutStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiCasketGridLayout::DuiCasketGridLayout(QGraphicsLayoutItem *parent): + DuiAbstractLayout(), + QGraphicsGridLayout(), + d_ptr(0) +{ + gDuiCasketGridLayoutStub->DuiCasketGridLayoutConstructor(parent); +} + +DuiCasketGridLayout::~DuiCasketGridLayout() +{ + gDuiCasketGridLayoutStub->DuiCasketGridLayoutDestructor(); +} + +void DuiCasketGridLayout::insertAt(QGraphicsLayoutItem *item, int index) +{ + gDuiCasketGridLayoutStub->insertAt(item, index); +} + +void DuiCasketGridLayout::insertAt(QGraphicsLayoutItem *item, int row, int column) +{ + gDuiCasketGridLayoutStub->insertAt(item, row, column); +} + +QGraphicsLayoutItem *DuiCasketGridLayout::removeAndCompressAt(int index) +{ + return gDuiCasketGridLayoutStub->removeAndCompressAt(index); +} + +QGraphicsLayoutItem *DuiCasketGridLayout::removeAndCompressAt(int row, int column) +{ + return gDuiCasketGridLayoutStub->removeAndCompressAt(row, column); +} + +QGraphicsLayoutItem *DuiCasketGridLayout::replaceAt(int index, QGraphicsLayoutItem *item) +{ + return gDuiCasketGridLayoutStub->replaceAt(index, item); +} + +QGraphicsLayoutItem *DuiCasketGridLayout::replaceAt(int row, int column, QGraphicsLayoutItem *item) +{ + return gDuiCasketGridLayoutStub->replaceAt(row, column, item); +} + +void DuiCasketGridLayout::moveItem(int from, int to) +{ + gDuiCasketGridLayoutStub->moveItem(from, to); +} + +void DuiCasketGridLayout::moveItem(int fromRow, int fromColumn, int toRow, int toColumn) +{ + gDuiCasketGridLayoutStub->moveItem(fromRow, fromColumn, toRow, toColumn); +} + +void DuiCasketGridLayout::setColumnCount(int count) +{ + gDuiCasketGridLayoutStub->setColumnCount(count); +} + +void DuiCasketGridLayout::setRowCount(int count) +{ + gDuiCasketGridLayoutStub->setRowCount(count); +} + + +void DuiCasketGridLayout::updateStyle() +{ + gDuiCasketGridLayoutStub->updateStyle(); +} + +void DuiCasketGridLayout::addItemsToLayout(QList const &items) +{ + gDuiCasketGridLayoutStub->addItemsToLayout(items); +} + +QList DuiCasketGridLayout::layoutParameters() +{ + return gDuiCasketGridLayoutStub->layoutParameters(); +} + +QSizeF DuiCasketGridLayout::layoutSizeHint(Qt::SizeHint which, const QSizeF &constraint) const +{ + return gDuiCasketGridLayoutStub->layoutSizeHint(which, constraint); + +} + + +DuiCasketGridLayout::DuiCasketGridLayout(const DuiCasketGridLayout &) : + DuiAbstractLayout(), + QGraphicsGridLayout(), + d_ptr(0) +{ +} + +DuiCasketGridLayout &DuiCasketGridLayout::operator=(const DuiCasketGridLayout &) +{ + static DuiCasketGridLayout bla; + return bla; +} + + +#endif diff --git a/tests/stubs/duicollator_stub.h b/tests/stubs/duicollator_stub.h new file mode 100644 index 000000000..662fd6cb8 --- /dev/null +++ b/tests/stubs/duicollator_stub.h @@ -0,0 +1,135 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUICOLLATOR_STUB +#define DUICOLLATOR_STUB + +#include "duicollator.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiCollatorStub : public StubBase +{ +public: + virtual void DuiCollatorConstructor(); + virtual void DuiCollatorConstructor(const DuiLocale &locale); + virtual void DuiCollatorConstructor(const DuiCollator &other); + virtual void DuiCollatorDestructor(); + virtual bool operator()(const QString &s1, const QString &s2) const; + virtual DuiLocale::Comparison compare(const QString &first, const QString &second); + virtual DuiLocale::Comparison compare(DuiLocale &locale, const QString &first, const QString &second); +}; + +// 2. IMPLEMENT STUB +void DuiCollatorStub::DuiCollatorConstructor() +{ + +} +void DuiCollatorStub::DuiCollatorConstructor(const DuiLocale &locale) +{ + Q_UNUSED(locale); + +} +void DuiCollatorStub::DuiCollatorConstructor(const DuiCollator &other) +{ + Q_UNUSED(other); + +} +void DuiCollatorStub::DuiCollatorDestructor() +{ + +} +bool DuiCollatorStub::operator()(const QString &s1, const QString &s2) const +{ + QList params; + params.append(new Parameter(s1)); + params.append(new Parameter(s2)); + stubMethodEntered("operator()", params); + return stubReturnValue("operator()"); +} + +DuiLocale::Comparison DuiCollatorStub::compare(const QString &first, const QString &second) +{ + QList params; + params.append(new Parameter(first)); + params.append(new Parameter(second)); + stubMethodEntered("compare", params); + return stubReturnValue("compare"); +} + +DuiLocale::Comparison DuiCollatorStub::compare(DuiLocale &locale, const QString &first, const QString &second) +{ + QList params; + params.append(new Parameter(locale)); + params.append(new Parameter(first)); + params.append(new Parameter(second)); + stubMethodEntered("compare", params); + return stubReturnValue("compare"); +} + + + +// 3. CREATE A STUB INSTANCE +DuiCollatorStub gDefaultDuiCollatorStub; +DuiCollatorStub *gDuiCollatorStub = &gDefaultDuiCollatorStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiCollator::DuiCollator() : + d_ptr(0) +{ + gDuiCollatorStub->DuiCollatorConstructor(); +} + +DuiCollator::DuiCollator(const DuiLocale &locale) : + d_ptr(0) +{ + gDuiCollatorStub->DuiCollatorConstructor(locale); +} + +DuiCollator::DuiCollator(const DuiCollator &other) : + d_ptr(0) +{ + gDuiCollatorStub->DuiCollatorConstructor(other); +} + +DuiCollator::~DuiCollator() +{ + gDuiCollatorStub->DuiCollatorDestructor(); +} + +bool DuiCollator::operator()(const QString &s1, const QString &s2) const +{ + return gDuiCollatorStub->operator()(s1, s2); +} + +DuiLocale::Comparison DuiCollator::compare(const QString &first, const QString &second) +{ + return gDuiCollatorStub->compare(first, second); +} + +DuiLocale::Comparison DuiCollator::compare(DuiLocale &locale, const QString &first, const QString &second) +{ + return gDuiCollatorStub->compare(locale, first, second); +} + + +#endif diff --git a/tests/stubs/duidesktopentry_stub.h b/tests/stubs/duidesktopentry_stub.h new file mode 100644 index 000000000..9b8e74502 --- /dev/null +++ b/tests/stubs/duidesktopentry_stub.h @@ -0,0 +1,437 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIDESKTOPENTRY_STUB +#define DUIDESKTOPENTRY_STUB + +#include "duidesktopentry.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiDesktopEntryStub : public StubBase +{ +public: + virtual void DuiDesktopEntryConstructor(const QString &fileName); + virtual void DuiDesktopEntryDestructor(); + virtual QString fileName() const; + virtual bool isValid() const; + virtual uint hash() const; + virtual QString type() const; + virtual QString version() const; + virtual QString name() const; + virtual QString nameUnlocalized() const; + virtual QString genericName() const; + virtual bool noDisplay() const; + virtual QString comment() const; + virtual QString icon() const; + virtual bool hidden() const; + virtual QStringList onlyShowIn() const; + virtual QStringList notShowIn() const; + virtual QString tryExec() const; + virtual QString exec() const; + virtual QString path() const; + virtual bool terminal() const; + virtual QStringList mimeType() const; + virtual QStringList categories() const; + virtual bool startupNotify() const; + virtual QString startupWMClass() const; + virtual QString url() const; + virtual QString xMaemoService() const; + virtual QString value(const QString &key) const; + virtual QString value(const QString &group, const QString &key) const; + virtual bool contains(const QString &key) const; + virtual bool contains(const QString &group, const QString &key) const; + virtual void DuiDesktopEntryConstructor(DuiDesktopEntryPrivate &dd); + + void stubSetKeyValue(const QString &key, const QString &value) { + keyValuePairs.insert(key, value); + } + void stubSetFilenameForDesktopEntry(DuiDesktopEntry *entry, const QString &filename) { + filenames.insert(entry, filename); + } + QString stubFilenameForDesktopEntry(DuiDesktopEntry *entry) { + return filenames.value(entry); + } + +private: + mutable QMap keyValuePairs; + mutable QHash filenames; +}; + +// 2. IMPLEMENT STUB +void DuiDesktopEntryStub::DuiDesktopEntryConstructor(const QString &fileName) +{ + Q_UNUSED(fileName); + +} +void DuiDesktopEntryStub::DuiDesktopEntryDestructor() +{ + +} +QString DuiDesktopEntryStub::fileName() const +{ + stubMethodEntered("fileName"); + return stubReturnValue("fileName"); +} + +bool DuiDesktopEntryStub::isValid() const +{ + stubMethodEntered("isValid"); + return stubReturnValue("isValid"); +} + +uint DuiDesktopEntryStub::hash() const +{ + stubMethodEntered("hash"); + return stubReturnValue("hash"); +} + +QString DuiDesktopEntryStub::type() const +{ + stubMethodEntered("type"); + return stubReturnValue("type"); +} + +QString DuiDesktopEntryStub::version() const +{ + stubMethodEntered("version"); + return stubReturnValue("version"); +} + +QString DuiDesktopEntryStub::name() const +{ + stubMethodEntered("name"); + return stubReturnValue("name"); +} + +QString DuiDesktopEntryStub::nameUnlocalized() const +{ + stubMethodEntered("nameUnlocalized"); + return stubReturnValue("nameUnlocalized"); +} + +QString DuiDesktopEntryStub::genericName() const +{ + stubMethodEntered("genericName"); + return stubReturnValue("genericName"); +} + +bool DuiDesktopEntryStub::noDisplay() const +{ + stubMethodEntered("noDisplay"); + return stubReturnValue("noDisplay"); +} + +QString DuiDesktopEntryStub::comment() const +{ + stubMethodEntered("comment"); + return stubReturnValue("comment"); +} + +QString DuiDesktopEntryStub::icon() const +{ + stubMethodEntered("icon"); + return stubReturnValue("icon"); +} + +bool DuiDesktopEntryStub::hidden() const +{ + stubMethodEntered("hidden"); + return stubReturnValue("hidden"); +} + +QStringList DuiDesktopEntryStub::onlyShowIn() const +{ + stubMethodEntered("onlyShowIn"); + return stubReturnValue("onlyShowIn"); +} + +QStringList DuiDesktopEntryStub::notShowIn() const +{ + stubMethodEntered("notShowIn"); + return stubReturnValue("notShowIn"); +} + +QString DuiDesktopEntryStub::tryExec() const +{ + stubMethodEntered("tryExec"); + return stubReturnValue("tryExec"); +} + +QString DuiDesktopEntryStub::exec() const +{ + stubMethodEntered("exec"); + return stubReturnValue("exec"); +} + +QString DuiDesktopEntryStub::path() const +{ + stubMethodEntered("path"); + return stubReturnValue("path"); +} + +bool DuiDesktopEntryStub::terminal() const +{ + stubMethodEntered("terminal"); + return stubReturnValue("terminal"); +} + +QStringList DuiDesktopEntryStub::mimeType() const +{ + stubMethodEntered("mimeType"); + return stubReturnValue("mimeType"); +} + +QStringList DuiDesktopEntryStub::categories() const +{ + stubMethodEntered("categories"); + return stubReturnValue("categories"); +} + +bool DuiDesktopEntryStub::startupNotify() const +{ + stubMethodEntered("startupNotify"); + return stubReturnValue("startupNotify"); +} + +QString DuiDesktopEntryStub::startupWMClass() const +{ + stubMethodEntered("startupWMClass"); + return stubReturnValue("startupWMClass"); +} + +QString DuiDesktopEntryStub::url() const +{ + stubMethodEntered("url"); + return stubReturnValue("url"); +} + +QString DuiDesktopEntryStub::xMaemoService() const +{ + stubMethodEntered("xMaemoService"); + return stubReturnValue("xMaemoService"); +} + +QString DuiDesktopEntryStub::value(const QString &key) const +{ + QList params; + params.append(new Parameter(key)); + stubMethodEntered("value", params); + return keyValuePairs.value(key); +} + +QString DuiDesktopEntryStub::value(const QString &group, const QString &key) const +{ + QList params; + params.append(new Parameter(group)); + params.append(new Parameter(key)); + stubMethodEntered("value", params); + return keyValuePairs.value(group + '/' + key); +} + +bool DuiDesktopEntryStub::contains(const QString &key) const +{ + QList params; + params.append(new Parameter(key)); + stubMethodEntered("contains", params); + return keyValuePairs.contains(key); +} + +bool DuiDesktopEntryStub::contains(const QString &group, const QString &key) const +{ + QList params; + params.append(new Parameter(group)); + params.append(new Parameter(key)); + stubMethodEntered("contains", params); + return keyValuePairs.contains(group + '/' + key); +} + +void DuiDesktopEntryStub::DuiDesktopEntryConstructor(DuiDesktopEntryPrivate &dd) +{ + Q_UNUSED(dd); + +} + + +// 3. CREATE A STUB INSTANCE +DuiDesktopEntryStub gDefaultDuiDesktopEntryStub; +DuiDesktopEntryStub *gDuiDesktopEntryStub = &gDefaultDuiDesktopEntryStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiDesktopEntry::DuiDesktopEntry(const QString &fileName) : d_ptr(NULL) +{ + gDuiDesktopEntryStub->DuiDesktopEntryConstructor(fileName); + gDuiDesktopEntryStub->stubSetFilenameForDesktopEntry(this, fileName); +} + +DuiDesktopEntry::~DuiDesktopEntry() +{ + gDuiDesktopEntryStub->DuiDesktopEntryDestructor(); +} + +QString DuiDesktopEntry::fileName() const +{ + return gDuiDesktopEntryStub->fileName().isEmpty() ? gDuiDesktopEntryStub->stubFilenameForDesktopEntry(const_cast(this)) : gDuiDesktopEntryStub->fileName(); +} + +bool DuiDesktopEntry::isValid() const +{ + return gDuiDesktopEntryStub->isValid(); +} + +uint DuiDesktopEntry::hash() const +{ + return gDuiDesktopEntryStub->hash(); +} + +QString DuiDesktopEntry::type() const +{ + return gDuiDesktopEntryStub->type(); +} + +QString DuiDesktopEntry::version() const +{ + return gDuiDesktopEntryStub->version(); +} + +QString DuiDesktopEntry::name() const +{ + return gDuiDesktopEntryStub->name(); +} + +QString DuiDesktopEntry::nameUnlocalized() const +{ + return gDuiDesktopEntryStub->nameUnlocalized(); +} + +QString DuiDesktopEntry::genericName() const +{ + return gDuiDesktopEntryStub->genericName(); +} + +bool DuiDesktopEntry::noDisplay() const +{ + return gDuiDesktopEntryStub->noDisplay(); +} + +QString DuiDesktopEntry::comment() const +{ + return gDuiDesktopEntryStub->comment(); +} + +QString DuiDesktopEntry::icon() const +{ + return gDuiDesktopEntryStub->icon(); +} + +bool DuiDesktopEntry::hidden() const +{ + return gDuiDesktopEntryStub->hidden(); +} + +QStringList DuiDesktopEntry::onlyShowIn() const +{ + return gDuiDesktopEntryStub->onlyShowIn(); +} + +QStringList DuiDesktopEntry::notShowIn() const +{ + return gDuiDesktopEntryStub->notShowIn(); +} + +QString DuiDesktopEntry::tryExec() const +{ + return gDuiDesktopEntryStub->tryExec(); +} + +QString DuiDesktopEntry::exec() const +{ + return gDuiDesktopEntryStub->exec(); +} + +QString DuiDesktopEntry::path() const +{ + return gDuiDesktopEntryStub->path(); +} + +bool DuiDesktopEntry::terminal() const +{ + return gDuiDesktopEntryStub->terminal(); +} + +QStringList DuiDesktopEntry::mimeType() const +{ + return gDuiDesktopEntryStub->mimeType(); +} + +QStringList DuiDesktopEntry::categories() const +{ + return gDuiDesktopEntryStub->categories(); +} + +bool DuiDesktopEntry::startupNotify() const +{ + return gDuiDesktopEntryStub->startupNotify(); +} + +QString DuiDesktopEntry::startupWMClass() const +{ + return gDuiDesktopEntryStub->startupWMClass(); +} + +QString DuiDesktopEntry::url() const +{ + return gDuiDesktopEntryStub->url(); +} + +QString DuiDesktopEntry::xMaemoService() const +{ + return gDuiDesktopEntryStub->xMaemoService(); +} + +QString DuiDesktopEntry::value(const QString &key) const +{ + return gDuiDesktopEntryStub->value(key); +} + +QString DuiDesktopEntry::value(const QString &group, const QString &key) const +{ + return gDuiDesktopEntryStub->value(group, key); +} + +bool DuiDesktopEntry::contains(const QString &key) const +{ + return gDuiDesktopEntryStub->contains(key); +} + +bool DuiDesktopEntry::contains(const QString &group, const QString &key) const +{ + return gDuiDesktopEntryStub->contains(group, key); +} + +DuiDesktopEntry::DuiDesktopEntry(DuiDesktopEntryPrivate &dd) : d_ptr(&dd) +{ + gDuiDesktopEntryStub->DuiDesktopEntryConstructor(dd); +} + + +#endif diff --git a/tests/stubs/duideviceprofile_stub.h b/tests/stubs/duideviceprofile_stub.h new file mode 100644 index 000000000..07c6b329e --- /dev/null +++ b/tests/stubs/duideviceprofile_stub.h @@ -0,0 +1,174 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIDEVICEPROFILE_STUB +#define DUIDEVICEPROFILE_STUB + +#include "duideviceprofile.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiDeviceProfileStub : public StubBase +{ +public: + virtual DuiDeviceProfile *instance(); + virtual QString name() const; + virtual QSize resolution() const; + virtual QRectF screenRectF() const; + virtual int width() const; + virtual int height() const; + virtual QSize pixelsPerInch() const; + virtual Dui::Orientation orientation() const; + virtual void setOrientationAngle(DuiDeviceProfile::DeviceOrientationAngle angle); + virtual void DuiDeviceProfileDestructor(); + virtual void orientationChanged(); + DuiDeviceProfilePrivate *d_ptr ; +}; + +// 2. IMPLEMENT STUB +DuiDeviceProfile *DuiDeviceProfileStub::instance() +{ + stubMethodEntered("instance"); + return stubReturnValue("instance"); +} + +QString DuiDeviceProfileStub::name() const +{ + stubMethodEntered("name"); + return stubReturnValue("name"); +} + +QSize DuiDeviceProfileStub::resolution() const +{ + stubMethodEntered("resolution"); + return stubReturnValue("resolution"); +} + +QRectF DuiDeviceProfileStub::screenRectF() const +{ + stubMethodEntered("screenRectF"); + return stubReturnValue("screenRectF"); +} + +int DuiDeviceProfileStub::width() const +{ + stubMethodEntered("width"); + return stubReturnValue("width"); +} + +int DuiDeviceProfileStub::height() const +{ + stubMethodEntered("height"); + return stubReturnValue("height"); +} + +QSize DuiDeviceProfileStub::pixelsPerInch() const +{ + stubMethodEntered("pixelsPerInch"); + return stubReturnValue("pixelsPerInch"); +} + +Dui::Orientation DuiDeviceProfileStub::orientation() const +{ + stubMethodEntered("orientation"); + return stubReturnValue("orientation"); +} + +void DuiDeviceProfileStub::orientationChanged() +{ +} + + +void DuiDeviceProfileStub::setOrientationAngle(DuiDeviceProfile::DeviceOrientationAngle angle) +{ + QList params; + params.append(new Parameter(angle)); + stubMethodEntered("setOrientationAngle", params); +} + +void DuiDeviceProfileStub::DuiDeviceProfileDestructor() +{ + +} + + +// 3. CREATE A STUB INSTANCE +DuiDeviceProfileStub gDefaultDuiDeviceProfileStub; +DuiDeviceProfileStub *gDuiDeviceProfileStub = &gDefaultDuiDeviceProfileStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiDeviceProfile *DuiDeviceProfile::instance() +{ + return gDuiDeviceProfileStub->instance(); +} + +QString DuiDeviceProfile::name() const +{ + return gDuiDeviceProfileStub->name(); +} + +QSize DuiDeviceProfile::resolution() const +{ + return gDuiDeviceProfileStub->resolution(); +} + +QRectF DuiDeviceProfile::screenRectF() const +{ + return gDuiDeviceProfileStub->screenRectF(); +} + +int DuiDeviceProfile::width() const +{ + return gDuiDeviceProfileStub->width(); +} + +int DuiDeviceProfile::height() const +{ + return gDuiDeviceProfileStub->height(); +} + +QSize DuiDeviceProfile::pixelsPerInch() const +{ + return gDuiDeviceProfileStub->pixelsPerInch(); +} + +Dui::Orientation DuiDeviceProfile::orientation() const +{ + return gDuiDeviceProfileStub->orientation(); +} + +void DuiDeviceProfile::setOrientationAngle(DeviceOrientationAngle angle) +{ + gDuiDeviceProfileStub->setOrientationAngle(angle); +} + +DuiDeviceProfile::~DuiDeviceProfile() +{ + gDuiDeviceProfileStub->DuiDeviceProfileDestructor(); +} + +void DuiDeviceProfile::orientationChanged() +{ + gDuiDeviceProfileStub->orientationChanged(); +} + +#endif diff --git a/tests/stubs/duifeedback_stub.h b/tests/stubs/duifeedback_stub.h new file mode 100644 index 000000000..1b1e69f81 --- /dev/null +++ b/tests/stubs/duifeedback_stub.h @@ -0,0 +1,79 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIFEEDBACKSTUB_H +#define DUIFEEDBACKSTUB_H + +#include "duifeedback.h" +#include + +#include +#include + +class DuiFeedbackStub : public StubBase +{ +public: + virtual void DuiFeedbackConstructor(QObject *parent); + virtual void DuiFeedbackDestructor(); + virtual QString name() const; + virtual void play(); +}; + +void DuiFeedbackStub::DuiFeedbackConstructor(QObject *) +{ +} + +void DuiFeedbackStub::DuiFeedbackDestructor() +{ +} + +QString DuiFeedbackStub::name() const +{ + stubMethodEntered("name"); + return stubReturnValue("name"); +} + +void DuiFeedbackStub::play() +{ + stubMethodEntered("play"); +} + +DuiFeedbackStub gDefaultDuiFeedbackStub; +DuiFeedbackStub *gDuiFeedbackStub = &gDefaultDuiFeedbackStub; + +DuiFeedback::DuiFeedback(const QString &, QObject *) : d_ptr(0) +{ +} + +DuiFeedback::~DuiFeedback() +{ +} + +QString DuiFeedback::name() const +{ + return gDuiFeedbackStub->name(); +} + +void DuiFeedback::play() const +{ + gDuiFeedbackStub->play(); +} + +#endif + diff --git a/tests/stubs/duifeedbackplayer_stub.h b/tests/stubs/duifeedbackplayer_stub.h new file mode 100644 index 000000000..06caa135e --- /dev/null +++ b/tests/stubs/duifeedbackplayer_stub.h @@ -0,0 +1,63 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIFEEDBACKPLAYER_STUB +#define DUIFEEDBACKPLAYER_STUB + +#include +#include +#include "duifeedbackplayerprivate_stub.h" + +class DuiFeedbackPlayerStub : public StubBase +{ +public: + virtual void DuiFeedbackPlayerConstructor(QObject *parent = 0); + virtual void DuiFeedbackPlayerDestructor(); +}; + +void DuiFeedbackPlayerStub::DuiFeedbackPlayerConstructor(QObject *parent) +{ + Q_UNUSED(parent); +} + +void DuiFeedbackPlayerStub::DuiFeedbackPlayerDestructor() +{ +} + +DuiFeedbackPlayerStub gDefaultDuiFeedbackPlayerStub; +DuiFeedbackPlayerStub *gDuiFeedbackPlayerStub = &gDefaultDuiFeedbackPlayerStub; + + +DuiFeedbackPlayer::DuiFeedbackPlayer(QObject *parent) + : QObject(parent), d_ptr(0) +{ + gDuiFeedbackPlayerStub->DuiFeedbackPlayerConstructor(parent); +} + +DuiFeedbackPlayer::~DuiFeedbackPlayer() +{ + gDuiFeedbackPlayerStub->DuiFeedbackPlayerDestructor(); +} + +void DuiFeedbackPlayer::play(const QString &feedbackName) +{ + Q_UNUSED(feedbackName); +} + +#endif diff --git a/tests/stubs/duifeedbackplayerprivate_stub.h b/tests/stubs/duifeedbackplayerprivate_stub.h new file mode 100644 index 000000000..239d04e2c --- /dev/null +++ b/tests/stubs/duifeedbackplayerprivate_stub.h @@ -0,0 +1,69 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIFEEDBACKPLAYERPRIVATE_STUB +#define DUIFEEDBACKPLAYERPRIVATE_STUB + +#include +#include + +class DuiFeedbackPlayerPrivateStub : public StubBase +{ +public: + virtual void DuiFeedbackPlayerPrivateConstructor(QObject *parent = 0); + virtual void DuiFeedbackPlayerPrivateDestructor(); + virtual bool init(const QString &applicationName); +}; + +void DuiFeedbackPlayerPrivateStub::DuiFeedbackPlayerPrivateConstructor(QObject *parent) +{ + Q_UNUSED(parent); +} + +void DuiFeedbackPlayerPrivateStub::DuiFeedbackPlayerPrivateDestructor() +{ +} + +bool DuiFeedbackPlayerPrivateStub::init(const QString &applicationName) +{ + Q_UNUSED(applicationName); + stubMethodEntered("init"); + return stubReturnValue("init"); +} + +DuiFeedbackPlayerPrivateStub gDefaultDuiFeedbackPlayerPrivateStub; +DuiFeedbackPlayerPrivateStub *gDuiFeedbackPlayerPrivateStub = &gDefaultDuiFeedbackPlayerPrivateStub; + + +DuiFeedbackPlayerPrivate::DuiFeedbackPlayerPrivate(QObject *parent) + : QObject(parent) +{ + gDuiFeedbackPlayerPrivateStub->DuiFeedbackPlayerPrivateConstructor(parent); +} + +DuiFeedbackPlayerPrivate::~DuiFeedbackPlayerPrivate() +{ + gDuiFeedbackPlayerPrivateStub->DuiFeedbackPlayerPrivateDestructor(); +} + +bool DuiFeedbackPlayerPrivate::init(const QString &applicationName) +{ + return gDuiFeedbackPlayerPrivateStub->init(applicationName); +} +#endif diff --git a/tests/stubs/duigridlayout_stub.h b/tests/stubs/duigridlayout_stub.h new file mode 100644 index 000000000..d5f8ab3e0 --- /dev/null +++ b/tests/stubs/duigridlayout_stub.h @@ -0,0 +1,148 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIGRIDLAYOUT_STUB +#define DUIGRIDLAYOUT_STUB + +#include "duigridlayout.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiGridLayoutStub : public StubBase +{ +public: + virtual void DuiGridLayoutConstructor(QGraphicsLayoutItem *parent); + virtual void DuiGridLayoutDestructor(); + virtual void setMargin(int margin); + virtual void setPadding(int padding); + virtual void updateStyle(); + virtual void addItemsToLayout(QList const &items); + virtual QSizeF layoutSizeHint(Qt::SizeHint which, const QSizeF &constraint) const; + + //virtual void Q_DISABLE_COPYConstructor(DuiGridLayout); + DuiGridLayoutPrivate *d_ptr ; +}; + +// 2. IMPLEMENT STUB +void DuiGridLayoutStub::DuiGridLayoutConstructor(QGraphicsLayoutItem *parent) +{ + Q_UNUSED(parent); + +} +void DuiGridLayoutStub::DuiGridLayoutDestructor() +{ + +} +void DuiGridLayoutStub::setMargin(int margin) +{ + QList params; + params.append(new Parameter(margin)); + stubMethodEntered("setMargin", params); +} + +void DuiGridLayoutStub::setPadding(int padding) +{ + QList params; + params.append(new Parameter(padding)); + stubMethodEntered("setPadding", params); +} + +void DuiGridLayoutStub::updateStyle() +{ + stubMethodEntered("updateStyle"); +} + +void DuiGridLayoutStub::addItemsToLayout(QList const &items) +{ + QList params; + params.append(new Parameter< QList >(items)); + stubMethodEntered("addItemsToLayout", params); +} + +QSizeF DuiGridLayoutStub::layoutSizeHint(Qt::SizeHint which, const QSizeF &constraint) const +{ + QList params; + params.append(new Parameter(which)); + params.append(new Parameter(constraint)); + stubMethodEntered("layoutSizeHint", params); + return stubReturnValue(QString("layoutSizeHint")); +} + +/* +void DuiGridLayoutStub::Q_DISABLE_COPYConstructor(DuiGridLayout) { + +} +*/ + +// 3. CREATE A STUB INSTANCE +DuiGridLayoutStub gDefaultDuiGridLayoutStub; +DuiGridLayoutStub *gDuiGridLayoutStub = &gDefaultDuiGridLayoutStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiGridLayout::DuiGridLayout(QGraphicsLayoutItem *parent) : d_ptr(0) +{ + gDuiGridLayoutStub->DuiGridLayoutConstructor(parent); +} + +DuiGridLayout::~DuiGridLayout() +{ + gDuiGridLayoutStub->DuiGridLayoutDestructor(); +} + +void DuiGridLayout::setMargin(int margin) +{ + gDuiGridLayoutStub->setMargin(margin); +} + +void DuiGridLayout::setPadding(int padding) +{ + gDuiGridLayoutStub->setPadding(padding); +} + +void DuiGridLayout::updateStyle() +{ + gDuiGridLayoutStub->updateStyle(); +} +void DuiGridLayout::addItemsToLayout(QList const &items) +{ + gDuiGridLayoutStub->addItemsToLayout(items); +} + + +QSizeF DuiGridLayout::layoutSizeHint(Qt::SizeHint which, const QSizeF &constraint) const +{ + return gDuiGridLayoutStub->layoutSizeHint(which, constraint); + +} + +QList DuiGridLayout::layoutParameters() +{ + QList params; + return params; +} +/* +DuiGridLayout::Q_DISABLE_COPY(DuiGridLayout) { + gDuiGridLayoutStub->Q_DISABLE_COPYConstructor(); +} +*/ + +#endif diff --git a/tests/stubs/duiimagewidget_stub.h b/tests/stubs/duiimagewidget_stub.h new file mode 100644 index 000000000..531ad74d5 --- /dev/null +++ b/tests/stubs/duiimagewidget_stub.h @@ -0,0 +1,273 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIIMAGEWIDGET_STUB +#define DUIIMAGEWIDGET_STUB + +#include "duiimagewidget.h" +#include +#include + + +// 1. DECLARE STUB +class DuiImageWidgetStub : public StubBase +{ +public: + virtual void DuiImageWidgetStubConstructor(QGraphicsWidget *parent); + virtual void DuiImageWidgetStubDestructor(); + virtual void setImageName(const QString &imageName); + virtual void setTargetSize(const QSizeF &size); + virtual void setZoomFactor(float factor); + virtual void setZoomFactor(float fx, float fy); + virtual void setAspectRatioMode(Qt::AspectRatioMode mode); + virtual void setCropSize(const QSizeF &size, const QPointF &topLeft = QPointF(-1.0, -1.0)); + virtual void setBorders(float left, float top, float right, float bottom); + virtual void setBackgroundColor(const QColor &color); + virtual void setBackgroundOpacity(const float opacity); + virtual void setImage(const QImage &image); + virtual void setPixmap(const QPixmap &pixmap); + + virtual QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const; + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + + DuiImageWidgetPrivate *d_ptr ; +}; + +// 2. IMPLEMENT STUB +void DuiImageWidgetStub::DuiImageWidgetStubConstructor(QGraphicsWidget *parent) +{ + Q_UNUSED(parent); + +} +void DuiImageWidgetStub::DuiImageWidgetStubDestructor() +{ +} + +void DuiImageWidgetStub::setImageName(const QString &imageName) +{ + QList params; + params.append(new Parameter(imageName)); + stubMethodEntered("setImageName", params); +} + +void DuiImageWidgetStub::setTargetSize(const QSizeF &size) +{ + QList params; + params.append(new Parameter(size)); + stubMethodEntered("setTargetSize", params); +} + +void DuiImageWidgetStub::setZoomFactor(float factor) +{ + QList params; + params.append(new Parameter(factor)); + stubMethodEntered("setZoomFactor", params); +} + +void DuiImageWidgetStub::setZoomFactor(float fx, float fy) +{ + QList params; + params.append(new Parameter(fx)); + params.append(new Parameter(fy)); + stubMethodEntered("setZoomFactor", params); +} + +void DuiImageWidgetStub::setAspectRatioMode(Qt::AspectRatioMode mode) +{ + QList params; + params.append(new Parameter(mode)); + stubMethodEntered("setAspectRatioMode", params); +} + +void DuiImageWidgetStub::setCropSize(const QSizeF &size, const QPointF &topLeft) +{ + QList params; + params.append(new Parameter(size)); + params.append(new Parameter(topLeft)); + stubMethodEntered("setCropSize", params); +} + +void DuiImageWidgetStub::setBorders(float left, float top, float right, float bottom) +{ + QList params; + params.append(new Parameter(left)); + params.append(new Parameter(top)); + params.append(new Parameter(right)); + params.append(new Parameter(bottom)); + stubMethodEntered("setBorders", params); +} + +void DuiImageWidgetStub::setBackgroundColor(const QColor &color) +{ + QList params; + params.append(new Parameter(color)); + stubMethodEntered("setBackgroundColor", params); +} + +void DuiImageWidgetStub::setBackgroundOpacity(const float opacity) +{ + QList params; + params.append(new Parameter(opacity)); + stubMethodEntered("setBackgroundOpacity", params); +} + +void DuiImageWidgetStub::setImage(const QImage &image) +{ + QList params; + params.append(new Parameter(image)); + stubMethodEntered("setImage", params); +} + +void DuiImageWidgetStub::setPixmap(const QPixmap &pixmap) +{ + QList params; + params.append(new Parameter(pixmap)); + stubMethodEntered("setPixmap", params); +} + +QSizeF DuiImageWidgetStub::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const +{ + QList params; + params.append(new Parameter(which)); + params.append(new Parameter(constraint)); + stubMethodEntered("sizeHint", params); + return stubReturnValue("sizeHint"); +} + +void DuiImageWidgetStub::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + QList params; + params.append(new Parameter(event)); + stubMethodEntered("mousePressEvent", params); +} + +void DuiImageWidgetStub::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + QList params; + params.append(new Parameter(event)); + stubMethodEntered("mouseReleaseEvent", params); +} + + +// 3. CREATE A STUB INSTANCE +DuiImageWidgetStub gDefaultDuiImageWidgetStub; +DuiImageWidgetStub *gDuiImageWidgetStub = &gDefaultDuiImageWidgetStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiImageWidget::DuiImageWidget(DuiWidget *parent) +{ + gDuiImageWidgetStub->DuiImageWidgetStubConstructor(parent); +} + +DuiImageWidget::DuiImageWidget(const QString &imageName, DuiWidget *parent) +{ + Q_UNUSED(imageName); + gDuiImageWidgetStub->DuiImageWidgetStubConstructor(parent); +} + +DuiImageWidget::DuiImageWidget(const QImage *image, DuiWidget *parent) +{ + Q_UNUSED(image); + gDuiImageWidgetStub->DuiImageWidgetStubConstructor(parent); +} + +DuiImageWidget::DuiImageWidget(const QPixmap *pixmap, DuiWidget *parent) +{ + Q_UNUSED(pixmap); + gDuiImageWidgetStub->DuiImageWidgetStubConstructor(parent); +} + +DuiImageWidget::~DuiImageWidget() +{ + gDuiImageWidgetStub->DuiImageWidgetStubDestructor(); +} + +void DuiImageWidget::setImageName(const QString &imageName) +{ + gDuiImageWidgetStub->setImageName(imageName); +} + +void DuiImageWidget::setTargetSize(const QSizeF &size) +{ + gDuiImageWidgetStub->setTargetSize(size); +} + +void DuiImageWidget::setZoomFactor(float factor) +{ + gDuiImageWidgetStub->setZoomFactor(factor); +} + +void DuiImageWidget::setZoomFactor(float fx, float fy) +{ + gDuiImageWidgetStub->setZoomFactor(fx, fy); +} + +void DuiImageWidget::setAspectRatioMode(Qt::AspectRatioMode mode) +{ + gDuiImageWidgetStub->setAspectRatioMode(mode); +} + +void DuiImageWidget::setCropSize(const QSizeF &size, const QPointF &topLeft) +{ + gDuiImageWidgetStub->setCropSize(size, topLeft); +} + +void DuiImageWidget::setBorders(float left, float top, float right, float bottom) +{ + gDuiImageWidgetStub->setBorders(left, top, right, bottom); +} + +void DuiImageWidget::setBackgroundColor(const QColor &color) +{ + gDuiImageWidgetStub->setBackgroundColor(color); +} + +void DuiImageWidget::setBackgroundOpacity(const float opacity) +{ + gDuiImageWidgetStub->setBackgroundOpacity(opacity); +} + +void DuiImageWidget::setImage(const QImage &image) +{ + gDuiImageWidgetStub->setImage(image); +} + +void DuiImageWidget::setPixmap(const QPixmap &pixmap) +{ + gDuiImageWidgetStub->setPixmap(pixmap); +} + +QSizeF DuiImageWidget::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const +{ + return gDuiImageWidgetStub->sizeHint(which, constraint); +} + +void DuiImageWidget::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + gDuiImageWidgetStub->mousePressEvent(event); +} + +void DuiImageWidget::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + gDuiImageWidgetStub->mouseReleaseEvent(event); +} + +#endif diff --git a/tests/stubs/duilinearlayout_stub.h b/tests/stubs/duilinearlayout_stub.h new file mode 100644 index 000000000..57c14d2ec --- /dev/null +++ b/tests/stubs/duilinearlayout_stub.h @@ -0,0 +1,174 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUILINEARLAYOUT_STUB +#define DUILINEARLAYOUT_STUB + +#include "duilinearlayout.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiLinearLayoutStub : public StubBase +{ +public: + virtual void DuiLinearLayoutConstructor(Qt::Orientation orientation, QGraphicsLayoutItem *parent); + virtual void DuiLinearLayoutDestructor(); + virtual DuiLayoutFactory::Type type(); + virtual void setMargin(int margin); + virtual void setPadding(int padding); + virtual QSizeF layoutSizeHint(Qt::SizeHint which, const QSizeF &constraint) const; + virtual void addItemsToLayout(QList const &items); + virtual void updateStyle(); + virtual QList layoutParameters(); + virtual void DuiLinearLayoutConstructor(const DuiLinearLayout &); + DuiLinearLayoutPrivate *d_ptr ; +}; + +// 2. IMPLEMENT STUB +void DuiLinearLayoutStub::DuiLinearLayoutConstructor(Qt::Orientation orientation, QGraphicsLayoutItem *parent) +{ + Q_UNUSED(orientation); + Q_UNUSED(parent); + +} +void DuiLinearLayoutStub::DuiLinearLayoutDestructor() +{ + +} +DuiLayoutFactory::Type DuiLinearLayoutStub::type() +{ + stubMethodEntered("type"); + return stubReturnValue("type"); +} + +void DuiLinearLayoutStub::setMargin(int margin) +{ + QList params; + params.append(new Parameter(margin)); + stubMethodEntered("setMargin", params); +} + +void DuiLinearLayoutStub::setPadding(int padding) +{ + QList params; + params.append(new Parameter(padding)); + stubMethodEntered("setPadding", params); +} + +QSizeF DuiLinearLayoutStub::layoutSizeHint(Qt::SizeHint which, const QSizeF &constraint) const +{ + QList params; + params.append(new Parameter(which)); + params.append(new Parameter(constraint)); + stubMethodEntered("layoutSizeHint", params); + return stubReturnValue("layoutSizeHint"); +} + +void DuiLinearLayoutStub::addItemsToLayout(QList const &items) +{ + QList params; + params.append(new Parameter const & >(items)); + stubMethodEntered("addItemsToLayout", params); +} + +void DuiLinearLayoutStub::updateStyle() +{ + stubMethodEntered("updateStyle"); +} + +QList DuiLinearLayoutStub::layoutParameters() +{ + stubMethodEntered("layoutParameters"); + return stubReturnValue >("layoutParameters"); +} + +void DuiLinearLayoutStub::DuiLinearLayoutConstructor(const DuiLinearLayout &) +{ + +} + + +// 3. CREATE A STUB INSTANCE +DuiLinearLayoutStub gDefaultDuiLinearLayoutStub; +DuiLinearLayoutStub *gDuiLinearLayoutStub = &gDefaultDuiLinearLayoutStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiLinearLayout::DuiLinearLayout(Qt::Orientation orientation, QGraphicsLayoutItem *parent): d_ptr(0) +{ + gDuiLinearLayoutStub->DuiLinearLayoutConstructor(orientation, parent); +} + +DuiLinearLayout::~DuiLinearLayout() +{ + gDuiLinearLayoutStub->DuiLinearLayoutDestructor(); +} + +DuiLayoutFactory::Type DuiLinearLayout::type() +{ + return gDuiLinearLayoutStub->type(); +} + +void DuiLinearLayout::setMargin(int margin) +{ + gDuiLinearLayoutStub->setMargin(margin); +} + +void DuiLinearLayout::setPadding(int padding) +{ + gDuiLinearLayoutStub->setPadding(padding); +} + +QSizeF DuiLinearLayout::layoutSizeHint(Qt::SizeHint which, const QSizeF &constraint) const +{ + return gDuiLinearLayoutStub->layoutSizeHint(which, constraint); +} + +void DuiLinearLayout::addItemsToLayout(QList const &items) +{ + gDuiLinearLayoutStub->addItemsToLayout(items); +} + +void DuiLinearLayout::updateStyle() +{ + gDuiLinearLayoutStub->updateStyle(); +} + +QList DuiLinearLayout::layoutParameters() +{ + return gDuiLinearLayoutStub->layoutParameters(); +} + +DuiLinearLayout::DuiLinearLayout(const DuiLinearLayout &): + DuiAbstractLayout(), + QGraphicsLinearLayout(), + d_ptr(0) +{ +} + +DuiLinearLayout &DuiLinearLayout::operator=(const DuiLinearLayout &) +{ + static DuiLinearLayout bla(Qt::Horizontal); + return bla; +} + + +#endif diff --git a/tests/stubs/duilocale_stub.h b/tests/stubs/duilocale_stub.h new file mode 100644 index 000000000..23bead017 --- /dev/null +++ b/tests/stubs/duilocale_stub.h @@ -0,0 +1,914 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUILOCALE_STUB +#define DUILOCALE_STUB + +#include "duilocale.h" +#include "duicollator_stub.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiLocaleStub : public StubBase +{ +public: + virtual DuiLocale *createSystemDuiLocale(); + virtual DuiLocale createCLocale(); + virtual void DuiLocaleConstructor(QObject *parent); + virtual void DuiLocaleConstructor(const QString &localeName, QObject *parent); + virtual void DuiLocaleConstructor(const DuiLocale &other, QObject *parent); + virtual void DuiLocaleDestructor(); + virtual DuiLocale operatorEquals(const DuiLocale &other); + virtual void setDefault(const DuiLocale &locale); + virtual bool isValid() const; + virtual void setCategoryLocale(DuiLocale::Category category, const QString &localeName); + virtual void setCollation(DuiLocale::Collation collation); + virtual DuiLocale::Collation collation() const; + virtual void setCalendar(DuiLocale::Calendar calendar); + virtual DuiLocale::Calendar calendar() const; + virtual DuiCollator collator() const; + virtual QString languageEndonym() const; + virtual QString countryEndonym() const; + virtual QString language() const; + virtual QString country() const; + virtual QString script() const; + virtual QString variant() const; + virtual QString name() const; + virtual Qt::LayoutDirection textDirection() const; + virtual QString categoryLanguage(DuiLocale::Category category) const; + virtual QString categoryCountry(DuiLocale::Category category) const; + virtual QString categoryVariant(DuiLocale::Category category) const; + virtual QString categoryName(DuiLocale::Category category) const; + virtual QString formatNumber(qlonglong i) const; + virtual QString formatNumber(short i) const; + virtual QString formatNumber(int i) const; + virtual QString formatNumber(double i, int precision) const; + virtual QString formatNumber(float i) const; + virtual QString formatPercent(double i, int decimals) const; + virtual QString formatCurrency(double amount, const QString ¤cy) const; + virtual QString formatDateTime(const QDateTime &dateTime, DuiLocale::DateType dateType, DuiLocale::TimeType timeType, DuiLocale::Calendar calendarType) const; + virtual QString formatDateTime(const QDateTime &dateTime, DuiLocale::Calendar calendarType) const; + virtual QString formatDateTime(const DuiCalendar &duiCalendar, DuiLocale::DateType datetype, DuiLocale::TimeType timetype) const; + virtual QString formatDateTimeICU(const QDateTime &dateTime, const QString &formatString) const; + virtual QString formatDateTimeICU(const DuiCalendar &duiCalendar, const QString &formatString) const; + virtual QString formatDateTime(const QDateTime &dateTime, const QString &formatString) const; + virtual QString formatDateTime(const DuiCalendar &duiCalendar, const QString &formatString) const; + virtual QString monthName(const DuiCalendar &duiCalendar, int monthNumber) const; + virtual QString monthName(const DuiCalendar &duiCalendar, int monthNumber, DuiLocale::DateSymbolContext context, DuiLocale::DateSymbolLength symbolLength) const; + virtual QString weekdayName(const DuiCalendar &duiCalendar, int weekday) const; + virtual QString weekdayName(const DuiCalendar &duiCalendar, int weekday, DuiLocale::DateSymbolContext context, DuiLocale::DateSymbolLength symbolLength) const; + virtual void installCategoryCatalog(DuiLocale::Category category, const QString &name); + virtual void removeCategoryCatalog(DuiLocale::Category category, const QString &name); + virtual void copyCatalogsFrom(const DuiLocale &other); + virtual bool hasCategoryCatalog(DuiLocale::Category category, const QString &name); + virtual void installTrCatalog(const QString &name); + virtual QString translate(const char *context, const char *sourceText, const char *comment, int n); + virtual void setDataPaths(const QStringList &dataPaths); + virtual void setDataPath(const QString &dataPath); + virtual void setTranslationPaths(const QStringList &paths); + virtual void addTranslationPath(const QString &path); + virtual void removeTranslationPath(const QString &path); + virtual QStringList translationPaths(); + virtual void connectSettings(); + virtual void disconnectSettings(); + virtual void insertTrToQCoreApp(); + virtual void removeTrFromQCoreApp(); + virtual DuiLocale getDefault(); + virtual bool operator==(const DuiLocale &other) const; + virtual bool operator!=(const DuiLocale &other) const; + virtual void refreshSettings(); +}; + +// 2. IMPLEMENT STUB +DuiLocale *DuiLocaleStub::createSystemDuiLocale() +{ + stubMethodEntered("createSystemDuiLocale"); + return stubReturnValue("createSystemDuiLocale"); +} + +DuiLocale DuiLocaleStub::createCLocale() +{ + stubMethodEntered("createCLocale"); + return stubReturnValue("createCLocale"); +} + +void DuiLocaleStub::DuiLocaleConstructor(QObject *parent) +{ + Q_UNUSED(parent); + +} +void DuiLocaleStub::DuiLocaleConstructor(const QString &localeName, QObject *parent) +{ + Q_UNUSED(localeName); + Q_UNUSED(parent); + +} +void DuiLocaleStub::DuiLocaleConstructor(const DuiLocale &other, QObject *parent) +{ + Q_UNUSED(other); + Q_UNUSED(parent); + +} +void DuiLocaleStub::DuiLocaleDestructor() +{ + +} +DuiLocale DuiLocaleStub::operatorEquals(const DuiLocale &other) +{ + QList params; + params.append(new Parameter(other)); + stubMethodEntered("operator=", params); + return stubReturnValue("operator="); +} + +void DuiLocaleStub::setDefault(const DuiLocale &locale) +{ + QList params; + params.append(new Parameter(locale)); + stubMethodEntered("setDefault", params); +} + +bool DuiLocaleStub::isValid() const +{ + stubMethodEntered("isValid"); + return stubReturnValue("isValid"); +} + +void DuiLocaleStub::setCategoryLocale(DuiLocale::Category category, const QString &localeName) +{ + QList params; + params.append(new Parameter(category)); + params.append(new Parameter(localeName)); + stubMethodEntered("setCategoryLocale", params); +} + +void DuiLocaleStub::setCollation(DuiLocale::Collation collation) +{ + QList params; + params.append(new Parameter(collation)); + stubMethodEntered("setCollation", params); +} + +DuiLocale::Collation DuiLocaleStub::collation() const +{ + stubMethodEntered("collation"); + return stubReturnValue("collation"); +} + +void DuiLocaleStub::setCalendar(DuiLocale::Calendar calendar) +{ + QList params; + params.append(new Parameter(calendar)); + stubMethodEntered("setCalendar", params); +} + +DuiLocale::Calendar DuiLocaleStub::calendar() const +{ + stubMethodEntered("calendar"); + return stubReturnValue("calendar"); +} + +DuiCollator DuiLocaleStub::collator() const +{ + stubMethodEntered("collator"); + return stubReturnValue("collator"); +} + +QString DuiLocaleStub::languageEndonym() const +{ + stubMethodEntered("languageEndonym"); + return stubReturnValue("languageEndonym"); +} + +QString DuiLocaleStub::countryEndonym() const +{ + stubMethodEntered("countryEndonym"); + return stubReturnValue("countryEndonym"); +} + +QString DuiLocaleStub::language() const +{ + stubMethodEntered("language"); + return stubReturnValue("language"); +} + +QString DuiLocaleStub::country() const +{ + stubMethodEntered("country"); + return stubReturnValue("country"); +} + +QString DuiLocaleStub::script() const +{ + stubMethodEntered("script"); + return stubReturnValue("script"); +} + +QString DuiLocaleStub::variant() const +{ + stubMethodEntered("variant"); + return stubReturnValue("variant"); +} + +QString DuiLocaleStub::name() const +{ + stubMethodEntered("name"); + return stubReturnValue("name"); +} + +Qt::LayoutDirection DuiLocaleStub::textDirection() const +{ + stubMethodEntered("textDirection"); + return stubReturnValue("textDirection"); +} + +QString DuiLocaleStub::categoryLanguage(DuiLocale::Category category) const +{ + QList params; + params.append(new Parameter(category)); + stubMethodEntered("categoryLanguage", params); + return stubReturnValue("categoryLanguage"); +} + +QString DuiLocaleStub::categoryCountry(DuiLocale::Category category) const +{ + QList params; + params.append(new Parameter(category)); + stubMethodEntered("categoryCountry", params); + return stubReturnValue("categoryCountry"); +} + +QString DuiLocaleStub::categoryVariant(DuiLocale::Category category) const +{ + QList params; + params.append(new Parameter(category)); + stubMethodEntered("categoryVariant", params); + return stubReturnValue("categoryVariant"); +} + +QString DuiLocaleStub::categoryName(DuiLocale::Category category) const +{ + QList params; + params.append(new Parameter(category)); + stubMethodEntered("categoryName", params); + return stubReturnValue("categoryName"); +} + +QString DuiLocaleStub::formatNumber(qlonglong i) const +{ + QList params; + params.append(new Parameter(i)); + stubMethodEntered("formatNumber", params); + return stubReturnValue("formatNumber"); +} + +QString DuiLocaleStub::formatNumber(short i) const +{ + QList params; + params.append(new Parameter(i)); + stubMethodEntered("formatNumber", params); + return stubReturnValue("formatNumber"); +} + +QString DuiLocaleStub::formatNumber(int i) const +{ + QList params; + params.append(new Parameter(i)); + stubMethodEntered("formatNumber", params); + return stubReturnValue("formatNumber"); +} + +QString DuiLocaleStub::formatNumber(double i, int precision) const +{ + QList params; + params.append(new Parameter(i)); + params.append(new Parameter(precision)); + stubMethodEntered("formatNumber", params); + return stubReturnValue("formatNumber"); +} + +QString DuiLocaleStub::formatNumber(float i) const +{ + QList params; + params.append(new Parameter(i)); + stubMethodEntered("formatNumber", params); + return stubReturnValue("formatNumber"); +} + +QString DuiLocaleStub::formatPercent(double i, int decimals) const +{ + QList params; + params.append(new Parameter(i)); + params.append(new Parameter(decimals)); + stubMethodEntered("formatPercent", params); + return stubReturnValue("formatPercent"); +} + +QString DuiLocaleStub::formatCurrency(double amount, const QString ¤cy) const +{ + QList params; + params.append(new Parameter(amount)); + params.append(new Parameter(currency)); + stubMethodEntered("formatCurrency", params); + return stubReturnValue("formatCurrency"); +} + +QString DuiLocaleStub::formatDateTime(const QDateTime &dateTime, DuiLocale::DateType dateType, DuiLocale::TimeType timeType, DuiLocale::Calendar calendarType) const +{ + QList params; + params.append(new Parameter(dateTime)); + params.append(new Parameter(dateType)); + params.append(new Parameter(timeType)); + params.append(new Parameter(calendarType)); + stubMethodEntered("formatDateTime", params); + return stubReturnValue("formatDateTime"); +} + +QString DuiLocaleStub::formatDateTime(const QDateTime &dateTime, DuiLocale::Calendar calendarType) const +{ + QList params; + params.append(new Parameter(dateTime)); + params.append(new Parameter(calendarType)); + stubMethodEntered("formatDateTime", params); + return stubReturnValue("formatDateTime"); +} + +QString DuiLocaleStub::formatDateTime(const DuiCalendar &duiCalendar, DuiLocale::DateType datetype, DuiLocale::TimeType timetype) const +{ + QList params; + params.append(new Parameter(duiCalendar)); + params.append(new Parameter(datetype)); + params.append(new Parameter(timetype)); + stubMethodEntered("formatDateTime", params); + return stubReturnValue("formatDateTime"); +} + +QString DuiLocaleStub::formatDateTimeICU(const QDateTime &dateTime, const QString &formatString) const +{ + QList params; + params.append(new Parameter(dateTime)); + params.append(new Parameter(formatString)); + stubMethodEntered("formatDateTimeICU", params); + return stubReturnValue("formatDateTimeICU"); +} + +QString DuiLocaleStub::formatDateTimeICU(const DuiCalendar &duiCalendar, const QString &formatString) const +{ + QList params; + params.append(new Parameter(duiCalendar)); + params.append(new Parameter(formatString)); + stubMethodEntered("formatDateTimeICU", params); + return stubReturnValue("formatDateTimeICU"); +} + +QString DuiLocaleStub::formatDateTime(const QDateTime &dateTime, const QString &formatString) const +{ + QList params; + params.append(new Parameter(dateTime)); + params.append(new Parameter(formatString)); + stubMethodEntered("formatDateTime", params); + return stubReturnValue("formatDateTime"); +} + +QString DuiLocaleStub::formatDateTime(const DuiCalendar &duiCalendar, const QString &formatString) const +{ + QList params; + params.append(new Parameter(duiCalendar)); + params.append(new Parameter(formatString)); + stubMethodEntered("formatDateTime", params); + return stubReturnValue("formatDateTime"); +} + +QString DuiLocaleStub::monthName(const DuiCalendar &duiCalendar, int monthNumber) const +{ + QList params; + params.append(new Parameter(duiCalendar)); + params.append(new Parameter(monthNumber)); + stubMethodEntered("monthName", params); + return stubReturnValue("monthName"); +} + +QString DuiLocaleStub::monthName(const DuiCalendar &duiCalendar, int monthNumber, DuiLocale::DateSymbolContext context, DuiLocale::DateSymbolLength symbolLength) const +{ + QList params; + params.append(new Parameter(duiCalendar)); + params.append(new Parameter(monthNumber)); + params.append(new Parameter(context)); + params.append(new Parameter(symbolLength)); + stubMethodEntered("monthName", params); + return stubReturnValue("monthName"); +} + +QString DuiLocaleStub::weekdayName(const DuiCalendar &duiCalendar, int weekday) const +{ + QList params; + params.append(new Parameter(duiCalendar)); + params.append(new Parameter(weekday)); + stubMethodEntered("weekdayName", params); + return stubReturnValue("weekdayName"); +} + +QString DuiLocaleStub::weekdayName(const DuiCalendar &duiCalendar, int weekday, DuiLocale::DateSymbolContext context, DuiLocale::DateSymbolLength symbolLength) const +{ + QList params; + params.append(new Parameter(duiCalendar)); + params.append(new Parameter(weekday)); + params.append(new Parameter(context)); + params.append(new Parameter(symbolLength)); + stubMethodEntered("weekdayName", params); + return stubReturnValue("weekdayName"); +} + +void DuiLocaleStub::installCategoryCatalog(DuiLocale::Category category, const QString &name) +{ + QList params; + params.append(new Parameter(category)); + params.append(new Parameter(name)); + stubMethodEntered("installCategoryCatalog", params); +} + +void DuiLocaleStub::removeCategoryCatalog(DuiLocale::Category category, const QString &name) +{ + QList params; + params.append(new Parameter(category)); + params.append(new Parameter(name)); + stubMethodEntered("removeCategoryCatalog", params); +} + +void DuiLocaleStub::copyCatalogsFrom(const DuiLocale &other) +{ + QList params; + params.append(new Parameter(other)); + stubMethodEntered("copyCatalogsFrom", params); +} + +bool DuiLocaleStub::hasCategoryCatalog(DuiLocale::Category category, const QString &name) +{ + QList params; + params.append(new Parameter(category)); + params.append(new Parameter(name)); + stubMethodEntered("hasCategoryCatalog", params); + return stubReturnValue("hasCategoryCatalog"); +} + +void DuiLocaleStub::installTrCatalog(const QString &name) +{ + QList params; + params.append(new Parameter(name)); + stubMethodEntered("installTrCatalog", params); +} + +QString DuiLocaleStub::translate(const char *context, const char *sourceText, const char *comment, int n) +{ + QList params; + params.append(new Parameter(context)); + params.append(new Parameter(sourceText)); + params.append(new Parameter(comment)); + params.append(new Parameter(n)); + stubMethodEntered("translate", params); + return stubReturnValue("translate"); +} + +void DuiLocaleStub::setDataPaths(const QStringList &dataPaths) +{ + QList params; + params.append(new Parameter(dataPaths)); + stubMethodEntered("setDataPaths", params); +} + +void DuiLocaleStub::setDataPath(const QString &dataPath) +{ + QList params; + params.append(new Parameter(dataPath)); + stubMethodEntered("setDataPath", params); +} + +void DuiLocaleStub::setTranslationPaths(const QStringList &paths) +{ + QList params; + params.append(new Parameter(paths)); + stubMethodEntered("setTranslationPaths", params); +} + +void DuiLocaleStub::addTranslationPath(const QString &path) +{ + QList params; + params.append(new Parameter(path)); + stubMethodEntered("addTranslationPath", params); +} + +void DuiLocaleStub::removeTranslationPath(const QString &path) +{ + QList params; + params.append(new Parameter(path)); + stubMethodEntered("removeTranslationPath", params); +} + +QStringList DuiLocaleStub::translationPaths() +{ + stubMethodEntered("translationPaths"); + return stubReturnValue("translationPaths"); +} + +void DuiLocaleStub::connectSettings() +{ + stubMethodEntered("connectSettings"); +} + +void DuiLocaleStub::disconnectSettings() +{ + stubMethodEntered("disconnectSettings"); +} + +void DuiLocaleStub::insertTrToQCoreApp() +{ + stubMethodEntered("insertTrToQCoreApp"); +} + +void DuiLocaleStub::removeTrFromQCoreApp() +{ + stubMethodEntered("removeTrFromQCoreApp"); +} + +DuiLocale DuiLocaleStub::getDefault() +{ + stubMethodEntered("getDefault"); + return stubReturnValue("getDefault"); +} + +bool DuiLocaleStub::operator==(const DuiLocale &other) const +{ + QList params; + params.append(new Parameter(other)); + stubMethodEntered("operator==", params); + return stubReturnValue("operator=="); +} + +bool DuiLocaleStub::operator!=(const DuiLocale &other) const +{ + QList params; + params.append(new Parameter(other)); + stubMethodEntered("operator!=", params); + return stubReturnValue("operator!="); +} + +void DuiLocaleStub::refreshSettings() +{ + stubMethodEntered("refreshSettings"); +} + + + +// 3. CREATE A STUB INSTANCE +DuiLocaleStub gDefaultDuiLocaleStub; +DuiLocaleStub *gDuiLocaleStub = &gDefaultDuiLocaleStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiLocale *DuiLocale::createSystemDuiLocale() +{ + return gDuiLocaleStub->createSystemDuiLocale(); +} + +DuiLocale DuiLocale::createCLocale() +{ + return gDuiLocaleStub->createCLocale(); +} + +DuiLocale::DuiLocale(QObject *parent) : QObject(parent), d_ptr(NULL) +{ + gDuiLocaleStub->DuiLocaleConstructor(parent); +} + +DuiLocale::DuiLocale(const QString &localeName, QObject *parent) : QObject(parent), d_ptr(NULL) +{ + gDuiLocaleStub->DuiLocaleConstructor(localeName, parent); +} + +DuiLocale::DuiLocale(const DuiLocale &other, QObject *parent) : QObject(parent), d_ptr(NULL) +{ + gDuiLocaleStub->DuiLocaleConstructor(other, parent); +} + +DuiLocale::~DuiLocale() +{ + gDuiLocaleStub->DuiLocaleDestructor(); +} + +DuiLocale &DuiLocale::operator=(const DuiLocale &other) +{ + static DuiLocale equals = gDuiLocaleStub->operatorEquals(other); + return equals; +} + +void DuiLocale::setDefault(const DuiLocale &locale) +{ + gDuiLocaleStub->setDefault(locale); +} + +bool DuiLocale::isValid() const +{ + return gDuiLocaleStub->isValid(); +} + +void DuiLocale::setCategoryLocale(DuiLocale::Category category, const QString &localeName) +{ + gDuiLocaleStub->setCategoryLocale(category, localeName); +} + +void DuiLocale::setCollation(DuiLocale::Collation collation) +{ + gDuiLocaleStub->setCollation(collation); +} + +DuiLocale::Collation DuiLocale::collation() const +{ + return gDuiLocaleStub->collation(); +} + +void DuiLocale::setCalendar(DuiLocale::Calendar calendar) +{ + gDuiLocaleStub->setCalendar(calendar); +} + +DuiLocale::Calendar DuiLocale::calendar() const +{ + return gDuiLocaleStub->calendar(); +} + +DuiCollator DuiLocale::collator() const +{ + return gDuiLocaleStub->collator(); +} + +QString DuiLocale::languageEndonym() const +{ + return gDuiLocaleStub->languageEndonym(); +} + +QString DuiLocale::countryEndonym() const +{ + return gDuiLocaleStub->countryEndonym(); +} + +QString DuiLocale::language() const +{ + return gDuiLocaleStub->language(); +} + +QString DuiLocale::country() const +{ + return gDuiLocaleStub->country(); +} + +QString DuiLocale::script() const +{ + return gDuiLocaleStub->script(); +} + +QString DuiLocale::variant() const +{ + return gDuiLocaleStub->variant(); +} + +QString DuiLocale::name() const +{ + return gDuiLocaleStub->name(); +} + +Qt::LayoutDirection DuiLocale::textDirection() const +{ + return gDuiLocaleStub->textDirection(); +} + +QString DuiLocale::categoryLanguage(DuiLocale::Category category) const +{ + return gDuiLocaleStub->categoryLanguage(category); +} + +QString DuiLocale::categoryCountry(DuiLocale::Category category) const +{ + return gDuiLocaleStub->categoryCountry(category); +} + +QString DuiLocale::categoryVariant(DuiLocale::Category category) const +{ + return gDuiLocaleStub->categoryVariant(category); +} + +QString DuiLocale::categoryName(DuiLocale::Category category) const +{ + return gDuiLocaleStub->categoryName(category); +} + +QString DuiLocale::formatNumber(qlonglong i) const +{ + return gDuiLocaleStub->formatNumber(i); +} + +QString DuiLocale::formatNumber(short i) const +{ + return gDuiLocaleStub->formatNumber(i); +} + +QString DuiLocale::formatNumber(int i) const +{ + return gDuiLocaleStub->formatNumber(i); +} + +QString DuiLocale::formatNumber(double i, int precision) const +{ + return gDuiLocaleStub->formatNumber(i, precision); +} + +QString DuiLocale::formatNumber(float i) const +{ + return gDuiLocaleStub->formatNumber(i); +} + +QString DuiLocale::formatPercent(double i, int decimals) const +{ + return gDuiLocaleStub->formatPercent(i, decimals); +} + +QString DuiLocale::formatCurrency(double amount, const QString ¤cy) const +{ + return gDuiLocaleStub->formatCurrency(amount, currency); +} + +QString DuiLocale::formatDateTime(const QDateTime &dateTime, DuiLocale::DateType dateType, DuiLocale::TimeType timeType, DuiLocale::Calendar calendarType) const +{ + return gDuiLocaleStub->formatDateTime(dateTime, dateType, timeType, calendarType); +} + +QString DuiLocale::formatDateTime(const QDateTime &dateTime, DuiLocale::Calendar calendarType) const +{ + return gDuiLocaleStub->formatDateTime(dateTime, calendarType); +} + +QString DuiLocale::formatDateTime(const DuiCalendar &duiCalendar, DuiLocale::DateType datetype, DuiLocale::TimeType timetype) const +{ + return gDuiLocaleStub->formatDateTime(duiCalendar, datetype, timetype); +} + +QString DuiLocale::formatDateTimeICU(const QDateTime &dateTime, const QString &formatString) const +{ + return gDuiLocaleStub->formatDateTimeICU(dateTime, formatString); +} + +QString DuiLocale::formatDateTimeICU(const DuiCalendar &duiCalendar, const QString &formatString) const +{ + return gDuiLocaleStub->formatDateTimeICU(duiCalendar, formatString); +} + +QString DuiLocale::formatDateTime(const QDateTime &dateTime, const QString &formatString) const +{ + return gDuiLocaleStub->formatDateTime(dateTime, formatString); +} + +QString DuiLocale::formatDateTime(const DuiCalendar &duiCalendar, const QString &formatString) const +{ + return gDuiLocaleStub->formatDateTime(duiCalendar, formatString); +} + +QString DuiLocale::monthName(const DuiCalendar &duiCalendar, int monthNumber) const +{ + return gDuiLocaleStub->monthName(duiCalendar, monthNumber); +} + +QString DuiLocale::monthName(const DuiCalendar &duiCalendar, int monthNumber, DuiLocale::DateSymbolContext context, DuiLocale::DateSymbolLength symbolLength) const +{ + return gDuiLocaleStub->monthName(duiCalendar, monthNumber, context, symbolLength); +} + +QString DuiLocale::weekdayName(const DuiCalendar &duiCalendar, int weekday) const +{ + return gDuiLocaleStub->weekdayName(duiCalendar, weekday); +} + +QString DuiLocale::weekdayName(const DuiCalendar &duiCalendar, int weekday, DuiLocale::DateSymbolContext context, DuiLocale::DateSymbolLength symbolLength) const +{ + return gDuiLocaleStub->weekdayName(duiCalendar, weekday, context, symbolLength); +} + +void DuiLocale::installCategoryCatalog(DuiLocale::Category category, const QString &name) +{ + gDuiLocaleStub->installCategoryCatalog(category, name); +} + +void DuiLocale::removeCategoryCatalog(DuiLocale::Category category, const QString &name) +{ + gDuiLocaleStub->removeCategoryCatalog(category, name); +} + +void DuiLocale::copyCatalogsFrom(const DuiLocale &other) +{ + gDuiLocaleStub->copyCatalogsFrom(other); +} + +bool DuiLocale::hasCategoryCatalog(DuiLocale::Category category, const QString &name) +{ + return gDuiLocaleStub->hasCategoryCatalog(category, name); +} + +void DuiLocale::installTrCatalog(const QString &name) +{ + gDuiLocaleStub->installTrCatalog(name); +} + +QString DuiLocale::translate(const char *context, const char *sourceText, const char *comment, int n) +{ + return gDuiLocaleStub->translate(context, sourceText, comment, n); +} + +void DuiLocale::setDataPaths(const QStringList &dataPaths) +{ + gDuiLocaleStub->setDataPaths(dataPaths); +} + +void DuiLocale::setDataPath(const QString &dataPath) +{ + gDuiLocaleStub->setDataPath(dataPath); +} + +void DuiLocale::setTranslationPaths(const QStringList &paths) +{ + gDuiLocaleStub->setTranslationPaths(paths); +} + +void DuiLocale::addTranslationPath(const QString &path) +{ + gDuiLocaleStub->addTranslationPath(path); +} + +void DuiLocale::removeTranslationPath(const QString &path) +{ + gDuiLocaleStub->removeTranslationPath(path); +} + +QStringList DuiLocale::translationPaths() +{ + return gDuiLocaleStub->translationPaths(); +} + +void DuiLocale::connectSettings() +{ + gDuiLocaleStub->connectSettings(); +} + +void DuiLocale::disconnectSettings() +{ + gDuiLocaleStub->disconnectSettings(); +} + +void DuiLocale::insertTrToQCoreApp() +{ + gDuiLocaleStub->insertTrToQCoreApp(); +} + +void DuiLocale::removeTrFromQCoreApp() +{ + gDuiLocaleStub->removeTrFromQCoreApp(); +} + +DuiLocale &DuiLocale::getDefault() +{ + static DuiLocale def = gDuiLocaleStub->getDefault(); + return def; +} + +bool DuiLocale::operator==(const DuiLocale &other) const +{ + return gDuiLocaleStub->operator==(other); +} + +bool DuiLocale::operator!=(const DuiLocale &other) const +{ + return gDuiLocaleStub->operator!=(other); +} + +void DuiLocale::refreshSettings() +{ + gDuiLocaleStub->refreshSettings(); +} + + +#endif diff --git a/tests/stubs/duimashupcanvas_stub.h b/tests/stubs/duimashupcanvas_stub.h new file mode 100644 index 000000000..b2743efde --- /dev/null +++ b/tests/stubs/duimashupcanvas_stub.h @@ -0,0 +1,164 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIMASHUPCANVAS_STUB +#define DUIMASHUPCANVAS_STUB + +#include "duimashupcanvas.h" +#include + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiMashupCanvasStub : public StubBase +{ +public: + virtual void DuiMashupCanvasConstructor(const QString &identifier, QGraphicsItem *parent); + virtual void DuiMashupCanvasDestructor(); + virtual DuiAppletInstanceManager *appletInstanceManager() const; + virtual void setCategories(const QStringList &categories); + virtual QStringList categories() const; + virtual QString identifier() const; + virtual QString serviceAddress() const; + virtual void DuiMashupCanvasConstructor(DuiMashupCanvasPrivate *dd, DuiMashupCanvasModel *model, QGraphicsItem *parent, const QString &identifier); + virtual void addWidget(DuiWidget *widget, DuiDataStore &store); + virtual void removeWidget(DuiWidget *widget); +}; + +// 2. IMPLEMENT STUB +void DuiMashupCanvasStub::DuiMashupCanvasConstructor(const QString &identifier, QGraphicsItem *parent) +{ + Q_UNUSED(identifier); + Q_UNUSED(parent); + +} +void DuiMashupCanvasStub::DuiMashupCanvasDestructor() +{ + +} +DuiAppletInstanceManager *DuiMashupCanvasStub::appletInstanceManager() const +{ + stubMethodEntered("appletInstanceManager"); + return stubReturnValue("appletInstanceManager"); +} + +void DuiMashupCanvasStub::setCategories(const QStringList &categories) +{ + QList params; + params.append(new Parameter(categories)); + stubMethodEntered("setCategories", params); +} + +QStringList DuiMashupCanvasStub::categories() const +{ + stubMethodEntered("categories"); + return stubReturnValue("categories"); +} + +QString DuiMashupCanvasStub::identifier() const +{ + stubMethodEntered("identifier"); + return stubReturnValue("identifier"); +} + +QString DuiMashupCanvasStub::serviceAddress() const +{ + stubMethodEntered("serviceAddress"); + return stubReturnValue("serviceAddress"); +} + +void DuiMashupCanvasStub::DuiMashupCanvasConstructor(DuiMashupCanvasPrivate *dd, DuiMashupCanvasModel *model, QGraphicsItem *parent, const QString &identifier) +{ + Q_UNUSED(dd); + Q_UNUSED(model); + Q_UNUSED(parent); + Q_UNUSED(identifier); +} + +void DuiMashupCanvasStub::addWidget(DuiWidget *widget, DuiDataStore &store) +{ + QList params; + params.append(new Parameter(widget)); + params.append(new Parameter(store)); + stubMethodEntered("addWidget", params); +} + +void DuiMashupCanvasStub::removeWidget(DuiWidget *widget) +{ + QList params; + params.append(new Parameter(widget)); + stubMethodEntered("removeWidget", params); +} + +// 3. CREATE A STUB INSTANCE +DuiMashupCanvasStub gDefaultDuiMashupCanvasStub; +DuiMashupCanvasStub *gDuiMashupCanvasStub = &gDefaultDuiMashupCanvasStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiMashupCanvas::DuiMashupCanvas(const QString &identifier, QGraphicsItem *parent) +{ + gDuiMashupCanvasStub->DuiMashupCanvasConstructor(identifier, parent); +} + +DuiMashupCanvas::~DuiMashupCanvas() +{ + gDuiMashupCanvasStub->DuiMashupCanvasDestructor(); +} + +DuiAppletInstanceManager *DuiMashupCanvas::appletInstanceManager() const +{ + return gDuiMashupCanvasStub->appletInstanceManager(); +} + +void DuiMashupCanvas::setCategories(const QStringList &categories) +{ + gDuiMashupCanvasStub->setCategories(categories); +} + +QStringList DuiMashupCanvas::categories() const +{ + return gDuiMashupCanvasStub->categories(); +} + +QString DuiMashupCanvas::identifier() const +{ + return gDuiMashupCanvasStub->identifier(); +} + +QString DuiMashupCanvas::serviceAddress() const +{ + return gDuiMashupCanvasStub->serviceAddress(); +} + +DuiMashupCanvas::DuiMashupCanvas(DuiMashupCanvasPrivate *dd, DuiMashupCanvasModel *model, QGraphicsItem *parent, const QString &identifier) +{ + gDuiMashupCanvasStub->DuiMashupCanvasConstructor(dd, model, parent, identifier); +} + +void DuiMashupCanvas::addWidget(DuiWidget *widget, DuiDataStore &store) +{ + gDuiMashupCanvasStub->addWidget(widget, store); +} + +void DuiMashupCanvas::removeWidget(DuiWidget *widget) +{ + gDuiMashupCanvasStub->removeWidget(widget); +} + +#endif diff --git a/tests/stubs/duimultilayoutitem_stub.h b/tests/stubs/duimultilayoutitem_stub.h new file mode 100644 index 000000000..01b128ee1 --- /dev/null +++ b/tests/stubs/duimultilayoutitem_stub.h @@ -0,0 +1,144 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DuiMultiLayoutItem_STUB +#define DuiMultiLayoutItem_STUB + +#include "DuiMultiLayoutItem.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiMultiLayoutItemStub : public StubBase +{ +public: + enum LayoutParameter { PosCoordinates = 0, PosIndex, ColumnSpanning, RowSpanning } ; + virtual void DuiMultiLayoutItemConstructor(); + virtual void DuiMultiLayoutItemDestructor(); + virtual bool belongsToLayout(QString const &layoutName) const; + virtual void assignToLayout(QString const &layoutName, QMap const &layoutParameter); + virtual void assignToLayout(QString const &layoutName); + virtual QMap layoutParameters(QString const &layoutName) const; + virtual void setWidget(DuiWidget *widget); + virtual void DuiMultiLayoutItemConstructor(const DuiMultiLayoutItem &); + DuiMultiLayoutItemPrivate *d_ptr ; +}; + +// 2. IMPLEMENT STUB +void DuiMultiLayoutItemStub::DuiMultiLayoutItemConstructor() +{ + +} +void DuiMultiLayoutItemStub::DuiMultiLayoutItemDestructor() +{ + +} +bool DuiMultiLayoutItemStub::belongsToLayout(QString const &layoutName) const +{ + QList params; + params.append(new Parameter(layoutName)); + stubMethodEntered("belongsToLayout", params); + return stubReturnValue("belongsToLayout"); +} + +void DuiMultiLayoutItemStub::assignToLayout(QString const &layoutName, QMap const &layoutParameter) +{ + QList params; + params.append(new Parameter(layoutName)); + params.append(new Parameter const & >(layoutParameter)); + stubMethodEntered("assignToLayout", params); +} + +void DuiMultiLayoutItemStub::assignToLayout(QString const &layoutName) +{ + QList params; + params.append(new Parameter(layoutName)); + stubMethodEntered("assignToLayout", params); +} + +QMap DuiMultiLayoutItemStub::layoutParameters(QString const &layoutName) const +{ + QList params; + params.append(new Parameter(layoutName)); + stubMethodEntered("layoutParameters", params); + return stubReturnValue >("layoutParameters"); +} + +void DuiMultiLayoutItemStub::setWidget(DuiWidget *widget) +{ + QList params; + params.append(new Parameter(widget)); + stubMethodEntered("setWidget", params); +} + +void DuiMultiLayoutItemStub::DuiMultiLayoutItemConstructor(const DuiMultiLayoutItem &) +{ + +} + + +// 3. CREATE A STUB INSTANCE +DuiMultiLayoutItemStub gDefaultDuiMultiLayoutItemStub; +DuiMultiLayoutItemStub *gDuiMultiLayoutItemStub = &gDefaultDuiMultiLayoutItemStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiMultiLayoutItem::DuiMultiLayoutItem() +{ + gDuiMultiLayoutItemStub->DuiMultiLayoutItemConstructor(); +} + +DuiMultiLayoutItem::~DuiMultiLayoutItem() +{ + gDuiMultiLayoutItemStub->DuiMultiLayoutItemDestructor(); +} + +bool DuiMultiLayoutItem::belongsToLayout(QString const &layoutName) const +{ + return gDuiMultiLayoutItemStub->belongsToLayout(layoutName); +} + +void DuiMultiLayoutItem::assignToLayout(QString const &layoutName, QMap const &layoutParameter) +{ + gDuiMultiLayoutItemStub->assignToLayout(layoutName, layoutParameter); +} + +void DuiMultiLayoutItem::assignToLayout(QString const &layoutName) +{ + gDuiMultiLayoutItemStub->assignToLayout(layoutName); +} + +QMap DuiMultiLayoutItem::layoutParameters(QString const &layoutName) const +{ + return gDuiMultiLayoutItemStub->layoutParameters(layoutName); +} + +void DuiMultiLayoutItem::setWidget(DuiWidget *widget) +{ + gDuiMultiLayoutItemStub->setWidget(widget); +} + +DuiMultiLayoutItem::DuiMultiLayoutItem(const DuiMultiLayoutItem &) +{ + gDuiMultiLayoutItemStub->DuiMultiLayoutItemConstructor(); +} + + +#endif diff --git a/tests/stubs/duinavigationbar_stub.h b/tests/stubs/duinavigationbar_stub.h new file mode 100644 index 000000000..10461b1de --- /dev/null +++ b/tests/stubs/duinavigationbar_stub.h @@ -0,0 +1,152 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUINAVIGATIONBAR_STUB +#define DUINAVIGATIONBAR_STUB + +#include "duinavigationbar.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiNavigationBarStub : public StubBase +{ +public: + virtual void DuiNavigationBarConstructor(QGraphicsWidget *parent); + virtual void DuiNavigationBarDestructor(); + virtual void updateStyle(); + virtual void dockToolbar(DuiToolbar *toolbar); + virtual DuiToolbar *undockToolbar(); + virtual bool isFullscreen() const; + virtual void setFullscreen(bool isFullscreen); + virtual void animateOrientationChange(qreal f, DuiOrientationChangeParameters *parameters); + virtual void finalizeOrientationChange(DuiOrientationChangeParameters *parameters); + DuiNavigationBarPrivate *d_ptr ; +}; + +// 2. IMPLEMENT STUB +void DuiNavigationBarStub::DuiNavigationBarConstructor(QGraphicsWidget *parent) +{ + Q_UNUSED(parent); + +} +void DuiNavigationBarStub::DuiNavigationBarDestructor() +{ + +} +void DuiNavigationBarStub::updateStyle() +{ + stubMethodEntered("updateStyle"); +} + +void DuiNavigationBarStub::dockToolbar(DuiToolbar *toolbar) +{ + QList params; + params.append(new Parameter(toolbar)); + stubMethodEntered("dockToolbar", params); +} + +DuiToolbar *DuiNavigationBarStub::undockToolbar() +{ + stubMethodEntered("undockToolbar"); + return stubReturnValue("undockToolbar"); +} + +bool DuiNavigationBarStub::isFullscreen() const +{ + stubMethodEntered("isFullscreen"); + return stubReturnValue("isFullscreen"); +} + +void DuiNavigationBarStub::setFullscreen(bool isFullscreen) +{ + QList params; + params.append(new Parameter(isFullscreen)); + stubMethodEntered("setFullscreen", params); +} + +void DuiNavigationBarStub::animateOrientationChange(qreal f, DuiOrientationChangeParameters *parameters) +{ + QList params; + params.append(new Parameter(f)); + params.append(new Parameter(parameters)); + stubMethodEntered("animateOrientationChange", params); +} + +void DuiNavigationBarStub::finalizeOrientationChange(DuiOrientationChangeParameters *parameters) +{ + QList params; + params.append(new Parameter(parameters)); + stubMethodEntered("finalizeOrientationChange", params); +} + +// 3. CREATE A STUB INSTANCE +DuiNavigationBarStub gDefaultDuiNavigationBarStub; +DuiNavigationBarStub *gDuiNavigationBarStub = &gDefaultDuiNavigationBarStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiNavigationBar::DuiNavigationBar(QGraphicsWidget *parent) +{ + gDuiNavigationBarStub->DuiNavigationBarConstructor(parent); +} + +DuiNavigationBar::~DuiNavigationBar() +{ + gDuiNavigationBarStub->DuiNavigationBarDestructor(); +} + +void DuiNavigationBar::updateStyle() +{ + gDuiNavigationBarStub->updateStyle(); +} + +void DuiNavigationBar::dockToolbar(DuiToolbar *toolbar) +{ + gDuiNavigationBarStub->dockToolbar(toolbar); +} + +DuiToolbar *DuiNavigationBar::undockToolbar() +{ + return gDuiNavigationBarStub->undockToolbar(); +} + +bool DuiNavigationBar::isFullscreen() const +{ + return gDuiNavigationBarStub->isFullscreen(); +} + +void DuiNavigationBar::setFullscreen(bool isFullscreen) +{ + gDuiNavigationBarStub->setFullscreen(isFullscreen); +} + +void DuiNavigationBar::animateOrientationChange(qreal f, DuiOrientationChangeParameters *parameters) +{ + gDuiNavigationBarStub->animateOrientationChange(f, parameters); +} + +void DuiNavigationBar::finalizeOrientationChange(DuiOrientationChangeParameters *parameters) +{ + gDuiNavigationBarStub->finalizeOrientationChange(parameters); +} + + +#endif diff --git a/tests/stubs/duinavigationbarview_stub.h b/tests/stubs/duinavigationbarview_stub.h new file mode 100644 index 000000000..537cde920 --- /dev/null +++ b/tests/stubs/duinavigationbarview_stub.h @@ -0,0 +1,169 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUINAVIGATIONBARVIEW_STUB +#define DUINAVIGATIONBARVIEW_STUB + +#include "duinavigationbarview.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiNavigationBarViewStub : public StubBase +{ +public: + virtual void DuiNavigationBarViewConstructor(const DuiNavigationBar *controller); + virtual void DuiNavigationBarViewDestructor(); + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + virtual QRectF boundingRect() const; + virtual QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint) const; + virtual void setGeometry(const QRectF &rect); + virtual void styleUpdated(); + virtual void registerStyleAttributes(DuiStyleDescription &description); + virtual void updateData(const int index); + virtual void viewModeTransition(qreal value); +}; + +// 2. IMPLEMENT STUB +void DuiNavigationBarViewStub::DuiNavigationBarViewConstructor(const DuiNavigationBar *controller) +{ + Q_UNUSED(controller); + +} +void DuiNavigationBarViewStub::DuiNavigationBarViewDestructor() +{ + +} +void DuiNavigationBarViewStub::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + QList params; + params.append(new Parameter(painter)); + params.append(new Parameter(option)); + params.append(new Parameter(widget)); + stubMethodEntered("paint", params); +} + +QRectF DuiNavigationBarViewStub::boundingRect() const +{ + stubMethodEntered("boundingRect"); + return stubReturnValue("boundingRect"); +} + +QSizeF DuiNavigationBarViewStub::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const +{ + QList params; + params.append(new Parameter(which)); + params.append(new Parameter(constraint)); + return stubReturnValue("sizeHint"); +} + +void DuiNavigationBarViewStub::setGeometry(const QRectF &rect) +{ + QList params; + params.append(new Parameter(rect)); + stubMethodEntered("setGeometry", params); +} + +void DuiNavigationBarViewStub::styleUpdated() +{ + stubMethodEntered("styleUpdated"); +} + +void DuiNavigationBarViewStub::registerStyleAttributes(DuiStyleDescription &description) +{ + QList params; + params.append(new Parameter(description)); + stubMethodEntered("registerStyleAttributes", params); +} + +void DuiNavigationBarViewStub::updateData(const int index) +{ + QList params; + params.append(new Parameter(index)); + stubMethodEntered("updateData", params); +} + +void DuiNavigationBarViewStub::viewModeTransition(qreal value) +{ + QList params; + params.append(new Parameter(value)); + stubMethodEntered("viewModeTransition", params); +} + + + +// 3. CREATE A STUB INSTANCE +DuiNavigationBarViewStub gDefaultDuiNavigationBarViewStub; +DuiNavigationBarViewStub *gDuiNavigationBarViewStub = &gDefaultDuiNavigationBarViewStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiNavigationBarView::DuiNavigationBarView(const DuiNavigationBar *controller) +{ + gDuiNavigationBarViewStub->DuiNavigationBarViewConstructor(controller); +} + +DuiNavigationBarView::~DuiNavigationBarView() +{ + gDuiNavigationBarViewStub->DuiNavigationBarViewDestructor(); +} + +void DuiNavigationBarView::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + gDuiNavigationBarViewStub->paint(painter, option, widget); +} + +QRectF DuiNavigationBarView::boundingRect() const +{ + return gDuiNavigationBarViewStub->boundingRect(); +} + +QSizeF DuiNavigationBarView::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const +{ + return gDuiNavigationBarViewStub->sizeHint(which, constraint); +} + +void DuiNavigationBarView::setGeometry(const QRectF &rect) +{ + gDuiNavigationBarViewStub->setGeometry(rect); +} + +void DuiNavigationBarView::styleUpdated() +{ + gDuiNavigationBarViewStub->styleUpdated(); +} + +void DuiNavigationBarView::registerStyleAttributes(DuiStyleDescription &description) +{ + gDuiNavigationBarViewStub->registerStyleAttributes(description); +} + +void DuiNavigationBarView::updateData(const int index) +{ + gDuiNavigationBarViewStub->updateData(index); +} + +void DuiNavigationBarView::viewModeTransition(qreal value) +{ + gDuiNavigationBarViewStub->viewModeTransition(value); +} + + +#endif diff --git a/tests/stubs/duinotificationgroup_stub.h b/tests/stubs/duinotificationgroup_stub.h new file mode 100644 index 000000000..723c66a5c --- /dev/null +++ b/tests/stubs/duinotificationgroup_stub.h @@ -0,0 +1,149 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUINOTIFICATIONGROUP_STUB +#define DUINOTIFICATIONGROUP_STUB + +#include "duinotificationgroup.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiNotificationGroupStub : public StubBase +{ +public: + virtual void DuiNotificationGroupConstructor(const QString &eventType, const QString &summary, const QString &body, const QString &imageURI, const DuiRemoteAction &action, uint count, bool persistent); + virtual void DuiNotificationGroupConstructor(unsigned int id); + virtual void DuiNotificationGroupDestructor(); + virtual unsigned int id() const; + virtual bool update(const QString &eventType, const QString &summary, const QString &body, const QString &imageURI, uint count, const DuiRemoteAction &action); + virtual bool remove(); + virtual bool isValid() const; + virtual void DuiNotificationGroupConstructor(DuiNotificationGroupPrivate &dd); + DuiNotificationGroupPrivate *d_ptr ; +}; + +// 2. IMPLEMENT STUB +void DuiNotificationGroupStub::DuiNotificationGroupConstructor(const QString &eventType, const QString &summary, const QString &body, const QString &imageURI, const DuiRemoteAction &action, uint count, bool persistent) +{ + Q_UNUSED(eventType); + Q_UNUSED(summary); + Q_UNUSED(body); + Q_UNUSED(imageURI); + Q_UNUSED(action); + Q_UNUSED(count); + Q_UNUSED(persistent); + +} +void DuiNotificationGroupStub::DuiNotificationGroupConstructor(unsigned int id) +{ + Q_UNUSED(id); + +} +void DuiNotificationGroupStub::DuiNotificationGroupDestructor() +{ + +} +unsigned int DuiNotificationGroupStub::id() const +{ + stubMethodEntered("id"); + return stubReturnValue("id"); +} + +bool DuiNotificationGroupStub::update(const QString &eventType, const QString &summary, const QString &body, const QString &imageURI, uint count, const DuiRemoteAction &action) +{ + QList params; + params.append(new Parameter(eventType)); + params.append(new Parameter(summary)); + params.append(new Parameter(body)); + params.append(new Parameter(imageURI)); + params.append(new Parameter(count)); + params.append(new Parameter(action)); + stubMethodEntered("update", params); + return stubReturnValue("update"); +} + +bool DuiNotificationGroupStub::remove() +{ + stubMethodEntered("remove"); + return stubReturnValue("remove"); +} + +bool DuiNotificationGroupStub::isValid() const +{ + stubMethodEntered("isValid"); + return stubReturnValue("isValid"); +} + +void DuiNotificationGroupStub::DuiNotificationGroupConstructor(DuiNotificationGroupPrivate &dd) +{ + Q_UNUSED(dd); + +} + + +// 3. CREATE A STUB INSTANCE +DuiNotificationGroupStub gDefaultDuiNotificationGroupStub; +DuiNotificationGroupStub *gDuiNotificationGroupStub = &gDefaultDuiNotificationGroupStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiNotificationGroup::DuiNotificationGroup(const QString &eventType, const QString &summary, const QString &body, const QString &imageURI, const DuiRemoteAction &action, uint count, bool persistent) +{ + gDuiNotificationGroupStub->DuiNotificationGroupConstructor(eventType, summary, body, imageURI, action, count, persistent); +} + +DuiNotificationGroup::DuiNotificationGroup(unsigned int id) +{ + gDuiNotificationGroupStub->DuiNotificationGroupConstructor(id); +} + +DuiNotificationGroup::~DuiNotificationGroup() +{ + gDuiNotificationGroupStub->DuiNotificationGroupDestructor(); +} + +unsigned int DuiNotificationGroup::id() const +{ + return gDuiNotificationGroupStub->id(); +} + +bool DuiNotificationGroup::update(const QString &eventType, const QString &summary, const QString &body, const QString &imageURI, uint count, const DuiRemoteAction &action) +{ + return gDuiNotificationGroupStub->update(eventType, summary, body, imageURI, count, action); +} + +bool DuiNotificationGroup::remove() +{ + return gDuiNotificationGroupStub->remove(); +} + +bool DuiNotificationGroup::isValid() const +{ + return gDuiNotificationGroupStub->isValid(); +} + +DuiNotificationGroup::DuiNotificationGroup(DuiNotificationGroupPrivate &dd) +{ + gDuiNotificationGroupStub->DuiNotificationGroupConstructor(dd); +} + + +#endif diff --git a/tests/stubs/duinotificationmanager_stub.h b/tests/stubs/duinotificationmanager_stub.h new file mode 100644 index 000000000..859792e5b --- /dev/null +++ b/tests/stubs/duinotificationmanager_stub.h @@ -0,0 +1,261 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUINOTIFICATIONMANAGER_STUB +#define DUINOTIFICATIONMANAGER_STUB + +#include "duinotificationmanager.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiNotificationManagerStub : public StubBase +{ +public: + virtual void DuiNotificationManagerConstructor(); + virtual void DuiNotificationManagerDestructor(); + virtual uint addGroup(const QString &eventType, const QString &summary, const QString &body, const QString &action, const QString &imageURI, uint count, bool persistent); + virtual uint addGroup(const QString &eventType, bool persistent); + virtual uint addNotification(uint groupId, const QString &eventType, const QString &summary, const QString &body, const QString &action, const QString &imageURI, uint count, bool persistent); + virtual uint addNotification(uint groupId, const QString &eventType, bool persistent); + virtual bool removeGroup(uint groupId); + virtual bool removeNotification(uint notificationId); + virtual bool updateGroup(uint groupId, const QString &eventType, const QString &summary, const QString &body, const QString &action, const QString &imageURI, uint count); + virtual bool updateGroup(uint groupId, const QString &eventType); + virtual bool updateNotification(uint notificationId, const QString &eventType, const QString &summary, const QString &body, const QString &action, const QString &imageURI, uint count); + virtual bool updateNotification(uint notificationId, const QString &eventType); + virtual QList notificationIdList(); +}; + +// 2. IMPLEMENT STUB +void DuiNotificationManagerStub::DuiNotificationManagerConstructor() +{ + +} +void DuiNotificationManagerStub::DuiNotificationManagerDestructor() +{ + +} + +uint DuiNotificationManagerStub::addGroup(const QString &eventType, const QString &summary, const QString &body, const QString &action, const QString &imageURI, uint count, bool persistent) +{ + QList params; + params.append(new Parameter(eventType)); + params.append(new Parameter(summary)); + params.append(new Parameter(body)); + params.append(new Parameter(action)); + params.append(new Parameter(imageURI)); + params.append(new Parameter(count)); + params.append(new Parameter(persistent)); + stubMethodEntered("addGroup", params); + return stubReturnValue("addGroup"); +} + +uint DuiNotificationManagerStub::addGroup(const QString &eventType, bool persistent) +{ + QList params; + params.append(new Parameter(eventType)); + params.append(new Parameter(persistent)); + stubMethodEntered("addGroup", params); + return stubReturnValue("addGroup"); +} + +uint DuiNotificationManagerStub::addNotification(uint groupId, const QString &eventType, const QString &summary, const QString &body, const QString &action, const QString &imageURI, uint count, bool persistent) +{ + QList params; + params.append(new Parameter(groupId)); + params.append(new Parameter(eventType)); + params.append(new Parameter(summary)); + params.append(new Parameter(body)); + params.append(new Parameter(action)); + params.append(new Parameter(imageURI)); + params.append(new Parameter(count)); + params.append(new Parameter(persistent)); + stubMethodEntered("addNotification", params); + return stubReturnValue("addNotification"); +} + +uint DuiNotificationManagerStub::addNotification(uint groupId, const QString &eventType, bool persistent) +{ + QList params; + params.append(new Parameter(groupId)); + params.append(new Parameter(eventType)); + params.append(new Parameter(persistent)); + stubMethodEntered("addNotification", params); + return stubReturnValue("addNotification"); +} + +bool DuiNotificationManagerStub::removeGroup(uint groupId) +{ + QList params; + params.append(new Parameter(groupId)); + stubMethodEntered("removeGroup", params); + return stubReturnValue("removeGroup"); +} + +bool DuiNotificationManagerStub::removeNotification(uint notificationId) +{ + QList params; + params.append(new Parameter(notificationId)); + stubMethodEntered("removeNotification", params); + return stubReturnValue("removeNotification"); +} + +bool DuiNotificationManagerStub::updateGroup(uint groupId, const QString &eventType, const QString &summary, const QString &body, const QString &action, const QString &imageURI, uint count) +{ + QList params; + params.append(new Parameter(groupId)); + params.append(new Parameter(eventType)); + params.append(new Parameter(summary)); + params.append(new Parameter(body)); + params.append(new Parameter(action)); + params.append(new Parameter(imageURI)); + params.append(new Parameter(count)); + stubMethodEntered("updateGroup", params); + return stubReturnValue("updateGroup"); +} + +bool DuiNotificationManagerStub::updateGroup(uint groupId, const QString &eventType) +{ + QList params; + params.append(new Parameter(groupId)); + params.append(new Parameter(eventType)); + stubMethodEntered("updateGroup", params); + return stubReturnValue("updateGroup"); +} + +bool DuiNotificationManagerStub::updateNotification(uint notificationId, const QString &eventType, const QString &summary, const QString &body, const QString &action, const QString &imageURI, uint count) +{ + QList params; + params.append(new Parameter(notificationId)); + params.append(new Parameter(eventType)); + params.append(new Parameter(summary)); + params.append(new Parameter(body)); + params.append(new Parameter(action)); + params.append(new Parameter(imageURI)); + params.append(new Parameter(count)); + stubMethodEntered("updateNotification", params); + return stubReturnValue("updateNotification"); +} + +bool DuiNotificationManagerStub::updateNotification(uint notificationId, const QString &eventType) +{ + QList params; + params.append(new Parameter(notificationId)); + params.append(new Parameter(eventType)); + stubMethodEntered("updateNotification", params); + return stubReturnValue("updateNotification"); +} + +QList DuiNotificationManagerStub::notificationIdList() +{ + stubMethodEntered("notificationIdList"); + return stubReturnValue >("notificationIdList"); +} + + + +// 3. CREATE A STUB INSTANCE +DuiNotificationManagerStub gDefaultDuiNotificationManagerStub; +DuiNotificationManagerStub *gDuiNotificationManagerStub = &gDefaultDuiNotificationManagerStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiNotificationManager::DuiNotificationManager() : proxy(QString(), QString(), QDBusConnection::sessionBus()) +{ + gDuiNotificationManagerStub->DuiNotificationManagerConstructor(); +} + +DuiNotificationManager::~DuiNotificationManager() +{ + gDuiNotificationManagerStub->DuiNotificationManagerDestructor(); +} + +DuiNotificationManager *DuiNotificationManager::instance() +{ + static DuiNotificationManager manager; + return &manager; +} + +uint DuiNotificationManager::addGroup(const QString &eventType, const QString &summary, const QString &body, const QString &action, const QString &imageURI, uint count, bool persistent) +{ + return gDuiNotificationManagerStub->addGroup(eventType, summary, body, action, imageURI, count, persistent); +} + +uint DuiNotificationManager::addGroup(const QString &eventType, bool persistent) +{ + return gDuiNotificationManagerStub->addGroup(eventType, persistent); +} + +uint DuiNotificationManager::addNotification(uint groupId, const QString &eventType, const QString &summary, const QString &body, const QString &action, const QString &imageURI, uint count, bool persistent) +{ + return gDuiNotificationManagerStub->addNotification(groupId, eventType, summary, body, action, imageURI, count, persistent); +} + +uint DuiNotificationManager::addNotification(uint groupId, const QString &eventType, bool persistent) +{ + return gDuiNotificationManagerStub->addNotification(groupId, eventType, persistent); +} + +bool DuiNotificationManager::removeGroup(uint groupId) +{ + return gDuiNotificationManagerStub->removeGroup(groupId); +} + +bool DuiNotificationManager::removeNotification(uint notificationId) +{ + return gDuiNotificationManagerStub->removeNotification(notificationId); +} + +bool DuiNotificationManager::updateGroup(uint groupId, const QString &eventType, const QString &summary, const QString &body, const QString &action, const QString &imageURI, uint count) +{ + return gDuiNotificationManagerStub->updateGroup(groupId, eventType, summary, body, action, imageURI, count); +} + +bool DuiNotificationManager::updateGroup(uint groupId, const QString &eventType) +{ + return gDuiNotificationManagerStub->updateGroup(groupId, eventType); +} + +bool DuiNotificationManager::updateNotification(uint notificationId, const QString &eventType, const QString &summary, const QString &body, const QString &action, const QString &imageURI, uint count) +{ + return gDuiNotificationManagerStub->updateNotification(notificationId, eventType, summary, body, action, imageURI, count); +} + +bool DuiNotificationManager::updateNotification(uint notificationId, const QString &eventType) +{ + return gDuiNotificationManagerStub->updateNotification(notificationId, eventType); +} + +QList DuiNotificationManager::notificationIdList() +{ + return gDuiNotificationManagerStub->notificationIdList(); +} + +DuiNotificationManagerProxy::DuiNotificationManagerProxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) + : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) +{ +} + +DuiNotificationManagerProxy::~DuiNotificationManagerProxy() +{ +} + +#endif diff --git a/tests/stubs/duiobjectmenu_stub.h b/tests/stubs/duiobjectmenu_stub.h new file mode 100644 index 000000000..8004f7857 --- /dev/null +++ b/tests/stubs/duiobjectmenu_stub.h @@ -0,0 +1,94 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIOBJECTMENU_STUB +#define DUIOBJECTMENU_STUB + +#include "duiobjectmenu.h" +#include "duiscenewindowprivate_stub.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiObjectMenuStub : public StubBase +{ +public: + virtual void DuiObjectMenuConstructor(DuiWidget *target); + virtual void DuiObjectMenuDestructor(); + virtual bool eventFilter(QObject *obj, QEvent *event); + virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent *event); +}; + +// 2. IMPLEMENT STUB +void DuiObjectMenuStub::DuiObjectMenuConstructor(DuiWidget *target) +{ + Q_UNUSED(target); + +} +void DuiObjectMenuStub::DuiObjectMenuDestructor() +{ + +} +bool DuiObjectMenuStub::eventFilter(QObject *obj, QEvent *event) +{ + QList params; + params.append(new Parameter(obj)); + params.append(new Parameter(event)); + stubMethodEntered("eventFilter", params); + return stubReturnValue("eventFilter"); +} + +void DuiObjectMenuStub::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) +{ + QList params; + params.append(new Parameter(event)); + stubMethodEntered("contextMenuEvent", params); +} + + + +// 3. CREATE A STUB INSTANCE +DuiObjectMenuStub gDefaultDuiObjectMenuStub; +DuiObjectMenuStub *gDuiObjectMenuStub = &gDefaultDuiObjectMenuStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiObjectMenu::DuiObjectMenu(DuiWidget *target) : DuiSceneWindow(new DuiSceneWindowPrivate, new DuiObjectMenuModel, DuiSceneWindow::ObjectMenu) +{ + gDuiObjectMenuStub->DuiObjectMenuConstructor(target); +} + +DuiObjectMenu::~DuiObjectMenu() +{ + gDuiObjectMenuStub->DuiObjectMenuDestructor(); +} + +bool DuiObjectMenu::eventFilter(QObject *obj, QEvent *event) +{ + return gDuiObjectMenuStub->eventFilter(obj, event); +} + +void DuiObjectMenu::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) +{ + gDuiObjectMenuStub->contextMenuEvent(event); +} + + +#endif diff --git a/tests/stubs/duipannableviewport_stub.h b/tests/stubs/duipannableviewport_stub.h new file mode 100644 index 000000000..b909f8b68 --- /dev/null +++ b/tests/stubs/duipannableviewport_stub.h @@ -0,0 +1,168 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIPANNABLEVIEWPORT_STUB +#define DUIPANNABLEVIEWPORT_STUB + +#include "duipannableviewport.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiPannableViewportStub : public StubBase +{ +public: + virtual void DuiPannableViewportConstructor(Qt::Orientations direction, DuiWidget *parent); + virtual void DuiPannableViewportDestructor(); + virtual void updateStyle(); + virtual QGraphicsWidget *setWidget(QGraphicsWidget *widget); + virtual void setGeometry(const QRectF &rect); + virtual QRectF boundingRect() const; + virtual QPainterPath shape() const; + virtual bool event(QEvent *event); + virtual void updatePosition(QPointF const &pos); + DuiPannableViewportPrivate *d_ptr ; + virtual QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const; +}; + +// 2. IMPLEMENT STUB +void DuiPannableViewportStub::DuiPannableViewportConstructor(Qt::Orientations direction, DuiWidget *parent) +{ + Q_UNUSED(direction); + Q_UNUSED(parent); + +} +void DuiPannableViewportStub::DuiPannableViewportDestructor() +{ + +} +void DuiPannableViewportStub::updateStyle() +{ + stubMethodEntered("updateStyle"); +} + +QGraphicsWidget *DuiPannableViewportStub::setWidget(QGraphicsWidget *widget) +{ + QList params; + params.append(new Parameter(widget)); + stubMethodEntered("setWidget", params); + return stubReturnValue("setWidget"); +} + +void DuiPannableViewportStub::setGeometry(const QRectF &rect) +{ + QList params; + params.append(new Parameter(rect)); + stubMethodEntered("setGeometry", params); +} + +QRectF DuiPannableViewportStub::boundingRect() const +{ + stubMethodEntered("boundingRect"); + return stubReturnValue("boundingRect"); +} + +QPainterPath DuiPannableViewportStub::shape() const +{ + stubMethodEntered("shape"); + return stubReturnValue("shape"); +} + +bool DuiPannableViewportStub::event(QEvent *event) +{ + QList params; + params.append(new Parameter(event)); + stubMethodEntered("event", params); + return stubReturnValue("event"); +} + +void DuiPannableViewportStub::updatePosition(QPointF const &pos) +{ + QList params; + params.append(new Parameter(pos)); + stubMethodEntered("updatePosition", params); +} + +QSizeF DuiPannableViewportStub::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const +{ + QList params; + params.append(new Parameter(which)); + params.append(new Parameter(constraint)); + stubMethodEntered("sizeHint", params); + return stubReturnValue("sizeHint"); +} + +// 3. CREATE A STUB INSTANCE +DuiPannableViewportStub gDefaultDuiPannableViewportStub; +DuiPannableViewportStub *gDuiPannableViewportStub = &gDefaultDuiPannableViewportStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiPannableViewport::DuiPannableViewport(Qt::Orientations direction, DuiWidget *parent) +{ + gDuiPannableViewportStub->DuiPannableViewportConstructor(direction, parent); +} + +DuiPannableViewport::~DuiPannableViewport() +{ + gDuiPannableViewportStub->DuiPannableViewportDestructor(); +} + +void DuiPannableViewport::updateStyle() +{ + gDuiPannableViewportStub->updateStyle(); +} + +QGraphicsWidget *DuiPannableViewport::setWidget(QGraphicsWidget *widget) +{ + return gDuiPannableViewportStub->setWidget(widget); +} + +void DuiPannableViewport::setGeometry(const QRectF &rect) +{ + gDuiPannableViewportStub->setGeometry(rect); +} + +QRectF DuiPannableViewport::boundingRect() const +{ + return gDuiPannableViewportStub->boundingRect(); +} + +QPainterPath DuiPannableViewport::shape() const +{ + return gDuiPannableViewportStub->shape(); +} + +bool DuiPannableViewport::event(QEvent *event) +{ + return gDuiPannableViewportStub->event(event); +} + +void DuiPannableViewport::updatePosition(QPointF const &pos) +{ + gDuiPannableViewportStub->updatePosition(pos); +} + +QSizeF DuiPannableViewport::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const +{ + return gDuiPannableViewportStub->sizeHint(which, constraint); +} + +#endif diff --git a/tests/stubs/duipannablewidget_stub.h b/tests/stubs/duipannablewidget_stub.h new file mode 100644 index 000000000..bf71d494f --- /dev/null +++ b/tests/stubs/duipannablewidget_stub.h @@ -0,0 +1,244 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIPANNABLEWIDGET_STUB +#define DUIPANNABLEWIDGET_STUB + +#include "duipannablewidget.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiPannableWidgetStub : public StubBase +{ +public: + virtual void DuiPannableWidgetConstructor(Qt::Orientations direction, DuiWidget *parent); + virtual void DuiPannableWidgetDestructor(); + virtual void updateStyle(); + virtual bool panningEnabled(Qt::Orientations const direction) const; + virtual void setPhysics(DuiPhysics2DPanning *physics); + virtual DuiPhysics2DPanning *physics() const; + virtual bool sceneEvent(QEvent *event); + virtual bool sceneEventFilter(QGraphicsItem *watched, QEvent *event); + virtual void timeOut(); + virtual void updatePosition(QPointF const &pos); + virtual bool checkForResent(QGraphicsItem *watched, QEvent *event); + virtual void myMousePressEvent(QGraphicsSceneMouseEvent *event, QGraphicsItem *watched); + virtual bool myMouseReleaseEvent(QGraphicsSceneMouseEvent *event, QGraphicsItem *watched); + virtual bool myMouseMoveEvent(QGraphicsSceneMouseEvent *event, QGraphicsItem *watched); + virtual void resendEvent(QGraphicsSceneMouseEvent *event, QGraphicsItem *watched); + DuiPannableWidgetPrivate *d_ptr ; +}; + +// 2. IMPLEMENT STUB +void DuiPannableWidgetStub::DuiPannableWidgetConstructor(Qt::Orientations direction, DuiWidget *parent) +{ + Q_UNUSED(direction); + Q_UNUSED(parent); + +} +void DuiPannableWidgetStub::DuiPannableWidgetDestructor() +{ + +} + +void DuiPannableWidgetStub::updateStyle() +{ + stubMethodEntered("updateStyle"); +} + +bool DuiPannableWidgetStub::panningEnabled(Qt::Orientations const direction) const +{ + QList params; + params.append(new Parameter(direction)); + stubMethodEntered("panningEnabled", params); + return stubReturnValue("panningEnabled"); +} + +void DuiPannableWidgetStub::setPhysics(DuiPhysics2DPanning *physics) +{ + QList params; + params.append(new Parameter(physics)); + stubMethodEntered("setPhysics", params); +} + +DuiPhysics2DPanning *DuiPannableWidgetStub::physics() const +{ + stubMethodEntered("physics"); + return stubReturnValue("physics"); +} + +bool DuiPannableWidgetStub::sceneEvent(QEvent *event) +{ + QList params; + params.append(new Parameter(event)); + stubMethodEntered("sceneEvent", params); + return stubReturnValue("sceneEvent"); +} + +bool DuiPannableWidgetStub::sceneEventFilter(QGraphicsItem *watched, QEvent *event) +{ + QList params; + params.append(new Parameter(watched)); + params.append(new Parameter(event)); + stubMethodEntered("sceneEventFilter", params); + return stubReturnValue("sceneEventFilter"); +} + +void DuiPannableWidgetStub::timeOut() +{ + stubMethodEntered("timeOut"); +} + +void DuiPannableWidgetStub::updatePosition(QPointF const &pos) +{ + QList params; + params.append(new Parameter(pos)); + stubMethodEntered("updatePosition", params); +} + +bool DuiPannableWidgetStub::checkForResent(QGraphicsItem *watched, QEvent *event) +{ + QList params; + params.append(new Parameter(watched)); + params.append(new Parameter(event)); + stubMethodEntered("checkForResent", params); + return stubReturnValue("checkForResent"); +} + +void DuiPannableWidgetStub::myMousePressEvent(QGraphicsSceneMouseEvent *event, QGraphicsItem *watched) +{ + QList params; + params.append(new Parameter(event)); + params.append(new Parameter(watched)); + stubMethodEntered("myMousePressEvent", params); +} + +bool DuiPannableWidgetStub::myMouseReleaseEvent(QGraphicsSceneMouseEvent *event, QGraphicsItem *watched) +{ + QList params; + params.append(new Parameter(event)); + params.append(new Parameter(watched)); + stubMethodEntered("myMouseReleaseEvent", params); + return stubReturnValue("myMouseReleaseEvent"); +} + +bool DuiPannableWidgetStub::myMouseMoveEvent(QGraphicsSceneMouseEvent *event, QGraphicsItem *watched) +{ + QList params; + params.append(new Parameter(event)); + params.append(new Parameter(watched)); + stubMethodEntered("myMouseMoveEvent", params); + return stubReturnValue("myMouseMoveEvent"); +} + +void DuiPannableWidgetStub::resendEvent(QGraphicsSceneMouseEvent *event, QGraphicsItem *watched) +{ + QList params; + params.append(new Parameter(event)); + params.append(new Parameter(watched)); + stubMethodEntered("resendEvent", params); +} + + + +// 3. CREATE A STUB INSTANCE +DuiPannableWidgetStub gDefaultDuiPannableWidgetStub; +DuiPannableWidgetStub *gDuiPannableWidgetStub = &gDefaultDuiPannableWidgetStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiPannableWidget::DuiPannableWidget(Qt::Orientations direction, DuiWidget *parent) +{ + gDuiPannableWidgetStub->DuiPannableWidgetConstructor(direction, parent); +} + +DuiPannableWidget::~DuiPannableWidget() +{ + gDuiPannableWidgetStub->DuiPannableWidgetDestructor(); +} + +void DuiPannableWidget::updateStyle() +{ + gDuiPannableWidgetStub->updateStyle(); +} + +bool DuiPannableWidget::panningEnabled(Qt::Orientations const direction) const +{ + return gDuiPannableWidgetStub->panningEnabled(direction); +} + +void DuiPannableWidget::setPhysics(DuiPhysics2DPanning *physics) +{ + gDuiPannableWidgetStub->setPhysics(physics); +} + +DuiPhysics2DPanning *DuiPannableWidget::physics(void) const +{ + return gDuiPannableWidgetStub->physics(); +} + +bool DuiPannableWidget::sceneEvent(QEvent *event) +{ + return gDuiPannableWidgetStub->sceneEvent(event); +} + +bool DuiPannableWidget::sceneEventFilter(QGraphicsItem *watched, QEvent *event) +{ + return gDuiPannableWidgetStub->sceneEventFilter(watched, event); +} + +void DuiPannableWidget::timeOut(void) +{ + gDuiPannableWidgetStub->timeOut(); +} + +void DuiPannableWidget::updatePosition(QPointF const &pos) +{ + gDuiPannableWidgetStub->updatePosition(pos); +} + +bool DuiPannableWidget::checkForResent(QGraphicsItem *watched, QEvent *event) +{ + return gDuiPannableWidgetStub->checkForResent(watched, event); +} + +void DuiPannableWidget::myMousePressEvent(QGraphicsSceneMouseEvent *event, QGraphicsItem *watched) +{ + gDuiPannableWidgetStub->myMousePressEvent(event, watched); +} + +bool DuiPannableWidget::myMouseReleaseEvent(QGraphicsSceneMouseEvent *event, QGraphicsItem *watched) +{ + return gDuiPannableWidgetStub->myMouseReleaseEvent(event, watched); +} + +bool DuiPannableWidget::myMouseMoveEvent(QGraphicsSceneMouseEvent *event, QGraphicsItem *watched) +{ + return gDuiPannableWidgetStub->myMouseMoveEvent(event, watched); +} + +void DuiPannableWidget::resendEvent(QGraphicsSceneMouseEvent *event, QGraphicsItem *watched) +{ + gDuiPannableWidgetStub->resendEvent(event, watched); +} + + +#endif diff --git a/tests/stubs/duiphysics2dpanning_stub.h b/tests/stubs/duiphysics2dpanning_stub.h new file mode 100644 index 000000000..24e936c62 --- /dev/null +++ b/tests/stubs/duiphysics2dpanning_stub.h @@ -0,0 +1,224 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIPHYSICS2DPANNING_STUB +#define DUIPHYSICS2DPANNING_STUB + +#include "duiphysics2dpanning.h" +#include "duiphysics2dpanning_p.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiPhysics2DPanningStub : public StubBase +{ +public: + virtual void DuiPhysics2DPanningConstructor(Qt::Orientations direction); + virtual void DuiPhysics2DPanningDestructor(); + virtual void start(); + virtual void stop(); + virtual void setRange(QSizeF range); + virtual QSizeF range() const; + virtual void setPosition(QPointF position); + virtual QPointF position() const; + virtual void setTimeDelta(qreal time_delta); + virtual qreal timeDelta() const; + virtual bool inMotion(); + virtual void mousePress(QPointF pos); + virtual void mouseMove(QPointF pos); + virtual void mouseRelease(); + virtual void integrator(int frame); +}; + +// 2. IMPLEMENT STUB +void DuiPhysics2DPanningStub::DuiPhysics2DPanningConstructor(Qt::Orientations direction) +{ + Q_UNUSED(direction); +} + +void DuiPhysics2DPanningStub::DuiPhysics2DPanningDestructor() +{ +} + +void DuiPhysics2DPanningStub::start() +{ + stubMethodEntered("start"); +} + +void DuiPhysics2DPanningStub::stop() +{ + stubMethodEntered("stop"); +} + +void DuiPhysics2DPanningStub::setRange(QSizeF range) +{ + QList params; + params.append(new Parameter(range)); + stubMethodEntered("setRange", params); +} + +QSizeF DuiPhysics2DPanningStub::range() const +{ + stubMethodEntered("range"); + return stubReturnValue("range"); +} + +void DuiPhysics2DPanningStub::setPosition(QPointF position) +{ + QList params; + params.append(new Parameter(position)); + stubMethodEntered("setPosition", params); +} + +QPointF DuiPhysics2DPanningStub::position() const +{ + stubMethodEntered("position"); + return stubReturnValue("position"); +} + +void DuiPhysics2DPanningStub::setTimeDelta(qreal time_delta) +{ + QList params; + params.append(new Parameter(time_delta)); + stubMethodEntered("setTimeDelta", params); +} + +qreal DuiPhysics2DPanningStub::timeDelta() const +{ + stubMethodEntered("timeDelta"); + return stubReturnValue("timeDelta"); +} + +bool DuiPhysics2DPanningStub::inMotion() +{ + stubMethodEntered("inMotion"); + return stubReturnValue("inMotion"); +} + +void DuiPhysics2DPanningStub::mousePress(QPointF pos) +{ + QList params; + params.append(new Parameter(pos)); + stubMethodEntered("mousePress", params); +} + +void DuiPhysics2DPanningStub::mouseMove(QPointF pos) +{ + QList params; + params.append(new Parameter(pos)); + stubMethodEntered("mouseMove", params); +} + +void DuiPhysics2DPanningStub::mouseRelease() +{ + stubMethodEntered("mouseRelease"); +} + +void DuiPhysics2DPanningStub::integrator(int frame) +{ + QList params; + params.append(new Parameter(frame)); + stubMethodEntered("integrator", params); +} + + +// 3. CREATE A STUB INSTANCE +DuiPhysics2DPanningStub gDefaultDuiPhysics2DPanningStub; +DuiPhysics2DPanningStub *gDuiPhysics2DPanningStub = &gDefaultDuiPhysics2DPanningStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiPhysics2DPanning::DuiPhysics2DPanning(Qt::Orientations direction) + : d_ptr(new DuiPhysics2DPanningPrivate(direction)) +{ + gDuiPhysics2DPanningStub->DuiPhysics2DPanningConstructor(direction); +} + +DuiPhysics2DPanning::~DuiPhysics2DPanning() +{ + gDuiPhysics2DPanningStub->DuiPhysics2DPanningDestructor(); +} + +void DuiPhysics2DPanning::start() +{ + gDuiPhysics2DPanningStub->start(); +} + +void DuiPhysics2DPanning::stop() +{ + gDuiPhysics2DPanningStub->stop(); +} + +void DuiPhysics2DPanning::setRange(QSizeF range) +{ + gDuiPhysics2DPanningStub->setRange(range); +} + +QSizeF DuiPhysics2DPanning::range() const +{ + return gDuiPhysics2DPanningStub->range(); +} + +void DuiPhysics2DPanning::setPosition(QPointF position) +{ + gDuiPhysics2DPanningStub->setPosition(position); +} + +QPointF DuiPhysics2DPanning::position() const +{ + return gDuiPhysics2DPanningStub->position(); +} + +void DuiPhysics2DPanning::setTimeDelta(qreal time_delta) +{ + gDuiPhysics2DPanningStub->setTimeDelta(time_delta); +} + +qreal DuiPhysics2DPanning::timeDelta() const +{ + return gDuiPhysics2DPanningStub->timeDelta(); +} + +bool DuiPhysics2DPanning::inMotion() const +{ + return gDuiPhysics2DPanningStub->inMotion(); +} + +void DuiPhysics2DPanning::mousePress(QPointF pos) +{ + gDuiPhysics2DPanningStub->mousePress(pos); +} + +void DuiPhysics2DPanning::mouseMove(QPointF pos) +{ + gDuiPhysics2DPanningStub->mouseMove(pos); +} + +void DuiPhysics2DPanning::mouseRelease() +{ + gDuiPhysics2DPanningStub->mouseRelease(); +} + +void DuiPhysics2DPanning::integrator(int frame) +{ + gDuiPhysics2DPanningStub->integrator(frame); +} + +#endif diff --git a/tests/stubs/duipixmaploader_stub.h b/tests/stubs/duipixmaploader_stub.h new file mode 100644 index 000000000..cbb9f8f4d --- /dev/null +++ b/tests/stubs/duipixmaploader_stub.h @@ -0,0 +1,261 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIPIXMAPLOADER_STUB +#define DUIPIXMAPLOADER_STUB + +#include "duipixmaploader.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiPixmapLoaderStub : public StubBase +{ +public: + virtual void DuiPixmapLoaderConstructor(); + virtual void DuiPixmapLoaderDestructor(); + virtual bool addDirectoryToPixmapSearchListRecursive(const QString &applicationName, int version, const QString &directoryName); + virtual bool addDirectoryToPixmapSearchList(const QString &applicationName, int version, const QString &directoryName); + virtual int pixmapHandle(const QString &applicationName, int version, const QString &pixmapName, int width, int height); + virtual bool releasePixmap(int handle); + virtual bool deletePixmapSearchList(const QString &applicationName, int version); + virtual bool addFileToPixmapSearchList(const QString &applicationName, int version, const QString &fileName); + virtual QString getFileForElement(const QString &applicationName, int version, const QString &pixmapName); + virtual PixmapSearchList *getPixmapSearchListForApplication(const QString &applicationName, int version); + virtual SharedPixmap *getSharedPixmap(const QString &filename, const QString &elementName, int width, int height); + virtual int getSharedPixmapHandle(const QString &filename, const QString &elementName, int width, int height); + virtual bool existsSharedPixmap(const QString &filename, const QString &elementName, int width, int height); + virtual bool addSharedPixmap(const QString &filename, int pixmapHandle, const QString &elementName, int width, int height); + DuiPixmapLoaderPrivate *d_ptr ; +}; + +// 2. IMPLEMENT STUB +void DuiPixmapLoaderStub::DuiPixmapLoaderConstructor() +{ + +} + +void DuiPixmapLoaderStub::DuiPixmapLoaderDestructor() +{ + +} + +bool DuiPixmapLoaderStub::addDirectoryToPixmapSearchListRecursive(const QString &applicationName, int version, const QString &directoryName) +{ + QList params; + params.append(new Parameter(applicationName)); + params.append(new Parameter(version)); + params.append(new Parameter(directoryName)); + stubMethodEntered("addDirectoryToPixmapSearchListRecursive", params); + return stubReturnValue("addDirectoryToPixmapSearchListRecursive"); +} + +bool DuiPixmapLoaderStub::addDirectoryToPixmapSearchList(const QString &applicationName, int version, const QString &directoryName) +{ + QList params; + params.append(new Parameter(applicationName)); + params.append(new Parameter(version)); + params.append(new Parameter(directoryName)); + stubMethodEntered("addDirectoryToPixmapSearchList", params); + return stubReturnValue("addDirectoryToPixmapSearchList"); +} + +int DuiPixmapLoaderStub::pixmapHandle(const QString &applicationName, int version, const QString &pixmapName, int width, int height) +{ + QList params; + params.append(new Parameter(applicationName)); + params.append(new Parameter(version)); + params.append(new Parameter(pixmapName)); + params.append(new Parameter(width)); + params.append(new Parameter(height)); + stubMethodEntered("pixmapHandle", params); + return stubReturnValue("pixmapHandle"); +} + +bool DuiPixmapLoaderStub::releasePixmap(int handle) +{ + QList params; + params.append(new Parameter(handle)); + stubMethodEntered("releasePixmap", params); + return stubReturnValue("releasePixmap"); +} + +bool DuiPixmapLoaderStub::deletePixmapSearchList(const QString &applicationName, int version) +{ + QList params; + params.append(new Parameter(applicationName)); + params.append(new Parameter(version)); + stubMethodEntered("deletePixmapSearchList", params); + return stubReturnValue("deletePixmapSearchList"); +} + +bool DuiPixmapLoaderStub::addFileToPixmapSearchList(const QString &applicationName, int version, const QString &fileName) +{ + QList params; + params.append(new Parameter(applicationName)); + params.append(new Parameter(version)); + params.append(new Parameter(fileName)); + stubMethodEntered("addFileToPixmapSearchList", params); + return stubReturnValue("addFileToPixmapSearchList"); +} + +QString DuiPixmapLoaderStub::getFileForElement(const QString &applicationName, int version, const QString &pixmapName) +{ + QList params; + params.append(new Parameter(applicationName)); + params.append(new Parameter(version)); + params.append(new Parameter(pixmapName)); + stubMethodEntered("getFileForElement", params); + return stubReturnValue("getFileForElement"); +} + +PixmapSearchList *DuiPixmapLoaderStub::getPixmapSearchListForApplication(const QString &applicationName, int version) +{ + QList params; + params.append(new Parameter(applicationName)); + params.append(new Parameter(version)); + stubMethodEntered("getPixmapSearchListForApplication", params); + return stubReturnValue("getPixmapSearchListForApplication"); +} + +SharedPixmap *DuiPixmapLoaderStub::getSharedPixmap(const QString &filename, const QString &elementName, int width, int height) +{ + QList params; + params.append(new Parameter(filename)); + params.append(new Parameter(elementName)); + params.append(new Parameter(width)); + params.append(new Parameter(height)); + stubMethodEntered("getSharedPixmap", params); + return stubReturnValue("getSharedPixmap"); +} + +int DuiPixmapLoaderStub::getSharedPixmapHandle(const QString &filename, const QString &elementName, int width, int height) +{ + QList params; + params.append(new Parameter(filename)); + params.append(new Parameter(elementName)); + params.append(new Parameter(width)); + params.append(new Parameter(height)); + stubMethodEntered("getSharedPixmapHandle", params); + return stubReturnValue("getSharedPixmapHandle"); +} + +bool DuiPixmapLoaderStub::existsSharedPixmap(const QString &filename, const QString &elementName, int width, int height) +{ + QList params; + params.append(new Parameter(filename)); + params.append(new Parameter(elementName)); + params.append(new Parameter(width)); + params.append(new Parameter(height)); + stubMethodEntered("existsSharedPixmap", params); + return stubReturnValue("existsSharedPixmap"); +} + +bool DuiPixmapLoaderStub::addSharedPixmap(const QString &filename, int pixmapHandle, const QString &elementName, int width, int height) +{ + QList params; + params.append(new Parameter(filename)); + params.append(new Parameter(pixmapHandle)); + params.append(new Parameter(elementName)); + params.append(new Parameter(width)); + params.append(new Parameter(height)); + stubMethodEntered("addSharedPixmap", params); + return stubReturnValue("addSharedPixmap"); +} + +// 3. CREATE A STUB INSTANCE +DuiPixmapLoaderStub gDefaultDuiPixmapLoaderStub; +DuiPixmapLoaderStub *gDuiPixmapLoaderStub = &gDefaultDuiPixmapLoaderStub; + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiPixmapLoader::DuiPixmapLoader() +{ + gDuiPixmapLoaderStub->DuiPixmapLoaderConstructor(); +} + +DuiPixmapLoader::~DuiPixmapLoader() +{ + gDuiPixmapLoaderStub->DuiPixmapLoaderDestructor(); +} + +bool DuiPixmapLoader::addDirectoryToPixmapSearchListRecursive(const QString &applicationName, int version, const QString &directoryName) +{ + return gDuiPixmapLoaderStub->addDirectoryToPixmapSearchListRecursive(applicationName, version, directoryName); +} + +bool DuiPixmapLoader::addDirectoryToPixmapSearchList(const QString &applicationName, int version, const QString &directoryName) +{ + return gDuiPixmapLoaderStub->addDirectoryToPixmapSearchList(applicationName, version, directoryName); +} + +int DuiPixmapLoader::pixmapHandle(const QString &applicationName, int version, const QString &pixmapName, int width, int height, bool usePngSizes) +{ + return gDuiPixmapLoaderStub->pixmapHandle(applicationName, version, pixmapName, width, height); +} + +bool DuiPixmapLoader::releasePixmap(int handle) +{ + return gDuiPixmapLoaderStub->releasePixmap(handle); +} + +bool DuiPixmapLoader::deletePixmapSearchList(const QString &applicationName, int version) +{ + return gDuiPixmapLoaderStub->deletePixmapSearchList(applicationName, version); +} + +bool DuiPixmapLoader::addFileToPixmapSearchList(const QString &applicationName, int version, const QString &fileName) +{ + return gDuiPixmapLoaderStub->addFileToPixmapSearchList(applicationName, version, fileName); +} + +QString DuiPixmapLoader::getFileForElement(const QString &applicationName, int version, const QString &pixmapName) +{ + return gDuiPixmapLoaderStub->getFileForElement(applicationName, version, pixmapName); +} + +PixmapSearchList *DuiPixmapLoader::getPixmapSearchListForApplication(const QString &applicationName, int version) +{ + return gDuiPixmapLoaderStub->getPixmapSearchListForApplication(applicationName, version); +} + +SharedPixmap *DuiPixmapLoader::getSharedPixmap(const QString &filename, const QString &elementName, int width, int height, + bool usePngSizes) +{ + return gDuiPixmapLoaderStub->getSharedPixmap(filename, elementName, width, height); +} + +int DuiPixmapLoader::getSharedPixmapHandle(const QString &filename, const QString &elementName, int width, int height) +{ + return gDuiPixmapLoaderStub->getSharedPixmapHandle(filename, elementName, width, height); +} + +bool DuiPixmapLoader::existsSharedPixmap(const QString &filename, const QString &elementName, int width, int height) +{ + return gDuiPixmapLoaderStub->existsSharedPixmap(filename, elementName, width, height); +} + +bool DuiPixmapLoader::addSharedPixmap(const QString &filename, int pixmapHandle, const QString &elementName, int width, int height) +{ + return gDuiPixmapLoaderStub->addSharedPixmap(filename, pixmapHandle, elementName, width, height); +} + + + +#endif diff --git a/tests/stubs/duipositionindicator_stub.h b/tests/stubs/duipositionindicator_stub.h new file mode 100644 index 000000000..08c9c6ca0 --- /dev/null +++ b/tests/stubs/duipositionindicator_stub.h @@ -0,0 +1,118 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIPOSITIONINDICATOR_STUB_H +#define DUIPOSITIONINDICATOR_STUB_H + +#include +#include +class DuiPositionIndicatorStub + : public StubBase +{ +public: + virtual void duiPositionIndicatorConstructor(Qt::Orientations panningDirection, DuiWidget *parent); + virtual void duiPositionIndicatorDestructor(); + virtual void setView(DuiWidgetView *view); + + virtual void updatePosData(const QPointF &); + virtual void updateSizeData(const QSizeF &, const QSizeF &); + virtual void show(); + virtual void hide(); + virtual QSizeF pannableViewportSize() const; +}; + +void DuiPositionIndicatorStub::duiPositionIndicatorConstructor(Qt::Orientations panningDirection, DuiWidget *parent) +{ + Q_UNUSED(parent); + Q_UNUSED(panningDirection); +} + +void DuiPositionIndicatorStub::duiPositionIndicatorDestructor() +{ +} + +void DuiPositionIndicatorStub::setView(DuiWidgetView *view) +{ + QList params; + params.append(new Parameter(view)); + stubMethodEntered("setView", params); + Q_UNUSED(view); +} +void DuiPositionIndicatorStub::updatePosData(const QPointF &pos) +{ + QList params; + params.append(new Parameter(pos)); + stubMethodEntered("updatePosData", params); + +} +void DuiPositionIndicatorStub::updateSizeData(const QSizeF &pannedWidgetSize, const QSizeF &pannableViewportSize) +{ + QList params; + params.append(new Parameter(pannedWidgetSize)); + params.append(new Parameter(pannableViewportSize)); + stubMethodEntered("updateSizeData", params); +} +void DuiPositionIndicatorStub::show() +{ + stubMethodEntered("show"); +} +void DuiPositionIndicatorStub::hide() +{ + stubMethodEntered("hide"); +} + +QSizeF DuiPositionIndicatorStub::pannableViewportSize() const +{ + stubMethodEntered("pannableViewportSize"); + return stubReturnValue("pannableViewportSize"); +} + +DuiPositionIndicatorStub gDefaultDuiPositionIndicatorStub; +DuiPositionIndicatorStub *gDuiPositionIndicatorStub = &gDefaultDuiPositionIndicatorStub; + +DuiPositionIndicator::DuiPositionIndicator(Qt::Orientations panningDirection, DuiWidget *parent) : d_ptr(0) +{ + gDuiPositionIndicatorStub->duiPositionIndicatorConstructor(panningDirection, parent); +} + +DuiPositionIndicator::~DuiPositionIndicator() +{ + gDuiPositionIndicatorStub->duiPositionIndicatorDestructor(); +} + +void DuiPositionIndicator::setView(DuiWidgetView *view) +{ + gDuiPositionIndicatorStub->setView(view); +} +void DuiPositionIndicator::show() +{ + gDuiPositionIndicatorStub->show(); +} + +void DuiPositionIndicator::hide() +{ + gDuiPositionIndicatorStub->hide(); +} + +QSizeF DuiPositionIndicator::pannableViewportSize() const +{ + return gDuiPositionIndicatorStub->pannableViewportSize(); +} + +#endif diff --git a/tests/stubs/duipositionindicatorview_stub.h b/tests/stubs/duipositionindicatorview_stub.h new file mode 100644 index 000000000..0e8aa4c3e --- /dev/null +++ b/tests/stubs/duipositionindicatorview_stub.h @@ -0,0 +1,98 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIPOSITIONINDICATORVIEW_STUB +#define DUIPOSITIONINDICATORVIEW_STUB + +#include "duipositionindicatorview.h" +#include + + +// 1. DECLARE STUB +class DuiPositionIndicatorViewStub : public StubBase +{ +public: + virtual void DuiPositionIndicatorViewConstructor(DuiPositionIndicator *controller); + virtual void DuiPositionIndicatorViewDestructor(); + virtual QRectF boundingRect() const; + virtual QPainterPath shape() const; +// virtual void styleUpdated(); + //DuiPositionIndicatorViewPrivate *d_ptr ; +}; + +// 2. IMPLEMENT STUB +void DuiPositionIndicatorViewStub::DuiPositionIndicatorViewConstructor(DuiPositionIndicator *controller) +{ + Q_UNUSED(controller); + +} +void DuiPositionIndicatorViewStub::DuiPositionIndicatorViewDestructor() +{ + +} + + +QRectF DuiPositionIndicatorViewStub::boundingRect() const +{ + stubMethodEntered("boundingRect"); + return stubReturnValue("boundingRect"); +} + +QPainterPath DuiPositionIndicatorViewStub::shape() const +{ + stubMethodEntered("shape"); + return stubReturnValue("shape"); +} +/*void DuiPositionIndicatorViewStub::styleUpdated() +{ + stubMethodEntered("styleUpdated"); +} +*/ +// 3. CREATE A STUB INSTANCE +DuiPositionIndicatorViewStub gDefaultDuiPositionIndicatorViewStub; +DuiPositionIndicatorViewStub *gDuiPositionIndicatorViewStub = &gDefaultDuiPositionIndicatorViewStub; + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiPositionIndicatorView::DuiPositionIndicatorView(DuiPositionIndicator *controller) +{ + gDuiPositionIndicatorViewStub->DuiPositionIndicatorViewConstructor(controller); +} + +DuiPositionIndicatorView::~DuiPositionIndicatorView() +{ + gDuiPositionIndicatorViewStub->DuiPositionIndicatorViewDestructor(); +} + + +QRectF DuiPositionIndicatorView::boundingRect() const +{ + return gDuiPositionIndicatorViewStub->boundingRect(); +} + +QPainterPath DuiPositionIndicatorView::shape() const +{ + return gDuiPositionIndicatorViewStub->shape(); +} +void DuiPositionIndicatorView::styleUpdated() +{ +// gDuiPositionIndicatorViewStub->styleUpdated(); +} + +#endif + diff --git a/tests/stubs/duiremoteaction_stub.h b/tests/stubs/duiremoteaction_stub.h new file mode 100644 index 000000000..409578bfb --- /dev/null +++ b/tests/stubs/duiremoteaction_stub.h @@ -0,0 +1,141 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIREMOTEACTION_STUB +#define DUIREMOTEACTION_STUB + +#include "duiremoteaction.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiRemoteActionStub : public StubBase +{ +public: + virtual void DuiRemoteActionConstructor(const QString &serviceName, const QString &objectPath, const QString &interface, const QString &methodName, const QList &arguments, QObject *parent); + virtual void DuiRemoteActionConstructor(const QString &string, QObject *parent); + virtual void DuiRemoteActionConstructor(const DuiRemoteAction &action); + virtual void DuiRemoteActionDestructor(); + virtual QString toString() const; + virtual void call(); + virtual void fromString(const QString &string); + virtual void DuiRemoteActionConstructor(DuiRemoteActionPrivate &dd, QObject *parent); +}; + +// 2. IMPLEMENT STUB +void DuiRemoteActionStub::DuiRemoteActionConstructor(const QString &serviceName, const QString &objectPath, const QString &interface, const QString &methodName, const QList &arguments, QObject *parent) +{ + Q_UNUSED(serviceName); + Q_UNUSED(objectPath); + Q_UNUSED(interface); + Q_UNUSED(methodName); + Q_UNUSED(arguments); + Q_UNUSED(parent); + +} +void DuiRemoteActionStub::DuiRemoteActionConstructor(const QString &string, QObject *parent) +{ + Q_UNUSED(string); + Q_UNUSED(parent); + +} +void DuiRemoteActionStub::DuiRemoteActionConstructor(const DuiRemoteAction &action) +{ + Q_UNUSED(action); + +} +void DuiRemoteActionStub::DuiRemoteActionDestructor() +{ + +} +QString DuiRemoteActionStub::toString() const +{ + stubMethodEntered("toString"); + return stubReturnValue("toString"); +} + +void DuiRemoteActionStub::call() +{ + stubMethodEntered("call"); +} + +void DuiRemoteActionStub::fromString(const QString &string) +{ + QList params; + params.append(new Parameter(string)); + stubMethodEntered("fromString", params); +} + +void DuiRemoteActionStub::DuiRemoteActionConstructor(DuiRemoteActionPrivate &dd, QObject *parent) +{ + Q_UNUSED(dd); + Q_UNUSED(parent); + +} + + +// 3. CREATE A STUB INSTANCE +DuiRemoteActionStub gDefaultDuiRemoteActionStub; +DuiRemoteActionStub *gDuiRemoteActionStub = &gDefaultDuiRemoteActionStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiRemoteAction::DuiRemoteAction(const QString &serviceName, const QString &objectPath, const QString &interface, const QString &methodName, const QList &arguments, QObject *parent) : DuiAction(parent) +{ + gDuiRemoteActionStub->DuiRemoteActionConstructor(serviceName, objectPath, interface, methodName, arguments, parent); +} + +DuiRemoteAction::DuiRemoteAction(const QString &string, QObject *parent) : DuiAction(parent) +{ + gDuiRemoteActionStub->DuiRemoteActionConstructor(string, parent); +} + +DuiRemoteAction::DuiRemoteAction(const DuiRemoteAction &action) : DuiAction(NULL) +{ + gDuiRemoteActionStub->DuiRemoteActionConstructor(action); +} + +DuiRemoteAction::~DuiRemoteAction() +{ + gDuiRemoteActionStub->DuiRemoteActionDestructor(); +} + +QString DuiRemoteAction::toString() const +{ + return gDuiRemoteActionStub->toString(); +} + +void DuiRemoteAction::call() +{ + gDuiRemoteActionStub->call(); +} + +void DuiRemoteAction::fromString(const QString &string) +{ + gDuiRemoteActionStub->fromString(string); +} + +DuiRemoteAction::DuiRemoteAction(DuiRemoteActionPrivate &dd, QObject *parent) : DuiAction(NULL) +{ + gDuiRemoteActionStub->DuiRemoteActionConstructor(dd, parent); +} + + +#endif diff --git a/tests/stubs/duiscene_stub.h b/tests/stubs/duiscene_stub.h new file mode 100644 index 000000000..1cf45fb86 --- /dev/null +++ b/tests/stubs/duiscene_stub.h @@ -0,0 +1,95 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISCENE_STUB +#define DUISCENE_STUB + +#include "duiscene.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiSceneStub : public StubBase +{ +public: + virtual void DuiSceneConstructor(QObject *parent); + virtual void DuiSceneDestructor(); + virtual void drawForeground(QPainter *painter, const QRectF &rect); + virtual bool event(QEvent *event); +}; + +// 2. IMPLEMENT STUB +void DuiSceneStub::DuiSceneConstructor(QObject *parent) +{ + Q_UNUSED(parent); + +} +void DuiSceneStub::DuiSceneDestructor() +{ + +} + +void DuiSceneStub::drawForeground(QPainter *painter, const QRectF &rect) +{ + QList params; + params.append(new Parameter(painter)); + params.append(new Parameter(rect)); + stubMethodEntered("drawForeground", params); +} + +bool DuiSceneStub::event(QEvent *event) +{ + QList params; + params.append(new Parameter(event)); + stubMethodEntered("event", params); + return stubReturnValue("event"); +} + + + +// 3. CREATE A STUB INSTANCE +DuiSceneStub gDefaultDuiSceneStub; +DuiSceneStub *gDuiSceneStub = &gDefaultDuiSceneStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiScene::DuiScene(QObject *parent) + : d_ptr(0) +{ + gDuiSceneStub->DuiSceneConstructor(parent); +} + +DuiScene::~DuiScene() +{ + gDuiSceneStub->DuiSceneDestructor(); +} + +void DuiScene::drawForeground(QPainter *painter, const QRectF &rect) +{ + gDuiSceneStub->drawForeground(painter, rect); +} + +bool DuiScene::event(QEvent *event) +{ + return gDuiSceneStub->event(event); +} + + +#endif diff --git a/tests/stubs/duiscenewindowprivate_stub.h b/tests/stubs/duiscenewindowprivate_stub.h new file mode 100644 index 000000000..020b5dd16 --- /dev/null +++ b/tests/stubs/duiscenewindowprivate_stub.h @@ -0,0 +1,76 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISCENEWINDOWPRIVATE_STUB +#define DUISCENEWINDOWPRIVATE_STUB + +#include "duiscenewindow_p.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiSceneWindowPrivateStub : public StubBase +{ +public: + virtual void DuiSceneWindowPrivateConstructor(); + virtual void appear(bool now, DuiWindow *window, DuiSceneWindow::DeletionPolicy policy); + DuiSceneWindow::WindowType windowType ; + DuiSceneWindow::DeletionPolicy policy ; + Qt::Alignment alignment ; + QPointF offset ; + bool managedManually ; + bool shown ; + bool dismissed ; +}; + +// 2. IMPLEMENT STUB +void DuiSceneWindowPrivateStub::DuiSceneWindowPrivateConstructor() +{ + +} +void DuiSceneWindowPrivateStub::appear(bool now, DuiWindow *window, DuiSceneWindow::DeletionPolicy policy) +{ + QList params; + params.append(new Parameter(now)); + params.append(new Parameter(window)); + params.append(new Parameter(policy)); + stubMethodEntered("appear", params); +} + + + +// 3. CREATE A STUB INSTANCE +DuiSceneWindowPrivateStub gDefaultDuiSceneWindowPrivateStub; +DuiSceneWindowPrivateStub *gDuiSceneWindowPrivateStub = &gDefaultDuiSceneWindowPrivateStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiSceneWindowPrivate::DuiSceneWindowPrivate() +{ + gDuiSceneWindowPrivateStub->DuiSceneWindowPrivateConstructor(); +} + +void DuiSceneWindowPrivate::appear(bool now, DuiWindow *window, DuiSceneWindow::DeletionPolicy policy) +{ + gDuiSceneWindowPrivateStub->appear(now, window, policy); +} + + +#endif diff --git a/tests/stubs/duiserviceaction_stub.h b/tests/stubs/duiserviceaction_stub.h new file mode 100644 index 000000000..23a3ef9fc --- /dev/null +++ b/tests/stubs/duiserviceaction_stub.h @@ -0,0 +1,88 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISERVICEACTION_STUB +#define DUISERVICEACTION_STUB + +#include "duiserviceaction.h" +#include +#include + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiServiceActionStub : public StubBase +{ +public: + virtual void DuiServiceActionConstructor(QObject *parent); + virtual void DuiServiceActionDestructor(); + virtual void executeService(); + virtual void DuiServiceActionConstructor(DuiServiceActionPrivate &dd, QObject *parent); +}; + +// 2. IMPLEMENT STUB +void DuiServiceActionStub::DuiServiceActionConstructor(QObject *parent) +{ + Q_UNUSED(parent); + +} +void DuiServiceActionStub::DuiServiceActionDestructor() +{ + +} +void DuiServiceActionStub::executeService() +{ + stubMethodEntered("executeService"); +} + +void DuiServiceActionStub::DuiServiceActionConstructor(DuiServiceActionPrivate &dd, QObject *parent) +{ + Q_UNUSED(dd); + Q_UNUSED(parent); + +} + + +// 3. CREATE A STUB INSTANCE +DuiServiceActionStub gDefaultDuiServiceActionStub; +DuiServiceActionStub *gDuiServiceActionStub = &gDefaultDuiServiceActionStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiServiceAction::DuiServiceAction(QObject *parent) : DuiAction(parent) +{ + gDuiServiceActionStub->DuiServiceActionConstructor(parent); +} + +DuiServiceAction::~DuiServiceAction() +{ + gDuiServiceActionStub->DuiServiceActionDestructor(); +} + +void DuiServiceAction::executeService() +{ + gDuiServiceActionStub->executeService(); +} + +DuiServiceAction::DuiServiceAction(DuiServiceActionPrivate &dd, QObject *parent) : DuiAction(parent) +{ + gDuiServiceActionStub->DuiServiceActionConstructor(dd, parent); +} + + +#endif diff --git a/tests/stubs/duiserviceinvoker_stub.h b/tests/stubs/duiserviceinvoker_stub.h new file mode 100644 index 000000000..d647a3b4b --- /dev/null +++ b/tests/stubs/duiserviceinvoker_stub.h @@ -0,0 +1,71 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISERVICEINVOKER_STUB +#define DUISERVICEINVOKER_STUB + +#include "duiserviceinvoker.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiServiceInvokerStub : public StubBase +{ +public: + virtual void DuiServiceInvokerConstructor(); + virtual void invoke(); +}; + +// 2. IMPLEMENT STUB +void DuiServiceInvokerStub::DuiServiceInvokerConstructor() +{ + +} + +void DuiServiceInvokerStub::invoke() +{ + stubMethodEntered("invoke"); +} + + + +// 3. CREATE A STUB INSTANCE +DuiServiceInvokerStub gDefaultDuiServiceInvokerStub; +DuiServiceInvokerStub *gDuiServiceInvokerStub = &gDefaultDuiServiceInvokerStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiServiceInvoker::DuiServiceInvoker() +{ + gDuiServiceInvokerStub->DuiServiceInvokerConstructor(); +} + +DuiServiceInvoker *DuiServiceInvoker::instance() +{ + return new DuiServiceInvoker; +} + +void DuiServiceInvoker::invoke() +{ + gDuiServiceInvokerStub->invoke(); +} + + +#endif diff --git a/tests/stubs/duisettingslanguagebinary_stub.h b/tests/stubs/duisettingslanguagebinary_stub.h new file mode 100644 index 000000000..edb1b669d --- /dev/null +++ b/tests/stubs/duisettingslanguagebinary_stub.h @@ -0,0 +1,76 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISETTINGSLANGUAGEBINARY_STUB +#define DUISETTINGSLANGUAGEBINARY_STUB + +#include "duisettingslanguagebinary.h" +#include +#include + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiSettingsLanguageBinaryStub : public StubBase +{ +public: + virtual void DuiSettingsLanguageBinaryConstructor(); + virtual void DuiSettingsLanguageBinaryDestructor(); + virtual QStringList keys() const; +}; + +// 2. IMPLEMENT STUB +void DuiSettingsLanguageBinaryStub::DuiSettingsLanguageBinaryConstructor() +{ + +} +void DuiSettingsLanguageBinaryStub::DuiSettingsLanguageBinaryDestructor() +{ + +} +QStringList DuiSettingsLanguageBinaryStub::keys() const +{ + stubMethodEntered("keys"); + return stubReturnValue("keys"); +} + + + +// 3. CREATE A STUB INSTANCE +DuiSettingsLanguageBinaryStub gDefaultDuiSettingsLanguageBinaryStub; +DuiSettingsLanguageBinaryStub *gDuiSettingsLanguageBinaryStub = &gDefaultDuiSettingsLanguageBinaryStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiSettingsLanguageBinary::DuiSettingsLanguageBinary() +{ + gDuiSettingsLanguageBinaryStub->DuiSettingsLanguageBinaryConstructor(); +} + +DuiSettingsLanguageBinary::~DuiSettingsLanguageBinary() +{ + gDuiSettingsLanguageBinaryStub->DuiSettingsLanguageBinaryDestructor(); +} + +QStringList DuiSettingsLanguageBinary::keys() const +{ + return gDuiSettingsLanguageBinaryStub->keys(); +} + + +#endif diff --git a/tests/stubs/duisettingslanguageboolean_stub.h b/tests/stubs/duisettingslanguageboolean_stub.h new file mode 100644 index 000000000..72debfa24 --- /dev/null +++ b/tests/stubs/duisettingslanguageboolean_stub.h @@ -0,0 +1,91 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISETTINGSLANGUAGEBOOLEAN_STUB +#define DUISETTINGSLANGUAGEBOOLEAN_STUB + +#include "duisettingslanguageboolean.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiSettingsLanguageBooleanStub : public StubBase +{ +public: + virtual void DuiSettingsLanguageBooleanConstructor(const QString &key, const QString &title); + virtual void DuiSettingsLanguageBooleanDestructor(); + virtual QString key() const; + virtual QString title() const; +}; + +// 2. IMPLEMENT STUB +void DuiSettingsLanguageBooleanStub::DuiSettingsLanguageBooleanConstructor(const QString &key, const QString &title) +{ + QList params; + params.append(new Parameter(key)); + params.append(new Parameter(title)); + stubMethodEntered("constructor", params); +} +void DuiSettingsLanguageBooleanStub::DuiSettingsLanguageBooleanDestructor() +{ + +} +QString DuiSettingsLanguageBooleanStub::key() const +{ + stubMethodEntered("key"); + return stubReturnValue("key"); +} + +QString DuiSettingsLanguageBooleanStub::title() const +{ + stubMethodEntered("title"); + return stubReturnValue("title"); +} + + + +// 3. CREATE A STUB INSTANCE +DuiSettingsLanguageBooleanStub gDefaultDuiSettingsLanguageBooleanStub; +DuiSettingsLanguageBooleanStub *gDuiSettingsLanguageBooleanStub = &gDefaultDuiSettingsLanguageBooleanStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiSettingsLanguageBoolean::DuiSettingsLanguageBoolean(const QString &key, const QString &title) +{ + gDuiSettingsLanguageBooleanStub->DuiSettingsLanguageBooleanConstructor(key, title); +} + +DuiSettingsLanguageBoolean::~DuiSettingsLanguageBoolean() +{ + gDuiSettingsLanguageBooleanStub->DuiSettingsLanguageBooleanDestructor(); +} + +QString DuiSettingsLanguageBoolean::key() const +{ + return gDuiSettingsLanguageBooleanStub->key(); +} + +QString DuiSettingsLanguageBoolean::title() const +{ + return gDuiSettingsLanguageBooleanStub->title(); +} + + +#endif diff --git a/tests/stubs/duisettingslanguagebooleancontroller_stub.h b/tests/stubs/duisettingslanguagebooleancontroller_stub.h new file mode 100644 index 000000000..6f2d058bf --- /dev/null +++ b/tests/stubs/duisettingslanguagebooleancontroller_stub.h @@ -0,0 +1,78 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISETTINGSLANGUAGEBOOLEANCONTROLLER_STUB +#define DUISETTINGSLANGUAGEBOOLEANCONTROLLER_STUB + +#include "duisettingslanguagebooleancontroller.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiSettingsLanguageBooleanControllerStub : public StubBase +{ +public: + virtual void DuiSettingsLanguageBooleanControllerConstructor(QObject *parent); + virtual void DuiSettingsLanguageBooleanControllerDestructor(); + virtual void buttonToggled(bool checked); +}; + +// 2. IMPLEMENT STUB +void DuiSettingsLanguageBooleanControllerStub::DuiSettingsLanguageBooleanControllerConstructor(QObject *parent) +{ + Q_UNUSED(parent); + +} +void DuiSettingsLanguageBooleanControllerStub::DuiSettingsLanguageBooleanControllerDestructor() +{ + +} +void DuiSettingsLanguageBooleanControllerStub::buttonToggled(bool checked) +{ + QList params; + params.append(new Parameter(checked)); + stubMethodEntered("buttonToggled", params); +} + + + +// 3. CREATE A STUB INSTANCE +DuiSettingsLanguageBooleanControllerStub gDefaultDuiSettingsLanguageBooleanControllerStub; +DuiSettingsLanguageBooleanControllerStub *gDuiSettingsLanguageBooleanControllerStub = &gDefaultDuiSettingsLanguageBooleanControllerStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiSettingsLanguageBooleanController::DuiSettingsLanguageBooleanController(QObject *parent) +{ + gDuiSettingsLanguageBooleanControllerStub->DuiSettingsLanguageBooleanControllerConstructor(parent); +} + +DuiSettingsLanguageBooleanController::~DuiSettingsLanguageBooleanController() +{ + gDuiSettingsLanguageBooleanControllerStub->DuiSettingsLanguageBooleanControllerDestructor(); +} + +void DuiSettingsLanguageBooleanController::buttonToggled(bool checked) +{ + gDuiSettingsLanguageBooleanControllerStub->buttonToggled(checked); +} + + +#endif diff --git a/tests/stubs/duisettingslanguagebooleanfactory_stub.h b/tests/stubs/duisettingslanguagebooleanfactory_stub.h new file mode 100644 index 000000000..110d5fdb6 --- /dev/null +++ b/tests/stubs/duisettingslanguagebooleanfactory_stub.h @@ -0,0 +1,60 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISETTINGSLANGUAGEBOOLEANFACTORY_STUB +#define DUISETTINGSLANGUAGEBOOLEANFACTORY_STUB + +#include "duisettingslanguagebooleanfactory.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiSettingsLanguageBooleanFactoryStub : public StubBase +{ +public: + virtual DuiWidgetController *createWidget(const DuiSettingsLanguageBoolean &settingsBool, DuiSettingsLanguageWidget &rootWidget, DuiDataStore *dataStore); +}; + +// 2. IMPLEMENT STUB +DuiWidgetController *DuiSettingsLanguageBooleanFactoryStub::createWidget(const DuiSettingsLanguageBoolean &settingsBool, DuiSettingsLanguageWidget &rootWidget, DuiDataStore *dataStore) +{ + QList params; + params.append(new Parameter(&settingsBool)); + params.append(new Parameter(rootWidget)); + params.append(new Parameter(dataStore)); + stubMethodEntered("createWidget", params); + return stubReturnValue("createWidget"); +} + + + +// 3. CREATE A STUB INSTANCE +DuiSettingsLanguageBooleanFactoryStub gDefaultDuiSettingsLanguageBooleanFactoryStub; +DuiSettingsLanguageBooleanFactoryStub *gDuiSettingsLanguageBooleanFactoryStub = &gDefaultDuiSettingsLanguageBooleanFactoryStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiWidgetController *DuiSettingsLanguageBooleanFactory::createWidget(const DuiSettingsLanguageBoolean &settingsBool, DuiSettingsLanguageWidget &rootWidget, DuiDataStore *dataStore) +{ + return gDuiSettingsLanguageBooleanFactoryStub->createWidget(settingsBool, rootWidget, dataStore); +} + + +#endif diff --git a/tests/stubs/duisettingslanguagegroup_stub.h b/tests/stubs/duisettingslanguagegroup_stub.h new file mode 100644 index 000000000..ea20b9ccc --- /dev/null +++ b/tests/stubs/duisettingslanguagegroup_stub.h @@ -0,0 +1,44 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISETTINGSLANGUAGEGROUP_STUB +#define DUISETTINGSLANGUAGEGROUP_STUB + +#include "duisettingslanguagegroup.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiSettingsLanguageGroupStub : public StubBase +{ +public: +}; + +// 2. IMPLEMENT STUB + + +// 3. CREATE A STUB INSTANCE +DuiSettingsLanguageGroupStub gDefaultDuiSettingsLanguageGroupStub; +DuiSettingsLanguageGroupStub *gDuiSettingsLanguageGroupStub = &gDefaultDuiSettingsLanguageGroupStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB + +#endif diff --git a/tests/stubs/duisettingslanguageinteger_stub.h b/tests/stubs/duisettingslanguageinteger_stub.h new file mode 100644 index 000000000..b8e13538d --- /dev/null +++ b/tests/stubs/duisettingslanguageinteger_stub.h @@ -0,0 +1,147 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISETTINGSLANGUAGEINTEGER_STUB +#define DUISETTINGSLANGUAGEINTEGER_STUB + +#include "duisettingslanguageinteger.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiSettingsLanguageIntegerStub : public StubBase +{ +public: + virtual void DuiSettingsLanguageIntegerConstructor(const QString &key, const QString &title); + virtual void DuiSettingsLanguageIntegerDestructor(); + virtual QString key() const; + virtual QString title() const; + virtual bool minValue(int &value) const; + virtual bool maxValue(int &value) const; + virtual void setMinValue(int newMin); + virtual void setMaxValue(int newMax); +}; + +// 2. IMPLEMENT STUB +void DuiSettingsLanguageIntegerStub::DuiSettingsLanguageIntegerConstructor(const QString &key, const QString &title) +{ + QList params; + params.append(new Parameter(key)); + params.append(new Parameter(title)); + stubMethodEntered("constructor", params); +} +void DuiSettingsLanguageIntegerStub::DuiSettingsLanguageIntegerDestructor() +{ + +} +QString DuiSettingsLanguageIntegerStub::key() const +{ + stubMethodEntered("key"); + return stubReturnValue("key"); +} + +QString DuiSettingsLanguageIntegerStub::title() const +{ + stubMethodEntered("title"); + return stubReturnValue("title"); +} + +bool DuiSettingsLanguageIntegerStub::minValue(int &value) const +{ + QList params; + params.append(new Parameter(value)); + stubMethodEntered("minValue", params); + value = stubReturnValue("minValueValue"); + return stubReturnValue("minValue"); +} + +bool DuiSettingsLanguageIntegerStub::maxValue(int &value) const +{ + QList params; + params.append(new Parameter(value)); + stubMethodEntered("maxValue", params); + value = stubReturnValue("maxValueValue"); + return stubReturnValue("maxValue"); +} + +void DuiSettingsLanguageIntegerStub::setMinValue(int newMin) +{ + QList params; + params.append(new Parameter(newMin)); + stubMethodEntered("setMinValue", params); +} + +void DuiSettingsLanguageIntegerStub::setMaxValue(int newMax) +{ + QList params; + params.append(new Parameter(newMax)); + stubMethodEntered("setMaxValue", params); +} + + + +// 3. CREATE A STUB INSTANCE +DuiSettingsLanguageIntegerStub gDefaultDuiSettingsLanguageIntegerStub; +DuiSettingsLanguageIntegerStub *gDuiSettingsLanguageIntegerStub = &gDefaultDuiSettingsLanguageIntegerStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiSettingsLanguageInteger::DuiSettingsLanguageInteger(const QString &key, const QString &title) +{ + gDuiSettingsLanguageIntegerStub->DuiSettingsLanguageIntegerConstructor(key, title); +} + +DuiSettingsLanguageInteger::~DuiSettingsLanguageInteger() +{ + gDuiSettingsLanguageIntegerStub->DuiSettingsLanguageIntegerDestructor(); +} + +QString DuiSettingsLanguageInteger::key() const +{ + return gDuiSettingsLanguageIntegerStub->key(); +} + +QString DuiSettingsLanguageInteger::title() const +{ + return gDuiSettingsLanguageIntegerStub->title(); +} + +bool DuiSettingsLanguageInteger::minValue(int &value) const +{ + return gDuiSettingsLanguageIntegerStub->minValue(value); +} + +bool DuiSettingsLanguageInteger::maxValue(int &value) const +{ + return gDuiSettingsLanguageIntegerStub->maxValue(value); +} + +void DuiSettingsLanguageInteger::setMinValue(int newMin) +{ + gDuiSettingsLanguageIntegerStub->setMinValue(newMin); +} + +void DuiSettingsLanguageInteger::setMaxValue(int newMax) +{ + gDuiSettingsLanguageIntegerStub->setMaxValue(newMax); +} + + +#endif diff --git a/tests/stubs/duisettingslanguageintegercontroller_stub.h b/tests/stubs/duisettingslanguageintegercontroller_stub.h new file mode 100644 index 000000000..4bfede2e4 --- /dev/null +++ b/tests/stubs/duisettingslanguageintegercontroller_stub.h @@ -0,0 +1,78 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISETTINGSLANGUAGEINTEGERCONTROLLER_STUB +#define DUISETTINGSLANGUAGEINTEGERCONTROLLER_STUB + +#include "duisettingslanguageintegercontroller.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiSettingsLanguageIntegerControllerStub : public StubBase +{ +public: + virtual void DuiSettingsLanguageIntegerControllerConstructor(QObject *parent); + virtual void DuiSettingsLanguageIntegerControllerDestructor(); + virtual void changeValue(int newValue); +}; + +// 2. IMPLEMENT STUB +void DuiSettingsLanguageIntegerControllerStub::DuiSettingsLanguageIntegerControllerConstructor(QObject *parent) +{ + Q_UNUSED(parent); + +} +void DuiSettingsLanguageIntegerControllerStub::DuiSettingsLanguageIntegerControllerDestructor() +{ + +} +void DuiSettingsLanguageIntegerControllerStub::changeValue(int newValue) +{ + QList params; + params.append(new Parameter(newValue)); + stubMethodEntered("changeValue", params); +} + + + +// 3. CREATE A STUB INSTANCE +DuiSettingsLanguageIntegerControllerStub gDefaultDuiSettingsLanguageIntegerControllerStub; +DuiSettingsLanguageIntegerControllerStub *gDuiSettingsLanguageIntegerControllerStub = &gDefaultDuiSettingsLanguageIntegerControllerStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiSettingsLanguageIntegerController::DuiSettingsLanguageIntegerController(QObject *parent) +{ + gDuiSettingsLanguageIntegerControllerStub->DuiSettingsLanguageIntegerControllerConstructor(parent); +} + +DuiSettingsLanguageIntegerController::~DuiSettingsLanguageIntegerController() +{ + gDuiSettingsLanguageIntegerControllerStub->DuiSettingsLanguageIntegerControllerDestructor(); +} + +void DuiSettingsLanguageIntegerController::changeValue(int newValue) +{ + gDuiSettingsLanguageIntegerControllerStub->changeValue(newValue); +} + + +#endif diff --git a/tests/stubs/duisettingslanguageintegerfactory_stub.h b/tests/stubs/duisettingslanguageintegerfactory_stub.h new file mode 100644 index 000000000..f43997785 --- /dev/null +++ b/tests/stubs/duisettingslanguageintegerfactory_stub.h @@ -0,0 +1,60 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISETTINGSLANGUAGEINTEGERFACTORY_STUB +#define DUISETTINGSLANGUAGEINTEGERFACTORY_STUB + +#include "duisettingslanguageintegerfactory.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiSettingsLanguageIntegerFactoryStub : public StubBase +{ +public: + virtual DuiWidgetController *createWidget(const DuiSettingsLanguageInteger &settingsInteger, DuiSettingsLanguageWidget &rootWidget, DuiDataStore *dataStore); +}; + +// 2. IMPLEMENT STUB +DuiWidgetController *DuiSettingsLanguageIntegerFactoryStub::createWidget(const DuiSettingsLanguageInteger &settingsInteger, DuiSettingsLanguageWidget &rootWidget, DuiDataStore *dataStore) +{ + QList params; + params.append(new Parameter(&settingsInteger)); + params.append(new Parameter(rootWidget)); + params.append(new Parameter(dataStore)); + stubMethodEntered("createWidget", params); + return stubReturnValue("createWidget"); +} + + + +// 3. CREATE A STUB INSTANCE +DuiSettingsLanguageIntegerFactoryStub gDefaultDuiSettingsLanguageIntegerFactoryStub; +DuiSettingsLanguageIntegerFactoryStub *gDuiSettingsLanguageIntegerFactoryStub = &gDefaultDuiSettingsLanguageIntegerFactoryStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiWidgetController *DuiSettingsLanguageIntegerFactory::createWidget(const DuiSettingsLanguageInteger &settingsInteger, DuiSettingsLanguageWidget &rootWidget, DuiDataStore *dataStore) +{ + return gDuiSettingsLanguageIntegerFactoryStub->createWidget(settingsInteger, rootWidget, dataStore); +} + + +#endif diff --git a/tests/stubs/duisettingslanguagenode_stub.h b/tests/stubs/duisettingslanguagenode_stub.h new file mode 100644 index 000000000..cec685918 --- /dev/null +++ b/tests/stubs/duisettingslanguagenode_stub.h @@ -0,0 +1,99 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISETTINGSLANGUAGENODE_STUB +#define DUISETTINGSLANGUAGENODE_STUB + +#include "duisettingslanguagenode.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiSettingsLanguageNodeStub : public StubBase +{ +public: + virtual void DuiSettingsLanguageNodeConstructor(); + virtual void DuiSettingsLanguageNodeDestructor(); + virtual void addChild(DuiSettingsLanguageNode *child); + virtual uint numChildren() const; + virtual QList children() const; +}; + +// 2. IMPLEMENT STUB +void DuiSettingsLanguageNodeStub::DuiSettingsLanguageNodeConstructor() +{ +} + +void DuiSettingsLanguageNodeStub::DuiSettingsLanguageNodeDestructor() +{ +} + +void DuiSettingsLanguageNodeStub::addChild(DuiSettingsLanguageNode *child) +{ + QList params; + params.append(new Parameter(child)); + stubMethodEntered("addChild", params); +} + +uint DuiSettingsLanguageNodeStub::numChildren() const +{ + stubMethodEntered("numChildren"); + return stubReturnValue("numChildren"); +} + +QList DuiSettingsLanguageNodeStub::children() const +{ + stubMethodEntered("children"); + return stubReturnValue >("children"); +} + + +// 3. CREATE A STUB INSTANCE +DuiSettingsLanguageNodeStub gDefaultDuiSettingsLanguageNodeStub; +DuiSettingsLanguageNodeStub *gDuiSettingsLanguageNodeStub = &gDefaultDuiSettingsLanguageNodeStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiSettingsLanguageNode::DuiSettingsLanguageNode() +{ + gDuiSettingsLanguageNodeStub->DuiSettingsLanguageNodeConstructor(); +} + +DuiSettingsLanguageNode::~DuiSettingsLanguageNode() +{ + gDuiSettingsLanguageNodeStub->DuiSettingsLanguageNodeDestructor(); +} + +void DuiSettingsLanguageNode::addChild(DuiSettingsLanguageNode *child) +{ + gDuiSettingsLanguageNodeStub->addChild(child); +} + +uint DuiSettingsLanguageNode::numChildren() const +{ + return gDuiSettingsLanguageNodeStub->numChildren(); +} + +QList DuiSettingsLanguageNode::children() const +{ + return gDuiSettingsLanguageNodeStub->children(); +} + +#endif diff --git a/tests/stubs/duisettingslanguageoption_stub.h b/tests/stubs/duisettingslanguageoption_stub.h new file mode 100644 index 000000000..4d5e55b52 --- /dev/null +++ b/tests/stubs/duisettingslanguageoption_stub.h @@ -0,0 +1,91 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISETTINGSLANGUAGEOPTION_STUB +#define DUISETTINGSLANGUAGEOPTION_STUB + +#include "duisettingslanguageoption.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiSettingsLanguageOptionStub : public StubBase +{ +public: + virtual void DuiSettingsLanguageOptionConstructor(const QString &title, int value); + virtual void DuiSettingsLanguageOptionDestructor(); + virtual QString title() const; + virtual int value() const; +}; + +// 2. IMPLEMENT STUB +void DuiSettingsLanguageOptionStub::DuiSettingsLanguageOptionConstructor(const QString &title, int value) +{ + QList params; + params.append(new Parameter(title)); + params.append(new Parameter(value)); + stubMethodEntered("constructor", params); +} +void DuiSettingsLanguageOptionStub::DuiSettingsLanguageOptionDestructor() +{ + +} +QString DuiSettingsLanguageOptionStub::title() const +{ + stubMethodEntered("title"); + return stubReturnValue("title"); +} + +int DuiSettingsLanguageOptionStub::value() const +{ + stubMethodEntered("value"); + return stubReturnValue("value"); +} + + + +// 3. CREATE A STUB INSTANCE +DuiSettingsLanguageOptionStub gDefaultDuiSettingsLanguageOptionStub; +DuiSettingsLanguageOptionStub *gDuiSettingsLanguageOptionStub = &gDefaultDuiSettingsLanguageOptionStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiSettingsLanguageOption::DuiSettingsLanguageOption(const QString &title, int value) +{ + gDuiSettingsLanguageOptionStub->DuiSettingsLanguageOptionConstructor(title, value); +} + +DuiSettingsLanguageOption::~DuiSettingsLanguageOption() +{ + gDuiSettingsLanguageOptionStub->DuiSettingsLanguageOptionDestructor(); +} + +QString DuiSettingsLanguageOption::title() const +{ + return gDuiSettingsLanguageOptionStub->title(); +} + +int DuiSettingsLanguageOption::value() const +{ + return gDuiSettingsLanguageOptionStub->value(); +} + + +#endif diff --git a/tests/stubs/duisettingslanguageselection_stub.h b/tests/stubs/duisettingslanguageselection_stub.h new file mode 100644 index 000000000..292903fe6 --- /dev/null +++ b/tests/stubs/duisettingslanguageselection_stub.h @@ -0,0 +1,131 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISETTINGSLANGUAGESELECTION_STUB +#define DUISETTINGSLANGUAGESELECTION_STUB + +#include "duisettingslanguageselection.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiSettingsLanguageSelectionStub : public StubBase +{ +public: + virtual void DuiSettingsLanguageSelectionConstructor(const QString &key); + virtual void DuiSettingsLanguageSelectionDestructor(); + virtual QString key() const; + virtual DuiSettingsLanguageOption *addOption(const QString &title, int value); + virtual DuiSettingsLanguageOption *addOption(DuiSettingsLanguageOption *option); + virtual uint numOptions() const; + virtual QList options() const; +}; + +// 2. IMPLEMENT STUB +void DuiSettingsLanguageSelectionStub::DuiSettingsLanguageSelectionConstructor(const QString &key) +{ + QList params; + params.append(new Parameter(key)); + stubMethodEntered("constructor", params); +} +void DuiSettingsLanguageSelectionStub::DuiSettingsLanguageSelectionDestructor() +{ + +} +QString DuiSettingsLanguageSelectionStub::key() const +{ + stubMethodEntered("key"); + return stubReturnValue("key"); +} + +DuiSettingsLanguageOption *DuiSettingsLanguageSelectionStub::addOption(const QString &title, int value) +{ + QList params; + params.append(new Parameter(title)); + params.append(new Parameter(value)); + stubMethodEntered("addOption", params); + return stubReturnValue("addOption"); +} + +DuiSettingsLanguageOption *DuiSettingsLanguageSelectionStub::addOption(DuiSettingsLanguageOption *option) +{ + QList params; + params.append(new Parameter(option)); + stubMethodEntered("addOption", params); + return stubReturnValue("addOption"); +} + +uint DuiSettingsLanguageSelectionStub::numOptions() const +{ + stubMethodEntered("numOptions"); + return stubReturnValue("numOptions"); +} + +QList DuiSettingsLanguageSelectionStub::options() const +{ + stubMethodEntered("options"); + return stubReturnValue >("options"); +} + + + +// 3. CREATE A STUB INSTANCE +DuiSettingsLanguageSelectionStub gDefaultDuiSettingsLanguageSelectionStub; +DuiSettingsLanguageSelectionStub *gDuiSettingsLanguageSelectionStub = &gDefaultDuiSettingsLanguageSelectionStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiSettingsLanguageSelection::DuiSettingsLanguageSelection(const QString &key) +{ + gDuiSettingsLanguageSelectionStub->DuiSettingsLanguageSelectionConstructor(key); +} + +DuiSettingsLanguageSelection::~DuiSettingsLanguageSelection() +{ + gDuiSettingsLanguageSelectionStub->DuiSettingsLanguageSelectionDestructor(); +} + +QString DuiSettingsLanguageSelection::key() const +{ + return gDuiSettingsLanguageSelectionStub->key(); +} + +DuiSettingsLanguageOption *DuiSettingsLanguageSelection::addOption(const QString &title, int value) +{ + return gDuiSettingsLanguageSelectionStub->addOption(title, value); +} + +DuiSettingsLanguageOption *DuiSettingsLanguageSelection::addOption(DuiSettingsLanguageOption *option) +{ + return gDuiSettingsLanguageSelectionStub->addOption(option); +} + +uint DuiSettingsLanguageSelection::numOptions() const +{ + return gDuiSettingsLanguageSelectionStub->numOptions(); +} + +QList DuiSettingsLanguageSelection::options() const +{ + return gDuiSettingsLanguageSelectionStub->options(); +} + + +#endif diff --git a/tests/stubs/duisettingslanguageselectioncontroller_stub.h b/tests/stubs/duisettingslanguageselectioncontroller_stub.h new file mode 100644 index 000000000..3e76f275f --- /dev/null +++ b/tests/stubs/duisettingslanguageselectioncontroller_stub.h @@ -0,0 +1,78 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISETTINGSLANGUAGESELECTIONCONTROLLER_STUB +#define DUISETTINGSLANGUAGESELECTIONCONTROLLER_STUB + +#include "duisettingslanguageselectioncontroller.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiSettingsLanguageSelectionControllerStub : public StubBase +{ +public: + virtual void DuiSettingsLanguageSelectionControllerConstructor(QObject *parent); + virtual void DuiSettingsLanguageSelectionControllerDestructor(); + virtual void buttonClicked(DuiButton *button); +}; + +// 2. IMPLEMENT STUB +void DuiSettingsLanguageSelectionControllerStub::DuiSettingsLanguageSelectionControllerConstructor(QObject *parent) +{ + Q_UNUSED(parent); + +} +void DuiSettingsLanguageSelectionControllerStub::DuiSettingsLanguageSelectionControllerDestructor() +{ + +} +void DuiSettingsLanguageSelectionControllerStub::buttonClicked(DuiButton *button) +{ + QList params; + params.append(new Parameter(button)); + stubMethodEntered("buttonClicked", params); +} + + + +// 3. CREATE A STUB INSTANCE +DuiSettingsLanguageSelectionControllerStub gDefaultDuiSettingsLanguageSelectionControllerStub; +DuiSettingsLanguageSelectionControllerStub *gDuiSettingsLanguageSelectionControllerStub = &gDefaultDuiSettingsLanguageSelectionControllerStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiSettingsLanguageSelectionController::DuiSettingsLanguageSelectionController(QObject *parent) +{ + gDuiSettingsLanguageSelectionControllerStub->DuiSettingsLanguageSelectionControllerConstructor(parent); +} + +DuiSettingsLanguageSelectionController::~DuiSettingsLanguageSelectionController() +{ + gDuiSettingsLanguageSelectionControllerStub->DuiSettingsLanguageSelectionControllerDestructor(); +} + +void DuiSettingsLanguageSelectionController::buttonClicked(DuiButton *button) +{ + gDuiSettingsLanguageSelectionControllerStub->buttonClicked(button); +} + + +#endif diff --git a/tests/stubs/duisettingslanguageselectionfactory_stub.h b/tests/stubs/duisettingslanguageselectionfactory_stub.h new file mode 100644 index 000000000..f2608ff7a --- /dev/null +++ b/tests/stubs/duisettingslanguageselectionfactory_stub.h @@ -0,0 +1,60 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISETTINGSLANGUAGESELECTIONFACTORY_STUB +#define DUISETTINGSLANGUAGESELECTIONFACTORY_STUB + +#include "duisettingslanguageselectionfactory.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiSettingsLanguageSelectionFactoryStub : public StubBase +{ +public: + virtual DuiWidgetController *createWidget(const DuiSettingsLanguageSelection &settingsSelection, DuiSettingsLanguageWidget &rootWidget, DuiDataStore *dataStore); +}; + +// 2. IMPLEMENT STUB +DuiWidgetController *DuiSettingsLanguageSelectionFactoryStub::createWidget(const DuiSettingsLanguageSelection &settingsSelection, DuiSettingsLanguageWidget &rootWidget, DuiDataStore *dataStore) +{ + QList params; + params.append(new Parameter(&settingsSelection)); + params.append(new Parameter(rootWidget)); + params.append(new Parameter(dataStore)); + stubMethodEntered("createWidget", params); + return stubReturnValue("createWidget"); +} + + + +// 3. CREATE A STUB INSTANCE +DuiSettingsLanguageSelectionFactoryStub gDefaultDuiSettingsLanguageSelectionFactoryStub; +DuiSettingsLanguageSelectionFactoryStub *gDuiSettingsLanguageSelectionFactoryStub = &gDefaultDuiSettingsLanguageSelectionFactoryStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiWidgetController *DuiSettingsLanguageSelectionFactory::createWidget(const DuiSettingsLanguageSelection &settingsSelection, DuiSettingsLanguageWidget &rootWidget, DuiDataStore *dataStore) +{ + return gDuiSettingsLanguageSelectionFactoryStub->createWidget(settingsSelection, rootWidget, dataStore); +} + + +#endif diff --git a/tests/stubs/duisettingslanguagesettingfactory_stub.h b/tests/stubs/duisettingslanguagesettingfactory_stub.h new file mode 100644 index 000000000..14e6f345e --- /dev/null +++ b/tests/stubs/duisettingslanguagesettingfactory_stub.h @@ -0,0 +1,60 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISETTINGSLANGUAGESETTINGFACTORY_STUB +#define DUISETTINGSLANGUAGESETTINGFACTORY_STUB + +#include "duisettingslanguagegroupfactory.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiSettingsLanguageSettingFactoryStub : public StubBase +{ +public: + virtual DuiWidgetController *createWidget(const DuiSettingsLanguageSetting &settingsItem, DuiSettingsLanguageWidget &rootWidget, DuiDataStore *dataStore); +}; + +// 2. IMPLEMENT STUB +DuiWidgetController *DuiSettingsLanguageSettingFactoryStub::createWidget(const DuiSettingsLanguageSetting &settingsItem, DuiSettingsLanguageWidget &rootWidget, DuiDataStore *dataStore) +{ + QList params; + params.append(new Parameter(settingsItem)); + params.append(new Parameter(rootWidget)); + params.append(new Parameter(dataStore)); + stubMethodEntered("createWidget", params); + return stubReturnValue("createWidget"); +} + + + +// 3. CREATE A STUB INSTANCE +DuiSettingsLanguageSettingFactoryStub gDefaultDuiSettingsLanguageSettingFactoryStub; +DuiSettingsLanguageSettingFactoryStub *gDuiSettingsLanguageSettingFactoryStub = &gDefaultDuiSettingsLanguageSettingFactoryStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiWidgetController *DuiSettingsLanguageSettingFactory::createWidget(const DuiSettingsLanguageSetting &settingsItem, DuiSettingsLanguageWidget &rootWidget, DuiDataStore *dataStore) +{ + return gDuiSettingsLanguageSettingFactoryStub->createWidget(settingsItem, rootWidget, dataStore); +} + + +#endif diff --git a/tests/stubs/duisettingslanguagesettings_stub.h b/tests/stubs/duisettingslanguagesettings_stub.h new file mode 100644 index 000000000..3aa39c3ef --- /dev/null +++ b/tests/stubs/duisettingslanguagesettings_stub.h @@ -0,0 +1,65 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISETTINGSLANGUAGESETTINGS_STUB +#define DUISETTINGSLANGUAGESETTINGS_STUB + +#include "duisettingslanguagesettings.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiSettingsLanguageSettingsStub : public StubBase +{ +public: + virtual void DuiSettingsLanguageSettingsConstructor(); + virtual void DuiSettingsLanguageSettingsDestructor(); +}; + +// 2. IMPLEMENT STUB +void DuiSettingsLanguageSettingsStub::DuiSettingsLanguageSettingsConstructor() +{ + +} +void DuiSettingsLanguageSettingsStub::DuiSettingsLanguageSettingsDestructor() +{ + +} + + + +// 3. CREATE A STUB INSTANCE +DuiSettingsLanguageSettingsStub gDefaultDuiSettingsLanguageSettingsStub; +DuiSettingsLanguageSettingsStub *gDuiSettingsLanguageSettingsStub = &gDefaultDuiSettingsLanguageSettingsStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiSettingsLanguageSettings::DuiSettingsLanguageSettings() +{ + gDuiSettingsLanguageSettingsStub->DuiSettingsLanguageSettingsConstructor(); +} + +DuiSettingsLanguageSettings::~DuiSettingsLanguageSettings() +{ + gDuiSettingsLanguageSettingsStub->DuiSettingsLanguageSettingsDestructor(); +} + + +#endif diff --git a/tests/stubs/duisettingslanguagesettingsfactory_stub.h b/tests/stubs/duisettingslanguagesettingsfactory_stub.h new file mode 100644 index 000000000..4d4cb6886 --- /dev/null +++ b/tests/stubs/duisettingslanguagesettingsfactory_stub.h @@ -0,0 +1,76 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISETTINGSLANGUAGESETTINGSFACTORY_STUB +#define DUISETTINGSLANGUAGESETTINGSFACTORY_STUB + +#include "duisettingslanguagesettingsfactory.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiSettingsLanguageSettingsFactoryStub : public StubBase +{ +public: + virtual DuiWidgetController *createWidget(const DuiSettingsLanguageSettings &settingsItem, DuiSettingsLanguageWidget &rootWidget, DuiDataStore *dataStore); + virtual void createChildren(QGraphicsLinearLayout &layout, const DuiSettingsLanguageNode &node, DuiSettingsLanguageWidget &rootWidget, DuiDataStore *dataStore); +}; + +// 2. IMPLEMENT STUB +DuiWidgetController *DuiSettingsLanguageSettingsFactoryStub::createWidget(const DuiSettingsLanguageSettings &settingsItem, DuiSettingsLanguageWidget &rootWidget, DuiDataStore *dataStore) +{ + QList params; + params.append(new Parameter(&settingsItem)); + params.append(new Parameter(rootWidget)); + params.append(new Parameter(dataStore)); + stubMethodEntered("createWidget", params); + return stubReturnValue("createWidget"); +} + +void DuiSettingsLanguageSettingsFactoryStub::createChildren(QGraphicsLinearLayout &layout, const DuiSettingsLanguageNode &node, DuiSettingsLanguageWidget &rootWidget, DuiDataStore *dataStore) +{ + QList params; + params.append(new Parameter(layout)); + params.append(new Parameter(node)); + params.append(new Parameter(rootWidget)); + params.append(new Parameter(dataStore)); + stubMethodEntered("createChildren", params); +} + + + +// 3. CREATE A STUB INSTANCE +DuiSettingsLanguageSettingsFactoryStub gDefaultDuiSettingsLanguageSettingsFactoryStub; +DuiSettingsLanguageSettingsFactoryStub *gDuiSettingsLanguageSettingsFactoryStub = &gDefaultDuiSettingsLanguageSettingsFactoryStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiWidgetController *DuiSettingsLanguageSettingsFactory::createWidget(const DuiSettingsLanguageSettings &settingsItem, DuiSettingsLanguageWidget &rootWidget, DuiDataStore *dataStore) +{ + return gDuiSettingsLanguageSettingsFactoryStub->createWidget(settingsItem, rootWidget, dataStore); +} + +void DuiSettingsLanguageSettingsFactory::createChildren(QGraphicsLinearLayout &layout, const DuiSettingsLanguageNode &node, DuiSettingsLanguageWidget &rootWidget, DuiDataStore *dataStore) +{ + gDuiSettingsLanguageSettingsFactoryStub->createChildren(layout, node, rootWidget, dataStore); +} + + +#endif diff --git a/tests/stubs/duisettingslanguagetext_stub.h b/tests/stubs/duisettingslanguagetext_stub.h new file mode 100644 index 000000000..88e7a5d34 --- /dev/null +++ b/tests/stubs/duisettingslanguagetext_stub.h @@ -0,0 +1,91 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISETTINGSLANGUAGETEXT_STUB +#define DUISETTINGSLANGUAGETEXT_STUB + +#include "duisettingslanguagetext.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiSettingsLanguageTextStub : public StubBase +{ +public: + virtual void DuiSettingsLanguageTextConstructor(const QString &key, const QString &title); + virtual void DuiSettingsLanguageTextDestructor(); + virtual QString key() const; + virtual QString title() const; +}; + +// 2. IMPLEMENT STUB +void DuiSettingsLanguageTextStub::DuiSettingsLanguageTextConstructor(const QString &key, const QString &title) +{ + QList params; + params.append(new Parameter(key)); + params.append(new Parameter(title)); + stubMethodEntered("constructor", params); +} +void DuiSettingsLanguageTextStub::DuiSettingsLanguageTextDestructor() +{ + +} +QString DuiSettingsLanguageTextStub::key() const +{ + stubMethodEntered("key"); + return stubReturnValue("key"); +} + +QString DuiSettingsLanguageTextStub::title() const +{ + stubMethodEntered("title"); + return stubReturnValue("title"); +} + + + +// 3. CREATE A STUB INSTANCE +DuiSettingsLanguageTextStub gDefaultDuiSettingsLanguageTextStub; +DuiSettingsLanguageTextStub *gDuiSettingsLanguageTextStub = &gDefaultDuiSettingsLanguageTextStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiSettingsLanguageText::DuiSettingsLanguageText(const QString &key, const QString &title) +{ + gDuiSettingsLanguageTextStub->DuiSettingsLanguageTextConstructor(key, title); +} + +DuiSettingsLanguageText::~DuiSettingsLanguageText() +{ + gDuiSettingsLanguageTextStub->DuiSettingsLanguageTextDestructor(); +} + +QString DuiSettingsLanguageText::key() const +{ + return gDuiSettingsLanguageTextStub->key(); +} + +QString DuiSettingsLanguageText::title() const +{ + return gDuiSettingsLanguageTextStub->title(); +} + + +#endif diff --git a/tests/stubs/duisettingslanguagetextcontroller_stub.h b/tests/stubs/duisettingslanguagetextcontroller_stub.h new file mode 100644 index 000000000..d6cfa7566 --- /dev/null +++ b/tests/stubs/duisettingslanguagetextcontroller_stub.h @@ -0,0 +1,78 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISETTINGSLANGUAGETEXTCONTROLLER_STUB +#define DUISETTINGSLANGUAGETEXTCONTROLLER_STUB + +#include "duisettingslanguagetextcontroller.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiSettingsLanguageTextControllerStub : public StubBase +{ +public: + virtual void DuiSettingsLanguageTextControllerConstructor(QObject *parent); + virtual void DuiSettingsLanguageTextControllerDestructor(); + virtual void textEditLostFocus(Qt::FocusReason reason); +}; + +// 2. IMPLEMENT STUB +void DuiSettingsLanguageTextControllerStub::DuiSettingsLanguageTextControllerConstructor(QObject *parent) +{ + Q_UNUSED(parent); + +} +void DuiSettingsLanguageTextControllerStub::DuiSettingsLanguageTextControllerDestructor() +{ + +} +void DuiSettingsLanguageTextControllerStub::textEditLostFocus(Qt::FocusReason reason) +{ + QList params; + params.append(new Parameter(reason)); + stubMethodEntered("textEditLostFocus", params); +} + + + +// 3. CREATE A STUB INSTANCE +DuiSettingsLanguageTextControllerStub gDefaultDuiSettingsLanguageTextControllerStub; +DuiSettingsLanguageTextControllerStub *gDuiSettingsLanguageTextControllerStub = &gDefaultDuiSettingsLanguageTextControllerStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiSettingsLanguageTextController::DuiSettingsLanguageTextController(QObject *parent) +{ + gDuiSettingsLanguageTextControllerStub->DuiSettingsLanguageTextControllerConstructor(parent); +} + +DuiSettingsLanguageTextController::~DuiSettingsLanguageTextController() +{ + gDuiSettingsLanguageTextControllerStub->DuiSettingsLanguageTextControllerDestructor(); +} + +void DuiSettingsLanguageTextController::textEditLostFocus(Qt::FocusReason reason) +{ + gDuiSettingsLanguageTextControllerStub->textEditLostFocus(reason); +} + + +#endif diff --git a/tests/stubs/duisettingslanguagetextfactory_stub.h b/tests/stubs/duisettingslanguagetextfactory_stub.h new file mode 100644 index 000000000..ffbddd71b --- /dev/null +++ b/tests/stubs/duisettingslanguagetextfactory_stub.h @@ -0,0 +1,60 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISETTINGSLANGUAGETEXTFACTORY_STUB +#define DUISETTINGSLANGUAGETEXTFACTORY_STUB + +#include "duisettingslanguagetextfactory.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiSettingsLanguageTextFactoryStub : public StubBase +{ +public: + virtual DuiWidgetController *createWidget(const DuiSettingsLanguageText &settingsText, DuiSettingsLanguageWidget &rootWidget, DuiDataStore *dataStore); +}; + +// 2. IMPLEMENT STUB +DuiWidgetController *DuiSettingsLanguageTextFactoryStub::createWidget(const DuiSettingsLanguageText &settingsText, DuiSettingsLanguageWidget &rootWidget, DuiDataStore *dataStore) +{ + QList params; + params.append(new Parameter(&settingsText)); + params.append(new Parameter(rootWidget)); + params.append(new Parameter(dataStore)); + stubMethodEntered("createWidget", params); + return stubReturnValue("createWidget"); +} + + + +// 3. CREATE A STUB INSTANCE +DuiSettingsLanguageTextFactoryStub gDefaultDuiSettingsLanguageTextFactoryStub; +DuiSettingsLanguageTextFactoryStub *gDuiSettingsLanguageTextFactoryStub = &gDefaultDuiSettingsLanguageTextFactoryStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiWidgetController *DuiSettingsLanguageTextFactory::createWidget(const DuiSettingsLanguageText &settingsText, DuiSettingsLanguageWidget &rootWidget, DuiDataStore *dataStore) +{ + return gDuiSettingsLanguageTextFactoryStub->createWidget(settingsText, rootWidget, dataStore); +} + + +#endif diff --git a/tests/stubs/duisettingslanguagewidget_stub.h b/tests/stubs/duisettingslanguagewidget_stub.h new file mode 100644 index 000000000..9eaa7a687 --- /dev/null +++ b/tests/stubs/duisettingslanguagewidget_stub.h @@ -0,0 +1,65 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISETTINGSLANGUAGEWIDGET_STUB +#define DUISETTINGSLANGUAGEWIDGET_STUB + +#include "duisettingslanguagewidget.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiSettingsLanguageWidgetStub : public StubBase +{ +public: + virtual void DuiSettingsLanguageConstructor(QGraphicsItem *parent); + virtual void DuiSettingsLanguageDestructor(); +}; + +// 2. IMPLEMENT STUB +void DuiSettingsLanguageWidgetStub::DuiSettingsLanguageConstructor(QGraphicsItem *parent) +{ + Q_UNUSED(parent); + +} +void DuiSettingsLanguageWidgetStub::DuiSettingsLanguageDestructor() +{ + +} + + +// 3. CREATE A STUB INSTANCE +DuiSettingsLanguageWidgetStub gDefaultDuiSettingsLanguageWidgetStub; +DuiSettingsLanguageWidgetStub *gDuiSettingsLanguageWidgetStub = &gDefaultDuiSettingsLanguageWidgetStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiSettingsLanguageWidget::DuiSettingsLanguageWidget(QGraphicsItem *parent) : DuiWidgetController(parent) +{ + gDuiSettingsLanguageWidgetStub->DuiSettingsLanguageConstructor(parent); +} + +DuiSettingsLanguageWidget::~DuiSettingsLanguageWidget() +{ + gDuiSettingsLanguageWidgetStub->DuiSettingsLanguageDestructor(); +} + + +#endif diff --git a/tests/stubs/duislider_stub.h b/tests/stubs/duislider_stub.h new file mode 100644 index 000000000..4e6c31399 --- /dev/null +++ b/tests/stubs/duislider_stub.h @@ -0,0 +1,185 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISLIDER_STUB +#define DUISLIDER_STUB + +#include + +#include "duislider.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiSliderStub : public StubBase +{ +public: + virtual void DuiSliderConstructor(DuiWidget *parent); + virtual void DuiSliderDestructor(); + virtual int minimum(); + virtual int maximum(); + virtual int value(); + virtual void setMinimum(int minimum); + virtual void setMaximum(int maximum); + virtual void setRange(int minimum, int maximum); + virtual void setValue(int value); + virtual void valueChanged(int newValue); + virtual bool limitValue(); + virtual void updateStyle(); +}; + +// 2. IMPLEMENT STUB +void DuiSliderStub::DuiSliderConstructor(DuiWidget *parent) +{ + Q_UNUSED(parent); +} + +void DuiSliderStub::DuiSliderDestructor() +{ +} + +int DuiSliderStub::minimum() +{ + stubMethodEntered("minimum"); + return stubReturnValue("minimum"); +} + +int DuiSliderStub::maximum() +{ + stubMethodEntered("maximum"); + return stubReturnValue("maximum"); +} + +int DuiSliderStub::value() +{ + stubMethodEntered("value"); + return stubReturnValue("value"); +} + +void DuiSliderStub::setMinimum(int minimum) +{ + QList params; + params.append(new Parameter(minimum)); + stubMethodEntered("setMinimum", params); +} + +void DuiSliderStub::setMaximum(int maximum) +{ + QList params; + params.append(new Parameter(maximum)); + stubMethodEntered("setMaximum", params); +} + +void DuiSliderStub::setRange(int minimum, int maximum) +{ + QList params; + params.append(new Parameter(minimum)); + params.append(new Parameter(maximum)); + stubMethodEntered("setRange", params); +} + +void DuiSliderStub::setValue(int value) +{ + QList params; + params.append(new Parameter(value)); + stubMethodEntered("setValue", params); +} + +void DuiSliderStub::valueChanged(int newValue) +{ + QList params; + params.append(new Parameter(newValue)); + stubMethodEntered("valueChanged", params); +} + +bool DuiSliderStub::limitValue() +{ + stubMethodEntered("limitValue"); + return stubReturnValue("limitValue"); +} + +void DuiSliderStub::updateStyle() +{ + stubMethodEntered("updateStyle"); +} + +// 3. CREATE A STUB INSTANCE +DuiSliderStub gDefaultDuiSliderStub; +DuiSliderStub *gDuiSliderStub = &gDefaultDuiSliderStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiSlider::DuiSlider(DuiWidget *parent) +{ + gDuiSliderStub->DuiSliderConstructor(parent); +} + +DuiSlider::~DuiSlider() +{ + gDuiSliderStub->DuiSliderDestructor(); +} + +int DuiSlider::minimum() +{ + return gDuiSliderStub->minimum(); +} + +int DuiSlider::maximum() +{ + return gDuiSliderStub->maximum(); +} + +int DuiSlider::value() +{ + return gDuiSliderStub->value(); +} + +void DuiSlider::setMinimum(int minimum) +{ + gDuiSliderStub->setMinimum(minimum); +} + +void DuiSlider::setMaximum(int maximum) +{ + gDuiSliderStub->setMaximum(maximum); +} + +void DuiSlider::setRange(int minimum, int maximum) +{ + gDuiSliderStub->setRange(minimum, maximum); +} + +void DuiSlider::setValue(int value) +{ + gDuiSliderStub->setValue(value); +} + +bool DuiSlider::limitValue() +{ + return gDuiSliderStub->limitValue(); +} + +void DuiSlider::updateStyle() +{ + gDuiSliderStub->updateStyle(); +} + + +#endif diff --git a/tests/stubs/duisliderdotview_stub.h b/tests/stubs/duisliderdotview_stub.h new file mode 100644 index 000000000..da1b15425 --- /dev/null +++ b/tests/stubs/duisliderdotview_stub.h @@ -0,0 +1,194 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISLIDERDOTVIEW_STUB +#define DUISLIDERDOTVIEW_STUB + +#include "duisliderdotview.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiSliderDotViewStub : public StubBase +{ +public: + virtual void DuiSliderDotViewConstructor(DuiSlider *controller); + virtual void DuiSliderDotViewDestructor(); + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + virtual QRectF boundingRect() const; + virtual void setGeometry(const QRectF &rect); + virtual void updateStyle(); + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event); + DuiSliderDotViewPrivate *d_ptr ; + virtual void setPressed(bool pressed); + virtual void modelUpdated(const int index); + virtual QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint); +}; + +// 2. IMPLEMENT STUB +void DuiSliderDotViewStub::DuiSliderDotViewConstructor(DuiSlider *controller) +{ + Q_UNUSED(controller); + +} +void DuiSliderDotViewStub::DuiSliderDotViewDestructor() +{ + +} +void DuiSliderDotViewStub::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + QList params; + params.append(new Parameter(painter)); + params.append(new Parameter(option)); + params.append(new Parameter(widget)); + stubMethodEntered("paint", params); +} + +QRectF DuiSliderDotViewStub::boundingRect() const +{ + stubMethodEntered("boundingRect"); + return stubReturnValue("boundingRect"); +} + +void DuiSliderDotViewStub::setGeometry(const QRectF &rect) +{ + QList params; + params.append(new Parameter(rect)); + stubMethodEntered("setGeometry", params); +} + +void DuiSliderDotViewStub::updateStyle(void) +{ + stubMethodEntered("updateStyle"); +} + +void DuiSliderDotViewStub::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + QList params; + params.append(new Parameter(event)); + stubMethodEntered("mousePressEvent", params); +} + +void DuiSliderDotViewStub::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + QList params; + params.append(new Parameter(event)); + stubMethodEntered("mouseReleaseEvent", params); +} + +void DuiSliderDotViewStub::mouseMoveEvent(QGraphicsSceneMouseEvent *event) +{ + QList params; + params.append(new Parameter(event)); + stubMethodEntered("mouseMoveEvent", params); +} + +void DuiSliderDotViewStub::setPressed(bool pressed) +{ + QList params; + params.append(new Parameter(pressed)); + stubMethodEntered("setPressed", params); +} + +void DuiSliderDotViewStub::modelUpdated(const int index) +{ + QList params; + params.append(new Parameter(index)); + stubMethodEntered("modelUpdated", params); +} + +QSizeF DuiSliderDotViewStub::sizeHint(Qt::SizeHint which, const QSizeF &constraint) +{ + QList params; + params.append(new Parameter(which)); + params.append(new Parameter(constraint)); + stubMethodEntered("sizeHint", params); + return stubReturnValue("sizeHint"); +} + + +// 3. CREATE A STUB INSTANCE +DuiSliderDotViewStub gDefaultDuiSliderDotViewStub; +DuiSliderDotViewStub *gDuiSliderDotViewStub = &gDefaultDuiSliderDotViewStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiSliderDotView::DuiSliderDotView(DuiSlider *controller) +{ + gDuiSliderDotViewStub->DuiSliderDotViewConstructor(controller); +} + +DuiSliderDotView::~DuiSliderDotView() +{ + gDuiSliderDotViewStub->DuiSliderDotViewDestructor(); +} + +void DuiSliderDotView::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + gDuiSliderDotViewStub->paint(painter, option, widget); +} + +QRectF DuiSliderDotView::boundingRect() const +{ + return gDuiSliderDotViewStub->boundingRect(); +} + +void DuiSliderDotView::setGeometry(const QRectF &rect) +{ + gDuiSliderDotViewStub->setGeometry(rect); +} + +void DuiSliderDotView::updateStyle() +{ + gDuiSliderDotViewStub->updateStyle(); +} + +void DuiSliderDotView::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + gDuiSliderDotViewStub->mousePressEvent(event); +} + +void DuiSliderDotView::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + gDuiSliderDotViewStub->mouseReleaseEvent(event); +} + +void DuiSliderDotView::mouseMoveEvent(QGraphicsSceneMouseEvent *event) +{ + gDuiSliderDotViewStub->mouseMoveEvent(event); +} + +void DuiSliderDotView::setPressed(bool pressed) +{ + gDuiSliderDotViewStub->setPressed(pressed); +} + +void DuiSliderDotView::modelUpdated(const int index) +{ + gDuiSliderDotViewStub->modelUpdated(index); +} + +QSizeF DuiSliderDotView::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const +{ + return gDuiSliderDotViewStub->sizeHint(which, constraint); +} +#endif diff --git a/tests/stubs/duistylablebase_stub.h b/tests/stubs/duistylablebase_stub.h new file mode 100644 index 000000000..c4083ad72 --- /dev/null +++ b/tests/stubs/duistylablebase_stub.h @@ -0,0 +1,146 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISTYLABLEBASE_STUB +#define DUISTYLABLEBASE_STUB + +#include "duistylablebase.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiStylableBaseStub : public StubBase +{ +public: + virtual void DuiStylableBaseConstructor(); + virtual void DuiStylableBaseDestructor(); + virtual void updateStyle(); +// void styleUpdated ; + virtual const DuiStyleAttribute &styleAttribute(int index) const; + virtual bool styleHasAttribute(int index) const; + virtual void initialize(const DuiStyleDescription &description, const QObject *object, const QString &type, const QString &mode); + virtual const DuiStyleDescription &completeStyleDescription() const; + virtual const DuiStyleDescription &styleDescription(); + mutable DuiStyleAttribute *att; + DuiStylableBasePrivate *d_ptr ; +}; + +// 2. IMPLEMENT STUB + +void DuiStylableBaseStub::DuiStylableBaseConstructor() +{ + QColor col(0, 0, 0); + att = new DuiStyleAttribute(col); + +} +void DuiStylableBaseStub::DuiStylableBaseDestructor() +{ + delete att; +} +void DuiStylableBaseStub::updateStyle() +{ + stubMethodEntered("updateStyle"); +} + +const DuiStyleAttribute &DuiStylableBaseStub::styleAttribute(int index) const +{ + QList params; + params.append(new Parameter(index)); + stubMethodEntered("styleAttribute", params); + return *att; +} + +bool DuiStylableBaseStub::styleHasAttribute(int index) const +{ + QList params; + params.append(new Parameter(index)); + stubMethodEntered("styleHasAttribute", params); + return stubReturnValue("styleHasAttribute"); +} + +void DuiStylableBaseStub::initialize(const DuiStyleDescription &description, const QObject *object, const QString &type, const QString &mode) +{ + Q_UNUSED(object); + + QList params; + params.append(new Parameter(description)); + params.append(new Parameter(object)); + params.append(new Parameter(type)); + params.append(new Parameter(mode)); + stubMethodEntered("initialize", params); +} + +const DuiStyleDescription &DuiStylableBaseStub::completeStyleDescription() const +{ + stubMethodEntered("completeStyleDescription"); + return stubReturnValue("completeStyleDescription"); +} + +const DuiStyleDescription &DuiStylableBaseStub::styleDescription() +{ + stubMethodEntered("styleDescription"); + return stubReturnValue("styleDescription"); +} + + + +// 3. CREATE A STUB INSTANCE +DuiStylableBaseStub gDefaultDuiStylableBaseStub; +DuiStylableBaseStub *gDuiStylableBaseStub = &gDefaultDuiStylableBaseStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiStylableBase::~DuiStylableBase() +{ + gDuiStylableBaseStub->DuiStylableBaseDestructor(); +} + +void DuiStylableBase::updateStyle() +{ + gDuiStylableBaseStub->updateStyle(); +} + +const DuiStyleAttribute &DuiStylableBase::styleAttribute(int index) const +{ + return gDuiStylableBaseStub->styleAttribute(index); +} + +bool DuiStylableBase::styleHasAttribute(int index) const +{ + return gDuiStylableBaseStub->styleHasAttribute(index); +} + +void DuiStylableBase::initialize(const DuiStyleDescription &description, const QObject *object, const QString &type, const QString &mode) +{ + gDuiStylableBaseStub->initialize(description, object, type, mode); +} + +const DuiStyleDescription &DuiStylableBase::completeStyleDescription() const +{ + return gDuiStylableBaseStub->completeStyleDescription(); +} + +const DuiStyleDescription &DuiStylableBase::styleDescription() +{ + return gDuiStylableBaseStub->styleDescription(); +} + + +#endif diff --git a/tests/stubs/duistyle_stub.h b/tests/stubs/duistyle_stub.h new file mode 100644 index 000000000..ea2634140 --- /dev/null +++ b/tests/stubs/duistyle_stub.h @@ -0,0 +1,238 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISTYLE_STUB +#define DUISTYLE_STUB + +#include +#include "duistyle.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiStyleStub : public StubBase +{ +public: + + virtual void DuiStyleConstructor(const QObject *object, const DuiStyleData *dataLandscape, const DuiStyleData *dataPortrait, const DuiStyleDescription &desc); + virtual void DuiStyleDestructor(); + virtual const DuiStyleAttribute &operator[](int index) const; + virtual const DuiStyleAttribute &attribute(int index) const; + virtual void setOrientation(const Dui::Orientation &orientation); + virtual const Dui::Orientation &orientation() const; + virtual void setMode(const QString &mode); + virtual const QString &mode() const; + virtual void setAttribute(int index, DuiStyleAttribute *value); + DuiStylePrivate *d_ptr ; + mutable QStack cleanupStack; + virtual bool landscapePortraitStylesEqual() const; + virtual const DuiStyleAttribute &attribute(Dui::Orientation orientation, int index) const; + virtual bool hasAttribute(int index) const; +}; + +// 2. IMPLEMENT STUB +void DuiStyleStub::DuiStyleConstructor(const QObject *object, const DuiStyleData *dataLandscape, const DuiStyleData *dataPortrait, const DuiStyleDescription &desc) +{ + Q_UNUSED(object); + Q_UNUSED(dataLandscape); + Q_UNUSED(dataPortrait); + Q_UNUSED(desc); + +} +void DuiStyleStub::DuiStyleDestructor() +{ + // delete cleanupStack + while (!cleanupStack.isEmpty()) + delete cleanupStack.pop(); +} +const DuiStyleAttribute &DuiStyleStub::operator[](int index) const +{ + QList params; + params.append(new Parameter(index)); + stubMethodEntered("operator[]", params); + DuiStyleAttribute *myDSA = new DuiStyleAttribute(0); + cleanupStack.push(myDSA); + return *myDSA; +} + +const DuiStyleAttribute &DuiStyleStub::attribute(int index) const +{ + QList params; + params.append(new Parameter(index)); + stubMethodEntered("attribute", params); + DuiStyleAttribute *myDSA = new DuiStyleAttribute(0); + cleanupStack.push(myDSA); + + return *myDSA; + + // Can't do the following because of the reference thing and the + // fact that DuiStyleAttribute doesn't have a default constructor. + // instead, we do the above, and if the user of the stub needs + // special behaviour (almost always, I'd think) they can derive + // a class from this stub class and override this function, + // making it do what they want. + // An alternative is to override the StubBase::stubReturnValue(Qstring + // methodName) function so that, instead of using T() (the + // default constructor), it uses a different one. + // ...but this will do for now + // + // return stubReturnValue(QString("attribute")); +} +const DuiStyleAttribute &DuiStyleStub::attribute(Dui::Orientation orientation, int index) const +{ + QList params; + params.append(new Parameter(orientation)); + params.append(new Parameter(index)); + stubMethodEntered("attribute", params); + DuiStyleAttribute *myDSA = new DuiStyleAttribute(0); + cleanupStack.push(myDSA); + + return *myDSA; + + // Can't do the following because of the reference thing and the + // fact that DuiStyleAttribute doesn't have a default constructor. + // instead, we do the above, and if the user of the stub needs + // special behaviour (almost always, I'd think) they can derive + // a class from this stub class and override this function, + // making it do what they want. + // An alternative is to override the StubBase::stubReturnValue(Qstring + // methodName) function so that, instead of using T() (the + // default constructor), it uses a different one. + // ...but this will do for now + // + // return stubReturnValue(QString("attribute")); +} + +void DuiStyleStub::setOrientation(const Dui::Orientation &orientation) +{ + QList params; + params.append(new Parameter(orientation)); + stubMethodEntered("setOrientation", params); +} + +const Dui::Orientation &DuiStyleStub::orientation() const +{ + stubMethodEntered("orientation"); + return stubReturnValue("orientation"); +} + +void DuiStyleStub::setMode(const QString &mode) +{ + QList params; + params.append(new Parameter(mode)); + stubMethodEntered("setMode", params); +} + +const QString &DuiStyleStub::mode() const +{ + stubMethodEntered("mode"); + return stubReturnValue("mode"); +} + +void DuiStyleStub::setAttribute(int index, DuiStyleAttribute *value) +{ + QList params; + params.append(new Parameter(index)); + params.append(new Parameter(value)); + stubMethodEntered("setAttribute", params); +} + +bool DuiStyleStub::landscapePortraitStylesEqual() const +{ + return stubReturnValue("landscapePortraitStylesEqual"); +} + +bool DuiStyleStub::hasAttribute(int index) const +{ + QList params; + params.append(new Parameter(index)); + stubMethodEntered("hasAttribute", params); + return stubReturnValue("hasAttribute"); +} + + +// 3. CREATE A STUB INSTANCE +DuiStyleStub gDefaultDuiStyleStub; +DuiStyleStub *gDuiStyleStub = &gDefaultDuiStyleStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiStyle::DuiStyle(const QObject *object, const DuiStyleData *dataLandscape, const DuiStyleData *dataPortrait, const DuiStyleDescription &desc) : d_ptr(0) +{ + gDuiStyleStub->DuiStyleConstructor(object, dataLandscape, dataPortrait, desc); +} + +DuiStyle::~DuiStyle() +{ + gDuiStyleStub->DuiStyleDestructor(); +} + +const DuiStyleAttribute &DuiStyle::operator[](int index) const +{ + return gDuiStyleStub->operator[](index); +} + +const DuiStyleAttribute &DuiStyle::attribute(int index) const +{ + return gDuiStyleStub->attribute(index); +} + +const DuiStyleAttribute &DuiStyle::attribute(Dui::Orientation orientation, int index) const +{ + return gDuiStyleStub->attribute(orientation, index); +} + +void DuiStyle::setOrientation(const Dui::Orientation &orientation) +{ + gDuiStyleStub->setOrientation(orientation); +} + +const Dui::Orientation &DuiStyle::orientation() const +{ + return gDuiStyleStub->orientation(); +} + +void DuiStyle::setMode(const QString &mode) +{ + gDuiStyleStub->setMode(mode); +} + +const QString &DuiStyle::mode() const +{ + return gDuiStyleStub->mode(); +} + +void DuiStyle::setAttribute(int index, DuiStyleAttribute *value) +{ + gDuiStyleStub->setAttribute(index, value); +} + +bool DuiStyle::landscapePortraitStylesEqual() const +{ + return gDuiStyleStub->landscapePortraitStylesEqual(); +} + +bool DuiStyle::hasAttribute(int index) const +{ + return gDuiStyleStub->hasAttribute(index); +} + + +#endif diff --git a/tests/stubs/duistyledescription_stub.h b/tests/stubs/duistyledescription_stub.h new file mode 100644 index 000000000..a2ea2f68e --- /dev/null +++ b/tests/stubs/duistyledescription_stub.h @@ -0,0 +1,144 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISTYLEDESCRIPTION_STUB +#define DUISTYLEDESCRIPTION_STUB + +#include "duistyledescription.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiStyleDescriptionStub : public StubBase +{ +public: + virtual void DuiStyleDescriptionConstructor(); + virtual void DuiStyleDescriptionConstructor(const DuiStyleDescription &other); + virtual void DuiStyleDescriptionDestructor(); + virtual const DuiStyleDescription &operator=(const DuiStyleDescription &other); + virtual bool operator==(const DuiStyleDescription &other) const; + virtual void addAttribute(int index, const QString &name); + virtual QString attributeAtIndex(int index) const; + virtual int numberOfAttributes() const; + DuiStyleDescriptionPrivate *d_ptr ; +}; + +// 2. IMPLEMENT STUB +void DuiStyleDescriptionStub::DuiStyleDescriptionConstructor() +{ + +} +void DuiStyleDescriptionStub::DuiStyleDescriptionConstructor(const DuiStyleDescription &other) +{ + Q_UNUSED(other); + +} +void DuiStyleDescriptionStub::DuiStyleDescriptionDestructor() +{ + +} +const DuiStyleDescription &DuiStyleDescriptionStub::operator=(const DuiStyleDescription &other) +{ + QList params; + params.append(new Parameter(other)); + stubMethodEntered("operator=", params); + return stubReturnValue("operator="); +} + +bool DuiStyleDescriptionStub::operator==(const DuiStyleDescription &other) const +{ + QList params; + params.append(new Parameter(other)); + stubMethodEntered("operator==", params); + return stubReturnValue("operator=="); +} + +void DuiStyleDescriptionStub::addAttribute(int index, const QString &name) +{ + QList params; + params.append(new Parameter(index)); + params.append(new Parameter(name)); + stubMethodEntered("addAttribute", params); +} + +QString DuiStyleDescriptionStub::attributeAtIndex(int index) const +{ + QList params; + params.append(new Parameter(index)); + stubMethodEntered("attributeAtIndex", params); + return stubReturnValue("attributeAtIndex"); +} + +int DuiStyleDescriptionStub::numberOfAttributes() const +{ + stubMethodEntered("numberOfAttributes"); + return stubReturnValue("numberOfAttributes"); +} + + + +// 3. CREATE A STUB INSTANCE +// while executing, static member initization is done first. +static DuiStyleDescriptionStub gDefaultDuiStyleDescriptionStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiStyleDescription::DuiStyleDescription() : d_ptr(0) +{ + gDefaultDuiStyleDescriptionStub.DuiStyleDescriptionConstructor(); +} + +DuiStyleDescription::DuiStyleDescription(const DuiStyleDescription &other) : d_ptr(0) +{ + gDefaultDuiStyleDescriptionStub.DuiStyleDescriptionConstructor(other); +} + +DuiStyleDescription::~DuiStyleDescription() +{ + gDefaultDuiStyleDescriptionStub.DuiStyleDescriptionDestructor(); +} + +const DuiStyleDescription &DuiStyleDescription::operator=(const DuiStyleDescription &other) +{ + return gDefaultDuiStyleDescriptionStub.operator = (other); +} + +bool DuiStyleDescription::operator==(const DuiStyleDescription &other) const +{ + return gDefaultDuiStyleDescriptionStub.operator == (other); +} + +void DuiStyleDescription::addAttribute(int index, const QString &name) +{ + gDefaultDuiStyleDescriptionStub.addAttribute(index, name); +} + +QString DuiStyleDescription::attributeAtIndex(int index) const +{ + return gDefaultDuiStyleDescriptionStub.attributeAtIndex(index); +} + +int DuiStyleDescription::numberOfAttributes() const +{ + return gDefaultDuiStyleDescriptionStub.numberOfAttributes(); +} + + +#endif diff --git a/tests/stubs/duistylesheet_stub.h b/tests/stubs/duistylesheet_stub.h new file mode 100644 index 000000000..986588a7e --- /dev/null +++ b/tests/stubs/duistylesheet_stub.h @@ -0,0 +1,96 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISTYLESHEET_STUB +#define DUISTYLESHEET_STUB + +#include "duistylesheet.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiStyleSheetStub : public StubBase +{ +public: + virtual void DuiStyleSheetConstructor(); + virtual void DuiStyleSheetDestructor(); + virtual DuiStyleData *createStyleDataObject(const QObject *object, const DuiStyle::Orientation &orientation, const QString &mode, const DuiStyleDescription &description); + virtual void findAttributeValues(const QObject *object, const QVector attributes, QVector &out); +}; + +// 2. IMPLEMENT STUB +void DuiStyleSheetStub::DuiStyleSheetConstructor() +{ + +} +void DuiStyleSheetStub::DuiStyleSheetDestructor() +{ + +} +DuiStyleData *DuiStyleSheetStub::createStyleDataObject(const QObject *object, const DuiStyle::Orientation &orientation, const QString &mode, const DuiStyleDescription &description) +{ + QList params; + params.append(new Parameter(object)); + params.append(new Parameter(orientation)); + params.append(new Parameter(mode)); + params.append(new Parameter(description)); + stubMethodEntered("createStyleDataObject", params); + return stubReturnValue("createStyleDataObject"); +} + +void DuiStyleSheetStub::findAttributeValues(const QObject *object, const QVector attributes, QVector &out) +{ + QList params; + params.append(new Parameter(object)); + params.append(new Parameter >(attributes)); + params.append(new Parameter & >(out)); + stubMethodEntered("findAttributeValues", params); +} + + + +// 3. CREATE A STUB INSTANCE +DuiStyleSheetStub gDefaultDuiStyleSheetStub; +DuiStyleSheetStub *gDuiStyleSheetStub = &gDefaultDuiStyleSheetStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiStyleSheet::DuiStyleSheet() +{ + gDuiStyleSheetStub->DuiStyleSheetConstructor(); +} + +DuiStyleSheet::~DuiStyleSheet() +{ + gDuiStyleSheetStub->DuiStyleSheetDestructor(); +} + +DuiStyleData *DuiStyleSheet::createStyleDataObject(const QObject *object, const DuiStyle::Orientation &orientation, const QString &mode, const DuiStyleDescription &description) +{ + return gDuiStyleSheetStub->createStyleDataObject(object, orientation, mode, description); +} + +void DuiStyleSheet::findAttributeValues(const QObject *object, const QVector attributes, QVector &out) +{ + gDuiStyleSheetStub->findAttributeValues(object, attributes, out); +} + + +#endif diff --git a/tests/stubs/duistylesheetparser_stub.h b/tests/stubs/duistylesheetparser_stub.h new file mode 100644 index 000000000..dfb18729f --- /dev/null +++ b/tests/stubs/duistylesheetparser_stub.h @@ -0,0 +1,91 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUISTYLESHEETPARSER_STUB +#define DUISTYLESHEETPARSER_STUB + +#include "duistylesheetparser.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiStyleSheetParserStub : public StubBase +{ +public: + virtual void DuiStyleSheetParserConstructor(); + virtual void DuiStyleSheetParserDestructor(); + virtual bool load(const QString &filename); + virtual QList & selectors() const; + DuiStyleSheetParserPrivate *d_ptr ; +}; + +// 2. IMPLEMENT STUB +void DuiStyleSheetParserStub::DuiStyleSheetParserConstructor() +{ + +} +void DuiStyleSheetParserStub::DuiStyleSheetParserDestructor() +{ + +} +bool DuiStyleSheetParserStub::load(const QString &filename) +{ + QList params; + params.append(new Parameter(filename)); + stubMethodEntered("load", params); + return stubReturnValue("load"); +} + +QList & DuiStyleSheetParserStub::selectors() const +{ + stubMethodEntered("selectors"); + return stubReturnValue< QList >("selectors"); +} + + + +// 3. CREATE A STUB INSTANCE +DuiStyleSheetParserStub gDefaultDuiStyleSheetParserStub; +DuiStyleSheetParserStub *gDuiStyleSheetParserStub = &gDefaultDuiStyleSheetParserStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiStyleSheetParser::DuiStyleSheetParser() +{ + gDuiStyleSheetParserStub->DuiStyleSheetParserConstructor(); +} + +DuiStyleSheetParser::~DuiStyleSheetParser() +{ + gDuiStyleSheetParserStub->DuiStyleSheetParserDestructor(); +} + +bool DuiStyleSheetParser::load(const QString &filename) +{ + return gDuiStyleSheetParserStub->load(filename); +} + +QList & DuiStyleSheetParser::selectors() const +{ + return gDuiStyleSheetParserStub->selectors(); +} + + +#endif diff --git a/tests/stubs/duitexteditview_stub.h b/tests/stubs/duitexteditview_stub.h new file mode 100644 index 000000000..106b96fe0 --- /dev/null +++ b/tests/stubs/duitexteditview_stub.h @@ -0,0 +1,158 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUITEXTEDITVIEW_STUB_H +#define DUITEXTEDITVIEW_STUB_H + +#include +#include + +// 1. DECLARE STUB +class DuiTextEditViewStub : public StubBase +{ +public: + virtual void duiTextEditViewConstructor(DuiTextEdit *controller); + virtual void duiTextEditViewDestructor(); + virtual void paint(QPainter *painter, + const QStyleOptionGraphicsItem *option, + QWidget *widget = 0); + virtual QRectF boundingRect() const; + virtual void setGeometry(const QRectF &rect); + virtual void setFocused(bool focused); + virtual void updateData(const int index); + virtual void styleUpdated(); + virtual void updateGeometry(); +}; + + +// 2. IMPLEMENT STUB +void DuiTextEditViewStub::duiTextEditViewConstructor(DuiTextEdit *controller) +{ + Q_UNUSED(controller); +} + +void DuiTextEditViewStub::duiTextEditViewDestructor() +{ +} + +void DuiTextEditViewStub::paint(QPainter *painter, + const QStyleOptionGraphicsItem *option, + QWidget *widget) +{ + QList params; + params.append(new Parameter(painter)); + params.append(new Parameter(option)); + params.append(new Parameter(widget)); + stubMethodEntered("paint", params); +} + +QRectF DuiTextEditViewStub::boundingRect() const +{ + stubMethodEntered("boundingRect"); + return stubReturnValue("boundingRect"); +} + +void DuiTextEditViewStub::setGeometry(const QRectF &rect) +{ + QList params; + params.append(new Parameter(rect)); + stubMethodEntered("setGeometry", params); +} + +void DuiTextEditViewStub::setFocused(bool focused) +{ + QList params; + params.append(new Parameter(focused)); + stubMethodEntered("setFocused", params); +} + + +void DuiTextEditViewStub::updateData(const int index) +{ + QList params; + params.append(new Parameter(index)); + stubMethodEntered("modelUpdated", params); +} + +void DuiTextEditViewStub::styleUpdated() +{ + stubMethodEntered("updateStyle"); +} + +void DuiTextEditViewStub::updateGeometry() +{ + stubMethodEntered("updateGeometry"); +} + +// 3. CREATE A STUB INSTANCE +DuiTextEditViewStub gDefaultDuiTextEditViewStub; +DuiTextEditViewStub *gDuiTextEditViewStub = &gDefaultDuiTextEditViewStub; + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiTextEditView::DuiTextEditView(DuiTextEdit *controller) +{ + gDuiTextEditViewStub->duiTextEditViewConstructor(controller); +} + +DuiTextEditView::~DuiTextEditView() +{ + gDuiTextEditViewStub->duiTextEditViewDestructor(); +} + +void DuiTextEditView::paint(QPainter *painter, + const QStyleOptionGraphicsItem *option, + QWidget *widget) +{ + Q_UNUSED(painter); + Q_UNUSED(option); + Q_UNUSED(widget); +} + +QRectF DuiTextEditView::boundingRect() const +{ + return gDuiTextEditViewStub->boundingRect(); +} + +void DuiTextEditView::setGeometry(const QRectF &rect) +{ + gDuiTextEditViewStub->setGeometry(rect); +} + +void DuiTextEditView::setFocused(bool focused) +{ + gDuiTextEditViewStub->setFocused(focused); +} + +void DuiTextEditView::updateData(const int index) +{ + gDuiTextEditViewStub->updateData(index); +} + +void DuiTextEditView::styleUpdated() +{ + gDuiTextEditViewStub->styleUpdated(); +} + +void DuiTextEditView::updateGeometry() +{ + gDuiTextEditViewStub->updateGeometry(); +} + + +#endif diff --git a/tests/stubs/duitheme_stub.h b/tests/stubs/duitheme_stub.h new file mode 100644 index 000000000..4551aef59 --- /dev/null +++ b/tests/stubs/duitheme_stub.h @@ -0,0 +1,281 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUITHEME_STUB +#define DUITHEME_STUB + +//#include +#include +#include +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiThemeStub : public StubBase +{ +public: + virtual void DuiThemeConstructor(const QString &applicationName, const QString &imglistFilename = QString(), DuiTheme::ThemeService themeService = DuiTheme::AnyTheme); + virtual void DuiThemeDestructor(); + + virtual DuiTheme *instance(); + /*virtual QPixmap * getPixmap(const QString &id, const QSize &size); + virtual QPixmap * getPixmap(const QString &id, const QSizeF &size); + virtual QPixmap * getPixmap(const QString &id, int x, int y); + virtual QPixmap * getPixmap(const QString &id, qreal x, qreal y);*/ + virtual QPixmap *pixmap(const QString &id, const QSize &size); + virtual QPixmap *pixmap(const QString &id, const QSizeF &size); + //virtual QPixmap * pixmap(const QString &id, int x, int y); + //virtual QPixmap * pixmap(const QString &id, qreal x, qreal y); + //virtual void setApplicationName(const QString &name); + virtual void releasePixmap(const QPixmap *pixmap); + virtual DuiWidgetView *view(const DuiWidgetController *controller); + virtual bool addPixmapDirectory(const QString &directoryName, const bool &recursive); + virtual void changeTheme(const QString &theme_id); + virtual bool loadCSS(const QString &filename, bool append = true); +}; + +// 2. IMPLEMENT STUB +void DuiThemeStub::DuiThemeConstructor(const QString &applicationName, const QString &imglistFilename, DuiTheme::ThemeService themeService) +{ + Q_UNUSED(applicationName) + Q_UNUSED(imglistFilename) + Q_UNUSED(themeService) +} +void DuiThemeStub::DuiThemeDestructor() +{ + +} + +// 3. CREATE A STUB INSTANCE +DuiThemeStub gDefaultDuiThemeStub; +DuiThemeStub *gDuiThemeStub = &gDefaultDuiThemeStub; + +static DuiTheme gTheme("STUB"); + +DuiTheme *DuiThemeStub::instance() +{ + stubMethodEntered("instance"); + // this is an exception to the regular pattern + // because duitheme has a single instance + return &gTheme; +} + +/*QPixmap * DuiThemeStub::getPixmap(const QString &id, const QSize &size) +{ + QList params; + params.append(new Parameter(id)); + params.append(new Parameter(size)); + stubMethodEntered("getPixmap", params); + return stubReturnValue("getPixmap"); +} + +QPixmap * DuiThemeStub::getPixmap(const QString &id, const QSizeF &size) +{ + QList params; + params.append(new Parameter(id)); + params.append(new Parameter(size)); + stubMethodEntered("getPixmap", params); + return stubReturnValue("getPixmap"); +} + +QPixmap * DuiThemeStub::getPixmap(const QString &id, int x, int y) +{ + QList params; + params.append(new Parameter(id)); + params.append(new Parameter(x)); + params.append(new Parameter(y)); + stubMethodEntered("getPixmap", params); + return stubReturnValue("getPixmap"); +} + +QPixmap * DuiThemeStub::getPixmap(const QString &id, qreal x, qreal y) +{ + QList params; + params.append(new Parameter(id)); + params.append(new Parameter(x)); + params.append(new Parameter(y)); + stubMethodEntered("getPixmap", params); + return stubReturnValue("getPixmap"); +}*/ + +QPixmap *DuiThemeStub::pixmap(const QString &id, const QSize &size) +{ + QList params; + params.append(new Parameter(id)); + params.append(new Parameter(size)); + stubMethodEntered("pixmap", params); + return stubReturnValue("pixmap"); +} + +QPixmap *DuiThemeStub::pixmap(const QString &id, const QSizeF &size) +{ + QList params; + params.append(new Parameter(id)); + params.append(new Parameter(size)); + stubMethodEntered("pixmap", params); + return stubReturnValue("pixmap"); +} + +/*QPixmap * DuiThemeStub::pixmap(const QString &id, int x, int y) +{ + QList params; + params.append(new Parameter(id)); + params.append(new Parameter(x)); + params.append(new Parameter(y)); + stubMethodEntered("pixmap", params); + return stubReturnValue("pixmap"); +} + +QPixmap * DuiThemeStub::pixmap(const QString &id, qreal x, qreal y) +{ + QList params; + params.append(new Parameter(id)); + params.append(new Parameter(x)); + params.append(new Parameter(y)); + stubMethodEntered("pixmap", params); + return stubReturnValue("pixmap"); +} + +void DuiThemeStub::setApplicationName(const QString &name) +{ + QList params; + params.append(new Parameter(name)); + stubMethodEntered("setApplicationName", params); +}*/ + +void DuiThemeStub::releasePixmap(const QPixmap *pixmap) +{ + QList params; + params.append(new Parameter(pixmap)); + stubMethodEntered("releasePixmap", params); +} + +DuiWidgetView *DuiThemeStub::view(const DuiWidgetController *controller) +{ + QList params; + params.append(new Parameter(controller)); + stubMethodEntered("view", params); + return stubReturnValue("view"); +} + +bool DuiThemeStub::addPixmapDirectory(const QString &directoryName, const bool &recursive) +{ + QList params; + params.append(new Parameter(directoryName)); + params.append(new Parameter(recursive)); + stubMethodEntered("addPixmapDirectory", params); + return stubReturnValue("addPixmapDirectory"); +} + +void DuiThemeStub::changeTheme(const QString &theme_id) +{ + Q_UNUSED(theme_id); + stubMethodEntered("changeTheme"); +} + +bool DuiThemeStub::loadCSS(const QString &filename, bool append) +{ + Q_UNUSED(append); + + QList params; + params.append(new Parameter(filename)); + stubMethodEntered("loadCSS", params); + return stubReturnValue("loadCSS"); +} + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiTheme::DuiTheme(const QString &applicationName, const QString &imglistFilename, DuiTheme::ThemeService themeService) : d_ptr(0) +{ + gDuiThemeStub->DuiThemeConstructor(applicationName, imglistFilename, themeService); +} + +DuiTheme::~DuiTheme() +{ + //gDuiThemeStub->DuiThemeDestructor(); +} + +DuiTheme *DuiTheme::instance() +{ + return gDuiThemeStub->instance(); +} + +/*QPixmap * DuiTheme::getPixmap(const QString &id, const QSize &size) +{ + return gDuiThemeStub->getPixmap(id, size); +} + +QPixmap * DuiTheme::getPixmap(const QString &id, const QSizeF &size) +{ + return gDuiThemeStub->getPixmap(id, size); +} + +QPixmap * DuiTheme::getPixmap(const QString &id, int x, int y) +{ + return gDuiThemeStub->getPixmap(id, x, y); +} + +QPixmap * DuiTheme::getPixmap(const QString &id, qreal x, qreal y) +{ + return gDuiThemeStub->getPixmap(id, x, y); +}*/ + +const QPixmap *DuiTheme::pixmap(const QString &id, const QSize &size) +{ + return gDuiThemeStub->pixmap(id, size); +} + +/*QPixmap * DuiTheme::pixmap(const QString &id, int x, int y) +{ + return gDuiThemeStub->pixmap(id, x, y); +} + +QPixmap * DuiTheme::pixmap(const QString &id, qreal x, qreal y) +{ + return gDuiThemeStub->pixmap(id, x, y); +}*/ + + +void DuiTheme::releasePixmap(const QPixmap *pixmap) +{ + gDuiThemeStub->releasePixmap(pixmap); +} + +DuiWidgetView *DuiTheme::view(const DuiWidgetController *controller) +{ + return gDuiThemeStub->view(controller); +} + +bool DuiTheme::addPixmapDirectory(const QString &directoryName, const bool &recursive) +{ + return gDuiThemeStub->addPixmapDirectory(directoryName, recursive); +} + +void DuiTheme::changeTheme(const QString &theme_id) +{ + gDuiThemeStub->changeTheme(theme_id); +} + +bool DuiTheme::loadCSS(const QString &filename, bool append) +{ + return gDuiThemeStub->loadCSS(filename, append); +} + + +#endif diff --git a/tests/stubs/duitheme_stub.h_backup b/tests/stubs/duitheme_stub.h_backup new file mode 100644 index 000000000..f5c463444 --- /dev/null +++ b/tests/stubs/duitheme_stub.h_backup @@ -0,0 +1,391 @@ +#ifndef DUITHEME_STUB +#define DUITHEME_STUB + +#include +#include +#include +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiThemeStub : public StubBase +{ +public: + virtual void DuiThemeConstructor(); + virtual void DuiThemeDestructor(); + virtual bool connectThemeDaemon(); + virtual DuiTheme * instance(); + virtual QPixmap * getPixmap(const QString &id, const QSize &size); + virtual QPixmap * getPixmap(const QString &id, const QSizeF &size); + virtual QPixmap * getPixmap(const QString &id, int x, int y); + virtual QPixmap * getPixmap(const QString &id, qreal x, qreal y); + virtual QPixmap * pixmap(const QString &id, const QSize &size); + virtual QPixmap * pixmap(const QString &id, const QSizeF &size); + virtual QPixmap * pixmap(const QString &id, int x, int y); + virtual QPixmap * pixmap(const QString &id, qreal x, qreal y); + virtual void setApplicationName(const QString &name); + virtual void releasePixmap(QPixmap *pixmap); + virtual const DuiStyle * style(const QObject *object, const DuiStyleDescription &desc); + virtual void releaseStyle(const DuiStyle *style); + virtual DuiWidgetView * view(const QObject *object, DuiWidgetController *controller); + virtual bool loadSVG(const QString &filename); + virtual bool addCSS(const QString &filename); + virtual bool addPixmapDirectory(const QString &directoryName); + virtual bool addPixmapDirectoryRecursive(const QString &directoryName); + virtual void prepareThemeChange(); + virtual void changeTheme(); + virtual bool loadCSS(const QString &filename); + virtual bool deletePixmapSearchList(const QString &applicationName, int version); + virtual QPixmap * pixmapFromHandle(int handle); +}; + +// 2. IMPLEMENT STUB +void DuiThemeStub::DuiThemeConstructor() +{ + +} +void DuiThemeStub::DuiThemeDestructor() +{ + +} +bool DuiThemeStub::connectThemeDaemon() +{ + stubMethodEntered("connectThemeDaemon"); + return stubReturnValue("connectThemeDaemon"); +} + +static DuiTheme gTheme; + +DuiTheme * DuiThemeStub::instance() +{ + stubMethodEntered("instance"); + // this is an exception to the regular pattern + // because duitheme has a single instance + return &gTheme; +} + +QPixmap * DuiThemeStub::getPixmap(const QString &id, const QSize &size) +{ + QList params; + params.append( new Parameter(id)); + params.append( new Parameter(size)); + stubMethodEntered("getPixmap",params); + return stubReturnValue("getPixmap"); +} + +QPixmap * DuiThemeStub::getPixmap(const QString &id, const QSizeF &size) +{ + QList params; + params.append( new Parameter(id)); + params.append( new Parameter(size)); + stubMethodEntered("getPixmap",params); + return stubReturnValue("getPixmap"); +} + +QPixmap * DuiThemeStub::getPixmap(const QString &id, int x, int y) +{ + QList params; + params.append( new Parameter(id)); + params.append( new Parameter(x)); + params.append( new Parameter(y)); + stubMethodEntered("getPixmap",params); + return stubReturnValue("getPixmap"); +} + +QPixmap * DuiThemeStub::getPixmap(const QString &id, qreal x, qreal y) +{ + QList params; + params.append( new Parameter(id)); + params.append( new Parameter(x)); + params.append( new Parameter(y)); + stubMethodEntered("getPixmap",params); + return stubReturnValue("getPixmap"); +} + +QPixmap * DuiThemeStub::pixmap(const QString &id, const QSize &size) +{ + QList params; + params.append( new Parameter(id)); + params.append( new Parameter(size)); + stubMethodEntered("pixmap",params); + return stubReturnValue("pixmap"); +} + +QPixmap * DuiThemeStub::pixmap(const QString &id, const QSizeF &size) +{ + QList params; + params.append( new Parameter(id)); + params.append( new Parameter(size)); + stubMethodEntered("pixmap",params); + return stubReturnValue("pixmap"); +} + +QPixmap * DuiThemeStub::pixmap(const QString &id, int x, int y) +{ + QList params; + params.append( new Parameter(id)); + params.append( new Parameter(x)); + params.append( new Parameter(y)); + stubMethodEntered("pixmap",params); + return stubReturnValue("pixmap"); +} + +QPixmap * DuiThemeStub::pixmap(const QString &id, qreal x, qreal y) +{ + QList params; + params.append( new Parameter(id)); + params.append( new Parameter(x)); + params.append( new Parameter(y)); + stubMethodEntered("pixmap",params); + return stubReturnValue("pixmap"); +} + +void DuiThemeStub::setApplicationName(const QString &name) +{ + QList params; + params.append( new Parameter(name)); + stubMethodEntered("setApplicationName",params); +} + +void DuiThemeStub::releasePixmap(QPixmap *pixmap) +{ + QList params; + params.append( new Parameter(pixmap)); + stubMethodEntered("releasePixmap",params); +} + +const DuiStyle * DuiThemeStub::style(const QObject *object, const DuiStyleDescription &desc) +{ + QList params; + params.append( new Parameter(object)); + params.append( new Parameter(desc)); + stubMethodEntered("style",params); + return stubReturnValue("style"); +} + +void DuiThemeStub::releaseStyle(const DuiStyle *style) +{ + QList params; + params.append( new Parameter(style)); + stubMethodEntered("releaseStyle",params); +} + +DuiWidgetView * DuiThemeStub::view(const QObject *object, DuiWidgetController *controller) +{ + QList params; + params.append( new Parameter(object)); + params.append( new Parameter(controller)); + stubMethodEntered("view",params); + return stubReturnValue("view"); +} + +bool DuiThemeStub::loadSVG(const QString &filename) +{ + QList params; + params.append( new Parameter(filename)); + stubMethodEntered("loadSVG",params); + return stubReturnValue("loadSVG"); +} + +bool DuiThemeStub::addCSS(const QString &filename) +{ + QList params; + params.append( new Parameter(filename)); + stubMethodEntered("addCSS",params); + return stubReturnValue("addCSS"); +} + +bool DuiThemeStub::addPixmapDirectory(const QString &directoryName) +{ + QList params; + params.append( new Parameter(directoryName)); + stubMethodEntered("addPixmapDirectory",params); + return stubReturnValue("addPixmapDirectory"); +} + +bool DuiThemeStub::addPixmapDirectoryRecursive(const QString &directoryName) +{ + QList params; + params.append( new Parameter(directoryName)); + stubMethodEntered("addPixmapDirectoryRecursive",params); + return stubReturnValue("addPixmapDirectoryRecursive"); +} + +void DuiThemeStub::prepareThemeChange() +{ + stubMethodEntered("prepareThemeChange"); +} + +void DuiThemeStub::changeTheme() +{ + stubMethodEntered("changeTheme"); +} + +bool DuiThemeStub::loadCSS(const QString &filename) +{ + QList params; + params.append( new Parameter(filename)); + stubMethodEntered("loadCSS",params); + return stubReturnValue("loadCSS"); +} + +bool DuiThemeStub::deletePixmapSearchList(const QString &applicationName, int version) +{ + QList params; + params.append( new Parameter(applicationName)); + params.append( new Parameter(version)); + stubMethodEntered("deletePixmapSearchList",params); + return stubReturnValue("deletePixmapSearchList"); +} + +QPixmap * DuiThemeStub::pixmapFromHandle(int handle) +{ + QList params; + params.append( new Parameter(handle)); + stubMethodEntered("pixmapFromHandle",params); + return stubReturnValue("pixmapFromHandle"); +} + + + +// 3. CREATE A STUB INSTANCE +DuiThemeStub gDefaultDuiThemeStub; +DuiThemeStub* gDuiThemeStub = &gDefaultDuiThemeStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiTheme::DuiTheme() +{ + // can't call this since DuiTheme is a global instance + //gDuiThemeStub->DuiThemeConstructor(); +} + +DuiTheme::~DuiTheme() +{ + // can't call this since DuiTheme is a global instance + //gDuiThemeStub->DuiThemeDestructor(); +} + +bool DuiTheme::connectThemeDaemon() +{ + return gDuiThemeStub->connectThemeDaemon(); +} + +DuiTheme * DuiTheme::instance() +{ + return gDuiThemeStub->instance(); +} + +QPixmap * DuiTheme::getPixmap(const QString &id, const QSize &size) +{ + return gDuiThemeStub->getPixmap(id, size); +} + +QPixmap * DuiTheme::getPixmap(const QString &id, const QSizeF &size) +{ + return gDuiThemeStub->getPixmap(id, size); +} + +QPixmap * DuiTheme::getPixmap(const QString &id, int x, int y) +{ + return gDuiThemeStub->getPixmap(id, x, y); +} + +QPixmap * DuiTheme::getPixmap(const QString &id, qreal x, qreal y) +{ + return gDuiThemeStub->getPixmap(id, x, y); +} + +QPixmap * DuiTheme::pixmap(const QString &id, const QSize &size) +{ + return gDuiThemeStub->pixmap(id, size); +} + +QPixmap * DuiTheme::pixmap(const QString &id, const QSizeF &size) +{ + return gDuiThemeStub->pixmap(id, size); +} + +QPixmap * DuiTheme::pixmap(const QString &id, int x, int y) +{ + return gDuiThemeStub->pixmap(id, x, y); +} + +QPixmap * DuiTheme::pixmap(const QString &id, qreal x, qreal y) +{ + return gDuiThemeStub->pixmap(id, x, y); +} + +void DuiTheme::setApplicationName(const QString &name) +{ + gDuiThemeStub->setApplicationName(name); +} + +void DuiTheme::releasePixmap(QPixmap *pixmap) +{ + gDuiThemeStub->releasePixmap(pixmap); +} + +const DuiStyle * DuiTheme::style(const QObject *object, const DuiStyleDescription &desc) +{ + return gDuiThemeStub->style(object, desc); +} + +void DuiTheme::releaseStyle(const DuiStyle *style) +{ + gDuiThemeStub->releaseStyle(style); +} + +DuiWidgetView * DuiTheme::view(const QObject *object, DuiWidgetController *controller) +{ + return gDuiThemeStub->view(object, controller); +} + +bool DuiTheme::loadSVG(const QString &filename) +{ + return gDuiThemeStub->loadSVG(filename); +} + +bool DuiTheme::addCSS(const QString &filename) +{ + return gDuiThemeStub->addCSS(filename); +} + +bool DuiTheme::addPixmapDirectory(const QString &directoryName) +{ + return gDuiThemeStub->addPixmapDirectory(directoryName); +} + +bool DuiTheme::addPixmapDirectoryRecursive(const QString &directoryName) +{ + return gDuiThemeStub->addPixmapDirectoryRecursive(directoryName); +} + +void DuiTheme::prepareThemeChange() +{ + gDuiThemeStub->prepareThemeChange(); +} + +void DuiTheme::changeTheme() +{ + gDuiThemeStub->changeTheme(); +} + +bool DuiTheme::loadCSS(const QString &filename) +{ + return gDuiThemeStub->loadCSS(filename); +} + +bool DuiTheme::deletePixmapSearchList(const QString &applicationName, int version) +{ + return gDuiThemeStub->deletePixmapSearchList(applicationName, version); +} + +QPixmap * DuiTheme::pixmapFromHandle(int handle) +{ + return gDuiThemeStub->pixmapFromHandle(handle); +} + + +#endif diff --git a/tests/stubs/duitoolbar_stub.h b/tests/stubs/duitoolbar_stub.h new file mode 100644 index 000000000..7a268f87e --- /dev/null +++ b/tests/stubs/duitoolbar_stub.h @@ -0,0 +1,55 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUITOOLBAR_STUB_H +#define DUITOOLBAR_STUB_H + +#include +#include + +class DuiToolbarStub : public StubBase +{ +public: + virtual void duiToolbarConstructor(DuiWidget *parent = 0); + virtual void duiToolbarDestructor(); +}; + +void DuiToolbarStub::duiToolbarConstructor(DuiWidget *parent) +{ + Q_UNUSED(parent); +} + +void DuiToolbarStub::duiToolbarDestructor() +{ +} + +DuiToolbarStub gDefaultDuiToolbarStub; +DuiToolbarStub *gDuiToolbarStub = &gDefaultDuiToolbarStub; + +DuiToolbar::DuiToolbar(DuiWidget *parent) +{ + gDuiToolbarStub->duiToolbarConstructor(parent); +} + +DuiToolbar::~DuiToolbar() +{ + gDuiToolbarStub->duiToolbarDestructor(); +} + +#endif diff --git a/tests/stubs/duitoolbarview_stub.h b/tests/stubs/duitoolbarview_stub.h new file mode 100644 index 000000000..2f1c631e6 --- /dev/null +++ b/tests/stubs/duitoolbarview_stub.h @@ -0,0 +1,131 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUITOOLBARVIEW_STUB +#define DUITOOLBARVIEW_STUB + +#include "duitoolbarview.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiToolbarViewStub : public StubBase +{ +public: + virtual void DuiToolbarViewConstructor(DuiToolbar *controller); + virtual void DuiToolbarViewDestructor(); + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + virtual QRectF boundingRect() const; + virtual void setGeometry(const QRectF &rect); + virtual void updateStyle(); + virtual QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint); + DuiToolbarViewPrivate *d_ptr ; +}; + +// 2. IMPLEMENT STUB +void DuiToolbarViewStub::DuiToolbarViewConstructor(DuiToolbar *controller) +{ + Q_UNUSED(controller); + +} +void DuiToolbarViewStub::DuiToolbarViewDestructor() +{ + +} +void DuiToolbarViewStub::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + QList params; + params.append(new Parameter(painter)); + params.append(new Parameter(option)); + params.append(new Parameter(widget)); + stubMethodEntered("paint", params); +} + +QRectF DuiToolbarViewStub::boundingRect() const +{ + stubMethodEntered("boundingRect"); + return stubReturnValue("boundingRect"); +} + +void DuiToolbarViewStub::setGeometry(const QRectF &rect) +{ + QList params; + params.append(new Parameter(rect)); + stubMethodEntered("setGeometry", params); +} + +void DuiToolbarViewStub::updateStyle() +{ + stubMethodEntered("updateStyle"); +} + +QSizeF DuiToolbarViewStub::sizeHint(Qt::SizeHint which, const QSizeF &constraint) +{ + QList params; + params.append(new Parameter(which)); + params.append(new Parameter(constraint)); + stubMethodEntered("sizeHint", params); + return stubReturnValue(QString("sizeHint")); +} + + +// 3. CREATE A STUB INSTANCE +DuiToolbarViewStub gDefaultDuiToolbarViewStub; +DuiToolbarViewStub *gDuiToolbarViewStub = &gDefaultDuiToolbarViewStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiToolbarView::DuiToolbarView(DuiToolbar *controller) +{ + gDuiToolbarViewStub->DuiToolbarViewConstructor(controller); +} + +DuiToolbarView::~DuiToolbarView() +{ + gDuiToolbarViewStub->DuiToolbarViewDestructor(); +} + +void DuiToolbarView::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + gDuiToolbarViewStub->paint(painter, option, widget); +} + +QRectF DuiToolbarView::boundingRect() const +{ + return gDuiToolbarViewStub->boundingRect(); +} + +void DuiToolbarView::setGeometry(const QRectF &rect) +{ + gDuiToolbarViewStub->setGeometry(rect); +} + +void DuiToolbarView::updateStyle() +{ + gDuiToolbarViewStub->updateStyle(); +} + +QSizeF DuiToolbarView::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const +{ + return gDuiToolbarViewStub->sizeHint(which, constraint); +} + + +#endif diff --git a/tests/stubs/duiviewfactory_stub.h b/tests/stubs/duiviewfactory_stub.h new file mode 100644 index 000000000..6bcc0efb9 --- /dev/null +++ b/tests/stubs/duiviewfactory_stub.h @@ -0,0 +1,107 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIVIEWFACTORY_STUB +#define DUIVIEWFACTORY_STUB + +#include "duiviewfactory.h" +#include + + +// 1. DECLARE STUB +class DuiViewFactoryStub : public StubBase +{ +public: + virtual void DuiViewFactoryConstructor(); + virtual void DuiViewFactoryDestructor(); + virtual bool registerViewClass(const QString &viewClass, ViewCreatorFunction function); + virtual bool unregisterViewClass(const QString &viewClass); + virtual DuiWidgetView *createView(const QString &viewClass, const DuiWidgetController *controller); +}; + +// 2. IMPLEMENT STUB +void DuiViewFactoryStub::DuiViewFactoryConstructor() +{ + +} +void DuiViewFactoryStub::DuiViewFactoryDestructor() +{ + +} +bool DuiViewFactoryStub::registerViewClass(const QString &viewClass, ViewCreatorFunction function) +{ + QList params; + params.append(new Parameter(viewClass)); + params.append(new Parameter(function)); + stubMethodEntered("registerViewClass", params); + return stubReturnValue("registerViewClass"); +} + +bool DuiViewFactoryStub::unregisterViewClass(const QString &viewClass) +{ + QList params; + params.append(new Parameter(viewClass)); + stubMethodEntered("unregisterViewClass", params); + return stubReturnValue("unregisterViewClass"); +} + +DuiWidgetView *DuiViewFactoryStub::createView(const QString &viewClass, const DuiWidgetController *controller) +{ + QList params; + params.append(new Parameter(viewClass)); + params.append(new Parameter(controller)); + stubMethodEntered("createView", params); + return stubReturnValue("createView"); +} + + + +// 3. CREATE A STUB INSTANCE +DuiViewFactoryStub gDefaultDuiViewFactoryStub; +DuiViewFactoryStub *gDuiViewFactoryStub = &gDefaultDuiViewFactoryStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiViewFactory::DuiViewFactory() +{ + gDuiViewFactoryStub->DuiViewFactoryConstructor(); +} + +DuiViewFactory::~DuiViewFactory() +{ + gDuiViewFactoryStub->DuiViewFactoryDestructor(); +} + +bool DuiViewFactory::registerViewClass(const QString &viewClass, ViewCreatorFunction function) +{ + return gDuiViewFactoryStub->registerViewClass(viewClass, function); +} + +bool DuiViewFactory::unregisterViewClass(const QString &viewClass) +{ + return gDuiViewFactoryStub->unregisterViewClass(viewClass); +} + +DuiWidgetView *DuiViewFactory::createView(const QString &viewClass, const DuiWidgetController *controller) +{ + return gDuiViewFactoryStub->createView(viewClass, controller); +} + + +#endif diff --git a/tests/stubs/duiviewfactoryregister_stub.h b/tests/stubs/duiviewfactoryregister_stub.h new file mode 100644 index 000000000..4ae89cd12 --- /dev/null +++ b/tests/stubs/duiviewfactoryregister_stub.h @@ -0,0 +1,59 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIVIEWFACTORYREGISTER_STUB +#define DUIVIEWFACTORYREGISTER_STUB + +#include "duiviewfactory.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiViewFactoryRegisterStub : public StubBase +{ +public: + const char *name ; + ViewCreatorFunction function ; + DuiViewFactoryRegister *nextView ; + DuiViewFactoryRegister *viewsHead ; + virtual void DuiViewFactoryRegisterConstructor(const char *viewName, ViewCreatorFunction viewCreator); +}; + +// 2. IMPLEMENT STUB +void DuiViewFactoryRegisterStub::DuiViewFactoryRegisterConstructor(const char *viewName, ViewCreatorFunction viewCreator) +{ + Q_UNUSED(viewName); + Q_UNUSED(viewCreator); + +} + + +// 3. CREATE A STUB INSTANCE +DuiViewFactoryRegisterStub gDefaultDuiViewFactoryRegisterStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiViewFactoryRegister::DuiViewFactoryRegister(const char *viewName, ViewCreatorFunction viewCreator) +{ + gDefaultDuiViewFactoryRegisterStub.DuiViewFactoryRegisterConstructor(viewName, viewCreator); +} + + +#endif diff --git a/tests/stubs/duiwidget_stub.h b/tests/stubs/duiwidget_stub.h new file mode 100644 index 000000000..3934d68c6 --- /dev/null +++ b/tests/stubs/duiwidget_stub.h @@ -0,0 +1,162 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIWIDGET_STUB +#define DUIWIDGET_STUB + +#include "duiwidget.h" +#include + + +class DuiWidgetStub : public StubBase +{ +public: + virtual void DuiWidgetConstructor(QGraphicsItem *parent); + virtual void DuiWidgetDestructor(); + virtual QPainterPath shape() const; + virtual void paintWindowFrame(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + virtual void executeOrientationAnimationPhase(DuiWindow::OrientationAnimationPhase phase, qreal offset, DuiOrientationChangeParameters *parameters); + virtual void finalizeOrientationAnimationPhase(DuiWindow::OrientationAnimationPhase phase, DuiOrientationChangeParameters *parameters); + virtual QVariant itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value); + virtual bool event(QEvent *event); +}; + +void DuiWidgetStub::DuiWidgetConstructor(QGraphicsItem *parent) +{ + Q_UNUSED(parent); +} + +void DuiWidgetStub::DuiWidgetDestructor() +{ +} + +QPainterPath DuiWidgetStub::shape() const +{ + stubMethodEntered("shape"); + return stubReturnValue("shape"); +} + +void DuiWidgetStub::paintWindowFrame(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + QList params; + params.append(new Parameter(painter)); + params.append(new Parameter(option)); + params.append(new Parameter(widget)); + stubMethodEntered("paintWindowFrame", params); +} + +void DuiWidgetStub::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + QList params; + params.append(new Parameter(painter)); + params.append(new Parameter(option)); + params.append(new Parameter(widget)); + stubMethodEntered("paint", params); +} + +void DuiWidgetStub::executeOrientationAnimationPhase(DuiWindow::OrientationAnimationPhase phase, qreal offset, DuiOrientationChangeParameters *parameters) +{ + QList params; + params.append(new Parameter(phase)); + params.append(new Parameter(offset)); + params.append(new Parameter(parameters)); + stubMethodEntered("executeOrientationAnimationPhase", params); +} + +void DuiWidgetStub::finalizeOrientationAnimationPhase(DuiWindow::OrientationAnimationPhase phase, DuiOrientationChangeParameters *parameters) +{ + QList params; + params.append(new Parameter(phase)); + params.append(new Parameter(parameters)); + stubMethodEntered("finalizeOrientationAnimationPhase", params); +} + +QVariant DuiWidgetStub::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value) +{ + QList params; + params.append(new Parameter(change)); + params.append(new Parameter(value)); + stubMethodEntered("itemChange", params); + return stubReturnValue("itemChange"); +} + +bool DuiWidgetStub::event(QEvent *event) +{ + QList params; + params.append(new Parameter(event)); + stubMethodEntered("event", params); + return stubReturnValue("event"); +} + + + +// 3. CREATE A STUB INSTANCE +DuiWidgetStub gDefaultDuiWidgetStub; +DuiWidgetStub *gDuiWidgetStub = &gDefaultDuiWidgetStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB FIXME +DuiWidget::DuiWidget(QGraphicsItem *parent) : d_ptr(0) +{ + gDuiWidgetStub->DuiWidgetConstructor(parent); +} + +DuiWidget::~DuiWidget() +{ + gDuiWidgetStub->DuiWidgetDestructor(); +} + +QPainterPath DuiWidget::shape() const +{ + return gDuiWidgetStub->shape(); +} + +void DuiWidget::paintWindowFrame(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + gDuiWidgetStub->paintWindowFrame(painter, option, widget); +} + +void DuiWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + gDuiWidgetStub->paint(painter, option, widget); +} + +void DuiWidget::executeOrientationAnimationPhase(DuiWindow::OrientationAnimationPhase phase, qreal offset, DuiOrientationChangeParameters *parameters) +{ + gDuiWidgetStub->executeOrientationAnimationPhase(phase, offset, parameters); +} + +void DuiWidget::finalizeOrientationAnimationPhase(DuiWindow::OrientationAnimationPhase phase, DuiOrientationChangeParameters *parameters) +{ + gDuiWidgetStub->finalizeOrientationAnimationPhase(phase, parameters); +} + +QVariant DuiWidget::itemChange(GraphicsItemChange change, const QVariant &value) +{ + return gDuiWidgetStub->itemChange(change, value); +} + +bool DuiWidget::event(QEvent *event) +{ + return gDuiWidgetStub->event(event); +} + + +#endif diff --git a/tests/stubs/duiwidgetcontroller_stub.h b/tests/stubs/duiwidgetcontroller_stub.h new file mode 100644 index 000000000..f3ab46790 --- /dev/null +++ b/tests/stubs/duiwidgetcontroller_stub.h @@ -0,0 +1,226 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIWIDGETCONTROLLER_STUB_H +#define DUIWIDGETCONTROLLER_STUB_H + +#include +#include + +class DuiWidgetView; +class QGraphicsItem; + +/** + * DuiWidgetController mocker base class. + * To mock DuiWidgetController operations, derive from this class + * and implement the methods you want to mock. Instantiate your + * derived mock class and assign it to gDuiWidgetControllerStub + * global variable. + */ +class DuiWidgetControllerStub : public StubBase +{ +public: + virtual void duiWidgetControllerConstructor(QGraphicsItem *parent, const QString &viewType); + virtual void duiWidgetControllerDestructor(); + + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + virtual void setObjectName(const QString &name); + virtual void setGeometry(const QRectF &rect); + virtual QRectF boundingRect() const; + virtual QPainterPath shape() const; + virtual void setView(DuiWidgetView *view); + + + virtual QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint); + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event); + virtual void resizeEvent(QGraphicsSceneResizeEvent *event); +}; + +void DuiWidgetControllerStub::duiWidgetControllerConstructor(QGraphicsItem *parent, const QString &viewType) +{ + Q_UNUSED(parent); + Q_UNUSED(viewType); +} + +void DuiWidgetControllerStub::duiWidgetControllerDestructor() +{ +} + +void DuiWidgetControllerStub::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + QList params; + params.append(new Parameter(painter)); + params.append(new Parameter(option)); + params.append(new Parameter(widget)); + stubMethodEntered("paint", params); +} + +void DuiWidgetControllerStub::setObjectName(const QString &name) +{ + QList params; + params.append(new Parameter(name)); + stubMethodEntered("setObjectName", params); +} + +void DuiWidgetControllerStub::setGeometry(const QRectF &rect) +{ + QList params; + params.append(new Parameter(rect)); + stubMethodEntered("setGeometry", params); +} + +QRectF DuiWidgetControllerStub::boundingRect() const +{ + QList params; + stubMethodEntered("boundingRect", params); + return stubReturnValue(QString("boundingRect")); +} + +QPainterPath DuiWidgetControllerStub::shape() const +{ + stubMethodEntered("shape"); + return stubReturnValue("shape"); +} + +QSizeF DuiWidgetControllerStub::sizeHint(Qt::SizeHint which, const QSizeF &constraint) +{ + QList params; + params.append(new Parameter(which)); + params.append(new Parameter(constraint)); + stubMethodEntered("sizeHint", params); + return stubReturnValue(QString("sizeHint")); +} + +void DuiWidgetControllerStub::setView(DuiWidgetView *view) +{ + QList params; + params.append(new Parameter(view)); + stubMethodEntered("setView", params); +} + +void DuiWidgetControllerStub::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + QList params; + params.append(new Parameter(event)); + stubMethodEntered("mousePressEvent", params); +} + +void DuiWidgetControllerStub::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + QList params; + params.append(new Parameter(event)); + stubMethodEntered("mouseReleaseEvent", params); +} + +void DuiWidgetControllerStub::mouseMoveEvent(QGraphicsSceneMouseEvent *event) +{ + QList params; + params.append(new Parameter(event)); + stubMethodEntered("mouseMoveEvent", params); +} + +void DuiWidgetControllerStub::resizeEvent(QGraphicsSceneResizeEvent *event) +{ + QList params; + params.append(new Parameter(event)); + stubMethodEntered("resizeEvent", params); +} + +DuiWidgetControllerStub gDefaultDuiWidgetControllerStub; + +/** + * This is the mock class instance used in the mocking. If you want to alter mocking behaviour + * derive your mocker from DuiWidgetControllerStub, implement the methods you want to + * affect, create an instance of your mocker class and assign the instance into this global variable. + */ +DuiWidgetControllerStub *gDuiWidgetControllerStub = &gDefaultDuiWidgetControllerStub; + +/** + * These are the stub method implementations of DuiWidgetController. They will + * call the mocking methods of the gDuiWidgetControllerStub. + */ +DuiWidgetController::DuiWidgetController(QGraphicsItem *parent, const QString &viewType) + : DuiWidget(parent) +{ + gDuiWidgetControllerStub->duiWidgetControllerConstructor(parent, viewType); +} + +DuiWidgetController::~DuiWidgetController() +{ + gDuiWidgetControllerStub->duiWidgetControllerDestructor(); +} + +void DuiWidgetController::setGeometry(const QRectF &rect) +{ + gDuiWidgetControllerStub->setGeometry(rect); +} + +void DuiWidgetController::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + gDuiWidgetControllerStub->paint(painter, option, widget); +} + +void DuiWidgetController::setObjectName(const QString &name) +{ + gDuiWidgetControllerStub->setObjectName(name); +} + +QRectF DuiWidgetController::boundingRect() const +{ + return gDuiWidgetControllerStub->boundingRect(); +} + +QPainterPath DuiWidgetController::shape() const +{ + return gDuiWidgetControllerStub->shape(); +} + +QSizeF DuiWidgetController::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const +{ + return gDuiWidgetControllerStub->sizeHint(which, constraint); +} + +void DuiWidgetController::setView(DuiWidgetView *view) +{ + gDuiWidgetControllerStub->setView(view); +} + +void DuiWidgetController::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + gDuiWidgetControllerStub->mousePressEvent(event); +} + +void DuiWidgetController::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + gDuiWidgetControllerStub->mouseReleaseEvent(event); +} + +void DuiWidgetController::mouseMoveEvent(QGraphicsSceneMouseEvent *event) +{ + gDuiWidgetControllerStub->mouseMoveEvent(event); +} + +void DuiWidgetController::resizeEvent(QGraphicsSceneResizeEvent *event) +{ + gDuiWidgetControllerStub->resizeEvent(event); +} + +#endif diff --git a/tests/stubs/duiwidgetview_stub.h b/tests/stubs/duiwidgetview_stub.h new file mode 100644 index 000000000..d6b9aa99c --- /dev/null +++ b/tests/stubs/duiwidgetview_stub.h @@ -0,0 +1,145 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIWIDGETVIEW_STUB +#define DUIWIDGETVIEW_STUB + +#include "duiwidgetview.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiWidgetViewStub : public StubBase +{ +public: + virtual void duiWidgetViewConstructor(); + virtual void duiWidgetViewDestructor(); + virtual QPainterPath shape() const; + virtual void resizeEvent(QGraphicsSceneResizeEvent *event); + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event); + virtual QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint) const; +}; + +// 2. IMPLEMENT STUB +void DuiWidgetViewStub::duiWidgetViewConstructor() +{ +} + +void DuiWidgetViewStub::duiWidgetViewDestructor() +{ +} + +QPainterPath DuiWidgetViewStub::shape() const +{ + stubMethodEntered("shape"); + return stubReturnValue("shape"); +} + +void DuiWidgetViewStub::resizeEvent(QGraphicsSceneResizeEvent *event) +{ + QList params; + params.append(new Parameter(event)); + stubMethodEntered("resizeEvent", params); +} + +void DuiWidgetViewStub::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + QList params; + params.append(new Parameter(event)); + stubMethodEntered("mousePressEvent", params); +} + +void DuiWidgetViewStub::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + QList params; + params.append(new Parameter(event)); + stubMethodEntered("mouseReleaseEvent", params); +} + +void DuiWidgetViewStub::mouseMoveEvent(QGraphicsSceneMouseEvent *event) +{ + QList params; + params.append(new Parameter(event)); + stubMethodEntered("mouseMoveEvent", params); +} + +QSizeF DuiWidgetViewStub::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const +{ + QList params; + params.append(new Parameter(which)); + params.append(new Parameter(constraint)); + stubMethodEntered("sizeHint", params); + return stubReturnValue("sizeHint"); +} + +// 3. CREATE A STUB INSTANCE +DuiWidgetViewStub gDefaultDuiWidgetViewStub; +DuiWidgetViewStub *gDuiWidgetViewStub = &gDefaultDuiWidgetViewStub; + +/* +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiWidgetView::DuiWidgetView(DuiWidgetController* controller) : +DuiStylableBase(this, controller), d_ptr(0) +{ + Q_UNUSED(controller); + gDuiWidgetViewStub->duiWidgetViewConstructor(); +} +*/ + +DuiWidgetView::~DuiWidgetView() +{ + gDuiWidgetViewStub->duiWidgetViewDestructor(); +} + +QPainterPath DuiWidgetView::shape() const +{ + return gDuiWidgetViewStub->shape(); +} + +void DuiWidgetView::resizeEvent(QGraphicsSceneResizeEvent *event) +{ + gDuiWidgetViewStub->resizeEvent(event); +} + +void DuiWidgetView::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + gDuiWidgetViewStub->mousePressEvent(event); +} + +void DuiWidgetView::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + gDuiWidgetViewStub->mouseReleaseEvent(event); +} + +void DuiWidgetView::mouseMoveEvent(QGraphicsSceneMouseEvent *event) +{ + gDuiWidgetViewStub->mouseMoveEvent(event); +} + +QSizeF DuiWidgetView::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const +{ + return gDuiWidgetViewStub->sizeHint(which, constraint); +} + + +#endif + diff --git a/tests/stubs/duiwindow_stub.h b/tests/stubs/duiwindow_stub.h new file mode 100644 index 000000000..27080eaf9 --- /dev/null +++ b/tests/stubs/duiwindow_stub.h @@ -0,0 +1,239 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIWINDOW_STUB +#define DUIWINDOW_STUB + +#include "duiwindow.h" +#include + + +// 1. DECLARE STUB +// FIXME - stubgen is not yet finished +class DuiWindowStub : public StubBase +{ +public: + virtual void DuiWindowConstructor(QWidget *parent); + virtual void DuiWindowDestructor(); + virtual void setOrientationAnimationLength(DuiWindow::OrientationAnimationPhase phase, qreal lenghtInSecs); + virtual bool orientationChanging(); + virtual qreal orientationChangePhase(); + virtual void registerForPermanentOrientationChangeAnimation(DuiWidget *widget); + virtual void storeOrientationChangeParameters(DuiWidget *widget, DuiOrientationChangeParameters *parameters); + virtual DuiOrientationChangeParameters *orientationChangeParameters(DuiWidget *widget); + virtual void orientationAngleChanged(DuiDeviceProfile::DeviceOrientationAngle angle); + virtual void orientationAnimationChanged(qreal value); + virtual void orientationAnimationCompleted(); + virtual void prepareOrientationAnimationPhase(DuiWindow::OrientationAnimationPhase phase, int startAngle, int endAngle); + virtual void executeOrientationAnimationPhase(DuiWindow::OrientationAnimationPhase phase, qreal offset, int startAngle, int endAngle); + virtual void finalizeOrientationAnimationPhase(DuiWindow::OrientationAnimationPhase phase); + virtual bool event(QEvent *event); +}; + +// 2. IMPLEMENT STUB +void DuiWindowStub::DuiWindowConstructor(QWidget *parent) +{ + Q_UNUSED(parent); + +} +void DuiWindowStub::DuiWindowDestructor() +{ + +} +void DuiWindowStub::setOrientationAnimationLength(DuiWindow::OrientationAnimationPhase phase, qreal lenghtInSecs) +{ + QList params; + params.append(new Parameter(phase)); + params.append(new Parameter(lenghtInSecs)); + stubMethodEntered("setOrientationAnimationLength", params); +} + +bool DuiWindowStub::orientationChanging() +{ + stubMethodEntered("orientationChanging"); + return stubReturnValue("orientationChanging"); +} + +qreal DuiWindowStub::orientationChangePhase() +{ + stubMethodEntered("orientationChangePhase"); + return stubReturnValue("orientationChangePhase"); +} + +void DuiWindowStub::registerForPermanentOrientationChangeAnimation(DuiWidget *widget) +{ + QList params; + params.append(new Parameter(widget)); + stubMethodEntered("registerForPermanentOrientationChangeAnimation", params); +} + +void DuiWindowStub::storeOrientationChangeParameters(DuiWidget *widget, DuiOrientationChangeParameters *parameters) +{ + QList params; + params.append(new Parameter(widget)); + params.append(new Parameter(parameters)); + stubMethodEntered("storeOrientationChangeParameters", params); +} + +DuiOrientationChangeParameters *DuiWindowStub::orientationChangeParameters(DuiWidget *widget) +{ + QList params; + params.append(new Parameter(widget)); + stubMethodEntered("orientationChangeParameters", params); + return stubReturnValue("orientationChangeParameters"); +} + +void DuiWindowStub::orientationAngleChanged(DuiDeviceProfile::DeviceOrientationAngle angle) +{ + QList params; + params.append(new Parameter(angle)); + stubMethodEntered("orientationAngleChanged", params); +} + +void DuiWindowStub::orientationAnimationChanged(qreal value) +{ + QList params; + params.append(new Parameter(value)); + stubMethodEntered("orientationAnimationChanged", params); +} + +void DuiWindowStub::orientationAnimationCompleted() +{ + stubMethodEntered("orientationAnimationCompleted"); +} + +void DuiWindowStub::prepareOrientationAnimationPhase(DuiWindow::OrientationAnimationPhase phase, int startAngle, int endAngle) +{ + QList params; + params.append(new Parameter(phase)); + params.append(new Parameter(startAngle)); + params.append(new Parameter(endAngle)); + stubMethodEntered("prepareOrientationAnimationPhase", params); +} + +void DuiWindowStub::executeOrientationAnimationPhase(DuiWindow::OrientationAnimationPhase phase, qreal offset, int startAngle, int endAngle) +{ + QList params; + params.append(new Parameter(phase)); + params.append(new Parameter(offset)); + params.append(new Parameter(startAngle)); + params.append(new Parameter(endAngle)); + stubMethodEntered("executeOrientationAnimationPhase", params); +} + +void DuiWindowStub::finalizeOrientationAnimationPhase(DuiWindow::OrientationAnimationPhase phase) +{ + QList params; + params.append(new Parameter(phase)); + stubMethodEntered("finalizeOrientationAnimationPhase", params); +} + +bool DuiWindowStub::event(QEvent *event) +{ + QList params; + params.append(new Parameter(event)); + stubMethodEntered("event", params); + return stubReturnValue("event"); +} + + + +// 3. CREATE A STUB INSTANCE +DuiWindowStub gDefaultDuiWindowStub; +DuiWindowStub *gDuiWindowStub = &gDefaultDuiWindowStub; + + +// 4. CREATE A PROXY WHICH CALLS THE STUB +DuiWindow::DuiWindow(QWidget *parent) : d_ptr(0) +{ + gDuiWindowStub->DuiWindowConstructor(parent); +} + +DuiWindow::~DuiWindow() +{ + gDuiWindowStub->DuiWindowDestructor(); +} + +void DuiWindow::setOrientationAnimationLength(DuiWindow::OrientationAnimationPhase phase, qreal lenghtInSecs) +{ + gDuiWindowStub->setOrientationAnimationLength(phase, lenghtInSecs); +} + +bool DuiWindow::orientationChanging() +{ + return gDuiWindowStub->orientationChanging(); +} + +qreal DuiWindow::orientationChangePhase() +{ + return gDuiWindowStub->orientationChangePhase(); +} + +void DuiWindow::registerForPermanentOrientationChangeAnimation(DuiWidget *widget) +{ + gDuiWindowStub->registerForPermanentOrientationChangeAnimation(widget); +} + +void DuiWindow::storeOrientationChangeParameters(DuiWidget *widget, DuiOrientationChangeParameters *parameters) +{ + gDuiWindowStub->storeOrientationChangeParameters(widget, parameters); +} + +DuiOrientationChangeParameters *DuiWindow::orientationChangeParameters(DuiWidget *widget) +{ + return gDuiWindowStub->orientationChangeParameters(widget); +} + +void DuiWindow::orientationAngleChanged(DuiDeviceProfile::DeviceOrientationAngle angle) +{ + gDuiWindowStub->orientationAngleChanged(angle); +} + +void DuiWindow::orientationAnimationChanged(qreal value) +{ + gDuiWindowStub->orientationAnimationChanged(value); +} + +void DuiWindow::orientationAnimationCompleted() +{ + gDuiWindowStub->orientationAnimationCompleted(); +} + +void DuiWindow::prepareOrientationAnimationPhase(DuiWindow::OrientationAnimationPhase phase, int startAngle, int endAngle) +{ + gDuiWindowStub->prepareOrientationAnimationPhase(phase, startAngle, endAngle); +} + +void DuiWindow::executeOrientationAnimationPhase(DuiWindow::OrientationAnimationPhase phase, qreal offset, int startAngle, int endAngle) +{ + gDuiWindowStub->executeOrientationAnimationPhase(phase, offset, startAngle, endAngle); +} + +void DuiWindow::finalizeOrientationAnimationPhase(DuiWindow::OrientationAnimationPhase phase) +{ + gDuiWindowStub->finalizeOrientationAnimationPhase(phase); +} + +bool DuiWindow::event(QEvent *event) +{ + return gDuiWindowStub->event(event); +} + + +#endif diff --git a/tests/stubs/methodcall.h b/tests/stubs/methodcall.h new file mode 100644 index 000000000..d2ef6e89c --- /dev/null +++ b/tests/stubs/methodcall.h @@ -0,0 +1,80 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef STUBMETHOD_H +#define STUBMETHOD_H + +class MethodCall +{ +public: + MethodCall(const QString &name, QList params, ParameterBase *returnValue) + : _name(name), + _params(params), + _returnValue(returnValue) { + } + + virtual ~MethodCall() { + foreach(ParameterBase * p, _params) { + delete p; + } + } + + QString name() { + return _name; + } + + QList params() { + return _params; + } + + template + T parameter(int number) { + if (number >= _params.count()) { + qDebug() << "MethodCall::" << __func__ << ": method " << _name << " does not have parameter #" << number + << ". Check your test code."; + } + Parameter* param = dynamic_cast* >(_params[number]); + if (!param) { + qDebug() << "MethodCall::" << __func__ << ": failed dynamic_cast, check that parameter type matches parameter number"; + } + return param->data; + } + + template + T returnValue() { + Parameter* value = dynamic_cast*>(_returnValue); + + if (!value) { + qDebug() << "MethodCall::" << __func__ << ": failed dynamic_cast, check that type matches return value"; + } + return value->data; + } + + bool returnValueExists() { + return (_returnValue != NULL); + } + +private: + QString _name; + QList _params; + ParameterBase *_returnValue; + +}; + +#endif diff --git a/tests/stubs/mockdatastore.h b/tests/stubs/mockdatastore.h new file mode 100644 index 000000000..87902d8f7 --- /dev/null +++ b/tests/stubs/mockdatastore.h @@ -0,0 +1,88 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef MOCKDATASTORE_H +#define MOCKDATASTORE_H + +#include + +class MockDataStore : public DuiDataStore +{ +public: + virtual bool createValue(const QString &key, const QVariant &value); + virtual bool setValue(const QString &key, const QVariant &value); + virtual QVariant value(const QString &key) const; + virtual QStringList allKeys() const; + virtual void remove(const QString &key); + virtual void clear(); + virtual bool contains(const QString &key) const; + +private: + QMap values; + +}; + +bool MockDataStore::createValue(const QString &key, const QVariant &value) +{ + values[key] = value; + emit valueChanged(key, value); + return true; +} + +bool MockDataStore::setValue(const QString &key, const QVariant &value) +{ + if (allKeys().contains(key)) { + values[key] = value; + emit valueChanged(key, value); + return true; + } else { + return false; + } +} + +QVariant MockDataStore::value(const QString &key) const +{ + if (values.contains(key)) { + return values[key]; + } else { + return QVariant(); + } +} + +QStringList MockDataStore::allKeys() const +{ + return values.keys(); +} + +void MockDataStore::remove(const QString &key) +{ + values.remove(key); +} + +void MockDataStore::clear() +{ + values.clear(); +} + +bool MockDataStore::contains(const QString &key) const +{ + return values.contains(key); +} + +#endif diff --git a/tests/stubs/parameter.h b/tests/stubs/parameter.h new file mode 100644 index 000000000..c188816ef --- /dev/null +++ b/tests/stubs/parameter.h @@ -0,0 +1,43 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef PARAMETER_H +#define PARAMETER_H + +class ParameterBase +{ +public: + virtual ~ParameterBase() { + // Class needs to have at least one virtual function to be polymorphic + // (and thus enable dynamic_cast) + } +protected: + ParameterBase() { + } +}; + +template +class Parameter : public ParameterBase +{ +public: + Parameter(T value) : ParameterBase(), data(value) { + } + T data; +}; +#endif diff --git a/tests/stubs/stubbase.cpp b/tests/stubs/stubbase.cpp new file mode 100644 index 000000000..703a2fdfd --- /dev/null +++ b/tests/stubs/stubbase.cpp @@ -0,0 +1,105 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include "stubbase.h" +#include "methodcall.h" + +QList StubBase::stubCallHistory() const +{ + return _stubCallHistory; +} + +void StubBase::stubReset() const +{ + foreach(ParameterBase * p, _stubReturnValues) { + delete p; + } + + foreach(MethodCall * p, _stubCallHistory) { + delete p; + } + + _stubReturnValues.clear(); + _stubCallCounts.clear(); + _stubCallHistory.clear(); +} + +int StubBase::stubCallCount(const QString &method) const +{ + return _stubCallCounts[method]; +} + +void StubBase::stubMethodEntered(const QString &methodName, QList params) const +{ + MethodCall *method = new MethodCall(methodName, params, stubReturnValue(methodName)); + _stubCallCounts[methodName] = _stubCallCounts[methodName] + 1; + _stubCallHistory.append(method); +} + +void StubBase::stubMethodEntered(const QString &methodName) const +{ + MethodCall *method = new MethodCall(methodName, QList(), stubReturnValue(methodName)); + _stubCallCounts[methodName] = _stubCallCounts[methodName] + 1; + _stubCallHistory.append(method); +} + +ParameterBase *StubBase::stubReturnValue(const QString &methodName) const +{ + ParameterBase *retVal = NULL; + + if (_stubReturnValues.contains(methodName)) + retVal = _stubReturnValues[methodName]; + + return retVal; +} + +StubBase::~StubBase() +{ + stubReset(); +} + +MethodCall &StubBase::stubLastCall() const +{ + return *(_stubCallHistory.last()); +} + +MethodCall &StubBase::stubLastCallTo(const QString &method) const +{ + for (int i = _stubCallHistory.count() - 1; i >= 0; i--) { + if (_stubCallHistory.at(i)->name() == method) { + return *(_stubCallHistory.at(i)); + } + } + qDebug() << "StubBase::lastCallTo: call not found to:" << method; + return *((MethodCall *)0); +} + +QList StubBase::stubCallsTo(const QString &method) const +{ + QList calls; + for (int i = 0; i < _stubCallHistory.count(); i++) { + if (_stubCallHistory.at(i)->name() == method) { + calls.append(_stubCallHistory.at(i)); + } + } + return calls; +} + + diff --git a/tests/stubs/stubbase.h b/tests/stubs/stubbase.h new file mode 100644 index 000000000..5e697255f --- /dev/null +++ b/tests/stubs/stubbase.h @@ -0,0 +1,107 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef STUBBASE_H +#define STUBBASE_H + +#include +#include +#include +#include +#include "parameter.h" +#include "methodcall.h" + + +class StubBase +{ +public: + // Return a list of method calls + QList stubCallHistory() const; + + // Return a reference to the last method call + MethodCall &stubLastCall() const; + + // Access parameters of the last method call + template + T stubLastParameters(int number) const; + + // Access parameters of the last method call + MethodCall &stubLastCallTo(const QString &method) const; + + // Return a list of calls to a particular method call + QList stubCallsTo(const QString &method) const; + + // Return the number of times a method has been called + int stubCallCount(const QString &method) const; + + // Set the return value for next call of methodName + template + void stubSetReturnValue(const QString &methodName, T value) const; + + // Return the return value set for methodName + template + T &stubReturnValue(const QString &methodName) const; + + + + // For use by stubs + virtual ~StubBase(); + void stubReset() const; + ParameterBase *stubReturnValue(const QString &methodName) const; + void stubMethodEntered(const QString &methodName, QList params) const; + void stubMethodEntered(const QString &methodName) const; + +private: + mutable QMap _stubReturnValues; + mutable QMap _stubCallCounts; + mutable QList _stubCallHistory; + +}; + +template +void StubBase::stubSetReturnValue(const QString &methodName, T value) const +{ + Parameter* param = new Parameter(value); + _stubReturnValues[methodName] = param; +} + +template +T &StubBase::stubReturnValue(const QString &methodName) const +{ + if (! _stubReturnValues.contains(methodName)) { + stubSetReturnValue(methodName, T()); + } + + ParameterBase *base = _stubReturnValues[methodName]; + Parameter* param = dynamic_cast*>(base); + if (!param) { + qDebug() << "StubBase::" << __func__ << ": failed dynamic_cast, check that return value type matches the method; check also that you have used stubSetReturnValue(" << methodName << ")"; + } + return param->data; + +} + +template +T StubBase::stubLastParameters(int number) const +{ + MethodCall &call = stubLastCall(); + return call.parameter(number); +} + +#endif diff --git a/tests/template/ut_template.cpp b/tests/template/ut_template.cpp new file mode 100644 index 000000000..983f1c296 --- /dev/null +++ b/tests/template/ut_template.cpp @@ -0,0 +1,48 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include + +mkutclassinclude +mkutclassinclude_p + +#include "ut_mkutclassname.h" + +void Ut_MkUtClassName::init() +{ + m_subject = new MkUtClassName(); +} + +void Ut_MkUtClassName::cleanup() +{ + delete m_subject; + m_subject = 0; +} + +void Ut_MkUtClassName::initTestCase() +{ + QSKIP("incomplete", SkipSingle); // remove this when you've finished +} + +void Ut_MkUtClassName::cleanupTestCase() +{ +} + +QTEST_MAIN(Ut_MkUtClassName) diff --git a/tests/template/ut_template.h b/tests/template/ut_template.h new file mode 100644 index 000000000..610b6f7a2 --- /dev/null +++ b/tests/template/ut_template.h @@ -0,0 +1,47 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_MKUTCLASSNAME_H +#define UT_MKUTCLASSNAME_H + +#include +#include + +// the real unit/MkUtClassName class declaration +#include + +Q_DECLARE_METATYPE(MkUtClassName *); + +class Ut_MkUtClassName : public QObject +{ + Q_OBJECT + +private slots: + void init(); + void cleanup(); + void initTestCase(); + void cleanupTestCase(); + + MKUTCLASSMEMBERS + +private: + MkUtClassName *m_subject; +}; + +#endif diff --git a/tests/template/ut_template.pro b/tests/template/ut_template.pro new file mode 100644 index 000000000..99cecdd23 --- /dev/null +++ b/tests/template/ut_template.pro @@ -0,0 +1,33 @@ +include(../common_top.pri) +TARGET = ut_mkutclassname + +TEST_SOURCES = \ + $$DUISRCDIR/mkutclassname.cpp \ + +# unit test and unit +SOURCES += \ + ut_mkutclassname.cpp \ + $$TEST_SOURCES \ + +# base classes +SOURCES += \ + mkutbasesources + +# service classes +SOURCES += \ + $$STUBSDIR/stubbase.cpp \ + +# unit test and unit +HEADERS += \ + ut_mkutclassname.h \ + $$DUISRCDIR/mkutclassname.h \ + +# base classes +HEADERS += \ + mkutbaseheaders + +# service classes +HEADERS += \ + mkutserviceheaders + +include(../common_bot.pri) diff --git a/tests/testSummary b/tests/testSummary new file mode 100755 index 000000000..3766d939a --- /dev/null +++ b/tests/testSummary @@ -0,0 +1,310 @@ +#! /usr/bin/perl +require 5.008_004; # we need at least Perl version v5.8.4 +$ENV{MALLOC_CHECK_} = 2; + +use Term::ANSIColor; + +my $startTime = time(); + +my %opts = ( + "a" => 0, # all directories, irrespective of if they're in tests.pro + "r" => 0, # don't reverse sort + "s" => "D", # by default, sort by directory name + "j" => 1, # one make job at a time by default +); + +for ( my $argNo=0; $argNo<@ARGV; $argNo++ ) { + my $arg = $ARGV[ $argNo ]; + if ( $arg eq "-h" ) { + print "usage: $0 [-a] [-s letter] [-r] [-j number] [-h]\n"; + print " -a include all ut_*/ directories - default is just the ones in tests.pro\n"; + print " -s [DTPFS] sort by column (Dirs, Tests, P(ass), F(ail), S(kipped)\n"; + print " -r reverse sort\n"; + print " -j use make jobs. Default is 1\n"; + print " -h this help\n"; + exit; + } elsif ( $arg eq "-r" ) { + $opts{ "r" } = 1; + } elsif ( $arg eq "-a" ) { + $opts{ "a" } = 1; + } elsif ( $arg eq "-s" ) { + $opts{ "s" } = $ARGV[ ++$argNo ]; + if ( $opts{ "s" } !~ /[DTPFS]/ ) { + print "Unrecognised column identifier\n"; + print "Must be one of [DTPFS] :\n"; + print " D = Dirs\n"; + print " T = Tests\n"; + print " P = Pass\n"; + print " F = Fail\n"; + print " S = Skipped\n"; + exit(-1); + } + } elsif ( $arg eq "-j" ) { + my $jobs = $ARGV[ ++$argNo ]; + # Test that the argument is a positive integer number + if ( $jobs * 1 eq $jobs && $jobs > 0 ) { + $opts{ "j" } = $jobs; + } + } +} + +# some globals to help sort be faster +$sortCol = $opts{ "s" }; +$sortIsNumeric = ( $sortCol =~ /[PFS]/ ); +$reverseSort = $opts{ "r" }; +# helper variable for the number of jobs +$numJobs = $opts{ "j" }; + +%maxLen = (); +%segFault = (); + +my @rowHeaders = ( + "D", # Dirs + "T", # Tests +); +my @rowData = ( + "P", # Passed + "F", # Failed + "S", # Skipped +); + +my @keys = ( @rowHeaders, @rowData ); + +my %title = ( + "D"=>"Dirs", + "T"=>"Tests", + "P"=>"P", + "F"=>"F", + "S"=>"S", +); + +my $headerLabelFormat = "%-*s"; +my $headerDataFormat = "%*s"; + +my $labelFormat = "%s%-*s%s%*s"; +my $dataFormat = "%*s%s%*s%s"; + +my %format = ( + "D" => $labelFormat, + "T" => $labelFormat, + "P" => $dataFormat, + "F" => $dataFormat, + "S" => $dataFormat, +); + +my %separator = ( + "D" => " ", + "T" => " : ", + "P" => " ", + "F" => " ", + "S" => " ", +); + +my %data = ( +); + +foreach $key ( @keys ) { + $maxLen{ $key } = length( $title{ key } ); +} + +# set the maximum length of the directories +if ( $opts{ "a" } ) { + push @allDirs, ; + push @allDirs, ; + foreach ( @allDirs ) { + setMaxLen( "D", length( $_ ) ); + $tested{ $_ } = 0; + } +} + +# Compile first with possibly multiple jobs +print "Compiling..."; +`make -j$numJobs -k > /dev/null 2>&1`; +print "done.\nNow checking...\n"; + +# then check with only one job so that the parsing succeeds +open( MAKE, "make -k check 2>&1|" ) || die( "Could not run make:$!" ); + +#$|=1; + +my $thisDir = ""; +while () { + chomp; + + if ( /Entering directory \`.*tests\/(\w+)\'/ ) { + $thisDir = $1; + print STDERR "Tests: $thisDir", ' 'x( $maxLen{ "D" }-length( $thisDir )+length("Tests: ") ), "\r"; + $tested{ $thisDir } = 1; + push @allDirs, $thisDir if ( !grep( /^$thisDir$/, @allDirs ) ); + setMaxLen( "D", length( $thisDir ) ); + } elsif ( /Segmentation fault/ ) { + $segFault{ $thisDir } = $_; + } elsif ( /Start testing of (\w+)/ ) { + $thisTest = $1; + $data{ "T" }{ $thisDir } = $thisTest; + setMaxLen( "T", length( $data{ "T" }{ $thisDir } ) ); + } elsif ( /^Totals: (\d+) passed, (\d+) failed, (\d+) skipped/ ) { + $data{ "P" }{ $thisDir } = "$1"; + $data{ "F" }{ $thisDir } = "$2"; + $data{ "S" }{ $thisDir } = "$3"; + setMaxLen( "P", length( $data{ "P" }{ $thisDir } ) ); + setMaxLen( "F", length( $data{ "F" }{ $thisDir } ) ); + setMaxLen( "S", length( $data{ "S" }{ $thisDir } ) ); + } +} + +close( MAKE ); + +print STDERR ' 'x( $maxLen{ "D" } + length( "Tests: " ) ), "\r"; + +foreach $thisDir ( @allDirs ) { + if ( !defined( $data{ "P" }{ $thisDir } ) || $data{ "P" }{ $thisDir } eq "" ) { + $data{ "P" }{ $thisDir } = "0"; + setMaxLen( "P", length( $data{ "P" }{ $thisDir } ) ); + } + if ( !defined( $data{ "F" }{ $thisDir } ) ) { + $data{ "F" }{ $thisDir } = "0"; + setMaxLen( "F", length( $data{ "F" }{ $thisDir } ) ); + } + if ( !defined( $data{ "S" }{ $thisDir } ) ) { + $data{ "S" }{ $thisDir } = "0"; + setMaxLen( "S", length( $data{ "S" }{ $thisDir } ) ); + } + + $data{ "D" }{ $thisDir } = $thisDir; +} + +my ( $testsPassed, $testsNeedWork ) = ( 0, 0 ); +my $noTests = scalar( @allDirs ); +my $noDigits = ($noTests>0)?int( log( $noTests )/log( 10 ) )+1:1; + +my $header = sprintf( "%*s ", $noDigits, "" ); + +foreach ( @rowHeaders ) { + $header .= sprintf( $headerLabelFormat.$separator{ $_ }, $maxLen{ $_ }, $title{ $_ } ); +} + +foreach ( @rowData ) { + $header .= sprintf( $headerDataFormat.$separator{ $_ }, $maxLen{ $_ }, $title{ $_ } ); +} + +my $headerLen = length( $header ); + +my $headerColor = color( 'reset' ); + +print "P = Pass, F = Fail, S = Skip\n"; +print $headerColor, "$header\n"; +print '-'x$headerLen, "\n"; + +my $testNo = 1; + +foreach $thisDir ( sort byCol @allDirs ) { + my %colors = (); + + foreach $key ( @keys ) { + $colors{ $key } = color( 'reset' ); + } + + if ( + ( defined( $data{ "P" }{ $thisDir } ) && $data{ "P" }{ $thisDir } ne "0" ) && + ( defined( $data{ "F" }{ $thisDir } ) && $data{ "F" }{ $thisDir } eq "0" ) && + ( defined( $data{ "S" }{ $thisDir } ) && $data{ "S" }{ $thisDir } eq "0" ) && + ( defined( $data{ "T" }{ $thisDir } ) && $data{ "T" }{ $thisDir } ne "" ) + ) { + $testsPassed++; + } else { + $testsNeedWork++; + } + + if ( defined( $data{ "P" }{ $thisDir } ) && $data{ "P" }{ $thisDir } eq "0" ) { + $colors{ "D" } .= color( 'reverse green' ); + $colors{ "T" } .= color( 'reverse green' ); + $colors{ "P" } .= color( 'reverse green' ); + } else { + $colors{ "D" } .= color( 'green' ); + $colors{ "T" } .= color( 'green' ); + $colors{ "P" } .= color( 'green' ); + } + + if ( defined( $data{ "F" }{ $thisDir} ) && $data{ "F" }{ $thisDir } eq "0" ) { + $colors{ "F" } .= color( 'red' ); + } else { + $colors{ "F" } .= color( 'reverse red' ); + } + + if ( defined( $data{ "S" }{ $thisDir } ) && $data{ "S" }{ $thisDir } eq "0" ) { + $colors{ "S" } .= color( 'blue' ); + } else { + $colors{ "S" } .= color( 'reverse blue' ); + } + + if ( !defined( $data{ "T" }{ $thisDir } ) || $data{ "T" }{ $thisDir } eq "" || $segFault{ $thisDir } ) { + $colors{ "T" } .= color( 'reverse red' ); + } + + printf( "%*s ", $noDigits, $testNo ); + + foreach ( @rowHeaders ) { + my $thisData = $data{ $_ }{ $thisDir }; + my $dataLength = length( $thisData ); + my $spaceLength = $maxLen{ $_ }-$dataLength; + + printf( + $format{ $_ }.$separator{ $_ }, + $colors{ $_ }, $dataLength, $thisData, + color( 'reset' ), $spaceLength, "" ); + } + + foreach ( @rowData ) { + my $thisData = $data{ $_ }{ $thisDir }; + my $dataLength = length( $thisData ); + my $spaceLength = $maxLen{ $_ }-$dataLength; + + printf( + $format{ $_ }.$separator{ $_ }, + $spaceLength, "", + $colors{ $_ }, $dataLength, $thisData, + color( 'reset' ) ); + } + + printf( $headerColor."\n" ); + + $testNo++; +} + +print '-'x$headerLen, "\n"; +print( "Tests with zero fails/skips : $testsPassed\n" ); +print( "Tests needing further work : $testsNeedWork\n" ); + +printf( "Elapsed time : %d seconds\n", time() - $startTime ); + +sub setMaxLen +{ + my ( $test, $length ) = @_; + + $maxLen{ $test } = $length if ( defined( $maxLen{ $test} ) && $length > $maxLen{ $test } ); +} + +sub byCol +{ + my $retVal = 0; + + my $localA = $a; + my $localB = $b; + + if ( $reverseSort ) { + my $tmp = $localA; + $localA = $localB; + $localB = $tmp; + } + + if ( $sortIsNumeric ) { + # numeric comparison + $retVal = $data{ $sortCol }{ $localA } <=> $data{ $sortCol }{ $localB }; + } else { + # string comparison + $retVal = $data{ $sortCol }{ $localA } cmp $data{ $sortCol }{ $localB }; + } + + return $retVal; +} diff --git a/tests/tests.pro b/tests/tests.pro new file mode 100644 index 000000000..3a692b632 --- /dev/null +++ b/tests/tests.pro @@ -0,0 +1,176 @@ +TEMPLATE = subdirs +#SUBDIRS = $$system(ls -1d ut_*/) + +include(../mkspecs/common.pri) + +SUBDIRS = \ + ft_duiservicefwgen \ + ft_duistylesheetparser \ + ft_duistylesheet \ + ft_duidialog \ + ft_duiprogressindicator \ + ft_duiscenemanager \ + ft_duigconfitem \ +# ft_duivideowidget \ + ft_theme \ +# ft_duibutton \ + ft_duislider \ + ft_duiscalableimage \ +# ut_duiapplication \ // Depends on private class + ut_duiapplicationpage \ + ut_duiapplicationwindow \ + ut_duiapplicationservice \ + ut_duiinputmethodstate \ + ut_duibutton \ + ut_duibuttonview \ + ut_duibuttongroup \ + ut_duicombobox \ + ut_duidialog \ + ut_duidialogview \ + ut_duinavigationbar \ + ut_duifastlistviewgroupheader \ + ut_duifastlistviewmulticolumn \ + ut_duiflowlayoutpolicy \ + ut_duifreestylelayoutpolicy \ + ut_duigridlayoutpolicy \ +# ut_duiimagewidget \ // CITA problems + ut_duilayout \ + ut_duilinearlayoutpolicy \ + ut_duiapplicationmenu \ + ut_duiapplicationmenuview \ +# ut_duiobjectmenu \ + ut_duioverlay \ + ut_duipannableviewport \ + ut_duipannablewidget \ + ut_duipositionindicator \ + ut_duipositionindicatorview \ + ut_duipopuplist \ + ut_duiscenemanager \ + ut_duislider \ + ut_duiseekbar \ + ut_duisliderview \ + ut_duitextedit \ + ut_duitexteditview \ +# ut_duitheme \ + ut_duitoolbar \ + ut_duitoolbarview \ + ut_duiwidget \ + ut_duiwidgetview \ + ut_duiwindow \ + ut_duiphysics2dpanning \ + ut_duilabel \ + ut_duilogicalvalues \ + ut_duidesktopentry \ + ut_duicontainer \ + ut_duiinfobanner \ + ut_duiwidgetcontroller \ + ut_duiservicemapper \ + ut_duiservicefwbaseif \ + ut_duiscene \ + ut_duiappletalivemessagerequest \ + ut_duiappletalivemessageresponse \ + ut_duiappletbutton \ + ut_duiappletcommunicator \ + ut_duiappletserver \ + ut_duiappletclient \ + ut_duiapplethandle \ + ut_duiapplethandleview \ +# ut_duiapplethandleglesview \ + ut_duiappletsharedmutex \ + ut_duiappletinstancemanager \ + ut_duiappletinstancedata \ + ut_duiappletinventory \ +# ut_duiappletinventoryview \ // Depends on private class + ut_duiappletmetadata \ + ut_duiappletmessage \ + ut_duiappletmessagefactory \ + ut_duiappletmousemessage \ + ut_duiappletorientationmessage \ + ut_duiappletrunner \ + ut_duiappletsetgeometrymessage \ + ut_duiappletpixmaptakenintousemessage \ + ut_duiappletvisibilitymessage \ + ut_duiappletupdategeometrymessage \ + ut_duiappletpixmapmodifiedmessage \ + ut_duiappletcancelmessage \ + ut_duiappletloader \ + ut_duiappletid \ + ut_duiappletsettings \ + ut_duiappletsettingsdialog \ + ut_duifiledatastore \ + ut_duiaggregatedataaccess \ + ut_duimashupcanvas \ + ut_duimashupcanvasview \ + ut_duisubdatastore \ + ut_duiactionprovider \ + ut_duiremoteaction \ + ut_duiserviceaction \ + ut_duiserviceinvoker \ + ut_duiscenewindow \ + ut_duimodalscenewindow \ + ut_duinotification \ + ut_duinotificationmanager \ + ut_duisettingslanguageparser \ + ut_duisettingslanguagebinary \ + ut_duisettingslanguagewidget \ + ut_duisettingslanguagewidgetfactory \ + ut_duisettingslanguagesettingsfactory \ + ut_duisettingslanguageselectionfactory \ + ut_duisettingslanguagebooleanfactory \ + ut_duisettingslanguagetextfactory \ + ut_duisettingslanguageintegerfactory \ + ut_duisettingslanguageselectioncontroller \ + ut_duisettingslanguagebooleancontroller \ + ut_duisettingslanguagetextcontroller \ + ut_duisettingslanguageintegercontroller \ + ut_duisettingslanguagesettings \ + ut_duisettingslanguageselection \ + ut_duisettingslanguageboolean \ + ut_duisettingslanguagetext \ + ut_duisettingslanguageoption \ + ut_duisettingslanguageinteger \ + ut_duiextendingbackgroundview \ + ut_duigconfdatastore \ + ut_duishareddata \ + ut_duiappletobjectmenurequestmessage \ + ut_duiappletobjectmenumessage \ + ut_duiappletobjectmenuactionselectedmessage \ + ut_duifeedback \ + ut_duifeedbackplayer \ + ut_duicompleter \ + ut_translations \ + ut_translations/translations-tr \ + ut_translations/translations-qttrid \ + ut_duiextensionarea \ + ut_duiapplicationextensionarea \ + ut_duiapplicationextensionareaview + +# enable only when we have icu available + +contains(DEFINES, HAVE_ICU) { +SUBDIRS += \ + ft_breakiterator \ + ft_locales \ + ft_localedata \ + ft_numbers \ + ft_sorting \ + ut_duicalendar \ + ut_duiappletinstantiator +} + + +QMAKE_STRIP = echo +include(shell.pri) +include(runtests.pri) + + +check.target = check +check.CONFIG = recursive +QMAKE_EXTRA_TARGETS += check + + +check-xml.target = check-xml +check-xml.CONFIG = recursive +QMAKE_EXTRA_TARGETS += check-xml + +QMAKE_CLEAN += **/*.log.xml ./coverage.log.xml **/*.log diff --git a/tests/ut_duiactionprovider/.gitignore b/tests/ut_duiactionprovider/.gitignore new file mode 100644 index 000000000..f42bec3c5 --- /dev/null +++ b/tests/ut_duiactionprovider/.gitignore @@ -0,0 +1 @@ +ut_duiactionprovider diff --git a/tests/ut_duiactionprovider/ut_duiactionprovider.cpp b/tests/ut_duiactionprovider/ut_duiactionprovider.cpp new file mode 100644 index 000000000..326455328 --- /dev/null +++ b/tests/ut_duiactionprovider/ut_duiactionprovider.cpp @@ -0,0 +1,48 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duiactionprovider.h" +#include +#include + +void Ut_DuiActionProvider::init() +{ +} + +void Ut_DuiActionProvider::cleanup() +{ +} + +void Ut_DuiActionProvider::initTestCase() +{ +} + +void Ut_DuiActionProvider::cleanupTestCase() +{ +} + +void Ut_DuiActionProvider::testGetDefaultAction() +{ + QUrl uri(QUrl::fromLocalFile("image.png")); + DuiAction *action = DuiActionProvider::getDefaultAction(uri); + QVERIFY(action != NULL); + delete action; +} + +QTEST_APPLESS_MAIN(Ut_DuiActionProvider) diff --git a/tests/ut_duiactionprovider/ut_duiactionprovider.h b/tests/ut_duiactionprovider/ut_duiactionprovider.h new file mode 100644 index 000000000..f840b4d78 --- /dev/null +++ b/tests/ut_duiactionprovider/ut_duiactionprovider.h @@ -0,0 +1,40 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIACTIONPROVIDER_H +#define UT_DUIACTIONPROVIDER_H + +#include +#include + +class Ut_DuiActionProvider : public QObject +{ + Q_OBJECT + +private slots: + void init(); + void cleanup(); + void initTestCase(); + void cleanupTestCase(); + + void testGetDefaultAction(); + +}; + +#endif diff --git a/tests/ut_duiactionprovider/ut_duiactionprovider.pro b/tests/ut_duiactionprovider/ut_duiactionprovider.pro new file mode 100644 index 000000000..cb93f6ed1 --- /dev/null +++ b/tests/ut_duiactionprovider/ut_duiactionprovider.pro @@ -0,0 +1,24 @@ +include(../common_top.pri) +TARGET = ut_duiactionprovider +INCLUDEPATH += $$DUISRCDIR/service + +TEST_SOURCES = \ + $$DUISRCDIR/service/duiactionprovider.cpp + +# unit test and unit +SOURCES += \ + ut_duiactionprovider.cpp \ + $$STUBSDIR/stubbase.cpp \ + $$TEST_SOURCES + +# unit test and unit +HEADERS += \ + ut_duiactionprovider.h \ + $$DUISRCDIR/service/duiactionprovider.h + +# service classes +HEADERS += \ + $$DUISRCDIR/core/duiaction.h \ + $$DUISRCDIR/service/duiserviceaction.h + +include(../common_bot.pri) diff --git a/tests/ut_duiaggregatedataaccess/.gitignore b/tests/ut_duiaggregatedataaccess/.gitignore new file mode 100644 index 000000000..1001d7586 --- /dev/null +++ b/tests/ut_duiaggregatedataaccess/.gitignore @@ -0,0 +1,2 @@ +ut_duiaggregatedataaccess + diff --git a/tests/ut_duiaggregatedataaccess/ut_duiaggregatedataaccess.cpp b/tests/ut_duiaggregatedataaccess/ut_duiaggregatedataaccess.cpp new file mode 100644 index 000000000..3fb940a4d --- /dev/null +++ b/tests/ut_duiaggregatedataaccess/ut_duiaggregatedataaccess.cpp @@ -0,0 +1,195 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include "ut_duiaggregatedataaccess.h" +#include "../stubs/mockdatastore.h" + +void Ut_DuiAggregateDataAccess::init() +{ + primaryAccess = new MockDataStore; + secondaryAccess = new MockDataStore; + testAccess = new DuiAggregateDataAccess(*primaryAccess, *secondaryAccess); +} + +void Ut_DuiAggregateDataAccess::cleanup() +{ + valueChangedSignals.clear(); + delete testAccess; + delete primaryAccess; + delete secondaryAccess; +} + +void Ut_DuiAggregateDataAccess::testAccessValueChanged(const QString &key, const QVariant &value) +{ + valueChangedSignals.append(QPair(key, value)); +} + +void Ut_DuiAggregateDataAccess::testSettingValueInPrimaryAccess() +{ + primaryAccess->createValue(QString("primaryKey"), QVariant(1)); + testAccess->setValue(QString("primaryKey"), QVariant(2)); + + QCOMPARE(primaryAccess->value(QString("primaryKey")), QVariant(2)); +} + +void Ut_DuiAggregateDataAccess::testSettingValueInSecondaryAccess() +{ + secondaryAccess->createValue(QString("secondaryKey"), QVariant(1)); + testAccess->setValue(QString("secondaryKey"), QVariant(2)); + + QCOMPARE(secondaryAccess->value(QString("secondaryKey")), QVariant(2)); +} + +void Ut_DuiAggregateDataAccess::testSettingValueDefinedInPrimaryAndSecondaryAccess() +{ + primaryAccess->createValue(QString("sharedKey"), QVariant(1)); + secondaryAccess->createValue(QString("sharedKey"), QVariant(1)); + testAccess->setValue(QString("sharedKey"), QVariant(2)); + + QCOMPARE(primaryAccess->value(QString("sharedKey")), QVariant(2)); + QCOMPARE(secondaryAccess->value(QString("sharedKey")), QVariant(1)); +} + +void Ut_DuiAggregateDataAccess::testGettingAggregateKeyList() +{ + primaryAccess->createValue(QString("primaryKey"), QVariant(1)); + secondaryAccess->createValue(QString("secondaryKey"), QVariant(1)); + + QCOMPARE(testAccess->allKeys().count(), 2); + QCOMPARE(testAccess->allKeys().contains("primaryKey"), QBool(true)); + QCOMPARE(testAccess->allKeys().contains("secondaryKey"), QBool(true)); +} + +void Ut_DuiAggregateDataAccess::testGettingAggregateKeyListWithoutDuplicates() +{ + primaryAccess->createValue(QString("sharedKey"), QVariant(1)); + secondaryAccess->createValue(QString("sharedKey"), QVariant(2)); + + QCOMPARE(testAccess->allKeys().count(), 1); + QCOMPARE(testAccess->allKeys().contains("sharedKey"), QBool(true)); +} + +void Ut_DuiAggregateDataAccess::testContainsKeyInPrimaryAccess() +{ + primaryAccess->createValue(QString("primaryKey"), QVariant(1)); + + QCOMPARE(testAccess->contains(QString("primaryKey")), true); + QCOMPARE(testAccess->contains(QString("secondaryKey")), false); +} + +void Ut_DuiAggregateDataAccess::testContainsKeyInSecondaryAccess() +{ + secondaryAccess->createValue(QString("secondaryKey"), QVariant(1)); + + QCOMPARE(testAccess->contains(QString("primaryKey")), false); + QCOMPARE(testAccess->contains(QString("secondaryKey")), true); +} + +void Ut_DuiAggregateDataAccess::testContainsKeyDefinedInPrimaryAndSecondaryAccess() +{ + primaryAccess->createValue(QString("sharedKey"), QVariant(1)); + secondaryAccess->createValue(QString("sharedKey"), QVariant(2)); + + QCOMPARE(testAccess->contains(QString("sharedKey")), true); +} + +void Ut_DuiAggregateDataAccess::testAcquiringValueFromPrimaryAccess() +{ + primaryAccess->createValue(QString("primaryKey"), QVariant(3)); + + QCOMPARE(testAccess->value(QString("primaryKey")), QVariant(3)); +} + +void Ut_DuiAggregateDataAccess::testAcquiringValueFromSecondaryAccess() +{ + secondaryAccess->createValue(QString("secondaryKey"), QVariant(3)); + + QCOMPARE(testAccess->value(QString("secondaryKey")), QVariant(3)); +} + +void Ut_DuiAggregateDataAccess::testAcquiringValueDefinedInPrimaryAndSecondaryAccess() +{ + primaryAccess->createValue(QString("sharedKey"), QVariant(3)); + secondaryAccess->createValue(QString("sharedKey"), QVariant(2)); + + QCOMPARE(testAccess->value(QString("sharedKey")), QVariant(3)); +} + +void Ut_DuiAggregateDataAccess::testValueChangedEmittedFromPrimaryAccess() +{ + connect(testAccess, SIGNAL(valueChanged(QString, QVariant)), this, SLOT(testAccessValueChanged(QString, QVariant))); + primaryAccess->createValue(QString("primaryKey"), QVariant(3)); + + QCOMPARE(valueChangedSignals.count(), 1); + QCOMPARE(valueChangedSignals.at(0).first, QString("primaryKey")); + QCOMPARE(valueChangedSignals.at(0).second.toInt(), 3); + valueChangedSignals.clear(); + + primaryAccess->setValue(QString("primaryKey"), QVariant(5)); + + QCOMPARE(valueChangedSignals.count(), 1); + QCOMPARE(valueChangedSignals.at(0).first, QString("primaryKey")); + QCOMPARE(valueChangedSignals.at(0).second.toInt(), 5); +} + +void Ut_DuiAggregateDataAccess::testValueChangedEmittedFromSecondaryAccess() +{ + connect(testAccess, SIGNAL(valueChanged(QString, QVariant)), this, SLOT(testAccessValueChanged(QString, QVariant))); + secondaryAccess->createValue(QString("secondaryKey"), QVariant(2)); + + QCOMPARE(valueChangedSignals.count(), 1); + QCOMPARE(valueChangedSignals.at(0).first, QString("secondaryKey")); + QCOMPARE(valueChangedSignals.at(0).second.toInt(), 2); + valueChangedSignals.clear(); + + secondaryAccess->setValue(QString("secondaryKey"), QVariant(8)); + + QCOMPARE(valueChangedSignals.count(), 1); + QCOMPARE(valueChangedSignals.at(0).first, QString("secondaryKey")); + QCOMPARE(valueChangedSignals.at(0).second.toInt(), 8); +} + +void Ut_DuiAggregateDataAccess::testValueChangedEmittedFromSharedKey() +{ + connect(testAccess, SIGNAL(valueChanged(QString, QVariant)), this, SLOT(testAccessValueChanged(QString, QVariant))); + + secondaryAccess->createValue(QString("sharedKey"), QVariant(2)); + QCOMPARE(valueChangedSignals.count(), 1); + QCOMPARE(valueChangedSignals.at(0).first, QString("sharedKey")); + QCOMPARE(valueChangedSignals.at(0).second.toInt(), 2); + valueChangedSignals.clear(); + + primaryAccess->createValue(QString("sharedKey"), QVariant(4)); + QCOMPARE(valueChangedSignals.count(), 1); + QCOMPARE(valueChangedSignals.at(0).first, QString("sharedKey")); + QCOMPARE(valueChangedSignals.at(0).second.toInt(), 4); + valueChangedSignals.clear(); + + secondaryAccess->setValue(QString("sharedKey"), QVariant(3)); + QCOMPARE(valueChangedSignals.count(), 0); + + primaryAccess->setValue(QString("sharedKey"), QVariant(7)); + QCOMPARE(valueChangedSignals.count(), 1); + QCOMPARE(valueChangedSignals.at(0).first, QString("sharedKey")); + QCOMPARE(valueChangedSignals.at(0).second.toInt(), 7); +} + +QTEST_MAIN(Ut_DuiAggregateDataAccess) diff --git a/tests/ut_duiaggregatedataaccess/ut_duiaggregatedataaccess.h b/tests/ut_duiaggregatedataaccess/ut_duiaggregatedataaccess.h new file mode 100644 index 000000000..ac5979802 --- /dev/null +++ b/tests/ut_duiaggregatedataaccess/ut_duiaggregatedataaccess.h @@ -0,0 +1,65 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIAGGREGATEDATAACCESS_H +#define UT_DUIAGGREGATEDATAACCESS_H + +#include +#include + +class MockDataStore; +class DuiDataAccess; + +class Ut_DuiAggregateDataAccess : public QObject +{ + Q_OBJECT + +private slots: + void init(); + void cleanup(); + void testSettingValueInPrimaryAccess(); + void testSettingValueInSecondaryAccess(); + void testSettingValueDefinedInPrimaryAndSecondaryAccess(); + void testAcquiringValueFromPrimaryAccess(); + void testAcquiringValueFromSecondaryAccess(); + void testAcquiringValueDefinedInPrimaryAndSecondaryAccess(); + void testGettingAggregateKeyList(); + void testGettingAggregateKeyListWithoutDuplicates(); + void testContainsKeyInPrimaryAccess(); + void testContainsKeyInSecondaryAccess(); + void testContainsKeyDefinedInPrimaryAndSecondaryAccess(); + void testValueChangedEmittedFromPrimaryAccess(); + void testValueChangedEmittedFromSecondaryAccess(); + void testValueChangedEmittedFromSharedKey(); + + /*! + * Connected to the valueChanged signal of the testAccess object + * This method will append the value changed signal contents to the + * valueChangedSignals list. + */ + void testAccessValueChanged(const QString &, const QVariant &); + +private: + MockDataStore *primaryAccess; + MockDataStore *secondaryAccess; + DuiDataAccess *testAccess; + QList< QPair > valueChangedSignals; +}; + +#endif diff --git a/tests/ut_duiaggregatedataaccess/ut_duiaggregatedataaccess.pro b/tests/ut_duiaggregatedataaccess/ut_duiaggregatedataaccess.pro new file mode 100644 index 000000000..81791d39b --- /dev/null +++ b/tests/ut_duiaggregatedataaccess/ut_duiaggregatedataaccess.pro @@ -0,0 +1,13 @@ +include(../common_top.pri) +TARGET = ut_duiaggregatedataaccess +INCLUDEPATH += $$DUISRCDIR/mashup/mashup + +# unit test and unit +SOURCES += \ + ut_duiaggregatedataaccess.cpp + +# unit test and unit +HEADERS += \ + ut_duiaggregatedataaccess.h + +include(../common_bot.pri) diff --git a/tests/ut_duiappletalivemessagerequest/.gitignore b/tests/ut_duiappletalivemessagerequest/.gitignore new file mode 100644 index 000000000..db257e22d --- /dev/null +++ b/tests/ut_duiappletalivemessagerequest/.gitignore @@ -0,0 +1 @@ +ut_duiappletalivemessagerequest diff --git a/tests/ut_duiappletalivemessagerequest/ut_duiappletalivemessagerequest.cpp b/tests/ut_duiappletalivemessagerequest/ut_duiappletalivemessagerequest.cpp new file mode 100644 index 000000000..e00d15cd8 --- /dev/null +++ b/tests/ut_duiappletalivemessagerequest/ut_duiappletalivemessagerequest.cpp @@ -0,0 +1,40 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duiappletalivemessagerequest.h" + +#include +#include "duiappletalivemessagerequest.h" + +void Ut_DuiAppletAliveMessageRequest::init() +{ + message = new DuiAppletAliveMessageRequest(); +} + +void Ut_DuiAppletAliveMessageRequest::cleanup() +{ + delete message; +} + +void Ut_DuiAppletAliveMessageRequest::testType() +{ + QCOMPARE(message->type(), DuiAppletMessage::APPLET_ALIVE_MESSAGE_REQUEST); +} + +QTEST_APPLESS_MAIN(Ut_DuiAppletAliveMessageRequest) diff --git a/tests/ut_duiappletalivemessagerequest/ut_duiappletalivemessagerequest.h b/tests/ut_duiappletalivemessagerequest/ut_duiappletalivemessagerequest.h new file mode 100644 index 000000000..026942b22 --- /dev/null +++ b/tests/ut_duiappletalivemessagerequest/ut_duiappletalivemessagerequest.h @@ -0,0 +1,41 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIAPPLETALIVEMESSAGEREQUEST_H +#define UT_DUIAPPLETALIVEMESSAGEREQUEST_H + +#include + +class DuiAppletAliveMessageRequest; + +class Ut_DuiAppletAliveMessageRequest : public QObject +{ + Q_OBJECT + +private: + DuiAppletAliveMessageRequest *message; + +private slots: + void init(); + void cleanup(); + + void testType(); +}; + +#endif // UT_DUIAPPLETALIVEMESSAGEREQUEST_H diff --git a/tests/ut_duiappletalivemessagerequest/ut_duiappletalivemessagerequest.pro b/tests/ut_duiappletalivemessagerequest/ut_duiappletalivemessagerequest.pro new file mode 100644 index 000000000..f03155185 --- /dev/null +++ b/tests/ut_duiappletalivemessagerequest/ut_duiappletalivemessagerequest.pro @@ -0,0 +1,13 @@ +include(../common_top.pri) +TARGET = ut_duiappletalivemessagerequest +INCLUDEPATH += $$DUISRCDIR/mashup/appletcommunication $$DUISRCDIR/mashup/appletinterface $$DUISRCDIR/mashup/mashup + +# unit test and unit classes +SOURCES += \ + ut_duiappletalivemessagerequest.cpp \ + +# unit test and unit classes +HEADERS += \ + ut_duiappletalivemessagerequest.h \ + +include(../common_bot.pri) diff --git a/tests/ut_duiappletalivemessageresponse/.gitignore b/tests/ut_duiappletalivemessageresponse/.gitignore new file mode 100644 index 000000000..a8ee4ad50 --- /dev/null +++ b/tests/ut_duiappletalivemessageresponse/.gitignore @@ -0,0 +1 @@ +ut_duiappletalivemessageresponse diff --git a/tests/ut_duiappletalivemessageresponse/ut_duiappletalivemessageresponse.cpp b/tests/ut_duiappletalivemessageresponse/ut_duiappletalivemessageresponse.cpp new file mode 100644 index 000000000..18cf6c991 --- /dev/null +++ b/tests/ut_duiappletalivemessageresponse/ut_duiappletalivemessageresponse.cpp @@ -0,0 +1,40 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duiappletalivemessageresponse.h" + +#include +#include "duiappletalivemessageresponse.h" + +void Ut_DuiAppletAliveMessageResponse::init() +{ + message = new DuiAppletAliveMessageResponse(); +} + +void Ut_DuiAppletAliveMessageResponse::cleanup() +{ + delete message; +} + +void Ut_DuiAppletAliveMessageResponse::testType() +{ + QCOMPARE(message->type(), DuiAppletMessage::APPLET_ALIVE_MESSAGE_RESPONSE); +} + +QTEST_APPLESS_MAIN(Ut_DuiAppletAliveMessageResponse) diff --git a/tests/ut_duiappletalivemessageresponse/ut_duiappletalivemessageresponse.h b/tests/ut_duiappletalivemessageresponse/ut_duiappletalivemessageresponse.h new file mode 100644 index 000000000..3437137e2 --- /dev/null +++ b/tests/ut_duiappletalivemessageresponse/ut_duiappletalivemessageresponse.h @@ -0,0 +1,41 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIAPPLETALIVEMESSAGERESPONSE_H +#define UT_DUIAPPLETALIVEMESSAGERESPONSE_H + +#include + +class DuiAppletAliveMessageResponse; + +class Ut_DuiAppletAliveMessageResponse : public QObject +{ + Q_OBJECT + +private: + DuiAppletAliveMessageResponse *message; + +private slots: + void init(); + void cleanup(); + + void testType(); +}; + +#endif // UT_DUIAPPLETALIVEMESSAGEREQUEST_H diff --git a/tests/ut_duiappletalivemessageresponse/ut_duiappletalivemessageresponse.pro b/tests/ut_duiappletalivemessageresponse/ut_duiappletalivemessageresponse.pro new file mode 100644 index 000000000..00839e177 --- /dev/null +++ b/tests/ut_duiappletalivemessageresponse/ut_duiappletalivemessageresponse.pro @@ -0,0 +1,13 @@ +include(../common_top.pri) +TARGET = ut_duiappletalivemessageresponse +INCLUDEPATH += $$DUISRCDIR/mashup/appletcommunication $$DUISRCDIR/mashup/appletinterface $$DUISRCDIR/mashup/mashup + +# unit test and unit classes +SOURCES += \ + ut_duiappletalivemessageresponse.cpp \ + +# unit test and unit classes +HEADERS += \ + ut_duiappletalivemessageresponse.h \ + +include(../common_bot.pri) diff --git a/tests/ut_duiappletbutton/.gitignore b/tests/ut_duiappletbutton/.gitignore new file mode 100644 index 000000000..0c3237cf7 --- /dev/null +++ b/tests/ut_duiappletbutton/.gitignore @@ -0,0 +1 @@ +ut_duiappletbutton diff --git a/tests/ut_duiappletbutton/ut_duiappletbutton.cpp b/tests/ut_duiappletbutton/ut_duiappletbutton.cpp new file mode 100644 index 000000000..830c6b2ae --- /dev/null +++ b/tests/ut_duiappletbutton/ut_duiappletbutton.cpp @@ -0,0 +1,54 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duiappletbutton.h" +#include "duiappletbutton.h" +#include +#include + +void Ut_DuiAppletButton::init() +{ + subject = new DuiAppletButton(); +} + +void Ut_DuiAppletButton::cleanup() +{ + delete subject; +} + +void Ut_DuiAppletButton::initTestCase() +{ + static int argc = 1; + static char *app_name[1] = { (char *) "./ut_duibutton" }; + app = new DuiApplication(argc, app_name); +} + +void Ut_DuiAppletButton::cleanupTestCase() +{ + delete app; +} + +void Ut_DuiAppletButton::testInitialization() +{ + gDuiAppletMetaDataStub->stubSetReturnValue("isValid", true); + const DuiAppletMetaData metaData("/dev/null"); + QCOMPARE(subject->initialize(metaData), true); +} + +QTEST_APPLESS_MAIN(Ut_DuiAppletButton) diff --git a/tests/ut_duiappletbutton/ut_duiappletbutton.h b/tests/ut_duiappletbutton/ut_duiappletbutton.h new file mode 100644 index 000000000..834b5efca --- /dev/null +++ b/tests/ut_duiappletbutton/ut_duiappletbutton.h @@ -0,0 +1,48 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef _UT_DUIAPPLETBUTTON_ +#define _UT_DUIAPPLETBUTTON_ + +#include +#include +#include "duiapplication.h" + +class DuiAppletButton; + +class Ut_DuiAppletButton : public QObject +{ + Q_OBJECT + +private: + DuiApplication *app; + + // DuiAppletButton instance under testing + DuiAppletButton *subject; + QString path; + +private slots: + void init(); + void cleanup(); + void initTestCase(); + void cleanupTestCase(); + void testInitialization(); +}; + +#endif //_UT_DUIAPPLETBUTTON_ diff --git a/tests/ut_duiappletbutton/ut_duiappletbutton.pro b/tests/ut_duiappletbutton/ut_duiappletbutton.pro new file mode 100644 index 000000000..5ffe5c062 --- /dev/null +++ b/tests/ut_duiappletbutton/ut_duiappletbutton.pro @@ -0,0 +1,18 @@ +include(../common_top.pri) +TARGET = ut_duiappletbutton +INCLUDEPATH += $$DUISRCDIR/mashup/mashup $$DUISRCDIR/mashup/appletinterface + +SOURCES += \ + ut_duiappletbutton.cpp \ + $$DUISRCDIR/mashup/mashup/duiappletbutton.cpp + +# service classes +SOURCES += \ + $$STUBSDIR/stubbase.cpp \ + +# unit test and unit classes +HEADERS += \ + ut_duiappletbutton.h \ + $$DUISRCDIR/mashup/mashup/duiappletbutton.h + +include(../common_bot.pri) diff --git a/tests/ut_duiappletcancelmessage/.gitignore b/tests/ut_duiappletcancelmessage/.gitignore new file mode 100644 index 000000000..e114f8f11 --- /dev/null +++ b/tests/ut_duiappletcancelmessage/.gitignore @@ -0,0 +1 @@ +ut_duiappletcancelmessage diff --git a/tests/ut_duiappletcancelmessage/ut_duiappletcancelmessage.cpp b/tests/ut_duiappletcancelmessage/ut_duiappletcancelmessage.cpp new file mode 100644 index 000000000..2daad3699 --- /dev/null +++ b/tests/ut_duiappletcancelmessage/ut_duiappletcancelmessage.cpp @@ -0,0 +1,41 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duiappletcancelmessage.h" +#include "duiappletcancelmessage.h" + +#include + +void Ut_DuiAppletCancelMessage::init() +{ + message = new DuiAppletCancelMessage(); +} + +void Ut_DuiAppletCancelMessage::cleanup() +{ + delete message; +} + +void Ut_DuiAppletCancelMessage::testDefaultAppletCancelMessageType() +{ + QCOMPARE(message->type(), DuiAppletMessage::CANCEL_MESSAGE); +} + +QTEST_APPLESS_MAIN(Ut_DuiAppletCancelMessage) + diff --git a/tests/ut_duiappletcancelmessage/ut_duiappletcancelmessage.h b/tests/ut_duiappletcancelmessage/ut_duiappletcancelmessage.h new file mode 100644 index 000000000..0d184478d --- /dev/null +++ b/tests/ut_duiappletcancelmessage/ut_duiappletcancelmessage.h @@ -0,0 +1,41 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIAPPLETCANCELMESSAGE_H +#define UT_DUIAPPLETCANCELMESSAGE_H + +#include + +class DuiAppletCancelMessage; + +class Ut_DuiAppletCancelMessage : public QObject +{ + Q_OBJECT + +private: + DuiAppletCancelMessage *message; + +private slots: + void init(); + void cleanup(); + + void testDefaultAppletCancelMessageType(); +}; + +#endif // UT_DUIAPPLETCANCELMESSAGE_H diff --git a/tests/ut_duiappletcancelmessage/ut_duiappletcancelmessage.pro b/tests/ut_duiappletcancelmessage/ut_duiappletcancelmessage.pro new file mode 100644 index 000000000..346861390 --- /dev/null +++ b/tests/ut_duiappletcancelmessage/ut_duiappletcancelmessage.pro @@ -0,0 +1,13 @@ +include(../common_top.pri) +TARGET = ut_duiappletcancelmessage +INCLUDEPATH += $$DUISRCDIR/mashup/appletcommunication $$DUISRCDIR/mashup/appletinterface $$DUISRCDIR/mashup/mashup + +# unit test and unit classes +SOURCES += \ + ut_duiappletcancelmessage.cpp \ + +# unit test and unit classes +HEADERS += \ + ut_duiappletcancelmessage.h \ + +include(../common_bot.pri) diff --git a/tests/ut_duiappletclient/.gitignore b/tests/ut_duiappletclient/.gitignore new file mode 100644 index 000000000..d7dfb54f5 --- /dev/null +++ b/tests/ut_duiappletclient/.gitignore @@ -0,0 +1 @@ +ut_duiappletclient diff --git a/tests/ut_duiappletclient/ut_duiappletclient.cpp b/tests/ut_duiappletclient/ut_duiappletclient.cpp new file mode 100644 index 000000000..0efc1f353 --- /dev/null +++ b/tests/ut_duiappletclient/ut_duiappletclient.cpp @@ -0,0 +1,127 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include + +#include "duiappletserver.h" +#include "duiappletclient.h" +#include "duiappletmessage.h" +#include "duiappletmessagefactory.h" +#include "ut_duiappletclient.h" + + +RemoteProcessThread::RemoteProcessThread() : + socket(NULL), + server(NULL), + doWait(false) +{ +} + +RemoteProcessThread::~RemoteProcessThread() +{ + doWait = false; + wait(); + delete server; +} + +void RemoteProcessThread::waitHere() +{ + while (doWait) { + QThread::msleep(100); + } +} + +void RemoteProcessThread::run() +{ + QLocalServer::removeServer("foobar"); + server = new QLocalServer(); + server->listen("foobar"); + + connect(server, SIGNAL(newConnection()), this, SLOT(newConnection())); + doWait = true; + waitHere(); +} + +void RemoteProcessThread::readyRead() +{ +} + +void RemoteProcessThread::newConnection() +{ + socket = server->nextPendingConnection(); +} + +void Ut_DuiAppletClient::init() +{ + connected = false; + + process = new QProcess; + client = new DuiAppletClient; + connect(client, SIGNAL(connectionEstablished()), this, SLOT(connectionEstablished())); +} + +void Ut_DuiAppletClient::cleanup() +{ + delete client; + client = NULL; + delete process; + process = NULL; +} + +void Ut_DuiAppletClient::testConnection() +{ + RemoteProcessThread thread; + thread.start(); + QCOMPARE(client->connectToServer("foobar"), true); + thread.doWait = false; + + // Verify whether connection has been established or not + QCOMPARE(connected, true); +} + +void Ut_DuiAppletClient::testReconnect() +{ + RemoteProcessThread thread; + thread.start(); + client->connectToServer("foobar"); + + QCOMPARE(client->isConnected(), true); + QCOMPARE(connected, true); + + // Close the connection + client->closeConnection(); + QCOMPARE(client->isConnected(), false); + + connected = false; + // Try to connect again + client->connectToServer("foobar"); + QCOMPARE(client->isConnected(), true); + QCOMPARE(connected, true); + + thread.doWait = false; +} + +void Ut_DuiAppletClient::connectionEstablished() +{ + connected = true; +} + +QTEST_MAIN(Ut_DuiAppletClient) diff --git a/tests/ut_duiappletclient/ut_duiappletclient.h b/tests/ut_duiappletclient/ut_duiappletclient.h new file mode 100644 index 000000000..6808d9685 --- /dev/null +++ b/tests/ut_duiappletclient/ut_duiappletclient.h @@ -0,0 +1,73 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIAPPLETCLIENT_H +#define UT_DUIAPPLETCLIENT_H + +#include +#include + +class QProcess; +class QLocalSocket; +class QLocalServer; +class DuiAppletClient; + +class Ut_DuiAppletClient : public QObject +{ + Q_OBJECT + +private: + QProcess *process; + DuiAppletClient *client; + bool connected; + +private slots: + void init(); + void cleanup(); + + void testConnection(); + void testReconnect(); + +public slots: + void connectionEstablished(); +}; + +class RemoteProcessThread : public QThread +{ + Q_OBJECT + +private: + QLocalSocket *socket; + QLocalServer *server; + + void waitHere(); + +private slots: + void readyRead(); + void newConnection(); + +public: + RemoteProcessThread(); + virtual ~RemoteProcessThread(); + virtual void run(); + + bool doWait; +}; + +#endif // UT_DUIAPPLETCLIENT_H diff --git a/tests/ut_duiappletclient/ut_duiappletclient.pro b/tests/ut_duiappletclient/ut_duiappletclient.pro new file mode 100644 index 000000000..e5693ac9a --- /dev/null +++ b/tests/ut_duiappletclient/ut_duiappletclient.pro @@ -0,0 +1,17 @@ +include(../common_top.pri) +TARGET = ut_duiappletclient +INCLUDEPATH += $$DUISRCDIR/mashup/appletcommunication $$DUISRCDIR/mashup/appletinterface $$DUISRCDIR/mashup/mashup + +QT += core network gui svg dbus + +# unit test and unit classes +SOURCES += \ + ut_duiappletclient.cpp \ + +# unit test and unit classes +HEADERS += \ + ut_duiappletclient.h \ + +DEFINES += MY_APPLET_LIBS=\'$$quote(\"./\")\' + +include(../common_bot.pri) diff --git a/tests/ut_duiappletcommunicator/.gitignore b/tests/ut_duiappletcommunicator/.gitignore new file mode 100644 index 000000000..9b326de38 --- /dev/null +++ b/tests/ut_duiappletcommunicator/.gitignore @@ -0,0 +1 @@ +ut_duiappletcommunicator diff --git a/tests/ut_duiappletcommunicator/ut_duiappletcommunicator.cpp b/tests/ut_duiappletcommunicator/ut_duiappletcommunicator.cpp new file mode 100644 index 000000000..ca4a7f72a --- /dev/null +++ b/tests/ut_duiappletcommunicator/ut_duiappletcommunicator.cpp @@ -0,0 +1,335 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duiappletcommunicator.h" +#include +#include +#include +#include + +#include + +// static variables +TestAppletCommunicator *Ut_DuiAppletCommunicator::m_subject; + + +// QDataStream stubs +QDataStream::Status gDataStreamStatus = QDataStream::Ok; +QDataStream::Status QDataStream::status() const +{ + return gDataStreamStatus; +} + +// QLocalSocket stubs +QLocalSocket::LocalSocketState gLocalSocketState; +QLocalSocket::LocalSocketState QLocalSocket::state() const +{ + return gLocalSocketState; +} + +bool gLocalSocketFlushed; +bool QLocalSocket::flush() +{ + gLocalSocketFlushed = true; + return true; +} + +class TestCommunicatorSocket : public QLocalSocket +{ +public: + virtual qint64 bytesAvailable() const { + return Ut_DuiAppletCommunicator::m_subject->getStream().device()->bytesAvailable(); + } +}; + +// A simple applet message for testing +class TestAppletMessage : public DuiAppletMessage +{ +public: + // Some data in the message + uint foo; + + TestAppletMessage(uint value = 2, DuiAppletMessageType type = (DuiAppletMessageType)1) : + DuiAppletMessage(type), + foo(value) { + } + + void serialize(QDataStream &stream) const { + stream << foo; + } + + void unserialize(QDataStream &stream) { + stream >> foo; + } +}; + +void myMessageSerializer(QDataStream &stream, const DuiAppletMessage &message) +{ + // Serialize the message to a temporary stream + QByteArray array; + QDataStream tmpStream(&array, QIODevice::ReadWrite); + message.serialize(tmpStream); + + // Type + stream << (uint)message.type(); + // Size + int size = array.size(); + stream << size; + // Copy message data + stream.writeRawData(array.data(), size); +} + +// DuiAppletMessageFactory stubs +DuiAppletMessage *DuiAppletMessageFactory::create(DuiAppletMessage::DuiAppletMessageType messageType) +{ + switch ((uint)messageType) { + case 1: + return new TestAppletMessage; + default: + return NULL; + } +} + +// The test subject +TestAppletCommunicator::TestAppletCommunicator() : + testByteArray(NULL) +{ +} + +TestAppletCommunicator::~TestAppletCommunicator() +{ + delete testByteArray; +} + +void TestAppletCommunicator::closeConnection() +{ +} + +void TestAppletCommunicator::setSocketState(QLocalSocket::LocalSocketState state) +{ + if (socket == NULL) { + socket = new TestCommunicatorSocket; + } + gLocalSocketState = state; +} + +void TestAppletCommunicator::setupConnection() +{ + setSocketState(QLocalSocket::ConnectedState); + + if (stream != NULL) { + delete stream; + } + if (testByteArray != NULL) { + delete testByteArray; + } + testByteArray = new QByteArray; + stream = new QDataStream(testByteArray, QIODevice::ReadWrite); +} + +QDataStream &TestAppletCommunicator::getStream() const +{ + return *stream; +} + +// The test class +void Ut_DuiAppletCommunicator::initTestCase() +{ +} + +void Ut_DuiAppletCommunicator::cleanupTestCase() +{ +} + +void Ut_DuiAppletCommunicator::init() +{ + gLocalSocketState = QLocalSocket::UnconnectedState; + gLocalSocketFlushed = false; + + messageDatas.clear(); + + m_subject = new TestAppletCommunicator; + connect(this, SIGNAL(signalReadyRead()), m_subject, SLOT(readyRead())); + connect(m_subject, SIGNAL(messageReceived(DuiAppletMessage)), this, SLOT(messageReceived(DuiAppletMessage))); +} + +void Ut_DuiAppletCommunicator::cleanup() +{ + delete m_subject; + m_subject = NULL; +} + +void Ut_DuiAppletCommunicator::testIsConnected() +{ + // By default shouldn't be connected (there's no socket) + QCOMPARE(m_subject->isConnected(), false); + + // Set the socket's state to something that tells that it's not connected (this also creates the socket) + m_subject->setSocketState(QLocalSocket::UnconnectedState); + QCOMPARE(m_subject->isConnected(), false); + + // Set the socket's state to connected, which ultimately indicates, that there is a connection + m_subject->setSocketState(QLocalSocket::ConnectedState); + QCOMPARE(m_subject->isConnected(), true); +} + +void Ut_DuiAppletCommunicator::testMessageSendingWhenNotConnected() +{ + // Try to send a message + TestAppletMessage message; + bool result = m_subject->sendMessage(message); + QCOMPARE(result, false); +} + +void Ut_DuiAppletCommunicator::testMessageSending() +{ + m_subject->setupConnection(); + + // Send a message + TestAppletMessage message; + bool result = m_subject->sendMessage(message); + + // Verify that sending was successful + QCOMPARE(result, true); + + // msg type msg size msg payload + int expectedSize = sizeof(uint) + sizeof(int) + sizeof(uint); + QCOMPARE(m_subject->testByteArray->size(), expectedSize); + + uint value = 0; + m_subject->getStream().device()->seek(0); + + // First there should be the type + m_subject->getStream() >> value; + QCOMPARE(value, (uint)1); + + // Then there should be the size + m_subject->getStream() >> value; + QCOMPARE(value, (uint)sizeof(uint)); + + // Then there should be the data + m_subject->getStream() >> value; + QCOMPARE(value, (uint)2); + + // The socket should have been flushed + QCOMPARE(gLocalSocketFlushed, true); +} + +void Ut_DuiAppletCommunicator::testReceivingMessages() +{ + m_subject->setupConnection(); + + // Put test data for two messages to the stream + myMessageSerializer(m_subject->getStream(), TestAppletMessage(3)); + myMessageSerializer(m_subject->getStream(), TestAppletMessage(4)); + m_subject->getStream().device()->seek(0); + + emit signalReadyRead(); + + QCOMPARE(messageDatas.count(), 2); + QCOMPARE(messageDatas.at(0), (uint)3); + QCOMPARE(messageDatas.at(1), (uint)4); +} + +void Ut_DuiAppletCommunicator::testReceivingMessageWithSocketFailure() +{ + m_subject->setupConnection(); + + // Put test data for two messages to the stream + myMessageSerializer(m_subject->getStream(), TestAppletMessage(3)); + myMessageSerializer(m_subject->getStream(), TestAppletMessage(4)); + m_subject->getStream().device()->seek(0); + QSignalSpy connectionSpy(m_subject, SIGNAL(connectionLost())); + // make socket fail + gDataStreamStatus = static_cast(-1); + + // socket fails, no data, connectionLost signal received + emit signalReadyRead(); + QCOMPARE(connectionSpy.count(), 1); + QCOMPARE(messageDatas.count(), 0); + + // make socket succeed + gDataStreamStatus = QDataStream::Ok; + + // Test that we can read valid data after socket error + m_subject->getStream().device()->seek(0); + myMessageSerializer(m_subject->getStream(), TestAppletMessage(3)); + myMessageSerializer(m_subject->getStream(), TestAppletMessage(4)); + m_subject->getStream().device()->seek(0); + emit signalReadyRead(); + QCOMPARE(connectionSpy.count(), 1); // no new connectionLost signals + QCOMPARE(messageDatas.count(), 2); + QCOMPARE(messageDatas.at(0), (uint)3); + QCOMPARE(messageDatas.at(1), (uint)4); +} + +void Ut_DuiAppletCommunicator::testInvalidMessageTypeReceiving() +{ + m_subject->setupConnection(); + + // Put test data with unknown message type to the stream + myMessageSerializer(m_subject->getStream(), TestAppletMessage(2, (DuiAppletMessage::DuiAppletMessageType)10)); + m_subject->getStream().device()->seek(0); + + emit signalReadyRead(); + + QCOMPARE(messageDatas.count(), 0); +} + +void Ut_DuiAppletCommunicator::testReceivingMessageInMultipleParts() +{ + m_subject->setupConnection(); + + // Serialize a message to a temporary stream + QByteArray byteArray; + QDataStream tmpStream(&byteArray, QIODevice::ReadWrite); + myMessageSerializer(tmpStream, TestAppletMessage()); + tmpStream.device()->seek(0); + + QIODevice *device = m_subject->getStream().device(); + // Put the data to the communicator's stream one byte at a time + for (int i = 0; i < byteArray.size(); ++i) { + uchar tmpValue; + tmpStream >> tmpValue; + qint64 oldPos = device->pos(); + device->seek(device->size()); + m_subject->getStream() << tmpValue; + device->seek(oldPos); + + emit signalReadyRead(); + + if (i < byteArray.size() - 1) { + // No message signals should be emitted before the whole message is transfered + QCOMPARE(messageDatas.count(), 0); + } else { + // Now the whole message is transfered, so a signal should be emitted + QCOMPARE(messageDatas.count(), 1); + QCOMPARE(messageDatas.at(0), (uint)2); + } + } +} + +void Ut_DuiAppletCommunicator::messageReceived(const DuiAppletMessage &message) +{ + if (message.type() == 1) { + messageDatas.append(dynamic_cast(message).foo); + } +} + +QTEST_APPLESS_MAIN(Ut_DuiAppletCommunicator) diff --git a/tests/ut_duiappletcommunicator/ut_duiappletcommunicator.h b/tests/ut_duiappletcommunicator/ut_duiappletcommunicator.h new file mode 100644 index 000000000..b973d223a --- /dev/null +++ b/tests/ut_duiappletcommunicator/ut_duiappletcommunicator.h @@ -0,0 +1,77 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIAPPLETCOMMUNICATOR_H +#define UT_DUIAPPLETCOMMUNICATOR_H + +#include + +class TestAppletCommunicator : public DuiAppletCommunicator +{ + Q_OBJECT + +public: + TestAppletCommunicator(); + virtual ~TestAppletCommunicator(); + + virtual void closeConnection(); + void setSocketState(QLocalSocket::LocalSocketState state); + void setupConnection(); + QDataStream &getStream() const; + + QByteArray *testByteArray; + +}; + +class Ut_DuiAppletCommunicator : public QObject +{ + Q_OBJECT + +private slots: + // Called before the first testfunction is executed + void initTestCase(); + // Called after the last testfunction was executed + void cleanupTestCase(); + // Called before each testfunction is executed + void init(); + // Called after every testfunction + void cleanup(); + + // Test cases + void testIsConnected(); + void testMessageSendingWhenNotConnected(); + void testMessageSending(); + void testReceivingMessages(); + void testInvalidMessageTypeReceiving(); + void testReceivingMessageInMultipleParts(); + void testReceivingMessageWithSocketFailure(); + +signals: + void signalReadyRead(); + +public slots: + void messageReceived(const DuiAppletMessage &message); + +public: + static TestAppletCommunicator *m_subject; + + QList messageDatas; +}; + +#endif diff --git a/tests/ut_duiappletcommunicator/ut_duiappletcommunicator.pro b/tests/ut_duiappletcommunicator/ut_duiappletcommunicator.pro new file mode 100644 index 000000000..1d7bfd447 --- /dev/null +++ b/tests/ut_duiappletcommunicator/ut_duiappletcommunicator.pro @@ -0,0 +1,13 @@ +include(../common_top.pri) +TARGET = ut_duiappletcommunicator +INCLUDEPATH += $$DUISRCDIR/mashup/appletcommunication + +SOURCES += \ + ut_duiappletcommunicator.cpp \ + $$DUISRCDIR/mashup/appletcommunication/duiappletcommunicator.cpp + +HEADERS += \ + ut_duiappletcommunicator.h \ + $$DUISRCDIR/mashup/appletcommunication/duiappletcommunicator.h + +include(../common_bot.pri) diff --git a/tests/ut_duiapplethandle/.gitignore b/tests/ut_duiapplethandle/.gitignore new file mode 100644 index 000000000..b2652724d --- /dev/null +++ b/tests/ut_duiapplethandle/.gitignore @@ -0,0 +1,2 @@ +ut_duiapplethandle + diff --git a/tests/ut_duiapplethandle/ut_duiapplethandle.cpp b/tests/ut_duiapplethandle/ut_duiapplethandle.cpp new file mode 100644 index 000000000..d76609758 --- /dev/null +++ b/tests/ut_duiapplethandle/ut_duiapplethandle.cpp @@ -0,0 +1,750 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include "ut_duiapplethandle.h" +#include +#include +#include "duiappletsetgeometrymessage.h" +#include "duiappletmousemessage.h" +#include "duiappletalivemessageresponse.h" +#include "duiappletpixmaptakenintousemessage.h" +#include "duiappletupdategeometrymessage.h" +#include "duiappletvisibilitymessage.h" +#include "duiappletobjectmenuactionselectedmessage.h" +#include "duiappleticonchangedmessage.h" +#include "duiapplettitlechangedmessage.h" +#include "duiapplettextchangedmessage.h" +#include +#include +#include +#include +#include "duisettingslanguageparser.h" +#include "duiappletsharedmutex_stub.h" +#include "duiappletobjectmenurequestmessage.h" +#include "duiappletobjectmenumessage.h" +#include "duiappletobjectmenuactionselectedmessage.h" +#include "duiobjectmenu_stub.h" +#include +#include +#include +#include + +DuiApplication *app; +DuiApplicationWindow *appWin; + +bool visibility; +QPointF mousePressPosition; +QPointF mouseReleasePosition; +QPointF mouseMovePosition; +QPointF contextMenuEventPos; +Qt::MouseButtons mouseEventButtons; +Qt::MouseButton mouseEventButton; +uint appletSpecificActionIndex = 0; +bool Ut_DuiAppletHandle::listenForConnection = true; +QSizeF Ut_DuiAppletHandle::minSize = QSizeF(); +QSizeF Ut_DuiAppletHandle::prefSize = QSizeF(); +QSizeF Ut_DuiAppletHandle::maxSize = QSizeF(); +QSize Ut_DuiAppletHandle::visibleSceneSize = QSize(1000, 1000); +bool Ut_DuiAppletHandle::contextMenuOpened; + +// DuiWidget stubs (used by DuiAppletHandle) +DuiWidgetPrivate::DuiWidgetPrivate() : selected(false) +{ +} + +DuiWidgetPrivate::~DuiWidgetPrivate() +{ +} + +void DuiWidget::contextMenuEvent(QGraphicsSceneContextMenuEvent *) +{ + Ut_DuiAppletHandle::contextMenuOpened = true; +} + +// DuiSceneManager stubs (used by DuiAppletHandle) +void DuiSceneManager::showWindow(DuiSceneWindow *, DuiSceneWindow::DeletionPolicy) +{ +} + +// A test applet handle implementation to allow mouse event sending +DuiTestAppletHandle::DuiTestAppletHandle() : DuiAppletHandle() +{ +} + +void DuiTestAppletHandle::messageReceivedFromRunner(const DuiAppletMessage &message) +{ + messageReceived(message); +} + +void DuiTestAppletHandle::sendMouseEvent(QGraphicsSceneMouseEvent &event) +{ + if (event.type() == QEvent::GraphicsSceneMousePress) + mousePressEvent(&event); + else if (event.type() == QEvent::GraphicsSceneMouseRelease) + mouseReleaseEvent(&event); + else if (event.type() == QEvent::GraphicsSceneMouseMove) + mouseMoveEvent(&event); +} + +void DuiTestAppletHandle::sendContextMenuEvent(QGraphicsSceneContextMenuEvent *event) +{ + contextMenuEvent(event); +} + +void DuiTestAppletHandle::aliveMessageResponseTimeout() +{ + communicationTimerTimeout(); +} + +void DuiTestAppletHandle::connectionTimeout() +{ + communicationTimerTimeout(); +} + +DuiTestAppletHandlePrivate *DuiTestAppletHandle::privateClass() +{ + Q_D(DuiTestAppletHandle); + + return d; +} + +// AppletCommunicator stubs to get rid of IPC and to send the size hint +bool DuiAppletServer::startServer(const QString &serverName) +{ + Q_UNUSED(serverName); + return Ut_DuiAppletHandle::listenForConnection; +} + +// Store information from the different message types sent by the handle +bool DuiAppletCommunicator::sendMessage(const DuiAppletMessage &message) +{ + const DuiAppletMouseMessage *mouseMessage = 0; + switch (message.type()) { + case DuiAppletMessage::MOUSE_PRESS_MESSAGE: + case DuiAppletMessage::MOUSE_RELEASE_MESSAGE: + case DuiAppletMessage::MOUSE_MOVE_MESSAGE: + mouseMessage = dynamic_cast(&message); + mouseEventButton = mouseMessage->button(); + mouseEventButtons = mouseMessage->buttons(); + if (message.type() == DuiAppletMessage::MOUSE_PRESS_MESSAGE) + mousePressPosition = (dynamic_cast(message)).position(); + else if (message.type() == DuiAppletMessage::MOUSE_RELEASE_MESSAGE) + mouseReleasePosition = (dynamic_cast(message)).position(); + else if (message.type() == DuiAppletMessage::MOUSE_MOVE_MESSAGE) + mouseMovePosition = (dynamic_cast(message)).position(); + break; + case DuiAppletMessage::OBJECT_MENU_REQUEST_MESSAGE: + contextMenuEventPos = (dynamic_cast(message)).pos(); + break; + case DuiAppletMessage::VISIBILITY_MESSAGE: + visibility = (dynamic_cast(message)).visible(); + break; + case DuiAppletMessage::OBJECT_MENU_ACTION_SELECTED_MESSAGE: + appletSpecificActionIndex = (dynamic_cast(message)).index(); + break; + default: + break; + } + + return true; +} + +// QLocalServer stubs +bool QLocalServer::listen(const QString &name) +{ + Q_UNUSED(name); + return true; +} + +bool QLocalServer::waitForNewConnection(int msec, bool *timedOut) +{ + Q_UNUSED(msec); + Q_UNUSED(timedOut); + return true; +} + +// QTimer stubs +bool timerCalled = false; + +void QTimer::stop() +{ + timerCalled = true; +} + +int elapsedQTime = 0; + +// QTime stubs +int QTime::elapsed() const +{ + return elapsedQTime; +} + +// QProcess stubs +bool gStartQProcess = true; +QString gQProcessProgram; +QStringList gQProcessArguments; +void QProcess::start(const QString &program, const QStringList &arguments, OpenMode) +{ + gQProcessProgram = program; + gQProcessArguments = arguments; + + if (gStartQProcess) { + emit started(); + } else { + emit error(QProcess::FailedToStart); + } +} + +Q_PID QProcess::pid() const +{ + if (gStartQProcess) { + return 100; + } else { + return 0; + } +} + +// DuiSettingsLanguageParser stubs +DuiSettingsLanguageBinary *DuiSettingsLanguageParser::createSettingsBinary() +{ + return new DuiSettingsLanguageBinary; +} + +// Unit test cases +void Ut_DuiAppletHandle::initTestCase() +{ + static int argc = 1; + static char *app_name[1] = { (char *) "./ut_duiapplethandle" }; + app = new DuiApplication(argc, app_name); + appWin = new DuiApplicationWindow; +} + +void Ut_DuiAppletHandle::cleanupTestCase() +{ + delete appWin; + // this is commented out for now, to prevent crash at exit: + // delete app; +} + +void Ut_DuiAppletHandle::init() +{ + mouseEventButtons = Qt::NoButton; + mouseEventButton = Qt::NoButton; + mousePressPosition = QPointF(); + mouseReleasePosition = QPointF(); + mouseMovePosition = QPointF(); + contextMenuEventPos = QPointF(); + appletSpecificActionIndex = 0; + visibility = true; + + handle = new DuiTestAppletHandle(); + handle->setViewType("default"); + connect(this, SIGNAL(connectionFromRunnerEstablished()), handle, SLOT(connectionEstablished())); + connect(this, SIGNAL(widgetVisibilityChanged(bool)), handle, SLOT(visibilityEvent(bool))); + connect(this, SIGNAL(applicationVisibilityChanged(bool)), handle, SLOT(applicationVisibilityChanged(bool))); + connect(this, SIGNAL(operationComplete(QString, QString, QString)), handle->privateClass(), SLOT(operationComplete(QString, QString, QString))); + connect(this, SIGNAL(operationProgress(QString, QString, int)), handle->privateClass(), SLOT(operationProgress(QString, QString, int))); + listenForConnection = true; + elapsedQTime = 0; + timerCalled = false; + + gStartQProcess = true; + + minSize = QSizeF(); + prefSize = QSizeF(); + maxSize = QSizeF(); + visibleSceneSize = QSize(1000, 1000); + gDuiAppletSharedMutexStub->stubReset(); + gDuiAppletSharedMutexStub->stubSetReturnValue("init", true); + gDuiAppletSharedMutexStub->stubSetReturnValue("lock", true); + gDuiAppletSharedMutexStub->stubSetReturnValue("unlock", true); + gDuiAppletSharedMutexStub->stubSetReturnValue("tryLock", true); + contextMenuOpened = false; + Ut_DuiAppletHandle::minSize = QSizeF(); + Ut_DuiAppletHandle::prefSize = QSizeF(); + Ut_DuiAppletHandle::maxSize = QSizeF(); + Ut_DuiAppletHandle::visibleSceneSize = QSize(1000, 1000); + appWin->scene()->addItem(handle); +} + +void Ut_DuiAppletHandle::cleanup() +{ + delete handle; +} + +void Ut_DuiAppletHandle::testInitializationWithCorrectData() +{ + // Use /bin/true as a runner binary that exists (should exist on every system) + QCOMPARE(handle->state(), DuiAppletHandleModel::STOPPED); + handle->init("/bin/true", "appletInstanceFileDataPath", "metaDataFileName", appletId); + emit connectionFromRunnerEstablished(); + QCOMPARE(handle->state(), DuiAppletHandleModel::RUNNING); + QCOMPARE(handle->property("pid").toInt(), 100); + + // Check that correct arguments were passed on to the runner + QCOMPARE(gQProcessProgram, QString("/bin/true")); + QCOMPARE(gQProcessArguments.count(), 4); + QCOMPARE(gQProcessArguments.at(0), appletId.toString()); + QCOMPARE(gQProcessArguments.at(1), QString("appletInstanceFileDataPath")); + QCOMPARE(gQProcessArguments.at(2), QString("metaDataFileName")); + QVERIFY(gQProcessArguments.at(3).length() > 0); + + // Check that shared mutex was created with a proper key + QVERIFY(!gDuiAppletSharedMutexStub->stubLastCallTo("init").parameter(0).isNull()); + + // Check that a pixmap mutex was created + QVERIFY(handle->model()->pixmapMutex() != NULL); + + // Check that no action is added when settings file is not defined + QCOMPARE(handle->actions().count(), 0); +} + +void Ut_DuiAppletHandle::testReinit() +{ + handle->init("/bin/true", "appletInstanceFileDataPath", "metaDataFileName", appletId); + emit connectionFromRunnerEstablished(); + + // Test killing + QRectF geom = handle->geometry(); + handle->kill(); + QVERIFY(handle->model()->pixmapMutex() == NULL); + QCOMPARE(handle->state(), DuiAppletHandleModel::STOPPED); + + // Check that a pixmap mutex was deleted + QVERIFY(handle->model()->pixmapMutex() == NULL); + + // Test reinit after killing. This will call kill() again. + handle->reinit(); + + emit connectionFromRunnerEstablished(); + QCOMPARE(handle->state(), DuiAppletHandleModel::RUNNING); + QCOMPARE(handle->geometry(), geom); + + QCOMPARE(handle->property("pid").toInt(), 100); + + // Check that shared mutex was created with a proper key + QVERIFY(!gDuiAppletSharedMutexStub->stubLastCallTo("init").parameter(0).isNull()); + + // Check that a pixmap mutex was created + QVERIFY(handle->model()->pixmapMutex() != NULL); + + // Test reinit after reinit. + handle->reinit(); + emit connectionFromRunnerEstablished(); + QCOMPARE(handle->state(), DuiAppletHandleModel::RUNNING); + QCOMPARE(handle->property("pid").toInt(), 100); +} + +void Ut_DuiAppletHandle::testAppletCommunicationFails() +{ + // cause the connection to the applet to fail, test that the state is correct + listenForConnection = false; + handle->init("/bin/true", "appletInstanceFileDataPath", "metaDataFileName", appletId); + QCOMPARE(handle->state(), DuiAppletHandleModel::BROKEN); + QCOMPARE(handle->property("pid").toInt(), 0); +} + +void Ut_DuiAppletHandle::testAppletMalfunction() +{ + // start a process which doesn't exit immediately + handle->init("/bin/sleep", "appletInstanceFileDataPath", "metaDataFileName", appletId); + emit connectionFromRunnerEstablished(); + QCOMPARE(handle->state(), DuiAppletHandleModel::RUNNING); + + // cause the response timer to timeout + handle->aliveMessageResponseTimeout(); + emit connectionFromRunnerEstablished(); + + // test that reinit has been called + QCOMPARE(handle->state(), DuiAppletHandleModel::RUNNING); + + // cause the response timer to timeout + handle->aliveMessageResponseTimeout(); + emit connectionFromRunnerEstablished(); + + // test that the applet is left in broken state + QCOMPARE(handle->state(), DuiAppletHandleModel::BROKEN); + + // test that the applet is left in broken state after it breaks immediately after restart + handle->reinit(); + handle->aliveMessageResponseTimeout(); + QCOMPARE(handle->state(), DuiAppletHandleModel::BROKEN); + + // test that the applet tries to reinit itself if broken after 30 seconds of startup + handle->reinit(); + emit connectionFromRunnerEstablished(); + elapsedQTime = 30000; + handle->aliveMessageResponseTimeout(); + emit connectionFromRunnerEstablished(); + QCOMPARE(handle->state(), DuiAppletHandleModel::RUNNING); +} + +void Ut_DuiAppletHandle::testAppletRunnerFailsToStart() +{ + gStartQProcess = false; + QCOMPARE(handle->state(), DuiAppletHandleModel::STOPPED); + handle->init("foobar", "appletInstanceFileDataPath", "metaDataFileName", appletId); + QCOMPARE(handle->state(), DuiAppletHandleModel::BROKEN); + QCOMPARE(handle->property("pid").toInt(), 0); +} + +void Ut_DuiAppletHandle::testScaling() +{ + // Get the available width + QSizeF maximumAppletSize(600, 400); + handle->modifiableStyle()->setMaximumAppletSize(maximumAppletSize); + + // Initialize an applethandle instance and cause a 1500x1000 minimum size hint response to be sent + // Expecting the scaling factor to be 1500 / screenWidth + handle->init("/bin/true", "appletInstanceFileDataPath", "metaDataFileName", appletId); + QVector sizeHints; + sizeHints << QSizeF(1500, 1000) << QSizeF(2500, 2000) << QSizeF(3500, 3000) << QSizeF(4500, 4000); + DuiAppletUpdateGeometryMessage message(sizeHints); + handle->messageReceivedFromRunner(message); + QCOMPARE(handle->model()->appletScale(), maximumAppletSize.width() / 1500.0f); + + // Expecting the scaling factor to be 1 + sizeHints.replace(Qt::MinimumSize, QSizeF(maximumAppletSize.width(), 10)); + message.setSizeHints(sizeHints); + handle->messageReceivedFromRunner(message); + QCOMPARE(handle->model()->appletScale(), qreal(1.0f)); + + // Expecting the scaling factor to be 1 + sizeHints.replace(Qt::MinimumSize, QSizeF(maximumAppletSize.width() * 0.5f, 10)); + message.setSizeHints(sizeHints); + QCOMPARE(handle->model()->appletScale(), qreal(1.0f)); +} + +void Ut_DuiAppletHandle::testMouseEventScaling() +{ + // Get the width of the screen + QSizeF maximumAppletSize(600, 400); + handle->modifiableStyle()->setMaximumAppletSize(maximumAppletSize); + + // Send mouse events to the applethandle and test that scaling works for them as well + QVector sizeHints; + sizeHints << QSizeF(1500, 1000) << QSizeF(2500, 2000) << QSizeF(3500, 3000) << QSizeF(4500, 4000); + DuiAppletUpdateGeometryMessage message(sizeHints); + handle->messageReceivedFromRunner(message); + QGraphicsSceneMouseEvent pressEvent(QEvent::GraphicsSceneMousePress); + pressEvent.setPos(QPointF(100, 50)); + handle->sendMouseEvent(pressEvent); + QCOMPARE(mousePressPosition, QPointF(100 * 1500 / maximumAppletSize.width(), 50 * 1500 / maximumAppletSize.width())); + + QGraphicsSceneMouseEvent releaseEvent(QEvent::GraphicsSceneMouseRelease); + releaseEvent.setPos(QPointF(100, 50)); + handle->sendMouseEvent(releaseEvent); + QCOMPARE(mouseReleasePosition, QPointF(100 * 1500 / maximumAppletSize.width(), 50 * 1500 / maximumAppletSize.width())); + + QGraphicsSceneMouseEvent moveEvent(QEvent::GraphicsSceneMouseMove); + moveEvent.setPos(QPointF(100, 50)); + handle->sendMouseEvent(moveEvent); + QCOMPARE(mouseMovePosition, QPointF(100 * 1500 / maximumAppletSize.width(), 50 * 1500 / maximumAppletSize.width())); +} + +void Ut_DuiAppletHandle::testAppletCommunication() +{ + handle->setAliveResponseTimeout(0); + handle->init("/bin/true", "appletInstanceFileDataPath", "metaDataFileName", appletId); + DuiAppletAliveMessageResponse message; + handle->messageReceivedFromRunner(message); + QCOMPARE(timerCalled, true); +} + +void Ut_DuiAppletHandle::testRelayingMousePress() +{ + handle->init("/bin/true", "appletInstanceFileDataPath", "metaDataFileName", appletId); + + QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMousePress); + event.setPos(QPointF(-3, 4)); + event.setButtons(Qt::LeftButton | Qt::RightButton); + event.setButton(Qt::LeftButton); + + handle->sendMouseEvent(event); + + QCOMPARE(mousePressPosition, QPointF(-3, 4)); + QCOMPARE(mouseEventButtons, Qt::LeftButton | Qt::RightButton); + QCOMPARE(mouseEventButton, Qt::LeftButton); +} + +void Ut_DuiAppletHandle::testRelayingMouseRelease() +{ + handle->init("/bin/true", "appletInstanceFileDataPath", "metaDataFileName", appletId); + + QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMouseRelease); + event.setPos(QPointF(-3, 4)); + event.setButtons(Qt::MidButton | Qt::RightButton); + event.setButton(Qt::MidButton); + + handle->sendMouseEvent(event); + + QCOMPARE(mouseReleasePosition, QPointF(-3, 4)); + QCOMPARE(mouseEventButtons, Qt::MidButton | Qt::RightButton); + QCOMPARE(mouseEventButton, Qt::MidButton); +} + +void Ut_DuiAppletHandle::testRelayingMouseMove() +{ + handle->init("/bin/true", "appletInstanceFileDataPath", "metaDataFileName", appletId); + + QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMouseMove); + event.setPos(QPointF(-3, 4)); + event.setButtons(Qt::RightButton); + event.setButton(Qt::RightButton); + + handle->sendMouseEvent(event); + + QCOMPARE(mouseMovePosition, QPointF(-3, 4)); + QCOMPARE(mouseEventButtons, Qt::RightButton); + QCOMPARE(mouseEventButton, Qt::RightButton); +} + +void Ut_DuiAppletHandle::testThatAppletBreaksIfConnectionIsNotEstablished() +{ + // Initialize applet handle + handle->init("/bin/true", "appletInstanceFileDataPath", "metaDataFileName", appletId); + QCOMPARE(handle->state(), DuiAppletHandleModel::STARTING); + + // Let connection time out + handle->connectionTimeout(); + + // Verify that applet tries to restart itself + QCOMPARE(handle->state(), DuiAppletHandleModel::STARTING); + + // Connection times out again + handle->connectionTimeout(); + + // Verify that the applet is broken + QCOMPARE(handle->state(), DuiAppletHandleModel::BROKEN); +} + +void Ut_DuiAppletHandle::testVisibility() +{ + // Visibility should be true only if both the widget and the application are visible + emit widgetVisibilityChanged(false); + QVERIFY(!visibility); + handle->exitDisplayEvent(); + QVERIFY(!visibility); + emit widgetVisibilityChanged(true); + QVERIFY(!visibility); + handle->enterDisplayEvent(); + QVERIFY(visibility); +} + +// Returns true if the list of actions contains an item with the specified text +bool actionsContains(const QList& actions, const QString &text) +{ + bool returnValue = false; + + foreach(QAction * action, actions) { + if (action->text() == text) { + returnValue = true; + break; + } + } + + return returnValue; +} + +void Ut_DuiAppletHandle::testSettingAppletSpecificActions() +{ + handle->init("/bin/true", "appletInstanceFileDataPath", "metaDataFileName", appletId); + + // Add one action + handle->setAppletSpecificActions(QStringList() << "action1"); + QList actions = handle->actions(); + QCOMPARE(actionsContains(actions, "action1"), true); + + // Add another action. This should replace the previous action + handle->setAppletSpecificActions(QStringList() << "action2"); + actions = handle->actions(); + QCOMPARE(actionsContains(actions, "action1"), false); + QCOMPARE(actionsContains(actions, "action2"), true); + + // Make the actions list empty + handle->setAppletSpecificActions(); + actions = handle->actions(); + QCOMPARE(actionsContains(actions, "action1"), false); + QCOMPARE(actionsContains(actions, "action2"), false); +} + +void Ut_DuiAppletHandle::testAppletSpecificActionsInBrokenState() +{ + handle->init("/bin/true", "appletInstanceFileDataPath", "metaDataFileName", appletId); + + // Add one action + handle->setAppletSpecificActions(QStringList() << "action1"); + + // Put the applet to broken state by time outting the connection twice + handle->connectionTimeout(); + handle->connectionTimeout(); + + // Check that there is no more an applet specific action + QCOMPARE(actionsContains(handle->actions(), "action1"), false); +} + +void Ut_DuiAppletHandle::testContextMenuTrigger() +{ + handle->init("/bin/true", "appletInstanceFileDataPath", "metaDataFileName", appletId); + + QGraphicsSceneContextMenuEvent event(QEvent::ContextMenu); + event.setPos(QPoint(-3, 4)); + + // Opening a content menu in any other state than RUNNING should use the base class functionality + handle->sendContextMenuEvent(&event); + QVERIFY(contextMenuOpened); + + // Opening a context menu in the RUNNING state should ask the actions from the applet + contextMenuOpened = false; + emit connectionFromRunnerEstablished(); + handle->sendContextMenuEvent(&event); + QCOMPARE(contextMenuEventPos, QPointF(-3, 4)); + QVERIFY(!contextMenuOpened); +} + +void Ut_DuiAppletHandle::testObjectMenuMessage() +{ + handle->init("/bin/true", "appletInstanceFileDataPath", "metaDataFileName", appletId); + + QList actions; + QAction action(this); + action.setText("action"); + actions.append(&action); + + DuiAppletObjectMenuMessage message(actions); + + handle->messageReceivedFromRunner(message); + + actions = handle->actions(); + QCOMPARE(actions.at(0)->text(), QString("action")); +} + +void Ut_DuiAppletHandle::testAppletSpecificActionTriggered() +{ + handle->init("/bin/true", "appletInstanceFileDataPath", "metaDataFileName", appletId); + + // Add two actions + handle->setAppletSpecificActions(QStringList() << "action1" << "action2"); + + // Find the newly added actions + QAction *action1 = NULL, *action2 = NULL; + foreach(QAction * a, handle->actions()) { + if (a->text() == "action1") { + action1 = a; + } else if (a->text() == "action2") { + action2 = a; + } + } + + appletSpecificActionIndex = 100; + action1->trigger(); + QCOMPARE(appletSpecificActionIndex, (uint)0); + action2->trigger(); + QCOMPARE(appletSpecificActionIndex, (uint)1); +} + +void Ut_DuiAppletHandle::testPlaceHolderInitialization() +{ + handle->initPlaceHolder(appletId, "package.deb"); + QCOMPARE(handle->state(), DuiAppletHandleModel::INSTALLING); + QCOMPARE(handle->model()->packageName(), QString("package.deb")); +} + +void Ut_DuiAppletHandle::testPlaceHolderInitializationWithError() +{ + handle->initPlaceHolder(appletId, "package.deb", "error"); + QCOMPARE(handle->state(), DuiAppletHandleModel::BROKEN); + QCOMPARE(handle->model()->installationError(), QString("error")); +} + +void Ut_DuiAppletHandle::testInstallationOperationCompleteWithError() +{ + handle->initPlaceHolder(appletId, "package.deb"); + handle->privateClass()->processStartTime = QTime::currentTime(); + handle->privateClass()->restartCount = 1; + emit operationComplete("Install", handle->model()->packageName(), "com.nokia.package_manager.Error.InvalidPackage"); + + // Verify that applet is broken + QCOMPARE(handle->state(), DuiAppletHandleModel::BROKEN); +} + +void Ut_DuiAppletHandle::testAppletInstallationProgess() +{ + handle->initPlaceHolder(appletId, "package.deb"); + emit operationProgress("Install", handle->model()->packageName(), 15); + + // Verify that progress is updated in the model + QCOMPARE(handle->model()->installationProgress(), 15); +} + +void Ut_DuiAppletHandle::testAppletIconMessageReceived() +{ + QSignalSpy spy(handle, SIGNAL(appletIconChanged(QString))); + DuiAppletIconChangedMessage message; + message.setIcon("test-icon"); + handle->messageReceivedFromRunner(message); + QCOMPARE(handle->appletIcon(), QString("test-icon")); + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.at(0).count(), 1); + QCOMPARE(spy.at(0).at(0), QVariant("test-icon")); +} + +void Ut_DuiAppletHandle::testAppletTitleMessageReceived() +{ + QSignalSpy spy(handle, SIGNAL(appletTitleChanged(QString))); + DuiAppletTitleChangedMessage message; + message.setTitle("test-title"); + handle->messageReceivedFromRunner(message); + QCOMPARE(handle->appletTitle(), QString("test-title")); + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.at(0).count(), 1); + QCOMPARE(spy.at(0).at(0), QVariant("test-title")); +} + +void Ut_DuiAppletHandle::testAppletTextMessageReceived() +{ + QSignalSpy spy(handle, SIGNAL(appletTextChanged(QString))); + DuiAppletTextChangedMessage message; + message.setText("test-text"); + handle->messageReceivedFromRunner(message); + QCOMPARE(handle->appletText(), QString("test-text")); + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.at(0).count(), 1); + QCOMPARE(spy.at(0).at(0), QVariant("test-text")); +} + +void Ut_DuiAppletHandle::testSetSizeHints() +{ + QVector sizeHints; + sizeHints.append(QSizeF(10, 40)); + sizeHints.append(QSizeF(20, 30)); + sizeHints.append(QSizeF(30, 20)); + sizeHints.append(QSizeF(40, 10)); + handle->setSizeHints(sizeHints); + QCOMPARE(handle->model()->sizeHints(), sizeHints); +} + +QTEST_APPLESS_MAIN(Ut_DuiAppletHandle) diff --git a/tests/ut_duiapplethandle/ut_duiapplethandle.h b/tests/ut_duiapplethandle/ut_duiapplethandle.h new file mode 100644 index 000000000..7f64b6b2c --- /dev/null +++ b/tests/ut_duiapplethandle/ut_duiapplethandle.h @@ -0,0 +1,125 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIAPPLETHANDLE +#define UT_DUIAPPLETHANDLE + +#include +#include "duiapplethandle.h" +#include "duiapplethandle_p.h" +#include "duiapplethandlestyle.h" +class DuiSettingsLanguageBinary; + +class DuiTestAppletHandlePrivate : public DuiAppletHandlePrivate +{ +}; + +class DuiTestAppletHandle : public DuiAppletHandle +{ + Q_DECLARE_PRIVATE(DuiTestAppletHandle) + +public: + DuiTestAppletHandle(); + void sendMouseEvent(QGraphicsSceneMouseEvent &event); + void messageReceivedFromRunner(const DuiAppletMessage &message); + void aliveMessageResponseTimeout(); + void connectionTimeout(); + void sendContextMenuEvent(QGraphicsSceneContextMenuEvent *event); + DuiTestAppletHandlePrivate *privateClass(); + + DuiAppletHandleStyle *modifiableStyle() { + DuiAppletHandleStyleContainer &sc = dynamic_cast(style()); + const DuiAppletHandleStyle *const_s = sc.operator ->(); + DuiAppletHandleStyle *s = const_cast(const_s); + return s; + } +}; + +// Test case must inherit QObject +class Ut_DuiAppletHandle : public QObject +{ + Q_OBJECT + +private: + //! AppletHandle instance under testing. + DuiTestAppletHandle *handle; + //! Applet Id of the applet + DuiAppletId appletId; + +public: + //! Indicates whether communication server listens to incoming connections or not. + static bool listenForConnection; + + //! Minimum size hint response + static QSizeF minSize; + //! Preferred size hint response + static QSizeF prefSize; + //! Maximum size hint response + static QSizeF maxSize; + //! The visible scene size returned by DuiSceneManager + static QSize visibleSceneSize; + + //! Whether the shared memory is attached or not + static bool sharedMemoryAttached; + //! Whether the DuiWidget::contextMenuEvent() has been called + static bool contextMenuOpened; + +private slots: + void initTestCase(); + void cleanupTestCase(); + + void init(); + void cleanup(); + + void testInitializationWithCorrectData(); + void testReinit(); + void testAppletCommunicationFails(); + void testAppletMalfunction(); + void testAppletRunnerFailsToStart(); + void testScaling(); + void testMouseEventScaling(); + void testAppletCommunication(); + void testRelayingMousePress(); + void testRelayingMouseRelease(); + void testRelayingMouseMove(); + void testThatAppletBreaksIfConnectionIsNotEstablished(); + void testVisibility(); + void testSettingAppletSpecificActions(); + void testAppletSpecificActionsInBrokenState(); + void testContextMenuTrigger(); + void testObjectMenuMessage(); + void testAppletSpecificActionTriggered(); + void testPlaceHolderInitialization(); + void testPlaceHolderInitializationWithError(); + void testInstallationOperationCompleteWithError(); + void testAppletInstallationProgess(); + void testAppletIconMessageReceived(); + void testAppletTitleMessageReceived(); + void testAppletTextMessageReceived(); + void testSetSizeHints(); + +signals: + void messageReceived(const DuiAppletMessage &message); + void connectionFromRunnerEstablished(); + void widgetVisibilityChanged(bool visible); + void applicationVisibilityChanged(bool visible); + void operationComplete(const QString &operation, const QString &pkg, const QString &error); + void operationProgress(const QString &operation, const QString &pkg, int); +}; +#endif // UT_DUIAPPLETHANDLE diff --git a/tests/ut_duiapplethandle/ut_duiapplethandle.pro b/tests/ut_duiapplethandle/ut_duiapplethandle.pro new file mode 100644 index 000000000..b672e8f75 --- /dev/null +++ b/tests/ut_duiapplethandle/ut_duiapplethandle.pro @@ -0,0 +1,50 @@ +include(../common_top.pri) + +TARGET = ut_duiapplethandle +INCLUDEPATH += $$DUISRCDIR/mashup/mashup \ + $$DUISRCDIR/mashup/appletcommunication \ + $$DUISRCDIR/widgets \ + $$DUISRCDIR/style +QT += xml + +win32 { + QMAKE_MOC = perl $${IN_PWD}\..\..\duimoc\duimoc +} else { + PRE_TARGETDEPS += ../../duigen/duigen + QMAKE_MOC = PATH=../../duigen:$$(PATH) $${IN_PWD}/../../duimoc/duimoc +} + +DUIGEN_OUTDIR = . +duigenerator_model.name = duigenerator model +duigenerator_model.input = MODEL_HEADERS +duigenerator_model.depends = ../../duigen/duigen +duigenerator_model.output = $$DUIGEN_OUTDIR/gen_${QMAKE_FILE_BASE}data.cpp +duigenerator_model.commands += ../../duigen/duigen --model ${QMAKE_FILE_NAME} $$DUIGEN_OUTDIR +duigenerator_model.clean += $$DUIGEN_OUTDIR/gen_* +duigenerator_model.CONFIG = target_predeps no_link +duigenerator_model.variable_out = GENERATED_SOURCES +QMAKE_EXTRA_COMPILERS += duigenerator_model + +MODEL_HEADERS += $$DUISRCDIR/widgets/duiwidgetmodel.h \ + $$DUISRCDIR/mashup/mashup/duiapplethandlemodel.h + +SOURCES += ut_duiapplethandle.cpp \ + $$DUISRCDIR/mashup/mashup/duiapplethandle.cpp \ + $$DUISRCDIR/widgets/core/duiwidgetcontroller.cpp \ + $$DUISRCDIR/widgets/duiwidgetmodel.cpp + +# service classes +SOURCES += \ + $$STUBSDIR/stubbase.cpp \ + +HEADERS += ut_duiapplethandle.h \ + $$DUISRCDIR/mashup/mashup/duiapplethandle.h \ + $$DUISRCDIR/mashup/mashup/duiapplethandle_p.h \ + $$DUISRCDIR/mashup/mashup/duiapplethandlemodel.h \ + $$DUISRCDIR/widgets/core/duiwidgetcontroller_p.h \ + $$DUISRCDIR/widgets/core/duiwidget_p.h \ + $$DUISRCDIR/widgets/duiwidgetmodel_p.h \ + $$DUISRCDIR/widgets/duiscenewindow_p.h \ + $$DUISRCDIR/widgets/duiobjectmenu.h + +include(../common_bot.pri) diff --git a/tests/ut_duiapplethandleglesview/.gitignore b/tests/ut_duiapplethandleglesview/.gitignore new file mode 100644 index 000000000..5ab13f33f --- /dev/null +++ b/tests/ut_duiapplethandleglesview/.gitignore @@ -0,0 +1 @@ +ut_duiapplethandleglesview diff --git a/tests/ut_duiapplethandleglesview/ut_duiapplethandleglesview.cpp b/tests/ut_duiapplethandleglesview/ut_duiapplethandleglesview.cpp new file mode 100644 index 000000000..0b5abdf12 --- /dev/null +++ b/tests/ut_duiapplethandleglesview/ut_duiapplethandleglesview.cpp @@ -0,0 +1,256 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include +#include "ut_duiapplethandleglesview.h" +#include +#include +#include +#include + +DuiApplication *app; + +// QPainter stubs +bool pixmapDrawn; + +void QPainter::drawPixmap(const QRectF &targetRect, const QPixmap &pixmap, const QRectF &sourceRect) +{ + Q_UNUSED(targetRect) + Q_UNUSED(pixmap) + Q_UNUSED(sourceRect) + + pixmapDrawn = true; +} + +// QGLWidget stubs +bool textureDeleted = false; + +void QGLWidget::deleteTexture(GLuint) +{ + textureDeleted = true; +} + +GLuint QGLWidget::bindTexture(const QPixmap &, GLenum, GLint) +{ + return 1; +} + + +// QGLFramebufferObject stubs +class QGLFramebufferObjectPrivate +{ +}; + +QGLFramebufferObject::QGLFramebufferObject(const QSize &, GLenum) +{ +} + +QGLFramebufferObject::~QGLFramebufferObject() +{ +} + +bool QGLFramebufferObject::bind() +{ + return false; +} + +QSize QGLFramebufferObject::size() const +{ + return QSize(); +} + +QImage QGLFramebufferObject::toImage() const +{ + return QImage(); +} + +bool QGLFramebufferObject::release() +{ + return false; +} + +// DuiAppletHandleViewPrivate stubs +bool appletHandleViewPixmapsDestroyed = false; + +void DuiAppletHandleViewPrivate::destroyPixmaps() +{ + appletHandleViewPixmapsDestroyed = true; +} + +// DuiGLRenderer stubs +QGLWidget *DuiGLRenderer::viewport() +{ + static QGLWidget glWidget; + + return &glWidget; +} + +bool glTextureDrawn; +QSizeF glTextureSize; + +void DuiGLRenderer::drawTexture(const QString &, const QTransform &, quint32, + const QSizeF &size, IDuiGLUniformProvider *, + bool) +{ + glTextureDrawn = true; + glTextureSize = size; +} + +// DuiGLShaderUniform stubs +DuiGLShaderUniform::DuiGLShaderUniform() : d_ptr(0) {} +DuiGLShaderUniform::~DuiGLShaderUniform() {} + +float uniformValue = 0; + +const DuiGLShaderUniform &DuiGLShaderUniform::operator=(const float &v) const +{ + uniformValue = v; + + return *this; +} + +// DuiWidgetController stubs +void DuiWidgetController::setGeometry(const QRectF &) +{ +} + +// DuiWidgetView stubs +DuiWidgetView::~DuiWidgetView() +{ +} + +void DuiWidgetView::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + Q_UNUSED(widget); + drawContents(painter, option); +} + +void DuiWidgetView::update(const QRectF &) +{ + QPainter p; + drawContents(&p, NULL); +} + +// A test applet view implementation +DuiTestAppletHandleGLESView::DuiTestAppletHandleGLESView(DuiAppletHandle *handle) : + DuiAppletHandleGLESView(handle) +{ +} + +// Unit test cases +void Ut_DuiAppletHandleGLESView::initTestCase() +{ + int argc = 1; + char *app_name = (char *) "./ut_duiapplethandleglesview"; + app = new DuiApplication(argc, &app_name); +} + + +void Ut_DuiAppletHandleGLESView::cleanupTestCase() +{ + delete app; +} + +void Ut_DuiAppletHandleGLESView::init() +{ + handle = new DuiAppletHandle(); + handleView = new DuiTestAppletHandleGLESView(handle); + + glTextureDrawn = false; + pixmapDrawn = false; + uniformValue = 0; + glTextureSize = QSizeF(); + appletHandleViewPixmapsDestroyed = false; + textureDeleted = false; +} + +void Ut_DuiAppletHandleGLESView::cleanup() +{ + delete handleView; + delete handle; +} + +void Ut_DuiAppletHandleGLESView::testBrokenAppletDrawing() +{ + DuiAppletHandleModel model; + handleView->setModel(&model); + + // set the geometry, so a pixmap is created for the view + handleView->setGeometry(QRectF(0, 0, 10, 10)); + QMetaObject::invokeMethod(handleView, "pixmapTakenIntoUse", Qt::DirectConnection, Q_ARG(Qt::HANDLE, 0)); + model.setState(DuiAppletHandleModel::BROKEN); + QVERIFY(glTextureDrawn); + QVERIFY(pixmapDrawn); + QCOMPARE(glTextureSize, QSizeF(10, 10)); +} + +void Ut_DuiAppletHandleGLESView::testPixmapAndTextureCleanup() +{ + DuiAppletHandleModel model; + handleView->setModel(&model); + + // set the geometry, so a pixmap and broken view texture is created for the view + handleView->setGeometry(QRectF(0, 0, 10, 10)); + QMetaObject::invokeMethod(handleView, "pixmapTakenIntoUse", Qt::DirectConnection, Q_ARG(Qt::HANDLE, 0)); + model.setState(DuiAppletHandleModel::BROKEN); + // test that the old textures and pixmaps of the base class are destroyed when state is changed to running + model.setState(DuiAppletHandleModel::RUNNING); + // The destruction of the base class pixmaps can only be verified if DUI_EXPORT is used +// QVERIFY(appletHandleViewPixmapsDestroyed); + QVERIFY(textureDeleted); +} + +void Ut_DuiAppletHandleGLESView::testUniforms() +{ + DuiGLShaderUniform u; + DuiAppletHandleViewUniformProvider upm1(-1.0f, -1.0f); + uniformValue = 0; + upm1.setUniformValue("width", u); + QCOMPARE(uniformValue, 1.0f); + uniformValue = 0; + upm1.setUniformValue("height", u); + QCOMPARE(uniformValue, 1.0f); + DuiAppletHandleViewUniformProvider up0(0.0f, 0.0f); + uniformValue = 0; + up0.setUniformValue("width", u); + QCOMPARE(uniformValue, 1.0f); + uniformValue = 0; + up0.setUniformValue("height", u); + QCOMPARE(uniformValue, 1.0f); + DuiAppletHandleViewUniformProvider up1(1.0f, 1.0f); + uniformValue = 0; + up1.setUniformValue("width", u); + QCOMPARE(uniformValue, 1.0f); + uniformValue = 0; + up1.setUniformValue("height", u); + QCOMPARE(uniformValue, 1.0f); + DuiAppletHandleViewUniformProvider up2(10.0f, 10.0f); + uniformValue = 0; + up2.setUniformValue("width", u); + QCOMPARE(uniformValue, 0.1f); + uniformValue = 0; + up2.setUniformValue("height", u); + QCOMPARE(uniformValue, 0.1f); +} + + +QTEST_APPLESS_MAIN(Ut_DuiAppletHandleGLESView) + diff --git a/tests/ut_duiapplethandleglesview/ut_duiapplethandleglesview.h b/tests/ut_duiapplethandleglesview/ut_duiapplethandleglesview.h new file mode 100644 index 000000000..83bdebd26 --- /dev/null +++ b/tests/ut_duiapplethandleglesview/ut_duiapplethandleglesview.h @@ -0,0 +1,59 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIAPPLETHANDLEGLESVIEW +#define UT_DUIAPPLETHANDLEGLESVIEW + +#include +#include "duiapplethandleglesview.h" + +class DuiTestAppletHandleGLESView : public DuiAppletHandleGLESView +{ + Q_OBJECT + + DUI_VIEW(DuiAppletHandleModel, DuiAppletHandleStyle) +public: + DuiTestAppletHandleGLESView(DuiAppletHandle *handle); +}; + + +// Test case must inherit QObject +class Ut_DuiAppletHandleGLESView : public QObject +{ + Q_OBJECT + +public: + +private: + //! DuiAppletHandleGLESView instance under testing. + DuiTestAppletHandleGLESView *handleView; + DuiAppletHandle *handle; + +private slots: + void initTestCase(); + void cleanupTestCase(); + + void init(); + void cleanup(); + + void testBrokenAppletDrawing(); + void testPixmapAndTextureCleanup(); + void testUniforms(); +}; +#endif // UT_DUIAPPLETHANDLEGLESVIEW diff --git a/tests/ut_duiapplethandleglesview/ut_duiapplethandleglesview.pro b/tests/ut_duiapplethandleglesview/ut_duiapplethandleglesview.pro new file mode 100644 index 000000000..c70db9855 --- /dev/null +++ b/tests/ut_duiapplethandleglesview/ut_duiapplethandleglesview.pro @@ -0,0 +1,15 @@ +include(../common_top.pri) + +TARGET = ut_duiapplethandleglesview +INCLUDEPATH += $$DUISRCDIR/mashup/mashup \ + $$DUISRCDIR/mashup/appletcommunication \ + $$DUISRCDIR/style + +QT += network opengl + +SOURCES += ut_duiapplethandleglesview.cpp \ + ../stubs/stubbase.cpp + +HEADERS += ut_duiapplethandleglesview.h + +include(../common_bot.pri) diff --git a/tests/ut_duiapplethandleview/.gitignore b/tests/ut_duiapplethandleview/.gitignore new file mode 100644 index 000000000..daaf4a657 --- /dev/null +++ b/tests/ut_duiapplethandleview/.gitignore @@ -0,0 +1 @@ +ut_duiapplethandleview diff --git a/tests/ut_duiapplethandleview/ut_duiapplethandleview.cpp b/tests/ut_duiapplethandleview/ut_duiapplethandleview.cpp new file mode 100644 index 000000000..21333cf0c --- /dev/null +++ b/tests/ut_duiapplethandleview/ut_duiapplethandleview.cpp @@ -0,0 +1,558 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duiapplethandleview.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "duimessagebox.h" +#include "duisettingslanguagebinary.h" +#include "duisettingslanguagewidgetfactory.h" +#include "duisettingslanguagewidget.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include "duiclassfactory.h" +#include "duiwidgetview_p.h" +#include +#include + +class DuiApplicationWindow; + +DuiApplication *app; +int Ut_DuiAppletHandleView::returnedPixmapWidth; +int Ut_DuiAppletHandleView::returnedPixmapHeight; +QRectF Ut_DuiAppletHandleView::updatedRect; +QRectF Ut_DuiAppletHandleView::drawnTargetRect; +QRectF Ut_DuiAppletHandleView::drawnSourceRect; + +QPointF mousePressPosition; +QPointF mouseReleasePosition; +QPointF mouseMovePosition; + +// DuiClassFactory stubs +void DuiClassFactory::registerViewCreator(DuiViewCreatorBase *, const char *) +{ +} + +void DuiClassFactory::unregisterViewCreator(DuiViewCreatorBase *) +{ +} + +// DuiWidgetViewPrivate stubs +DuiWidgetViewPrivate::DuiWidgetViewPrivate() : + controller(NULL), + model(NULL), + styleContainer(NULL), + showAnimation(NULL), + hideAnimation(NULL) +{ +} + +DuiWidgetViewPrivate::~DuiWidgetViewPrivate() +{ +} + +void DuiWidgetViewPrivate::orientationChanged() +{ + // notify views that the style has changed + q_ptr->applyStyle(); +} + +// QGraphicsItem stubs (Used by DuiAppletHandleView) +void QGraphicsItem::update(const QRectF &rect) +{ + Ut_DuiAppletHandleView::updatedRect = rect; +} + +// QThread stubs (used by DuiImageLoader) +void QThread::start(QThread::Priority) +{ +} + +// QPixmap stubs (used by AppletHandle) +bool QPixmap::isNull() const +{ + return false; +} + +int QPixmap::width() const +{ + return Ut_DuiAppletHandleView::returnedPixmapWidth; +} + +int QPixmap::height() const +{ + return Ut_DuiAppletHandleView::returnedPixmapHeight; +} + +void QPainter::drawPixmap(const QRectF &targetRect, const QPixmap &, const QRectF &sourceRect) +{ + Ut_DuiAppletHandleView::drawnTargetRect = targetRect; + Ut_DuiAppletHandleView::drawnSourceRect = sourceRect; +} + +#ifdef Q_WS_X11 +Qt::HANDLE QPixmap::handle() const +{ + return 0; +} +#endif + +// DuiStyleContainer stubs +DuiAppletHandleStyleContainer handleStyleContainer; +DuiAppletHandleStyle *handleStyle = 0; +const DuiStyle *DuiStyleContainer::currentStyle() const +{ + return handleStyle; +} + +// DuiWidgetView stubs +DuiAppletHandleModel handleModel; +DuiWidgetModel *DuiWidgetView::model() +{ + return &handleModel; +} + +const DuiWidgetModel *DuiWidgetView::model() const +{ + return &handleModel; +} + +DuiWidgetStyleContainer &DuiWidgetView::style() +{ + return handleStyleContainer; +} + +const DuiWidgetStyleContainer &DuiWidgetView::style() const +{ + return handleStyleContainer; +} + +DuiWidgetView::~DuiWidgetView() +{ +} + +void DuiWidgetView::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + Q_UNUSED(widget); + drawContents(painter, option); +} + +// DuiProgressIndicator stubs +bool progressIndicatorRunning = false; + +void DuiProgressIndicator::setUnknownDuration(bool run) +{ + if (DuiProgressIndicator::viewType() != DuiProgressIndicator::barType) { + progressIndicatorRunning = run; + } else { + progressIndicatorRunning = (!run); + } +} + +bool progressIndicatorVisible = false; + +// QGraphicsItem stubs +void QGraphicsItem::setVisible(bool visible) +{ + if (dynamic_cast(this)) { + progressIndicatorVisible = visible; + } +} + +// DuiSceneManager stubs +bool dialogShown = false; +int DuiSceneManager::execDialog(DuiDialog *) +{ + dialogShown = true; + return 1; +} + +void QGraphicsLinearLayout::insertItem(int , QGraphicsLayoutItem *) +{ +} + + +// DuiDialog stubs +int dialogClickedButtonIndex = 0; +QList dialogButtons; + +void DuiDialogModel::addButton(DuiButtonModel *buttonModel) +{ + dialogButtons.append(buttonModel); +} + +DuiButtonModel *DuiDialog::clickedButton() const +{ + if (dialogClickedButtonIndex >= 0) + return dialogButtons.at(dialogClickedButtonIndex); + else + return NULL; +} + +// DuiWidgetController stubs +void DuiWidgetController::setGeometry(const QRectF &) +{ +} + +// A test applet handle implementation to allow mouse event sending +DuiTestAppletHandleView::DuiTestAppletHandleView(DuiAppletHandle *handle) : + DuiAppletHandleView(handle) +{ +} + +void DuiTestAppletHandleView::click() +{ + QGraphicsSceneMouseEvent event; + event.setButton(Qt::LeftButton); + mouseReleaseEvent(&event); +} + +QSizeF DuiTestAppletHandleView::askSizeHints(Qt::SizeHint which, QSizeF &constraint) +{ + return sizeHint(which, constraint); +} + +void DuiTestAppletHandleView::appletPixmapModified(const QRectF &rect) +{ + DuiAppletHandleView::appletPixmapModified(rect); +} + +// QTimer stubs +bool timerCalled = false; + +void QTimer::stop() +{ + timerCalled = true; +} + +// DuiSettingsLanguageWidgetFactory stubs +DuiSettingsLanguageWidget *DuiSettingsLanguageWidgetFactory::createWidget(const DuiSettingsLanguageBinary &, DuiDataStore *) +{ + return new DuiSettingsLanguageWidget; +} + +// DuiAppletSettingsDialog stubs +bool gDuiAppletSettingsDialogExecCalled = false; +void DuiAppletSettingsDialog::exec() const +{ + gDuiAppletSettingsDialogExecCalled = true; +} + +// Unit test cases +void Ut_DuiAppletHandleView::initTestCase() +{ + static int argc = 1; + static char *app_name[1] = { (char *) "./ut_duiapplethandleview" }; + app = new DuiApplication(argc, app_name); +} + + +void Ut_DuiAppletHandleView::cleanupTestCase() +{ + delete app; +} + +void Ut_DuiAppletHandleView::init() +{ + handle = new DuiAppletHandle(); + handleView = new DuiTestAppletHandleView(handle); + handleStyle = new DuiAppletHandleStyle(); + + updatedRect = QRectF(); + drawnTargetRect = QRectF(); + drawnSourceRect = QRectF(); + progressIndicatorRunning = false; + dialogShown = false; + dialogButtons.clear(); + dialogClickedButtonIndex = 0; + gDuiAppletSettingsDialogExecCalled = false; + progressIndicatorVisible = false; + returnedPixmapWidth = 0; + returnedPixmapHeight = 0; + + gDuiAppletHandleStub->stubReset(); + gDuiAppletSharedMutexStub->stubReset(); + gDuiAppletSharedMutexStub->stubSetReturnValue("lock", true); + gDuiAppletSharedMutexStub->stubSetReturnValue("unlock", true); + gDuiAppletSharedMutexStub->stubSetReturnValue("tryLock", true); + handleStyle->setMaximumAppletSize(QSizeF(1000, 1000)); +} + +void Ut_DuiAppletHandleView::cleanup() +{ + delete handleView; + delete handle; +} + +void Ut_DuiAppletHandleView::testScaling_data() +{ + QTest::addColumn("maximumAppletSize"); + QTest::addColumn("minimumSizeHint"); + QTest::addColumn("setGeometry"); + QTest::addColumn("appletGeometry"); + QTest::addColumn("boundingRect"); + + QTest::newRow("Size OK") << QSizeF(500, 300) << QSizeF(250, 150) << QRectF(0, 0, 250, 150) << QRectF(0, 0, 250, 150) << QRectF(0, 0, 250, 150); + QTest::newRow("Minimum size over") << QSizeF(500, 300) << QSizeF(1000, 600) << QRectF(0, 0, 500, 300) << QRectF(0, 0, 1000, 600) << QRectF(0, 0, 500, 300); +} + +void Ut_DuiAppletHandleView::testScaling() +{ + QFETCH(QSizeF, maximumAppletSize); + QFETCH(QSizeF, minimumSizeHint); + QFETCH(QRectF, setGeometry); + QFETCH(QRectF, appletGeometry); + QFETCH(QRectF, boundingRect); + + // Reset the state to a known state for testing make sure there is no pixmap to be taken into use. + handleView->setGeometry(QRectF(0, 0, 1, 1)); + handleView->setGeometry(QRectF(0, 0, 2, 2)); + QMetaObject::invokeMethod(handleView, "pixmapTakenIntoUse", Qt::DirectConnection, Q_ARG(Qt::HANDLE, 0)); + QMetaObject::invokeMethod(handleView, "pixmapTakenIntoUse", Qt::DirectConnection, Q_ARG(Qt::HANDLE, 0)); + + // Test size hints returned when applet size is smaller than minimum size of applet defined in style + handleStyle->setMaximumAppletSize(maximumAppletSize); + QVector sizeHints; + sizeHints.append(minimumSizeHint); + sizeHints.append(QSizeF(20, 20)); + sizeHints.append(QSizeF(800, 800)); + sizeHints.append(QSizeF(800, 800)); + handleModel.setSizeHints(sizeHints); + + // The pixmap size sent to the applet should be scaled + handleView->setGeometry(setGeometry); + QCOMPARE(gDuiAppletHandleStub->stubLastCallTo("sendGeometryMessage").parameter(0), appletGeometry); + + // When the pixmap has been taken into use the bounding rect should be the pixmap size scaled + returnedPixmapWidth = appletGeometry.width(); + returnedPixmapHeight = appletGeometry.height(); + QMetaObject::invokeMethod(handleView, "pixmapTakenIntoUse", Qt::DirectConnection, Q_ARG(Qt::HANDLE, 0)); + QCOMPARE(handleView->boundingRect(), boundingRect); +} + +void Ut_DuiAppletHandleView::testSetGeometry() +{ + // Reset the state to a known state for testing make sure there is no pixmap to be taken into use. + handleView->setGeometry(QRectF(0, 0, 1, 1)); + handleView->setGeometry(QRectF(0, 0, 2, 2)); + QMetaObject::invokeMethod(handleView, "pixmapTakenIntoUse", Qt::DirectConnection, Q_ARG(Qt::HANDLE, 0)); + QMetaObject::invokeMethod(handleView, "pixmapTakenIntoUse", Qt::DirectConnection, Q_ARG(Qt::HANDLE, 0)); + + // The first setGeometry should go through normally: after this there's a pixmap to be taken into use + handleView->setGeometry(QRectF(0, 0, 300, 150)); + QCOMPARE(gDuiAppletHandleStub->stubLastCallTo("sendGeometryMessage").parameter(0), QRectF(0, 0, 300, 150)); + + // The second and thid setGeometrys should get queued because the pixmap has not been taken into use yet + handleView->setGeometry(QRectF(0, 0, 350, 175)); + handleView->setGeometry(QRectF(0, 0, 400, 200)); + QCOMPARE(gDuiAppletHandleStub->stubLastCallTo("sendGeometryMessage").parameter(0), QRectF(0, 0, 300, 150)); + + // Mark the pixmap as taken into use: this will take the latest size into use. + QMetaObject::invokeMethod(handleView, "pixmapTakenIntoUse", Qt::DirectConnection, Q_ARG(Qt::HANDLE, 0)); + + // The current geometry should now have been sent + QCOMPARE(gDuiAppletHandleStub->stubLastCallTo("sendGeometryMessage").parameter(0), QRectF(0, 0, 400, 200)); +} + +void Ut_DuiAppletHandleView::testReturnedSizeHintManipulation() +{ + // Test size hints returned when applet size is smaller than minimum size of applet defined in style + handleStyle->setMinimumAppletSize(QSizeF(50, 50)); + handleStyle->setMaximumAppletSize(QSizeF(200, 200)); + QVector sizeHints; + sizeHints.append(QSizeF(20, 20)); + sizeHints.append(QSizeF(20, 20)); + sizeHints.append(QSizeF(800, 800)); + sizeHints.append(QSizeF(800, 800)); + handleModel.setSizeHints(sizeHints); + + // Check that reported size hints are between minimum and maximum size hints specified in style + QSizeF constraint(-1, -1); + QCOMPARE(handleView->askSizeHints(Qt::MinimumSize, constraint), QSizeF(50, 50)); + QCOMPARE(handleView->askSizeHints(Qt::MaximumSize, constraint), QSizeF(200, 200)); +} + +void Ut_DuiAppletHandleView::testStateFeedback() +{ + handleView->setModel(&handleModel); + + // test that the progress indicator is not visible by default + QVERIFY(!progressIndicatorVisible); + + // test that the progress indicator is running and visible in the possible applet handle states + handleModel.setState(DuiAppletHandleModel::RUNNING); + QVERIFY(!progressIndicatorVisible); + QVERIFY(!progressIndicatorRunning); + handleModel.setState(DuiAppletHandleModel::STOPPED); + QVERIFY(!progressIndicatorVisible); + QVERIFY(!progressIndicatorRunning); + handleModel.setState(DuiAppletHandleModel::BROKEN); + QVERIFY(!progressIndicatorVisible); + QVERIFY(!progressIndicatorRunning); + handleModel.setState(DuiAppletHandleModel::STARTING); + QVERIFY(progressIndicatorVisible); + QVERIFY(progressIndicatorRunning); + handleModel.setState(DuiAppletHandleModel::INSTALLING); + QVERIFY(progressIndicatorVisible); + QVERIFY(progressIndicatorRunning); +} + +void Ut_DuiAppletHandleView::testBrokenAppletDialog() +{ + // Set the geometry of the applet to a certain size + QRectF geometry(0, 0, 50, 50); + handleView->setGeometry(geometry); + QCOMPARE(gDuiAppletHandleStub->stubLastCallTo("sendGeometryMessage").parameter(0), geometry); + QMetaObject::invokeMethod(handleView, "pixmapTakenIntoUse", Qt::DirectConnection, Q_ARG(Qt::HANDLE, 0)); + + // test that clicking the applet view in non broken state doesn't show a dialog + handleView->click(); + QVERIFY(!dialogShown); + + // test that clicking a broken applet view will show a dialog + handleModel.setState(DuiAppletHandleModel::BROKEN); + handleView->click(); + QVERIFY(dialogShown); + + // test that accepting the dialog will reinitialize the applet handle + QCOMPARE(gDuiAppletHandleStub->stubCallCount("reinit"), 1); + QCOMPARE(gDuiAppletHandleStub->stubCallCount("removeApplet"), 0); + + // Test that setting the same geometry again will send the pixmap ID and the geometry + handleModel.setState(DuiAppletHandleModel::RUNNING); + handleView->setGeometry(geometry); + QCOMPARE(gDuiAppletHandleStub->stubLastCallTo("sendGeometryMessage").parameter(0), geometry); + + // test that rejecting the dialog will remove the applet handle + gDuiAppletHandleStub->stubReset(); + dialogShown = false; + dialogButtons.clear(); + handleModel.setState(DuiAppletHandleModel::BROKEN); + dialogClickedButtonIndex = 1; + handleView->click(); + QVERIFY(dialogShown); + QCOMPARE(gDuiAppletHandleStub->stubCallCount("reinit"), 0); + QCOMPARE(gDuiAppletHandleStub->stubCallCount("removeApplet"), 1); + + // test that canceling the dialog will do nothing + gDuiAppletHandleStub->stubReset(); + dialogShown = false; + dialogButtons.clear(); + handleModel.setState(DuiAppletHandleModel::BROKEN); + dialogClickedButtonIndex = -1; + handleView->click(); + QVERIFY(dialogShown); + QCOMPARE(gDuiAppletHandleStub->stubCallCount("reinit"), 0); + QCOMPARE(gDuiAppletHandleStub->stubCallCount("removeApplet"), 0); +} + +void Ut_DuiAppletHandleView::testPixmapCleanup() +{ + // set the geometry, so a pixmap is created for the view + handleView->setGeometry(QRectF(0, 0, 10, 10)); +} + +void Ut_DuiAppletHandleView::testSettingsDialog() +{ + handleView->setModel(&handleModel); + connect(this, SIGNAL(openAppletSettings()), handleView, SLOT(openAppletSettings())); + + // Check that settings dialog is not executed when applet settings is not set + emit openAppletSettings(); + QVERIFY(!gDuiAppletSettingsDialogExecCalled); + + // Check that settings dialog is executed when applet settings is set + DuiAppletId appletId("applicationName", "mashupCanvasName", 1); + handleModel.setAppletSettings(new DuiAppletSettings("metaDataFilename", appletId)); + emit openAppletSettings(); + QVERIFY(gDuiAppletSettingsDialogExecCalled); +} + +void Ut_DuiAppletHandleView::testPixmapModified() +{ + DuiAppletSharedMutex mutex; + handleModel.setPixmapMutex(NULL); + handleView->setGeometry(QRectF(0, 0, 400, 200)); + QMetaObject::invokeMethod(handleView, "pixmapTakenIntoUse", Qt::DirectConnection, Q_ARG(Qt::HANDLE, 0)); + + // Test one failing pixmap modification + updatedRect = QRectF(); + handleView->appletPixmapModified(QRectF(0, 0, 10, 10)); + QCOMPARE(updatedRect, QRectF()); + QCOMPARE(drawnTargetRect, updatedRect); + QCOMPARE(drawnSourceRect, updatedRect); + + // Test that unhandled consecutive modifications unite the regions + handleModel.setPixmapMutex(&mutex); + handleView->appletPixmapModified(QRectF(10, 10, 10, 10)); + QCOMPARE(updatedRect, QRectF(0, 0, 20, 20)); + QCOMPARE(drawnTargetRect, updatedRect); + QCOMPARE(drawnSourceRect, updatedRect); + + // Test that the united region is cleared after the operation succeeds + updatedRect = QRectF(); + handleView->appletPixmapModified(QRectF(0, 0, 10, 10)); + QCOMPARE(updatedRect, QRectF(0, 0, 10, 10)); + QCOMPARE(drawnTargetRect, updatedRect); + QCOMPARE(drawnSourceRect, updatedRect); +} + +void Ut_DuiAppletHandleView::testInstallationFailedDialog() +{ + // Set the geometry of the applet to a certain size + QRectF geometry(0, 0, 50, 50); + handleView->setGeometry(geometry); + QMetaObject::invokeMethod(handleView, "pixmapTakenIntoUse", Qt::DirectConnection, Q_ARG(Qt::HANDLE, 0)); + + handleModel.setInstallationError(""); + + // test that clicking the applet view in non broken state doesn't show a dialog + handleModel.setState(DuiAppletHandleModel::RUNNING); + handleView->click(); + QVERIFY(!dialogShown); + + // test that clicking a broken applet view will show a dialog with one remove button + handleModel.setInstallationError("CRITICAL ERROR"); + handleModel.setState(DuiAppletHandleModel::BROKEN); + handleView->click(); + QVERIFY(dialogShown); + QCOMPARE(dialogButtons.count(), 1); + + // test that clicking on the button removes the applet + dialogClickedButtonIndex = -1; + handleView->click(); + QVERIFY(dialogShown); + QCOMPARE(gDuiAppletHandleStub->stubCallCount("reinit"), 0); + QCOMPARE(gDuiAppletHandleStub->stubCallCount("removeApplet"), 1); +} + +QTEST_APPLESS_MAIN(Ut_DuiAppletHandleView) diff --git a/tests/ut_duiapplethandleview/ut_duiapplethandleview.h b/tests/ut_duiapplethandleview/ut_duiapplethandleview.h new file mode 100644 index 000000000..b06022ce4 --- /dev/null +++ b/tests/ut_duiapplethandleview/ut_duiapplethandleview.h @@ -0,0 +1,75 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIAPPLETHANDLEVIEW +#define UT_DUIAPPLETHANDLEVIEW + +#include +#include "duiapplethandleview.h" + +class DuiTestAppletHandleView : public DuiAppletHandleView +{ + DUI_VIEW(DuiAppletHandleModel, DuiAppletHandleStyle) + +public: + DuiTestAppletHandleView(DuiAppletHandle *handle); + void click(); + QSizeF askSizeHints(Qt::SizeHint which, QSizeF &constraint); + void appletPixmapModified(const QRectF &rect); +}; + +// Test case must inherit QObject +class Ut_DuiAppletHandleView : public QObject +{ + Q_OBJECT + +public: + static int returnedPixmapWidth; + static int returnedPixmapHeight; + static QRectF updatedRect; + static QRectF drawnTargetRect; + static QRectF drawnSourceRect; + +private: + //! DuiAppletHandleView instance under testing. + DuiTestAppletHandleView *handleView; + DuiAppletHandle *handle; + +signals: + void openAppletSettings(); + +private slots: + void initTestCase(); + void cleanupTestCase(); + + void init(); + void cleanup(); + + void testScaling_data(); + void testScaling(); + void testSetGeometry(); + void testReturnedSizeHintManipulation(); + void testStateFeedback(); + void testBrokenAppletDialog(); + void testPixmapCleanup(); + void testSettingsDialog(); + void testPixmapModified(); + void testInstallationFailedDialog(); +}; +#endif // UT_DUIAPPLETHANDLEVIEW diff --git a/tests/ut_duiapplethandleview/ut_duiapplethandleview.pro b/tests/ut_duiapplethandleview/ut_duiapplethandleview.pro new file mode 100644 index 000000000..9c2a5aa6f --- /dev/null +++ b/tests/ut_duiapplethandleview/ut_duiapplethandleview.pro @@ -0,0 +1,37 @@ +include(../common_top.pri) + +TARGET = ut_duiapplethandleview +INCLUDEPATH += $$DUISRCDIR/mashup/mashup \ + $$DUISRCDIR/mashup/appletcommunication \ + $$DUISRCDIR/widgets \ + $$DUISRCDIR/widgets/core \ + $$DUISRCDIR/core \ + $$DUISRCDIR/style + +DUIGEN_OUTDIR = . +duigenerator_model.name = duigenerator model +duigenerator_model.input = MODEL_HEADERS +duigenerator_model.depends = ../../duigen/duigen +duigenerator_model.output = $$DUIGEN_OUTDIR/gen_${QMAKE_FILE_BASE}data.cpp +duigenerator_model.commands += ../../duigen/duigen --model ${QMAKE_FILE_NAME} $$DUIGEN_OUTDIR +duigenerator_model.clean += $$DUIGEN_OUTDIR/gen_* +duigenerator_model.CONFIG = target_predeps no_link +duigenerator_model.variable_out = GENERATED_SOURCES +QMAKE_EXTRA_COMPILERS += duigenerator_model + +MODEL_HEADERS += $$DUISRCDIR/widgets/duiwidgetmodel.h \ + $$DUISRCDIR/mashup/mashup/duiapplethandlemodel.h + +SOURCES += ut_duiapplethandleview.cpp \ + $$DUISRCDIR/mashup/mashup/duiapplethandleview.cpp \ + $$DUISRCDIR/widgets/duiwidgetmodel.cpp \ + ../stubs/stubbase.cpp + +HEADERS += ut_duiapplethandleview.h \ + $$DUISRCDIR/mashup/mashup/duiapplethandleview.h \ + $$DUISRCDIR/mashup/mashup/duiapplethandle.h \ + $$DUISRCDIR/mashup/mashup/duiapplethandlemodel.h \ + $$DUISRCDIR/widgets/duiwidgetmodel_p.h \ + $$DUISRCDIR/widgets/core/duiwidgetview_p.h + +include(../common_bot.pri) diff --git a/tests/ut_duiappletid/.gitignore b/tests/ut_duiappletid/.gitignore new file mode 100644 index 000000000..a097f5720 --- /dev/null +++ b/tests/ut_duiappletid/.gitignore @@ -0,0 +1 @@ +ut_duiappletid diff --git a/tests/ut_duiappletid/ut_duiappletid.cpp b/tests/ut_duiappletid/ut_duiappletid.cpp new file mode 100644 index 000000000..c4c578d57 --- /dev/null +++ b/tests/ut_duiappletid/ut_duiappletid.cpp @@ -0,0 +1,53 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include "ut_duiappletid.h" + +void Ut_DuiAppletId::init() +{ + m_subject = new DuiAppletId(); +} + +void Ut_DuiAppletId::cleanup() +{ + delete m_subject; + m_subject = 0; +} + +void Ut_DuiAppletId::initTestCase() +{ +} + +void Ut_DuiAppletId::cleanupTestCase() +{ +} + +void Ut_DuiAppletId::testAppletInstanceIdentifier() +{ + QCOMPARE(m_subject->toString(), QString("//0")); + QCOMPARE(m_subject->instanceId(), uint(0)); + + delete m_subject; + m_subject = new DuiAppletId("Foo", "FooCanvas", 1); + QCOMPARE(m_subject->toString(), QString("Foo/FooCanvas/1")); + QCOMPARE(m_subject->instanceId(), uint(1)); +} + +QTEST_MAIN(Ut_DuiAppletId) diff --git a/tests/ut_duiappletid/ut_duiappletid.h b/tests/ut_duiappletid/ut_duiappletid.h new file mode 100644 index 000000000..28bdc3e65 --- /dev/null +++ b/tests/ut_duiappletid/ut_duiappletid.h @@ -0,0 +1,43 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIAPPLETID_H +#define UT_DUIAPPLETID_H + +#include +#include + +#include + +class Ut_DuiAppletId : public QObject +{ + Q_OBJECT + +private slots: + void init(); + void cleanup(); + void initTestCase(); + void cleanupTestCase(); + void testAppletInstanceIdentifier(); + +private: + DuiAppletId *m_subject; +}; + +#endif diff --git a/tests/ut_duiappletid/ut_duiappletid.pro b/tests/ut_duiappletid/ut_duiappletid.pro new file mode 100644 index 000000000..a60f2d759 --- /dev/null +++ b/tests/ut_duiappletid/ut_duiappletid.pro @@ -0,0 +1,15 @@ +include(../common_top.pri) + +TARGET = ut_duiappletid +INCLUDEPATH += $$DUISRCDIR/mashup/mashup \ + $$DUISRCDIR/mashup/appletcommunication + +QT += network + +SOURCES += ut_duiappletid.cpp \ + $$DUISRCDIR/mashup/mashup/duiappletid.cpp + +HEADERS += ut_duiappletid.h \ + $$DUISRCDIR/mashup/mashup/duiappletid.h + +include(../common_bot.pri) diff --git a/tests/ut_duiappletinstancedata/.gitignore b/tests/ut_duiappletinstancedata/.gitignore new file mode 100644 index 000000000..cd0557120 --- /dev/null +++ b/tests/ut_duiappletinstancedata/.gitignore @@ -0,0 +1 @@ +ut_duiappletinstancedata diff --git a/tests/ut_duiappletinstancedata/ut_duiappletinstancedata.cpp b/tests/ut_duiappletinstancedata/ut_duiappletinstancedata.cpp new file mode 100644 index 000000000..cb2d50e8b --- /dev/null +++ b/tests/ut_duiappletinstancedata/ut_duiappletinstancedata.cpp @@ -0,0 +1,46 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include + +#include "ut_duiappletinstancedata.h" +#include "duiappletinstancedata.h" +#include "duiappletid_stub.h" + +// The test class +void Ut_DuiAppletInstanceData::initTestCase() +{ +} + +void Ut_DuiAppletInstanceData::cleanupTestCase() +{ +} + +void Ut_DuiAppletInstanceData::init() +{ + instanceData = new DuiAppletInstanceData; +} + +void Ut_DuiAppletInstanceData::cleanup() +{ + // Destroy the manager data + delete instanceData; +} + +QTEST_APPLESS_MAIN(Ut_DuiAppletInstanceData) diff --git a/tests/ut_duiappletinstancedata/ut_duiappletinstancedata.h b/tests/ut_duiappletinstancedata/ut_duiappletinstancedata.h new file mode 100644 index 000000000..6dcd70f52 --- /dev/null +++ b/tests/ut_duiappletinstancedata/ut_duiappletinstancedata.h @@ -0,0 +1,41 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIAPPLETINSTANCEDATA_H +#define UT_DUIAPPLETINSTANCEDATA_H + +#include + +class DuiAppletInstanceData; + +class Ut_DuiAppletInstanceData : public QObject +{ + Q_OBJECT + +private: + DuiAppletInstanceData *instanceData; + +private slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); +}; + +#endif // UT_DUIAPPLETINSTANCEDATA_H diff --git a/tests/ut_duiappletinstancedata/ut_duiappletinstancedata.pro b/tests/ut_duiappletinstancedata/ut_duiappletinstancedata.pro new file mode 100644 index 000000000..e70bb8796 --- /dev/null +++ b/tests/ut_duiappletinstancedata/ut_duiappletinstancedata.pro @@ -0,0 +1,20 @@ +include(../common_top.pri) +TARGET = ut_duiappletinstancedata +INCLUDEPATH += $$DUISRCDIR/mashup/appletcommunication $$DUISRCDIR/mashup/appletinterface $$DUISRCDIR/mashup/mashup $$DUISRCDIR/widgets + +# unit test and unit classes +SOURCES += \ + ut_duiappletinstancedata.cpp \ + $$DUISRCDIR/mashup/mashup/duiappletinstancedata.cpp + +# service classes +SOURCES += \ + $$STUBSDIR/stubbase.cpp \ + +# unit test and unit classes +HEADERS += \ + ut_duiappletinstancedata.h \ + $$DUISRCDIR/mashup/mashup/duiappletinstancedata.h \ + $$DUISRCDIR/mashup/mashup/duiappletid.h + +include(../common_bot.pri) diff --git a/tests/ut_duiappletinstancemanager/.gitignore b/tests/ut_duiappletinstancemanager/.gitignore new file mode 100644 index 000000000..c16655545 --- /dev/null +++ b/tests/ut_duiappletinstancemanager/.gitignore @@ -0,0 +1 @@ +ut_duiappletinstancemanager diff --git a/tests/ut_duiappletinstancemanager/ut_duiappletinstancemanager.cpp b/tests/ut_duiappletinstancemanager/ut_duiappletinstancemanager.cpp new file mode 100644 index 000000000..ff9c8a172 --- /dev/null +++ b/tests/ut_duiappletinstancemanager/ut_duiappletinstancemanager.cpp @@ -0,0 +1,793 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include "duiapplication.h" +#include "duiwindow.h" +#include "duiappletpackagemetadata.h" +#include "duiappletinstancemanager.h" +#include "duiappletinstancedata.h" +#include "duiappletmessage.h" +#include "duiapplethandle_stub.h" +#include "duibutton.h" +#include "duiappletmetadata.h" +#include "ut_duiappletinstancemanager.h" +#include "duifiledatastore.h" +#include "duiscenemanager.h" +#include "duiappletinstancemanagerdbusadaptor.h" +#include "duiappletloader_stub.h" +#include "duiappletid.h" +#include "duiappletsettings_stub.h" +#include "duiapplication.h" +#include "mockdatastore.h" + +bool outOfProcess = false; +int appletValueIteration = 0; +QStringList removedFiles; +QString pluginLoaderFileName; + +// QDBusInterface stubs (used by DuiRemoteAction) +QDBusInterface::QDBusInterface(const QString &service, const QString &path, const QString &interface, const QDBusConnection &connection, QObject *parent) : QDBusAbstractInterface("service", "path", "interface", connection, parent) +{ + Ut_DuiAppletInstanceManager::callServiceName = service; + Ut_DuiAppletInstanceManager::callObjectPath = path; + Ut_DuiAppletInstanceManager::callInterface = interface; +} + +QDBusInterface::~QDBusInterface() +{ +} + +// QDBusPendingCall stubs (used by DuiAppletInstanceManager) +QDBusPendingCall QDBusAbstractInterface::asyncCall(const QString &method, + const QVariant &arg1, + const QVariant &arg2, + const QVariant &arg3, + const QVariant &arg4, + const QVariant &arg5, + const QVariant &arg6, + const QVariant &arg7, + const QVariant &arg8) + +{ + if (Ut_DuiAppletInstanceManager::captureCalls) { + QList args; + if (arg1.isValid()) { + args.append(arg1); + if (arg2.isValid()) { + args.append(arg2); + if (arg3.isValid()) { + args.append(arg3); + if (arg4.isValid()) { + args.append(arg4); + if (arg5.isValid()) { + args.append(arg5); + if (arg6.isValid()) { + args.append(arg6); + if (arg7.isValid()) { + args.append(arg7); + if (arg8.isValid()) { + args.append(arg8); + } + } + } + } + } + } + } + } + Ut_DuiAppletInstanceManager::callMethods.append(method); + Ut_DuiAppletInstanceManager::callArguments.append(args); + } + + return QDBusPendingCall::fromCompletedCall(QDBusMessage()); +} + +bool QDBusPendingCall::isError() const +{ + return Ut_DuiAppletInstanceManager::callError; +} + +// QDBusPendingReply stubs (used by DuiAppletInstanceManager) +void QDBusPendingReplyData::setMetaTypes(int, int const *) +{ +} + +QVariant QDBusPendingReplyData::argumentAt(int) const +{ + return Ut_DuiAppletInstanceManager::replyDataString; +} + +// DuiAppletInstanceManagerDBusAdpator stubs +DuiAppletInstanceManagerDBusAdaptor::DuiAppletInstanceManagerDBusAdaptor(DuiAppletInstanceManager *parent) : QDBusAbstractAdaptor(parent) +{ +} + +DuiAppletInstanceManagerDBusAdaptor::~DuiAppletInstanceManagerDBusAdaptor() +{ +} + +void DuiAppletInstanceManagerDBusAdaptor::instantiateAppletFromPackage(const QString &, const QMap &) +{ +} + +DuiAppletHandleModel::~DuiAppletHandleModel() +{ +} + +bool Ut_DuiAppletInstanceManager::captureCalls = false; +QString Ut_DuiAppletInstanceManager::callServiceName; +QString Ut_DuiAppletInstanceManager::callObjectPath; +QString Ut_DuiAppletInstanceManager::callInterface; +QList Ut_DuiAppletInstanceManager::callMethods; +QList< QList > Ut_DuiAppletInstanceManager::callArguments; +bool Ut_DuiAppletInstanceManager::callError = false; +QString Ut_DuiAppletInstanceManager::replyDataString; + +// AppletInstanceCollection (connected to DuiAppletInstanceManager) +AppletInstanceCollection::~AppletInstanceCollection() +{ +} + +int AppletInstanceCollection::count() const +{ + return instances.count(); +} + +DuiWidget *AppletInstanceCollection::at(int index) const +{ + return instances.at(index); +} + +void AppletInstanceCollection::addInstance(DuiWidget *widget, DuiDataStore &store) +{ + Q_UNUSED(store); + instances.append(widget); +} + +void AppletInstanceCollection::removeInstance(DuiWidget *widget) +{ + int index = instances.indexOf(widget); + if (index != -1) { + instances.removeAt(index); + } +} + +// DuiAppletMetaData stubs (used by DuiAppletInstanceManager) +QString DuiAppletMetaData::appletBinary() const +{ + if (fileName() == "/tmp/testapplet1.desktop") { + return APPLET_LIBS "/testapplet1.so"; + } else if (fileName() == "/tmp/testapplet2.desktop") { + return APPLET_LIBS "/testapplet2.so"; + } else if (fileName() == "/tmp/testapplet3.desktop") { + return APPLET_LIBS "/testapplet3.so"; + } else if (fileName() == "/tmp/testapplet4.desktop") { + return APPLET_LIBS "/testapplet4.so"; + } + + return QString(); +} + + +// QProcess stubs (used by DuiAppletHandle) +void QProcess::start(const QString &, const QStringList &, OpenMode) +{ +} + +// QLocalServer stubs (used by AppletCommunicator) +bool QLocalServer::waitForNewConnection(int, bool *) +{ + return true; +} + +QString DuiDesktopEntry::value(const QString &key) const +{ + // These are used by DuiDesktopEntry and DuiAppletMetaData + if (key == "Desktop Entry/Type") + return QString("DUIApplet"); + else if (key == "Desktop Entry/Name") + return QString("Calendar"); + else if (key == "Desktop Entry/Icon") + return QString("W-Icon-calendar"); + else if (key == "Desktop Entry/Exec") + return QString(outOfProcess ? "duiappletrunner" : ""); + else if (key == "DUI/X-DUIApplet-Applet") { + // Give a different name for the two applet binaries + appletValueIteration++; + if (appletValueIteration == 1) + return QString("testapplet1.so"); + else + return QString("testapplet4.so"); + } else + return QString(); +} + +bool DuiDesktopEntry::contains(const QString &key) const +{ + // These are used by DuiDesktopEntry and DuiAppletMetaData + return (key == "Desktop Entry/Type" || + key == "Desktop Entry/Name" || + key == "Desktop Entry/Icon" || + key == "Desktop Entry/Exec" || + key == "DUI/X-DUIApplet-Applet"); +} + +bool DuiAppletMetaData::isValid() const +{ + return true; +} + +// DuiFileDataStore stubs +bool DuiFileDataStore_isReadable = true; +bool DuiFileDataStore::isReadable() const +{ + return DuiFileDataStore_isReadable; +} +bool DuiFileDataStore_isWritable = true; +bool DuiFileDataStore::isWritable() const +{ + return DuiFileDataStore_isWritable; +} + +QMap instantiateAppletPlaceHolderMetaData; + +// QFile stubs (used by DuiAppletInstanceManager) +bool QFile::remove(const QString &fileName) +{ + removedFiles.append(fileName); + return true; +} + +QPair fileCopy; +bool QFile::copy(const QString &fileName, const QString &newName) +{ + fileCopy.first = fileName; + fileCopy.second = newName; + + return true; +} + +QStringList existingFiles; +bool QFile::exists(const QString &fileName) +{ + return existingFiles.contains(fileName); +} + +// QDir stubs (used by DuiAppletInstanceManager) +bool dataDirectoryExists = false; +bool QDir::exists(const QString &fileName) const +{ + QString dataDirectoryName = QDir::homePath() + "/.config/ut_duiappletinstancemanager/"; + + if (fileName == dataDirectoryName) { + return dataDirectoryExists; + } + + return true; +} + +QString dirMkpath; +bool QDir::mkpath(const QString &dirPath) const +{ + dirMkpath = dirPath; + return true; +} + +// QFileInfo stubs (used by DuiAppletMetaData) +bool QFileInfo::exists() const +{ + return true; +} + +bool QFileInfo::isFile() const +{ + return true; +} + +bool QFileInfo::isExecutable() const +{ + return true; +} + +// QFile stubs +bool QFile::exists() const +{ + return existingFiles.contains(fileName()); +} + +DuiTestAppletInstanceManager::DuiTestAppletInstanceManager(const QString &identifier, DuiDataStore *dataStore) : + DuiAppletInstanceManager(identifier, dataStore) +{ +} + +// The test class +void Ut_DuiAppletInstanceManager::initTestCase() +{ + static int argc = 1; + static char *app_name[1] = { (char *) "./ut_duiappletinstancedata" }; + app = new DuiApplication(argc, app_name); + window = new DuiWindow; +} + +void Ut_DuiAppletInstanceManager::cleanupTestCase() +{ + delete window; + delete app; +} + +void Ut_DuiAppletInstanceManager::init() +{ + // Initialize default data store with data + defaultDataStore = new MockDataStore(); + defaultDataStore->createValue(QString("1/desktopFile"), QVariant("/tmp/testapplet1.desktop")); + defaultDataStore->createValue(QString("1/title"), QVariant("Title 1")); + defaultDataStore->createValue(QString("1/sizeLandscape"), QVariant("101 201")); + defaultDataStore->createValue(QString("1/sizePortrait"), QVariant("101 201")); + defaultDataStore->createValue(QString("3/foo"), QVariant("bar")); + defaultDataStore->createValue(QString("4/desktopFile"), QVariant("/tmp/testapplet4.desktop")); + defaultDataStore->createValue(QString("4/title"), QVariant("Title 4")); + defaultDataStore->createValue(QString("4/sizeLandscape"), QVariant("104 204")); + defaultDataStore->createValue(QString("4/sizePortrait"), QVariant("104 204")); + defaultDataStore->createValue(QString("5/desktopFile"), QVariant("/tmp/testapplet5.desktop")); + defaultDataStore->createValue(QString("5/packageName"), QVariant("/tmp/testapplet5.deb")); + defaultDataStore->createValue(QString("5/title"), QVariant("Title 5")); + defaultDataStore->createValue(QString("5/sizeLandscape"), QVariant("105 205")); + defaultDataStore->createValue(QString("5/sizePortrait"), QVariant("105 205")); + existingFiles.clear(); + existingFiles.append("/tmp/testapplet1.desktop"); + existingFiles.append("/tmp/testapplet4.desktop"); + + // Create applet instance manager under test + manager = new DuiTestAppletInstanceManager("testmanager", defaultDataStore); + + removedFiles.clear(); + + appletValueIteration = 0; + outOfProcess = false; + + DuiFileDataStore_isReadable = true; + DuiFileDataStore_isWritable = true; + + gDuiAppletSettingsStub->stubReset(); + gDuiAppletHandleStub->stubReset(); + gDuiAppletHandleStub->stubSetReturnValue("state", DuiAppletHandleModel::RUNNING); + + dataDirectoryExists = false; + fileCopy.first = QString(); + fileCopy.second = QString(); + dirMkpath = QString(); + instantiateAppletPlaceHolderMetaData.clear(); + + captureCalls = false; + callServiceName = QString(); + callObjectPath = QString(); + callInterface = QString(); + callMethods.clear(); + callArguments.clear(); + callError = false; + replyDataString.clear(); + connect(this, SIGNAL(operationComplete(QString, QString, QString)), manager, SLOT(operationComplete(QString, QString, QString))); + + gDuiAppletHandleStub->stubReset(); +} + +void Ut_DuiAppletInstanceManager::cleanup() +{ + // Destroy the manager + delete manager; + manager = 0; + + // Destroy default data store + delete defaultDataStore; + defaultDataStore = 0; +} + + +void Ut_DuiAppletInstanceManager::testInProcessAppletRestoration() +{ + QSignalSpy spy(manager, SIGNAL(appletInstantiated(DuiWidget *, DuiDataStore &))); + + // Verify that the restoration process does not return an error + QVERIFY(manager->restoreApplets()); + + // Make sure the appletInstantiated signal was emitted exactly twice + QCOMPARE(spy.count(), 2); + + // Applets 1 and 4 should be restored, 2 and 3 not + QCOMPARE(gDuiAppletLoaderStub->stubCallCount("loadApplet"), 2); + QCOMPARE(gDuiAppletLoaderStub->stubCallsTo("loadApplet").at(0)->parameter(0), QString("/tmp/testapplet1.desktop")); + QCOMPARE(gDuiAppletLoaderStub->stubCallsTo("loadApplet").at(1)->parameter(0), QString("/tmp/testapplet4.desktop")); +} + +void Ut_DuiAppletInstanceManager::testOutOfProcessAppletRestoration() +{ + outOfProcess = true; + + // Create AppletInstanceCollection to verify created applet instances + AppletInstanceCollection collection; + QObject::connect(manager, SIGNAL(appletInstantiated(DuiWidget *, DuiDataStore &)), &collection, SLOT(addInstance(DuiWidget *, DuiDataStore &))); + + // Verify that the restoration process does not return an error + QVERIFY(manager->restoreApplets()); + + // Make sure the two applet instances were created + QCOMPARE(collection.count(), 2); + + // Make sure correct applets were instantiated as out of process applets + DuiAppletHandle *instance1 = dynamic_cast(collection.at(0)); + DuiAppletHandle *instance2 = dynamic_cast(collection.at(1)); + QVERIFY(instance1 != NULL); + QVERIFY(instance2 != NULL); + QList initCalls = gDuiAppletHandleStub->stubCallsTo("init"); + QCOMPARE(initCalls.length(), 2); + QCOMPARE(initCalls[0]->parameter(3).toString(), QString("ut_duiappletinstancemanager/testmanager/1")); + QCOMPARE(initCalls[1]->parameter(3).toString(), QString("ut_duiappletinstancemanager/testmanager/4")); + + // Make sure the titles are set + QList setAppletTitleCalls = gDuiAppletHandleStub->stubCallsTo("setAppletTitle"); + QCOMPARE(setAppletTitleCalls.length(), 2); + QCOMPARE(setAppletTitleCalls[0]->parameter(0), QString("Title 1")); + QCOMPARE(setAppletTitleCalls[1]->parameter(0), QString("Title 4")); + + // Make sure size hints are set + QList setSizeHintsCalls = gDuiAppletHandleStub->stubCallsTo("setSizeHints"); + QCOMPARE(setSizeHintsCalls.length(), 2); + QCOMPARE(setSizeHintsCalls[0]->parameter >(0).at(0), QSizeF(101, 201)); + QCOMPARE(setSizeHintsCalls[0]->parameter >(0).at(1), QSizeF(101, 201)); + QCOMPARE(setSizeHintsCalls[0]->parameter >(0).at(2), QSizeF(101, 201)); + QCOMPARE(setSizeHintsCalls[0]->parameter >(0).at(3), QSizeF(101, 201)); + QCOMPARE(setSizeHintsCalls[1]->parameter >(0).at(0), QSizeF(104, 204)); + QCOMPARE(setSizeHintsCalls[1]->parameter >(0).at(1), QSizeF(104, 204)); + QCOMPARE(setSizeHintsCalls[1]->parameter >(0).at(2), QSizeF(104, 204)); + QCOMPARE(setSizeHintsCalls[1]->parameter >(0).at(3), QSizeF(104, 204)); +} + +void Ut_DuiAppletInstanceManager::testAppletDataStoring() +{ + // Create DuiAppletInstanceManager with a mock datastore. + MockDataStore mockDataStore; + delete manager; + manager = new DuiTestAppletInstanceManager("testmanager", &mockDataStore); + + // Instantiate two applets + QVERIFY(manager->instantiateApplet("/tmp/testapplet1.desktop")); + QCOMPARE(mockDataStore.value("1/desktopFile"), QVariant("/tmp/testapplet1.desktop")); + QCOMPARE(mockDataStore.value("1/packageName"), QVariant("")); + QCOMPARE(mockDataStore.value("1/title"), QVariant("")); +} + +void Ut_DuiAppletInstanceManager::testAppletInstantiation() +{ + // Create DuiAppletInstanceManager with a mock datastore. + MockDataStore mockDataStore; + delete manager; + manager = new DuiTestAppletInstanceManager("testmanager", &mockDataStore); + + // Create a signal spy to investigate if appletInstantiated signal is emitted for all applets. + QSignalSpy spy(manager, SIGNAL(appletInstantiated(DuiWidget *, DuiDataStore &))); + + // Verify that the instantiation process does not return an error + QVERIFY(manager->instantiateApplet("/tmp/testapplet1.desktop")); + QVERIFY(manager->instantiateApplet("/tmp/testapplet4.desktop")); + + // Make sure the appletInstantiated signal was emitted exactly two times + QCOMPARE(spy.count(), 2); +} + + +void Ut_DuiAppletInstanceManager::testAppletInstantiationWithMissingDesktopFiles() +{ + // Create DuiAppletInstanceManager with a mock datastore. + existingFiles.clear(); + MockDataStore mockDataStore; + delete manager; + manager = new DuiTestAppletInstanceManager("testmanager", &mockDataStore); + + // Create a signal spy to investigate if appletInstantiated signal is emitted for all applets. + QSignalSpy spy(manager, SIGNAL(appletInstantiated(DuiWidget *, DuiDataStore &))); + + // Verify that the instantiation process does return an error + QVERIFY(!manager->instantiateApplet("/tmp/testapplet1.desktop")); + QVERIFY(!manager->instantiateApplet("/tmp/testapplet4.desktop")); + + // Make sure the appletInstantiated signal was emitted exactly zero times + QCOMPARE(spy.count(), 0); +} + +void Ut_DuiAppletInstanceManager::testAppletInstanceRemoval() +{ + QSignalSpy instantiateSpy(manager, SIGNAL(appletInstantiated(DuiWidget *, DuiDataStore &))); + QSignalSpy removeSpy(manager, SIGNAL(appletRemoved(DuiWidget *))); + + // Verify that the instantiation process does not return an error + QVERIFY(manager->restoreApplets()); + + // Remove one of the instantiated applets + DuiAppletId appletId("ut_duiappletinstancemanager", "testmanager", 4); + QVERIFY(manager->removeApplet(appletId)); + + // Make sure the appletRemoved signal was emitted exactly once + QCOMPARE(removeSpy.count(), 1); + + // Verify that applet instance data file was removed + QCOMPARE(removedFiles.count(), 1); + QString dataFileName = QDir::homePath() + "/.config/ut_duiappletinstancemanager/testmanager/4.data"; + QCOMPARE(removedFiles.at(0), dataFileName); + + // Verify that the applet instance settings were removed + QCOMPARE(gDuiAppletSettingsStub->stubCallCount("removeInstanceSettingValues"), 1); + QCOMPARE(gDuiAppletSettingsStub->stubLastCallTo("duiAppletSettingsConstructor").parameter(0), QString("/tmp/testapplet4.desktop")); + QCOMPARE(gDuiAppletSettingsStub->stubLastCallTo("duiAppletSettingsConstructor").parameter(1).toString(), appletId.toString()); +} + +void Ut_DuiAppletInstanceManager::testAppletUninstallation() +{ + QSignalSpy removeSpy(manager, SIGNAL(appletRemoved(DuiWidget *))); + + // Verify that the instantiation process does not return an error + QVERIFY(manager->restoreApplets()); + + // Emit an applet uninstalled signal + connect(this, SIGNAL(appletUninstalled(QString)), manager, SLOT(appletUninstalled(QString))); + emit appletUninstalled("/tmp/testapplet1.desktop"); + + // Make sure the appletRemoved signal was emitted exactly once + QCOMPARE(removeSpy.count(), 1); + + // Verify that applet instance data file was removed + QCOMPARE(removedFiles.count(), 1); + QString dataFileName = QDir::homePath() + "/.config/ut_duiappletinstancemanager/testmanager/1.data"; + QCOMPARE(removedFiles.at(0), dataFileName); +} + +void Ut_DuiAppletInstanceManager::testAppletInstanceDataStoreIsNonReadWrite() +{ + // Create DuiAppletInstanceManager with a mock datastore. + MockDataStore mockDataStore; + delete manager; + manager = new DuiTestAppletInstanceManager("testmanager", &mockDataStore); + + // Create a signal spy to investigate if appletInstantiated signal is emitted + QSignalSpy spy(manager, SIGNAL(appletInstantiated(DuiWidget *, DuiDataStore &))); + + DuiFileDataStore_isReadable = false; + QVERIFY(!manager->instantiateApplet("/tmp/testapplet1.desktop")); + QVERIFY(!mockDataStore.contains("1/desktopFile")); + QCOMPARE(spy.count(), 0); + + DuiFileDataStore_isWritable = false; + QVERIFY(!manager->instantiateApplet("/tmp/testapplet1.desktop")); + QVERIFY(!mockDataStore.contains("1/desktopFile")); + QCOMPARE(spy.count(), 0); + + DuiFileDataStore_isReadable = true; + QVERIFY(!manager->instantiateApplet("/tmp/testapplet1.desktop")); + QVERIFY(!mockDataStore.contains("1/desktopFile")); + QCOMPARE(spy.count(), 0); +} + +void Ut_DuiAppletInstanceManager::testPreconfiguredAppletInstances() +{ + existingFiles.append(DUI_XDG_DIR "/" "ut_duiappletinstancemanager/testmanager.data"); + + delete manager; + manager = new DuiTestAppletInstanceManager("testmanager"); + QCOMPARE(dirMkpath, QDir::homePath() + "/.config/ut_duiappletinstancemanager/"); + QCOMPARE(fileCopy.first, QString(DUI_XDG_DIR "/" "ut_duiappletinstancemanager/testmanager.data")); + QCOMPARE(fileCopy.second, QDir::homePath() + "/.config/ut_duiappletinstancemanager/testmanager.data"); + + // The data directory should not be created if it already exists + fileCopy.first = QString(); + fileCopy.second = QString(); + dirMkpath = QString(); + dataDirectoryExists = true; + delete manager; + manager = new DuiTestAppletInstanceManager("testmanager"); + QCOMPARE(dirMkpath, QString()); + QCOMPARE(fileCopy.first, QString(DUI_XDG_DIR "/" "ut_duiappletinstancemanager/testmanager.data")); + QCOMPARE(fileCopy.second, QDir::homePath() + "/.config/ut_duiappletinstancemanager/testmanager.data"); + + // The data file should not be copied if it already exists and the dir should not be created + fileCopy.first = QString(); + fileCopy.second = QString(); + dirMkpath = QString(); + dataDirectoryExists = false; + existingFiles.append(QDir::homePath() + "/.config/ut_duiappletinstancemanager/testmanager.data"); + delete manager; + manager = new DuiTestAppletInstanceManager("testmanager"); + QCOMPARE(dirMkpath, QString()); + QCOMPARE(fileCopy.first, QString()); + QCOMPARE(fileCopy.second, QString()); +} + +void Ut_DuiAppletInstanceManager::testOOPAppletStartsToBrokenState() +{ + outOfProcess = true; + gDuiAppletHandleStub->stubSetReturnValue("state", DuiAppletHandleModel::BROKEN); + + // Create a signal spy to investigate if appletInstantiated signal is emitted for all applets. + QSignalSpy spy(manager, SIGNAL(appletInstantiated(DuiWidget *, DuiDataStore &))); + + // Verify that the instantiation process doesn't succeed + QVERIFY(!manager->instantiateApplet("/tmp/testapplet1.desktop")); + + // Make sure the appletInstantiated signal is not emitted + QCOMPARE(spy.count(), 0); +} + +void Ut_DuiAppletInstanceManager::testInstallingAppletFromPackage() +{ + // Create a signal spy to investigate if appletInstantiated signal is emitted + QSignalSpy spy(manager, SIGNAL(appletInstantiated(DuiWidget *, DuiDataStore &))); + + // Instantiate an applet from a package + QMap metaData; + metaData.insert("Maemo-Desktop-File", "test.desktop"); + metaData.insert("Maemo-Applet-Title", "Test Title"); + metaData.insert("Maemo-Applet-Size-Landscape", "600 300"); + metaData.insert("Maemo-Applet-Size-Portrait", "600 300"); + manager->instantiateAppletFromPackage("testpackage.deb", metaData); + + // Make sure the applet placeholder is instantiated + QCOMPARE(gDuiAppletHandleStub->stubCallCount("initPlaceHolder"), 1); + QCOMPARE(gDuiAppletHandleStub->stubLastCallTo("initPlaceHolder").parameter(0).instanceId(), (uint)2); + + // Make sure the titles are set + QList setAppletTitleCalls = gDuiAppletHandleStub->stubCallsTo("setAppletTitle"); + QCOMPARE(setAppletTitleCalls.length(), 1); + QCOMPARE(setAppletTitleCalls[0]->parameter(0), QString("Test Title")); + + // Make sure size hints are set + QList setSizeHintsCalls = gDuiAppletHandleStub->stubCallsTo("setSizeHints"); + QCOMPARE(setSizeHintsCalls.length(), 1); + QCOMPARE(setSizeHintsCalls[0]->parameter >(0).at(0), QSizeF(600, 300)); + QCOMPARE(setSizeHintsCalls[0]->parameter >(0).at(1), QSizeF(600, 300)); + QCOMPARE(setSizeHintsCalls[0]->parameter >(0).at(2), QSizeF(600, 300)); + QCOMPARE(setSizeHintsCalls[0]->parameter >(0).at(3), QSizeF(600, 300)); +} + +void Ut_DuiAppletInstanceManager::testInstallationOperationComplete() +{ + // Instantiate an applet from a package + QMap metaData; + metaData.insert("Maemo-Desktop-File", "/tmp/test.desktop"); + manager->instantiateAppletFromPackage("testpackage.deb", metaData); + + // When the installation of the package being installed is complete the applet should be instantiated + outOfProcess = true; + existingFiles.append("/tmp/test.desktop"); + emit operationComplete("Install", "testpackage.deb", QString()); + QCOMPARE(gDuiAppletHandleStub->stubCallCount("init"), 1); + QCOMPARE(gDuiAppletHandleStub->stubLastCallTo("init").parameter(3).instanceId(), (uint)2); +} + +void Ut_DuiAppletInstanceManager::testInstallationOperationCompleteForUnknownPackage() +{ + // Instantiate an applet from a package + QMap metaData; + metaData.insert("Maemo-Desktop-File", "/tmp/test.desktop"); + manager->instantiateAppletFromPackage("testpackage.deb", metaData); + + // When the installation of the package being installed is complete the applet should be instantiated + outOfProcess = true; + existingFiles.append("/tmp/test.desktop"); + emit operationComplete("Install", "otherpackage.deb", QString()); + QCOMPARE(gDuiAppletHandleStub->stubCallCount("init"), 0); +} + +void Ut_DuiAppletInstanceManager::testUnknownOperationComplete() +{ + // Instantiate an applet from a package + QMap metaData; + metaData.insert("Maemo-Desktop-File", "/tmp/test.desktop"); + manager->instantiateAppletFromPackage("testpackage.deb", metaData); + + // When the installation of the package being installed is complete the applet should be instantiated + outOfProcess = true; + existingFiles.append("/tmp/test.desktop"); + emit operationComplete("UnknownOperation", "testpackage.deb", QString()); + QCOMPARE(gDuiAppletHandleStub->stubCallCount("init"), 0); +} + +void Ut_DuiAppletInstanceManager::testRestoringAppletsBeingInstalled() +{ + // Verify that the restoration process does not return an error + captureCalls = true; + QVERIFY(manager->restoreApplets()); + + // Make sure the package installation status is queried with an Operation D-Bus call + QCOMPARE(callServiceName, QString("com.nokia.package_manager")); + QCOMPARE(callObjectPath, QString("/com/nokia/package_manager")); + QCOMPARE(callInterface, QString("com.nokia.package_manager")); + QCOMPARE(callMethods.count(), 1); + QCOMPARE(callMethods.at(0), QString("Operation")); + QCOMPARE(callArguments.count(), 1); + QCOMPARE(callArguments.at(0).count(), 1); + QCOMPARE(callArguments.at(0).at(0), QVariant("/tmp/testapplet5.deb")); +} + +void Ut_DuiAppletInstanceManager::testReceiveOperationFailed() +{ + QSignalSpy spy(manager, SIGNAL(appletInstantiated(DuiWidget *, DuiDataStore &))); + connect(this, SIGNAL(receiveOperation(QDBusPendingCallWatcher *)), manager, SLOT(receiveOperation(QDBusPendingCallWatcher *))); + + DuiAppletId appletId("ut_duiappletinstancemanager", "testmanager", 5); + QDBusMessage msg; + QDBusPendingCall call = QDBusPendingCall::fromCompletedCall(msg); + QDBusPendingCallWatcher watcher(call, NULL); + watcher.setProperty("appletId", appletId.toString()); + + // When the D-Bus call fails the desktop file should not be relayed + callError = true; + emit receiveOperation(&watcher); + QCOMPARE(spy.count(), 1); + QCOMPARE(gDuiAppletHandleStub->stubCallCount("initPlaceHolder"), 1); + QCOMPARE(gDuiAppletHandleStub->stubLastCallTo("initPlaceHolder").parameter(0).instanceId(), (uint)5); + QCOMPARE(gDuiAppletHandleStub->stubLastCallTo("initPlaceHolder").parameter(2), qtTrId("duiappletinstancedata_nopackagemetadata")); +} + +void Ut_DuiAppletInstanceManager::testReceiveUnknownOperation() +{ + QSignalSpy spy(manager, SIGNAL(appletInstantiated(DuiWidget *, DuiDataStore &))); + connect(this, SIGNAL(receiveOperation(QDBusPendingCallWatcher *)), manager, SLOT(receiveOperation(QDBusPendingCallWatcher *))); + + DuiAppletId appletId("ut_duiappletinstancemanager", "testmanager", 5); + QDBusMessage msg; + QDBusPendingCall call = QDBusPendingCall::fromCompletedCall(msg); + QDBusPendingCallWatcher watcher(call, NULL); + watcher.setProperty("appletId", appletId.toString()); + + // When the operation is not known the desktop file should not be relayed + callError = false; + emit receiveOperation(&watcher); + QCOMPARE(instantiateAppletPlaceHolderMetaData.count(), 0); + QCOMPARE(spy.count(), 1); + QCOMPARE(gDuiAppletHandleStub->stubCallCount("initPlaceHolder"), 1); + QCOMPARE(gDuiAppletHandleStub->stubLastCallTo("initPlaceHolder").parameter(0).instanceId(), (uint)5); + QCOMPARE(gDuiAppletHandleStub->stubLastCallTo("initPlaceHolder").parameter(2), qtTrId("duiappletinstancedata_nopackagemetadata")); +} + +void Ut_DuiAppletInstanceManager::testReceiveInstallOperation() +{ + QSignalSpy spy(manager, SIGNAL(appletInstantiated(DuiWidget *, DuiDataStore &))); + connect(this, SIGNAL(receiveOperation(QDBusPendingCallWatcher *)), manager, SLOT(receiveOperation(QDBusPendingCallWatcher *))); + + DuiAppletId appletId("ut_duiappletinstancemanager", "testmanager", 5); + QDBusMessage msg; + QDBusPendingCall call = QDBusPendingCall::fromCompletedCall(msg); + QDBusPendingCallWatcher watcher(call, NULL); + watcher.setProperty("appletId", appletId.toString()); + + // When the operation is Install the desktop file should be relayed + replyDataString = "Install"; + emit receiveOperation(&watcher); + QCOMPARE(spy.count(), 1); + QCOMPARE(gDuiAppletHandleStub->stubCallCount("initPlaceHolder"), 1); + QCOMPARE(gDuiAppletHandleStub->stubLastCallTo("initPlaceHolder").parameter(0).instanceId(), (uint)5); + QCOMPARE(gDuiAppletHandleStub->stubLastCallTo("initPlaceHolder").parameter(2), QString()); +} + +QTEST_APPLESS_MAIN(Ut_DuiAppletInstanceManager) diff --git a/tests/ut_duiappletinstancemanager/ut_duiappletinstancemanager.h b/tests/ut_duiappletinstancemanager/ut_duiappletinstancemanager.h new file mode 100644 index 000000000..d3cf3c269 --- /dev/null +++ b/tests/ut_duiappletinstancemanager/ut_duiappletinstancemanager.h @@ -0,0 +1,112 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIAPPLETINSTANCEMANAGER_H +#define UT_DUIAPPLETINSTANCEMANAGER_H + +#include +#include +#include "duiappletinstancemanager.h" + +class DuiApplication; +class DuiWindow; +class MockDataStore; +class DuiDataStore; +class QDBusPendingCallWatcher; + +class DuiTestAppletInstanceManager : public DuiAppletInstanceManager +{ +public: + DuiTestAppletInstanceManager(const QString &identifier, DuiDataStore *dataStore = NULL); +}; + +// AppletInstanceCollection is used to store all instantiated applets into. +// The collection can be used to verify that correct applets were instantiated during the test run. +class AppletInstanceCollection : public QObject +{ + Q_OBJECT + +public: + virtual ~AppletInstanceCollection(); + int count() const; + DuiWidget *at(int index) const; + +public slots: + void addInstance(DuiWidget *widget, DuiDataStore &store); + void removeInstance(DuiWidget *widget); + +private: + QList instances; +}; + +class Ut_DuiAppletInstanceManager : public QObject +{ + Q_OBJECT + +public: + // For storing information about the D-Bus stub calls made + static bool captureCalls; + static QString callServiceName; + static QString callObjectPath; + static QString callInterface; + static QList callMethods; + static QList< QList > callArguments; + static bool callError; + static QString replyDataString; + +private: + DuiApplication *app; + DuiWindow *window; + MockDataStore *defaultDataStore; + DuiTestAppletInstanceManager *manager; + QString dataPath; + +signals: + void appletUninstalled(const QString &desktopFile); + void operationComplete(const QString &operation, const QString &pkg, const QString &error); + void receiveOperation(QDBusPendingCallWatcher *watcher); + +private slots: + void initTestCase(); + void cleanupTestCase(); + + void init(); + void cleanup(); + + void testInProcessAppletRestoration(); + void testOutOfProcessAppletRestoration(); + void testAppletDataStoring(); + void testAppletInstantiation(); + void testAppletInstantiationWithMissingDesktopFiles(); + void testAppletInstanceRemoval(); + void testAppletUninstallation(); + void testAppletInstanceDataStoreIsNonReadWrite(); + void testOOPAppletStartsToBrokenState(); + void testPreconfiguredAppletInstances(); + void testInstallingAppletFromPackage(); + void testInstallationOperationComplete(); + void testInstallationOperationCompleteForUnknownPackage(); + void testUnknownOperationComplete(); + void testRestoringAppletsBeingInstalled(); + void testReceiveOperationFailed(); + void testReceiveUnknownOperation(); + void testReceiveInstallOperation(); +}; + +#endif // UT_DUIAPPLETINSTANCEMANAGER_H diff --git a/tests/ut_duiappletinstancemanager/ut_duiappletinstancemanager.pro b/tests/ut_duiappletinstancemanager/ut_duiappletinstancemanager.pro new file mode 100644 index 000000000..e79e521ac --- /dev/null +++ b/tests/ut_duiappletinstancemanager/ut_duiappletinstancemanager.pro @@ -0,0 +1,25 @@ +include(../common_top.pri) +TARGET = ut_duiappletinstancemanager +INCLUDEPATH += $$DUISRCDIR/mashup/appletcommunication $$DUISRCDIR/mashup/appletinterface $$DUISRCDIR/mashup/mashup + +QT += core network gui svg dbus + +# unit test and unit classes +SOURCES += \ + ut_duiappletinstancemanager.cpp \ + $$DUISRCDIR/mashup/mashup/duiappletinstancemanager.cpp \ + $$DUISRCDIR/mashup/mashup/duiappletinstancedata.cpp \ + $$DUISRCDIR/mashup/mashup/duiappletid.cpp \ + ../stubs/stubbase.cpp + +# unit test and unit classes +HEADERS += \ + ut_duiappletinstancemanager.h \ + $$DUISRCDIR/mashup/mashup/duiappletinstancemanager.h \ + $$DUISRCDIR/mashup/mashup/duiappletinstancedata.h \ + $$DUISRCDIR/mashup/mashup/duiappletid.h \ + $$DUISRCDIR/mashup/mashup/duiapplethandle.h \ + $$DUISRCDIR/mashup/mashup/duiapplethandlemodel.h \ + $$DUISRCDIR/mashup/mashup/duiappletinstancemanagerdbusadaptor.h + +include(../common_bot.pri) diff --git a/tests/ut_duiappletinstantiator/.gitignore b/tests/ut_duiappletinstantiator/.gitignore new file mode 100644 index 000000000..1a85a070d --- /dev/null +++ b/tests/ut_duiappletinstantiator/.gitignore @@ -0,0 +1 @@ +ut_duiappletinstantiator diff --git a/tests/ut_duiappletinstantiator/ut_duiappletinstantiator.cpp b/tests/ut_duiappletinstantiator/ut_duiappletinstantiator.cpp new file mode 100644 index 000000000..f35b0919e --- /dev/null +++ b/tests/ut_duiappletinstantiator/ut_duiappletinstantiator.cpp @@ -0,0 +1,319 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include +#include "ut_duiappletinstantiator.h" +#include "duiappletinstantiator.h" + +// QDBusInterface stubs (used by DuiRemoteAction) +QDBusInterface::QDBusInterface(const QString &service, const QString &path, const QString &interface, const QDBusConnection &connection, QObject *parent) : QDBusAbstractInterface(service, path, interface.toUtf8().constData(), connection, parent) +{ + Ut_DuiAppletInstantiator::callServiceNames.append(service); + Ut_DuiAppletInstantiator::callObjectPaths.append(path); + Ut_DuiAppletInstantiator::callInterfaces.append(interface); +} + +QDBusInterface::~QDBusInterface() +{ +} + +// QDBusAbstractInterface stubs (used by DuiRemoteAction) +QDBusMessage QDBusAbstractInterface::call(QDBus::CallMode, const QString &method, + const QVariant &arg1, + const QVariant &arg2, + const QVariant &arg3, + const QVariant &arg4, + const QVariant &arg5, + const QVariant &arg6, + const QVariant &arg7, + const QVariant &arg8) +{ + if (Ut_DuiAppletInstantiator::captureCalls) { + QList args; + if (arg1.isValid()) { + args.append(arg1); + if (arg2.isValid()) { + args.append(arg2); + if (arg3.isValid()) { + args.append(arg3); + if (arg4.isValid()) { + args.append(arg4); + if (arg5.isValid()) { + args.append(arg5); + if (arg6.isValid()) { + args.append(arg6); + if (arg7.isValid()) { + args.append(arg7); + if (arg8.isValid()) { + args.append(arg8); + } + } + } + } + } + } + } + } + Ut_DuiAppletInstantiator::callMethods.append(method); + Ut_DuiAppletInstantiator::callArguments.append(args); + } + + return QDBusMessage(); +} + +// QDBusPendingCall stubs (used by DuiAppletInstantiator) +QDBusPendingCall QDBusAbstractInterface::asyncCall(const QString &method, + const QVariant &arg1, + const QVariant &arg2, + const QVariant &arg3, + const QVariant &arg4, + const QVariant &arg5, + const QVariant &arg6, + const QVariant &arg7, + const QVariant &arg8) + +{ + if (Ut_DuiAppletInstantiator::captureCalls) { + QList args; + if (arg1.isValid()) { + args.append(arg1); + if (arg2.isValid()) { + args.append(arg2); + if (arg3.isValid()) { + args.append(arg3); + if (arg4.isValid()) { + args.append(arg4); + if (arg5.isValid()) { + args.append(arg5); + if (arg6.isValid()) { + args.append(arg6); + if (arg7.isValid()) { + args.append(arg7); + if (arg8.isValid()) { + args.append(arg8); + } + } + } + } + } + } + } + } + Ut_DuiAppletInstantiator::callMethods.append(Ut_DuiAppletInstantiator::callInterfaces.last() + '.' + method); + Ut_DuiAppletInstantiator::callArguments.append(args); + } + + return QDBusPendingCall::fromCompletedCall(QDBusMessage()); +} + +bool QDBusPendingCall::isError() const +{ + return Ut_DuiAppletInstantiator::callError; +} + +// QDBusPendingReply stubs (used by DuiAppletInstantiator) +void QDBusPendingReplyData::setMetaTypes(int, int const *) +{ +} + +QVariant QDBusPendingReplyData::argumentAt(int) const +{ + return Ut_DuiAppletInstantiator::replyDataMap; +} + +bool Ut_DuiAppletInstantiator::captureCalls = false; +QList Ut_DuiAppletInstantiator::callServiceNames; +QList Ut_DuiAppletInstantiator::callObjectPaths; +QList Ut_DuiAppletInstantiator::callInterfaces; +QList Ut_DuiAppletInstantiator::callMethods; +QList< QList > Ut_DuiAppletInstantiator::callArguments; +bool Ut_DuiAppletInstantiator::callError = false; +QMap Ut_DuiAppletInstantiator::replyDataMap; + +void Ut_DuiAppletInstantiator::initTestCase() +{ +} + +void Ut_DuiAppletInstantiator::cleanupTestCase() +{ +} + +void Ut_DuiAppletInstantiator::init() +{ + captureCalls = false; + callServiceNames.clear(); + callObjectPaths.clear(); + callInterfaces.clear(); + callMethods.clear(); + callArguments.clear(); + callError = false; + replyDataMap.clear(); + connect(this, SIGNAL(receivePackageData(QDBusPendingCallWatcher *)), DuiAppletInstantiator::instance(), SLOT(receivePackageData(QDBusPendingCallWatcher *))); +} + +void Ut_DuiAppletInstantiator::cleanup() +{ +} + +void Ut_DuiAppletInstantiator::testInstantiateAppletInPackageToKnownCanvas() +{ + static const QString TEST_PACKAGE_NAME = "testPackage.deb"; + static const QString TEST_PACKAGE_BASE_NAME = "testPackage"; + static const QString CANVAS_DBUS_ADDRESS = "service/path/to/canvas"; + captureCalls = true; + + // Test that telling the instantiator that a package is being installed asks for the meta data of the package + DuiAppletInstantiator::instance()->instantiateAppletsInPackage(TEST_PACKAGE_NAME, CANVAS_DBUS_ADDRESS); + QCOMPARE(callServiceNames.last(), QString("com.nokia.package_manager")); + QCOMPARE(callObjectPaths.last(), QString("/com/nokia/package_manager")); + QCOMPARE(callInterfaces.last(), QString("com.nokia.package_manager")); + QCOMPARE(callMethods.count(), 1); + QCOMPARE(callMethods.at(0), QString("com.nokia.package_manager.FetchPackageData")); + QCOMPARE(callArguments.at(0).count(), 2); + QCOMPARE(callArguments.at(0).at(0).type(), QVariant::String); + QCOMPARE(callArguments.at(0).at(0).toString(), TEST_PACKAGE_BASE_NAME); + QCOMPARE(callArguments.at(0).at(1).type(), QVariant::String); + QCOMPARE(callArguments.at(0).at(1).toString(), QString()); +} + +void Ut_DuiAppletInstantiator::testInstantiateAppletInPackageToKnownCanvasFromLocalFile() +{ + static const QString TEST_PACKAGE_NAME = "./testPackage.deb"; + static const QString CANVAS_DBUS_ADDRESS = "service/path/to/canvas"; + captureCalls = true; + + // Test that telling the instantiator that a package is being installed asks for the meta data of the package + DuiAppletInstantiator::instance()->instantiateAppletsInPackage(TEST_PACKAGE_NAME, CANVAS_DBUS_ADDRESS); + QCOMPARE(callServiceNames.last(), QString("com.nokia.package_manager")); + QCOMPARE(callObjectPaths.last(), QString("/com/nokia/package_manager")); + QCOMPARE(callInterfaces.last(), QString("com.nokia.package_manager")); + QCOMPARE(callMethods.count(), 1); + QCOMPARE(callMethods.at(0), QString("com.nokia.package_manager.FetchPackageDataFile")); + QCOMPARE(callArguments.at(0).count(), 1); + QCOMPARE(callArguments.at(0).at(0).type(), QVariant::String); + QCOMPARE(callArguments.at(0).at(0).toString(), TEST_PACKAGE_NAME); +} + +void Ut_DuiAppletInstantiator::testInstantiateAppletInPackageToInvalidCanvas() +{ + static const QString TEST_PACKAGE_NAME = "testPackage.deb"; + static const QString INVALID_CANVAS_DBUS_ADDRESS = "invalidCanvas"; + captureCalls = true; + + // Test that instantiating a package to a canvas with an invalid address does nothing + DuiAppletInstantiator::instance()->instantiateAppletsInPackage(TEST_PACKAGE_NAME, INVALID_CANVAS_DBUS_ADDRESS); + + QCOMPARE(callMethods.count(), 0); +} + +void Ut_DuiAppletInstantiator::testReceivePackageData() +{ + static const QString TEST_PACKAGE_NAME = "testPackage.deb"; + static const QString CANVAS_DBUS_ADDRESS = "service/path/to/canvas"; + static const QString DESKTOP_FILE_NAME = "test.desktop"; + captureCalls = true; + + // Test that receiving the meta data of the package being installed informs the target canvas about it and starts the installation + QDBusMessage msg; + QDBusPendingCall call = QDBusPendingCall::fromCompletedCall(msg); + QDBusPendingCallWatcher watcher(call, NULL); + watcher.setProperty("packageName", TEST_PACKAGE_NAME); + watcher.setProperty("canvasDBusAddress", CANVAS_DBUS_ADDRESS); + replyDataMap.insert("Maemo-Desktop-File", DESKTOP_FILE_NAME); + emit receivePackageData(&watcher); + + // The canvas should be told + QCOMPARE(callServiceNames.first(), QString("service")); + QCOMPARE(callObjectPaths.first(), QString("/path/to/canvas")); + QCOMPARE(callInterfaces.first(), QString("org.maemo.dui.DuiAppletInstanceManager")); + QVERIFY(callMethods.count() > 1); + QCOMPARE(callMethods.first(), QString("instantiateAppletFromPackage")); + QCOMPARE(callArguments.first().count(), 2); + QCOMPARE(callArguments.first().at(0).type(), QVariant::String); + QCOMPARE(callArguments.first().at(0).toString(), TEST_PACKAGE_NAME); + QCOMPARE(callArguments.first().at(1).type(), QVariant::Map); + QCOMPARE(callArguments.first().at(1).toMap().value("Maemo-Desktop-File"), QVariant(DESKTOP_FILE_NAME)); + + // The installation should start + QCOMPARE(callServiceNames.last(), QString("com.nokia.package_manager")); + QCOMPARE(callObjectPaths.last(), QString("/com/nokia/package_manager")); + QCOMPARE(callInterfaces.last(), QString("com.nokia.package_manager")); + QCOMPARE(callMethods.last(), QString("Install")); + QCOMPARE(callArguments.last().count(), 1); + QCOMPARE(callArguments.last().at(0).type(), QVariant::String); + QCOMPARE(callArguments.last().at(0).toString(), TEST_PACKAGE_NAME); +} + +void Ut_DuiAppletInstantiator::testReceivePackageDataFromLocalFile() +{ + static const QString TEST_PACKAGE_NAME = "./testPackage.deb"; + static const QString CANVAS_DBUS_ADDRESS = "service/path/to/canvas"; + static const QString DESKTOP_FILE_NAME = "test.desktop"; + captureCalls = true; + + // Test that receiving the meta data of the package being installed informs the target canvas about it and starts the installation + QDBusMessage msg; + QDBusPendingCall call = QDBusPendingCall::fromCompletedCall(msg); + QDBusPendingCallWatcher watcher(call, NULL); + watcher.setProperty("packageName", TEST_PACKAGE_NAME); + watcher.setProperty("canvasDBusAddress", CANVAS_DBUS_ADDRESS); + replyDataMap.insert("Maemo-Desktop-File", DESKTOP_FILE_NAME); + emit receivePackageData(&watcher); + + // The installation should start + QCOMPARE(callServiceNames.last(), QString("com.nokia.package_manager")); + QCOMPARE(callObjectPaths.last(), QString("/com/nokia/package_manager")); + QCOMPARE(callInterfaces.last(), QString("com.nokia.package_manager")); + QCOMPARE(callMethods.last(), QString("InstallFile")); + QCOMPARE(callArguments.last().count(), 1); + QCOMPARE(callArguments.last().at(0).type(), QVariant::String); + QCOMPARE(callArguments.last().at(0).toString(), TEST_PACKAGE_NAME); +} + +void Ut_DuiAppletInstantiator::testReceivePackageDataWithError() +{ + static const QString TEST_PACKAGE_NAME = "testPackage.deb"; + static const QString CANVAS_DBUS_ADDRESS = "service/path/to/canvas"; + captureCalls = true; + + // Test that receiving an error instead of meta data does nothing + callError = true; + QDBusMessage msg; + QDBusPendingCall call = QDBusPendingCall::fromCompletedCall(msg); + QDBusPendingCallWatcher watcher(call, NULL); + watcher.setProperty("packageName", TEST_PACKAGE_NAME); + watcher.setProperty("canvasDBusAddress", CANVAS_DBUS_ADDRESS); + emit receivePackageData(&watcher); + + // The canvas should be told with no meta data + QCOMPARE(callServiceNames.first(), QString("service")); + QCOMPARE(callObjectPaths.first(), QString("/path/to/canvas")); + QCOMPARE(callInterfaces.first(), QString("org.maemo.dui.DuiAppletInstanceManager")); + QVERIFY(callMethods.count() > 1); + QCOMPARE(callMethods.first(), QString("instantiateAppletFromPackage")); + QCOMPARE(callArguments.first().count(), 2); + QCOMPARE(callArguments.first().at(0).type(), QVariant::String); + QCOMPARE(callArguments.first().at(0).toString(), TEST_PACKAGE_NAME); + QCOMPARE(callArguments.first().at(1).type(), QVariant::Map); + QCOMPARE(callArguments.first().at(1).toMap().size(), 0); +} + +QTEST_APPLESS_MAIN(Ut_DuiAppletInstantiator) diff --git a/tests/ut_duiappletinstantiator/ut_duiappletinstantiator.h b/tests/ut_duiappletinstantiator/ut_duiappletinstantiator.h new file mode 100644 index 000000000..8cdbf2696 --- /dev/null +++ b/tests/ut_duiappletinstantiator/ut_duiappletinstantiator.h @@ -0,0 +1,73 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIAPPLETINSTANTIATOR_H +#define UT_DUIAPPLETINSTANTIATOR_H + +#include +#include + +class DuiAppletInstantiator; +class QDBusPendingCallWatcher; + +class Ut_DuiAppletInstantiator : public QObject +{ + Q_OBJECT + +public: + // For storing information about the D-Bus stub calls made + static bool captureCalls; + static QList callServiceNames; + static QList callObjectPaths; + static QList callInterfaces; + static QList callMethods; + static QList< QList > callArguments; + static bool callError; + static QMap replyDataMap; + +signals: + void receivePackageData(QDBusPendingCallWatcher *watcher); + +private slots: + // Called before the first testfunction is executed + void initTestCase(); + // Called after the last testfunction was executed + void cleanupTestCase(); + // Called before each testfunction is executed + void init(); + // Called after every testfunction + void cleanup(); + + // Test cases + void testInstantiateAppletInPackageToKnownCanvas(); + void testInstantiateAppletInPackageToKnownCanvasFromLocalFile(); + void testInstantiateAppletInPackageToInvalidCanvas(); + void testReceivePackageData(); + void testReceivePackageDataFromLocalFile(); + void testReceivePackageDataWithError(); + + // Future test cases + /* + void testInstantiateAppletInPackageToUnknownCanvas(); + void testInstantiateAppletsInMetaPackageToKnownCanvas(); + void testInstantiateAppletsInMetaPackageToUnknownCanvas(); + */ +}; + +#endif diff --git a/tests/ut_duiappletinstantiator/ut_duiappletinstantiator.pro b/tests/ut_duiappletinstantiator/ut_duiappletinstantiator.pro new file mode 100644 index 000000000..ffbd36059 --- /dev/null +++ b/tests/ut_duiappletinstantiator/ut_duiappletinstantiator.pro @@ -0,0 +1,17 @@ +include(../common_top.pri) +TARGET = ut_duiappletinstantiator +INCLUDEPATH += \ + $$DUISRCDIR/mashup/appletinstallation + +# unit test and unit classes +SOURCES += \ + ut_duiappletinstantiator.cpp \ + $$DUISRCDIR/mashup/appletinstallation/duiappletinstantiator.cpp + +# unit test and unit classes +HEADERS += \ + ut_duiappletinstantiator.h \ + $$DUISRCDIR/mashup/appletinstallation/duiappletinstantiator_p.h \ + $$DUISRCDIR/mashup/appletinstallation/duiappletinstantiator.h + +include(../common_bot.pri) diff --git a/tests/ut_duiappletinventory/.gitignore b/tests/ut_duiappletinventory/.gitignore new file mode 100644 index 000000000..90029dfe8 --- /dev/null +++ b/tests/ut_duiappletinventory/.gitignore @@ -0,0 +1 @@ +ut_duiappletinventory diff --git a/tests/ut_duiappletinventory/ut_duiappletinventory.cpp b/tests/ut_duiappletinventory/ut_duiappletinventory.cpp new file mode 100644 index 000000000..76b0f8a8c --- /dev/null +++ b/tests/ut_duiappletinventory/ut_duiappletinventory.cpp @@ -0,0 +1,458 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duiappletinventory.h" + +#include +#include +#include +#include +#include "ut_duiappletinventory.h" +#include "duiappletinstantiator.h" +#include "duimashupcanvas.h" +#include +#include +#include +#include +#include +#include + +QStringList Ut_DuiAppletInventory::watchedDirectories; +QStringList Ut_DuiAppletInventory::appletList; +bool Ut_DuiAppletInventory::addPathCalled = false; +bool Ut_DuiAppletInventory::directoriesCalled = false; +bool Ut_DuiAppletInventory::pluginPathExists = true; +bool Ut_DuiAppletInventory::pluginPathIsReadable = true; +bool Ut_DuiAppletInventory::tooManyMonitoredPaths = false; + +// Test applet source +QList gTestAppletSourceCreatedWidgets; +bool gTestAppletSourceCreateWidget = true; +DuiWidget *TestAppletSource::constructWidget() +{ + if (gTestAppletSourceCreateWidget) { + DuiWidget *sourceWidget = new DuiWidget; + gTestAppletSourceCreatedWidgets.append(sourceWidget); + return sourceWidget; + } else { + return NULL; + } +} + +// QPluginLoader stubs +QStringList gQPluginLoaderFileNames; +QPluginLoader::QPluginLoader(const QString &fileName, QObject *parent) +{ + Q_UNUSED(parent); + // The plugin will load testability.so if libdui is compiled with flag TESTABILITY=on + if (!fileName.contains("testability")) { + gQPluginLoaderFileNames.append(fileName); + } +} + +QPluginLoader::~QPluginLoader() +{ +} + +bool gQPluginLoaderInstanceCreate = true; +QObject *QPluginLoader::instance() +{ + return gQPluginLoaderInstanceCreate ? new TestAppletSource : NULL; +} + +// QFileInfo stubs +bool gQFileInfoExists; +bool QFileInfo::exists() const +{ + return gQFileInfoExists; +} + +bool gQFileInfoIsFile; +bool QFileInfo::isFile() const +{ + return gQFileInfoIsFile; +} + +// Method mocks +void QFileSystemWatcher::addPath(const QString &path) +{ + if (!Ut_DuiAppletInventory::tooManyMonitoredPaths) + Ut_DuiAppletInventory::watchedDirectories.push_back(path); + + Ut_DuiAppletInventory::addPathCalled = true; +} + +QStringList QFileSystemWatcher::directories() const +{ + Ut_DuiAppletInventory::directoriesCalled = true; + + return Ut_DuiAppletInventory::watchedDirectories; +} + +bool QDir::exists() const +{ + return Ut_DuiAppletInventory::pluginPathExists; +} + +bool QDir::isReadable() const +{ + return Ut_DuiAppletInventory::pluginPathIsReadable; +} + +QStringList QDir::entryList(const QStringList &nameFilters, Filters /*filters*/, SortFlags /*sort*/) const +{ + QStringList filteredAppletList; + foreach(QString filter, nameFilters) { + if (filter == "*.desktop") { + foreach(QString appletPath, Ut_DuiAppletInventory::appletList) { + if (appletPath.right(8) == ".desktop") { + filteredAppletList.push_back(appletPath); + } + } + } + } + return filteredAppletList; +} + +// Unit test cases +void Ut_DuiAppletInventory::init() +{ + // Create DesktopPluginInventory instance + inventory = new DuiAppletInventory(); + inventory->setMashupCanvas(*mashupCanvas); + connect(this, SIGNAL(appletPathChanged(QString)), inventory, SLOT(appletPathChanged(QString))); + connect(this, SIGNAL(instantiateAppletsFromPackage(QString)), inventory, SLOT(instantiateAppletsFromPackage(QString))); + + watchedDirectories.clear(); + appletList.clear(); + addPathCalled = false; + directoriesCalled = false; + pluginPathExists = true; + pluginPathIsReadable = true; + tooManyMonitoredPaths = false; + gDuiAppletButtonStub->stubSetReturnValue("initialize", true); + gQFileInfoExists = false; + gQFileInfoIsFile = false; + + appWin->scene()->addItem(inventory); +} + +void Ut_DuiAppletInventory::cleanup() +{ + // Destroy inventory (which will destroy the applet buttons created by it) + delete inventory; +} + +// Tests +void Ut_DuiAppletInventory::initTestCase() +{ + // Create a DuiApplication + static int argc = 1; + static char *app_name[1] = { (char *) "./ut_duiappletinventory" }; + app = new DuiApplication(argc, app_name); + appWin = new DuiApplicationWindow; + + mashupCanvas = new DuiMashupCanvas("testcanvas"); +} + +void Ut_DuiAppletInventory::cleanupTestCase() +{ + // Destroy DuiApplication and desktop + delete mashupCanvas; + delete appWin; + delete app; +} + +void Ut_DuiAppletInventory::testSuccessfulInitialization() +{ + inventory->setEnabled(true); + QVERIFY(addPathCalled); + QVERIFY(directoriesCalled); +} + +void Ut_DuiAppletInventory::testInitializationWithInvalidPluginPath() +{ + // Make the plugin path not exist; it's OK, there just won't be any applets + pluginPathExists = false; + inventory->setEnabled(true); + QVERIFY(!addPathCalled); + QVERIFY(!directoriesCalled); + + // Make the plugin path exist but not readable; it's OK, there just won't be any applets + pluginPathExists = true; + pluginPathIsReadable = false; + inventory->setEnabled(true); + QVERIFY(!addPathCalled); + QVERIFY(!directoriesCalled); +} + +void Ut_DuiAppletInventory::testStartWithExistingApplets() +{ + // Initialize path with existing applet metadata files + appletList.push_back("test0.desktop"); + appletList.push_back("test1.desktop"); + + // Make applet initialization succeed + gDuiAppletButtonStub->stubSetReturnValue("initialize", true); + + // Start inventory + inventory->setEnabled(true); + + // Make sure that the inventory added widgets for both applets in itself. + QCOMPARE(inventory->model()->widgets().count(), 2); + + for (int i = 0; i < inventory->model()->widgets().count(); i++) { + DuiAppletButton *b = dynamic_cast(inventory->model()->widgets().at(i)); + + // Each widget must be an DuiAppletButton + QVERIFY(b != NULL); + + // Make sure that the applet was initialized with the correct name + // QCOMPARE(b->metadataFilename(), QString().sprintf("%stest%d.desktop", APPLET_DATA "/", i)); + } +} + +void Ut_DuiAppletInventory::testStartWithInvalidApplets() +{ + // Initialize path with existing applet metadata files + appletList.push_back("test0.desktop"); + appletList.push_back("test1.desktop"); + + // Make applet initialization fail + gDuiAppletButtonStub->stubSetReturnValue("initialize", false); + + // Start inventory + inventory->setEnabled(true); + + // Make sure that the inventory did not add invalid widgets. + QCOMPARE(inventory->model()->widgets().count(), 0); +} + +void Ut_DuiAppletInventory::testAppletAdd() +{ + // Start inventory + inventory->setEnabled(true); + + // There should be no widgets in the view + QCOMPARE(inventory->model()->widgets().count(), 0); + + // Add an applet metadata file + appletList.push_back("test0.desktop"); + + // Fake a directory change notification + emit appletPathChanged(QDir(APPLET_DATA).absolutePath()); + + // There should be one widget in the view + QCOMPARE(inventory->model()->widgets().count(), 1); +} + +void Ut_DuiAppletInventory::testAppletRemove() +{ + // Add applet metadata files + appletList.push_back("test0.desktop"); + appletList.push_back("test1.desktop"); + appletList.push_back("test2.desktop"); + + // Start inventory + inventory->setEnabled(true); + + // There should be three widgets in the view + QCOMPARE(inventory->model()->widgets().count(), 3); + + // "Delete" the second applet metadata file + appletList.removeAt(1); + + // Spy on applet uninstallation signal + QSignalSpy uninstallSpy(inventory, SIGNAL(appletUninstalled(QString))); + + // Fake a directory change notification + emit appletPathChanged(QDir(APPLET_DATA).absolutePath()); + + // There should be two widgets in the view + QCOMPARE(inventory->model()->widgets().count(), 2); + + // The uninstall signal should have been called once... + QCOMPARE(uninstallSpy.count(), 1); + + // ...with the argument test1.desktop + QCOMPARE(uninstallSpy.takeFirst().at(0).toString(), QString(QDir(APPLET_DATA).absolutePath()) + "/test1.desktop"); +} + +void Ut_DuiAppletInventory::testCategories_data() +{ + QTest::addColumn("initialAppletInventoryCategories"); + QTest::addColumn("changedAppletInventoryCategories"); + QTest::addColumn("appletCategories"); + QTest::addColumn("initialWidgetCount"); + QTest::addColumn("changedWidgetCount"); + + QStringList initialAppletInventoryCategories; + initialAppletInventoryCategories.append("Utility"); + initialAppletInventoryCategories.append("Game"); + QStringList changedAppletInventoryCategories; + changedAppletInventoryCategories.append("Utility"); + QStringList applet0Categories; + applet0Categories.append("Utility"); + QStringList applet1Categories; + applet1Categories.append("Utility"); + applet1Categories.append("Game"); + QStringList applet2Categories; + applet2Categories.append("Utility"); + applet2Categories.append("Office"); + QStringList applet3Categories; + applet3Categories.append("Game"); + QStringList applet4Categories; + applet4Categories.append("Office"); + QTest::newRow("Includes one") << initialAppletInventoryCategories << changedAppletInventoryCategories << applet0Categories << 1 << 1; + QTest::newRow("Includes one") << initialAppletInventoryCategories << changedAppletInventoryCategories << applet1Categories << 1 << 1; + QTest::newRow("Includes one") << initialAppletInventoryCategories << changedAppletInventoryCategories << applet2Categories << 1 << 1; + QTest::newRow("Includes one") << initialAppletInventoryCategories << changedAppletInventoryCategories << applet3Categories << 1 << 0; + QTest::newRow("Includes one") << initialAppletInventoryCategories << changedAppletInventoryCategories << applet4Categories << 0 << 0; +} + +void Ut_DuiAppletInventory::testCategories() +{ + QFETCH(QStringList, initialAppletInventoryCategories); + QFETCH(QStringList, changedAppletInventoryCategories); + QFETCH(QStringList, appletCategories); + QFETCH(int, initialWidgetCount); + QFETCH(int, changedWidgetCount); + + // Set the categories for the applet inventory + inventory->setCategories(initialAppletInventoryCategories); + + // Add applet metadata files + appletList.push_back("test0.desktop"); + + // Set the categories of the applets + gDuiDesktopEntryStub->stubSetReturnValue("categories", appletCategories); + + // Start inventory + inventory->setEnabled(true); + + // There should be four widgets in the view + QCOMPARE(inventory->model()->widgets().count(), initialWidgetCount); + + for (int i = 0; i < inventory->model()->widgets().count(); i++) { + DuiAppletButton *b = dynamic_cast(inventory->model()->widgets().at(i)); + + // Each widget must be an DuiAppletButton + QVERIFY(b != NULL); + + // Make sure that the applet was initialized with the correct name +// QCOMPARE(b->metadataFilename(), QString().sprintf("%stest%d.desktop", APPLET_DATA"/", i)); + } + + // Reset the categories for the applet inventory + inventory->setCategories(changedAppletInventoryCategories); + + // There should be three widgets in the view + QCOMPARE(inventory->model()->widgets().count(), changedWidgetCount); + + for (int i = 0; i < inventory->model()->widgets().count(); i++) { + DuiAppletButton *b = dynamic_cast(inventory->model()->widgets().at(i)); + + // Each widget must be an DuiAppletButton + QVERIFY(b != NULL); + + // Make sure that the applet was initialized with the correct name +// QCOMPARE(b->metadataFilename(), QString().sprintf("%stest%d.desktop", APPLET_DATA"/", i)); + } +} + +void Ut_DuiAppletInventory::testEnabled() +{ + // The close button should not be visible by default + QVERIFY(!inventory->model()->closeButtonVisible()); + + // Enabling the inventory should show the close button + inventory->setEnabled(true); + QVERIFY(inventory->model()->closeButtonVisible()); + + // Disabling the inventory should hide the close button + inventory->setEnabled(false); + QVERIFY(!inventory->model()->closeButtonVisible()); +} + +void Ut_DuiAppletInventory::testOnlyDotDesktopFilesAreParsed() +{ + // Add applet metadata files + appletList.push_back("test0.desktop"); + appletList.push_back("noextension"); + appletList.push_back("test1.desktop"); + appletList.push_back("test2.junkextension"); + + // Start inventory + inventory->setEnabled(true); + + // There should be two widgets in the view + QCOMPARE(inventory->model()->widgets().count(), 2); +} + +void Ut_DuiAppletInventory::testAppletInstallationSourcesLoading() +{ + // No sources initially + inventory->setEnabled(true); + QCOMPARE(inventory->model()->installationSources().count(), 0); + + // Add some sources + gQFileInfoExists = true; + gQFileInfoIsFile = true; + QString sourceName1 = "libFooAppletSource.so"; + QString sourceName2 = "libBarAppletSource.so"; + QStringList sourceList; + sourceList << sourceName1 << sourceName2; + inventory->setInstallationSources(QStringList() << sourceName1 << sourceName2); + + // Test that correct plugin is loaded + QCOMPARE(gQPluginLoaderFileNames[0], QFileInfo(QString(APPLET_INSTALLATION_SOURCES), sourceName1).absoluteFilePath()); + QCOMPARE(inventory->model()->installationSources().count(), 2); + QCOMPARE(inventory->model()->installationSources(), gTestAppletSourceCreatedWidgets); + + // Try to instantiate an applet from a package and check inventory is closed + QSignalSpy spy(inventory, SIGNAL(hideAppletInventory())); + emit instantiateAppletsFromPackage("FooAppletSource"); + QCOMPARE(spy.count(), 1); + spy.clear(); + + // Nonexisting sources are not added + gQFileInfoExists = false; + inventory->setInstallationSources(QStringList() << sourceName1); + QCOMPARE(inventory->model()->installationSources().count(), 0); + + // Nonfile sources are not added + gQFileInfoIsFile = false; + inventory->setInstallationSources(QStringList() << sourceName2); + QCOMPARE(inventory->model()->installationSources().count(), 0); + + // If plugin doesn't return correct interface, source is not added + gQFileInfoExists = true; + gQFileInfoIsFile = true; + gQPluginLoaderInstanceCreate = false; + inventory->setInstallationSources(QStringList() << sourceName1 << sourceName2); + QCOMPARE(inventory->model()->installationSources().count(), 0); + + // If plugin returns null widget, source is not added + gTestAppletSourceCreateWidget = false; + gQPluginLoaderInstanceCreate = true; + inventory->setInstallationSources(QStringList() << sourceName1); + QCOMPARE(inventory->model()->installationSources().count(), 0); +} + +QTEST_APPLESS_MAIN(Ut_DuiAppletInventory) diff --git a/tests/ut_duiappletinventory/ut_duiappletinventory.h b/tests/ut_duiappletinventory/ut_duiappletinventory.h new file mode 100644 index 000000000..5e4b9d343 --- /dev/null +++ b/tests/ut_duiappletinventory/ut_duiappletinventory.h @@ -0,0 +1,94 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef _UT_DUIAPPLETINVENTORY_ +#define _UT_DUIAPPLETINVENTORY_ + +#include +#include +#include + +class DuiAppletInventory; +class DuiApplication; +class DuiApplicationWindow; +class DuiWidget; +class DuiMashupCanvas; +class DuiDesktopEntry; + +class TestAppletSource : public QObject, public DuiAppletInstallationSourceInterface +{ + Q_OBJECT + Q_INTERFACES(DuiAppletInstallationSourceInterface) + +public: + // methods derived from DuiAppletInstallationSourceInterface + virtual DuiWidget *constructWidget(); +}; + +class Ut_DuiAppletInventory : public QObject +{ + Q_OBJECT + +public: + static QStringList watchedDirectories; + static QStringList appletList; + static bool addPathCalled; + static bool directoriesCalled; + static bool pluginPathExists; + static bool pluginPathIsReadable; + static bool tooManyMonitoredPaths; + +private: + // DuiAppletInventory instance under testing + DuiAppletInventory *inventory; + + // DuiApplication + DuiApplication *app; + + // DuiApplication + DuiApplicationWindow *appWin; + + // Mashup canvas for the inventory + DuiMashupCanvas *mashupCanvas; + +signals: + void appletPathChanged(const QString path); + void instantiateAppletsFromPackage(const QString &packageName); + +private slots: + + void init(); + void cleanup(); + void initTestCase(); + void cleanupTestCase(); + + void testSuccessfulInitialization(); + void testInitializationWithInvalidPluginPath(); + void testStartWithExistingApplets(); + void testStartWithInvalidApplets(); + void testAppletAdd(); + void testAppletRemove(); + void testCategories_data(); + void testCategories(); + void testEnabled(); + void testOnlyDotDesktopFilesAreParsed(); + void testAppletInstallationSourcesLoading(); +}; + +#endif // _UT_DUIAPPLETINVENTORY_ diff --git a/tests/ut_duiappletinventory/ut_duiappletinventory.pro b/tests/ut_duiappletinventory/ut_duiappletinventory.pro new file mode 100644 index 000000000..df34b1775 --- /dev/null +++ b/tests/ut_duiappletinventory/ut_duiappletinventory.pro @@ -0,0 +1,59 @@ +include(../common_top.pri) +TARGET = ut_duiappletinventory +INCLUDEPATH += $$DUISRCDIR/mashup/appletcommunication \ + $$DUISRCDIR/mashup/appletinterface \ + $$DUISRCDIR/mashup/appletinstallation \ + $$DUISRCDIR/mashup/mashup \ + $$DUISRCDIR/widgets \ + $$DUISRCDIR/events + +win32 { + QMAKE_MOC = perl $${IN_PWD}\..\..\duimoc\duimoc +} else { + PRE_TARGETDEPS += ../../duigen/duigen + QMAKE_MOC = PATH=../../duigen:$$(PATH) $${IN_PWD}/../../duimoc/duimoc +} + +DUIGEN_OUTDIR = . +duigenerator_model.name = duigenerator model +duigenerator_model.input = MODEL_HEADERS +duigenerator_model.depends = ../../duigen/duigen +duigenerator_model.output = $$DUIGEN_OUTDIR/gen_${QMAKE_FILE_BASE}data.cpp +duigenerator_model.commands += ../../duigen/duigen --model ${QMAKE_FILE_NAME} $$DUIGEN_OUTDIR +duigenerator_model.clean += $$DUIGEN_OUTDIR/gen_* +duigenerator_model.CONFIG = target_predeps no_link +duigenerator_model.variable_out = GENERATED_SOURCES +QMAKE_EXTRA_COMPILERS += duigenerator_model + +MODEL_HEADERS += $$DUISRCDIR/widgets/duiwidgetmodel.h \ + $$DUISRCDIR/mashup/mashup/duiappletinventorymodel.h + +SOURCES += \ + ut_duiappletinventory.cpp \ + $$DUISRCDIR/mashup/mashup/duiappletinventory.cpp \ + $$DUISRCDIR/mashup/appletinstallation/duiappletinstantiator.cpp \ + $$DUISRCDIR/widgets/core/duiwidgetcontroller.cpp \ + $$DUISRCDIR/widgets/core/duiwidget.cpp \ + $$DUISRCDIR/widgets/duiwidgetmodel.cpp + +# service classes +SOURCES += \ + $$STUBSDIR/stubbase.cpp \ + +# unit test and unit classes +HEADERS += \ + ut_duiappletinventory.h \ + $$DUISRCDIR/mashup/mashup/duiappletinventory.h \ + $$DUISRCDIR/mashup/mashup/duiappletinventorymodel.h \ + $$DUISRCDIR/mashup/appletinstallation/duiappletinstantiator.h \ + $$DUISRCDIR/mashup/appletinstallation/duiappletinstantiator_p.h \ + $$DUISRCDIR/mashup/mashup/duiappletbutton.h \ + $$DUISRCDIR/mashup/mashup/duiappletinstancemanager.h \ + $$DUISRCDIR/mashup/mashup/duiappletid.h \ + $$DUISRCDIR/widgets/core/duiwidgetcontroller_p.h \ + $$DUISRCDIR/widgets/core/duiwidget_p.h \ + $$DUISRCDIR/widgets/duiwidgetmodel_p.h \ + $$DUISRCDIR/widgets/duiscenewindow_p.h \ + $$DUISRCDIR/widgets/duiobjectmenu.h + +include(../common_bot.pri) diff --git a/tests/ut_duiappletinventoryview/.gitignore b/tests/ut_duiappletinventoryview/.gitignore new file mode 100644 index 000000000..b71bac3e0 --- /dev/null +++ b/tests/ut_duiappletinventoryview/.gitignore @@ -0,0 +1 @@ +ut_duiappletinventoryview diff --git a/tests/ut_duiappletinventoryview/ut_duiappletinventoryview.cpp b/tests/ut_duiappletinventoryview/ut_duiappletinventoryview.cpp new file mode 100644 index 000000000..a526c37c8 --- /dev/null +++ b/tests/ut_duiappletinventoryview/ut_duiappletinventoryview.cpp @@ -0,0 +1,229 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "duiwidgetcontroller_p.h" +#include "ut_duiappletinventoryview.h" + +// DuiClassFactory stubs +void DuiClassFactory::registerViewCreator(DuiViewCreatorBase *, const char *) +{ +} + +void DuiClassFactory::unregisterViewCreator(DuiViewCreatorBase *) +{ +} + +// DuiAppletInventory stubs +DuiAppletInventory::DuiAppletInventory(QGraphicsItem *parent) : + DuiWidgetController(new DuiWidgetControllerPrivate, new DuiAppletInventoryModel, parent), + mashupCanvas(NULL), + watcher(new QFileSystemWatcher()), + appletPath(APPLET_DATA) +{ +} + +DuiAppletInventory::~DuiAppletInventory() +{ +} + +void DuiAppletInventory::appletPathChanged(QString const &) +{ +} + +void DuiAppletInventory::appletButtonClicked() +{ +} + +void DuiAppletInventory::instantiateAppletsFromPackage(QString const &) +{ +} + +// DuiSceneManager stubs +void DuiSceneManager::showWindow(DuiSceneWindow *window, DuiSceneWindow::DeletionPolicy) +{ + window->show(); + Ut_DuiAppletInventoryView::appearCalled = true; +} + +void DuiSceneManager::hideWindow(DuiSceneWindow *window) +{ + window->hide(); + Ut_DuiAppletInventoryView::disappearCalled = true; +} + +// QGraphicsItem stubs (used by DuiSceneManager) +void QGraphicsItem::setZValue(qreal z) +{ + Q_UNUSED(z); +} + +// DuiContainer stubs +QList gDuiContainers; +QList gDuiContainerCentralWidgets; +void DuiContainer::setCentralWidget(DuiWidget *centralWidget, bool /*destroy*/) +{ + gDuiContainers.append(this); + gDuiContainerCentralWidgets.append(centralWidget); +} + +// TestAppletInventoryView implementation +TestAppletInventoryView::TestAppletInventoryView(DuiAppletInventory *controller) : DuiAppletInventoryView(controller) +{ +} + +bool Ut_DuiAppletInventoryView::appearCalled; +bool Ut_DuiAppletInventoryView::disappearCalled; + +void Ut_DuiAppletInventoryView::initTestCase() +{ + // Create a DuiAapplication + int argc = 1; + char *app_name = (char *)"./ut_duiappletinventoryview"; + app = new DuiApplication(argc, &app_name); + appWin = new DuiApplicationWindow; +} + +void Ut_DuiAppletInventoryView::cleanupTestCase() +{ + delete appWin; + // this is commented out for now, to prevent crash at exit: + // delete app; +} + +void Ut_DuiAppletInventoryView::init() +{ + controller = new DuiAppletInventory; + view = new TestAppletInventoryView(controller); + controller->setView(view); + appWin->scene()->addItem(controller); + + appearCalled = false; + disappearCalled = false; +} + +void Ut_DuiAppletInventoryView::cleanup() +{ + controller->model()->setWidgets(WidgetList()); + delete controller; +} + +void Ut_DuiAppletInventoryView::testModelModifiedWidgets() +{ + // Set three widgets in the model + DuiWidget widget1; + DuiWidget widget2; + DuiWidget widget3; + QList widgets; + widgets.append(&widget1); + widgets.append(&widget2); + widgets.append(&widget3); + controller->model()->setWidgets(widgets); + + // The widgets should now be in the DuiFlowLayoutPolicy + DuiLayout *layout = dynamic_cast(controller->layout()); + QVERIFY(layout != NULL); + + DuiContainer *appletContainer = dynamic_cast(layout->itemAt(0)); + QVERIFY(appletContainer != NULL); + + layout = dynamic_cast(appletContainer->centralWidget()->layout()); + QVERIFY(layout != NULL); + + DuiFlowLayoutPolicy *policy = dynamic_cast(layout->policy()); + QVERIFY(policy != NULL); + QCOMPARE(policy->count(), 3); + QCOMPARE(dynamic_cast(policy->itemAt(0)), &widget1); + QCOMPARE(dynamic_cast(policy->itemAt(1)), &widget2); + QCOMPARE(dynamic_cast(policy->itemAt(2)), &widget3); + + // Remove two widgets from the list + widgets.removeAt(0); + widgets.removeAt(1); + controller->model()->setWidgets(widgets); + + // Verify that only the relevant one is still there + QCOMPARE(policy->count(), 1); + QCOMPARE(dynamic_cast(policy->itemAt(0)), &widget2); +} + +void Ut_DuiAppletInventoryView::testModelModifiedCloseButtonVisible() +{ + // Set the close button visible + controller->model()->setCloseButtonVisible(true); + QVERIFY(!disappearCalled); + QVERIFY(appearCalled); + + // Set the close button invisible + appearCalled = false; + controller->model()->setCloseButtonVisible(false); + QVERIFY(disappearCalled); + QVERIFY(!appearCalled); +} + +void Ut_DuiAppletInventoryView::testModelModifiedInstallationSources() +{ + QList sourceWidgets; + + // See that containers are created for all source widgets + gDuiContainerCentralWidgets.clear(); + sourceWidgets.append(new DuiWidget); + sourceWidgets.append(new DuiWidget); + controller->model()->setInstallationSources(sourceWidgets); + QCOMPARE(gDuiContainerCentralWidgets, sourceWidgets); + + gDuiContainerCentralWidgets.clear(); + gDuiContainers.clear(); + sourceWidgets.clear(); + TestSourceWidget *testSourceWidget = new TestSourceWidget; + testSourceWidget->installationSourceIcon_ = "fooicon"; + testSourceWidget->installationSourceTitle_ = "footitle"; + testSourceWidget->installationSourceText_ = "footext"; + + // Source container's properties should come from the source widget + sourceWidgets.append(testSourceWidget); + controller->model()->setInstallationSources(sourceWidgets); + QCOMPARE(gDuiContainerCentralWidgets, sourceWidgets); + QCOMPARE(gDuiContainers[0]->iconID(), testSourceWidget->installationSourceIcon_); + QCOMPARE(gDuiContainers[0]->title(), testSourceWidget->installationSourceTitle_); + QCOMPARE(gDuiContainers[0]->text(), testSourceWidget->installationSourceText_); + + // Signals from source widget should change the values in the container + testSourceWidget->setInstallationSourceIcon("baricon"); + testSourceWidget->setInstallationSourceTitle("bartitle"); + testSourceWidget->setInstallationSourceText("bartext"); + QCOMPARE(gDuiContainers[0]->iconID(), testSourceWidget->installationSourceIcon_); + QCOMPARE(gDuiContainers[0]->title(), testSourceWidget->installationSourceTitle_); + QCOMPARE(gDuiContainers[0]->text(), testSourceWidget->installationSourceText_); +} + +QTEST_APPLESS_MAIN(Ut_DuiAppletInventoryView) diff --git a/tests/ut_duiappletinventoryview/ut_duiappletinventoryview.h b/tests/ut_duiappletinventoryview/ut_duiappletinventoryview.h new file mode 100644 index 000000000..7b7d0c992 --- /dev/null +++ b/tests/ut_duiappletinventoryview/ut_duiappletinventoryview.h @@ -0,0 +1,119 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIAPPLETINVENTORYVIEW_H +#define UT_DUIAPPLETINVENTORYVIEW_H + +#include +#include +#include + +class DuiApplication; +class DuiApplicationWindow; +class DuiAppletInventory; + +class TestAppletInventoryView : public DuiAppletInventoryView +{ + DUI_VIEW(DuiAppletInventoryModel, DuiAppletInventoryStyle) + +public: + TestAppletInventoryView(DuiAppletInventory *controller); + + DuiAppletInventoryStyle *modifiableStyle() { + DuiAppletInventoryStyleContainer &sc = style(); + const DuiAppletInventoryStyle *const_s = sc.operator ->(); + DuiAppletInventoryStyle *s = const_cast(const_s); + return s; + } +}; + +class TestSourceWidget : public DuiWidget +{ + Q_OBJECT + Q_PROPERTY(QString installationSourceIcon READ installationSourceIcon) + Q_PROPERTY(QString installationSourceTitle READ installationSourceTitle) + Q_PROPERTY(QString installationSourceText READ installationSourceText) + +public: + QString installationSourceIcon() { + return installationSourceIcon_; + }; + QString installationSourceTitle() { + return installationSourceTitle_; + }; + QString installationSourceText() { + return installationSourceText_; + }; + + void setInstallationSourceIcon(const QString &icon) { + installationSourceIcon_ = icon; + emit installationSourceIconChanged(icon); + } + void setInstallationSourceTitle(const QString &title) { + installationSourceTitle_ = title; + emit installationSourceTitleChanged(title); + }; + void setInstallationSourceText(const QString &text) { + installationSourceText_ = text; + emit installationSourceTextChanged(text); + }; + + QString installationSourceIcon_; + QString installationSourceTitle_; + QString installationSourceText_; + +signals: + void installationSourceIconChanged(const QString &icon); + void installationSourceTitleChanged(const QString &title); + void installationSourceTextChanged(const QString &text); +}; + +class Ut_DuiAppletInventoryView : public QObject +{ + Q_OBJECT + +public: + static bool appearCalled; + static bool disappearCalled; + +private slots: + void init(); + void cleanup(); + void initTestCase(); + void cleanupTestCase(); + + //! Test that changing the widgets puts them into the layout + void testModelModifiedWidgets(); + //! Test that changing the close button visibility shows and hides the close button + void testModelModifiedCloseButtonVisible(); + //! Test that changing the installation sources puts them into the layout + void testModelModifiedInstallationSources(); + +private: + //! DuiApplication for the test case + DuiApplication *app; + //! DuiApplicationWindow for the test case + DuiApplicationWindow *appWin; + //! A controller for the view + DuiAppletInventory *controller; + //! The view to be tested + TestAppletInventoryView *view; +}; + +#endif diff --git a/tests/ut_duiappletinventoryview/ut_duiappletinventoryview.pro b/tests/ut_duiappletinventoryview/ut_duiappletinventoryview.pro new file mode 100644 index 000000000..fda605d63 --- /dev/null +++ b/tests/ut_duiappletinventoryview/ut_duiappletinventoryview.pro @@ -0,0 +1,54 @@ +include(../common_top.pri) +TARGET = ut_duiappletinventoryview +INCLUDEPATH += $$DUISRCDIR/mashup/mashup +INCLUDEPATH += $$DUISRCDIR/mashup/appletinstallation +INCLUDEPATH += $$DUISRCDIR/style +INCLUDEPATH += $$DUISRCDIR/widgets +INCLUDEPATH += $$DUISRCDIR/widgets/core +INCLUDEPATH += $$DUISRCDIR/core + +DUIGEN_OUTDIR = . +duigenerator_model.name = duigenerator model +duigenerator_model.input = MODEL_HEADERS +duigenerator_model.depends = ../../duigen/duigen +duigenerator_model.output = $$DUIGEN_OUTDIR/gen_${QMAKE_FILE_BASE}data.cpp +duigenerator_model.commands += ../../duigen/duigen --model ${QMAKE_FILE_NAME} $$DUIGEN_OUTDIR +duigenerator_model.clean += $$DUIGEN_OUTDIR/gen_* +duigenerator_model.CONFIG = target_predeps no_link +duigenerator_model.variable_out = GENERATED_SOURCES +QMAKE_EXTRA_COMPILERS += duigenerator_model + +STYLE_HEADERS += $$DUISRCDIR/style/duiappletinventorystyle.h +MODEL_HEADERS += $$DUISRCDIR/widgets/duiwidgetmodel.h \ + $$DUISRCDIR/mashup/mashup/duiappletinventorymodel.h + +# unit test and unit +SOURCES += \ + ut_duiappletinventoryview.cpp \ + $$DUISRCDIR/mashup/mashup/duiappletinventoryview.cpp \ + $$TEST_SOURCES \ + +# base classes +SOURCES += \ + $$DUISRCDIR/widgets/core/duiwidgetcontroller.cpp \ + $$DUISRCDIR/widgets/core/duiwidget.cpp \ + $$DUISRCDIR/widgets/duiwidgetmodel.cpp + +# service classes +SOURCES += \ + $$STUBSDIR/stubbase.cpp \ + +# unit test and unit +HEADERS += \ + ut_duiappletinventoryview.h \ + $$DUISRCDIR/widgets/core/duiwidgetcontroller_p.h \ + $$DUISRCDIR/widgets/views/duiextendingbackgroundview_p.h \ + $$DUISRCDIR/mashup/mashup/duiappletbutton.h \ + $$DUISRCDIR/mashup/mashup/duiappletinventory.h \ + $$DUISRCDIR/mashup/mashup/duiappletinventoryview.h \ + $$DUISRCDIR/mashup/mashup/duiappletinventorymodel.h \ + $$DUISRCDIR/widgets/duiwidgetmodel_p.h \ + $$DUISRCDIR/widgets/duiscenewindow_p.h \ + $$DUISRCDIR/widgets/duiobjectmenu.h + +include(../common_bot.pri) diff --git a/tests/ut_duiappletloader/.gitignore b/tests/ut_duiappletloader/.gitignore new file mode 100644 index 000000000..34c6826cd --- /dev/null +++ b/tests/ut_duiappletloader/.gitignore @@ -0,0 +1,2 @@ +ut_duiappletloader + diff --git a/tests/ut_duiappletloader/ut_duiappletloader.cpp b/tests/ut_duiappletloader/ut_duiappletloader.cpp new file mode 100644 index 000000000..72f64f8aa --- /dev/null +++ b/tests/ut_duiappletloader/ut_duiappletloader.cpp @@ -0,0 +1,161 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duiappletloader.h" + +#include +#include +#include +#include +#include +#include "../stubs/mockdatastore.h" + +#include + +class MockAppletSettingsInterface : public DuiDataAccess +{ +public: + virtual QVariant value(const QString &) const { + return QVariant(); + } + + virtual bool setValue(const QString &, const QVariant &) { + return true; + } + + virtual QStringList allKeys() const { + return QStringList(); + } + + virtual bool contains(const QString &) const { + return true; + } +}; + +Q_EXPORT_PLUGIN2(testapplet, TestApplet) + +DuiWidget *gLastConstructedWidget = NULL; + +DuiWidget *TestApplet::constructWidget(const DuiAppletMetaData &, DuiDataStore &, DuiDataAccess &) +{ + gLastConstructedWidget = new DuiWidget; + return gLastConstructedWidget; +} + +bool SomeQObject_destructor_called = false; +SomeQObject::~SomeQObject() +{ + SomeQObject_destructor_called = true; +} + +// DuiAppletMetaData stubs +QString DuiAppletMetaData::appletBinary() const +{ + return "TestAppletBinary"; +} + +// QPluginLoader stubs +QString gQPluginLoaderFileName; +QPluginLoader::QPluginLoader(const QString &fileName, QObject *parent) +{ + Q_UNUSED(parent); + + gQPluginLoaderFileName = fileName; +} + +QPluginLoader::~QPluginLoader() +{ +} + +void QPluginLoader::setFileName(const QString &fileName) +{ + gQPluginLoaderFileName = fileName; +} + +QObject *QPluginLoader_instance_return = NULL; +// NOTE: DuiAppletLoader deletes the returned value from this function so it musn't be deleted anywhere in this test case +QObject *QPluginLoader::instance() +{ + return QPluginLoader_instance_return; +} + +void Ut_DuiAppletLoader::init() +{ + gLastConstructedWidget = NULL; + gQPluginLoaderFileName.clear(); + QPluginLoader_instance_return = NULL; + SomeQObject_destructor_called = false; + + metadata = new DuiAppletMetaData("testmetadata.desktop"); + dataStore = new MockDataStore; + appletSettingsInterface = new MockAppletSettingsInterface; +} + +void Ut_DuiAppletLoader::cleanup() +{ + QPluginLoader_instance_return = NULL; + + delete appletSettingsInterface; + appletSettingsInterface = NULL; + delete dataStore; + dataStore = NULL; + delete metadata; + metadata = NULL; +} + +void Ut_DuiAppletLoader::initTestCase() +{ +} + +void Ut_DuiAppletLoader::cleanupTestCase() +{ +} + +void Ut_DuiAppletLoader::testAppletLoading() +{ + QPluginLoader_instance_return = new TestApplet; + + DuiWidget *widget = DuiAppletLoader::loadApplet(*metadata, *dataStore, *appletSettingsInterface); + + QVERIFY(widget != NULL); + QCOMPARE(widget, gLastConstructedWidget); + QCOMPARE(gQPluginLoaderFileName, QString("TestAppletBinary")); +} + +void Ut_DuiAppletLoader::testAppletLoadingFailNullAppletObject() +{ + // Returns NULL from QPluginLoader::instance() + DuiWidget *widget = DuiAppletLoader::loadApplet(*metadata, *dataStore, *appletSettingsInterface); + + QVERIFY(widget == NULL); +} + +void Ut_DuiAppletLoader::testAppletLoadingFailWrongTypeAppletObject() +{ + // Use an object that can't be cast to DuiAppletInterface + QPluginLoader_instance_return = new SomeQObject; + + DuiWidget *widget = DuiAppletLoader::loadApplet(*metadata, *dataStore, *appletSettingsInterface); + + QVERIFY(widget == NULL); + // Ensure that the loader still deletes the object even though it was of a wrong type + QCOMPARE(SomeQObject_destructor_called, true); +} + +QTEST_APPLESS_MAIN(Ut_DuiAppletLoader) diff --git a/tests/ut_duiappletloader/ut_duiappletloader.h b/tests/ut_duiappletloader/ut_duiappletloader.h new file mode 100644 index 000000000..2ce75cadd --- /dev/null +++ b/tests/ut_duiappletloader/ut_duiappletloader.h @@ -0,0 +1,71 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIAPPLETLOADER_H +#define UT_DUIAPPLETLOADER_H + +#include +#include + +class DuiAppletMetaData; +class MockDataStore; +class MockAppletSettingsInterface; + +class TestApplet : public QObject, public DuiAppletInterface +{ + Q_OBJECT + Q_INTERFACES(DuiAppletInterface) + +public: + // methods derived from DuiAppletInterface + virtual DuiWidget *constructWidget(const DuiAppletMetaData &, DuiDataStore &, DuiDataAccess &); + + // A flag to tell if we should use the deprecated or the new applet construction interface + static bool useDeprecatedInterface; +}; + +class SomeQObject : public QObject +{ + Q_OBJECT + +public: + virtual ~SomeQObject(); +}; + + +class Ut_DuiAppletLoader : public QObject +{ + Q_OBJECT + + DuiAppletMetaData *metadata; + MockDataStore *dataStore; + MockAppletSettingsInterface *appletSettingsInterface; + +private slots: + void init(); + void cleanup(); + void initTestCase(); + void cleanupTestCase(); + + void testAppletLoading(); + void testAppletLoadingFailNullAppletObject(); + void testAppletLoadingFailWrongTypeAppletObject(); +}; + +#endif diff --git a/tests/ut_duiappletloader/ut_duiappletloader.pro b/tests/ut_duiappletloader/ut_duiappletloader.pro new file mode 100644 index 000000000..fab952228 --- /dev/null +++ b/tests/ut_duiappletloader/ut_duiappletloader.pro @@ -0,0 +1,21 @@ +include(../common_top.pri) +TARGET = ut_duiappletloader + +INCLUDEPATH += \ + $$DUISRCDIR/mashup/mashup \ + $$DUISRCDIR/mashup/appletinterface + +TEST_SOURCES = \ + $$DUISRCDIR/mashup/mashup/duiappletloader.cpp + +# unit test and unit +SOURCES += \ + ut_duiappletloader.cpp \ + $$TEST_SOURCES + +# unit test and unit +HEADERS += \ + ut_duiappletloader.h \ + $$DUISRCDIR/mashup/mashup/duiappletloader.h + +include(../common_bot.pri) diff --git a/tests/ut_duiappletmessage/.gitignore b/tests/ut_duiappletmessage/.gitignore new file mode 100644 index 000000000..bfaa22c47 --- /dev/null +++ b/tests/ut_duiappletmessage/.gitignore @@ -0,0 +1 @@ +ut_duiappletmessage diff --git a/tests/ut_duiappletmessage/ut_duiappletmessage.cpp b/tests/ut_duiappletmessage/ut_duiappletmessage.cpp new file mode 100644 index 000000000..d73269729 --- /dev/null +++ b/tests/ut_duiappletmessage/ut_duiappletmessage.cpp @@ -0,0 +1,97 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include + +#include "duiappletmessage.h" +#include "ut_duiappletmessage.h" + +bool testAppletMessageSerialized = false; +bool testAppletMessageUnserialized = false; + +class TestAppletMessage : public DuiAppletMessage +{ +public: + TestAppletMessage() : DuiAppletMessage((DuiAppletMessageType)1) { } + + int foo; + + void serialize(QDataStream &stream) const { + stream << foo; + testAppletMessageSerialized = true; + } + + void unserialize(QDataStream &stream) { + stream >> foo; + testAppletMessageUnserialized = true; + } +}; + +void Ut_DuiAppletMessage::init() +{ + // Allocate a buffer and a stream for serialization + buffer = new QBuffer; + buffer->open(QIODevice::ReadWrite); + + stream = new QDataStream(buffer); + + // Allocate test messages + message = new TestAppletMessage; +} + +void Ut_DuiAppletMessage::cleanup() +{ + delete buffer; + delete stream; + delete message; +} + +void Ut_DuiAppletMessage::testType() +{ + QCOMPARE(message->type(), (DuiAppletMessage::DuiAppletMessageType)1); +} + +void Ut_DuiAppletMessage::testSerialization() +{ + testAppletMessageSerialized = false; + + message->serialize(*stream); + + QVERIFY(testAppletMessageSerialized); +} + +void Ut_DuiAppletMessage::testUnserialization() +{ + testAppletMessageUnserialized = false; + + *stream << 1; + // Seek to the beginning of the buffer + buffer->seek(0); + + // Unserialize the message and compare whether it is similar than it used to be + message = new TestAppletMessage; + message->unserialize(*stream); + + QCOMPARE(((TestAppletMessage *)message)->foo, 1); + QVERIFY(testAppletMessageUnserialized); +} + +QTEST_APPLESS_MAIN(Ut_DuiAppletMessage) diff --git a/tests/ut_duiappletmessage/ut_duiappletmessage.h b/tests/ut_duiappletmessage/ut_duiappletmessage.h new file mode 100644 index 000000000..4ad29f334 --- /dev/null +++ b/tests/ut_duiappletmessage/ut_duiappletmessage.h @@ -0,0 +1,47 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIAPPLETMESSAGE_H +#define UT_DUIAPPLETMESSAGE_H + +#include + +class QBuffer; +class QDataStream; +class DuiAppletMessage; + +class Ut_DuiAppletMessage : public QObject +{ + Q_OBJECT + +private: + QBuffer *buffer; + QDataStream *stream; + DuiAppletMessage *message; + +private slots: + void init(); + void cleanup(); + + void testType(); + void testSerialization(); + void testUnserialization(); +}; + +#endif // UT_DUIAPPLETMESSAGE_H diff --git a/tests/ut_duiappletmessage/ut_duiappletmessage.pro b/tests/ut_duiappletmessage/ut_duiappletmessage.pro new file mode 100644 index 000000000..a3b62b4d0 --- /dev/null +++ b/tests/ut_duiappletmessage/ut_duiappletmessage.pro @@ -0,0 +1,13 @@ +include(../common_top.pri) +TARGET = ut_duiappletmessage +INCLUDEPATH += $$DUISRCDIR/mashup/appletcommunication $$DUISRCDIR/mashup/appletinterface $$DUISRCDIR/mashup/mashup + +# unit test and unit classes +SOURCES += \ + ut_duiappletmessage.cpp \ + +# unit test and unit classes +HEADERS += \ + ut_duiappletmessage.h \ + +include(../common_bot.pri) diff --git a/tests/ut_duiappletmessagefactory/.gitignore b/tests/ut_duiappletmessagefactory/.gitignore new file mode 100644 index 000000000..664b05327 --- /dev/null +++ b/tests/ut_duiappletmessagefactory/.gitignore @@ -0,0 +1 @@ +ut_duiappletmessagefactory diff --git a/tests/ut_duiappletmessagefactory/ut_duiappletmessagefactory.cpp b/tests/ut_duiappletmessagefactory/ut_duiappletmessagefactory.cpp new file mode 100644 index 000000000..8dbf01150 --- /dev/null +++ b/tests/ut_duiappletmessagefactory/ut_duiappletmessagefactory.cpp @@ -0,0 +1,51 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include + +#include "duiappletmessagefactory.h" +#include "duiappletmessage.h" +#include "ut_duiappletmessagefactory.h" + +void Ut_DuiAppletMessageFactory::init() +{ +} + +void Ut_DuiAppletMessageFactory::cleanup() +{ +} + +void Ut_DuiAppletMessageFactory::testCreation() +{ + // Try instantiating an object of unknown type + DuiAppletMessage *m = DuiAppletMessageFactory::create(DuiAppletMessage::INVALID); + QVERIFY(m == NULL); + + int i = (int)DuiAppletMessage::INVALID; + ++i; + for (; i < (int)DuiAppletMessage::NUM_TYPES; ++i) { + m = DuiAppletMessageFactory::create((DuiAppletMessage::DuiAppletMessageType)i); + QVERIFY(m != NULL); + QCOMPARE(m->type(), (DuiAppletMessage::DuiAppletMessageType)i); + delete m; + } +} + +QTEST_APPLESS_MAIN(Ut_DuiAppletMessageFactory) diff --git a/tests/ut_duiappletmessagefactory/ut_duiappletmessagefactory.h b/tests/ut_duiappletmessagefactory/ut_duiappletmessagefactory.h new file mode 100644 index 000000000..f6c648725 --- /dev/null +++ b/tests/ut_duiappletmessagefactory/ut_duiappletmessagefactory.h @@ -0,0 +1,36 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIAPPLETMESSAGEFACTORY_H +#define UT_DUIAPPLETMESSAGEFACTORY_H + +#include + +class Ut_DuiAppletMessageFactory : public QObject +{ + Q_OBJECT + +private slots: + void init(); + void cleanup(); + + void testCreation(); +}; + +#endif // UT_DUIAPPLETMESSAGEFACTORY_H diff --git a/tests/ut_duiappletmessagefactory/ut_duiappletmessagefactory.pro b/tests/ut_duiappletmessagefactory/ut_duiappletmessagefactory.pro new file mode 100644 index 000000000..39496d8eb --- /dev/null +++ b/tests/ut_duiappletmessagefactory/ut_duiappletmessagefactory.pro @@ -0,0 +1,13 @@ +include(../common_top.pri) +TARGET = ut_duiappletmessagefactory +INCLUDEPATH += $$DUISRCDIR/mashup/appletcommunication $$DUISRCDIR/mashup/appletinterface $$DUISRCDIR/mashup/mashup + +# unit test and unit classes +SOURCES += \ + ut_duiappletmessagefactory.cpp \ + +# unit test and unit classes +HEADERS += \ + ut_duiappletmessagefactory.h \ + +include(../common_bot.pri) diff --git a/tests/ut_duiappletmetadata/.gitignore b/tests/ut_duiappletmetadata/.gitignore new file mode 100644 index 000000000..2dd1f1c0a --- /dev/null +++ b/tests/ut_duiappletmetadata/.gitignore @@ -0,0 +1 @@ +ut_duiappletmetadata diff --git a/tests/ut_duiappletmetadata/ut_duiappletmetadata.cpp b/tests/ut_duiappletmetadata/ut_duiappletmetadata.cpp new file mode 100644 index 000000000..4102d5a63 --- /dev/null +++ b/tests/ut_duiappletmetadata/ut_duiappletmetadata.cpp @@ -0,0 +1,200 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include + +#include "ut_duiappletmetadata.h" +#include "duiappletmetadata.h" + +QString gType = "DUIApplet"; +QString gRunner = ""; +QString gApplet = ""; +QString gName = ""; +QString gIcon = ""; +QString gExtraIdentifier = ""; + +// DuiDesktop entry stubs +QString DuiDesktopEntry::value(const QString &key) const +{ + if (key == "Desktop Entry/Type") { + return QString(gType); + } else if (key == "Desktop Entry/Name") { + return QString(gName); + } else if (key == "Desktop Entry/Icon") { + return QString(gIcon); + } else if (key == "Desktop Entry/Exec") { + return QString(gRunner); + } else if (key == "DUI/X-DUIApplet-Applet") { + return QString(gApplet); + } else if (key == "DUI/X-DUIApplet-Identifier") { + return QString(gExtraIdentifier); + } + return QString(); +} + +bool DuiDesktopEntry::contains(const QString &key) const +{ + if (key == "Desktop Entry/Type") { + return gType != ""; + } else if (key == "Desktop Entry/Name") { + return gName != ""; + } else if (key == "Desktop Entry/Icon") { + return gIcon != ""; + } else if (key == "Desktop Entry/Exec") { + return gRunner != ""; + } else if (key == "DUI/X-DUIApplet-Applet") { + return gApplet != ""; + } else if (key == "DUI/X-DUIApplet-Identifier") { + return gExtraIdentifier != ""; + } + return false; +} + +// QFileInfo stubs +bool QFileInfo::exists() const +{ + if (filePath() == QString(APPLET_LIBS) + QDir::separator() + "inexisting") + return false; + else + return (filePath() == QString(APPLET_LIBS) + QDir::separator() + gApplet || + filePath() == QString(APPLET_LIBS) + QDir::separator() + gRunner); +} + +bool QFileInfo::isFile() const +{ + if (filePath() == QString(APPLET_LIBS) + QDir::separator() + "inexisting") + return false; + else + return (filePath() == QString(APPLET_LIBS) + QDir::separator() + gApplet || + filePath() == QString(APPLET_LIBS) + QDir::separator() + gRunner); +} + +bool QFileInfo::isExecutable() const +{ + if (filePath() == QString(APPLET_LIBS) + QDir::separator() + "inexisting") + return false; + else + return (filePath() == QString(APPLET_LIBS) + QDir::separator() + gApplet || + filePath() == QString(APPLET_LIBS) + QDir::separator() + gRunner); +} + +void Ut_DuiAppletMetaData::init() +{ + m_subject = new DuiAppletMetaData(""); + gName = "Unit Test"; + gIcon = "Icon-UnitTest"; + gRunner = "duiappletrunner"; + gApplet = "test.so"; +} + +void Ut_DuiAppletMetaData::cleanup() +{ + delete m_subject; + m_subject = 0; +} + +void Ut_DuiAppletMetaData::testValidMetaData() +{ + // Runner is defined. This marks out-of-process applet + QCOMPARE(m_subject->isValid(), true); + + // Runner is not defined. This marks in-process applet + gRunner = ""; + QCOMPARE(m_subject->isValid(), true); +} + +void Ut_DuiAppletMetaData::testBinaryMissing() +{ + gApplet = ""; + QCOMPARE(m_subject->isValid(), false); +} + +void Ut_DuiAppletMetaData::testBinaryAndRunnerPaths() +{ + // APPLET_LIBS path should be prepended to binary and runner paths. + QString absoluteBinaryPath = QFileInfo(QString(APPLET_LIBS) + QDir::separator() + gApplet).absoluteFilePath(); + QString absoluteRunnerPath = QFileInfo(QString(APPLET_LIBS) + QDir::separator() + gRunner).absoluteFilePath(); + QCOMPARE(m_subject->appletBinary(), absoluteBinaryPath); + QCOMPARE(m_subject->runnerBinary(), absoluteRunnerPath); +} + +void Ut_DuiAppletMetaData::testInvalidRunner() +{ + gRunner = "inexisting"; + QCOMPARE(m_subject->isValid(), false); +} + +void Ut_DuiAppletMetaData::testInvalidApplet() +{ + gApplet = "inexisting"; + QCOMPARE(m_subject->isValid(), false); +} + +void Ut_DuiAppletMetaData::testAppletMissing() +{ + gApplet = ""; + QCOMPARE(m_subject->isValid(), false); +} + +void Ut_DuiAppletMetaData::testNameMissing() +{ + gName = ""; + QCOMPARE(m_subject->isValid(), false); +} + +void Ut_DuiAppletMetaData::testIconMissing() +{ + gIcon = ""; + QCOMPARE(m_subject->isValid(), false); +} + +void Ut_DuiAppletMetaData::testExtraIdentifier() +{ + gExtraIdentifier = ""; + QVERIFY(!m_subject->contains("DUI/X-DUIApplet-Identifier")); + gExtraIdentifier = "foo"; + QVERIFY(m_subject->contains("DUI/X-DUIApplet-Identifier")); +} + +void Ut_DuiAppletMetaData::testResourceIdentifier() +{ + // Valid cases + gExtraIdentifier = "foo"; + gApplet = "libfoo.so"; + QCOMPARE(m_subject->resourceIdentifier(), QString("foo")); + gApplet = DUI_INSTALL_LIBS "/libfoo.so"; + QCOMPARE(m_subject->resourceIdentifier(), QString("foo")); + gExtraIdentifier = "xyz"; + gApplet = DUI_INSTALL_LIBS "/libfoo.so"; + QCOMPARE(m_subject->resourceIdentifier(), QString("xyz")); + + // Invalid cases + gExtraIdentifier = ""; + gApplet = ""; + QCOMPARE(m_subject->resourceIdentifier(), QString("")); + gApplet = "foo"; + QCOMPARE(m_subject->resourceIdentifier(), QString("")); + gApplet = "foo.so"; + QCOMPARE(m_subject->resourceIdentifier(), QString("")); + gApplet = "libfoo"; + QCOMPARE(m_subject->resourceIdentifier(), QString("")); + +} + +QTEST_APPLESS_MAIN(Ut_DuiAppletMetaData) diff --git a/tests/ut_duiappletmetadata/ut_duiappletmetadata.h b/tests/ut_duiappletmetadata/ut_duiappletmetadata.h new file mode 100644 index 000000000..8875374aa --- /dev/null +++ b/tests/ut_duiappletmetadata/ut_duiappletmetadata.h @@ -0,0 +1,51 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIAPPLETMETADATA_H +#define UT_DUIAPPLETMETADATA_H + +#include + +class DuiAppletMetaData; + +class Ut_DuiAppletMetaData : public QObject +{ + Q_OBJECT + +private: + DuiAppletMetaData *m_subject; + +private slots: + void init(); + void cleanup(); + + void testValidMetaData(); + void testBinaryMissing(); + void testBinaryAndRunnerPaths(); + void testInvalidRunner(); + void testInvalidApplet(); + void testAppletMissing(); + void testNameMissing(); + void testIconMissing(); + + void testExtraIdentifier(); + void testResourceIdentifier(); +}; + +#endif // UT_DUIAPPLETMETADATA_H diff --git a/tests/ut_duiappletmetadata/ut_duiappletmetadata.pro b/tests/ut_duiappletmetadata/ut_duiappletmetadata.pro new file mode 100644 index 000000000..e97f2cb60 --- /dev/null +++ b/tests/ut_duiappletmetadata/ut_duiappletmetadata.pro @@ -0,0 +1,21 @@ +include(../common_top.pri) +TARGET = ut_duiappletmetadata +INCLUDEPATH += $$DUISRCDIR/mashup/appletcommunication \ + $$DUISRCDIR/mashup/appletinterface \ + $$DUISRCDIR/mashup/mashup + +# unit test and unit classes +SOURCES += \ + ut_duiappletmetadata.cpp \ + $$DUISRCDIR/mashup/appletinterface/duiappletmetadata.cpp + +# unit test and unit classes +HEADERS += \ + ut_duiappletmetadata.h \ + $$DUISRCDIR/mashup/appletinterface/duiappletmetadata.h + +DEFINES += DUI_INSTALL_LIBS=\\\"\"$$DUI_INSTALL_LIBS\"\\\" + +#DEFINES += APPLET_LIBS=\'$$quote(\"$$DUI_APPLET_DIR/lib/dui/applets/\")\' + +include(../common_bot.pri) diff --git a/tests/ut_duiappletmousemessage/.gitignore b/tests/ut_duiappletmousemessage/.gitignore new file mode 100644 index 000000000..aa1623c07 --- /dev/null +++ b/tests/ut_duiappletmousemessage/.gitignore @@ -0,0 +1 @@ +ut_duiappletmousemessage diff --git a/tests/ut_duiappletmousemessage/ut_duiappletmousemessage.cpp b/tests/ut_duiappletmousemessage/ut_duiappletmousemessage.cpp new file mode 100644 index 000000000..fbe9d24c0 --- /dev/null +++ b/tests/ut_duiappletmousemessage/ut_duiappletmousemessage.cpp @@ -0,0 +1,130 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duiappletmousemessage.h" + +#include +#include "duiappletmousemessage.h" + +void Ut_DuiAppletMouseMessage::init() +{ + // Allocate a buffer and a stream for (un)serialization + buffer = new QBuffer; + buffer->open(QIODevice::ReadWrite); + stream = new QDataStream(buffer); + + message = new DuiAppletMouseMessage(DuiAppletMessage::MOUSE_PRESS_MESSAGE); +} + +void Ut_DuiAppletMouseMessage::cleanup() +{ + delete message; + delete stream; + delete buffer; +} + +void Ut_DuiAppletMouseMessage::testTypes() +{ + QCOMPARE(message->type(), DuiAppletMessage::MOUSE_PRESS_MESSAGE); + delete message; + + message = new DuiAppletMouseMessage(DuiAppletMessage::MOUSE_RELEASE_MESSAGE); + QCOMPARE(message->type(), DuiAppletMessage::MOUSE_RELEASE_MESSAGE); + delete message; + + message = new DuiAppletMouseMessage(DuiAppletMessage::MOUSE_MOVE_MESSAGE); + QCOMPARE(message->type(), DuiAppletMessage::MOUSE_MOVE_MESSAGE); +} + +void Ut_DuiAppletMouseMessage::testPositionProperty() +{ + QCOMPARE(message->position(), QPointF(0.0, 0.0)); + message->setPosition(QPointF(1.0, 2.0)); + QCOMPARE(message->position(), QPointF(1.0, 2.0)); + + delete message; + message = new DuiAppletMouseMessage(DuiAppletMessage::MOUSE_PRESS_MESSAGE, QPointF(1.0, 2.0)); + QCOMPARE(message->position(), QPointF(1.0, 2.0)); +} + +void Ut_DuiAppletMouseMessage::testButtonProperty() +{ + QCOMPARE(message->button(), Qt::NoButton); + message->setButton(Qt::RightButton); + QCOMPARE(message->button(), Qt::RightButton); + + delete message; + message = new DuiAppletMouseMessage(DuiAppletMessage::MOUSE_PRESS_MESSAGE, QPointF(1.0, 2.0), Qt::MidButton); + QCOMPARE(message->button(), Qt::MidButton); +} + +void Ut_DuiAppletMouseMessage::testButtonsProperty() +{ + QCOMPARE(message->buttons(), Qt::NoButton); + message->setButtons(Qt::LeftButton | Qt::RightButton); + QCOMPARE(message->buttons(), Qt::LeftButton | Qt::RightButton); + + delete message; + message = new DuiAppletMouseMessage(DuiAppletMessage::MOUSE_PRESS_MESSAGE, QPointF(1.0, 2.0), Qt::MidButton, Qt::LeftButton | Qt::MidButton); + QCOMPARE(message->buttons(), Qt::LeftButton | Qt::MidButton); +} + +void Ut_DuiAppletMouseMessage::testSerialization() +{ + QPointF pos(-1.0, -2.0); + Qt::MouseButton button(Qt::MidButton); + Qt::MouseButtons buttons(Qt::LeftButton | Qt::MidButton); + message->setPosition(pos); + message->setButton(button); + message->setButtons(buttons); + message->serialize(*stream); + + // Seek to the beginning of the buffer + buffer->seek(0); + QPointF resPos; + quint32 tmp; + *stream >> resPos; + *stream >> tmp; + Qt::MouseButton resButton = (Qt::MouseButton)tmp; + *stream >> tmp; + Qt::MouseButtons resButtons = (Qt::MouseButtons)tmp; + + QCOMPARE(resPos, pos); + QCOMPARE(resButton, button); + QCOMPARE(resButtons, buttons); +} + +void Ut_DuiAppletMouseMessage::testUnserialization() +{ + QPointF pos(-1.0, -2.0); + Qt::MouseButton button(Qt::RightButton); + Qt::MouseButtons buttons(Qt::LeftButton | Qt::RightButton); + *stream << pos; + *stream << button; + *stream << buttons; + + buffer->seek(0); + message->unserialize(*stream); + + QCOMPARE(message->position(), pos); + QCOMPARE(message->button(), button); + QCOMPARE(message->buttons(), buttons); +} + +QTEST_APPLESS_MAIN(Ut_DuiAppletMouseMessage) diff --git a/tests/ut_duiappletmousemessage/ut_duiappletmousemessage.h b/tests/ut_duiappletmousemessage/ut_duiappletmousemessage.h new file mode 100644 index 000000000..1e0d70a13 --- /dev/null +++ b/tests/ut_duiappletmousemessage/ut_duiappletmousemessage.h @@ -0,0 +1,50 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIAPPLETMOUSEMESSAGE_H +#define UT_DUiAPPLETMOUSEMESSAGE_H + +#include + +class QBuffer; +class QDataStream; +class DuiAppletMouseMessage; + +class Ut_DuiAppletMouseMessage : public QObject +{ + Q_OBJECT + +private: + QBuffer *buffer; + QDataStream *stream; + DuiAppletMouseMessage *message; + +private slots: + void init(); + void cleanup(); + + void testTypes(); + void testPositionProperty(); + void testButtonProperty(); + void testButtonsProperty(); + void testSerialization(); + void testUnserialization(); +}; + +#endif // UT_DUIAPPLETMOUSEMESSAGE_H diff --git a/tests/ut_duiappletmousemessage/ut_duiappletmousemessage.pro b/tests/ut_duiappletmousemessage/ut_duiappletmousemessage.pro new file mode 100644 index 000000000..99a45b2d7 --- /dev/null +++ b/tests/ut_duiappletmousemessage/ut_duiappletmousemessage.pro @@ -0,0 +1,13 @@ +include(../common_top.pri) +TARGET = ut_duiappletmousemessage +INCLUDEPATH += $$DUISRCDIR/mashup/appletcommunication $$DUISRCDIR/mashup/appletinterface $$DUISRCDIR/mashup/mashup + +# unit test and unit classes +SOURCES += \ + ut_duiappletmousemessage.cpp \ + +# unit test and unit classes +HEADERS += \ + ut_duiappletmousemessage.h \ + +include(../common_bot.pri) diff --git a/tests/ut_duiappletobjectmenuactionselectedmessage/.gitignore b/tests/ut_duiappletobjectmenuactionselectedmessage/.gitignore new file mode 100644 index 000000000..86bb0b289 --- /dev/null +++ b/tests/ut_duiappletobjectmenuactionselectedmessage/.gitignore @@ -0,0 +1 @@ +ut_duiappletobjectmenuactionselectedmessage diff --git a/tests/ut_duiappletobjectmenuactionselectedmessage/ut_duiappletobjectmenuactionselectedmessage.cpp b/tests/ut_duiappletobjectmenuactionselectedmessage/ut_duiappletobjectmenuactionselectedmessage.cpp new file mode 100644 index 000000000..ec9498505 --- /dev/null +++ b/tests/ut_duiappletobjectmenuactionselectedmessage/ut_duiappletobjectmenuactionselectedmessage.cpp @@ -0,0 +1,76 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duiappletobjectmenuactionselectedmessage.h" + +#include +#include +#include "duiappletobjectmenuactionselectedmessage.h" + +void Ut_DuiAppletObjectMenuActionSelectedMessage::init() +{ + // Allocate a buffer and a stream for (un)serialization + buffer = new QBuffer; + buffer->open(QIODevice::ReadWrite); + stream = new QDataStream(buffer); + + message = new DuiAppletObjectMenuActionSelectedMessage(100); +} + +void Ut_DuiAppletObjectMenuActionSelectedMessage::cleanup() +{ + delete message; + delete stream; + delete buffer; +} + +void Ut_DuiAppletObjectMenuActionSelectedMessage::testType() +{ + QCOMPARE(message->type(), DuiAppletMessage::OBJECT_MENU_ACTION_SELECTED_MESSAGE); +} + +void Ut_DuiAppletObjectMenuActionSelectedMessage::testSerialization() +{ + message->serialize(*stream); + + // Seek to the beginning of the buffer + buffer->seek(0); + uint actionIndex = 0; + *stream >> actionIndex; + + QCOMPARE(actionIndex, (uint)100); +} + +void Ut_DuiAppletObjectMenuActionSelectedMessage::testUnserialization() +{ + uint actionIndex = 20; + *stream << actionIndex; + + buffer->seek(0); + message->unserialize(*stream); + + QCOMPARE(message->index(), actionIndex); +} + +void Ut_DuiAppletObjectMenuActionSelectedMessage::testActionIndex() +{ + QCOMPARE(message->index(), (uint)100); +} + +QTEST_APPLESS_MAIN(Ut_DuiAppletObjectMenuActionSelectedMessage) diff --git a/tests/ut_duiappletobjectmenuactionselectedmessage/ut_duiappletobjectmenuactionselectedmessage.h b/tests/ut_duiappletobjectmenuactionselectedmessage/ut_duiappletobjectmenuactionselectedmessage.h new file mode 100644 index 000000000..69d66e9b0 --- /dev/null +++ b/tests/ut_duiappletobjectmenuactionselectedmessage/ut_duiappletobjectmenuactionselectedmessage.h @@ -0,0 +1,48 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIAPPLETOBJECTMENUACTIONSELECTEDMESSAGE_H +#define UT_DUIAPPLETOBJECTMENUACTIONSELECTEDMESSAGE_H + +#include + +class QBuffer; +class QDataStream; +class DuiAppletObjectMenuActionSelectedMessage; + +class Ut_DuiAppletObjectMenuActionSelectedMessage : public QObject +{ + Q_OBJECT + +private: + QBuffer *buffer; + QDataStream *stream; + DuiAppletObjectMenuActionSelectedMessage *message; + +private slots: + void init(); + void cleanup(); + + void testType(); + void testActionIndex(); + void testSerialization(); + void testUnserialization(); +}; + +#endif // UT_DUIAPPLETOBJECTMENUACTIONSELECTEDMESSAGE_H diff --git a/tests/ut_duiappletobjectmenuactionselectedmessage/ut_duiappletobjectmenuactionselectedmessage.pro b/tests/ut_duiappletobjectmenuactionselectedmessage/ut_duiappletobjectmenuactionselectedmessage.pro new file mode 100644 index 000000000..ca72d04c2 --- /dev/null +++ b/tests/ut_duiappletobjectmenuactionselectedmessage/ut_duiappletobjectmenuactionselectedmessage.pro @@ -0,0 +1,13 @@ +include(../common_top.pri) +TARGET = ut_duiappletobjectmenuactionselectedmessage +INCLUDEPATH += $$DUISRCDIR/mashup/appletcommunication $$DUISRCDIR/mashup/appletinterface $$DUISRCDIR/mashup/mashup + +# unit test and unit classes +SOURCES += \ + ut_duiappletobjectmenuactionselectedmessage.cpp + +# unit test and unit classes +HEADERS += \ + ut_duiappletobjectmenuactionselectedmessage.h + +include(../common_bot.pri) diff --git a/tests/ut_duiappletobjectmenumessage/.gitignore b/tests/ut_duiappletobjectmenumessage/.gitignore new file mode 100644 index 000000000..87f41cb70 --- /dev/null +++ b/tests/ut_duiappletobjectmenumessage/.gitignore @@ -0,0 +1 @@ +ut_duiappletobjectmenumessage diff --git a/tests/ut_duiappletobjectmenumessage/ut_duiappletobjectmenumessage.cpp b/tests/ut_duiappletobjectmenumessage/ut_duiappletobjectmenumessage.cpp new file mode 100644 index 000000000..ef4c19229 --- /dev/null +++ b/tests/ut_duiappletobjectmenumessage/ut_duiappletobjectmenumessage.cpp @@ -0,0 +1,91 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duiappletobjectmenumessage.h" + +#include +#include +#include "duiappletobjectmenumessage.h" + +void Ut_DuiAppletObjectMenuMessage::init() +{ + // Allocate a buffer and a stream for (un)serialization + buffer = new QBuffer; + buffer->open(QIODevice::ReadWrite); + stream = new QDataStream(buffer); + + QList actions; + QObject mockobject; + QAction action1("action1", &mockobject); + QAction action2("action2", &mockobject); + QAction action3("action3", &mockobject); + actions.append(&action1); + actions.append(&action2); + actions.append(&action3); + + message = new DuiAppletObjectMenuMessage(actions); +} + +void Ut_DuiAppletObjectMenuMessage::cleanup() +{ + delete message; + delete stream; + delete buffer; +} + +void Ut_DuiAppletObjectMenuMessage::testType() +{ + QCOMPARE(message->type(), DuiAppletMessage::OBJECT_MENU_MESSAGE); +} + +void Ut_DuiAppletObjectMenuMessage::testSerialization() +{ + message->serialize(*stream); + + // Seek to the beginning of the buffer + buffer->seek(0); + + QList actionNames; + *stream >> actionNames; + QCOMPARE(actionNames.at(0), QString("action1")); + QCOMPARE(actionNames.at(1), QString("action2")); + QCOMPARE(actionNames.at(2), QString("action3")); +} + +void Ut_DuiAppletObjectMenuMessage::testUnserialization() +{ + QList actionNames; + actionNames.append("action1"); + actionNames.append("action2"); + *stream << actionNames; + + buffer->seek(0); + message->unserialize(*stream); + + QCOMPARE(message->actionList().size(), 2); + QCOMPARE(message->actionList().at(0), actionNames.at(0)); + QCOMPARE(message->actionList().at(1), actionNames.at(1)); +} + +void Ut_DuiAppletObjectMenuMessage::testActionList() +{ + QCOMPARE(message->actionList().at(0), QString("action1")); +} + +QTEST_APPLESS_MAIN(Ut_DuiAppletObjectMenuMessage) diff --git a/tests/ut_duiappletobjectmenumessage/ut_duiappletobjectmenumessage.h b/tests/ut_duiappletobjectmenumessage/ut_duiappletobjectmenumessage.h new file mode 100644 index 000000000..2fdbc0a03 --- /dev/null +++ b/tests/ut_duiappletobjectmenumessage/ut_duiappletobjectmenumessage.h @@ -0,0 +1,48 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIAPPLETOBJECTMENUMESSAGE_H +#define UT_DUIAPPLETOBJECTMENUMESSAGE_H + +#include + +class QBuffer; +class QDataStream; +class DuiAppletObjectMenuMessage; + +class Ut_DuiAppletObjectMenuMessage : public QObject +{ + Q_OBJECT + +private: + QBuffer *buffer; + QDataStream *stream; + DuiAppletObjectMenuMessage *message; + +private slots: + void init(); + void cleanup(); + + void testType(); + void testActionList(); + void testSerialization(); + void testUnserialization(); +}; + +#endif // UT_DUIAPPLETOBJECTMENUMESSAGE_H diff --git a/tests/ut_duiappletobjectmenumessage/ut_duiappletobjectmenumessage.pro b/tests/ut_duiappletobjectmenumessage/ut_duiappletobjectmenumessage.pro new file mode 100644 index 000000000..14e86dfc5 --- /dev/null +++ b/tests/ut_duiappletobjectmenumessage/ut_duiappletobjectmenumessage.pro @@ -0,0 +1,13 @@ +include(../common_top.pri) +TARGET = ut_duiappletobjectmenumessage +INCLUDEPATH += $$DUISRCDIR/mashup/appletcommunication $$DUISRCDIR/mashup/appletinterface $$DUISRCDIR/mashup/mashup + +# unit test and unit classes +SOURCES += \ + ut_duiappletobjectmenumessage.cpp + +# unit test and unit classes +HEADERS += \ + ut_duiappletobjectmenumessage.h + +include(../common_bot.pri) diff --git a/tests/ut_duiappletobjectmenurequestmessage/.gitignore b/tests/ut_duiappletobjectmenurequestmessage/.gitignore new file mode 100644 index 000000000..b02b0be4d --- /dev/null +++ b/tests/ut_duiappletobjectmenurequestmessage/.gitignore @@ -0,0 +1 @@ +ut_duiappletobjectmenurequestmessage diff --git a/tests/ut_duiappletobjectmenurequestmessage/ut_duiappletobjectmenurequestmessage.cpp b/tests/ut_duiappletobjectmenurequestmessage/ut_duiappletobjectmenurequestmessage.cpp new file mode 100644 index 000000000..615d4b2e7 --- /dev/null +++ b/tests/ut_duiappletobjectmenurequestmessage/ut_duiappletobjectmenurequestmessage.cpp @@ -0,0 +1,75 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duiappletobjectmenurequestmessage.h" + +#include +#include "duiappletobjectmenurequestmessage.h" + +void Ut_DuiAppletObjectMenuRequestMessage::init() +{ + // Allocate a buffer and a stream for (un)serialization + buffer = new QBuffer; + buffer->open(QIODevice::ReadWrite); + stream = new QDataStream(buffer); + + message = new DuiAppletObjectMenuRequestMessage(QPoint(1, 2)); +} + +void Ut_DuiAppletObjectMenuRequestMessage::cleanup() +{ + delete message; + delete stream; + delete buffer; +} + +void Ut_DuiAppletObjectMenuRequestMessage::testType() +{ + QCOMPARE(message->type(), DuiAppletMessage::OBJECT_MENU_REQUEST_MESSAGE); +} + +void Ut_DuiAppletObjectMenuRequestMessage::testSerialization() +{ + message->serialize(*stream); + + // Seek to the beginning of the buffer + buffer->seek(0); + QPointF point; + *stream >> point; + + QCOMPARE(point, QPointF(1, 2)); +} + +void Ut_DuiAppletObjectMenuRequestMessage::testUnserialization() +{ + QPointF point(5, 6); + *stream << point; + + buffer->seek(0); + message->unserialize(*stream); + + QCOMPARE(message->pos(), point); +} + +void Ut_DuiAppletObjectMenuRequestMessage::testPos() +{ + QCOMPARE(message->pos(), QPointF(1, 2)); +} + +QTEST_APPLESS_MAIN(Ut_DuiAppletObjectMenuRequestMessage) diff --git a/tests/ut_duiappletobjectmenurequestmessage/ut_duiappletobjectmenurequestmessage.h b/tests/ut_duiappletobjectmenurequestmessage/ut_duiappletobjectmenurequestmessage.h new file mode 100644 index 000000000..e56672b50 --- /dev/null +++ b/tests/ut_duiappletobjectmenurequestmessage/ut_duiappletobjectmenurequestmessage.h @@ -0,0 +1,48 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIAPPLETOBJECTMENUREQUESTMESSAGE_H +#define UT_DUIAPPLETOBJECTMENUREQUESTMESSAGE_H + +#include + +class QBuffer; +class QDataStream; +class DuiAppletObjectMenuRequestMessage; + +class Ut_DuiAppletObjectMenuRequestMessage : public QObject +{ + Q_OBJECT + +private: + QBuffer *buffer; + QDataStream *stream; + DuiAppletObjectMenuRequestMessage *message; + +private slots: + void init(); + void cleanup(); + + void testType(); + void testPos(); + void testSerialization(); + void testUnserialization(); +}; + +#endif // UT_DUIAPPLETOBJECTMENUREQUESTMESSAGE_H diff --git a/tests/ut_duiappletobjectmenurequestmessage/ut_duiappletobjectmenurequestmessage.pro b/tests/ut_duiappletobjectmenurequestmessage/ut_duiappletobjectmenurequestmessage.pro new file mode 100644 index 000000000..96a4350b1 --- /dev/null +++ b/tests/ut_duiappletobjectmenurequestmessage/ut_duiappletobjectmenurequestmessage.pro @@ -0,0 +1,13 @@ +include(../common_top.pri) +TARGET = ut_duiappletobjectmenurequestmessage +INCLUDEPATH += $$DUISRCDIR/mashup/appletcommunication $$DUISRCDIR/mashup/appletinterface $$DUISRCDIR/mashup/mashup + +# unit test and unit classes +SOURCES += \ + ut_duiappletobjectmenurequestmessage.cpp + +# unit test and unit classes +HEADERS += \ + ut_duiappletobjectmenurequestmessage.h + +include(../common_bot.pri) diff --git a/tests/ut_duiappletorientationmessage/.gitignore b/tests/ut_duiappletorientationmessage/.gitignore new file mode 100644 index 000000000..7ea8d6de8 --- /dev/null +++ b/tests/ut_duiappletorientationmessage/.gitignore @@ -0,0 +1 @@ +ut_duiappletorientationmessage diff --git a/tests/ut_duiappletorientationmessage/ut_duiappletorientationmessage.cpp b/tests/ut_duiappletorientationmessage/ut_duiappletorientationmessage.cpp new file mode 100644 index 000000000..2dbdc727c --- /dev/null +++ b/tests/ut_duiappletorientationmessage/ut_duiappletorientationmessage.cpp @@ -0,0 +1,77 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duiappletorientationmessage.h" + +#include +#include "duiappletorientationmessage.h" + +void Ut_DuiAppletOrientationMessage::init() +{ + // Allocate a buffer and a stream for (un)serialization + buffer = new QBuffer; + buffer->open(QIODevice::ReadWrite); + stream = new QDataStream(buffer); + + message = new DuiAppletOrientationMessage(); +} + +void Ut_DuiAppletOrientationMessage::cleanup() +{ + delete message; + delete stream; + delete buffer; +} + +void Ut_DuiAppletOrientationMessage::testType() +{ + QCOMPARE(message->type(), DuiAppletMessage::ORIENTATION_MESSAGE); +} + +void Ut_DuiAppletOrientationMessage::testOrientationProperty() +{ + QCOMPARE(message->orientation(), Dui::Landscape); + message->setOrientation(Dui::Portrait); + QCOMPARE(message->orientation(), Dui::Portrait); +} + +void Ut_DuiAppletOrientationMessage::testSerialization() +{ + message->serialize(*stream); + + // Seek to the beginning of the buffer + buffer->seek(0); + uchar tmp = (uchar)Dui::Portrait; + *stream >> tmp; + Dui::Orientation result = (Dui::Orientation)tmp; + + QCOMPARE(result, Dui::Landscape); +} + +void Ut_DuiAppletOrientationMessage::testUnserialization() +{ + *stream << (uchar)Dui::Portrait; + + buffer->seek(0); + message->unserialize(*stream); + + QCOMPARE(message->orientation(), Dui::Portrait); +} + +QTEST_APPLESS_MAIN(Ut_DuiAppletOrientationMessage) diff --git a/tests/ut_duiappletorientationmessage/ut_duiappletorientationmessage.h b/tests/ut_duiappletorientationmessage/ut_duiappletorientationmessage.h new file mode 100644 index 000000000..263633827 --- /dev/null +++ b/tests/ut_duiappletorientationmessage/ut_duiappletorientationmessage.h @@ -0,0 +1,48 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIAPPLETORIENTATIONMESSAGE_H +#define UT_DUIAPPLETORIENTATIONMESSAGE_H + +#include + +class QBuffer; +class QDataStream; +class DuiAppletOrientationMessage; + +class Ut_DuiAppletOrientationMessage : public QObject +{ + Q_OBJECT + +private: + QBuffer *buffer; + QDataStream *stream; + DuiAppletOrientationMessage *message; + +private slots: + void init(); + void cleanup(); + + void testType(); + void testOrientationProperty(); + void testSerialization(); + void testUnserialization(); +}; + +#endif // UT_DUIAPPLETORIENTATIONMESSAGE_H diff --git a/tests/ut_duiappletorientationmessage/ut_duiappletorientationmessage.pro b/tests/ut_duiappletorientationmessage/ut_duiappletorientationmessage.pro new file mode 100644 index 000000000..37b381a0b --- /dev/null +++ b/tests/ut_duiappletorientationmessage/ut_duiappletorientationmessage.pro @@ -0,0 +1,13 @@ +include(../common_top.pri) +TARGET = ut_duiappletorientationmessage +INCLUDEPATH += $$DUISRCDIR/mashup/appletcommunication $$DUISRCDIR/mashup/appletinterface $$DUISRCDIR/mashup/mashup + +# unit test and unit classes +SOURCES += \ + ut_duiappletorientationmessage.cpp \ + +# unit test and unit classes +HEADERS += \ + ut_duiappletorientationmessage.h \ + +include(../common_bot.pri) diff --git a/tests/ut_duiappletpixmapmodifiedmessage/.gitignore b/tests/ut_duiappletpixmapmodifiedmessage/.gitignore new file mode 100644 index 000000000..b2039afc1 --- /dev/null +++ b/tests/ut_duiappletpixmapmodifiedmessage/.gitignore @@ -0,0 +1 @@ +ut_duiappletpixmapmodifiedmessage diff --git a/tests/ut_duiappletpixmapmodifiedmessage/ut_duiappletpixmapmodifiedmessage.cpp b/tests/ut_duiappletpixmapmodifiedmessage/ut_duiappletpixmapmodifiedmessage.cpp new file mode 100644 index 000000000..112c48472 --- /dev/null +++ b/tests/ut_duiappletpixmapmodifiedmessage/ut_duiappletpixmapmodifiedmessage.cpp @@ -0,0 +1,78 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duiappletpixmapmodifiedmessage.h" + +#include +#include "duiappletpixmapmodifiedmessage.h" + +void Ut_DuiAppletPixmapModifiedMessage::init() +{ + // Allocate a buffer and a stream for (un)serialization + buffer = new QBuffer; + buffer->open(QIODevice::ReadWrite); + stream = new QDataStream(buffer); + + message = new DuiAppletPixmapModifiedMessage(); +} + +void Ut_DuiAppletPixmapModifiedMessage::cleanup() +{ + delete message; + delete stream; + delete buffer; +} + +void Ut_DuiAppletPixmapModifiedMessage::testType() +{ + QCOMPARE(message->type(), DuiAppletMessage::PIXMAP_MODIFIED_MESSAGE); +} + +void Ut_DuiAppletPixmapModifiedMessage::testGeometryProperty() +{ + QCOMPARE(message->geometry(), QRectF()); + QRectF tmp(1.0, 2.0, 3.0, 4.0); + message->setGeometry(tmp); + QCOMPARE(message->geometry(), tmp); +} + +void Ut_DuiAppletPixmapModifiedMessage::testSerialization() +{ + message->serialize(*stream); + + // Seek to the beginning of the buffer + buffer->seek(0); + QRectF geometry(1.0, 2.0, 3.0, 4.0); + *stream >> geometry; + + QCOMPARE(geometry, QRectF()); +} + +void Ut_DuiAppletPixmapModifiedMessage::testUnserialization() +{ + QRectF geometry(1.0, 2.0, 3.0, 4.0); + *stream << geometry; + + buffer->seek(0); + message->unserialize(*stream); + + QCOMPARE(message->geometry(), geometry); +} + +QTEST_APPLESS_MAIN(Ut_DuiAppletPixmapModifiedMessage) diff --git a/tests/ut_duiappletpixmapmodifiedmessage/ut_duiappletpixmapmodifiedmessage.h b/tests/ut_duiappletpixmapmodifiedmessage/ut_duiappletpixmapmodifiedmessage.h new file mode 100644 index 000000000..c5dac68bb --- /dev/null +++ b/tests/ut_duiappletpixmapmodifiedmessage/ut_duiappletpixmapmodifiedmessage.h @@ -0,0 +1,48 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIAPPLETPIXMAPMODIFIEDMESSAGE_H +#define UT_DUIAPPLETPIXMAPMODIFIEDMESSAGE_H + +#include + +class QBuffer; +class QDataStream; +class DuiAppletPixmapModifiedMessage; + +class Ut_DuiAppletPixmapModifiedMessage : public QObject +{ + Q_OBJECT + +private: + QBuffer *buffer; + QDataStream *stream; + DuiAppletPixmapModifiedMessage *message; + +private slots: + void init(); + void cleanup(); + + void testType(); + void testGeometryProperty(); + void testSerialization(); + void testUnserialization(); +}; + +#endif // UT_DUIAPPLETPIXMAPMODIFIEDMESSAGE_H diff --git a/tests/ut_duiappletpixmapmodifiedmessage/ut_duiappletpixmapmodifiedmessage.pro b/tests/ut_duiappletpixmapmodifiedmessage/ut_duiappletpixmapmodifiedmessage.pro new file mode 100644 index 000000000..7420d6614 --- /dev/null +++ b/tests/ut_duiappletpixmapmodifiedmessage/ut_duiappletpixmapmodifiedmessage.pro @@ -0,0 +1,13 @@ +include(../common_top.pri) +TARGET = ut_duiappletpixmapmodifiedmessage +INCLUDEPATH += $$DUISRCDIR/mashup/appletcommunication $$DUISRCDIR/mashup/appletinterface $$DUISRCDIR/mashup/mashup + +# unit test and unit classes +SOURCES += \ + ut_duiappletpixmapmodifiedmessage.cpp + +# unit test and unit classes +HEADERS += \ + ut_duiappletpixmapmodifiedmessage.h + +include(../common_bot.pri) diff --git a/tests/ut_duiappletpixmaptakenintousemessage/.gitignore b/tests/ut_duiappletpixmaptakenintousemessage/.gitignore new file mode 100644 index 000000000..35dfbcc6b --- /dev/null +++ b/tests/ut_duiappletpixmaptakenintousemessage/.gitignore @@ -0,0 +1 @@ +ut_duiappletpixmaptakenintousemessage diff --git a/tests/ut_duiappletpixmaptakenintousemessage/ut_duiappletpixmaptakenintousemessage.cpp b/tests/ut_duiappletpixmaptakenintousemessage/ut_duiappletpixmaptakenintousemessage.cpp new file mode 100644 index 000000000..4c7fe782c --- /dev/null +++ b/tests/ut_duiappletpixmaptakenintousemessage/ut_duiappletpixmaptakenintousemessage.cpp @@ -0,0 +1,77 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duiappletpixmaptakenintousemessage.h" + +#include +#include "duiappletpixmaptakenintousemessage.h" + +void Ut_DuiAppletPixmapTakenIntoUseMessage::init() +{ + // Allocate a buffer and a stream for (un)serialization + buffer = new QBuffer; + buffer->open(QIODevice::ReadWrite); + stream = new QDataStream(buffer); + + message = new DuiAppletPixmapTakenIntoUseMessage(); +} + +void Ut_DuiAppletPixmapTakenIntoUseMessage::cleanup() +{ + delete message; + delete stream; + delete buffer; +} + +void Ut_DuiAppletPixmapTakenIntoUseMessage::testType() +{ + QCOMPARE(message->type(), DuiAppletMessage::PIXMAP_TAKEN_INTO_USE_MESSAGE); +} + +void Ut_DuiAppletPixmapTakenIntoUseMessage::testHandleProperty() +{ + QCOMPARE(message->handle(), (Qt::HANDLE)0); + Qt::HANDLE tmp = 52; + message->setHandle(tmp); + QCOMPARE(message->handle(), tmp); +} + +void Ut_DuiAppletPixmapTakenIntoUseMessage::testSerialization() +{ + message->serialize(*stream); + + buffer->seek(0); + quint64 handle = 52; + *stream >> handle; + + QCOMPARE(handle, (quint64)0); +} + +void Ut_DuiAppletPixmapTakenIntoUseMessage::testUnserialization() +{ + Qt::HANDLE handle = 52; + *stream << (quint64)handle; + + buffer->seek(0); + message->unserialize(*stream); + + QCOMPARE(message->handle(), handle); +} + +QTEST_APPLESS_MAIN(Ut_DuiAppletPixmapTakenIntoUseMessage) diff --git a/tests/ut_duiappletpixmaptakenintousemessage/ut_duiappletpixmaptakenintousemessage.h b/tests/ut_duiappletpixmaptakenintousemessage/ut_duiappletpixmaptakenintousemessage.h new file mode 100644 index 000000000..9b9ad9852 --- /dev/null +++ b/tests/ut_duiappletpixmaptakenintousemessage/ut_duiappletpixmaptakenintousemessage.h @@ -0,0 +1,48 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIAPPLETPIXMAPTAKENINTOUSEMESSAGE_H +#define UT_DUIAPPLETPIXMAPTAKENINTOUSEMESSAGE_H + +#include + +class QBuffer; +class QDataStream; +class DuiAppletPixmapTakenIntoUseMessage; + +class Ut_DuiAppletPixmapTakenIntoUseMessage : public QObject +{ + Q_OBJECT + +private: + QBuffer *buffer; + QDataStream *stream; + DuiAppletPixmapTakenIntoUseMessage *message; + +private slots: + void init(); + void cleanup(); + + void testType(); + void testHandleProperty(); + void testSerialization(); + void testUnserialization(); +}; + +#endif // UT_DUIAPPLETPIXMAPTAKENINTOUSEMESSAGE_H diff --git a/tests/ut_duiappletpixmaptakenintousemessage/ut_duiappletpixmaptakenintousemessage.pro b/tests/ut_duiappletpixmaptakenintousemessage/ut_duiappletpixmaptakenintousemessage.pro new file mode 100644 index 000000000..686294856 --- /dev/null +++ b/tests/ut_duiappletpixmaptakenintousemessage/ut_duiappletpixmaptakenintousemessage.pro @@ -0,0 +1,13 @@ +include(../common_top.pri) +TARGET = ut_duiappletpixmaptakenintousemessage +INCLUDEPATH += $$DUISRCDIR/mashup/appletcommunication $$DUISRCDIR/mashup/appletinterface $$DUISRCDIR/mashup/mashup + +# unit test and unit classes +SOURCES += \ + ut_duiappletpixmaptakenintousemessage.cpp + +# unit test and unit classes +HEADERS += \ + ut_duiappletpixmaptakenintousemessage.h + +include(../common_bot.pri) diff --git a/tests/ut_duiappletrunner/.gitignore b/tests/ut_duiappletrunner/.gitignore new file mode 100644 index 000000000..3404d2393 --- /dev/null +++ b/tests/ut_duiappletrunner/.gitignore @@ -0,0 +1,2 @@ +ut_duiappletrunner + diff --git a/tests/ut_duiappletrunner/ut_duiappletrunner.cpp b/tests/ut_duiappletrunner/ut_duiappletrunner.cpp new file mode 100644 index 000000000..881197d86 --- /dev/null +++ b/tests/ut_duiappletrunner/ut_duiappletrunner.cpp @@ -0,0 +1,541 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duiappletrunner.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +QString gAppletBinary; + +// DuiWindow stubs (to prevent crashing) +DuiWindow::DuiWindow(QWidget *parent) + : QGraphicsView(parent), + d_ptr(0) +{ +} +DuiWindow::~DuiWindow() +{ +} + +// QTimer stubs (used by DuiAppletRunner) +void QTimer::start(int) +{ + if (Ut_DuiAppletRunner::timerImmediateTimeout) { + emit timeout(); + } +} + +// QCoreApplication stubs (used by DuiAppletRunner) +void QCoreApplication::quit() +{ + Ut_DuiAppletRunner::quitCalled = true; +} + +// DuiSettingsLanguageBinary stubs (used by DuiAppletRunner) +QStringList DuiSettingsLanguageBinary::keys() const +{ + QStringList list; + if (Ut_DuiAppletRunner::processingInstanceSettingsFile) { + list.append("instanceKey1"); + list.append("instanceKey2"); + } else if (Ut_DuiAppletRunner::processingGlobalSettingsFile) { + list.append("globalKey1"); + list.append("globalKey2"); + } + return list; +} + +// QFile stubs (used by DuiAppletRunner) +bool QFile::exists() const +{ + Ut_DuiAppletRunner::processingInstanceSettingsFile = fileName().contains("-instance.xml"); + Ut_DuiAppletRunner::processingGlobalSettingsFile = fileName().contains("-global.xml"); + return true; +} + +// DuiSettingsLanguageParser stubs (used by DuiAppletRunner) +DuiSettingsLanguageBinary *DuiSettingsLanguageParser::createSettingsBinary() +{ + return new DuiSettingsLanguageBinary; +} + +// QGraphicsScene stubs +bool sceneRenderCalled; +void QGraphicsScene::render(QPainter *, const QRectF &, const QRectF &, Qt::AspectRatioMode) +{ + sceneRenderCalled = true; +} + + +MouseEventFilter::~MouseEventFilter() +{ + foreach(QGraphicsSceneMouseEvent * e, events) { + delete e; + } +} + +bool MouseEventFilter::eventFilter(QObject *o, QEvent *e) +{ + Q_UNUSED(o); + + if (e->type() == QEvent::GraphicsSceneMousePress || e->type() == QEvent::GraphicsSceneMouseRelease || e->type() == QEvent::GraphicsSceneMouseMove) { + QGraphicsSceneMouseEvent *mouseEvent = static_cast(e); + QGraphicsSceneMouseEvent *storedEvent = new QGraphicsSceneMouseEvent(e->type()); + storedEvent->setButton(mouseEvent->button()); + storedEvent->setButtons(mouseEvent->buttons()); + events.append(storedEvent); + } + + return false; +} + +bool DuiAppletCommunicator_connectToProcessReturn = true; +bool DuiAppletClient::connectToServer(const QString &serverName) +{ + Q_UNUSED(serverName); + return DuiAppletCommunicator_connectToProcessReturn; +} +DuiAppletMessage::DuiAppletMessageType DuiAppletCommunicator_sentMessageType; +QRectF DuiAppletCommunicator_sentPixmapModifiedMessageGeometry; +QList DuiAppletCommunicator_sentObjectMenuActionList; +QVector DuiAppletCommunicator_sentUpdateGeometryMessageSizeHints; +bool DuiAppletCommunicator::sendMessage(const DuiAppletMessage &message) +{ + DuiAppletCommunicator_sentMessageType = message.type(); + if (DuiAppletCommunicator_sentMessageType == DuiAppletMessage::PIXMAP_MODIFIED_MESSAGE) { + const DuiAppletPixmapModifiedMessage pixmapModifiedMessage = dynamic_cast(message); + DuiAppletCommunicator_sentPixmapModifiedMessageGeometry = pixmapModifiedMessage.geometry(); + } else if (DuiAppletCommunicator_sentMessageType == DuiAppletMessage::UPDATE_GEOMETRY_MESSAGE) { + const DuiAppletUpdateGeometryMessage updateGeometryMessage = dynamic_cast(message); + DuiAppletCommunicator_sentUpdateGeometryMessageSizeHints = updateGeometryMessage.sizeHints(); + } else if (DuiAppletCommunicator_sentMessageType == DuiAppletMessage::OBJECT_MENU_MESSAGE) { + const DuiAppletObjectMenuMessage objectMenuMessage = dynamic_cast(message); + DuiAppletCommunicator_sentObjectMenuActionList = objectMenuMessage.actionList(); + } + return true; +} + +bool DuiAppletMetaData_isValidReturn = true; +bool DuiAppletMetaData::isValid() const +{ + return DuiAppletMetaData_isValidReturn; +} + +bool DuiAppletLoader_doConstructWidget = true; +bool DuiAppletLoader_returnPreCreatedWidget = false; +DuiWidget *widget; +DuiWidget *DuiAppletLoader::loadApplet(const DuiAppletMetaData &, DuiDataStore &, DuiDataAccess &) +{ + if (DuiAppletLoader_doConstructWidget) { + if (DuiAppletLoader_returnPreCreatedWidget) { + return widget; + } else { + DuiWidget *widget = new DuiWidget; + widget->setMinimumSize(QSizeF(50, 50)); + widget->setPreferredSize(QSizeF(100, 100)); + widget->setMaximumSize(QSizeF(150, 150)); + return widget; + } + } else { + return NULL; + } +} + +bool Ut_DuiAppletRunner::timerImmediateTimeout; +bool Ut_DuiAppletRunner::quitCalled; +bool Ut_DuiAppletRunner::processingInstanceSettingsFile; +bool Ut_DuiAppletRunner::processingGlobalSettingsFile; + +// Unit test cases +void Ut_DuiAppletRunner::init() +{ + m_instance = new DuiAppletRunner(); + connect(this, SIGNAL(sendMessage(DuiAppletMessage)), m_instance, SLOT(messageReceived(DuiAppletMessage))); + meta = new DuiAppletMetaData("ut_duiappletrunner/ut_duiappletrunner.desktop"); + + gAppletBinary = ""; + timerImmediateTimeout = false; + quitCalled = false; + gDuiAppletSharedMutexStub->stubReset(); + gDuiAppletSharedMutexStub->stubSetReturnValue("init", true); + gDuiAppletSharedMutexStub->stubSetReturnValue("lock", true); + gDuiAppletSharedMutexStub->stubSetReturnValue("unlock", true); + gDuiAppletSharedMutexStub->stubSetReturnValue("tryLock", true); + processingInstanceSettingsFile = false; + processingGlobalSettingsFile = false; + DuiAppletCommunicator_connectToProcessReturn = true; + DuiAppletCommunicator_sentMessageType = DuiAppletMessage::INVALID; + DuiAppletCommunicator_sentPixmapModifiedMessageGeometry = QRectF(); + DuiAppletCommunicator_sentUpdateGeometryMessageSizeHints = QVector(Qt::NSizeHints); + DuiAppletMetaData_isValidReturn = true; + DuiAppletLoader_doConstructWidget = true; + sceneRenderCalled = false; + DuiAppletLoader_returnPreCreatedWidget = false; + widget = NULL; + gDuiAppletSettingsStub->stubReset(); +} + +void Ut_DuiAppletRunner::cleanup() +{ + delete meta; + meta = NULL; + delete m_instance; + m_instance = NULL; +} + +void Ut_DuiAppletRunner::initTestCase() +{ +} + +void Ut_DuiAppletRunner::cleanupTestCase() +{ +} + +void Ut_DuiAppletRunner::testInitializationSuccess() +{ + QCOMPARE(m_instance->init("appletId", "/tmp/applet.data", *meta, "servername"), true); + QCOMPARE(gDuiAppletSharedMutexStub->stubLastCallTo("init").parameter(0), QString("servername")); + QCOMPARE(gDuiAppletSettingsStub->stubLastCallTo("duiAppletSettingsConstructor").parameter(0), QString("ut_duiappletrunner/ut_duiappletrunner.desktop")); + QCOMPARE(gDuiAppletSettingsStub->stubLastCallTo("duiAppletSettingsConstructor").parameter(1), QString("appletId")); +} + +void Ut_DuiAppletRunner::testInitializationFailInvalidAppletId() +{ + QCOMPARE(m_instance->init("", "/tmp/applet.data", *meta, "servername"), false); +} + +void Ut_DuiAppletRunner::testInitializationFailInvalidInstanceDataLocation() +{ + QCOMPARE(m_instance->init("appletId", "", *meta, "servername"), false); +} + +void Ut_DuiAppletRunner::testInitializationFailInvalidMetadata() +{ + DuiAppletMetaData_isValidReturn = false; + QCOMPARE(m_instance->init("appletId", "/tmp/applet.data", *meta, "servername"), false); +} + +void Ut_DuiAppletRunner::testInitializationFailCommunicationFails() +{ + DuiAppletCommunicator_connectToProcessReturn = false; + QCOMPARE(m_instance->init("appletId", "/tmp/applet.data", *meta, "servername"), false); +} + +void Ut_DuiAppletRunner::testInitializationFailConstructWidgetFails() +{ + DuiAppletLoader_doConstructWidget = false; + QCOMPARE(m_instance->init("appletId", "/tmp/applet.data", *meta, "servername"), false); +} + +void Ut_DuiAppletRunner::testInitializationFailSharedMemoryAttachFails() +{ + gDuiAppletSharedMutexStub->stubSetReturnValue("init", false); + QCOMPARE(m_instance->init("appletId", "/tmp/applet.data", *meta, "servername"), false); +} + +void Ut_DuiAppletRunner::testRelayingMouseEvents() +{ + m_instance->init("appletId", "/tmp/applet.data", *meta, "servername"); + + // Install event filter + MouseEventFilter filter; + QCoreApplication::instance()->installEventFilter(&filter); + + // Emit mouse press message + DuiAppletMouseMessage message1(DuiAppletMessage::MOUSE_PRESS_MESSAGE, QPointF(-5, 2), Qt::RightButton, Qt::RightButton | Qt::MidButton); + emit sendMessage(message1); + QCOMPARE(filter.events.count(), 1); + QCOMPARE(filter.events.at(0)->type(), QEvent::GraphicsSceneMousePress); + QCOMPARE(filter.events.at(0)->button(), Qt::RightButton); + QCOMPARE(filter.events.at(0)->buttons(), Qt::RightButton | Qt::MidButton); + + // Emit mouse release message + DuiAppletMouseMessage message2(DuiAppletMessage::MOUSE_RELEASE_MESSAGE, QPointF(0, 4), Qt::LeftButton, Qt::LeftButton | Qt::MidButton); + emit sendMessage(message2); + QCOMPARE(filter.events.count(), 2); + QCOMPARE(filter.events.at(1)->type(), QEvent::GraphicsSceneMouseRelease); + QCOMPARE(filter.events.at(1)->button(), Qt::LeftButton); + QCOMPARE(filter.events.at(1)->buttons(), Qt::LeftButton | Qt::MidButton); + + // Emit mouse move message + DuiAppletMouseMessage message3(DuiAppletMessage::MOUSE_MOVE_MESSAGE, QPointF(-5, 2), Qt::MidButton, Qt::MidButton); + emit sendMessage(message3); + QCOMPARE(filter.events.count(), 3); + QCOMPARE(filter.events.at(2)->type(), QEvent::GraphicsSceneMouseMove); + QCOMPARE(filter.events.at(2)->button(), Qt::MidButton); + QCOMPARE(filter.events.at(2)->buttons(), Qt::MidButton); + + // Remove event filter + QCoreApplication::instance()->removeEventFilter(&filter); +} + +void Ut_DuiAppletRunner::testAppletRunnerQuitsIfMessageReceivingTimeouts() +{ + m_instance->init("appletId", "/tmp/applet.data", *meta, "servername"); + + // Verify that the quit is not always called + DuiAppletMouseMessage message1(DuiAppletMessage::MOUSE_PRESS_MESSAGE, QPointF(-5, 2), Qt::RightButton, Qt::RightButton | Qt::MidButton); + emit sendMessage(message1); + QVERIFY(!quitCalled); + + // Verify that quit is called when the timer times out + timerImmediateTimeout = true; + emit sendMessage(message1); + QVERIFY(quitCalled); +} + +// This test is here to test to nothing happens. Not segfaults or anything. That's why it doesn't really compare anything +void Ut_DuiAppletRunner::testMessageReceivedBeforeAppletInit() +{ + { + // Mouse messages are more or less the same so it's enough to test only one + DuiAppletMouseMessage msg(DuiAppletMessage::MOUSE_PRESS_MESSAGE, QPointF(-5, 2), Qt::RightButton, Qt::RightButton | Qt::MidButton); + emit sendMessage(msg); + } + + { + DuiAppletVisibilityMessage msg(true); + emit sendMessage(msg); + } + + { + DuiAppletOrientationMessage msg; + emit sendMessage(msg); + } + + { + DuiAppletSetGeometryMessage msg; + emit sendMessage(msg); + } + + { + DuiAppletAliveMessageRequest msg; + emit sendMessage(msg); + } +} + +void Ut_DuiAppletRunner::testPaintingOnPixmap() +{ + connect(this, SIGNAL(changeScene(QList)), m_instance, SLOT(sceneChanged(QList))); + + m_instance->init("appletId", "/tmp/applet.data", *meta, "servername"); + + // Create target pixmap and fill it with full opaque white + QPixmap targetPixmap(150, 100); + // Painting with transparent will activate the alpha channel in the pixmap + targetPixmap.fill(Qt::transparent); + targetPixmap.fill(Qt::white); + + // Assign the pixmap to the applet runner to be painted to. + DuiAppletSetGeometryMessage msg(QRectF(0, 0, 150, 100), targetPixmap.handle()); + emit sendMessage(msg); + + // Update subregion of the pixmap + QList region; + region.append(QRectF(25, 26, 30, 25)); + emit changeScene(region); + + // Verify that subregion was cleared to full transparent + QImage result = targetPixmap.toImage(); + QVERIFY(!result.isNull()); + QCOMPARE(result.pixel(QPoint(25, 26)), qRgba(0, 0, 0, 0)); + QCOMPARE(result.pixel(QPoint(54, 26)), qRgba(0, 0, 0, 0)); + QCOMPARE(result.pixel(QPoint(54, 50)), qRgba(0, 0, 0, 0)); + QCOMPARE(result.pixel(QPoint(25, 50)), qRgba(0, 0, 0, 0)); + QCOMPARE(result.pixel(QPoint(40, 38)), qRgba(0, 0, 0, 0)); + + // Verify that the rest of the pixmap is intact + QCOMPARE(result.pixel(QPoint(0, 0)), qRgba(255, 255, 255, 255)); + QCOMPARE(result.pixel(QPoint(24, 25)), qRgba(255, 255, 255, 255)); + QCOMPARE(result.pixel(QPoint(24, 50)), qRgba(255, 255, 255, 255)); + QCOMPARE(result.pixel(QPoint(75, 75)), qRgba(255, 255, 255, 255)); + QCOMPARE(result.pixel(QPoint(40, 70)), qRgba(255, 255, 255, 255)); +} + +void Ut_DuiAppletRunner::testSendUpdateGeometryMessage() +{ + m_instance->init("appletId", "/tmp/applet.data", *meta, "servername"); + m_instance->sendUpdateGeometryMessage(); + QCOMPARE(DuiAppletCommunicator_sentMessageType, DuiAppletMessage::UPDATE_GEOMETRY_MESSAGE); + QCOMPARE(DuiAppletCommunicator_sentUpdateGeometryMessageSizeHints.at(Qt::MinimumSize), QSizeF(50, 50)); + QCOMPARE(DuiAppletCommunicator_sentUpdateGeometryMessageSizeHints.at(Qt::PreferredSize), QSizeF(100, 100)); + QCOMPARE(DuiAppletCommunicator_sentUpdateGeometryMessageSizeHints.at(Qt::MaximumSize), QSizeF(150, 150)); +} + +void Ut_DuiAppletRunner::testSceneChanged() +{ + connect(this, SIGNAL(changeScene(QList)), m_instance, SLOT(sceneChanged(QList))); + + m_instance->init("appletId", "/tmp/applet.data", *meta, "servername"); + + // Create target pixmap + QPixmap targetPixmap(30, 30); + + // Assign the pixmap to the applet runner to be painted to. + DuiAppletSetGeometryMessage msg(QRectF(0, 0, 30, 30), targetPixmap.handle()); + emit sendMessage(msg); + + // Update subregion of the pixmap + QList region; + region.append(QRectF(0, 0, 10, 10)); + region.append(QRectF(10, 10, 10, 10)); + emit changeScene(region); + + QCOMPARE(DuiAppletCommunicator_sentMessageType, DuiAppletMessage::PIXMAP_MODIFIED_MESSAGE); + QCOMPARE(DuiAppletCommunicator_sentPixmapModifiedMessageGeometry, QRectF(0, 0, 20, 20)); + QVERIFY(sceneRenderCalled); + + // Check that no pixmap modified messages are sent when invisible + DuiAppletCommunicator_sentMessageType = DuiAppletMessage::INVALID; + DuiAppletCommunicator_sentPixmapModifiedMessageGeometry = QRectF(); + sceneRenderCalled = false; + + emit sendMessage(DuiAppletVisibilityMessage(false)); + emit changeScene(region); + QCOMPARE(DuiAppletCommunicator_sentMessageType, DuiAppletMessage::INVALID); + QCOMPARE(DuiAppletCommunicator_sentPixmapModifiedMessageGeometry, QRectF()); + QVERIFY(!sceneRenderCalled); + + region.append(QRectF(20, 20, 10, 10)); + emit changeScene(region); + QCOMPARE(DuiAppletCommunicator_sentMessageType, DuiAppletMessage::INVALID); + QCOMPARE(DuiAppletCommunicator_sentPixmapModifiedMessageGeometry, QRectF()); + QVERIFY(!sceneRenderCalled); + + // Check that pixmap modified message with cumulated rect is sent when set visible again + emit sendMessage(DuiAppletVisibilityMessage(true)); + QCOMPARE(DuiAppletCommunicator_sentMessageType, DuiAppletMessage::PIXMAP_MODIFIED_MESSAGE); + QCOMPARE(DuiAppletCommunicator_sentPixmapModifiedMessageGeometry, QRectF(0, 0, 30, 30)); + QVERIFY(sceneRenderCalled); + + // Check that cumulation of changed rect doesn't happen when applet is visible + region.clear(); + region.append(QRectF(5, 5, 15, 15)); + sceneRenderCalled = false; + emit changeScene(region); + QCOMPARE(DuiAppletCommunicator_sentMessageType, DuiAppletMessage::PIXMAP_MODIFIED_MESSAGE); + QCOMPARE(DuiAppletCommunicator_sentPixmapModifiedMessageGeometry, QRectF(5, 5, 15, 15)); + QVERIFY(sceneRenderCalled); +} + +void Ut_DuiAppletRunner::testObjectMenuRequestMessage() +{ + widget = new DuiWidget; + + DuiAppletLoader_returnPreCreatedWidget = true; + m_instance->init("appletId", "/tmp/applet.data", *meta, "servername"); + + DuiAction action1(widget); + action1.setText("objectmenuaction1"); + action1.setLocation(DuiAction::ObjectMenuLocation); + widget->addAction(&action1); + + DuiAction action2(widget); + action2.setText("normalaction"); + action2.setLocation(DuiAction::ToolBarLocation); + widget->addAction(&action2); + + DuiAction action3(widget); + action3.setText("objectmenuaction2"); + action3.setLocation(DuiAction::ObjectMenuLocation); + widget->addAction(&action3); + + DuiAction action4(widget); + action4.setText("actionforallplaces"); + action4.setLocation(DuiAction::EveryLocation); + widget->addAction(&action4); + + widget->setGeometry(3, 4, 10, 10); + + DuiAppletObjectMenuRequestMessage message(QPoint(3, 4)); + emit sendMessage(message); + + QCOMPARE(DuiAppletCommunicator_sentObjectMenuActionList.size(), 3); + QCOMPARE(DuiAppletCommunicator_sentObjectMenuActionList.at(0), QString("objectmenuaction1")); + QCOMPARE(DuiAppletCommunicator_sentObjectMenuActionList.at(1), QString("objectmenuaction2")); + QCOMPARE(DuiAppletCommunicator_sentObjectMenuActionList.at(2), QString("actionforallplaces")); + + emit sendMessage(message); + QCOMPARE(DuiAppletCommunicator_sentObjectMenuActionList.size(), 3); +} + +void Ut_DuiAppletRunner::testObjectMenuRequestMessageGetsPropagated() +{ + // Bottommost widget. This widget has an action that shouldn't get selected + widget = new DuiWidget; + // Middle widget. This widget has an action that is supposed to get selected + DuiWidget widget2(widget); + // Topmost widget. This widget has no actions so the search for actions should continue below this widget + DuiWidget widget3(&widget2); + + DuiAppletLoader_returnPreCreatedWidget = true; + m_instance->init("appletId", "/tmp/applet.data", *meta, "servername"); + + // Add action to bottommost widget + DuiAction action(widget); + action.setText("wrong_action"); + action.setLocation(DuiAction::ObjectMenuLocation); + widget->addAction(&action); + + // Add action to middle widget + DuiAction action2(&widget2); + action2.setText("correct_action"); + action2.setLocation(DuiAction::ObjectMenuLocation); + widget2.addAction(&action2); + + widget->setGeometry(0, 0, 10, 10); + widget2.setGeometry(0, 0, 10, 10); + widget3.setGeometry(0, 0, 10, 10); + + DuiAppletObjectMenuRequestMessage message(QPoint(3, 4)); + emit sendMessage(message); + + QCOMPARE(DuiAppletCommunicator_sentObjectMenuActionList.size(), 1); + QCOMPARE(DuiAppletCommunicator_sentObjectMenuActionList.at(0), QString("correct_action")); +} + +QTEST_MAIN(Ut_DuiAppletRunner) diff --git a/tests/ut_duiappletrunner/ut_duiappletrunner.h b/tests/ut_duiappletrunner/ut_duiappletrunner.h new file mode 100644 index 000000000..4c66e3c7d --- /dev/null +++ b/tests/ut_duiappletrunner/ut_duiappletrunner.h @@ -0,0 +1,93 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef _UT_DUIAPPLETRUNNER_ +#define _UT_DUIAPPLETRUNNER_ + +#include +#include +#include +#include +#include + +class DuiAppletRunner; +class DuiAppletMessage; +class DuiAppletMetaData; + +class MouseEventFilter : public QObject +{ + Q_OBJECT + +public: + ~MouseEventFilter(); + +protected: + bool eventFilter(QObject *o, QEvent *e); + +public: + QList events; +}; + +// Test case must inherit QObject +class Ut_DuiAppletRunner: public QObject +{ + Q_OBJECT + +private: + + /** DuiAppletRunner instance under testing. */ + DuiAppletRunner *m_instance; + DuiAppletMetaData *meta; + +public: + static bool timerImmediateTimeout; + static bool quitCalled; + static QHash gConfKeyMap; + static bool processingInstanceSettingsFile; + static bool processingGlobalSettingsFile; + +private slots: + + void init(); + void cleanup(); + void initTestCase(); + void cleanupTestCase(); + + void testInitializationSuccess(); + void testInitializationFailInvalidAppletId(); + void testInitializationFailInvalidInstanceDataLocation(); + void testInitializationFailInvalidMetadata(); + void testInitializationFailCommunicationFails(); + void testInitializationFailConstructWidgetFails(); + void testInitializationFailSharedMemoryAttachFails(); + void testRelayingMouseEvents(); + void testAppletRunnerQuitsIfMessageReceivingTimeouts(); + void testMessageReceivedBeforeAppletInit(); + void testPaintingOnPixmap(); + void testSendUpdateGeometryMessage(); + void testSceneChanged(); + void testObjectMenuRequestMessage(); + void testObjectMenuRequestMessageGetsPropagated(); + +signals: + void sendMessage(const DuiAppletMessage &message); + void changeScene(const QList ®ion); +}; + +#endif //_UT_DUIAPPLETRUNNER_ diff --git a/tests/ut_duiappletrunner/ut_duiappletrunner.pro b/tests/ut_duiappletrunner/ut_duiappletrunner.pro new file mode 100644 index 000000000..2b99cfb4c --- /dev/null +++ b/tests/ut_duiappletrunner/ut_duiappletrunner.pro @@ -0,0 +1,20 @@ +include(../common_top.pri) + +TARGET = ut_duiappletrunner + +APPLETRUNNERDIR = ../../duiappletrunner +INCLUDEPATH += $$APPLETRUNNERDIR \ + $$DUISRCDIR/mashup/mashup \ + $$DUISRCDIR/mashup/appletinterface \ + $$DUISRCDIR/mashup/appletcommunication + +QT += network xml + +SOURCES += ut_duiappletrunner.cpp \ + $$APPLETRUNNERDIR/duiappletrunner.cpp \ + ../stubs/stubbase.cpp + +HEADERS += ut_duiappletrunner.h \ + $$APPLETRUNNERDIR/duiappletrunner.h + +include(../common_bot.pri) diff --git a/tests/ut_duiappletserver/.gitignore b/tests/ut_duiappletserver/.gitignore new file mode 100644 index 000000000..f07cee23d --- /dev/null +++ b/tests/ut_duiappletserver/.gitignore @@ -0,0 +1 @@ +ut_duiappletserver diff --git a/tests/ut_duiappletserver/ut_duiappletserver.cpp b/tests/ut_duiappletserver/ut_duiappletserver.cpp new file mode 100644 index 000000000..c2e156390 --- /dev/null +++ b/tests/ut_duiappletserver/ut_duiappletserver.cpp @@ -0,0 +1,98 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duiappletserver.h" +#include "duiappletserver.h" +#include "duiappletmessage.h" +#include "duiappletmessagefactory.h" + +#include +#include + +void Ut_DuiAppletServer::init() +{ + connected = false; + + m_subject = new DuiAppletServer; + connect(m_subject, SIGNAL(connectionEstablished()), this, SLOT(connectionEstablished())); +} + +void Ut_DuiAppletServer::cleanup() +{ + delete socket; + socket = NULL; + delete m_subject; + m_subject = NULL; +} + +void Ut_DuiAppletServer::setupServer() +{ + // Initiate connection to a process + QCOMPARE(m_subject->startServer("duioopwidget_1"), true); + + // Emulate being the process to connect to + socket = new QLocalSocket; + socket->connectToServer("duioopwidget_1"); + + // Process events max. 100 times to enable Qt signal handling + for (int retries = 0; retries < 100 && !connected; retries++) { + QCoreApplication::processEvents(QEventLoop::AllEvents, 1000000); + } +} + +void Ut_DuiAppletServer::testConnection() +{ + setupServer(); + + // Verify whether connection has been established or not + QCOMPARE(connected, true); +} + +void Ut_DuiAppletServer::testReconnect() +{ + setupServer(); + QCOMPARE(socket->state(), QLocalSocket::ConnectedState); + QCOMPARE(m_subject->isConnected(), true); + + m_subject->closeConnection(); + QCOMPARE(m_subject->isConnected(), false); + + // Test that new connections can't be made + delete socket; + socket = new QLocalSocket; + socket->connectToServer("duioopwidget_1"); + QCOMPARE(socket->waitForConnected(), false); + QCOMPARE(socket->error(), QLocalSocket::ServerNotFoundError); + QCOMPARE(m_subject->isConnected(), false); + + // Test that restarting the server works + delete socket; + connected = false; + setupServer(); + QCOMPARE(connected, true); + QCOMPARE(socket->state(), QLocalSocket::ConnectedState); + QCOMPARE(m_subject->isConnected(), true); +} + +void Ut_DuiAppletServer::connectionEstablished() +{ + connected = true; +} + +QTEST_MAIN(Ut_DuiAppletServer) diff --git a/tests/ut_duiappletserver/ut_duiappletserver.h b/tests/ut_duiappletserver/ut_duiappletserver.h new file mode 100644 index 000000000..4ade14591 --- /dev/null +++ b/tests/ut_duiappletserver/ut_duiappletserver.h @@ -0,0 +1,50 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIAPPLETSERVER_H +#define UT_DUIAPPLETSERVER_H + +#include + +class QLocalSocket; +class DuiAppletServer; + +class Ut_DuiAppletServer : public QObject +{ + Q_OBJECT + +private: + QLocalSocket *socket; + DuiAppletServer *m_subject; + bool connected; + + void setupServer(); + +private slots: + void init(); + void cleanup(); + + void testConnection(); + void testReconnect(); + +public slots: + void connectionEstablished(); +}; + +#endif // UT_DUIAPPLETSERVER_H diff --git a/tests/ut_duiappletserver/ut_duiappletserver.pro b/tests/ut_duiappletserver/ut_duiappletserver.pro new file mode 100644 index 000000000..6902e9947 --- /dev/null +++ b/tests/ut_duiappletserver/ut_duiappletserver.pro @@ -0,0 +1,17 @@ +include(../common_top.pri) +TARGET = ut_duiappletserver +INCLUDEPATH += $$DUISRCDIR/mashup/appletcommunication $$DUISRCDIR/mashup/appletinterface $$DUISRCDIR/mashup/mashup + +QT += core network gui svg dbus + +# unit test and unit classes +SOURCES += \ + ut_duiappletserver.cpp \ + +# unit test and unit classes +HEADERS += \ + ut_duiappletserver.h \ + +DEFINES += MY_APPLET_LIBS=\'$$quote(\"./\")\' + +include(../common_bot.pri) diff --git a/tests/ut_duiappletsetgeometrymessage/.gitignore b/tests/ut_duiappletsetgeometrymessage/.gitignore new file mode 100644 index 000000000..4da0d37d2 --- /dev/null +++ b/tests/ut_duiappletsetgeometrymessage/.gitignore @@ -0,0 +1,2 @@ +ut_duiappletsetgeometrymessage + diff --git a/tests/ut_duiappletsetgeometrymessage/ut_duiappletsetgeometrymessage.cpp b/tests/ut_duiappletsetgeometrymessage/ut_duiappletsetgeometrymessage.cpp new file mode 100644 index 000000000..53119c4ef --- /dev/null +++ b/tests/ut_duiappletsetgeometrymessage/ut_duiappletsetgeometrymessage.cpp @@ -0,0 +1,96 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duiappletsetgeometrymessage.h" + +#include +#include "duiappletsetgeometrymessage.h" + +void Ut_DuiAppletSetGeometryMessage::init() +{ + // Allocate a buffer and a stream for (un)serialization + buffer = new QBuffer; + buffer->open(QIODevice::ReadWrite); + stream = new QDataStream(buffer); + + message = new DuiAppletSetGeometryMessage(); +} + +void Ut_DuiAppletSetGeometryMessage::cleanup() +{ + delete message; + delete stream; + delete buffer; +} + +void Ut_DuiAppletSetGeometryMessage::testType() +{ + QCOMPARE(message->type(), DuiAppletMessage::SET_GEOMETRY_MESSAGE); +} + +void Ut_DuiAppletSetGeometryMessage::testGeometryProperty() +{ + QCOMPARE(message->geometry(), QRectF()); + QRectF tmp(1.0, 2.0, 3.0, 4.0); + message->setGeometry(tmp); + QCOMPARE(message->geometry(), tmp); +} + +void Ut_DuiAppletSetGeometryMessage::testHandleProperty() +{ +#ifdef Q_WS_X11 + QCOMPARE(message->handle(), (Qt::HANDLE)0); + Qt::HANDLE tmp = 52; + message->setHandle(tmp); + QCOMPARE(message->handle(), tmp); +#endif +} + +void Ut_DuiAppletSetGeometryMessage::testSerialization() +{ + message->serialize(*stream); + + // Seek to the beginning of the buffer + buffer->seek(0); + QRectF geometry(1.0, 2.0, 3.0, 4.0); + quint64 handle = 52; + *stream >> geometry; + *stream >> handle; + + QCOMPARE(geometry, QRectF()); + QCOMPARE(handle, (quint64)0); +} + +void Ut_DuiAppletSetGeometryMessage::testUnserialization() +{ +#ifdef Q_WS_X11 + QRectF geometry(1.0, 2.0, 3.0, 4.0); + Qt::HANDLE handle = 52; + *stream << geometry; + *stream << (quint64)handle; + + buffer->seek(0); + message->unserialize(*stream); + + QCOMPARE(message->geometry(), geometry); + QCOMPARE(message->handle(), handle); +#endif +} + +QTEST_APPLESS_MAIN(Ut_DuiAppletSetGeometryMessage) diff --git a/tests/ut_duiappletsetgeometrymessage/ut_duiappletsetgeometrymessage.h b/tests/ut_duiappletsetgeometrymessage/ut_duiappletsetgeometrymessage.h new file mode 100644 index 000000000..8995de996 --- /dev/null +++ b/tests/ut_duiappletsetgeometrymessage/ut_duiappletsetgeometrymessage.h @@ -0,0 +1,49 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIAPPLETSETGEOMETRYMESSAGE_H +#define UT_DUIAPPLETSETGEOMETRYMESSAGE_H + +#include + +class QBuffer; +class QDataStream; +class DuiAppletSetGeometryMessage; + +class Ut_DuiAppletSetGeometryMessage : public QObject +{ + Q_OBJECT + +private: + QBuffer *buffer; + QDataStream *stream; + DuiAppletSetGeometryMessage *message; + +private slots: + void init(); + void cleanup(); + + void testType(); + void testGeometryProperty(); + void testHandleProperty(); + void testSerialization(); + void testUnserialization(); +}; + +#endif // UT_DUIAPPLETSETGEOMETRYMESSAGE_H diff --git a/tests/ut_duiappletsetgeometrymessage/ut_duiappletsetgeometrymessage.pro b/tests/ut_duiappletsetgeometrymessage/ut_duiappletsetgeometrymessage.pro new file mode 100644 index 000000000..913784a24 --- /dev/null +++ b/tests/ut_duiappletsetgeometrymessage/ut_duiappletsetgeometrymessage.pro @@ -0,0 +1,13 @@ +include(../common_top.pri) +TARGET = ut_duiappletsetgeometrymessage +INCLUDEPATH += $$DUISRCDIR/mashup/appletcommunication $$DUISRCDIR/mashup/appletinterface $$DUISRCDIR/mashup/mashup + +# unit test and unit classes +SOURCES += \ + ut_duiappletsetgeometrymessage.cpp + +# unit test and unit classes +HEADERS += \ + ut_duiappletsetgeometrymessage.h + +include(../common_bot.pri) diff --git a/tests/ut_duiappletsettings/.gitignore b/tests/ut_duiappletsettings/.gitignore new file mode 100644 index 000000000..7b52b9689 --- /dev/null +++ b/tests/ut_duiappletsettings/.gitignore @@ -0,0 +1 @@ +ut_duiappletsettings diff --git a/tests/ut_duiappletsettings/ut_duiappletsettings.cpp b/tests/ut_duiappletsettings/ut_duiappletsettings.cpp new file mode 100644 index 000000000..2fb1a71b4 --- /dev/null +++ b/tests/ut_duiappletsettings/ut_duiappletsettings.cpp @@ -0,0 +1,236 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duiappletsettings.h" + +#include +#include +#include +#include +#include + +#include + +// Some constants for testing purposes +static const QString gAppletBaseName("appletmetadatafile"); +static const QString gMetaDataFile(gAppletBaseName + ".desktop"); +static const QString gInstanceSettingsFile(QString(APPLET_SETTINGS_DIR "/") + gAppletBaseName + "-instance.xml"); +static const QString gGlobalSettingsFile(QString(APPLET_SETTINGS_DIR "/") + gAppletBaseName + "-global.xml"); + +// Unit test class static variables +const DuiAppletId Ut_DuiAppletSettings::appletId("applicationName", "canvas", 0); +DuiSettingsLanguageBinary *Ut_DuiAppletSettings::instanceSettingsBinary = NULL; +DuiSettingsLanguageBinary *Ut_DuiAppletSettings::globalSettingsBinary = NULL; +bool Ut_DuiAppletSettings::instanceSettingsFileExists = false; +bool Ut_DuiAppletSettings::globalSettingsFileExists = false; +QList Ut_DuiAppletSettings::readXmlFiles; +QHash Ut_DuiAppletSettings::gconfKeys; +QList Ut_DuiAppletSettings::gUnsetGConfKeys; + +// DuiSettingsLanguageParser stubs +DuiSettingsLanguageParser::~DuiSettingsLanguageParser() +{ + // Needs to overwrite the destructor so it doesn't try to delete the document + // member which in this test is used for another purpose. +} + +QDomDocument *parserDocument = NULL; +bool DuiSettingsLanguageParser::readFrom(QIODevice &device) +{ + QFile *file = qobject_cast(&device); + if (file != NULL) { + Ut_DuiAppletSettings::readXmlFiles.append(file->fileName()); + if (file->fileName().contains("-instance.xml")) { + parserDocument = (QDomDocument *)Ut_DuiAppletSettings::instanceSettingsBinary; + return Ut_DuiAppletSettings::instanceSettingsFileExists; + } else if (file->fileName().contains("-global.xml")) { + parserDocument = (QDomDocument *)Ut_DuiAppletSettings::globalSettingsBinary; + return Ut_DuiAppletSettings::globalSettingsFileExists; + } + } + + return false; +} + +DuiSettingsLanguageBinary *DuiSettingsLanguageParser::createSettingsBinary() +{ + return (DuiSettingsLanguageBinary *)parserDocument; +} + +// DuiGConfDataStore stubs +QStringList DuiGConfDataStore::allKeys() const +{ + return Ut_DuiAppletSettings::gconfKeys.values(); +} + +DuiGConfDataStore *clearedDataStore; +void DuiGConfDataStore::clear() +{ + clearedDataStore = this; +} + +// The test class +void Ut_DuiAppletSettings::initializeInstanceSettings() +{ + instanceSettingsFileExists = true; + instanceSettingsBinary = new DuiSettingsLanguageBinary(); +} + +void Ut_DuiAppletSettings::initializeGlobalSettings() +{ + globalSettingsFileExists = true; + globalSettingsBinary = new DuiSettingsLanguageBinary(); +} + +QString Ut_DuiAppletSettings::instanceKey(const QString &key) +{ + return QString("/apps/") + appletId.toString() + QDir::separator() + key; +} + +QString Ut_DuiAppletSettings::globalKey(const QString &key) +{ + return QString("/apps/") + gAppletBaseName + QDir::separator() + key; +} + +void Ut_DuiAppletSettings::initTestCase() +{ +} + +void Ut_DuiAppletSettings::cleanupTestCase() +{ +} + +void Ut_DuiAppletSettings::init() +{ + parserDocument = NULL; + instanceSettingsBinary = NULL; + globalSettingsBinary = NULL; + instanceSettingsFileExists = false; + globalSettingsFileExists = false; + readXmlFiles.clear(); + gconfKeys.clear(); + gUnsetGConfKeys.clear(); + clearedDataStore = NULL; + m_subject = new DuiAppletSettings(gMetaDataFile, appletId); +} + +void Ut_DuiAppletSettings::cleanup() +{ + delete m_subject; + m_subject = NULL; +} + +void Ut_DuiAppletSettings::testGettingEmptyInstanceSettingsBinary() +{ + const DuiSettingsLanguageBinary *sb = m_subject->instanceSettingsBinary(); + QVERIFY(sb == NULL); +} + +void Ut_DuiAppletSettings::testGettingEmptyGlobalSettingsBinary() +{ + const DuiSettingsLanguageBinary *sb = m_subject->globalSettingsBinary(); + QVERIFY(sb == NULL); +} + +void Ut_DuiAppletSettings::testGettingInstanceSettingsBinary() +{ + initializeInstanceSettings(); + const DuiSettingsLanguageBinary *sb = m_subject->instanceSettingsBinary(); + QCOMPARE(sb, instanceSettingsBinary); + QCOMPARE(bool(readXmlFiles.contains(gInstanceSettingsFile)), true); +} + +void Ut_DuiAppletSettings::testGettingGlobalSettingsBinary() +{ + initializeGlobalSettings(); + const DuiSettingsLanguageBinary *sb = m_subject->globalSettingsBinary(); + QCOMPARE(sb, globalSettingsBinary); + QCOMPARE(bool(readXmlFiles.contains(gGlobalSettingsFile)), true); +} + +void Ut_DuiAppletSettings::testHasNoSettings() +{ + QCOMPARE(m_subject->hasSettings(), false); +} + +void Ut_DuiAppletSettings::testHasInstanceSettings() +{ + initializeInstanceSettings(); + QCOMPARE(m_subject->hasSettings(), true); +} + +void Ut_DuiAppletSettings::testHasGlobalSettings() +{ + initializeGlobalSettings(); + QCOMPARE(m_subject->hasSettings(), true); +} + +void Ut_DuiAppletSettings::testHasBothSettings() +{ + initializeInstanceSettings(); + initializeGlobalSettings(); + QCOMPARE(m_subject->hasSettings(), true); +} + +void Ut_DuiAppletSettings::testEmptyDataStore() +{ + QVERIFY(m_subject->instanceDataStore() != NULL); + QCOMPARE(m_subject->instanceDataStore()->allKeys().count(), 0); + QVERIFY(m_subject->globalDataStore() != NULL); + QCOMPARE(m_subject->globalDataStore()->allKeys().count(), 0); + QVERIFY(m_subject->dataAccess() != NULL); + QCOMPARE(m_subject->dataAccess()->allKeys().count(), 0); +} + +void Ut_DuiAppletSettings::testInstanceSettingsDataStore() +{ + initializeInstanceSettings(); + QVERIFY(m_subject->instanceDataStore() != NULL); + QVERIFY(m_subject->dataAccess() != NULL); +} + +void Ut_DuiAppletSettings::testGlobalSettingsDataStore() +{ + initializeGlobalSettings(); + QVERIFY(m_subject->globalDataStore() != NULL); + QVERIFY(m_subject->dataAccess() != NULL); +} + +void Ut_DuiAppletSettings::testBothSettingsDataStores() +{ + initializeInstanceSettings(); + initializeGlobalSettings(); + + QVERIFY(m_subject->instanceDataStore() != NULL); + QVERIFY(m_subject->globalDataStore() != NULL); + QVERIFY(m_subject->dataAccess() != NULL); +} + +void Ut_DuiAppletSettings::testRemoveInstanceSettingValues() +{ + // Add both instance and global settings + initializeInstanceSettings(); + initializeGlobalSettings(); + + m_subject->removeInstanceSettingValues(); + QCOMPARE(clearedDataStore, m_subject->instanceDataStore()); +} + + +QTEST_APPLESS_MAIN(Ut_DuiAppletSettings) diff --git a/tests/ut_duiappletsettings/ut_duiappletsettings.h b/tests/ut_duiappletsettings/ut_duiappletsettings.h new file mode 100644 index 000000000..cf3b0342b --- /dev/null +++ b/tests/ut_duiappletsettings/ut_duiappletsettings.h @@ -0,0 +1,91 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIAPPLETSETTINGS_H +#define UT_DUIAPPLETSETTINGS_H + +#include +#include +#include +#include + +class DuiAppletSettings; +class DuiSettingsLanguageBinary; + +class Ut_DuiAppletSettings : public QObject +{ + Q_OBJECT + +public: + //! An applet id for as a parameter for the test subject + static const DuiAppletId appletId; + //! A settings binary object for instance settings + static DuiSettingsLanguageBinary *instanceSettingsBinary; + //! A settings binary object for global settings + static DuiSettingsLanguageBinary *globalSettingsBinary; + //! Specify the existence of applet instance settings file + static bool instanceSettingsFileExists; + //! Specify the existence of applet global settings file + static bool globalSettingsFileExists; + static QList readXmlFiles; + //! The keys added to a DuiGConfDataStore object + static QHash gconfKeys; + //! A list of keys unset by a DuiGConfDataStore object + static QList gUnsetGConfKeys; + +private: + void initializeInstanceSettings(); + void initializeGlobalSettings(); + + QString instanceKey(const QString &key); + QString globalKey(const QString &key); + +private slots: + // Called before the first testfunction is executed + void initTestCase(); + // Called after the last testfunction was executed + void cleanupTestCase(); + // Called before each testfunction is executed + void init(); + // Called after every testfunction + void cleanup(); + + // Test cases + void testGettingEmptyInstanceSettingsBinary(); + void testGettingEmptyGlobalSettingsBinary(); + void testGettingInstanceSettingsBinary(); + void testGettingGlobalSettingsBinary(); + + void testHasNoSettings(); + void testHasInstanceSettings(); + void testHasGlobalSettings(); + void testHasBothSettings(); + + void testEmptyDataStore(); + void testInstanceSettingsDataStore(); + void testGlobalSettingsDataStore(); + void testBothSettingsDataStores(); + + void testRemoveInstanceSettingValues(); + +private: + DuiAppletSettings *m_subject; +}; + +#endif diff --git a/tests/ut_duiappletsettings/ut_duiappletsettings.pro b/tests/ut_duiappletsettings/ut_duiappletsettings.pro new file mode 100644 index 000000000..a664c0524 --- /dev/null +++ b/tests/ut_duiappletsettings/ut_duiappletsettings.pro @@ -0,0 +1,20 @@ +include(../common_top.pri) +TARGET = ut_duiappletsettings +INCLUDEPATH += $$DUISRCDIR/mashup/mashup + +QT += xml + +SOURCES += \ + ut_duiappletsettings.cpp \ + $$DUISRCDIR/mashup/mashup/duiappletsettings.cpp + +# service classes +SOURCES += \ + $$STUBSDIR/stubbase.cpp \ + +HEADERS += \ + ut_duiappletsettings.h \ + $$DUISRCDIR/mashup/mashup/duiappletsettings.h \ + $$DUISRCDIR/mashup/mashup/duiappletid.h + +include(../common_bot.pri) diff --git a/tests/ut_duiappletsettingsdialog/.gitignore b/tests/ut_duiappletsettingsdialog/.gitignore new file mode 100644 index 000000000..181540a01 --- /dev/null +++ b/tests/ut_duiappletsettingsdialog/.gitignore @@ -0,0 +1 @@ +ut_duiappletsettingsdialog diff --git a/tests/ut_duiappletsettingsdialog/ut_duiappletsettingsdialog.cpp b/tests/ut_duiappletsettingsdialog/ut_duiappletsettingsdialog.cpp new file mode 100644 index 000000000..dcc35abef --- /dev/null +++ b/tests/ut_duiappletsettingsdialog/ut_duiappletsettingsdialog.cpp @@ -0,0 +1,144 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include + +#include "ut_duiappletsettingsdialog.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DuiApplication *app; +const DuiSettingsLanguageBinary Ut_DuiAppletSettingsDialog::instanceSettingsBinary; +const DuiSettingsLanguageBinary Ut_DuiAppletSettingsDialog::globalSettingsBinary; +bool Ut_DuiAppletSettingsDialog::dialogCreated = false; +int Ut_DuiAppletSettingsDialog::instanceSettingsWidgetsCount = 0; +int Ut_DuiAppletSettingsDialog::globalSettingsWidgetsCount = 0; +QString Ut_DuiAppletSettingsDialog::containerTitle; + +// DuiSettingsLanguageWidgetFactory stubs +DuiSettingsLanguageWidget *DuiSettingsLanguageWidgetFactory::createWidget(const DuiSettingsLanguageBinary &binary, DuiDataStore *) +{ + if (&binary == &Ut_DuiAppletSettingsDialog::instanceSettingsBinary) { + ++Ut_DuiAppletSettingsDialog::instanceSettingsWidgetsCount; + } else if (&binary == &Ut_DuiAppletSettingsDialog::globalSettingsBinary) { + ++Ut_DuiAppletSettingsDialog::globalSettingsWidgetsCount; + } + + return NULL; +} + +// DuiDialog stubs +int DuiDialog::exec(DuiWindow *window) +{ + Q_UNUSED(window); + Ut_DuiAppletSettingsDialog::dialogCreated = true; + return 0; +} + +void DuiContainer::setTitle(const QString &title) +{ + Ut_DuiAppletSettingsDialog::containerTitle = title; +} + +void Ut_DuiAppletSettingsDialog::initTestCase() +{ + static int argc = 1; + static char *app_name[1] = { (char *) "./ut_duiappletsettingsdialog" }; + app = new DuiApplication(argc, app_name); + + appletSettings = new DuiAppletSettings("metadata.desktop", DuiAppletId()); +} + +void Ut_DuiAppletSettingsDialog::cleanupTestCase() +{ + delete appletSettings; + appletSettings = NULL; + + delete app; + app = NULL; +} + +void Ut_DuiAppletSettingsDialog::init() +{ + instanceSettingsWidgetsCount = 0; + globalSettingsWidgetsCount = 0; + dialogCreated = false; + containerTitle.clear(); + gDuiAppletSettingsStub->stubReset(); + + m_subject = new DuiAppletSettingsDialog(*appletSettings); +} + +void Ut_DuiAppletSettingsDialog::cleanup() +{ + delete m_subject; + m_subject = NULL; +} + +void Ut_DuiAppletSettingsDialog::testSettingsDialogCreation() +{ + // Check that dialog is not created when there are no applet settings present + gDuiAppletSettingsStub->stubSetReturnValue("hasSettings", false); + m_subject->exec(); + QCOMPARE(dialogCreated, false); + + // Check that dialog is created when there are instance applet settings present + gDuiAppletSettingsStub->stubSetReturnValue("hasSettings", true); + m_subject->exec(); + QCOMPARE(dialogCreated, true); +} + +void Ut_DuiAppletSettingsDialog::testSettingsContainerCreation() +{ + // Check that when instance binaries are present, widgets are created in a container + gDuiAppletSettingsStub->stubSetReturnValue("hasSettings", true); + gDuiAppletSettingsStub->stubSetReturnValue("instanceSettingsBinary", &instanceSettingsBinary); + m_subject->exec(); + QCOMPARE(instanceSettingsWidgetsCount, 1); + QCOMPARE(globalSettingsWidgetsCount, 0); + // the message id used here comes from + // src/mashup/mashup/duiappletsettingsdialog.cpp + // it must be the same as the message id used there. + //% "Applet Instance Settings" + QCOMPARE(containerTitle, qtTrId("duiappletsettingsdialog_applet_instance_settings_title")); + + // Check that when global binaries are present, widgets are created in a container + instanceSettingsWidgetsCount = 0; + gDuiAppletSettingsStub->stubReset(); + gDuiAppletSettingsStub->stubSetReturnValue("hasSettings", true); + gDuiAppletSettingsStub->stubSetReturnValue("globalSettingsBinary", &globalSettingsBinary); + m_subject->exec(); + QCOMPARE(instanceSettingsWidgetsCount, 0); + QCOMPARE(globalSettingsWidgetsCount, 1); + // the message id used here comes from + // src/mashup/mashup/duiappletsettingsdialog.cpp + // it must be the same as the message id used there. + //% "Applet Global Settings" + QCOMPARE(containerTitle, qtTrId("duiappletsettingsdialog_applet_global_settings_title")); +} + +QTEST_APPLESS_MAIN(Ut_DuiAppletSettingsDialog) diff --git a/tests/ut_duiappletsettingsdialog/ut_duiappletsettingsdialog.h b/tests/ut_duiappletsettingsdialog/ut_duiappletsettingsdialog.h new file mode 100644 index 000000000..72a0c78ae --- /dev/null +++ b/tests/ut_duiappletsettingsdialog/ut_duiappletsettingsdialog.h @@ -0,0 +1,62 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIAPPLETSETTINGSDIALOG_H +#define UT_DUIAPPLETSETTINGSDIALOG_H + +#include +#include + +class DuiAppletSettingsDialog; +class DuiAppletSettings; + +class Ut_DuiAppletSettingsDialog : public QObject +{ + Q_OBJECT + +public: + //! Settings language binary representing the instance settings + static const DuiSettingsLanguageBinary instanceSettingsBinary; + //! Settings language binary representing the global settings + static const DuiSettingsLanguageBinary globalSettingsBinary; + //! Specifies if the applet settings dialog is created + static bool dialogCreated; + //! A counter for how many instance settings widgets get created + static int instanceSettingsWidgetsCount; + //! A counter for how many global settings widgets get created + static int globalSettingsWidgetsCount; + //! Title of the container + static QString containerTitle; + + +private slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + + void testSettingsDialogCreation(); + void testSettingsContainerCreation(); + +private: + DuiAppletSettings *appletSettings; + DuiAppletSettingsDialog *m_subject; +}; + +#endif diff --git a/tests/ut_duiappletsettingsdialog/ut_duiappletsettingsdialog.pro b/tests/ut_duiappletsettingsdialog/ut_duiappletsettingsdialog.pro new file mode 100644 index 000000000..34e980a09 --- /dev/null +++ b/tests/ut_duiappletsettingsdialog/ut_duiappletsettingsdialog.pro @@ -0,0 +1,19 @@ +include(../common_top.pri) +include(../../mkspecs/common.pri) + +TARGET = ut_duiappletsettingsdialog +INCLUDEPATH += $$DUISRCDIR/mashup/mashup \ + $$DUISRCDIR/mashup/appletcommunication \ + $$DUISRCDIR/widgets + +QT += xml + +SOURCES += ut_duiappletsettingsdialog.cpp \ + $$DUISRCDIR/mashup/mashup/duiappletsettingsdialog.cpp \ + ../stubs/stubbase.cpp + +HEADERS += ut_duiappletsettingsdialog.h \ + $$DUISRCDIR/mashup/mashup/duiappletsettingsdialog.h \ + $$DUISRCDIR/mashup/mashup/duiappletid.h + +include(../common_bot.pri) diff --git a/tests/ut_duiappletsharedmutex/.gitignore b/tests/ut_duiappletsharedmutex/.gitignore new file mode 100644 index 000000000..88c9800cd --- /dev/null +++ b/tests/ut_duiappletsharedmutex/.gitignore @@ -0,0 +1 @@ +ut_duiappletsharedmutex diff --git a/tests/ut_duiappletsharedmutex/ut_duiappletsharedmutex.cpp b/tests/ut_duiappletsharedmutex/ut_duiappletsharedmutex.cpp new file mode 100644 index 000000000..e1793135b --- /dev/null +++ b/tests/ut_duiappletsharedmutex/ut_duiappletsharedmutex.cpp @@ -0,0 +1,121 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include "ut_duiappletsharedmutex.h" + +void Ut_DuiAppletSharedMutex::init() +{ + mutex1 = new DuiAppletSharedMutex(); + mutex2 = NULL; + mutex3 = NULL; +} + +void Ut_DuiAppletSharedMutex::cleanup() +{ + delete mutex1; + delete mutex2; + delete mutex3; +} + +void Ut_DuiAppletSharedMutex::initTestCase() +{ +} + +void Ut_DuiAppletSharedMutex::cleanupTestCase() +{ +} + +void Ut_DuiAppletSharedMutex::testInitSuccess() +{ + // Initialize the mutex + QVERIFY(mutex1->init("mutex")); + + // Attach to the same mutex + mutex2 = new DuiAppletSharedMutex; + QVERIFY(mutex2->init("mutex")); + delete mutex2; + mutex2 = NULL; + + // Create a new mutex (the first one should still exist) + mutex3 = new DuiAppletSharedMutex; + QVERIFY(mutex3->init("mutex3")); + delete mutex3; + mutex3 = NULL; +} + +void Ut_DuiAppletSharedMutex::testInitFailureEmptyKey() +{ + // Initializing with an empty key should fail + QVERIFY(!mutex1->init("")); +} + +void Ut_DuiAppletSharedMutex::testLockInitialized() +{ + // Locking an initialized mutex should succeed + QVERIFY(mutex1->init("mutex")); + QVERIFY(mutex1->lock()); +} + +void Ut_DuiAppletSharedMutex::testLockNotInitialized() +{ + // Locking an uninitialized mutex should not succeed + QVERIFY(!mutex1->lock()); +} + +void Ut_DuiAppletSharedMutex::testUnlockInitialized() +{ + // Unlocking an initialized mutex should succeed + QVERIFY(mutex1->init("mutex")); + QVERIFY(mutex1->unlock()); +} + +void Ut_DuiAppletSharedMutex::testUnlockNotInitialized() +{ + // Unlocking an uninitialized mutex should not succeed + QVERIFY(!mutex1->unlock()); +} + +void Ut_DuiAppletSharedMutex::testTryLockInitialized() +{ + // Locking an initialized mutex should succeed + QVERIFY(mutex1->init("mutex")); + QVERIFY(mutex1->tryLock()); + + // Trying to lock the mutex again should not succeed + QVERIFY(!mutex1->tryLock()); + + // Attach to the same mutex + mutex2 = new DuiAppletSharedMutex; + QVERIFY(mutex2->init("mutex")); + + // Locking the same mutex should not succeed + QVERIFY(!mutex2->tryLock()); + delete mutex2; + mutex2 = NULL; +} + +void Ut_DuiAppletSharedMutex::testTryLockNotInitialized() +{ + // Locking an uninitialized mutex should not succeed + QVERIFY(!mutex1->tryLock()); +} + +QTEST_MAIN(Ut_DuiAppletSharedMutex) diff --git a/tests/ut_duiappletsharedmutex/ut_duiappletsharedmutex.h b/tests/ut_duiappletsharedmutex/ut_duiappletsharedmutex.h new file mode 100644 index 000000000..bf3acd945 --- /dev/null +++ b/tests/ut_duiappletsharedmutex/ut_duiappletsharedmutex.h @@ -0,0 +1,52 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIAPPLETSHAREDMUTEX_H +#define UT_DUIAPPLETSHAREDMUTEX_H + +#include + +class DuiAppletSharedMutex; + +class Ut_DuiAppletSharedMutex : public QObject +{ + Q_OBJECT + +private slots: + void init(); + void cleanup(); + void initTestCase(); + void cleanupTestCase(); + + void testInitSuccess(); + void testInitFailureEmptyKey(); + void testLockInitialized(); + void testLockNotInitialized(); + void testUnlockInitialized(); + void testUnlockNotInitialized(); + void testTryLockInitialized(); + void testTryLockNotInitialized(); + +private: + DuiAppletSharedMutex *mutex1; + DuiAppletSharedMutex *mutex2; + DuiAppletSharedMutex *mutex3; +}; + +#endif diff --git a/tests/ut_duiappletsharedmutex/ut_duiappletsharedmutex.pro b/tests/ut_duiappletsharedmutex/ut_duiappletsharedmutex.pro new file mode 100644 index 000000000..bcca1cbb4 --- /dev/null +++ b/tests/ut_duiappletsharedmutex/ut_duiappletsharedmutex.pro @@ -0,0 +1,22 @@ +include(../common_top.pri) +TARGET = ut_duiappletsharedmutex +INCLUDEPATH += $$DUISRCDIR/mashup/mashup + +TEST_SOURCES = \ + $$DUISRCDIR/mashup/mashup/duiappletsharedmutex.cpp \ + +# unit test and unit +SOURCES += \ + ut_duiappletsharedmutex.cpp \ + $$TEST_SOURCES \ + +# service classes +SOURCES += \ + $$STUBSDIR/stubbase.cpp \ + +# unit test and unit +HEADERS += \ + ut_duiappletsharedmutex.h \ + $$DUISRCDIR/mashup/mashup/duiappletsharedmutex.h \ + +include(../common_bot.pri) diff --git a/tests/ut_duiappletupdategeometrymessage/.gitignore b/tests/ut_duiappletupdategeometrymessage/.gitignore new file mode 100644 index 000000000..6c4fb9e2c --- /dev/null +++ b/tests/ut_duiappletupdategeometrymessage/.gitignore @@ -0,0 +1 @@ +ut_duiappletupdategeometrymessage diff --git a/tests/ut_duiappletupdategeometrymessage/ut_duiappletupdategeometrymessage.cpp b/tests/ut_duiappletupdategeometrymessage/ut_duiappletupdategeometrymessage.cpp new file mode 100644 index 000000000..23ea48c68 --- /dev/null +++ b/tests/ut_duiappletupdategeometrymessage/ut_duiappletupdategeometrymessage.cpp @@ -0,0 +1,86 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duiappletupdategeometrymessage.h" +#include "duiappletupdategeometrymessage.h" + +#include + +void Ut_DuiAppletUpdateGeometryMessage::init() +{ + // Allocate a buffer and a stream for (un)serialization + buffer = new QBuffer; + buffer->open(QIODevice::ReadWrite); + stream = new QDataStream(buffer); + + message = new DuiAppletUpdateGeometryMessage(); +} + +void Ut_DuiAppletUpdateGeometryMessage::cleanup() +{ + delete message; + delete stream; + delete buffer; +} + +void Ut_DuiAppletUpdateGeometryMessage::testType() +{ + QCOMPARE(message->type(), DuiAppletMessage::UPDATE_GEOMETRY_MESSAGE); +} + +void Ut_DuiAppletUpdateGeometryMessage::testSizeHintsProperty() +{ + QCOMPARE(message->sizeHints(), QVector(Qt::NSizeHints)); + QVector sizeHints; + sizeHints.append(QSizeF(1, 2)); + sizeHints.append(QSizeF(3, 4)); + sizeHints.append(QSizeF(5, 6)); + sizeHints.append(QSizeF(7, 8)); + message->setSizeHints(sizeHints); + QCOMPARE(message->sizeHints(), sizeHints); +} + +void Ut_DuiAppletUpdateGeometryMessage::testSerialization() +{ + message->serialize(*stream); + + // Seek to the beginning of the buffer + buffer->seek(0); + QVector sizeHints; + *stream >> sizeHints; + + QCOMPARE(sizeHints, QVector(Qt::NSizeHints)); +} + +void Ut_DuiAppletUpdateGeometryMessage::testUnserialization() +{ + QVector sizeHints; + sizeHints.append(QSizeF(1, 2)); + sizeHints.append(QSizeF(3, 4)); + sizeHints.append(QSizeF(5, 6)); + sizeHints.append(QSizeF(7, 8)); + *stream << sizeHints; + + buffer->seek(0); + message->unserialize(*stream); + + QCOMPARE(message->sizeHints(), sizeHints); +} + +QTEST_APPLESS_MAIN(Ut_DuiAppletUpdateGeometryMessage) diff --git a/tests/ut_duiappletupdategeometrymessage/ut_duiappletupdategeometrymessage.h b/tests/ut_duiappletupdategeometrymessage/ut_duiappletupdategeometrymessage.h new file mode 100644 index 000000000..3f15a5de4 --- /dev/null +++ b/tests/ut_duiappletupdategeometrymessage/ut_duiappletupdategeometrymessage.h @@ -0,0 +1,48 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIAPPLETUPDATEGEOMETRYMESSAGE_H +#define UT_DUIAPPLETUPDATEGEOMETRYMESSAGE_H + +#include + +class QBuffer; +class QDataStream; +class DuiAppletUpdateGeometryMessage; + +class Ut_DuiAppletUpdateGeometryMessage : public QObject +{ + Q_OBJECT + +private: + QBuffer *buffer; + QDataStream *stream; + DuiAppletUpdateGeometryMessage *message; + +private slots: + void init(); + void cleanup(); + + void testType(); + void testSizeHintsProperty(); + void testSerialization(); + void testUnserialization(); +}; + +#endif // UT_DUIAPPLETUPDATEGEOMETRYMESSAGE_H diff --git a/tests/ut_duiappletupdategeometrymessage/ut_duiappletupdategeometrymessage.pro b/tests/ut_duiappletupdategeometrymessage/ut_duiappletupdategeometrymessage.pro new file mode 100644 index 000000000..24cd8ceb3 --- /dev/null +++ b/tests/ut_duiappletupdategeometrymessage/ut_duiappletupdategeometrymessage.pro @@ -0,0 +1,13 @@ +include(../common_top.pri) +TARGET = ut_duiappletupdategeometrymessage +INCLUDEPATH += $$DUISRCDIR/mashup/appletcommunication $$DUISRCDIR/mashup/appletinterface $$DUISRCDIR/mashup/mashup + +# unit test and unit classes +SOURCES += \ + ut_duiappletupdategeometrymessage.cpp \ + +# unit test and unit classes +HEADERS += \ + ut_duiappletupdategeometrymessage.h \ + +include(../common_bot.pri) diff --git a/tests/ut_duiappletvisibilitymessage/.gitignore b/tests/ut_duiappletvisibilitymessage/.gitignore new file mode 100644 index 000000000..b7753fae4 --- /dev/null +++ b/tests/ut_duiappletvisibilitymessage/.gitignore @@ -0,0 +1,2 @@ +ut_duiappletvisibilitymessage + diff --git a/tests/ut_duiappletvisibilitymessage/ut_duiappletvisibilitymessage.cpp b/tests/ut_duiappletvisibilitymessage/ut_duiappletvisibilitymessage.cpp new file mode 100644 index 000000000..46ba01f61 --- /dev/null +++ b/tests/ut_duiappletvisibilitymessage/ut_duiappletvisibilitymessage.cpp @@ -0,0 +1,76 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duiappletvisibilitymessage.h" + +#include +#include "duiappletvisibilitymessage.h" + +void Ut_DuiAppletVisibilityMessage::init() +{ + // Allocate a buffer and a stream for (un)serialization + buffer = new QBuffer; + buffer->open(QIODevice::ReadWrite); + stream = new QDataStream(buffer); + + message = new DuiAppletVisibilityMessage(); +} + +void Ut_DuiAppletVisibilityMessage::cleanup() +{ + delete message; + delete stream; + delete buffer; +} + +void Ut_DuiAppletVisibilityMessage::testType() +{ + QCOMPARE(message->type(), DuiAppletMessage::VISIBILITY_MESSAGE); +} + +void Ut_DuiAppletVisibilityMessage::testVisibilityProperty() +{ + QVERIFY(message->visible()); + message->setVisible(false); + QVERIFY(!message->visible()); +} + +void Ut_DuiAppletVisibilityMessage::testSerialization() +{ + message->serialize(*stream); + + // Seek to the beginning of the buffer + buffer->seek(0); + bool result = false; + *stream >> result; + + QVERIFY(result); +} + +void Ut_DuiAppletVisibilityMessage::testUnserialization() +{ + *stream << false; + + buffer->seek(0); + message->unserialize(*stream); + + QVERIFY(!message->visible()); +} + +QTEST_APPLESS_MAIN(Ut_DuiAppletVisibilityMessage) diff --git a/tests/ut_duiappletvisibilitymessage/ut_duiappletvisibilitymessage.h b/tests/ut_duiappletvisibilitymessage/ut_duiappletvisibilitymessage.h new file mode 100644 index 000000000..40008356c --- /dev/null +++ b/tests/ut_duiappletvisibilitymessage/ut_duiappletvisibilitymessage.h @@ -0,0 +1,48 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIAPPLETVISIBILITYMESSAGE_H +#define UT_DUIAPPLETVISIBILITYMESSAGE_H + +#include + +class QBuffer; +class QDataStream; +class DuiAppletVisibilityMessage; + +class Ut_DuiAppletVisibilityMessage : public QObject +{ + Q_OBJECT + +private: + QBuffer *buffer; + QDataStream *stream; + DuiAppletVisibilityMessage *message; + +private slots: + void init(); + void cleanup(); + + void testType(); + void testVisibilityProperty(); + void testSerialization(); + void testUnserialization(); +}; + +#endif // UT_DUIAPPLETVISIBILITYMESSAGE_H diff --git a/tests/ut_duiappletvisibilitymessage/ut_duiappletvisibilitymessage.pro b/tests/ut_duiappletvisibilitymessage/ut_duiappletvisibilitymessage.pro new file mode 100644 index 000000000..fe22119dd --- /dev/null +++ b/tests/ut_duiappletvisibilitymessage/ut_duiappletvisibilitymessage.pro @@ -0,0 +1,13 @@ +include(../common_top.pri) +TARGET = ut_duiappletvisibilitymessage +INCLUDEPATH += $$DUISRCDIR/mashup/appletcommunication $$DUISRCDIR/mashup/appletinterface $$DUISRCDIR/mashup/mashup + +# unit test and unit classes +SOURCES += \ + ut_duiappletvisibilitymessage.cpp + +# unit test and unit classes +HEADERS += \ + ut_duiappletvisibilitymessage.h + +include(../common_bot.pri) diff --git a/tests/ut_duiapplication/.gitignore b/tests/ut_duiapplication/.gitignore new file mode 100644 index 000000000..fdb993a07 --- /dev/null +++ b/tests/ut_duiapplication/.gitignore @@ -0,0 +1 @@ +ut_duiapplication diff --git a/tests/ut_duiapplication/ut_duiapplication.cpp b/tests/ut_duiapplication/ut_duiapplication.cpp new file mode 100644 index 000000000..b63f0e616 --- /dev/null +++ b/tests/ut_duiapplication/ut_duiapplication.cpp @@ -0,0 +1,525 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include "ut_duiapplication.h" + +#include +#include +#include + +#include +#include +#include +#include + +class MyApplication: public DuiApplication +{ +public: + MyApplication(int &argc, char **argv); + MyApplication(int &argc, char **argv, DuiApplicationService *service); + virtual void releasePrestart(); + virtual void restorePrestart(); +}; + + +MyApplication::MyApplication(int &argc, char **argv) + : DuiApplication(argc, argv) +{ +} + +MyApplication::MyApplication(int &argc, char **argv, DuiApplicationService *service) + : DuiApplication(argc, argv, service) +{ +} + +bool Ut_DuiApplication::m_releasePrestart = false; +void MyApplication::releasePrestart() +{ + Ut_DuiApplication::m_releasePrestart = true; +} + +bool Ut_DuiApplication::m_restorePrestart = false; +void MyApplication::restorePrestart() +{ + Ut_DuiApplication::m_restorePrestart = true; +} + +void Ut_DuiApplication::init() +{ + m_prestartReleased = false; + m_prestartRestored = false; + m_releasePrestart = false; + m_restorePrestart = false; + + registeredService.clear(); +} + +void Ut_DuiApplication::cleanup() +{ +} + +void Ut_DuiApplication::duiApplicationConstructor_data() +{ + QTest::addColumn("count"); + QTest::addColumn("params"); + QTest::newRow("hw") << 2 << QString("-show-br -show-fps"); + QTest::newRow("hw-fullscreen") << 3 << QString("-show-br -show-fps -fullscreen"); + QTest::newRow("sw") << 2 << QString("-software -show-br"); + QTest::newRow("sw-fullscreen") << 3 << QString("-software -show-br -fullscreen"); +} + +DuiApplication *Ut_DuiApplication::buildApp(int count, const QString ¶ms, DuiApplicationService *service) +{ + return buildApp(count, params, QString(), service); +} + +DuiApplication *Ut_DuiApplication::buildApp(int count, const QString ¶ms, const QString &appId, DuiApplicationService *service) +{ + DuiApplication *retVal = 0; + + QChar sep(' '); + char *argv[MAX_PARAMS]; + int x = 0; + + QStringList list = params.split(sep); + QStringListIterator it(list); + while (it.hasNext() && x < MAX_PARAMS) { + argv[x++] = strdup(it.next().toLocal8Bit().constData()); + } + + // try to call the constructor with the correct signature + if (service) { + if (appId.isEmpty()) { + retVal = new DuiApplication(count, argv, service); + } else { + retVal = new DuiApplication(count, argv, appId, service); + } + } else { + if (appId.isEmpty()) { + retVal = new DuiApplication(count, argv); + } else { + retVal = new DuiApplication(count, argv, appId); + } + } + + return retVal; +} + +DuiApplication *Ut_DuiApplication::buildPrestartApp(int count, const QString ¶ms, DuiApplicationService *service) +{ + DuiApplication *retVal = 0; + + QChar sep(' '); + char *argv[MAX_PARAMS]; + int x = 0; + + QStringList list = params.split(sep); + QStringListIterator it(list); + while (it.hasNext() && x < MAX_PARAMS) { + argv[x++] = strdup(it.next().toLocal8Bit().constData()); + } + + // try to call the constructor with the correct signature + if (service) { + retVal = new MyApplication(count, argv, service); + } else { + retVal = new MyApplication(count, argv); + } + + return retVal; +} + +QDir Ut_DuiApplication::generateThemeDirectory() +{ + QDir themeDir(THEMEDIR); + return themeDir; +} + +QDir Ut_DuiApplication::generateApplicationThemeDirectory(const QString &applicationName) +{ + QDir themeDir = generateThemeDirectory(); + themeDir.setPath(themeDir.absolutePath() + QDir::separator() + applicationName); + return themeDir; +} + +void Ut_DuiApplication::duiApplicationConstructor() +{ + QFETCH(int, count); + QFETCH(QString, params); + + DuiApplication *app = NULL; + + app = buildApp(count, params); + QVERIFY(app != NULL); + QVERIFY(!registeredService.isEmpty()); + delete app; +} + +QString Ut_DuiApplication::registeredService = QString(); + +bool DuiApplicationService::registerService() +{ + Ut_DuiApplication::registeredService = registeredName(); + + return true; +} + +void Ut_DuiApplication::duiApplicationConstructorWithAppId() +{ + QString serviceBasename = "com.nokia."; + QString appName; + QString argv0; + + argv0 = "appName"; + DuiApplication *app = buildApp(1, argv0); + delete app; + QCOMPARE(registeredService, serviceBasename + argv0); + + appName = "xY0_-"; + argv0 = "appName"; + app = buildApp(1, argv0, appName); + delete app; + QCOMPARE(registeredService, serviceBasename + appName); + + // A whitespace as app identifier is invalid and not used + appName = ' '; + argv0 = "appName"; + app = buildApp(1, argv0, appName); + delete app; + QCOMPARE(registeredService, serviceBasename + argv0); +} + +class MyApplicationService : public DuiApplicationService +{ +public: + MyApplicationService(const QString &newServiceName); + virtual ~MyApplicationService(); +}; + +MyApplicationService::MyApplicationService(const QString &newServiceName) : + DuiApplicationService(newServiceName) +{ +} + +MyApplicationService::~MyApplicationService() +{ +} + +void Ut_DuiApplication::duiApplicationConstructorWithService() +{ + MyApplicationService *myService = new MyApplicationService("com.nokia.Ut_DuiApplicationService"); + DuiApplication *app = buildApp(1, "appName", myService); + QString thisRegisteredName = myService->registeredName(); + delete app; + QCOMPARE(thisRegisteredName, QString("com.nokia.Ut_DuiApplicationService")); +} + +#if 0 +void Ut_DuiApplication::duiApplicationName() +{ + DuiApplication *app = buildApp(1, "appName -foobar"); + QCOMPARE(app->applicationName(), QString("appName")); + delete app; + + app = buildApp(1, "./appName -foobar"); + QCOMPARE(app->applicationName(), QString("appName")); + delete app; + + app = buildApp(1, "/foo/bar/appName -foobar"); + QCOMPARE(app->applicationName(), QString("appName")); + delete app; +} + +void Ut_DuiApplication::themeFileLoadingFromCurrentPath() +{ + // Setup the testing environment + // Both svg and css files are found from current directory. + gFileSystemVerifier.addValidFile("dui.css"); + gFileSystemVerifier.addValidFile("dui.svg"); + // Create application + DuiApplication *app = buildApp(1, "appName -foobar"); + QCOMPARE(app->applicationName(), QString("appName")); + delete app; + + // Verify that correct svg and css files were loaded + MyDuiThemeStub *themeStub = dynamic_cast(gDuiThemeStub); + Q_ASSERT(themeStub); + QCOMPARE(themeStub->loadedSVG, QString("dui.svg")); + QCOMPARE(themeStub->loadedCSS, QString("dui.css")); +} + +void Ut_DuiApplication::themeFileLoadingFromApplicationThemePath() +{ + // Setup the testing environment + gFileSystemVerifier.addValidPath(generateThemeDirectory().path()); + gFileSystemVerifier.addValidPath(generateApplicationThemeDirectory("appName").path()); + // Create application + DuiApplication *app = buildApp(1, "appName -foobar"); + QCOMPARE(app->applicationName(), QString("appName")); + delete app; + + // Verify that correct svg file was loaded + MyDuiThemeStub *themeStub = dynamic_cast(gDuiThemeStub); + Q_ASSERT(themeStub); + QFileInfo loadedSVG(generateApplicationThemeDirectory(QString("appName")), "dui.svg"); + QCOMPARE(themeStub->loadedSVG, loadedSVG.absoluteFilePath()); + QFileInfo loadedCSS(generateApplicationThemeDirectory(QString("appName")), "dui.css"); + QCOMPARE(themeStub->loadedCSS, loadedCSS.absoluteFilePath()); +} + +void Ut_DuiApplication::themeFileLoadingFromGlobalThemePath() +{ + // Setup the testing environment + gFileSystemVerifier.addValidPath(generateThemeDirectory().path()); + // Create application + DuiApplication *app = buildApp(1, "appName -foobar"); + QCOMPARE(app->applicationName(), QString("appName")); + delete app; + + // Verify that correct svg file was loaded + MyDuiThemeStub *themeStub = dynamic_cast(gDuiThemeStub); + Q_ASSERT(themeStub); + QFileInfo loadedSVG(generateThemeDirectory(), "dui.svg"); + QCOMPARE(themeStub->loadedSVG, loadedSVG.absoluteFilePath()); + QFileInfo loadedCSS(generateThemeDirectory(), "dui.css"); + QCOMPARE(themeStub->loadedCSS, loadedCSS.absoluteFilePath()); +} +#endif + +void Ut_DuiApplication::duiApplicationTranslationPath() +{ + DuiApplication *app = buildApp(1, "appName"); + DuiLocale l; + + QStringList list = l.translationPaths(); + + QVERIFY(list.size() == 1); + if (list.size() == 1) { + QVERIFY(list.at(0) == TRANSLATION_DIR); + } + + delete app; +} + +void Ut_DuiApplication::duiApplicationNoFeedback() +{ + gDuiFeedbackPlayerPrivateStub->stubSetReturnValue("init", false); + DuiApplication *app = buildApp(1, "appName"); + QVERIFY(app->feedbackPlayer() == 0); + delete app; + + gDuiFeedbackPlayerPrivateStub->stubSetReturnValue("init", true); + app = buildApp(1, "appName"); + QVERIFY(app->feedbackPlayer() != 0); + delete app; +} + +/* +void Ut_DuiApplication::testActiveApplicationWindow() +{ + app = buildApp( 2, "appName -software" ); + QVERIFY( app->activeApplicationWindow() == 0 ); + + DuiApplicationWindow *appWin = new DuiApplicationWindow; + QVERIFY( app->activeApplicationWindow() == appWin ); + + delete appWin; + QVERIFY( app->activeApplicationWindow() == 0 ); + + delete app; +} + +void Ut_DuiApplication::testApplicationWindows() +{ + app = buildApp( 2, "appName -software" ); + DuiApplicationWindow *appWin1 = new DuiApplicationWindow; + Q_UNUSED(appWin1); + DuiApplicationWindow *appWin2 = new DuiApplicationWindow; + DuiApplicationWindow *appWin3 = new DuiApplicationWindow; + + DuiApplicationWindow *appWin4 = new DuiApplicationWindow; + delete appWin4; + + QVERIFY( app->windows().size() == 3 ); + QVERIFY( app->windows().contains( appWin1 ) ); + QVERIFY( app->windows().contains( appWin2 ) ); + QVERIFY( app->windows().contains( appWin3 ) ); + + QVERIFY( !app->windows().contains( appWin4 ) ); + + delete appWin3; + QVERIFY( !app->windows().contains( appWin3 ) ); + + delete appWin2; + delete appWin1; + delete app; +} +*/ + +void Ut_DuiApplication::testPrestartMode() +{ + // Test that mode is set when started with -prestart + app = buildApp(2, "appName -prestart"); + app->setPrestartMode(Dui::TerminateOnClose); + QCOMPARE(app->prestartMode(), Dui::TerminateOnClose); + app->setPrestartMode(Dui::LazyShutdown); + QCOMPARE(app->prestartMode(), Dui::LazyShutdown); + delete app; + + // Test that mode is not set when not started with -prestart + app = buildApp(1, "appName"); + app->setPrestartMode(Dui::TerminateOnClose); + QCOMPARE(app->prestartMode(), Dui::NoPrestart); + delete app; +} + +void Ut_DuiApplication::testReleasePrestartModeTerminateOnClose() +{ + // Test that app releases correctly from prestart + DuiApplicationService *service = new DuiApplicationService("com.nokia.appName"); + app = buildPrestartApp(2, "appName -prestart", service); + app->connect(app, SIGNAL(prestartReleased()), this, SLOT(prestartReleased())); + app->setPrestartMode(Dui::TerminateOnClose); + service->launch(); + // Test that we have the correct mode set + QCOMPARE(app->isPrestarted(), false); + // Test that the signal was sent + QCOMPARE(m_prestartReleased, true); + // Test that the handler is called + QCOMPARE(m_releasePrestart, true); + delete app; +} + +void Ut_DuiApplication::testReleasePrestartModeLazyShutdown() +{ + // Test that app releases correctly from prestart + DuiApplicationService *service = new DuiApplicationService("com.nokia.appName"); + app = buildPrestartApp(2, "appName -prestart", service); + app->connect(app, SIGNAL(prestartReleased()), this, SLOT(prestartReleased())); + app->setPrestartMode(Dui::LazyShutdown); + service->launch(); + // Test that we have the correct mode set + QCOMPARE(app->isPrestarted(), false); + // Test that the signal was sent + QCOMPARE(m_prestartReleased, true); + // Test that the handler is called + QCOMPARE(m_releasePrestart, true); + delete app; +} + +void Ut_DuiApplication::testRestorePrestartModeLazyShutdown() +{ + // Test that app restores correctly to prestart + // if in LazyShutdown mode + DuiApplicationService *service = new DuiApplicationService("com.nokia.appName"); + app = buildPrestartApp(2, "appName -prestart", service); + app->connect(app, SIGNAL(prestartRestored()), this, SLOT(prestartRestored())); + app->setPrestartMode(Dui::LazyShutdown); + service->launch(); + QCOMPARE(app->isPrestarted(), false); + service->close(); + // Test that we have the correct mode set + QCOMPARE(app->isPrestarted(), true); + // Test that the signal was sent + QCOMPARE(m_prestartRestored, true); + // Test that the handler is called + QCOMPARE(m_restorePrestart, true); + delete app; +} + +void Ut_DuiApplication::testRestorePrestartModeTerminateOnClose() +{ + // Test that app won't restore to prestart + // if not in LazyShutdown mode + DuiApplicationService *service = new DuiApplicationService("com.nokia.appName"); + app = buildPrestartApp(2, "appName -prestart", service); + app->connect(app, SIGNAL(prestartRestored()), this, SLOT(prestartRestored())); + app->setPrestartMode(Dui::TerminateOnClose); + service->launch(); + QCOMPARE(app->isPrestarted(), false); + service->close(); + // Test that we have the correct mode set + QCOMPARE(app->isPrestarted(), false); + // Test that the signal was not sent + QCOMPARE(m_prestartRestored, false); + // Test that the handler is called + QCOMPARE(m_restorePrestart, false); + delete app; +} + +void Ut_DuiApplication::testIsPrestartedLazyShutdown() +{ + // Test that app restores correctly to prestart + // if in LazyShutdown mode + DuiApplicationService *service = new DuiApplicationService("com.nokia.appName"); + app = buildPrestartApp(2, "appName -prestart", service); + QCOMPARE(app->isPrestarted(), false); + app->setPrestartMode(Dui::LazyShutdown); + QCOMPARE(app->isPrestarted(), true); + service->launch(); + QCOMPARE(app->isPrestarted(), false); + service->close(); + QCOMPARE(app->isPrestarted(), true); + delete app; +} + +void Ut_DuiApplication::testIsPrestartedTerminateOnClose() +{ + // Test that app won't restore to prestart + // if not in LazyShutdown mode + DuiApplicationService *service = new DuiApplicationService("com.nokia.appName"); + app = buildPrestartApp(2, "appName -prestart", service); + QCOMPARE(app->isPrestarted(), false); + app->setPrestartMode(Dui::TerminateOnClose); + QCOMPARE(app->isPrestarted(), true); + service->launch(); + QCOMPARE(app->isPrestarted(), false); + service->close(); + QCOMPARE(app->isPrestarted(), false); + delete app; +} + +void Ut_DuiApplication::testIsPrestartedNoPrestart() +{ + // Test that app won't enter prestart + // if -prestart not set + DuiApplicationService *service = new DuiApplicationService("com.nokia.appName"); + app = buildPrestartApp(1, "appName", service); + QCOMPARE(app->isPrestarted(), false); + app->setPrestartMode(Dui::TerminateOnClose); + QCOMPARE(app->isPrestarted(), false); + service->launch(); + QCOMPARE(app->isPrestarted(), false); + service->close(); + QCOMPARE(app->isPrestarted(), false); + delete app; +} + +void Ut_DuiApplication::prestartReleased() +{ + m_prestartReleased = true; +} + +void Ut_DuiApplication::prestartRestored() +{ + m_prestartRestored = true; +} + +QTEST_APPLESS_MAIN(Ut_DuiApplication); diff --git a/tests/ut_duiapplication/ut_duiapplication.h b/tests/ut_duiapplication/ut_duiapplication.h new file mode 100644 index 000000000..d3ef0265d --- /dev/null +++ b/tests/ut_duiapplication/ut_duiapplication.h @@ -0,0 +1,89 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIAPPLICATION_H +#define UT_DUIAPPLICATION_H + +#include +#include +#include + +class DuiApplicationService; + +#define MAX_PARAMS 10 +class Ut_DuiApplication: public QObject +{ + Q_OBJECT + +public: + static QString registeredService; + static bool m_releasePrestart; + static bool m_restorePrestart; + +private: + DuiApplication *app; + DuiApplication *buildApp(int count, const QString ¶ms, const QString &appId = QString(), DuiApplicationService *service = 0); + DuiApplication *buildApp(int count, const QString ¶ms, DuiApplicationService *service); + // Build application used in prestart API tests. + DuiApplication *buildPrestartApp(int count, const QString ¶ms, DuiApplicationService *service = 0); + QDir generateThemeDirectory(); + QDir generateApplicationThemeDirectory(const QString &applicationName); + + // Helper flags + bool m_prestartReleased; + bool m_prestartRestored; + +private slots: + void init(); + void cleanup(); + + void duiApplicationConstructor_data(); + void duiApplicationConstructor(); + void duiApplicationConstructorWithAppId(); + void duiApplicationConstructorWithService(); + + void duiApplicationTranslationPath(); + void duiApplicationNoFeedback(); + + //void testActiveApplicationWindow(); + //void testApplicationWindows(); + void testPrestartMode(); + void testReleasePrestartModeLazyShutdown(); + void testReleasePrestartModeTerminateOnClose(); + void testRestorePrestartModeLazyShutdown(); + void testRestorePrestartModeTerminateOnClose(); + void testIsPrestartedNoPrestart(); + void testIsPrestartedTerminateOnClose(); + void testIsPrestartedLazyShutdown(); + +public slots: + + // Test slots for prestart signals + void prestartReleased(); + void prestartRestored(); + +#if 0 + void duiApplicationName(); + void themeFileLoadingFromCurrentPath(); + void themeFileLoadingFromApplicationThemePath(); + void themeFileLoadingFromGlobalThemePath(); +#endif +}; + +#endif diff --git a/tests/ut_duiapplication/ut_duiapplication.pro b/tests/ut_duiapplication/ut_duiapplication.pro new file mode 100644 index 000000000..53671670d --- /dev/null +++ b/tests/ut_duiapplication/ut_duiapplication.pro @@ -0,0 +1,29 @@ +include(../common_top.pri) + +TARGET = ut_duiapplication + +#holger FIXME check DEFINES += THEMEDIR=\'$$quote(\"$$[QT_INSTALL_DATA]/themes/dui/\")\' + +#holger FIXME check DEFINES += TRANSLATION_DIR=\'$$quote(\"$$[QT_INSTALL_DATA]/share/l10n/dui/\")\' + +TEST_HEADERS = $$DUISRCDIR/core/duiapplication.h + +INCLUDEPATH += $$DUISRCDIR/feedback + +TEST_SOURCES = \ + $$DUISRCDIR/core/duiapplication.cpp + +# Input +HEADERS += \ + ut_duiapplication.h \ + $$TEST_HEADERS + +SOURCES += \ + ut_duiapplication.cpp \ + $$TEST_SOURCES \ + +# service classes +SOURCES += \ + $$STUBSDIR/stubbase.cpp \ + +include(../common_bot.pri) diff --git a/tests/ut_duiapplicationextensionarea/.gitignore b/tests/ut_duiapplicationextensionarea/.gitignore new file mode 100644 index 000000000..d0266143b --- /dev/null +++ b/tests/ut_duiapplicationextensionarea/.gitignore @@ -0,0 +1 @@ +ut_duiapplicationextensionarea diff --git a/tests/ut_duiapplicationextensionarea/ut_duiapplicationextensionarea.cpp b/tests/ut_duiapplicationextensionarea/ut_duiapplicationextensionarea.cpp new file mode 100644 index 000000000..3432439c0 --- /dev/null +++ b/tests/ut_duiapplicationextensionarea/ut_duiapplicationextensionarea.cpp @@ -0,0 +1,51 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duiapplicationextensionarea.h" +#include "duiapplication.h" +#include "duiapplicationextensionarea.h" + +#include + +// The test class +void Ut_DuiApplicationExtensionArea::init() +{ + area = new DuiApplicationExtensionArea("testcanvas"); +} + +void Ut_DuiApplicationExtensionArea::cleanup() +{ + delete area; +} + +void Ut_DuiApplicationExtensionArea::initTestCase() +{ + // DuiApplications must be created manually due to theme system changes + static int argc = 1; + static char *app_name[1] = { (char *) "./ut_duiapplicationextensionarea" }; + app = new DuiApplication(argc, app_name); +} + +void Ut_DuiApplicationExtensionArea::cleanupTestCase() +{ + delete app; +} + +QTEST_APPLESS_MAIN(Ut_DuiApplicationExtensionArea) + diff --git a/tests/ut_duiapplicationextensionarea/ut_duiapplicationextensionarea.h b/tests/ut_duiapplicationextensionarea/ut_duiapplicationextensionarea.h new file mode 100644 index 000000000..74a65ba6c --- /dev/null +++ b/tests/ut_duiapplicationextensionarea/ut_duiapplicationextensionarea.h @@ -0,0 +1,56 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIAPPLICATIONEXTENSIONAREA_ +#define UT_DUIAPPLICATIONEXTENSIONAREA_ + +#include +#include +#include "duiapplicationextensionareamodel.h" +#include "duiapplicationextensionareastyle.h" + +class DuiApplicationExtensionArea; +class DuiApplication; +class DuiApplicationWindow; + +class Ut_DuiApplicationExtensionArea : public QObject +{ + Q_OBJECT + +private: + // TestApplicationExtensionArea is derived from DuiApplicationExtensionArea + DuiApplicationExtensionArea *area; + // DuiApplication instance required by DuiWidget. + DuiApplication *app; + +private slots: + // Executed once before every test case + void init(); + + // Executed once after every test case + void cleanup(); + + // Executed once before first test case + void initTestCase(); + + // Executed once after last test case + void cleanupTestCase(); +}; + +#endif // UT_DUIAPPLICATIONEXTENSIONAREA_ diff --git a/tests/ut_duiapplicationextensionarea/ut_duiapplicationextensionarea.pro b/tests/ut_duiapplicationextensionarea/ut_duiapplicationextensionarea.pro new file mode 100644 index 000000000..e77e9d718 --- /dev/null +++ b/tests/ut_duiapplicationextensionarea/ut_duiapplicationextensionarea.pro @@ -0,0 +1,22 @@ +include(../common_top.pri) +TARGET = ut_duiapplicationextensionarea +INCLUDEPATH += \ + $$DUISRCDIR/applicationextension \ + $$DUISRCDIR/mashup/mashup \ + $$DUISRCDIR/widgets \ + $$DUISRCDIR/style \ + $$DUISRCDIR/core \ + +# unit test and unit classes +SOURCES += \ + ut_duiapplicationextensionarea.cpp \ + +# service classes +SOURCES += \ + $$STUBSDIR/stubbase.cpp \ + +# unit test and unit classes +HEADERS += \ + ut_duiapplicationextensionarea.h \ + +include(../common_bot.pri) diff --git a/tests/ut_duiapplicationextensionareaview/.gitignore b/tests/ut_duiapplicationextensionareaview/.gitignore new file mode 100644 index 000000000..ea5c85f61 --- /dev/null +++ b/tests/ut_duiapplicationextensionareaview/.gitignore @@ -0,0 +1 @@ +ut_duiapplicationextensionareaview diff --git a/tests/ut_duiapplicationextensionareaview/ut_duiapplicationextensionareaview.cpp b/tests/ut_duiapplicationextensionareaview/ut_duiapplicationextensionareaview.cpp new file mode 100644 index 000000000..430c61ca6 --- /dev/null +++ b/tests/ut_duiapplicationextensionareaview/ut_duiapplicationextensionareaview.cpp @@ -0,0 +1,175 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duiapplicationextensionareaview.h" + +#include "duiapplicationextensionarea.h" +#include "../stubs/mockdatastore.h" + +#include +#include +#include +#include +#include +#include + +#include +#include + +void QFileSystemWatcher::addPath(const QString &) +{ +} + +bool QDBusConnection::registerObject(const QString &, QObject *, RegisterOptions) +{ + return true; +} + +void Ut_DuiApplicationExtensionAreaView::initTestCase() +{ + // DuiApplications must be created manually due to theme system changes + static int argc = 1; + static char *app_name[1] = { (char *)"./ut_duiapplicationextensionareaview" }; + app = new DuiApplication(argc, app_name); + appWindow = new DuiApplicationWindow; +} + +void Ut_DuiApplicationExtensionAreaView::cleanupTestCase() +{ + delete appWindow; + delete app; +} + +void Ut_DuiApplicationExtensionAreaView::init() +{ + extensionArea = new DuiApplicationExtensionArea("test"); + m_subject = new TestDuiApplicationExtensionAreaView(extensionArea); + extensionArea->setView(m_subject); +} + +void Ut_DuiApplicationExtensionAreaView::cleanup() +{ + delete m_subject; +} + +void Ut_DuiApplicationExtensionAreaView::addWidgetToApplicationExtensionArea(DuiWidget *widget, DuiDataStore *dataStore) +{ + QMap *dataStores = const_cast *>(extensionArea->model()->dataStores()); + (*dataStores)[widget] = dataStore; + extensionArea->model()->dataStoresModified(); +} + +void Ut_DuiApplicationExtensionAreaView::removeWidgetFromApplicationExtensionArea(DuiWidget *widget) +{ + QMap *dataStores = const_cast *>(extensionArea->model()->dataStores()); + dataStores->remove(widget); + extensionArea->model()->dataStoresModified(); +} + +QList *Ut_DuiApplicationExtensionAreaView::createWidgets(int numberOfWidgets, bool containerMode) +{ + m_subject->modifiableStyle()->setContainerMode(containerMode); + m_subject->applyStyle(); + QList *widgetList = new QList; + for (int i = 0; i < numberOfWidgets; ++i) { + DuiWidget *widget = new DuiWidget; + MockDataStore *store = new MockDataStore; + addWidgetToApplicationExtensionArea(widget, store); + widgetList->append(widget); + } + return widgetList; +} + +bool Ut_DuiApplicationExtensionAreaView::widgetInLayout(DuiWidget *widget) +{ + QGraphicsLinearLayout *layout = dynamic_cast(extensionArea->layout()); + + bool found = false; + for (int i = 0; i < layout->count(); ++i) { + DuiWidget *w = NULL; + + DuiContainer *container = dynamic_cast(layout->itemAt(i)); + if (container != NULL) { + // Widget has a container, take the centralWidget data + w = container->centralWidget(); + } else { + // No container + w = dynamic_cast(layout->itemAt(i)); + } + + found |= w == widget; + } + + return found; +} + +void Ut_DuiApplicationExtensionAreaView::testLayoutPolicy() +{ + QGraphicsLinearLayout *mainLayout = dynamic_cast(extensionArea->layout()); + QVERIFY(mainLayout != NULL); +} + +void Ut_DuiApplicationExtensionAreaView::testAddition() +{ + DuiWidget *widget1 = new DuiWidget; + MockDataStore store1; + DuiWidget *widget2 = new DuiWidget; + MockDataStore store2; + + // Add one widget. + addWidgetToApplicationExtensionArea(widget1, &store1); + + // Check that it was added into the layout. + QVERIFY(widgetInLayout(widget1)); + + // Ensure that the layout data is written to data store. + QVERIFY(store1.contains("layoutIndex")); + + // Add another widget. Addition will change layout data of both widgets. + addWidgetToApplicationExtensionArea(widget2, &store2); + + // Check that it was added into the layout. + QVERIFY(widgetInLayout(widget2)); + + // Ensure that new layout data is stored into data store. + QVERIFY(store1.contains("layoutIndex")); + QVERIFY(store2.contains("layoutIndex")); + + delete widget1; + delete widget2; +} + + +void Ut_DuiApplicationExtensionAreaView::testRemoval() +{ + QList *widgetList = createWidgets(3); + + // Remove widget2 + removeWidgetFromApplicationExtensionArea(widgetList->at(1)); + + // Ensure that widget1 and widget3 are still in the layout but widget2 is not. + QVERIFY(widgetInLayout(widgetList->at(0))); + QVERIFY(!widgetInLayout(widgetList->at(1))); + QVERIFY(widgetInLayout(widgetList->at(2))); + + while (!widgetList->isEmpty()) + delete widgetList->takeFirst(); +} + +QTEST_APPLESS_MAIN(Ut_DuiApplicationExtensionAreaView) diff --git a/tests/ut_duiapplicationextensionareaview/ut_duiapplicationextensionareaview.h b/tests/ut_duiapplicationextensionareaview/ut_duiapplicationextensionareaview.h new file mode 100644 index 000000000..51d7eae8b --- /dev/null +++ b/tests/ut_duiapplicationextensionareaview/ut_duiapplicationextensionareaview.h @@ -0,0 +1,90 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIAPPLICATIONEXTENSIONAREAVIEW_H +#define UT_DUIAPPLICATIONEXTENSIONAREAVIEW_H + +#include +#include "duiapplicationextensionareaview.h" + +class DuiApplicationWindow; +class DuiApplication; +class DuiApplicationExtensionAreaView; +class DuiApplicationExtensionArea; +class DuiWidget; +class DuiDataStore; + +class TestDuiApplicationExtensionAreaView : public DuiApplicationExtensionAreaView +{ + DUI_VIEW(DuiApplicationExtensionAreaModel, DuiApplicationExtensionAreaStyle) + +public: + TestDuiApplicationExtensionAreaView(DuiApplicationExtensionArea *canvas) : DuiApplicationExtensionAreaView(canvas) {} + + DuiApplicationExtensionAreaStyle *modifiableStyle() { + DuiApplicationExtensionAreaStyleContainer &sc = style(); + const DuiApplicationExtensionAreaStyle *const_s = sc.operator ->(); + DuiApplicationExtensionAreaStyle *s = const_cast(const_s); + return s; + } + + void applyStyle() { + DuiApplicationExtensionAreaView::applyStyle(); + } +}; + +class Ut_DuiApplicationExtensionAreaView : public QObject +{ + Q_OBJECT + +private slots: + // Called before the first testfunction is executed + void initTestCase(); + // Called after the last testfunction was executed + void cleanupTestCase(); + // Called before each testfunction is executed + void init(); + // Called after every testfunction + void cleanup(); + + // Test that the layout is set up as expected + void testLayoutPolicy(); + // Test widget addition + void testAddition(); + // Test widget removal + void testRemoval(); + +private: + bool widgetInLayout(DuiWidget *widget); + void addWidgetToApplicationExtensionArea(DuiWidget *widget, DuiDataStore *dataStore); + void removeWidgetFromApplicationExtensionArea(DuiWidget *widget); + + // Widget creation helpers + QList *createWidgets(int numberOfWidgets, bool containerMode = true); + // DuiApplication instance required by DuiWidget. + DuiApplication *app; + // DuiApplicationWindow instance required to get the scene and scene manager. + DuiApplicationWindow *appWindow; + // The object being tested + TestDuiApplicationExtensionAreaView *m_subject; + // Controller for the view + DuiApplicationExtensionArea *extensionArea; +}; + +#endif diff --git a/tests/ut_duiapplicationextensionareaview/ut_duiapplicationextensionareaview.pro b/tests/ut_duiapplicationextensionareaview/ut_duiapplicationextensionareaview.pro new file mode 100644 index 000000000..d5ddbd35d --- /dev/null +++ b/tests/ut_duiapplicationextensionareaview/ut_duiapplicationextensionareaview.pro @@ -0,0 +1,15 @@ +include(../common_top.pri) +TARGET = ut_duiapplicationextensionareaview +INCLUDEPATH += $$DUISRCDIR/applicationextension $$DUISRCDIR/layout $$DUISRCDIR/style + +QT += core network gui svg dbus + +# unit test and unit classes +SOURCES += \ + ut_duiapplicationextensionareaview.cpp \ + +# unit test and unit classes +HEADERS += \ + ut_duiapplicationextensionareaview.h \ + +include(../common_bot.pri) diff --git a/tests/ut_duiapplicationmenu/.gitignore b/tests/ut_duiapplicationmenu/.gitignore new file mode 100644 index 000000000..1ac9394c4 --- /dev/null +++ b/tests/ut_duiapplicationmenu/.gitignore @@ -0,0 +1 @@ +ut_duiapplicationmenu diff --git a/tests/ut_duiapplicationmenu/ut_duiapplicationmenu.cpp b/tests/ut_duiapplicationmenu/ut_duiapplicationmenu.cpp new file mode 100644 index 000000000..e0db65eb0 --- /dev/null +++ b/tests/ut_duiapplicationmenu/ut_duiapplicationmenu.cpp @@ -0,0 +1,265 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duiapplicationmenu.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "duiapplicationmenu_p.h" + +DuiApplication *app; +DuiApplicationWindow *appWin; + +void Ut_DuiApplicationMenu::init() +{ + m_subject = new DuiApplicationMenu(); +} + +void Ut_DuiApplicationMenu::cleanup() +{ + delete m_subject; + m_subject = 0; +} + +void Ut_DuiApplicationMenu::initTestCase() +{ + static int argc = 1; + static char *app_name[1] = { (char *) "./ut_duiapplicationmenu" }; + app = new DuiApplication(argc, app_name); + appWin = new DuiApplicationWindow; +} + +void Ut_DuiApplicationMenu::cleanupTestCase() +{ + delete appWin; + delete app; +} + +void Ut_DuiApplicationMenu::testConstructor() +{ + QVERIFY(m_subject); +} + +void Ut_DuiApplicationMenu::testDestructor() +{ + DuiApplicationMenu *menu = new DuiApplicationMenu(); + delete menu; +} + +void Ut_DuiApplicationMenu::testAddAction() +{ + // empty action list, check + m_subject->clearActions(); + QVERIFY(m_subject->actions().count() == 0); + + // return value action + DuiAction *action; + + // test addAction(const QString &text) + DuiAction *action0 = new DuiAction("TEXTONLY", m_subject); + m_subject->addAction(action0); + action = qobject_cast(m_subject->actions().at(0)); + // must be one + QVERIFY(m_subject->actions().count() == 1); + QVERIFY(action == action0); + QVERIFY(action->text() == "TEXTONLY"); + + // test addAction(const QString &icon, const QString &text) + DuiAction *action1 = new DuiAction("Icon-list-view-on", "TEXT", m_subject); + m_subject->addAction(action1); + QVERIFY(m_subject->actions().count() == 2); + action = qobject_cast(m_subject->actions().at(1)); + QVERIFY(action == action1); + QVERIFY(action->iconID() == "Icon-list-view-on"); + QVERIFY(action->text() == "TEXT"); + + testValue = false; + senderAction = NULL; + connect(action1, SIGNAL(triggered(bool)), this, SLOT(actionSlot(bool))); + action1->trigger(); + QVERIFY(testValue); + QVERIFY(senderAction == action1); + + // test addAction(DuiAction* action) + DuiAction *action2 = new DuiAction("Icon-time-line-on", "TEXT4", NULL); + m_subject->addAction(action2); + QVERIFY(m_subject->actions().count() == 3); + + action = qobject_cast(m_subject->actions().at(2)); + QVERIFY(action == action2); + delete action2; +} + +void Ut_DuiApplicationMenu::testInsertAction() +{ + + m_subject->clearActions(); + QVERIFY(m_subject->actions().count() == 0); + + DuiAction *action0 = new DuiAction("action0", m_subject); + m_subject->addAction(action0); + + DuiAction *action1 = new DuiAction("action1", m_subject); + m_subject->addAction(action1); + + DuiAction *action2 = new DuiAction("action2", m_subject); + m_subject->insertAction(action0, action2); + + QVERIFY(m_subject->actions().count() == 3); + + DuiAction *action_at0 = qobject_cast(m_subject->actions().at(0)); + DuiAction *action_at1 = qobject_cast(m_subject->actions().at(1)); + DuiAction *action_at2 = qobject_cast(m_subject->actions().at(2)); + + QVERIFY(action_at0); + QVERIFY(action_at0 == action2); + QVERIFY(action_at1); + QVERIFY(action_at1 == action0); + QVERIFY(action_at2); + QVERIFY(action_at2 == action1); + +} + +void Ut_DuiApplicationMenu::testActionVisiblity() +{ + + m_subject->clearActions(); + QVERIFY(m_subject->actions().count() == 0); + + DuiAction *action0 = new DuiAction("action0", m_subject); + action0->setLocation(DuiAction::ApplicationMenuLocation); + m_subject->addAction(action0); + + DuiAction *action1 = new DuiAction("action1", m_subject); + action1->setLocation(DuiAction::ApplicationMenuLocation); + m_subject->addAction(action1); + + DuiAction *action2 = new DuiAction("action2", m_subject); + action2->setLocation(DuiAction::ApplicationMenuLocation); + m_subject->addAction(action2); + + DuiAction *action3 = new DuiAction("action3", m_subject); + action3->setLocation(DuiAction::ApplicationMenuLocation); + m_subject->addAction(action3); + + QVERIFY(m_subject->actions().count() == 4); + + action0->setVisible(false); + action1->setVisible(false); + + QVERIFY(m_subject->actions().count() == 4); + + DuiAction *action = qobject_cast(m_subject->actions().at(0)); + QVERIFY(action); + QVERIFY(action == action0); + QVERIFY(action->isVisible() == false); + + action = qobject_cast(m_subject->actions().at(1)); + QVERIFY(action); + QVERIFY(action == action1); + QVERIFY(action->isVisible() == false); + + action = qobject_cast(m_subject->actions().at(2)); + QVERIFY(action); + QVERIFY(action == action2); + QVERIFY(action->isVisible() == true); + + action = qobject_cast(m_subject->actions().at(3)); + QVERIFY(action); + QVERIFY(action == action3); + QVERIFY(action->isVisible() == true); + + DuiWidgetAction *comboAction = new DuiWidgetAction(m_subject); + comboAction->setLocation(DuiAction::ApplicationMenuLocation); + QStringList list; + for (int i = 0; i < 5; ++i) { + list << QString::number(100 + i); + } + DuiComboBox *comboBox = new DuiComboBox(); + comboBox->setIconVisible(false); + comboBox->addItems(list); + comboAction->setWidget(comboBox); + m_subject->addAction(comboAction); + + DuiWidgetAction *widgetAction = qobject_cast(m_subject->actions().at(4)); + QVERIFY(widgetAction); + QVERIFY(widgetAction == comboAction); + QVERIFY(widgetAction->isVisible() == true); + + widgetAction->setVisible(false); + QVERIFY(widgetAction->widget()->isVisible() == false); +} + +void Ut_DuiApplicationMenu::actionSlot(bool checked) +{ + Q_UNUSED(checked); + senderAction = qobject_cast(sender()); + testValue = true; +} + + +void Ut_DuiApplicationMenu::testClear() +{ + for (int i = 0; i < 5; ++i) { + DuiAction *action = new DuiAction("", "Action" + QString::number(i), m_subject); + m_subject->addAction(action); + } + + QVERIFY(m_subject->actions().count() == 5); + + // empty action list, check + m_subject->clearActions(); + QVERIFY(m_subject->actions().count() == 0); +} + +void Ut_DuiApplicationMenu::testEventsPassingThrough() +{ + m_subject->appear(); + // The event should be swallowed if it is not triggering any action. + QGraphicsSceneMouseEvent mousePressEvent(QEvent::GraphicsSceneMousePress); + QVERIFY(mousePressEvent.isAccepted()); + + QGraphicsSceneMouseEvent mouseReleaseEvent(QEvent::GraphicsSceneMouseRelease); + m_subject->mouseReleaseEvent(&mouseReleaseEvent); +} + + +void Ut_DuiApplicationMenu::testPaint() +{ + QPixmap pixmap(864, 480); + pixmap.fill(Qt::transparent); + QPainter painter(&pixmap); + m_subject->addAction(new DuiAction("text action", m_subject)); + m_subject->paint(&painter, NULL, NULL); + delete m_subject; + + m_subject = new DuiApplicationMenu("object"); + m_subject->addAction(new DuiAction("text action", m_subject)); + m_subject->paint(&painter, NULL, NULL); +} + +QTEST_APPLESS_MAIN(Ut_DuiApplicationMenu) diff --git a/tests/ut_duiapplicationmenu/ut_duiapplicationmenu.h b/tests/ut_duiapplicationmenu/ut_duiapplicationmenu.h new file mode 100644 index 000000000..922798b5a --- /dev/null +++ b/tests/ut_duiapplicationmenu/ut_duiapplicationmenu.h @@ -0,0 +1,59 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIAPPLICATIONMENU_H +#define UT_DUIAPPLICATIONMENU_H + +#include +#include + +class DuiAction; +class DuiApplicationMenu; + +class Ut_DuiApplicationMenu : public QObject +{ + Q_OBJECT + +private Q_SLOTS: + + void init(); + void cleanup(); + void initTestCase(); + void cleanupTestCase(); + + // class testing + void testConstructor(); + void testDestructor(); + void testAddAction(); + void testInsertAction(); + void testActionVisiblity(); + void testClear(); + void testPaint(); + void testEventsPassingThrough(); + + void actionSlot(bool checked); + +private: + DuiApplicationMenu *m_subject; + + DuiAction *senderAction; + bool testValue; +}; + +#endif diff --git a/tests/ut_duiapplicationmenu/ut_duiapplicationmenu.pro b/tests/ut_duiapplicationmenu/ut_duiapplicationmenu.pro new file mode 100644 index 000000000..28c4ac2cb --- /dev/null +++ b/tests/ut_duiapplicationmenu/ut_duiapplicationmenu.pro @@ -0,0 +1,13 @@ +include(../common_top.pri) +TARGET = ut_duiapplicationmenu + + +INCLUDEPATH += $$DUISRCDIR/widgets $$DUISRCDIR/style $$DUISRCDIR/scene + +SOURCES += \ + ut_duiapplicationmenu.cpp \ + +HEADERS += \ + ut_duiapplicationmenu.h + +include(../common_bot.pri) diff --git a/tests/ut_duiapplicationmenuview/.gitignore b/tests/ut_duiapplicationmenuview/.gitignore new file mode 100644 index 000000000..3cc6f2f37 --- /dev/null +++ b/tests/ut_duiapplicationmenuview/.gitignore @@ -0,0 +1 @@ +ut_duiapplicationmenuview diff --git a/tests/ut_duiapplicationmenuview/ut_duiapplicationmenuview.cpp b/tests/ut_duiapplicationmenuview/ut_duiapplicationmenuview.cpp new file mode 100644 index 000000000..4b7642dc5 --- /dev/null +++ b/tests/ut_duiapplicationmenuview/ut_duiapplicationmenuview.cpp @@ -0,0 +1,60 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include + +#include "ut_duiapplicationmenuview.h" + +DuiApplication *app; + +void Ut_DuiApplicationMenuView::initTestCase() +{ + static int argc = 1; + static char *app_name[1] = { (char *) "./Ut_DuiApplicationMenuView" }; + app = new DuiApplication(argc, app_name); +} + +void Ut_DuiApplicationMenuView::cleanupTestCase() +{ + delete app; +} + +void Ut_DuiApplicationMenuView::init() +{ + m_menu = new DuiApplicationMenu(); + m_subject = new DuiApplicationMenuView(m_menu); +} + +void Ut_DuiApplicationMenuView::cleanup() +{ + delete m_menu; + m_menu = 0; + // menu destruction also destroys the view +} + +void Ut_DuiApplicationMenuView::testSetView() +{ + QVERIFY(m_menu != 0); + QVERIFY(m_subject != 0); + + m_menu->setView(m_subject); +} + +QTEST_APPLESS_MAIN(Ut_DuiApplicationMenuView) diff --git a/tests/ut_duiapplicationmenuview/ut_duiapplicationmenuview.h b/tests/ut_duiapplicationmenuview/ut_duiapplicationmenuview.h new file mode 100644 index 000000000..41c954de6 --- /dev/null +++ b/tests/ut_duiapplicationmenuview/ut_duiapplicationmenuview.h @@ -0,0 +1,52 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIAPPLICATIONMENUVIEW_H +#define UT_DUIAPPLICATIONMENUVIEW_H + +#include +#include + +// the real unit/DuiApplicationMenuView class declaration +#include + +Q_DECLARE_METATYPE(DuiApplicationMenuView *); + +class DuiApplicationMenu; + +class Ut_DuiApplicationMenuView : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase(); + void cleanupTestCase(); + + void init(); + void cleanup(); + + // class testing + void testSetView(); + +private: + DuiApplicationMenuView *m_subject; + DuiApplicationMenu *m_menu; +}; + +#endif diff --git a/tests/ut_duiapplicationmenuview/ut_duiapplicationmenuview.pro b/tests/ut_duiapplicationmenuview/ut_duiapplicationmenuview.pro new file mode 100644 index 000000000..f7ccb75c5 --- /dev/null +++ b/tests/ut_duiapplicationmenuview/ut_duiapplicationmenuview.pro @@ -0,0 +1,14 @@ +include(../common_top.pri) +TARGET = ut_duiapplicationmenuview + +INCLUDEPATH += $$DUISRCDIR/widgets $$DUISRCDIR/style + +# unit test and unit +SOURCES += \ + ut_duiapplicationmenuview.cpp \ + +# unit test and unit +HEADERS += \ + ut_duiapplicationmenuview.h \ + +include(../common_bot.pri) diff --git a/tests/ut_duiapplicationpage/.gitignore b/tests/ut_duiapplicationpage/.gitignore new file mode 100644 index 000000000..bbc5e8b82 --- /dev/null +++ b/tests/ut_duiapplicationpage/.gitignore @@ -0,0 +1 @@ +ut_duiapplicationpage diff --git a/tests/ut_duiapplicationpage/ut_duiapplicationpage.cpp b/tests/ut_duiapplicationpage/ut_duiapplicationpage.cpp new file mode 100644 index 000000000..5ba53704d --- /dev/null +++ b/tests/ut_duiapplicationpage/ut_duiapplicationpage.cpp @@ -0,0 +1,246 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duiapplicationpage.h" + +#include +#include +#include "duiapplicationpage_p.h" + +#include +#include +#include +#include +#include + +#include "duiondisplaychangeevent.h" + +void Ut_DuiApplicationPage::initTestCase() +{ + static int argc = 1; + static char *app_name[1] = { (char *) "./ut_duiapplicationpage" }; + app = new DuiApplication(argc, app_name); + appWin = new DuiApplicationWindow; + + qRegisterMetaType(); + qRegisterMetaType(); +} + +void Ut_DuiApplicationPage::cleanupTestCase() +{ + delete appWin; + delete app; +} + +void Ut_DuiApplicationPage::init() +{ + m_subject = new DuiApplicationPage; +} + +void Ut_DuiApplicationPage::cleanup() +{ + // important: testCentralWidget deletes m_subject on its own + if (m_subject) { + delete m_subject; + m_subject = 0; + } +} + +void Ut_DuiApplicationPage::testInitialValues() +{ + QCOMPARE(m_subject->title(), QString()); + QCOMPARE(m_subject->isContentCreated(), false); + QVERIFY(m_subject->centralWidget()); + + QCOMPARE(m_subject->isPannableAreaInteractive(), true); + QCOMPARE(m_subject->escapeButtonMode(), DuiEscapeButtonPanelModel::CloseMode); + QCOMPARE(m_subject->rememberPosition(), true); +} + +void Ut_DuiApplicationPage::testProperties() +{ + QString title("Title of the page"); + bool pannableAreaInteractive = true; + Qt::Orientations pannableAreaDirection = Qt::Horizontal | Qt::Vertical; + bool autoMarginsForComponents = true; + DuiEscapeButtonPanelModel::EscapeMode escapeMode = DuiEscapeButtonPanelModel::BackMode; + bool rememberPosition = false; + + m_subject->setTitle(title); + QCOMPARE(m_subject->title(), title); + m_subject->setPannableAreaInteractive(pannableAreaInteractive); + QCOMPARE(m_subject->isPannableAreaInteractive(), pannableAreaInteractive); + m_subject->setPannableAreaDirection(pannableAreaDirection); + QCOMPARE(m_subject->pannableAreaDirection(), pannableAreaDirection); + m_subject->setAutoMarginsForComponentsEnabled(autoMarginsForComponents); + QCOMPARE(m_subject->autoMarginsForComponentsEnabled(), autoMarginsForComponents); + m_subject->setEscapeButtonMode(escapeMode); + QCOMPARE(m_subject->escapeButtonMode(), escapeMode); + m_subject->setRememberPosition(rememberPosition); + QCOMPARE(m_subject->rememberPosition(), rememberPosition); +} + +void Ut_DuiApplicationPage::testCentralWidget() +{ + QPointer widget = new DuiWidget; + m_subject->setCentralWidget(widget); + QCOMPARE(m_subject->centralWidget(), widget.data()); + + // remove the current central widget and verify that it has been deleted + m_subject->setCentralWidget(0); + QCOMPARE(m_subject->centralWidget(), (DuiWidget *) 0); + QVERIFY(widget.isNull()); + + widget = new DuiWidget; + m_subject->setCentralWidget(widget); + QCOMPARE(m_subject->centralWidget(), widget.data()); + + // delete the page to see if the central widget is deleted + delete m_subject; + m_subject = 0; + QVERIFY(widget.isNull()); +} + +void Ut_DuiApplicationPage::testCreateContent() +{ + QVERIFY(!m_subject->isContentCreated()); + m_subject->createContent(); + QVERIFY(m_subject->isContentCreated()); +} + +void Ut_DuiApplicationPage::testPageTitleChanged() +{ + QSignalSpy spy(m_subject, SIGNAL(pageTitleChanged(DuiApplicationPage *, QString))); + QString title("Title!"); + + m_subject->setTitle(m_subject->title()); + QCOMPARE(spy.count(), 0); + m_subject->setTitle(title); + QCOMPARE(spy.count(), 1); + m_subject->setTitle(title); + QCOMPARE(spy.count(), 1); + m_subject->setTitle(QString()); + QCOMPARE(spy.count(), 2); + + QCOMPARE(spy.at(0).at(0).value(), m_subject); + QCOMPARE(spy.at(0).at(1).toString(), title); + + QCOMPARE(spy.at(1).at(0).value(), m_subject); + QCOMPARE(spy.at(1).at(1).toString(), QString()); +} + +void Ut_DuiApplicationPage::testEscapeButtonModeChanged() +{ + QSignalSpy spy(m_subject, SIGNAL(escapeButtonModeChanged(DuiEscapeButtonPanelModel::EscapeMode))); + DuiEscapeButtonPanelModel::EscapeMode backMode = DuiEscapeButtonPanelModel::BackMode; + DuiEscapeButtonPanelModel::EscapeMode closeMode = DuiEscapeButtonPanelModel::CloseMode; + + m_subject->setEscapeButtonMode(m_subject->escapeButtonMode()); + QCOMPARE(spy.count(), 0); + m_subject->setEscapeButtonMode(backMode); + QCOMPARE(spy.count(), 1); + m_subject->setEscapeButtonMode(backMode); + QCOMPARE(spy.count(), 1); + m_subject->setEscapeButtonMode(closeMode); + QCOMPARE(spy.count(), 2); + + QCOMPARE(spy.at(0).at(0).value(), backMode); + QCOMPARE(spy.at(1).at(0).value(), closeMode); +} + +void Ut_DuiApplicationPage::testRememberPosition() +{ + m_subject->setRememberPosition(true); + m_subject->d_func()->pannableViewPort->setPosition(QPointF(0, 10)); + m_subject->appearNow(); + QCOMPARE(m_subject->d_func()->pannableViewPort->position() + QPointF(10, 10), QPointF(10, 20)); + QCOMPARE(m_subject->d_func()->pannableViewPort->physics()->position() + QPointF(10, 10), QPointF(10, 20)); +} + +void Ut_DuiApplicationPage::testForgetPosition() +{ + m_subject->setRememberPosition(false); + m_subject->d_func()->pannableViewPort->setPosition(QPointF(0, 10)); + m_subject->appearNow(); + QCOMPARE(m_subject->d_func()->pannableViewPort->position() + QPointF(10, 10), QPointF(10, 10)); + QCOMPARE(m_subject->d_func()->pannableViewPort->physics()->position() + QPointF(10, 10), QPointF(10, 10)); +} + +void Ut_DuiApplicationPage::testActionUpdated() +{ + m_subject->clearActions(); + QSignalSpy spy(m_subject, SIGNAL(actionUpdated(QActionEvent *))); + QCOMPARE(spy.count(), 0); + + m_subject->addAction(new DuiAction("test application page", m_subject)); + QCOMPARE(spy.count(), 1); + + m_subject->clearActions(); + QCOMPARE(spy.count(), 2); +} + +void Ut_DuiApplicationPage::testDefaultComponentDisplayModes() +{ + QCOMPARE(m_subject->componentDisplayMode(DuiApplicationPage::NavigationBar), DuiApplicationPageModel::Show); + QCOMPARE(m_subject->componentDisplayMode(DuiApplicationPage::HomeButton), DuiApplicationPageModel::Show); + QCOMPARE(m_subject->componentDisplayMode(DuiApplicationPage::EscapeButton), DuiApplicationPageModel::Show); +} + +void Ut_DuiApplicationPage::testSettingComponentsDisplayModes() +{ + DuiApplicationPageModel *model = m_subject->model(); + + m_subject->setComponentsDisplayMode(DuiApplicationPage::NavigationBar, DuiApplicationPageModel::Hide); + QCOMPARE(m_subject->componentDisplayMode(DuiApplicationPage::NavigationBar), DuiApplicationPageModel::Hide); + QCOMPARE(model->navigationBarDisplayMode(), DuiApplicationPageModel::Hide); + + m_subject->setComponentsDisplayMode(DuiApplicationPage::HomeButton, DuiApplicationPageModel::AutoHide); + QCOMPARE(m_subject->componentDisplayMode(DuiApplicationPage::HomeButton), DuiApplicationPageModel::AutoHide); + QCOMPARE(model->homeButtonDisplayMode(), DuiApplicationPageModel::AutoHide); +} + +void Ut_DuiApplicationPage::testSettingMultipleComponentsDisplayModes() +{ + DuiApplicationPageModel *model = m_subject->model(); + + m_subject->setComponentsDisplayMode(DuiApplicationPage::NavigationBar | DuiApplicationPage::HomeButton, + DuiApplicationPageModel::Hide); + + QCOMPARE(m_subject->componentDisplayMode(DuiApplicationPage::NavigationBar), DuiApplicationPageModel::Hide); + QCOMPARE(model->navigationBarDisplayMode(), DuiApplicationPageModel::Hide); + QCOMPARE(m_subject->componentDisplayMode(DuiApplicationPage::HomeButton), DuiApplicationPageModel::Hide); + QCOMPARE(model->homeButtonDisplayMode(), DuiApplicationPageModel::Hide); +} + +void Ut_DuiApplicationPage::testSettingAllComponentsDisplayMode() +{ + m_subject->setComponentsDisplayMode(DuiApplicationPage::AllComponents, DuiApplicationPageModel::Hide); + + QCOMPARE(m_subject->componentDisplayMode(DuiApplicationPage::NavigationBar), DuiApplicationPageModel::Hide); + QCOMPARE(m_subject->componentDisplayMode(DuiApplicationPage::HomeButton), DuiApplicationPageModel::Hide); + QCOMPARE(m_subject->componentDisplayMode(DuiApplicationPage::EscapeButton), DuiApplicationPageModel::Hide); + + m_subject->setComponentsDisplayMode(DuiApplicationPage::AllComponents, DuiApplicationPageModel::Show); + + QCOMPARE(m_subject->componentDisplayMode(DuiApplicationPage::NavigationBar), DuiApplicationPageModel::Show); + QCOMPARE(m_subject->componentDisplayMode(DuiApplicationPage::HomeButton), DuiApplicationPageModel::Show); + QCOMPARE(m_subject->componentDisplayMode(DuiApplicationPage::EscapeButton), DuiApplicationPageModel::Show); +} + +QTEST_APPLESS_MAIN(Ut_DuiApplicationPage) diff --git a/tests/ut_duiapplicationpage/ut_duiapplicationpage.h b/tests/ut_duiapplicationpage/ut_duiapplicationpage.h new file mode 100644 index 000000000..82f85a3f7 --- /dev/null +++ b/tests/ut_duiapplicationpage/ut_duiapplicationpage.h @@ -0,0 +1,68 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUISCENEWINDOW_H +#define UT_DUISCENEWINDOW_H + +#include +#include +#include + +#define MAX_PARAMS 10 + +class DuiApplication; +class DuiApplicationWindow; + +Q_DECLARE_METATYPE(DuiApplicationPage *); +Q_DECLARE_METATYPE(DuiEscapeButtonPanelModel::EscapeMode); + +class Ut_DuiApplicationPage : public QObject +{ + Q_OBJECT + +private slots: + void init(); + void cleanup(); + void initTestCase(); + void cleanupTestCase(); + + void testInitialValues(); + void testProperties(); + void testCentralWidget(); + void testCreateContent(); + void testPageTitleChanged(); + void testEscapeButtonModeChanged(); + void testRememberPosition(); + void testForgetPosition(); + void testActionUpdated(); + void testDefaultComponentDisplayModes(); + void testSettingComponentsDisplayModes(); + void testSettingMultipleComponentsDisplayModes(); + void testSettingAllComponentsDisplayMode(); + +private: + DuiApplicationPage *m_subject; + DuiApplicationWindow *appWin; + DuiApplication *app; + +}; + +//Q_DECLARE_METATYPE(DuiApplicationPage*); + +#endif diff --git a/tests/ut_duiapplicationpage/ut_duiapplicationpage.pro b/tests/ut_duiapplicationpage/ut_duiapplicationpage.pro new file mode 100644 index 000000000..7571e5c60 --- /dev/null +++ b/tests/ut_duiapplicationpage/ut_duiapplicationpage.pro @@ -0,0 +1,11 @@ +include(../common_top.pri) +TARGET = ut_duiapplicationpage +INCLUDEPATH += $$DUISRCDIR/widgets \ + +SOURCES += \ + ut_duiapplicationpage.cpp + +HEADERS += \ + ut_duiapplicationpage.h + +include(../common_bot.pri) diff --git a/tests/ut_duiapplicationservice/.gitignore b/tests/ut_duiapplicationservice/.gitignore new file mode 100644 index 000000000..0a1bb4a43 --- /dev/null +++ b/tests/ut_duiapplicationservice/.gitignore @@ -0,0 +1 @@ +ut_duiapplicationservice diff --git a/tests/ut_duiapplicationservice/ut_duiapplicationservice.cpp b/tests/ut_duiapplicationservice/ut_duiapplicationservice.cpp new file mode 100644 index 000000000..dd72222d0 --- /dev/null +++ b/tests/ut_duiapplicationservice/ut_duiapplicationservice.cpp @@ -0,0 +1,369 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include "duiapplicationservice_p.h" +#include +#include +#include + +#include "ut_duiapplicationservice.h" + +// has to be included last +#include "duiapplication_p.h" + +QString Ut_DuiApplicationService::appName; +QStringList Ut_DuiApplicationService::arguments; +char *Ut_DuiApplicationService::argv[MAX_PARAMS]; +int Ut_DuiApplicationService::argc; +bool Ut_DuiApplicationService::programArgsCorrect = false; +bool Ut_DuiApplicationService::programStarted = false; +bool Ut_DuiApplicationService::allowRegisterService = true; +bool Ut_DuiApplicationService::allowRegisterService2 = true; +int Ut_DuiApplicationService::failRegisterServiceTimes = 1; +int Ut_DuiApplicationService::failRegisterServiceCounter = 0; +QString Ut_DuiApplicationService::registeredService("notSet"); +bool Ut_DuiApplicationService::applicationExited = false; +bool Ut_DuiApplicationService::activeWindowSet = false; +bool Ut_DuiApplicationService::windowActivated = false; +bool Ut_DuiApplicationService::windowRaised = false; +bool Ut_DuiApplicationService::windowClosed = false; +bool Ut_DuiApplicationService::windowShown = false; + +DuiWindow::DuiWindow(QWidget *): + d_ptr(0) +{ +} + +DuiWindow *DuiComponentData::activeWindow() +{ + QWidget *qw = new QWidget(); + return new DuiWindow(qw); +} + +Dui::PrestartMode DuiComponentData::prestartMode() +{ + return Dui::NoPrestart; +} + +QString DuiComponentData::appName() +{ + return "ut_duiapplicationservice"; +} + +QString DuiComponentData::binaryName() +{ + return "ut_duiapplicationservice"; +} + +QDBusPendingReply<> DuiApplicationIfProxy::launch() +{ + return QDBusPendingReply<>(); +} + +void DuiApplicationPrivate::stdExit(int status) +{ + Ut_DuiApplicationService::applicationExited = true; + Q_UNUSED(status); + // don't exit - need to carry on to complete other tests +} + +QString DuiApplicationServicePrivate::appName() +{ + return QString(Ut_DuiApplicationService::argv[0]); +} + +bool DuiApplicationServicePrivate::thisAppRunWithDBus() +{ + return true; +} + +bool Ut_DuiApplicationService::isPrestartedReturnValue = false; +bool DuiApplicationServicePrivate::isPrestarted() +{ + return Ut_DuiApplicationService::isPrestartedReturnValue; +} + +bool Ut_DuiApplicationService::isLazyShutdownReturnValue = false; +bool DuiApplicationServicePrivate::prestartModeIsLazyShutdown() +{ + return Ut_DuiApplicationService::isLazyShutdownReturnValue; +} + +bool Ut_DuiApplicationService::prestartReleased = false; +void DuiApplicationServicePrivate::releasePrestart() +{ + Ut_DuiApplicationService::prestartReleased = true; +} + +bool Ut_DuiApplicationService::prestartRestored = false; +void DuiApplicationServicePrivate::restorePrestart() +{ + Ut_DuiApplicationService::prestartRestored = true; +} + +bool DuiApplicationServicePrivate::activeWindowSet() +{ + return Ut_DuiApplicationService::activeWindowSet; +} + +void DuiApplicationServicePrivate::activateActiveWindow() +{ + Ut_DuiApplicationService::windowActivated = true; +} + +void DuiApplicationServicePrivate::raiseActiveWindow() +{ + Ut_DuiApplicationService::windowRaised = true; +} + +QStringList DuiApplicationServicePrivate::arguments() +{ + return Ut_DuiApplicationService::arguments; +} + +QString DuiApplicationServicePrivate::binaryName() +{ + return Ut_DuiApplicationService::argv[ 0 ]; +} + +void DuiApplicationServicePrivate::launchNewProcess(const QString &binaryName, const QStringList &arguments) +{ + Ut_DuiApplicationService::programStarted = (binaryName == Ut_DuiApplicationService::argv[0]); + + // check argc is correct + int argumentCountShouldBe = Ut_DuiApplicationService::argc - 1; + int argumentCountIs = arguments.count(); + Ut_DuiApplicationService::programArgsCorrect = (argumentCountIs == argumentCountShouldBe); + + // check argvs are correct + for (int thisArg = 0; thisArg < arguments.count(); ++thisArg) { + QString isThis = arguments.at(thisArg); + QString shouldBeThis = QString(Ut_DuiApplicationService::argv[ thisArg+1 ]); + Ut_DuiApplicationService::programArgsCorrect &= (isThis == shouldBeThis); + } +} + +bool DuiApplicationServicePrivate::registerService(const QString &name) +{ + bool retVal = false; + + if (Ut_DuiApplicationService::allowRegisterService) { + retVal = true; + Ut_DuiApplicationService::registeredService = name; + } else { + if (Ut_DuiApplicationService::allowRegisterService2) { + if (Ut_DuiApplicationService::failRegisterServiceCounter < + Ut_DuiApplicationService::failRegisterServiceTimes) { + Ut_DuiApplicationService::failRegisterServiceCounter++; + } else { + retVal = true; + Ut_DuiApplicationService::registeredService = name; + Ut_DuiApplicationService::failRegisterServiceCounter = 0; + } + } + } + + qDebug() << "DuiApplicationServicePrivate::registerService() returning " << retVal; + return retVal; +} + +void DuiApplicationServicePrivate::registerObject(const QString &path, QObject *object) +{ + Q_UNUSED(path); + Q_UNUSED(object); +} + +void DuiApplicationServicePrivate::unregisterObject(const QString &path) +{ + Q_UNUSED(path); +} + +void Ut_DuiApplicationService::init() +{ + m_subject = new DuiApplicationService("ut_duiapplicationservice"); + //new DuiComponentData( m_subject ); + isPrestartedReturnValue = false; + isLazyShutdownReturnValue = false; +} + +void Ut_DuiApplicationService::cleanup() +{ + delete m_subject; +} + +void Ut_DuiApplicationService::initTestCase() +{ + argc = 2; + argv[0] = strdup("ut_duiapplicationservice"); + argv[1] = strdup("-software"); + appName = QString(argv[0]); + for (int arg = 0; arg < argc; ++arg) { + arguments << argv[ arg ]; + } +} + +void Ut_DuiApplicationService::cleanupTestCase() +{ + for (int i = 0; i < argc; i++) { + free(argv[i]); + } +} + +void Ut_DuiApplicationService::plainLaunch() +{ + Ut_DuiApplicationService::allowRegisterService = true; + Ut_DuiApplicationService::allowRegisterService2 = true; + windowRaised = false; + windowActivated = false; + + // without window + activeWindowSet = false; + m_subject->launch(); + QCOMPARE(Ut_DuiApplicationService::windowRaised, false); + QCOMPARE(Ut_DuiApplicationService::windowActivated, false); + + // with window + activeWindowSet = true; + m_subject->launch(); + QCOMPARE(Ut_DuiApplicationService::windowRaised, true); + QCOMPARE(Ut_DuiApplicationService::windowActivated, true); +} + +void Ut_DuiApplicationService::launchWithRegistrationFailure() +{ + Ut_DuiApplicationService::allowRegisterService = false; + Ut_DuiApplicationService::allowRegisterService2 = false; + windowRaised = false; + windowActivated = false; + + // without window + activeWindowSet = false; + m_subject->launch(); + QCOMPARE(Ut_DuiApplicationService::windowRaised, false); + QCOMPARE(Ut_DuiApplicationService::windowActivated, false); + + // with window + activeWindowSet = true; + m_subject->launch(); + QCOMPARE(Ut_DuiApplicationService::windowRaised, true); + QCOMPARE(Ut_DuiApplicationService::windowActivated, true); +} + +void Ut_DuiApplicationService::launchAnotherWithQProcess() +{ + Ut_DuiApplicationService::allowRegisterService = true; + Ut_DuiApplicationService::allowRegisterService2 = true; + + // DuiApplication constructor calls this once + m_subject->launchAnotherWithQProcess(); + QCOMPARE(Ut_DuiApplicationService::programArgsCorrect, false); + QCOMPARE(Ut_DuiApplicationService::programStarted, false); + + // another called from launch + m_subject->launchAnotherWithQProcess(); + QCOMPARE(Ut_DuiApplicationService::programArgsCorrect, true); + QCOMPARE(Ut_DuiApplicationService::programStarted, true); +} + +void Ut_DuiApplicationService::incrementAndRegisterOneFail() +{ + Ut_DuiApplicationService::allowRegisterService = false; + Ut_DuiApplicationService::allowRegisterService2 = true; + Ut_DuiApplicationService::failRegisterServiceTimes = 1; + + m_subject->incrementAndRegister(); + QCOMPARE(Ut_DuiApplicationService::registeredService, QString("com.nokia.ut_duiapplicationservice2")); +} + +void Ut_DuiApplicationService::incrementAndRegisterTenFail() +{ + Ut_DuiApplicationService::allowRegisterService = false; + Ut_DuiApplicationService::allowRegisterService2 = true; + Ut_DuiApplicationService::failRegisterServiceTimes = 10; + + m_subject->incrementAndRegister(); + QCOMPARE(Ut_DuiApplicationService::registeredService, QString("com.nokia.ut_duiapplicationservice11")); +} + +void Ut_DuiApplicationService::misc() +{ + Ut_DuiApplicationService::allowRegisterService = false; + windowRaised = false; + windowActivated = false; + + m_subject->close(); + m_subject->exit(); +} + +void Ut_DuiApplicationService::prestartLaunch() +{ + isPrestartedReturnValue = true; + prestartReleased = false; + m_subject->launch(); + QVERIFY(prestartReleased == true); +} + +void Ut_DuiApplicationService::prestartLaunchNoPrestart() +{ + prestartReleased = false; + m_subject->launch(); + QVERIFY(prestartReleased == false); +} + +void Ut_DuiApplicationService::prestartCloseLazyShutdown() +{ + prestartRestored = false; + isLazyShutdownReturnValue = true; + m_subject->close(); + QVERIFY(prestartRestored == true); +} + +void Ut_DuiApplicationService::prestartCloseNoLazyShutdown() +{ + prestartRestored = false; + m_subject->close(); + QVERIFY(prestartRestored == false); +} + +void Ut_DuiApplicationService::prestartExitLazyShutdown() +{ + prestartRestored = false; + isLazyShutdownReturnValue = true; + m_subject->exit(); + QVERIFY(prestartRestored == true); +} + +void Ut_DuiApplicationService::prestartExitNoLazyShutdown() +{ + prestartRestored = false; + m_subject->exit(); + QVERIFY(prestartRestored == false); +} + + +QTEST_MAIN(Ut_DuiApplicationService) diff --git a/tests/ut_duiapplicationservice/ut_duiapplicationservice.h b/tests/ut_duiapplicationservice/ut_duiapplicationservice.h new file mode 100644 index 000000000..f8345cbf4 --- /dev/null +++ b/tests/ut_duiapplicationservice/ut_duiapplicationservice.h @@ -0,0 +1,86 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIAPPLICATIONSERVICE_H +#define UT_DUIAPPLICATIONSERVICE_H + +#include +#include + +#include + +Q_DECLARE_METATYPE(DuiApplicationService *); + +class DuiApplication; + +#define MAX_PARAMS 10 + +class Ut_DuiApplicationService : public QObject +{ + Q_OBJECT + +public: + // mock control/report variables + static bool activeWindowSet; + static bool windowRaised; + static bool windowActivated; + static bool windowShown; + static bool windowClosed; + static bool applicationExited; + static bool allowRegisterService; + static bool allowRegisterService2; + static int failRegisterServiceTimes; + static int failRegisterServiceCounter; + static bool programStarted; + static bool programArgsCorrect; + static bool prestartReleased; + static bool prestartRestored; + static bool isPrestartedReturnValue; + static bool isLazyShutdownReturnValue; + static QString registeredService; + static char *argv[MAX_PARAMS]; + static int argc; + static QString appName; + static QStringList arguments; + +private slots: + void init(); + void cleanup(); + void initTestCase(); + void cleanupTestCase(); + void plainLaunch(); + void incrementAndRegisterTenFail(); + void launchWithRegistrationFailure(); + void launchAnotherWithQProcess(); + void incrementAndRegisterOneFail(); + void misc(); + void prestartLaunch(); + void prestartLaunchNoPrestart(); + void prestartCloseLazyShutdown(); + void prestartCloseNoLazyShutdown(); + void prestartExitLazyShutdown(); + void prestartExitNoLazyShutdown(); + +private: + void buildApp(); + DuiApplicationService *m_subject; + DuiApplication *m_duiApp; +}; + +#endif diff --git a/tests/ut_duiapplicationservice/ut_duiapplicationservice.pro b/tests/ut_duiapplicationservice/ut_duiapplicationservice.pro new file mode 100644 index 000000000..23862f1d4 --- /dev/null +++ b/tests/ut_duiapplicationservice/ut_duiapplicationservice.pro @@ -0,0 +1,13 @@ +include(../common_top.pri) +INCLUDEPATH += $$DUISRCDIR/core +TARGET = ut_duiapplicationservice + +# unit test and unit +SOURCES += \ + ut_duiapplicationservice.cpp \ + +# unit test and unit +HEADERS += \ + ut_duiapplicationservice.h \ + +include(../common_bot.pri) diff --git a/tests/ut_duiapplicationwindow/.gitignore b/tests/ut_duiapplicationwindow/.gitignore new file mode 100644 index 000000000..e48eddf7e --- /dev/null +++ b/tests/ut_duiapplicationwindow/.gitignore @@ -0,0 +1 @@ +ut_duiapplicationwindow diff --git a/tests/ut_duiapplicationwindow/ut_duiapplicationwindow.cpp b/tests/ut_duiapplicationwindow/ut_duiapplicationwindow.cpp new file mode 100644 index 000000000..fc897ace4 --- /dev/null +++ b/tests/ut_duiapplicationwindow/ut_duiapplicationwindow.cpp @@ -0,0 +1,314 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duiapplicationwindow.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +const DuiWidgetView *DuiWidgetController::view() const +{ + return 0; +} + +// DuiDeviceProfile stubs +class DuiDeviceProfile +{ +public: + static DuiDeviceProfile *instance(); + QSize resolution() const; +}; + +DuiDeviceProfile *DuiDeviceProfile::instance() +{ + static DuiDeviceProfile p; + return &p; +} + +QSize DuiDeviceProfile::resolution() const +{ + return QSize(1000, 500); +} + +// DuiComponentData stubs +DuiWindow *gActiveWindow = 0; +bool DuiComponentData::softwareRendering() +{ + return true; +} + +bool DuiComponentData::fullScreen() +{ + return false; +} + +void DuiComponentData::setActiveWindow(DuiWindow *window) +{ + gActiveWindow = window; +} + +DuiWindow *DuiComponentData::activeWindow() +{ + return gActiveWindow; +} + +DuiApplicationWindow *DuiComponentData::activeApplicationWindow() +{ + return qobject_cast(gActiveWindow); +} + +void DuiComponentData::registerWindow(DuiWindow *window) +{ + if (gActiveWindow == 0) + setActiveWindow(window); +} + +void DuiComponentData::unregisterWindow(DuiWindow *window) +{ + if (gActiveWindow == window) + setActiveWindow(0); +} + +// WARNING: This restricts the unit test to the support one window only +QList DuiComponentData::windows() +{ + QList list; + if (gActiveWindow) + list << gActiveWindow; + return list; +} + +// Just a dummy stub to avoid need for real DuiComponentData instance +// because of this method +void DuiComponentData::setPrestarted(bool) +{} + +//DuiApplication stubs + +static Dui::PrestartMode fakeMode = Dui::LazyShutdown; + +bool Ut_DuiApplicationWindow::m_prestartRestored = false; + +bool DuiApplication::isPrestarted() +{ + if ((fakeMode == Dui::LazyShutdown) || (fakeMode == Dui::TerminateOnClose)) + return true; + + return false; +} + +void DuiApplication::setPrestartMode(Dui::PrestartMode mode) +{ + fakeMode = mode; + return; +} + +Dui::PrestartMode DuiApplication::prestartMode() +{ + return fakeMode; +} + +// Test class implementation + +void Ut_DuiApplicationWindow::initTestCase() +{ + qRegisterMetaType("DuiApplicationPage*"); +} + +void Ut_DuiApplicationWindow::cleanupTestCase() +{ +} + +void Ut_DuiApplicationWindow::init() +{ + m_subject = new DuiApplicationWindow; +} + +void Ut_DuiApplicationWindow::cleanup() +{ + delete m_subject; + m_subject = 0; +} + +// It's not possible to owerwrite inlined QWidget::show, setVisible is used instead +bool Ut_DuiApplicationWindow::m_windowShown = false; +void QWidget::setVisible(bool visible) +{ + Ut_DuiApplicationWindow::m_windowShown = visible; +} + +bool Ut_DuiApplicationWindow::m_windowClosed = false; +bool QWidget::close() +{ + Ut_DuiApplicationWindow::m_windowClosed = true; + return true; +} + +void Ut_DuiApplicationWindow::testConstructorWithoutScene() +{ + QVERIFY(m_subject->scene()); +} + +void Ut_DuiApplicationWindow::testConstructorWithScene() +{ + DuiScene *scene = new DuiScene; + DuiApplicationWindow *window = new DuiApplicationWindow(scene); + QCOMPARE((quintptr) window->scene(), (quintptr) scene); + delete window; +} + +void Ut_DuiApplicationWindow::testIsOnDisplay() +{ + m_subject = DuiApplication::activeApplicationWindow(); + + QPointer page1 = new DuiApplicationPage; + QPointer page2 = new DuiApplicationPage; + + QVERIFY(page1->isOnDisplay() == false); + QVERIFY(page2->isOnDisplay() == false); + + // Window is not visible => page should not become visible + page2->appearNow(); + QVERIFY(page1->isOnDisplay() == false); + QVERIFY(page2->isOnDisplay() == false); + + // To be revisited: how these could be unit-tested + // (event->viewRect().intersects(sceneBoundingRect()) + // does not return meaningful values in this. + + page1->disappear(); + page1->disappear(); + QVERIFY(page1->isOnDisplay() == false); + QVERIFY(page2->isOnDisplay() == false); +} + +void Ut_DuiApplicationWindow::testPrestartNoPrestart() +{ + DuiApplication::setPrestartMode(Dui::NoPrestart); + m_windowShown = false; + m_subject->show(); + QCOMPARE(m_windowShown, true); + m_prestartRestored = false; + m_windowClosed = false; + m_subject->close(); + QCOMPARE(m_prestartRestored, false); + QCOMPARE(m_windowClosed, true); +} + +void Ut_DuiApplicationWindow::testPrestartTerminateOnClose() +{ + DuiApplication::setPrestartMode(Dui::TerminateOnClose); + m_windowShown = false; + m_subject->show(); + QCOMPARE(m_windowShown, false); + m_prestartRestored = false; + m_windowClosed = false; + m_subject->close(); + QCOMPARE(m_prestartRestored, false); + QCOMPARE(m_windowClosed, true); +} + +void Ut_DuiApplicationWindow::testPrestartLazyShutdown() +{ + DuiApplication::setPrestartMode(Dui::LazyShutdown); + m_windowShown = false; + m_subject->show(); + QCOMPARE(Ut_DuiApplicationWindow::m_windowShown, false); + m_prestartRestored = false; + m_windowClosed = false; + m_subject->close(); + // For some reason the DuiApplicationPrivate::restorePrestart() + // stub never gets called. + // QCOMPARE( m_prestartRestored, true ); + QCOMPARE(Ut_DuiApplicationWindow::m_windowClosed, false); +} + +void Ut_DuiApplicationWindow::testWindowActivate() +{ + QVERIFY(DuiApplication::activeApplicationWindow() == m_subject); + + DuiApplicationWindow *appWin = new DuiApplicationWindow; + QVERIFY(DuiApplication::activeApplicationWindow() == m_subject); + + QEvent activate(QEvent::WindowActivate); + + qApp->sendEvent(appWin, &activate); + QVERIFY(DuiApplication::activeApplicationWindow() == appWin); + + delete appWin; + QVERIFY(DuiApplication::activeApplicationWindow() == 0); + + qApp->sendEvent(m_subject, &activate); + QVERIFY(DuiApplication::activeApplicationWindow() == m_subject); + +} + +void Ut_DuiApplicationWindow::testPageChanged() +{ + QSignalSpy spy(m_subject, SIGNAL(pageChanged(DuiApplicationPage *))); + DuiApplicationPage *page = new DuiApplicationPage; + DuiApplicationPage *page2 = new DuiApplicationPage; + page->appearNow(m_subject); + page2->appearNow(m_subject); + + QCOMPARE(spy.count(), 2); + QCOMPARE(spy.at(0).at(0).value(), page); + QCOMPARE(spy.at(1).at(0).value(), page2); + + delete page; + delete page2; +} + +void Ut_DuiApplicationWindow::testDeleteOnClose() +{ + qDebug() << "if the test crashes here, " + << "Qt::WA_DeleteOnClose is broken for DuiApplicationWindow"; + DuiApplicationWindow *win = new DuiApplicationWindow; + win->setAttribute(Qt::WA_DeleteOnClose, true); + win->show(); + win->close(); +} + +void Ut_DuiApplicationWindow::testDisplayExitedOnClose() +{ + m_subject->show(); + QSignalSpy spy(m_subject, SIGNAL(exitedDisplay())); + m_subject->close(); + QCOMPARE(spy.count(), 1); +} + +void Ut_DuiApplicationWindow::testDisplayExitedOnCloseLazyShutdownApp() +{ + DuiApplication::setPrestartMode(Dui::LazyShutdown); + m_subject->show(); + QSignalSpy spy(m_subject, SIGNAL(exitedDisplay())); + m_subject->close(); + QCOMPARE(spy.count(), 1); +} + + +QTEST_MAIN(Ut_DuiApplicationWindow) diff --git a/tests/ut_duiapplicationwindow/ut_duiapplicationwindow.h b/tests/ut_duiapplicationwindow/ut_duiapplicationwindow.h new file mode 100644 index 000000000..c1a46da36 --- /dev/null +++ b/tests/ut_duiapplicationwindow/ut_duiapplicationwindow.h @@ -0,0 +1,68 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIAPPLICATIONWINDOW +#define UT_DUIAPPLICATIONWINDOW + +#include +#include +#include + +class DuiApplicationWindow; +class DuiApplicationPage; + +class Ut_DuiApplicationWindow : public QObject +{ + Q_OBJECT + +public: + static bool m_windowShown; + static bool m_windowClosed; + static bool m_prestartRestored; + +private slots: + void init(); // Executed before each test function + void cleanup(); // Executed after each test function + void initTestCase(); // Executed before all + void cleanupTestCase(); // Executed after all tests have been run + + void testConstructorWithoutScene(); + void testConstructorWithScene(); + void testPageChanged(); + void testWindowActivate(); + void testDeleteOnClose(); + + void testIsOnDisplay(); + void testPrestartNoPrestart(); + void testPrestartTerminateOnClose(); + void testPrestartLazyShutdown(); + + void testDisplayExitedOnClose(); + void testDisplayExitedOnCloseLazyShutdownApp(); + +private: + DuiApplicationWindow *m_subject; + +}; + +Q_DECLARE_METATYPE(DuiApplicationPage *); +Q_DECLARE_METATYPE(Dui::OrientationAngle); +Q_DECLARE_METATYPE(Dui::Orientation); + +#endif diff --git a/tests/ut_duiapplicationwindow/ut_duiapplicationwindow.pro b/tests/ut_duiapplicationwindow/ut_duiapplicationwindow.pro new file mode 100644 index 000000000..9a07cbac9 --- /dev/null +++ b/tests/ut_duiapplicationwindow/ut_duiapplicationwindow.pro @@ -0,0 +1,12 @@ +include(../common_top.pri) + +TARGET = ut_duiapplicationwindow +INCLUDEPATH += $$DUISRCDIR/core $$DUISRCDIR/scene $$DUISRCDIR/widgets + +SOURCES += \ + ut_duiapplicationwindow.cpp \ + +HEADERS += \ + ut_duiapplicationwindow.h + +include(../common_bot.pri) diff --git a/tests/ut_duibutton/.gitignore b/tests/ut_duibutton/.gitignore new file mode 100644 index 000000000..9ddf556ee --- /dev/null +++ b/tests/ut_duibutton/.gitignore @@ -0,0 +1 @@ +ut_duibutton diff --git a/tests/ut_duibutton/ut_duibutton.cpp b/tests/ut_duibutton/ut_duibutton.cpp new file mode 100644 index 000000000..f21f360b2 --- /dev/null +++ b/tests/ut_duibutton/ut_duibutton.cpp @@ -0,0 +1,243 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include +#include "duibutton_p.h" +#include +#include "views/duibuttonview_p.h" +#include "ut_duibutton.h" +#include "duiapplication.h" +#include "duicancelevent.h" +#include + +void Ut_DuiButton::init() +{ + m_subject = new DuiButton(); + QApplication::processEvents(QEventLoop::WaitForMoreEvents, 10); + m_tmp = 0; +} + +void Ut_DuiButton::cleanup() +{ + delete m_subject; + m_subject = 0; +} +DuiApplication *app; + +void Ut_DuiButton::initTestCase() +{ + static int argc = 1; + static char *app_name[1] = { (char *) "./ut_duibutton" }; + app = new DuiApplication(argc, app_name); +} + +void Ut_DuiButton::cleanupTestCase() +{ + delete app; +} + +void Ut_DuiButton::testConstructionAndDestruction() +{ + QString ButtonText("NewButton"); + m_tmp = new DuiButton(ButtonText); + QCOMPARE(m_tmp->text(), ButtonText); + delete m_tmp; + + QString IconId("Icon-home"); + m_tmp = new DuiButton(IconId, ButtonText); + QCOMPARE(m_tmp->text(), ButtonText); + QCOMPARE(m_tmp->iconID(), IconId); + delete m_tmp; +} + +void Ut_DuiButton::testTextVisible() +{ + m_subject->setTextVisible(false); + QVERIFY(m_subject->isTextVisible() == false); + m_subject->setTextVisible(true); + QVERIFY(m_subject->isTextVisible() == true); +} + +void Ut_DuiButton::testIconVisible() +{ + m_subject->setIconVisible(false); + QVERIFY(m_subject->isIconVisible() == false); + m_subject->setIconVisible(true); + QVERIFY(m_subject->isIconVisible() == true); +} + +void Ut_DuiButton::testCheckable() +{ + m_subject->setCheckable(false); + QVERIFY(m_subject->isCheckable() == false); + m_subject->setCheckable(true); + QVERIFY(m_subject->isCheckable() == true); + + + QSignalSpy toggledSpy(m_subject, SIGNAL(toggled(bool))); + + m_subject->setCheckable(true); + m_subject->setChecked(true); + QVERIFY(m_subject->isChecked() == true); + QCOMPARE(toggledSpy.count(), 1); + QVERIFY(toggledSpy.takeFirst().at(0).toBool() == true); + + m_subject->setChecked(false); + QCOMPARE(toggledSpy.count(), 1); + QVERIFY(toggledSpy.takeFirst().at(0).toBool() == false); + + + m_subject->setChecked(true); + m_subject->setCheckable(false); + QVERIFY(m_subject->isCheckable() == false); + QVERIFY(m_subject->isChecked() == false); +} + +void Ut_DuiButton::testPressedReleased() +{ + QSignalSpy pressedSpy(m_subject, SIGNAL(pressed())); + QSignalSpy releasedSpy(m_subject, SIGNAL(released())); + + m_subject->setDown(true); + QVERIFY(m_subject->isDown()); + QCOMPARE(pressedSpy.count(), 1); + + m_subject->setDown(false); + QVERIFY(!m_subject->isDown()); + QCOMPARE(releasedSpy.count(), 1); +} + +void Ut_DuiButton::testIconID() +{ + QString myIconID("myIconID"); + m_subject->setIconID(myIconID); + QCOMPARE(m_subject->iconID(), myIconID); +} + +void Ut_DuiButton::testToggledIconID() +{ + QString myToggledIconID("myToggledIconID"); + m_subject->setToggledIconID(myToggledIconID); + QCOMPARE(m_subject->toggledIconID(), myToggledIconID); +} + +void Ut_DuiButton::testText() +{ + QString myQString("testing setText()"); + m_subject->setText(myQString); + QCOMPARE(m_subject->text(), myQString); +} + +void Ut_DuiButton::setView() +{ + DuiButtonView *myButtonView = new DuiButtonView(m_subject); + //myButtonView->updateStyle(); + + m_subject->setView(myButtonView); + + // compare addresses + QCOMPARE(m_subject->view(), myButtonView); +} + +void Ut_DuiButton::click() +{ + QSignalSpy pressedSpy(m_subject, SIGNAL(pressed())); + QSignalSpy releasedSpy(m_subject, SIGNAL(released())); + QSignalSpy clickedSpy(m_subject, SIGNAL(clicked())); + + m_subject->click(); + QCOMPARE(pressedSpy.count(), 1); + QCOMPARE(releasedSpy.count(), 1); + QCOMPARE(clickedSpy.count(), 1); +} + +void Ut_DuiButton::toggle() +{ + m_subject->setCheckable(true); + m_subject->setChecked(true); + + QSignalSpy toggledSpy(m_subject, SIGNAL(toggled(bool))); + + // -> to false + m_subject->toggle(); + + QVERIFY(m_subject->isChecked() == false); + + // verify signal & the argument + QCOMPARE(toggledSpy.count(), 1); + QVERIFY(toggledSpy.takeFirst().at(0).toBool() == false); + + // -> to true + m_subject->toggle(); + QVERIFY(m_subject->isChecked() == true); + + // verify signal & the argument + QCOMPARE(toggledSpy.count(), 1); + QVERIFY(toggledSpy.takeFirst().at(0).toBool() == true); +} + +void Ut_DuiButton::testPressedCanceled() +{ + QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMousePress); + m_subject->mousePressEvent(&mouseEvent); + QVERIFY(m_subject->isDown() == true); + + QSignalSpy spy(m_subject, SIGNAL(clicked())); + DuiCancelEvent event; + m_subject->cancelEvent(&event); + + QCOMPARE(spy.count(), 0); + QVERIFY(m_subject->isDown() == false); +} + +void Ut_DuiButton::testGroup() +{ + DuiButtonGroup group; + + m_subject->setCheckable(true); + group.addButton(m_subject); + m_subject->setChecked(true); + m_subject->setChecked(false); + QVERIFY(m_subject->isChecked() == true); + delete m_subject; + m_subject = NULL; + QCOMPARE(group.buttons().count(), 0); +} + +/* + * Check that DuiButton doesn't change the model when + * it's passed on the constructor. + */ +void Ut_DuiButton::testConstructorWithModel() +{ + DuiButtonModel *model = new DuiButtonModel; + model->setText("foo"); + + DuiButton *button = new DuiButton(0, model); + + QCOMPARE(model->text(), QString("foo")); + QCOMPARE(button->text(), QString("foo")); + + delete button; + // model should have gone to heaven on DuiButton's destructor. +} + +QTEST_APPLESS_MAIN(Ut_DuiButton) diff --git a/tests/ut_duibutton/ut_duibutton.h b/tests/ut_duibutton/ut_duibutton.h new file mode 100644 index 000000000..d2a267a99 --- /dev/null +++ b/tests/ut_duibutton/ut_duibutton.h @@ -0,0 +1,61 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIBUTTON_H +#define UT_DUIBUTTON_H + +#include +#include + +#include + +Q_DECLARE_METATYPE(DuiButton *); + +class Ut_DuiButton : public QObject +{ + Q_OBJECT + +private slots: + void init(); + void cleanup(); + void initTestCase(); + void cleanupTestCase(); + + void testConstructionAndDestruction(); + void testIconID(); + void testToggledIconID(); + void testText(); + void testTextVisible(); + void testCheckable(); + void testIconVisible(); + void testPressedReleased(); + void testPressedCanceled(); + void testGroup(); + void testConstructorWithModel(); + + void setView(); + + void click(); + void toggle(); +private: + DuiButton *m_subject; + DuiButton *m_tmp; +}; + +#endif diff --git a/tests/ut_duibutton/ut_duibutton.pro b/tests/ut_duibutton/ut_duibutton.pro new file mode 100644 index 000000000..ea6b0c58e --- /dev/null +++ b/tests/ut_duibutton/ut_duibutton.pro @@ -0,0 +1,18 @@ +include(../common_top.pri) +INCLUDEPATH += $$DUISRCDIR/widgets $$DUISRCDIR/style + +TARGET = ut_duibutton + +# unit +TEST_SOURCES = \ +# $$DUISRCDIR/duibutton.cpp \ + +# unit test and unit +SOURCES += \ + ut_duibutton.cpp \ + +# unit test and unit +HEADERS += \ + ut_duibutton.h \ + +include(../common_bot.pri) diff --git a/tests/ut_duibuttongroup/.gitignore b/tests/ut_duibuttongroup/.gitignore new file mode 100644 index 000000000..e3c1befc2 --- /dev/null +++ b/tests/ut_duibuttongroup/.gitignore @@ -0,0 +1 @@ +ut_duibuttongroup diff --git a/tests/ut_duibuttongroup/ut_duibuttongroup.cpp b/tests/ut_duibuttongroup/ut_duibuttongroup.cpp new file mode 100644 index 000000000..375cda030 --- /dev/null +++ b/tests/ut_duibuttongroup/ut_duibuttongroup.cpp @@ -0,0 +1,462 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include + +#include +#include +#include +#include + +#include "ut_duibuttongroup.h" + +void Ut_DuiButtonGroup::init() +{ + m_subject = new DuiButtonGroup(); +} + +void Ut_DuiButtonGroup::cleanup() +{ + delete m_subject; + m_subject = 0; +} + +DuiApplication *app; + +void Ut_DuiButtonGroup::initTestCase() +{ + static int argc = 1; + static char *app_name[1] = { (char *) "./ut_duibuttongroup" }; + app = new DuiApplication(argc, app_name); +} + +void Ut_DuiButtonGroup::cleanupTestCase() +{ + delete app; +} + +void Ut_DuiButtonGroup::addButton() +{ + DuiButton b1; + + b1.setCheckable(true); + + QCOMPARE(m_subject->buttons().count(), 0); + + m_subject->addButton(&b1); + m_subject->addButton(&b1); + QCOMPARE(m_subject->buttons().count(), 1); + + m_subject->removeButton(&b1); + QCOMPARE(m_subject->buttons().count(), 0); + + m_subject->addButton(&b1, 10); + QCOMPARE(m_subject->buttons().count(), 1); + + m_subject->removeButton(&b1); + QCOMPARE(m_subject->buttons().count(), 0); + + m_subject->addButton(&b1, -1); + QCOMPARE(m_subject->buttons().count(), 1); +} + +void Ut_DuiButtonGroup::button() +{ + DuiButton b1; + b1.setCheckable(true); + m_subject->addButton(&b1, 10); + QVERIFY(m_subject->button(11) == 0); + QVERIFY(m_subject->button(10) == &b1); + + DuiButton b2; + DuiButton b3; + DuiButton b4; + DuiButton b5; + DuiButton b6; + + b2.setCheckable(true); + b3.setCheckable(true); + b4.setCheckable(true); + b5.setCheckable(true); + b6.setCheckable(true); + + m_subject->addButton(&b2, 10); + m_subject->addButton(&b3, 11); + m_subject->addButton(&b4, 12); + m_subject->addButton(&b5, 13); + m_subject->addButton(&b6, 14); + + QVERIFY(m_subject->button(10) != &b1); + QVERIFY(m_subject->button(10) == &b2); + QVERIFY(m_subject->button(14) == &b6); + + m_subject->removeButton(&b2); + QVERIFY(m_subject->button(10) == &b1); + + m_subject->removeButton(&b6); + QVERIFY(m_subject->button(14) == 0); + + m_subject->removeButton(&b1); + m_subject->removeButton(&b3); + m_subject->removeButton(&b4); + m_subject->removeButton(&b5); +} + +void Ut_DuiButtonGroup::buttons() +{ + const QList list = m_subject->buttons(); + QVERIFY(list.count() == 0); + + DuiButton b1; + DuiButton b2; + DuiButton b3; + DuiButton b4; + DuiButton b5; + DuiButton b6; + + b1.setCheckable(true); + b2.setCheckable(true); + b3.setCheckable(true); + b4.setCheckable(true); + b5.setCheckable(true); + b6.setCheckable(true); + + m_subject->addButton(&b1); + m_subject->addButton(&b2); + m_subject->addButton(&b3); + m_subject->addButton(&b4); + m_subject->addButton(&b5); + m_subject->addButton(&b6); + + const QList list1 = m_subject->buttons(); + QCOMPARE(list1.count(), 6); +} + +void Ut_DuiButtonGroup::checkedButton() +{ + DuiButton b1; + DuiButton b2; + DuiButton b3; + DuiButton b4; + DuiButton b5; + DuiButton b6; + + QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents, 10); + + b1.setCheckable(true); + b2.setCheckable(true); + b3.setCheckable(true); + b4.setCheckable(true); + b5.setCheckable(true); + + m_subject->addButton(&b1, 10); + m_subject->addButton(&b2, 10); + m_subject->addButton(&b3, 11); + m_subject->addButton(&b4, 12); + + QVERIFY(m_subject->checkedButton() == 0); + + b6.setCheckable(false); + b6.setChecked(true); + m_subject->addButton(&b6, 14); + QVERIFY(m_subject->checkedButton() == 0); + b6.setChecked(true); + QVERIFY(m_subject->checkedButton() == 0); + + b6.setCheckable(true); + b6.setChecked(true); + QVERIFY(m_subject->checkedButton() == &b6); + + m_subject->removeButton(&b2); + QVERIFY(m_subject->checkedButton() == &b6); + + b5.setChecked(true); + m_subject->addButton(&b5, 13); + QVERIFY(m_subject->checkedButton() == &b5); + + m_subject->removeButton(&b1); + m_subject->removeButton(&b2); + m_subject->removeButton(&b3); + m_subject->removeButton(&b4); + m_subject->removeButton(&b5); +} + +void Ut_DuiButtonGroup::checkedId() +{ + DuiButton b1; + DuiButton b2; + DuiButton b3; + DuiButton b4; + DuiButton b5; + DuiButton b6; + + b1.setCheckable(true); + b2.setCheckable(true); + b3.setCheckable(true); + b4.setCheckable(true); + b5.setCheckable(true); + b6.setCheckable(true); + + m_subject->addButton(&b1, 10); + m_subject->addButton(&b2, 10); + m_subject->addButton(&b3, 11); + m_subject->addButton(&b4, 12); + m_subject->addButton(&b5, 13); + + QCOMPARE(m_subject->checkedId(), -1); + + b6.setChecked(true); + m_subject->addButton(&b6, 14); + + QCOMPARE(m_subject->checkedId(), 14); +} + +void Ut_DuiButtonGroup::exclusive() +{ + DuiButton b1; + DuiButton b2; + QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents, 10); + b1.setCheckable(true); + b2.setCheckable(true); + + QVERIFY(m_subject->exclusive() == true); + m_subject->setExclusive(false); + m_subject->addButton(&b1, 1); + m_subject->addButton(&b2, 2); + b1.setChecked(true); + b2.setChecked(true); + + QVERIFY(b1.isChecked() == true); + QVERIFY(b2.isChecked() == true); + QVERIFY(m_subject->exclusive() == false); + + m_subject->removeButton(&b1); + m_subject->removeButton(&b2); + m_subject->setExclusive(true); + m_subject->addButton(&b1, 1); + m_subject->addButton(&b2, 2); + b1.setChecked(true); + b2.setChecked(true); + QVERIFY(b1.isChecked() == false); + QVERIFY(b2.isChecked() == true); + QVERIFY(m_subject->exclusive() == true); +} + +void Ut_DuiButtonGroup::switchModes() +{ + DuiButton b1; + DuiButton b2; + DuiButton b3; + QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents, 10); + b1.setCheckable(true); + b2.setCheckable(true); + b3.setCheckable(true); + + //Case: Add unchecked buttons to a group with non-exclusive + //mode, and then change the mode to exclusive. + //This should result in first button as checked. + m_subject->setExclusive(false); + b1.setChecked(false); + b2.setChecked(false); + m_subject->addButton(&b1, 1); + m_subject->addButton(&b2, 2); + m_subject->setExclusive(true); + + QVERIFY(b1.isChecked() == true); + QVERIFY(b2.isChecked() == false); + + //Case: make more than one button in non-exclusive + //mode as checked, and then change the mode to exclusive + //This should result in unchecking all the buttons + //except the first checked button. + m_subject->removeButton(&b1); + m_subject->removeButton(&b2); + m_subject->setExclusive(false); + m_subject->addButton(&b1, 1); + m_subject->addButton(&b2, 2); + m_subject->addButton(&b3, 3); + b1.setChecked(false); + b2.setChecked(true); + b3.setChecked(true); + m_subject->setExclusive(true); + + QVERIFY(b1.isChecked() == false); + QVERIFY(b2.isChecked() == true); + QVERIFY(b3.isChecked() == false); + + //Case: remove checked button in exclusive + //mode.This should result in first (checkable) button as checked. + m_subject->removeButton(&b1); + m_subject->removeButton(&b2); + m_subject->removeButton(&b3); + + m_subject->setExclusive(true); + b1.setChecked(false); + b2.setChecked(true); + b3.setChecked(false); + m_subject->addButton(&b1, 1); + m_subject->addButton(&b2, 2); + m_subject->addButton(&b3, 3); + + m_subject->removeButton(&b2); + + QVERIFY(b1.isChecked() == true); + QVERIFY(b3.isChecked() == false); + + //Case: non-checkable button made checked + m_subject->removeButton(&b1); + m_subject->removeButton(&b2); + m_subject->removeButton(&b3); + + b1.setCheckable(false); + m_subject->addButton(&b1, 1); + b1.model()->setChecked(true); +} + +void Ut_DuiButtonGroup::id() +{ + DuiButton b1; + DuiButton b2; + DuiButton b3; + DuiButton b4; + DuiButton b5; + DuiButton b6; + + b1.setCheckable(true); + b2.setCheckable(true); + b3.setCheckable(true); + b4.setCheckable(true); + b5.setCheckable(true); + b6.setCheckable(true); + + m_subject->addButton(&b1, 10); + m_subject->addButton(&b2, 10); + m_subject->addButton(&b3, 11); + m_subject->addButton(&b4, 12); + m_subject->addButton(&b5, 13); + + QCOMPARE(m_subject->id(&b1), 10); + QCOMPARE(m_subject->id(&b5), 13); + QCOMPARE(m_subject->id(&b4), 12); + QCOMPARE(m_subject->id(&b3), 11); + QCOMPARE(m_subject->id(&b2), 10); + QCOMPARE(m_subject->id(&b6), -1); + + m_subject->removeButton(&b5); + QCOMPARE(m_subject->id(&b5), -1); + +} + +void Ut_DuiButtonGroup::removeButton() +{ + DuiButton b1; + DuiButton b2; + DuiButton b3; + DuiButton b4; + DuiButton b5; + DuiButton b6; + + b1.setCheckable(true); + b2.setCheckable(true); + b3.setCheckable(true); + b4.setCheckable(true); + b5.setCheckable(true); + b6.setCheckable(true); + + QCOMPARE(m_subject->buttons().count(), 0); + + m_subject->addButton(&b1, 10); + m_subject->addButton(&b2, 10); + m_subject->addButton(&b3, 11); + m_subject->addButton(&b4, 12); + m_subject->addButton(&b5, 13); + m_subject->addButton(&b6, 14); + + QCOMPARE(m_subject->buttons().count(), 6); + m_subject->removeButton(&b1); + QCOMPARE(m_subject->buttons().count(), 5); + + m_subject->removeButton(&b2); + m_subject->removeButton(&b3); + m_subject->removeButton(&b4); + m_subject->removeButton(&b5); + m_subject->removeButton(&b6); + + QCOMPARE(m_subject->buttons().count(), 0); +} + +void Ut_DuiButtonGroup::setId() +{ + DuiButton b1; + DuiButton b2; + DuiButton b3; + + b1.setCheckable(true); + b2.setCheckable(true); + b3.setCheckable(true); + + m_subject->setId(&b1, 10); + + m_subject->addButton(&b1); + m_subject->addButton(&b2); + m_subject->addButton(&b3); + + m_subject->setId(&b1, 10); + m_subject->setId(&b2, 10); + m_subject->setId(&b3, 11); + m_subject->setId(&b1, -1); + + QCOMPARE(m_subject->id(&b2), 10); + QCOMPARE(m_subject->id(&b1), 10); + QCOMPARE(m_subject->id(&b3), 11); + +} + +void Ut_DuiButtonGroup::buttonPressReleaseClick() +{ + DuiButton b1; + + QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents, 10); + + QSignalSpy buttonPressedSpy(m_subject, SIGNAL(buttonPressed(DuiButton *))); + QSignalSpy buttonPressedIdSpy(m_subject, SIGNAL(buttonPressed(int))); + QSignalSpy buttonReleasedSpy(m_subject, SIGNAL(buttonReleased(DuiButton *))); + QSignalSpy buttonReleasedIdSpy(m_subject, SIGNAL(buttonReleased(int))); + QSignalSpy buttonClickedSpy(m_subject, SIGNAL(buttonClicked(DuiButton *))); + QSignalSpy buttonClickedIdSpy(m_subject, SIGNAL(buttonClicked(int))); + + b1.setCheckable(true); + m_subject->addButton(&b1, 1); + b1.setDown(true); + + QCOMPARE(buttonPressedSpy.count(), 1); + QCOMPARE(buttonPressedIdSpy.count(), 1); + + b1.setDown(false); + QCOMPARE(buttonReleasedSpy.count(), 1); + QCOMPARE(buttonReleasedIdSpy.count(), 1); + + b1.click(); + QCOMPARE(buttonClickedSpy.count(), 1); + QCOMPARE(buttonClickedIdSpy.count(), 1); +} + + +QTEST_APPLESS_MAIN(Ut_DuiButtonGroup) diff --git a/tests/ut_duibuttongroup/ut_duibuttongroup.h b/tests/ut_duibuttongroup/ut_duibuttongroup.h new file mode 100644 index 000000000..774722953 --- /dev/null +++ b/tests/ut_duibuttongroup/ut_duibuttongroup.h @@ -0,0 +1,67 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIBUTTONGROUP_H +#define UT_DUIBUTTONGROUP_H + +#include +#include + +#include + +Q_DECLARE_METATYPE(DuiButtonGroup *); +Q_DECLARE_METATYPE(DuiButton *); + +class Ut_DuiButtonGroup : public QObject +{ + Q_OBJECT + +private slots: + void init(); + void cleanup(); + void initTestCase(); + void cleanupTestCase(); + + void addButton(); + + void button(); + + void buttons(); + + void checkedButton(); + + void checkedId(); + + void exclusive(); + + void switchModes(); + + void id(); + + void removeButton(); + + void setId(); + + void buttonPressReleaseClick(); + +private: + DuiButtonGroup *m_subject; +}; + +#endif diff --git a/tests/ut_duibuttongroup/ut_duibuttongroup.pro b/tests/ut_duibuttongroup/ut_duibuttongroup.pro new file mode 100644 index 000000000..6aadb8eee --- /dev/null +++ b/tests/ut_duibuttongroup/ut_duibuttongroup.pro @@ -0,0 +1,14 @@ +include(../common_top.pri) +INCLUDEPATH += $$DUISRCDIR/widgets + +TARGET = ut_duibuttongroup + +# unit test and unit +SOURCES += \ + ut_duibuttongroup.cpp \ + +# unit test and unit +HEADERS += \ + ut_duibuttongroup.h \ + +include(../common_bot.pri) diff --git a/tests/ut_duibuttoniconview/.gitignore b/tests/ut_duibuttoniconview/.gitignore new file mode 100644 index 000000000..8640f87ab --- /dev/null +++ b/tests/ut_duibuttoniconview/.gitignore @@ -0,0 +1 @@ +ut_duibuttoniconview diff --git a/tests/ut_duibuttonview/.gitignore b/tests/ut_duibuttonview/.gitignore new file mode 100644 index 000000000..47f987f64 --- /dev/null +++ b/tests/ut_duibuttonview/.gitignore @@ -0,0 +1 @@ +ut_duibuttonview diff --git a/tests/ut_duibuttonview/duitheme.cpp b/tests/ut_duibuttonview/duitheme.cpp new file mode 100644 index 000000000..dc99334df --- /dev/null +++ b/tests/ut_duibuttonview/duitheme.cpp @@ -0,0 +1,63 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include +#include + +#include +#include "ut_duibuttonview.h" // for themePixmap + +DuiTheme::DuiTheme() +{ +} + +DuiTheme::~DuiTheme() +{ +} + +DuiTheme *DuiTheme::instance() +{ + static DuiTheme singleton; + return &singleton; +} + +QPixmap *DuiTheme::pixmap(const QString &name, int width, int height) +{ + Q_UNUSED(name); + QPixmap *retVal = 0; + + if (!DuiButtonViewTest::themePixmap.contains(name)) + DuiButtonViewTest::themePixmap[ name ] = new QPixmap(width, height); + + retVal = DuiButtonViewTest::themePixmap[ name ]; + + return retVal; +} + +QPixmap *DuiTheme::pixmap(const QString &name, const QSizeF &size) +{ + return pixmap(name, (int)size.width(), (int)size.height()); +} + +QPixmap *DuiTheme::pixmap(const QString &name, const QSize &size) +{ + return pixmap(name, size.width(), size.height()); +} diff --git a/tests/ut_duibuttonview/ut_duibuttonview.cpp b/tests/ut_duibuttonview/ut_duibuttonview.cpp new file mode 100644 index 000000000..865a65094 --- /dev/null +++ b/tests/ut_duibuttonview/ut_duibuttonview.cpp @@ -0,0 +1,325 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include "ut_duibuttonview.h" +#include "duiapplication.h" + +#include "duicancelevent.h" + +DuiApplication *app; + +void Ut_DuiButtonView::initTestCase() +{ + static int argc = 1; + static char *app_name[1] = { (char *) "./ut_duibuttonview" }; + app = new DuiApplication(argc, app_name); + + m_button = new DuiButton(); + m_subject = new DuiButtonIconView(m_button); + m_button->setView(m_subject); +} + +void Ut_DuiButtonView::cleanupTestCase() +{ + delete m_button; + m_button = 0; + + delete app; +} + +void Ut_DuiButtonView::testDrawText_data() +{ + QTest::addColumn("font"); + QTest::addColumn("textColor"); + QTest::addColumn("horizontalTextAlign"); + QTest::addColumn("verticalTextAlign"); + QTest::addColumn("textMarginLeft"); + QTest::addColumn("textMarginRight"); + QTest::addColumn("textMarginTop"); + QTest::addColumn("textMarginBottom"); + + QTest::newRow("testDrawText1") << QFont() << QColor(255, 255, 255) << (int)Qt::AlignLeft << (int)Qt::AlignTop << 0 << 0 << 0 << 0; + //QTest::newRow("testDrawText2") << QFont() << QColor(255,255,255) << Qt::AlignLeft << Qt::AlignTop << 0 << 0 << 0 << 0; + //QTest::newRow("testDrawText3") << QFont() << QColor(255,255,255) << Qt::AlignLeft << Qt::AlignTop << 0 << 0 << 0 << 0; + //QTest::newRow("testDrawText4") << QFont() << QColor(255,255,255) << Qt::AlignLeft << Qt::AlignTop << 0 << 0 << 0 << 0; +} + +void Ut_DuiButtonView::testDrawText() +{ + QFETCH(QFont, font); + QFETCH(QColor, textColor); + QFETCH(int, horizontalTextAlign); + QFETCH(int, verticalTextAlign); + QFETCH(int, textMarginLeft); + QFETCH(int, textMarginRight); + QFETCH(int, textMarginTop); + QFETCH(int, textMarginBottom); + + + m_button->setTextVisible(true); + m_button->setIconVisible(false); + m_button->setText("test1"); + + QRectF iconRect, textRect; + + QRectF rect = QRectF(0, 0, 200, 100); + m_button->setGeometry(rect); + + int buttonWidth = m_button->size().width(); + int buttonHeight = m_button->size().height(); + + DuiButtonStyle *s = (DuiButtonStyle *)m_subject->style().operator->(); + + s->setFont(font); + s->setTextColor(textColor); + s->setHorizontalTextAlign((Qt::Alignment)horizontalTextAlign); + s->setVerticalTextAlign((Qt::Alignment)verticalTextAlign); + s->setTextMarginLeft(textMarginLeft); + s->setTextMarginRight(textMarginRight); + s->setTextMarginTop(textMarginTop); + s->setTextMarginBottom(textMarginBottom); + m_subject->applyStyle(); + + QPixmap pm(QSize(buttonWidth, buttonHeight)); + QPainter p(&pm); + m_subject->drawContents(&p, NULL); +} + +void Ut_DuiButtonView::testDrawIcon_data() +{ + QTest::addColumn("iconAlign"); + QTest::addColumn("icon"); + QTest::addColumn("toggledIcon"); + QTest::addColumn("iconSize"); + QTest::addColumn("checkable"); + + + QTest::newRow("testDrawIcon1") << (int)Qt::AlignLeft << "Icon-close" << "Icon-close" << QSize(16, 16) << false; + QTest::newRow("testDrawIcon2") << (int)Qt::AlignRight << "Icon-close" << "Icon-close" << QSize(32, 32) << true; + QTest::newRow("testDrawIcon3") << (int)Qt::AlignBottom << "Icon-close" << "Icon-close" << QSize(64, 64) << false; + QTest::newRow("testDrawIcon4") << (int)Qt::AlignTop << "Icon-close" << "Icon-close" << QSize(128, 128) << true; +} + +void Ut_DuiButtonView::testDrawIcon() +{ + QFETCH(int, iconAlign); + QFETCH(QString, icon); + QFETCH(QString, toggledIcon); + QFETCH(QSize, iconSize); + QFETCH(bool, checkable); + + m_button->setTextVisible(false); + m_button->setIconVisible(true); + m_button->setCheckable(checkable); + m_button->setIconID(icon); + m_button->setToggledIconID(toggledIcon); + + QRectF iconRect, textRect; + + QRectF rect = QRectF(0, 0, 200, 100); + m_button->setGeometry(rect); + + int buttonWidth = m_button->size().width(); + int buttonHeight = m_button->size().height(); + + DuiButtonStyle *s = (DuiButtonStyle *)m_subject->style().operator->(); + + s->setIconAlign((Qt::Alignment)iconAlign); + s->setIconSize(iconSize); + s->setPreferredSize(QSize(-1, -1)); + m_subject->applyStyle(); + + QPixmap pm(QSize(buttonWidth, buttonHeight)); + QPainter p(&pm); + m_subject->drawContents(&p, NULL); + + m_button->model()->setDown(true); + m_subject->drawContents(&p, NULL); + m_button->model()->setDown(false); +} + +void Ut_DuiButtonView::testDrawIconText_data() +{ + QTest::addColumn("iconAlign"); + QTest::addColumn("icon"); + QTest::addColumn("toggledIcon"); + QTest::addColumn("iconSize"); + + QTest::newRow("testDrawIcon1") << (int)Qt::AlignLeft << "Icon-close" << "Icon-close" << QSize(16, 16); + QTest::newRow("testDrawIcon2") << (int)Qt::AlignRight << "Icon-close" << "Icon-close" << QSize(32, 32); + QTest::newRow("testDrawIcon3") << (int)Qt::AlignBottom << "Icon-close" << "Icon-close" << QSize(64, 64); + QTest::newRow("testDrawIcon4") << (int)Qt::AlignTop << "Icon-close" << "Icon-close" << QSize(128, 128); +} + +void Ut_DuiButtonView::testDrawIconText() +{ + QFETCH(int, iconAlign); + QFETCH(QString, icon); + QFETCH(QString, toggledIcon); + QFETCH(QSize, iconSize); + + m_button->setTextVisible(true); + m_button->setIconVisible(true); + m_button->setIconID(icon); + m_button->setToggledIconID(toggledIcon); + m_button->setText("button"); + + QRectF iconRect, textRect; + + QRectF rect = QRectF(0, 0, 200, 100); + m_button->setGeometry(rect); + + int buttonWidth = m_button->size().width(); + int buttonHeight = m_button->size().height(); + + DuiButtonStyle *s = (DuiButtonStyle *)m_subject->style().operator->(); + + s->setIconAlign((Qt::Alignment)iconAlign); + s->setIconSize(iconSize); + s->setPreferredSize(QSize(-1, -1)); + m_subject->applyStyle(); + + QPixmap pm(QSize(buttonWidth, buttonHeight)); + QPainter p(&pm); + m_button->paint(&p, NULL, NULL); + + m_button->model()->setDown(true); + m_button->paint(&p, NULL, NULL); + m_button->model()->setDown(false); +} + +void Ut_DuiButtonView::testMouseEvents() +{ + QRectF rect = QRectF(0, 0, 200, 100); + m_button->setGeometry(rect); + + //press + QGraphicsSceneMouseEvent pressEvent(QEvent::GraphicsSceneMousePress); + m_subject->mousePressEvent(&pressEvent); + QVERIFY(m_button->isDown() == true); + m_subject->mousePressEvent(&pressEvent); + + //release + QGraphicsSceneMouseEvent releaseEvent(QEvent::GraphicsSceneMouseRelease); + m_subject->mouseReleaseEvent(&releaseEvent); + QVERIFY(m_button->isDown() == false); + m_subject->mouseReleaseEvent(&releaseEvent); + + //cancel + m_subject->mousePressEvent(&pressEvent); + DuiCancelEvent event; + m_subject->cancelEvent(&event); + QVERIFY(m_button->isDown() == false); + m_subject->cancelEvent(&event); +} + +void Ut_DuiButtonView::testSwitchView() +{ + m_button->setCheckable(true); + m_button->setChecked(false); + m_button->setViewType(DuiButton::switchType); + QRectF rect = QRectF(0, 0, 200, 100); + m_button->setGeometry(rect); + + //draw unchecked + QImage img0 = captureImage(m_button); + + //draw checked + m_button->setChecked(true); + QImage img1 = captureImage(m_button); + + //draw checked down + m_button->setDown(true); + QImage img2 = captureImage(m_button); + + //draw down + m_button->setChecked(false); + QImage img3 = captureImage(m_button); + + m_button->setDown(false); + + /*QVERIFY(img0 != img1); + QVERIFY(img0 != img2); + QVERIFY(img0 == img3); + + QVERIFY(img1 == img2); + QVERIFY(img1 != img3); + + QVERIFY(img2 != img3);*/ +} + +void Ut_DuiButtonView::testCheckboxView() +{ + m_button->setCheckable(true); + m_button->setChecked(false); + m_button->setViewType(DuiButton::checkboxType); + QRectF rect = QRectF(0, 0, 200, 100); + m_button->setGeometry(rect); + + //draw unchecked + QImage img0 = captureImage(m_button); + + //draw checked + m_button->setChecked(true); + QImage img1 = captureImage(m_button); + + //draw checked down + m_button->setDown(true); + QImage img2 = captureImage(m_button); + + //draw down + m_button->setChecked(false); + QImage img3 = captureImage(m_button); + + m_button->setDown(false); + + /*QVERIFY(img0 != img1); + QVERIFY(img0 != img2); + QVERIFY(img0 != img3); + + QVERIFY(img1 != img2); + QVERIFY(img1 != img3); + + QVERIFY(img2 != img3);*/ +} + +QImage Ut_DuiButtonView::captureImage(DuiButton *button) +{ + QPixmap pixmap(button->size().toSize()); + pixmap.fill(Qt::transparent); + QPainter painter(&pixmap); + button->paint(&painter, NULL, NULL); + + return pixmap.toImage(); +} + +QTEST_APPLESS_MAIN(Ut_DuiButtonView) diff --git a/tests/ut_duibuttonview/ut_duibuttonview.h b/tests/ut_duibuttonview/ut_duibuttonview.h new file mode 100644 index 000000000..b74e600f7 --- /dev/null +++ b/tests/ut_duibuttonview/ut_duibuttonview.h @@ -0,0 +1,62 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIBUTTONVIEW_H +#define UT_DUIBUTTONVIEW_H + +#include +#include + +class DuiButton; +class DuiButtonView; + +class Ut_DuiButtonView : public QObject +{ + Q_OBJECT +public: + +private slots: + void initTestCase(); + void cleanupTestCase(); + + void testDrawText_data(); + void testDrawText(); + + void testDrawIcon_data(); + void testDrawIcon(); + + void testDrawIconText_data(); + void testDrawIconText(); + + void testMouseEvents(); + + void testSwitchView(); + void testCheckboxView(); + +private: + + QImage captureImage(DuiButton *button); + + + DuiButton *m_button; + DuiButtonView *m_subject; +}; + +#endif + diff --git a/tests/ut_duibuttonview/ut_duibuttonview.pro b/tests/ut_duibuttonview/ut_duibuttonview.pro new file mode 100644 index 000000000..81669be98 --- /dev/null +++ b/tests/ut_duibuttonview/ut_duibuttonview.pro @@ -0,0 +1,12 @@ + +include(../common_top.pri) +INCLUDEPATH += $$DUISRCDIR/widgets $$DUISRCDIR/style + +TARGET = ut_duibuttonview + +SOURCES += \ + ut_duibuttonview.cpp \ + +HEADERS += \ + ut_duibuttonview.h +include(../common_bot.pri) diff --git a/tests/ut_duicalendar/.gitignore b/tests/ut_duicalendar/.gitignore new file mode 100644 index 000000000..1bc5f8f8b --- /dev/null +++ b/tests/ut_duicalendar/.gitignore @@ -0,0 +1 @@ +ut_duicalendar diff --git a/tests/ut_duicalendar/ut_duicalendar.cpp b/tests/ut_duicalendar/ut_duicalendar.cpp new file mode 100644 index 000000000..2f05c9f80 --- /dev/null +++ b/tests/ut_duicalendar/ut_duicalendar.cpp @@ -0,0 +1,1643 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include +#include + +#include "ut_duicalendar.h" + +void Ut_DuiCalendar::initTestCase() +{ + static int argc = 0; + static char *argv[1] = { (char *) "" }; + qap = new QCoreApplication(argc, argv); + QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8")); + QProcess process; + process.start("sh -c \"dpkg -s libicu42 | grep Version | perl -pe 's/^Version:[[:space:]]*([^[[:space:]]+)$/$1/g'\""); + if (!process.waitForFinished()) { + qDebug() << "cannot run process to check libicu42 package version , exiting ..."; + exit(1); + } + icuPackageVersion = process.readAllStandardOutput(); + icuPackageVersion.replace("\n", ""); + qDebug() << "libicu42 package version is:" << icuPackageVersion; +} + +void Ut_DuiCalendar::cleanupTestCase() +{ + delete qap; +} + +void Ut_DuiCalendar::init() +{ + // most tests use the Finnish timezone: + DuiCalendar::setSystemTimeZone("Europe/Helsinki"); +} + +void Ut_DuiCalendar::cleanup() +{ +} + +void Ut_DuiCalendar::testDuiLocaleCalendar_data() +{ + QTest::addColumn("cal"); + QTest::newRow("default") << DuiLocale::DefaultCalendar; + QTest::newRow("gregorian") << DuiLocale::GregorianCalendar; + QTest::newRow("islamic") << DuiLocale::IslamicCalendar; + QTest::newRow("chinese") << DuiLocale::ChineseCalendar; + QTest::newRow("islamiccivil") << DuiLocale::IslamicCivilCalendar; + QTest::newRow("hebrew") << DuiLocale::HebrewCalendar; + QTest::newRow("japanese") << DuiLocale::JapaneseCalendar; + QTest::newRow("buddhist") << DuiLocale::BuddhistCalendar; + QTest::newRow("persian") << DuiLocale::PersianCalendar; + QTest::newRow("coptic") << DuiLocale::CopticCalendar; + QTest::newRow("ethiopian") << DuiLocale::EthiopicCalendar; +} + +void Ut_DuiCalendar::testDuiLocaleCalendar() +{ + DuiLocale *z = 0; + // We can't test with default locale because the s_systemDefault + // is persistent and whatever we set to default locale will be + // kept there. + z = new DuiLocale("fi"); + QVERIFY2(z->isValid(), "new DuiLocale() did not create a valid locale"); + + QFETCH(DuiLocale::Calendar, cal); + + QVERIFY2(z->calendar() == DuiLocale::DefaultCalendar, + "Constructor didn't set the default calendar"); + z->setCalendar(cal); + QVERIFY2(z->calendar() == cal, "Calendar was not set properly"); + delete z; +} + +void Ut_DuiCalendar::testDuiLocaleCalendarConversionsFromLocaltimeQDateTime_data() +{ + QTest::addColumn("datetime"); + QTest::addColumn("localeName"); + QTest::addColumn("cal"); + QTest::addColumn("dateShortResult"); + QTest::addColumn("dateMediumResult"); + QTest::addColumn("dateLongResult"); + QTest::addColumn("dateFullResult"); + QTest::addColumn("timeShortResult"); + QTest::addColumn("timeMediumResult"); + QTest::addColumn("timeLongResult"); + QTest::addColumn("timeFullResult"); + + QDate date(2008, 7, 21); + QTime time(12, 31, 0, 0); + QDateTime datetime(date, time, Qt::LocalTime); + + QTest::newRow("21.7.2008_fi_FI_Gregorian") + << datetime + << QString("fi_FI") + << DuiLocale::GregorianCalendar + << QString("21.7.2008") + << QString("21.7.2008") + << QString("21. heinäkuuta 2008") + << QString("maanantaina 21. heinäkuuta 2008") + << QString("12.31") + << QString("12.31.00") + << QString("12.31.00 UTC+3.00") + << QString("12.31.00 Itä-Euroopan kesäaika"); + QTest::newRow("21.7.2008_en_GB_Gregorian") + << datetime + << QString("en_GB") + << DuiLocale::GregorianCalendar + << QString("21/07/2008") + << QString("21 Jul 2008") + << QString("21 July 2008") + << QString("Monday, 21 July 2008") + << QString("12:31") + << QString("12:31:00") + << QString("12:31:00 EEST") + << QString("12:31:00 Eastern European Summer Time"); + QTest::newRow("21.7.2008_de_DE_Gregorian") + << datetime + << QString("de_DE") + << DuiLocale::GregorianCalendar + << QString("21.07.08") + << QString("21.07.2008") + << QString("21. Juli 2008") + << QString("Montag, 21. Juli 2008") + << QString("12:31") + << QString("12:31:00") + << QString("12:31:00 GMT+03:00") + << QString("12:31:00 Osteuropäische Sommerzeit"); + QTest::newRow("21.7.2008_nn_NO_Gregorian") + << datetime + << QString("nn_NO") + << DuiLocale::GregorianCalendar + << QString("21.07.08") + << QString("21. jul. 2008") + << QString("21. juli 2008") + << QString("måndag 21. juli 2008") + << QString("12.31") + << QString("12.31.00") + << QString("12.31.00 GMT+03.00") + << QString("kl. 12.31.00 austeuropeisk sommartid"); + QTest::newRow("21.7.2008_nb_NO_Gregorian") + << datetime + << QString("nb_NO") + << DuiLocale::GregorianCalendar + << QString("21.07.08") + << QString("21. juli 2008") + << QString("21. juli 2008") + << QString("mandag 21. juli 2008") + << QString("12.31") + << QString("12.31.00") + << QString("12.31.00 GMT+03.00") + << QString("kl. 12.31.00 østeuropeisk sommertid"); + QTest::newRow("21.7.2008_no_NO_Gregorian") + << datetime + << QString("no_NO") + << DuiLocale::GregorianCalendar + << QString("21.07.08") + << QString("21. juli 2008") + << QString("21. juli 2008") + << QString("mandag 21. juli 2008") + << QString("12.31") + << QString("12.31.00") + << QString("12.31.00 GMT+03.00") + << QString("kl. 12.31.00 østeuropeisk sommertid"); +} + +void Ut_DuiCalendar::testDuiLocaleCalendarConversionsFromLocaltimeQDateTime() +{ + QFETCH(QDateTime, datetime); + QFETCH(QString, localeName); + QFETCH(DuiLocale::Calendar, cal); + QFETCH(QString, dateShortResult); + QFETCH(QString, dateMediumResult); + QFETCH(QString, dateLongResult); + QFETCH(QString, dateFullResult); + QFETCH(QString, timeShortResult); + QFETCH(QString, timeMediumResult); + QFETCH(QString, timeLongResult); + QFETCH(QString, timeFullResult); + + DuiLocale locale(localeName); + + QList dateResults; + dateResults << QString("") + << dateShortResult + << dateMediumResult + << dateLongResult + << dateFullResult; + QList timeResults; + timeResults << QString("") + << timeShortResult + << timeMediumResult + << timeLongResult + << timeFullResult; + + for (unsigned dateType = DuiLocale::DateNone; dateType <= DuiLocale::DateFull; + ++dateType) { + for (unsigned timeType = DuiLocale::TimeNone; timeType <= DuiLocale::TimeFull; + ++timeType) { + QString result; + if (dateType == DuiLocale::DateNone) + result = timeResults[timeType]; + else if (timeType == DuiLocale::TimeNone) + result = dateResults[dateType]; + else + result = dateResults[dateType] + ' ' + timeResults[timeType]; + qDebug() << "dateType" << dateType << "timeType" << timeType + << "result" << result; + QCOMPARE( + locale.formatDateTime(datetime, + static_cast(dateType), + static_cast(timeType), + cal), + result); + } + } +} + +void Ut_DuiCalendar::testDuiLocaleCalendarConversionsFromUTCQDateTime_data() +{ + QTest::addColumn("datetime"); + QTest::addColumn("localeName"); + QTest::addColumn("cal"); + QTest::addColumn("short_result"); + QTest::addColumn("long_result"); + QTest::addColumn("full_result"); + + QDate date(2008, 7, 21); + QTime time(12, 31, 0, 0); + QDateTime datetime(date, time, Qt::UTC); // finland is utc+3 so maps to 15:31 + + QTest::newRow("21.7.2008_fi_FI_Gregorian") + << datetime + << QString("fi_FI") + << DuiLocale::GregorianCalendar + << QString("21.7.2008 15.31") + << QString("21. heinäkuuta 2008 15.31.00 UTC+3.00") + << QString("maanantaina 21. heinäkuuta 2008 15.31.00 Itä-Euroopan kesäaika"); + QTest::newRow("21.7.2008_en_GB_Gregorian") + << datetime + << QString("en_GB") + << DuiLocale::GregorianCalendar + << QString("21/07/2008 15:31") + << QString("21 July 2008 15:31:00 EEST") + << QString("Monday, 21 July 2008 15:31:00 Eastern European Summer Time"); + QTest::newRow("21.7.2008_nn_NO_Gregorian") + << datetime + << QString("nn_NO") + << DuiLocale::GregorianCalendar + << QString("21.07.08 15.31") + << QString("21. juli 2008 15.31.00 GMT+03.00") + << QString("måndag 21. juli 2008 kl. 15.31.00 austeuropeisk sommartid"); + QTest::newRow("21.7.2008_nb_NO_Gregorian") + << datetime + << QString("nb_NO") + << DuiLocale::GregorianCalendar + << QString("21.07.08 15.31") + << QString("21. juli 2008 15.31.00 GMT+03.00") + << QString("mandag 21. juli 2008 kl. 15.31.00 østeuropeisk sommertid"); +} + +void Ut_DuiCalendar::testDuiLocaleCalendarConversionsFromUTCQDateTime() +{ + QFETCH(QDateTime, datetime); + QFETCH(QString, localeName); + QFETCH(DuiLocale::Calendar, cal); + QFETCH(QString, short_result); + QFETCH(QString, long_result); + QFETCH(QString, full_result); + + DuiLocale locale(localeName); + + QCOMPARE(locale.formatDateTime(datetime, DuiLocale::DateShort, + DuiLocale::TimeShort, cal), + short_result); + QCOMPARE(locale.formatDateTime(datetime, DuiLocale::DateLong, + DuiLocale::TimeLong, cal), + long_result); + QCOMPARE(locale.formatDateTime(datetime, DuiLocale::DateFull, + DuiLocale::TimeFull, cal), + full_result); +} + +void Ut_DuiCalendar::testDuiLocaleCalendarConversionsFromDuiCalendar_data() +{ + QTest::addColumn("localeName"); + QTest::addColumn("cal"); + QTest::addColumn("year"); + QTest::addColumn("month"); + QTest::addColumn("day"); + QTest::addColumn("dateShortResult"); + QTest::addColumn("dateMediumResult"); + QTest::addColumn("dateLongResult"); + QTest::addColumn("dateFullResult"); + QTest::addColumn("timeShortResult"); + QTest::addColumn("timeMediumResult"); + QTest::addColumn("timeLongResult"); + QTest::addColumn("timeFullResult"); + + QTest::newRow("21.7.2008_fi_FI_Gregorian") + << QString("fi_FI") + << DuiLocale::GregorianCalendar + << 2008 + << 7 + << 21 + << "21.7.2008" + << "21.7.2008" + << "21. heinäkuuta 2008" + << "maanantaina 21. heinäkuuta 2008" + << "14.31" + << "14.31.00" + << "14.31.00 UTC+3.00" + << "14.31.00 Itä-Euroopan kesäaika"; + + QTest::newRow("21.7.2008_en_GB_Gregorian") + << QString("en_GB") + << DuiLocale::GregorianCalendar + << 2008 + << 7 + << 21 + << "21/07/2008" + << "21 Jul 2008" + << "21 July 2008" + << "Monday, 21 July 2008" + << "14:31" + << "14:31:00" + << "14:31:00 EEST" + << "14:31:00 Eastern European Summer Time"; + + QTest::newRow("21.7.2008_nn_NO_Gregorian") + << QString("nn_NO") + << DuiLocale::GregorianCalendar + << 2008 + << 7 + << 21 + << "21.07.08" + << "21. jul. 2008" + << "21. juli 2008" + << "måndag 21. juli 2008" + << "14.31" + << "14.31.00" + << "14.31.00 GMT+03.00" + << "kl. 14.31.00 austeuropeisk sommartid"; + + QTest::newRow("21.7.2008_nb_NO_Gregorian") + << QString("nb_NO") + << DuiLocale::GregorianCalendar + << 2008 + << 7 + << 21 + << "21.07.08" + << "21. juli 2008" + << "21. juli 2008" + << "mandag 21. juli 2008" + << "14.31" + << "14.31.00" + << "14.31.00 GMT+03.00" + << "kl. 14.31.00 østeuropeisk sommertid"; + + QTest::newRow("21.7.2008_no_NO_Gregorian") + << QString("no_NO") + << DuiLocale::GregorianCalendar + << 2008 + << 7 + << 21 + << "21.07.08" + << "21. juli 2008" + << "21. juli 2008" + << "mandag 21. juli 2008" + << "14.31" + << "14.31.00" + << "14.31.00 GMT+03.00" + << "kl. 14.31.00 østeuropeisk sommertid"; +} + +void Ut_DuiCalendar::testDuiLocaleCalendarConversionsFromDuiCalendar() +{ + QFETCH(QString, localeName); + QFETCH(DuiLocale::Calendar, cal); + QFETCH(int, year); + QFETCH(int, month); + QFETCH(int, day); + QFETCH(QString, dateShortResult); + QFETCH(QString, dateMediumResult); + QFETCH(QString, dateLongResult); + QFETCH(QString, dateFullResult); + QFETCH(QString, timeShortResult); + QFETCH(QString, timeMediumResult); + QFETCH(QString, timeLongResult); + QFETCH(QString, timeFullResult); + + DuiLocale locale(localeName); + DuiCalendar duical(cal); + duical.setDate(year, month, day); + duical.setTime(14, 31, 0); + + QList dateResults; + dateResults << QString("") + << dateShortResult + << dateMediumResult + << dateLongResult + << dateFullResult; + QList timeResults; + timeResults << QString("") + << timeShortResult + << timeMediumResult + << timeLongResult + << timeFullResult; + + for (unsigned dateType = DuiLocale::DateNone; dateType <= DuiLocale::DateFull; + ++dateType) { + for (unsigned timeType = DuiLocale::TimeNone; timeType <= DuiLocale::TimeFull; + ++timeType) { + QString result; + if (dateType == DuiLocale::DateNone) + result = timeResults[timeType]; + else if (timeType == DuiLocale::TimeNone) + result = dateResults[dateType]; + else + result = dateResults[dateType] + ' ' + timeResults[timeType]; + qDebug() << "dateType" << dateType << "timeType" << timeType + << "result" << result; + QCOMPARE( + locale.formatDateTime(duical, + static_cast(dateType), + static_cast(timeType)), + result); + } + } +} + +void Ut_DuiCalendar::testDuiCalendarAdditions() +{ + DuiLocale fi_FI("fi_FI"); + DuiCalendar cal(fi_FI); + cal.setDate(2008, 1, 31); + cal.setTime(19, 23, 0); + cal.addMonths(1); + + QVERIFY2(cal.year() == 2008, "year is incorrect"); + QVERIFY2(cal.month() == 2, "month is incorrect"); + QVERIFY2(cal.dayOfMonth() == 29, "day of month is incorrect"); + QVERIFY2(cal.dayOfYear() == 60, "day of year is incorrect"); + QVERIFY2(cal.firstDayOfMonth() == 1, "first day of month is incorrect"); + QVERIFY2(cal.lastDayOfMonth() == 29, "last day of month is incorrect"); + QVERIFY2(cal.firstDayOfWeek() == 1, "first day of week is incorrect"); + QVERIFY2(cal.weekNumber() == 9, "week number is incorrect"); + QVERIFY2(cal.maximumWeeksInMonth() == 6, "maximum weeks in month is incorrect"); + QVERIFY2(cal.daysInWeek() == 7, "days is week is incorrect"); + + // add some hours so calendar changes to 1.3.2008 + cal.addHours(5); + QVERIFY2(cal.hour() == 0, "hour failed"); + QVERIFY2(cal.minute() == 23, "minute failed"); + QVERIFY2(cal.second() == 0, "second failed"); + QVERIFY2(cal.month() == 3, "month failed"); + QVERIFY2(cal.dayOfMonth() == 1, "day of month failed"); +} + +void Ut_DuiCalendar::testWeekNumbers() +{ + // 31.12.2007 belongs to week 1 of year 2008, check it really is so + DuiLocale fi_FI("fi_FI"); + DuiCalendar cal(fi_FI); + cal.setDate(2007, 12, 31); + QVERIFY2(cal.yearOfWeek() == 2008, "year of week is incorrect"); + + cal.setDate(2005, 1, 1); + QVERIFY2(cal.weekOfYear() == 53, "year of week 1.1.2005 is incorrect2"); + + cal.setMinimalDaysInFirstWeek(1); + QVERIFY2(cal.minimalDaysInFirstWeek() == 1, "setMinimalDaysInFirstWeek() failed"); + QVERIFY2(cal.weekOfYear() == 1, "year of week 1.1.2005 with overridden week data failed"); + +} + +void Ut_DuiCalendar::testComparisons() +{ + DuiCalendar cal1; + DuiCalendar cal2; + cal1.setDate(2008, 3, 4); + cal2.setDate(2007, 7, 23); + + QVERIFY2(cal1.after(cal2) == true, "after() comparison failed"); + QVERIFY2(cal2.before(cal2) == false, "before() comparison failed"); + QVERIFY2(cal1.equals(cal2) == false, "equals() comparison failed"); + + QVERIFY2((cal1 < cal2) == false, "< operator failed"); + QVERIFY2((cal2 < cal1) == true, "< operator failed"); + QVERIFY2((cal1 > cal2) == true, "> operator failed"); + QVERIFY2((cal2 > cal1) == false, "> operator failed"); + QVERIFY2((cal1 == cal2) == false, "== operator failed"); + QVERIFY2((cal1 == cal1) == true, "== operator failed"); + QVERIFY2((cal1 <= cal2) == false, "<= operator failed"); + QVERIFY2((cal1 <= cal1) == true, "<= operator failed"); + QVERIFY2((cal1 >= cal1) == true, ">= operator failed"); + QVERIFY2((cal1 >= cal2) == true, ">= operator failed"); + QVERIFY2((cal1 != cal1) == false, "!= operator failed"); + QVERIFY2((cal1 != cal2) == true, "!= operator failed"); +} + +void Ut_DuiCalendar::testIslamicCalendar() +{ + DuiLocale loc("fi_FI"); + loc.setCalendar(DuiLocale::IslamicCalendar); + DuiCalendar cal(loc); + QDate date(2008, 1, 1); // use qdate to set date as gregorian + cal.setDate(date); + QString format = loc.formatDateTime(cal, DuiLocale::DateShort, DuiLocale::TimeNone); + bool gotCorrect = false; + + // we allow off-by-one conversion because the dates can be a bit ambiguous + // e.g. islamic day starts from sunset + if (format == "22.12.1428" + || format == "23.12.1428" + || format == "21.12.1428") { + gotCorrect = true; + } + + QVERIFY2(gotCorrect == true, "gregorian -> islamic conversion failed"); +} + +void Ut_DuiCalendar::testPosixFormatPattern_data() +{ + QTest::addColumn("calendarType"); + QTest::addColumn("year"); + QTest::addColumn("month"); + QTest::addColumn("day"); + QTest::addColumn("hour"); + QTest::addColumn("minute"); + QTest::addColumn("second"); + QTest::addColumn("localeName"); + QTest::addColumn("format"); + QTest::addColumn("result"); + + // ************************************************************ + QTest::newRow("fi_FI %a") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "fi_FI" + << "%a" // locale's abbreviated weekday name (e.g., Sun) + << "su"; + QTest::newRow("fi_FI %b") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "fi_FI" + << "%b" // locale's abbreviated month name (e.g., Jan) + << "helmi"; // probably wrong! FIXME!! + QTest::newRow("fi_FI %c") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "fi_FI" + << "%c" // locale's date and time (e.g., Thu Mar 3 23:05:25 2005) + << "3.2.2008 12.25.03"; + QTest::newRow("fi_FI %d") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "fi_FI" + << "%d" // %d day of month (e.g, 01) + << "03"; + QTest::newRow("fi_FI %e") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "fi_FI" + << "%e" // %e day of month, space padded; same as %_d + << "3"; // padding missing, FIXME!!! + QTest::newRow("fi_FI %g") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "fi_FI" + << "%g" // %g last two digits of year of ISO week number (see %G) + << "08"; + QTest::newRow("fi_FI %h") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "fi_FI" + << "%h" // %h same as %b, locale's abbreviated month name (e.g., Jan) + << "helmi"; // probably wrong! FIXME!!! + QTest::newRow("fi_FI %j") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "fi_FI" + << "%j" // day of year (001..366) + << "034"; + QTest::newRow("fi_FI %m") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "fi_FI" + << "%m" // month (01..12) + << "02"; + QTest::newRow("fi_FI %p") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "fi_FI" + << "%p" // %p locale's equivalent of either AM or PM; blank if not known + << "ip."; + QTest::newRow("fi_FI %r") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "fi_FI" + << "%r" // locale's 12-hour clock time (e.g., 11:11:04 PM) + << "00 ip."; + QTest::newRow("fi_FI %t") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "fi_FI" + << "%t" // a tab + << "\t"; + QTest::newRow("fi_FI %u") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "fi_FI" + << "%u" // %u day of week (1..7); 1 is Monday + << "7"; + QTest::newRow("fi_FI %v") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "fi_FI" + << "%v" // week number of the year in two digits (missing in POSIX?) + << "05"; + QTest::newRow("fi_FI %w") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "fi_FI" + << "%w" // day of week (0..6); 0 is Sunday + << "0"; + QTest::newRow("fi_FI %x") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "fi_FI" + << "%x" // locale's date representation (e.g., 12/31/99) + << "3.2.2008"; + QTest::newRow("fi_FI %y") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "fi_FI" + << "%y" // last two digits of year (00..99) + << "08"; + QTest::newRow("fi_FI %z") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "fi_FI" + << "%z" // +hhmm numeric timezone (e.g., -0400) + << "+0200"; + QTest::newRow("fi_FI %A") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "fi_FI" + << "%A" // locale's full weekday name (e.g., Sunday) + << "sunnuntaina"; + QTest::newRow("fi_FI %B") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "fi_FI" + << "%B" // locale's full month name (e.g., January) + << "helmikuuta"; + QTest::newRow("fi_FI %C") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "fi_FI" + << "%C" // century; like %Y, except omit last two digits (e.g., 21) + << "20"; + QTest::newRow("fi_FI %D") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "fi_FI" + << "%D" // date; same as %m/%d/%y + << "02/03/08"; + QTest::newRow("fi_FI %F") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "fi_FI" + << "%F" // full date; same as %Y-%m-%d" + << "2008-02-03"; + QTest::newRow("fi_FI %G") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "fi_FI" + << "%G" // year of ISO week number (see %V); normally useful only with %V + << "2008"; + QTest::newRow("fi_FI %H") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "fi_FI" + << "%H" // hour (00..23) + << "12"; + QTest::newRow("fi_FI %I") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "fi_FI" + << "%I" // hour (01..12) + << "00"; + QTest::newRow("fi_FI %M") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "fi_FI" + << "%M" // minute (00..59)" + << "25"; + QTest::newRow("fi_FI %R") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "fi_FI" + << "%R" // 24-hour hour and minute; same as %H:%M + << "12:25"; + QTest::newRow("fi_FI %S") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "fi_FI" + << "%S" // second (00..60) + << "03"; + QTest::newRow("fi_FI %T") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "fi_FI" + << "%T" // time; same as %H:%M:%S + << "12:25:03"; + QTest::newRow("fi_FI %U") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "fi_FI" + << "%U" // week number of year, with Sunday as first day of week (00..53) + << "5"; + QTest::newRow("fi_FI %V") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "fi_FI" + << "%V" // ISO week number, with Monday as first day of week (01..53)" + << "5"; + QTest::newRow("fi_FI %W") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "fi_FI" + << "%W" // week number of year, with Monday as first day of week (00..53) + << "4"; + QTest::newRow("fi_FI %X") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "fi_FI" + << "%X" // locale's time representation (e.g., 23:13:48) + << "12.25.03"; + QTest::newRow("fi_FI %Y") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "fi_FI" + << "%Y" // year + << "2008"; + QTest::newRow("fi_FI %Z") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "fi_FI" + << "%Z" // Time-zone name, or no characters if no time zone is determinable + << "Suomi"; + + // ************************************************************ + QTest::newRow("en_GB %a") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "en_GB" + << "%a" // locale's abbreviated weekday name (e.g., Sun) + << "Sun"; + QTest::newRow("en_GB %b") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "en_GB" + << "%b" // locale's abbreviated month name (e.g., Jan) + << "helmi"; // probably wrong! FIXME!! + QTest::newRow("en_GB %c") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "en_GB" + << "%c" // locale's date and time (e.g., Thu Mar 3 23:05:25 2005) + << "3 Feb 2008 12:25:03"; + QTest::newRow("en_GB %d") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "en_GB" + << "%d" // %d day of month (e.g, 01) + << "03"; + QTest::newRow("en_GB %e") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "en_GB" + << "%e" // %e day of month, space padded; same as %_d + << "3"; // padding missing, FIXME!!! + QTest::newRow("en_GB %g") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "en_GB" + << "%g" // %g last two digits of year of ISO week number (see %G) + << "08"; + QTest::newRow("en_GB %h") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "en_GB" + << "%h" // %h same as %b, locale's abbreviated month name (e.g., Jan) + << "Feb"; + QTest::newRow("en_GB %j") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "en_GB" + << "%j" // day of year (001..366) + << "034"; + QTest::newRow("en_GB %m") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "en_GB" + << "%m" // month (01..12) + << "02"; + QTest::newRow("en_GB %p") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "en_GB" + << "%p" // %p locale's equivalent of either AM or PM; blank if not known + << "PM"; + QTest::newRow("en_GB %r") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "en_GB" + << "%r" // locale's 12-hour clock time (e.g., 11:11:04 PM) + << "00 PM"; + QTest::newRow("en_GB %t") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "en_GB" + << "%t" // a tab + << "\t"; + QTest::newRow("en_GB %u") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "en_GB" + << "%u" // %u day of week (1..7); 1 is Monday + << "7"; + QTest::newRow("en_GB %v") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "en_GB" + << "%v" // week number of the year in two digits (missing in POSIX?) + << "05"; + QTest::newRow("en_GB %w") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "en_GB" + << "%w" // day of week (0..6); 0 is Sunday + << "0"; + QTest::newRow("en_GB %x") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "en_GB" + << "%x" // locale's date representation (e.g., 12/31/99) + << "3 Feb 2008"; + QTest::newRow("en_GB %y") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "en_GB" + << "%y" // last two digits of year (00..99) + << "08"; + QTest::newRow("en_GB %z") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "en_GB" + << "%z" // +hhmm numeric timezone (e.g., -0400) + << "+0200"; + QTest::newRow("en_GB %A") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "en_GB" + << "%A" // locale's full weekday name (e.g., Sunday) + << "Sunday"; + QTest::newRow("en_GB %B") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "en_GB" + << "%B" // locale's full month name (e.g., January) + << "February"; + QTest::newRow("en_GB %C") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "en_GB" + << "%C" // century; like %Y, except omit last two digits (e.g., 21) + << "20"; + QTest::newRow("en_GB %D") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "en_GB" + << "%D" // date; same as %m/%d/%y + << "02/03/08"; + QTest::newRow("en_GB %F") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "en_GB" + << "%F" // full date; same as %Y-%m-%d" + << "2008-02-03"; + QTest::newRow("en_GB %G") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "en_GB" + << "%G" // year of ISO week number (see %V); normally useful only with %V + << "2008"; + QTest::newRow("en_GB %H") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "en_GB" + << "%H" // hour (00..23) + << "12"; + QTest::newRow("en_GB %I") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "en_GB" + << "%I" // hour (01..12) + << "00"; + QTest::newRow("en_GB %M") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "en_GB" + << "%M" // minute (00..59)" + << "25"; + QTest::newRow("en_GB %R") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "en_GB" + << "%R" // 24-hour hour and minute; same as %H:%M + << "12:25"; + QTest::newRow("en_GB %S") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "en_GB" + << "%S" // second (00..60) + << "03"; + QTest::newRow("en_GB %T") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "en_GB" + << "%T" // time; same as %H:%M:%S + << "12:25:03"; + QTest::newRow("en_GB %U") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "en_GB" + << "%U" // week number of year, with Sunday as first day of week (00..53) + << "5"; + QTest::newRow("en_GB %V") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "en_GB" + << "%V" // ISO week number, with Monday as first day of week (01..53)" + << "5"; + QTest::newRow("en_GB %W") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "en_GB" + << "%W" // week number of year, with Monday as first day of week (00..53) + << "4"; + QTest::newRow("en_GB %X") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "en_GB" + << "%X" // locale's time representation (e.g., 23:13:48) + << "12:25:03"; + QTest::newRow("en_GB %Y") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "en_GB" + << "%Y" // year + << "2008"; + QTest::newRow("en_GB %Z") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "en_GB" + << "%Z" // Time-zone name, or no characters if no time zone is determinable + << "Finland Time"; + + // ************************************************************ + QTest::newRow("de_DE %Z") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "de_DE" + << "%Z" // Time-zone name, or no characters if no time zone is determinable + << "Finnland"; + // ************************************************************ + QTest::newRow("fi_FI %R %Z") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "fi_FI" + << "%R %Z" + << "12:25 Suomi"; + QTest::newRow("en_GB %R %Z") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "en_GB" + << "%R %Z" + << "12:25 Finland Time"; + QTest::newRow("de_DE %R %Z") + << DuiLocale::GregorianCalendar + << 2008 + << 2 + << 3 + << 12 + << 25 + << 3 + << "de_DE" + << "%R %Z" + << "12:25 Finnland"; +} + +void Ut_DuiCalendar::testPosixFormatPattern() +{ + QFETCH(DuiLocale::Calendar, calendarType); + QFETCH(int, year); + QFETCH(int, month); + QFETCH(int, day); + QFETCH(int, hour); + QFETCH(int, minute); + QFETCH(int, second); + QFETCH(QString, localeName); + QFETCH(QString, format); + QFETCH(QString, result); + + DuiLocale locale(localeName); + locale.setCalendar(calendarType); + DuiCalendar duical(locale); + duical.setDate(year, month, day); + duical.setTime(hour, minute, second); + QDate date(year, month, day); + QTime time(hour, minute, second); + QDateTime datetime(date, time, Qt::LocalTime); + QLocale qlocale(localeName); + + qDebug() << "format:" << format << "result: " << result; +// qDebug() << "QLocale time ShortFormat" << qlocale.toString(time, QLocale::ShortFormat) << "QLocale time LongFormat" << qlocale.toString(time, QLocale::LongFormat); +// qDebug() << "QLocale format" << qlocale.toString(time, "hh:mm"); +// qDebug() << "QLocale date ShortFormat" << qlocale.toString(date, QLocale::ShortFormat) << "QLocale date LongFormat" << qlocale.toString(date, QLocale::LongFormat); + qDebug() << "DateNone TimeNone" << locale.formatDateTime(datetime, DuiLocale::DateNone, DuiLocale::TimeNone, calendarType); + qDebug() << "DateNone TimeShort" << locale.formatDateTime(datetime, DuiLocale::DateNone, DuiLocale::TimeShort, calendarType); + qDebug() << "DateShort TimeNone" << locale.formatDateTime(datetime, DuiLocale::DateShort, DuiLocale::TimeNone, calendarType); +// qDebug() << "DateShort TimeShort" << locale.formatDateTime(datetime, DuiLocale::DateShort, DuiLocale::TimeShort, calendarType); +// qDebug() << "DateMedium TimeMedium" << locale.formatDateTime(datetime, DuiLocale::DateMedium, DuiLocale::TimeMedium, calendarType); +// qDebug() << "DateLong TimeLong" << locale.formatDateTime(datetime, DuiLocale::DateLong, DuiLocale::TimeLong, calendarType); +// qDebug() << "DateFull TimeFull" << locale.formatDateTime(datetime, DuiLocale::DateFull, DuiLocale::TimeFull, calendarType); + if ((format == "%b" || format == "%h") && result == "helmi") { + QEXPECT_FAIL("", "FIXME: ICU does %b and %h wrong for Finnish", Continue); + QVERIFY(false); + } else { + QCOMPARE(locale.formatDateTime(duical, format), result); + QCOMPARE(locale.formatDateTime(datetime, format), result); + } +} + +void Ut_DuiCalendar::testWeekdaySymbols_data() +{ + QTest::addColumn("localeName"); + QTest::addColumn("cal"); + QTest::addColumn("symbols"); + + // FIXME: better translations would be without -na suffix + QStringList fi_FI_Symbols; + fi_FI_Symbols + << QString("maanantaina") + << QString("tiistaina") + << QString("keskiviikkona") + << QString("torstaina") + << QString("perjantaina") + << QString("lauantaina") + << QString("sunnuntaina"); + + QTest::newRow("weekday_symbols_fi_FI_Gregorian") + << QString("fi_FI") + << DuiLocale::GregorianCalendar + << fi_FI_Symbols; + + QStringList en_GB_Symbols; + en_GB_Symbols + << QString("Monday") + << QString("Tuesday") + << QString("Wednesday") + << QString("Thursday") + << QString("Friday") + << QString("Saturday") + << QString("Sunday"); + + QTest::newRow("weekday_symbols_en_GB_Gregorian") + << QString("en_GB") + << DuiLocale::GregorianCalendar + << en_GB_Symbols; + + QStringList nn_NO_Symbols; + nn_NO_Symbols + << QString("måndag") + << QString("tysdag") + << QString("onsdag") + << QString("torsdag") + << QString("fredag") + << QString("laurdag") + << QString("søndag"); + + QTest::newRow("weekday_symbols_nn_NO_Gregorian") + << QString("nn_NO") + << DuiLocale::GregorianCalendar + << nn_NO_Symbols; + + QStringList nb_NO_Symbols; + nb_NO_Symbols + << QString("mandag") + << QString("tirsdag") + << QString("onsdag") + << QString("torsdag") + << QString("fredag") + << QString("lørdag") + << QString("søndag"); + + QTest::newRow("weekday_symbols_nb_NO_Gregorian") + << QString("nb_NO") + << DuiLocale::GregorianCalendar + << nb_NO_Symbols; + + QStringList no_NO_Symbols; + no_NO_Symbols = nb_NO_Symbols; + + QTest::newRow("weekday_symbols_no_NO_Gregorian") + << QString("no_NO") + << DuiLocale::GregorianCalendar + << no_NO_Symbols; +} + +void Ut_DuiCalendar::testWeekdaySymbols() +{ + QFETCH(QString, localeName); + QFETCH(DuiLocale::Calendar, cal); + QFETCH(QStringList, symbols); + + DuiLocale locale(localeName); + DuiCalendar duical(cal); + for (int i = 1; i <= 7; ++i) { + QString symbol = symbols.at(i - 1); + QCOMPARE(locale.weekdayName(duical, i), symbol); + } +} + +void Ut_DuiCalendar::testMonthSymbols_data() +{ + QTest::addColumn("localeName"); + QTest::addColumn("cal"); + QTest::addColumn("symbols"); + + // FIXME: again better translations without -ta + QStringList fi_FI_Symbols; + fi_FI_Symbols + << QString("tammikuuta") + << QString("helmikuuta") + << QString("maaliskuuta") + << QString("huhtikuuta") + << QString("toukokuuta") + << QString("kesäkuuta") + << QString("heinäkuuta") + << QString("elokuuta") + << QString("syyskuuta") + << QString("lokakuuta") + << QString("marraskuuta") + << QString("joulukuuta"); + + QTest::newRow("month_symbols_fi_FI_Gregorian") + << QString("fi_FI") + << DuiLocale::GregorianCalendar + << fi_FI_Symbols; + + QStringList en_GB_Symbols; + en_GB_Symbols + << QString("January") + << QString("February") + << QString("March") + << QString("April") + << QString("May") + << QString("June") + << QString("July") + << QString("August") + << QString("September") + << QString("October") + << QString("November") + << QString("December"); + + QTest::newRow("month_symbols_en_GB_Gregorian") + << QString("en_GB") + << DuiLocale::GregorianCalendar + << en_GB_Symbols; + + QStringList nn_NO_Symbols; + nn_NO_Symbols + << QString("januar") + << QString("februar") + << QString("mars") + << QString("april") + << QString("mai") + << QString("juni") + << QString("juli") + << QString("august") + << QString("september") + << QString("oktober") + << QString("november") + << QString("desember"); + + QTest::newRow("month_symbols_nn_NO_Gregorian") + << QString("nn_NO") + << DuiLocale::GregorianCalendar + << nn_NO_Symbols; + + QStringList nb_NO_Symbols; + nb_NO_Symbols + << QString("januar") + << QString("februar") + << QString("mars") + << QString("april") + << QString("mai") + << QString("juni") + << QString("juli") + << QString("august") + << QString("september") + << QString("oktober") + << QString("november") + << QString("desember"); + + QTest::newRow("month_symbols_nb_NO_Gregorian") + << QString("nb_NO") + << DuiLocale::GregorianCalendar + << nb_NO_Symbols; + + QStringList no_NO_Symbols; + no_NO_Symbols = nb_NO_Symbols; + + QTest::newRow("month_symbols_no_NO_Gregorian") + << QString("no_NO") + << DuiLocale::GregorianCalendar + << no_NO_Symbols; +} + +void Ut_DuiCalendar::testMonthSymbols() +{ + QFETCH(QString, localeName); + QFETCH(DuiLocale::Calendar, cal); + + DuiLocale locale(localeName); + DuiCalendar duical(cal); + QFETCH(QStringList, symbols); + + for (int i = 1; i <= 12; ++i) { + QString symbol = symbols.at(i - 1); + QCOMPARE(locale.monthName(duical, i), symbol); + } +} + +QTEST_APPLESS_MAIN(Ut_DuiCalendar); + diff --git a/tests/ut_duicalendar/ut_duicalendar.h b/tests/ut_duicalendar/ut_duicalendar.h new file mode 100644 index 000000000..78c2fd6d7 --- /dev/null +++ b/tests/ut_duicalendar/ut_duicalendar.h @@ -0,0 +1,77 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_CALENDAR_H +#define UT_CALENDAR_H + + +#include +#include +#include +#include + +Q_DECLARE_METATYPE(DuiLocale::Calendar); +Q_DECLARE_METATYPE(DuiLocale); + + +#define MAX_PARAMS 10 +class Ut_DuiCalendar : public QObject +{ + Q_OBJECT + +private: + QCoreApplication *qap; + QString icuPackageVersion; + +private slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + + void testDuiLocaleCalendar_data(); + void testDuiLocaleCalendar(); + + void testDuiLocaleCalendarConversionsFromLocaltimeQDateTime_data(); + void testDuiLocaleCalendarConversionsFromLocaltimeQDateTime(); + + void testDuiLocaleCalendarConversionsFromUTCQDateTime_data(); + void testDuiLocaleCalendarConversionsFromUTCQDateTime(); + + void testDuiLocaleCalendarConversionsFromDuiCalendar_data(); + void testDuiLocaleCalendarConversionsFromDuiCalendar(); + + void testDuiCalendarAdditions(); + void testWeekNumbers(); + void testComparisons(); + + void testIslamicCalendar(); + + void testPosixFormatPattern_data(); + void testPosixFormatPattern(); + + void testWeekdaySymbols_data(); + void testWeekdaySymbols(); + + void testMonthSymbols_data(); + void testMonthSymbols(); +}; + + +#endif diff --git a/tests/ut_duicalendar/ut_duicalendar.pro b/tests/ut_duicalendar/ut_duicalendar.pro new file mode 100644 index 000000000..cd60a5023 --- /dev/null +++ b/tests/ut_duicalendar/ut_duicalendar.pro @@ -0,0 +1,12 @@ +include(../common_top.pri) + +TARGET = ut_duicalendar + +TEST_SOURCES += \ +# $$DUISRCDIR/duicalendar.cpp \ + +# Input +HEADERS += ut_duicalendar.h +SOURCES += ut_duicalendar.cpp + +include(../common_bot.pri) diff --git a/tests/ut_duicombobox/.gitignore b/tests/ut_duicombobox/.gitignore new file mode 100644 index 000000000..6aa7e7cc5 --- /dev/null +++ b/tests/ut_duicombobox/.gitignore @@ -0,0 +1 @@ +ut_duicombobox diff --git a/tests/ut_duicombobox/ut_duicombobox.cpp b/tests/ut_duicombobox/ut_duicombobox.cpp new file mode 100644 index 000000000..9c1153489 --- /dev/null +++ b/tests/ut_duicombobox/ut_duicombobox.cpp @@ -0,0 +1,361 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ut_duicombobox.h" +#include "duicancelevent.h" +#include "duicomboboxview.h" +#include "duicomboboxview_p.h" + +DuiApplication *app; +DuiWindow *win; + +void Ut_DuiComboBox::initTestCase() +{ + static int argc = 1; + static char *argv[1] = { (char *) "./Ut_DuiComboBox" }; + app = new DuiApplication(argc, argv); + + win = new DuiWindow(); + win->setSceneManager(new DuiSceneManager()); +} + +void Ut_DuiComboBox::cleanupTestCase() +{ + delete win; + win = NULL; + delete app; + app = NULL; +} + +void Ut_DuiComboBox::init() +{ + m_combobox = new DuiComboBox(); +} + +void Ut_DuiComboBox::cleanup() +{ + if (m_combobox) + delete m_combobox; + m_combobox = NULL; +} + +void Ut_DuiComboBox::testItemModel() +{ + QStringList buffer; + int total = 10; + for (int i = 0; i < total; i++) + buffer << "Item" + QString::number(i); + + // test StandardItemModel + m_combobox->addItems(buffer); + + QAbstractItemModel *itemModel = m_combobox->itemModel(); + QStandardItemModel *smodel = qobject_cast(itemModel); + QVERIFY(smodel != NULL); + + // test use model from outside + QStringListModel model; + model.setStringList(buffer); + + m_combobox->setItemModel(&model); + QCOMPARE(&model, m_combobox->itemModel()); + QCOMPARE(m_combobox->count(), total); +} + +void Ut_DuiComboBox::testActions() +{ + QStringList buffer; + int total = 10; + for (int i = 0; i < total; i++) + buffer << "Item" + QString::number(i); + + // test add items + m_combobox->addItems(buffer); + QCOMPARE(m_combobox->count(), 10); + + QAbstractItemModel *itemModel = m_combobox->itemModel(); + QCOMPARE(itemModel->rowCount(), total); + + m_combobox->clear(); + QCOMPARE(m_combobox->count(), 0); + + m_combobox->addItem("Just a test"); + QCOMPARE(m_combobox->count(), 1); + + m_combobox->addItem("Icon", "Just a test"); + QCOMPARE(m_combobox->count(), 2); + + // test remove item + m_combobox->removeItem(0); + QCOMPARE(m_combobox->count(), 1); + + m_combobox->removeItem(0); + QCOMPARE(m_combobox->count(), 0); + + // test insert item + m_combobox->insertItem(0, "Just a test"); + QCOMPARE(m_combobox->count(), 1); + + m_combobox->insertItem(0, "Icon", "Just a test"); + QCOMPARE(m_combobox->count(), 2); + + m_combobox->clear(); + m_combobox->insertItems(0, buffer); + QCOMPARE(m_combobox->count(), total); +} + +void Ut_DuiComboBox::testCurrentIndex() +{ + QStringList buffer; + int total = 10; + for (int i = 0; i < total; i++) + buffer << "Item" + QString::number(i); + + m_combobox->addItems(buffer); + + QSignalSpy spy1(m_combobox, SIGNAL(currentIndexChanged(int))); + QSignalSpy spy2(m_combobox, SIGNAL(currentIndexChanged(QString))); + + m_combobox->setCurrentIndex(0); + QCOMPARE(m_combobox->currentIndex(), 0); + QCOMPARE(m_combobox->currentText(), QString("Item0")); + + QCOMPARE(spy1.count(), 1); + QCOMPARE(spy2.count(), 1); + + QList arguments1 = spy1.takeFirst(); + QVERIFY(arguments1.at(0).type() == QVariant::Int); + QVERIFY(arguments1.at(0).toInt() == 0); + + QList arguments2 = spy2.takeFirst(); + QVERIFY(arguments2.at(0).type() == QVariant::String); + QCOMPARE(arguments2.at(0).toString(), QString("Item0")); +} + +void Ut_DuiComboBox::testFunctions() +{ + QString value = "test"; + m_combobox->setIconID(value); + QCOMPARE(m_combobox->iconID(), value); + + m_combobox->setTitle(value); + QCOMPARE(m_combobox->title(), value); + + m_combobox->setIconVisible(false); + QCOMPARE(m_combobox->isIconVisible(), false); + + m_combobox->setIconVisible(true); + QCOMPARE(m_combobox->isIconVisible(), true); + + m_combobox->insertItem(0, "Just a test"); + m_combobox->setItemText(0, value); + QCOMPARE(m_combobox->itemText(0), value); + + m_combobox->setItemIconID(0, value); + QCOMPARE(m_combobox->itemIconID(0), value); +} + +void Ut_DuiComboBox::testCancelEvent() +{ + QSignalSpy showPopupSpy(m_combobox, SIGNAL(showPopupList())); + + QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMousePress); + m_combobox->mousePressEvent(&mouseEvent); + QVERIFY(m_combobox->isDown() == true); + + DuiCancelEvent event; + m_combobox->cancelEvent(&event); + + QCOMPARE(showPopupSpy.count(), 0); + QVERIFY(m_combobox->isDown() == false); +} + +void Ut_DuiComboBox::testIconVisibility() +{ + DuiComboBoxView *view = (DuiComboBoxView *)m_combobox->view(); + DuiComboBoxViewPrivate *viewPrivate = view->d_func(); + + m_combobox->setTitle("Title"); + view->updateData(QList() << DuiComboBoxModel::Title); + QCOMPARE(viewPrivate->icon->isVisible(), false); + QCOMPARE(viewPrivate->layout->itemAt(0, 0), viewPrivate->title); + + m_combobox->setIconID("Icon-music"); + view->updateData(QList() << DuiComboBoxModel::IconID); + QCOMPARE(viewPrivate->icon->isVisible(), true); + QCOMPARE(viewPrivate->layout->itemAt(0, 0), viewPrivate->icon); + + m_combobox->setIconVisible(false); + view->updateData(QList() << DuiComboBoxModel::IconVisible); + QCOMPARE(viewPrivate->icon->isVisible(), false); + QCOMPARE(viewPrivate->layout->itemAt(0, 0), viewPrivate->title); + + m_combobox->setIconVisible(true); + view->updateData(QList() << DuiComboBoxModel::IconVisible); + QCOMPARE(viewPrivate->icon->isVisible(), true); + QCOMPARE(viewPrivate->layout->itemAt(0, 0), viewPrivate->icon); +} + + +void Ut_DuiComboBox::testClickSlot() +{ + win->scene()->addItem(m_combobox); + + DuiComboBoxView *view = (DuiComboBoxView *)m_combobox->view(); + DuiComboBoxViewPrivate *viewPrivate = view->d_func(); + + m_combobox->addItem("Item1"); + m_combobox->addItem("Item2"); + + m_combobox->click(); + + QVERIFY(viewPrivate->popuplist != 0); + QVERIFY(viewPrivate->popuplist->isVisible()); + + win->scene()->removeItem(m_combobox); +} + +void Ut_DuiComboBox::testBuiltinModel() +{ + DuiComboBoxView *view = (DuiComboBoxView *)m_combobox->view(); + DuiComboBoxViewPrivate *viewPrivate = view->d_func(); + + m_combobox->addItems(QStringList() << "item0" << "item1" << "item2" << "item3"); + + // select item2 + m_combobox->setCurrentIndex(2); + QCOMPARE(m_combobox->currentIndex(), 2); + QCOMPARE(viewPrivate->subtitle->text(), QString("item2")); + // remove item1, index should change + m_combobox->removeItem(1); + QCOMPARE(m_combobox->currentIndex(), 1); + QCOMPARE(viewPrivate->subtitle->text(), QString("item2")); + // remove current item + m_combobox->removeItem(1); + QCOMPARE(m_combobox->currentIndex(), -1); + QCOMPARE(viewPrivate->subtitle->text(), QString("!! Tap to Select")); + // check that after removing items everything looks ok + QCOMPARE(m_combobox->count(), 2); + m_combobox->setCurrentIndex(1); + QCOMPARE(m_combobox->currentIndex(), 1); + QCOMPARE(viewPrivate->subtitle->text(), QString("item3")); + // add one item + m_combobox->insertItem(0, QString("itemX")); + QCOMPARE(m_combobox->currentIndex(), 2); + QCOMPARE(viewPrivate->subtitle->text(), QString("item3")); + + // change current item text + m_combobox->setItemText(2, QString("beef")); + QCOMPARE(m_combobox->currentIndex(), 2); + QCOMPARE(viewPrivate->subtitle->text(), QString("beef")); +} + +void Ut_DuiComboBox::testModelSwitching() +{ + DuiComboBoxView *view = (DuiComboBoxView *)m_combobox->view(); + DuiComboBoxViewPrivate *viewPrivate = view->d_func(); + + m_combobox->addItems(QStringList() << "item0" << "item1" << "item2" << "item3"); + + m_combobox->setCurrentIndex(2); + QCOMPARE(m_combobox->currentIndex(), 2); + QCOMPARE(viewPrivate->subtitle->text(), QString("item2")); + + QStringListModel *strListModel = new QStringListModel(); + strListModel->setStringList(QStringList() << "foo0" << "foo1" << "foo2" << "foo3"); + m_combobox->setItemModel(strListModel); + + // model changed selection should reset + QCOMPARE(m_combobox->currentIndex(), -1); + QCOMPARE(viewPrivate->subtitle->text(), QString("!! Tap to Select")); +} + +void Ut_DuiComboBox::testStringListModel() +{ + DuiComboBoxView *view = (DuiComboBoxView *)m_combobox->view(); + DuiComboBoxViewPrivate *viewPrivate = view->d_func(); + + QStringListModel *strListModel = new QStringListModel(); + strListModel->setStringList(QStringList() << "foo0" << "foo1" << "foo2" << "foo3"); + m_combobox->setItemModel(strListModel); + + // select item 2 + m_combobox->setCurrentIndex(2); + QCOMPARE(viewPrivate->subtitle->text(), QString("foo2")); + // remove item1, index should change + strListModel->removeRow(1); + QCOMPARE(m_combobox->currentIndex(), 1); + QCOMPARE(viewPrivate->subtitle->text(), QString("foo2")); + // remove current item + strListModel->removeRow(1); + QCOMPARE(m_combobox->currentIndex(), -1); + QCOMPARE(viewPrivate->subtitle->text(), QString("!! Tap to Select")); + // check that after removing items everything looks ok + QCOMPARE(m_combobox->count(), 2); + m_combobox->setCurrentIndex(1); + QCOMPARE(m_combobox->currentIndex(), 1); + QCOMPARE(viewPrivate->subtitle->text(), QString("foo3")); + // add one item + strListModel->insertRow(0); + strListModel->setData(strListModel->index(0, 0), QString("fooX"), Qt::DisplayRole); + QCOMPARE(m_combobox->currentIndex(), 2); + QCOMPARE(viewPrivate->subtitle->text(), QString("foo3")); + + // change current item text + strListModel->setData(strListModel->index(2, 0), QString("lamb"), Qt::DisplayRole); + QCOMPARE(m_combobox->currentIndex(), 2); + QCOMPARE(viewPrivate->subtitle->text(), QString("lamb")); +} + +void Ut_DuiComboBox::testStringListModelSetStringList() +{ + DuiComboBoxView *view = (DuiComboBoxView *)m_combobox->view(); + DuiComboBoxViewPrivate *viewPrivate = view->d_func(); + + QStringListModel *strListModel = new QStringListModel(); + strListModel->setStringList(QStringList() << "foo0" << "foo1" << "foo2" << "foo3"); + m_combobox->setItemModel(strListModel); + + // select foo2 + m_combobox->setCurrentIndex(2); + // change string list completely + strListModel->setStringList(QStringList() << "bar0" << "bar1" << "bar2" << "bar3"); + QCOMPARE(m_combobox->currentIndex(), -1); + QCOMPARE(viewPrivate->subtitle->text(), QString("!! Tap to Select")); +} + +QTEST_APPLESS_MAIN(Ut_DuiComboBox) + diff --git a/tests/ut_duicombobox/ut_duicombobox.h b/tests/ut_duicombobox/ut_duicombobox.h new file mode 100644 index 000000000..8402fa411 --- /dev/null +++ b/tests/ut_duicombobox/ut_duicombobox.h @@ -0,0 +1,61 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUICOMBOBOX_H +#define UT_DUICOMBOBOX_H + +#include +#include +#include +#include + +#include + +Q_DECLARE_METATYPE(DuiComboBox *); + +class Ut_DuiComboBox : public QObject +{ + Q_OBJECT + +private slots: + void init(); + void cleanup(); + + void initTestCase(); + void cleanupTestCase(); + + void testItemModel(); + void testActions(); + void testCurrentIndex(); + void testFunctions(); + void testCancelEvent(); + void testIconVisibility(); + void testClickSlot(); + void testBuiltinModel(); + void testModelSwitching(); + void testStringListModel(); + void testStringListModelSetStringList(); + +private: + DuiComboBox *m_combobox; + QStringListModel m_model; + QStringList m_stringList; +}; + +#endif diff --git a/tests/ut_duicombobox/ut_duicombobox.pro b/tests/ut_duicombobox/ut_duicombobox.pro new file mode 100644 index 000000000..cc0d9f366 --- /dev/null +++ b/tests/ut_duicombobox/ut_duicombobox.pro @@ -0,0 +1,19 @@ + +include(../common_top.pri) +TARGET = ut_duicombobox + +# unit + +# unit test and unit +SOURCES += \ + ut_duicombobox.cpp \ + +# unit test and unit +HEADERS += \ + ut_duicombobox.h + +INCLUDEPATH += \ + ../../src/widgets/views \ + ../../src/widgets \ + +include(../common_bot.pri) diff --git a/tests/ut_duicompleter/.gitignore b/tests/ut_duicompleter/.gitignore new file mode 100644 index 000000000..09034eabc --- /dev/null +++ b/tests/ut_duicompleter/.gitignore @@ -0,0 +1 @@ +ut_duicompleter diff --git a/tests/ut_duicompleter/ut_duicompleter.cpp b/tests/ut_duicompleter/ut_duicompleter.cpp new file mode 100644 index 000000000..b4d8d8ffa --- /dev/null +++ b/tests/ut_duicompleter/ut_duicompleter.cpp @@ -0,0 +1,462 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duicompleter.h" + +#include +#include +#include +#include +#include +#include +#include +#include "duicompleter_p.h" +#include + +#include +#include +#include + +class CompleterTestModel : public QAbstractTableModel +{ +public : + CompleterTestModel(const QStringList &, const QStringList &, QObject *parent = 0); + ~CompleterTestModel(); + + //! \reimp + virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; + virtual QModelIndex parent(const QModelIndex &index) const; + virtual int rowCount(const QModelIndex &parent = QModelIndex()) const; + virtual int columnCount(const QModelIndex &parent = QModelIndex()) const; + virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + //! \reimp_end +private: + QStringList column1, column2; +}; + +CompleterTestModel::CompleterTestModel(const QStringList &list1, const QStringList &list2, QObject *parent) + : QAbstractTableModel(parent), + column1(list1), + column2(list2) +{ +} + +CompleterTestModel::~CompleterTestModel() +{ +} + +QModelIndex CompleterTestModel::index(int row, int column, const QModelIndex &parent) const +{ + return hasIndex(row, column, parent) ? createIndex(row, column, 0) : QModelIndex(); +} + +QModelIndex CompleterTestModel::parent(const QModelIndex & /* index */) const +{ + return QModelIndex(); +} + +int CompleterTestModel::columnCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent); + return 2; +} + +int CompleterTestModel::rowCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent); + int maxRow = qMax(column1.count(), column2.count()); + return maxRow; +} + +QVariant CompleterTestModel::data(const QModelIndex &index, int role) const +{ + Q_UNUSED(role); + int row = index.row(); + int column = index.column(); + QString value; + if (row < rowCount() && row >= 0 && column < 2 && column >= 0) { + if (column == 0 && row < column1.count()) + value = column1[row]; + else if (column == 1 && row < column2.count()) + value = column2[row]; + } + return QVariant(value); +} + +/*! + * Called once before the first testcase is run. + */ +void Ut_DuiCompleter::initTestCase() +{ + int dummyArgc = 1; + char *dummyArgv = (char *) "./ut_duicompleter"; + + // prevent loading of duiinputcontext because we don't need it + DuiApplication::setLoadDuiInputContext(false); + + m_app = new DuiApplication(dummyArgc, &dummyArgv); + m_window = new DuiApplicationWindow(); + QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8")); + + m_editWidget = new DuiTextEdit(DuiTextEditModel::MultiLine, ""); + m_subject = new DuiCompleter(); + m_editWidget->setCompleter(m_subject); + + m_window->scene()->addItem(m_editWidget); + m_window->scene()->addItem(m_subject); + QEvent activate(QEvent::WindowActivate); + qApp->sendEvent(m_window->scene(), &activate); + + QStringList modelColumn1; + modelColumn1.append("Tom While"); + modelColumn1.append("Nancy"); + modelColumn1.append("Jenny Branc"); + modelColumn1.append("Park Hammer"); + modelColumn1.append("Tom Branc"); + modelColumn1.append("TomasJerry"); + modelColumn1.append("Antony"); + modelColumn1.append("Branc"); + modelColumn1.append("Charles"); + modelColumn1.append("davids"); + modelColumn1.append("Edison"); + modelColumn1.append("Frank"); + QStringList modelColumn2; + modelColumn2.append(""); + modelColumn2.append(""); + modelColumn2.append(""); + modelColumn2.append(""); + modelColumn2.append(""); + modelColumn2.append(""); + modelColumn2.append(""); + modelColumn2.append(""); + modelColumn2.append(""); + modelColumn2.append(""); + modelColumn2.append(""); + modelColumn2.append(""); + testModel = new CompleterTestModel(modelColumn1, modelColumn2, this); +} + + +/*! + * Called once after the last testcase has finished. + */ +void Ut_DuiCompleter::cleanupTestCase() +{ + delete m_editWidget; + m_editWidget = 0; + delete m_subject; + m_subject = 0; + delete m_window; + m_window = 0; + delete m_app; + m_app = 0; +} + + +/*! + * Called before each testcase. + */ +void Ut_DuiCompleter::init() +{ + m_subject->setCandidateSourceModel(testModel); + m_subject->setCharactersToTrim(QString("<>")); + m_subject->setAcceptMultipleEntries(true); + m_editWidget->setText(""); + //set the completing time interval to 0, avoid wait + (static_cast(m_subject->d_ptr))->completerTimer->setInterval(0); + + m_window->scene()->setFocusItem(m_editWidget); +} + + +/*! + * Called after each testcase. + */ +void Ut_DuiCompleter::cleanup() +{ +} + +void Ut_DuiCompleter::checkConstruct() +{ + QStringList testlist; + testlist << "apple" << "appreciate" << "orange" << "offset"; + DuiCompleter *completer1 = new DuiCompleter(testlist); + QStringList testlist2; + QVariant var; + for (int i = 0; i < completer1->candidateSourceModel()->rowCount(); i++) { + var = completer1->candidateSourceModel()->data(completer1->candidateSourceModel()->index(i, 0)); + if (var.isValid()) + testlist2 << var.toString(); + } + QCOMPARE(testlist2, testlist); + delete completer1; + + QStringList testlist1; + testlist1.append("Tom While "); + testlist1.append("Nancy Lee "); + testlist1.append("Jenny Branc "); + testlist1.append("Park Hammer "); + testlist1.append("Tom Branc "); + testlist1.append("TomasJerry "); + testlist1.append("Nice Bright "); + testlist1.append("Janice Manus "); + + QStringList cs, c1, c2; + foreach(QString s, testlist1) { + cs = s.split("<"); + if (cs.count() >= 2) { + c1 << cs[0]; + c2 << QString('<' + cs[1]); + } + } + CompleterTestModel *testModel2 = new CompleterTestModel(c1, c2, this); + DuiCompleter *completer2 = new DuiCompleter(testModel2); + + for (int column = 0; column < completer2->candidateSourceModel()->columnCount(); column++) { + for (int row = 0; row < completer2->candidateSourceModel()->rowCount(); row++) { + var = completer2->candidateSourceModel()->data(completer2->candidateSourceModel()->index(row, 0)); + if (var.isValid()) { + QVERIFY(row < testlist1.count()); + QVERIFY(testlist1[row].indexOf(var.toString()) >= 0); + } + } + } + + delete testModel2; + delete completer2; + + DuiCompleter *completer3 = new DuiCompleter(); + completer3->setCandidateSourceModel(testModel); + delete completer3; + + +} + +void Ut_DuiCompleter::checkWidget() +{ + //test the widget + QCOMPARE(m_subject->widget(), m_editWidget); +} + + +void Ut_DuiCompleter::checkPrefix() +{ + QString prefix2 = "ap"; + m_editWidget->setText(prefix2); + m_subject->complete(); + while (qApp->hasPendingEvents()) { + qApp->processEvents(); + } + //the completion prefix should be the one set in text entry + QCOMPARE(m_subject->completionPrefix(), prefix2); +} + +void Ut_DuiCompleter::checkCandidates() +{ + QStringList testlist; + testlist << "apple" << "appreciate" << "orange" << "offset" + << "test" << "judgement" << "plane" << "never" << "northern"; + m_subject->setCandidateSourceModel(new QStringListModel(testlist, this)); + + //checke the candidates + QVariant var; + QStringList testlist2; + for (int i = 0; i < m_subject->candidateSourceModel()->rowCount(); i++) { + var = m_subject->candidateSourceModel()->data(m_subject->candidateSourceModel()->index(i, 0)); + if (var.isValid()) + testlist2 << var.toString(); + } + QCOMPARE(testlist2, testlist); + + QString prefix = "a"; + m_editWidget->setText(prefix); + m_subject->complete(); + while (qApp->hasPendingEvents()) { + qApp->processEvents(); + } + //check the matched candidates + QCOMPARE(m_subject->matchedCandidateModel()->rowCount(), 2); + var = m_subject->matchedCandidateModel()->data(m_subject->matchedCandidateModel()->index(0, 0)); + QString toBeConfirm = var.toString(); + m_subject->confirm(); + QVERIFY(m_editWidget->text() == toBeConfirm); + + //using model + m_subject->setCandidateSourceModel(testModel); + prefix = "tomas"; + m_editWidget->setText(prefix); + m_subject->complete(); + while (qApp->hasPendingEvents()) { + qApp->processEvents(); + } + QCOMPARE(m_subject->matchedCandidateModel()->rowCount(), 1); + prefix = "tom"; + m_editWidget->setText(prefix); + m_subject->complete(); + while (qApp->hasPendingEvents()) { + qApp->processEvents(); + } + QCOMPARE(m_subject->matchedCandidateModel()->rowCount(), 3); +} + +void Ut_DuiCompleter::checkMultipleEntries() +{ + m_subject->setAcceptMultipleEntries(true); + QVERIFY(m_subject->acceptMultipleEntries()); + + //first confirm + QString prefix = "tomas"; + m_editWidget->setText(prefix); + m_subject->complete(); + while (qApp->hasPendingEvents()) { + qApp->processEvents(); + } + QCOMPARE(m_subject->completionPrefix(), prefix); + QCOMPARE(m_subject->matchedCandidateModel()->rowCount(), 1); + m_subject->confirm(); + QCOMPARE(m_editWidget->text(), QString("tomas.j@example.com")); + + //second confirm + prefix = "nancy"; + m_editWidget->setText(QString("%1%2%3").arg(m_editWidget->text()).arg(",").arg(prefix)); + m_subject->complete(); + while (qApp->hasPendingEvents()) { + qApp->processEvents(); + } + QCOMPARE(m_subject->completionPrefix(), prefix); + m_subject->confirm(); + //acceptMultipleEntries will accept second confirm + QVERIFY(m_editWidget->text().indexOf(QString("nancy@example.com")) > 0); + + m_subject->setAcceptMultipleEntries(false); + QVERIFY(!m_subject->acceptMultipleEntries()); + + //first confirm + prefix = "tomas"; + m_editWidget->setText(prefix); + m_subject->complete(); + while (qApp->hasPendingEvents()) { + qApp->processEvents(); + } + QCOMPARE(m_subject->completionPrefix(), prefix); + QCOMPARE(m_subject->matchedCandidateModel()->rowCount(), 1); + m_subject->confirm(); + QCOMPARE(m_editWidget->text(), QString("tomas.j@example.com")); + + prefix = "nancy"; + m_editWidget->setText(QString("%1%2%3").arg(m_editWidget->text()).arg(",").arg(prefix)); + m_subject->complete(); + while (qApp->hasPendingEvents()) { + qApp->processEvents(); + } + m_subject->confirm(); + //if acceptMultipleEntries==false, will not accept second confirm + QVERIFY(m_editWidget->text().indexOf(QString("nancy@example.com")) == -1); + + m_subject->setAcceptMultipleEntries(false); + QVERIFY(!m_subject->acceptMultipleEntries()); +} + +void Ut_DuiCompleter::checkComplete() +{ + //using model, and give left and right delimiters + DuiCompleter *completer1 = new DuiCompleter(testModel); + completer1->setCharactersToTrim(QString("<>")); + DuiTextEdit *editWidget1 = new DuiTextEdit(DuiTextEditModel::MultiLine, "", 0); + editWidget1->setCompleter(completer1); + QCOMPARE(completer1->widget(), editWidget1); + m_window->scene()->addItem(editWidget1); + m_window->scene()->setFocusItem(editWidget1); + //set the completing time interval to 0, avoid wait + (static_cast(completer1->d_ptr))->completerTimer->setInterval(0); + + + QString prefix = "tom"; + editWidget1->setText(prefix); + completer1->complete(); + while (qApp->hasPendingEvents()) { + qApp->processEvents(); + } + + QCOMPARE(completer1->completionPrefix(), prefix); + QCOMPARE(completer1->matchedCandidateModel()->rowCount(), 3); + prefix = "tomas"; + editWidget1->setText(prefix); + completer1->complete(); + while (qApp->hasPendingEvents()) { + qApp->processEvents(); + } + QCOMPARE(completer1->completionPrefix(), prefix); + QCOMPARE(completer1->matchedCandidateModel()->rowCount(), 1); + QVariant var = completer1->matchedCandidateModel()->data(completer1->matchedCandidateModel()->index(0, 0)); + QVERIFY(var.toString().indexOf("") > 0); + + //after confirm, the left and right delimiters will be trimed + completer1->confirm(); + QCOMPARE(editWidget1->text(), QString("tomas.j@example.com")); + + //if the number of matched candidates is larger than 10, then complete won't get all candidates + //call queryAll() can get all + prefix = "com"; + editWidget1->setText(prefix); + completer1->complete(); + while (qApp->hasPendingEvents()) { + qApp->processEvents(); + } + QCOMPARE(completer1->completionPrefix(), prefix); + QVERIFY(completer1->matchedCandidateModel()->rowCount() < 12); + completer1->queryAll(); + QVERIFY(completer1->matchedCandidateModel()->rowCount() == 12); + + delete editWidget1; + delete completer1; +} + +void Ut_DuiCompleter::checkTrim() +{ + //if don't trim + m_subject->setCharactersToTrim(""); + QString prefix = "tomas"; + m_editWidget->setText(prefix); + m_subject->complete(); + while (qApp->hasPendingEvents()) { + qApp->processEvents(); + } + QCOMPARE(m_subject->completionPrefix(), prefix); + QCOMPARE(m_subject->matchedCandidateModel()->rowCount(), 1); + m_subject->confirm(); + QCOMPARE(m_editWidget->text(), QString("")); + + //if do trim + m_subject->setCharactersToTrim("<>"); + //second confirm + prefix = "nancy"; + m_editWidget->setText(prefix); + m_subject->complete(); + while (qApp->hasPendingEvents()) { + qApp->processEvents(); + } + QCOMPARE(m_subject->completionPrefix(), prefix); + m_subject->confirm(); + QCOMPARE(m_editWidget->text(), QString("nancy@example.com")); + +} + +QTEST_APPLESS_MAIN(Ut_DuiCompleter); + diff --git a/tests/ut_duicompleter/ut_duicompleter.h b/tests/ut_duicompleter/ut_duicompleter.h new file mode 100644 index 000000000..e305e0d97 --- /dev/null +++ b/tests/ut_duicompleter/ut_duicompleter.h @@ -0,0 +1,69 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUITEXTEDIT_H +#define UT_DUITEXTEDIT_H + +#include +#include + +class DuiApplication; +class DuiApplicationWindow; +class DuiTextEdit; +class DuiCompleter; +class CompleterTestModel; + +Q_DECLARE_METATYPE(DuiCompleter *); + +class Ut_DuiCompleter : public QObject +{ + Q_OBJECT + +private: + DuiTextEdit *m_editWidget; + DuiCompleter *m_subject; + DuiApplication *m_app; + DuiApplicationWindow *m_window; + CompleterTestModel *testModel; + QStringList modelColumn1, modelColumn2; + +private slots: + void initTestCase(); + void cleanupTestCase(); + + void init(); + void cleanup(); + + void checkConstruct(); + + void checkWidget(); + + void checkPrefix(); + + void checkCandidates(); + + void checkMultipleEntries(); + + void checkComplete(); + + void checkTrim(); +}; + +#endif + diff --git a/tests/ut_duicompleter/ut_duicompleter.pro b/tests/ut_duicompleter/ut_duicompleter.pro new file mode 100644 index 000000000..23b17700c --- /dev/null +++ b/tests/ut_duicompleter/ut_duicompleter.pro @@ -0,0 +1,16 @@ +include(../common_top.pri) + +TARGET = ut_duicompleter + +SOURCES += \ + ut_duicompleter.cpp \ + $$STUBSDIR/stubbase.cpp \ + +HEADERS += \ + $$STUBSDIR/duitheme_stub.h \ + $$STUBSDIR/duiwidgetview_stub.h \ + ut_duicompleter.h \ + +INCLUDEPATH += $$DUISRCDIR/widgets/ + +include(../common_bot.pri) diff --git a/tests/ut_duiconf/.gitignore b/tests/ut_duiconf/.gitignore new file mode 100644 index 000000000..ab43b2f97 --- /dev/null +++ b/tests/ut_duiconf/.gitignore @@ -0,0 +1 @@ +ut_duiconf diff --git a/tests/ut_duicontainer/.gitignore b/tests/ut_duicontainer/.gitignore new file mode 100644 index 000000000..f5f6b5a56 --- /dev/null +++ b/tests/ut_duicontainer/.gitignore @@ -0,0 +1 @@ +ut_duicontainer diff --git a/tests/ut_duicontainer/ut_duicontainer.cpp b/tests/ut_duicontainer/ut_duicontainer.cpp new file mode 100644 index 000000000..d40dace55 --- /dev/null +++ b/tests/ut_duicontainer/ut_duicontainer.cpp @@ -0,0 +1,246 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include +#include + +#include +#include "duicontainer_p.h" +#include +#include "views/duicontainerview_p.h" + +#include "ut_duicontainer.h" +#include "duiapplication.h" + +#include "duicancelevent.h" + +void Ut_DuiContainer::init() +{ + m_subject = new DuiContainer(); +} + +void Ut_DuiContainer::cleanup() +{ + delete m_subject; + m_subject = 0; +} +DuiApplication *app; + +void Ut_DuiContainer::initTestCase() +{ + static int argc = 1; + static char *app_name[1] = { (char *) "./ut_duicontainer" }; + app = new DuiApplication(argc, app_name); +} + +void Ut_DuiContainer::cleanupTestCase() +{ + delete app; +} + +void Ut_DuiContainer::centralWidget() +{ + // check that there exists centralWidget + QVERIFY(m_subject->centralWidget() != NULL); +} + +void Ut_DuiContainer::setCentralWidget() +{ + DuiWidget *tmp = new DuiWidget(); + + m_subject->setCentralWidget(tmp); + + // check that there exists centralWidget + QVERIFY(m_subject->centralWidget() == tmp); + + delete tmp; +} + +void Ut_DuiContainer::title() +{ + QString myQString("testing title()"); + + m_subject->setTitle(myQString); + QCOMPARE(m_subject->title(), myQString); +} + +void Ut_DuiContainer::text() +{ + QString myQString("testing text()"); + + m_subject->setText(myQString); + QCOMPARE(m_subject->text(), myQString); +} + +void Ut_DuiContainer::iconID() +{ + QString myIconID("testing iconID()"); + + m_subject->setIconID(myIconID); + QCOMPARE(m_subject->iconID(), myIconID); +} + +void Ut_DuiContainer::headerVisible() +{ + // default state + QVERIFY(m_subject->headerVisible() == true); + + m_subject->setHeaderVisible(false); + + QVERIFY(m_subject->headerVisible() == false); +} + +void Ut_DuiContainer::toggleHeaderVisible() +{ + // default state + QVERIFY(m_subject->headerVisible() == true); + + m_subject->toggleHeaderVisible(); + + QVERIFY(m_subject->headerVisible() == false); + + m_subject->toggleHeaderVisible(); + + QVERIFY(m_subject->headerVisible() == true); +} + + +void Ut_DuiContainer::toggleProgressIndicatorVisible() +{ + // default state + QVERIFY(m_subject->isProgressIndicatorVisible() == false); + + m_subject->toggleProgressIndicatorVisible(); + + QVERIFY(m_subject->isProgressIndicatorVisible() == true); + + m_subject->toggleProgressIndicatorVisible(); + + QVERIFY(m_subject->isProgressIndicatorVisible() == false); +} + +void Ut_DuiContainer::testCreatingViewImmediatelyInLayout() +{ + //Add the container to a layout then force the view to be created by calling minimumSize() + QGraphicsLinearLayout layout(Qt::Horizontal); + layout.addItem(m_subject); + m_subject->minimumSize(); + +} +void Ut_DuiContainer::testCreatingViewImmediately() +{ + //Force the view to be created by calling minimumSize() + //This checks BUG:126088 which causes a segmentation fault + m_subject->minimumSize(); +} + +void Ut_DuiContainer::testCancelEvent() +{ + QSignalSpy spy(m_subject, SIGNAL(headerClicked())); + + QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMousePress); + m_subject->mousePressEvent(&mouseEvent); + + DuiCancelEvent event; + m_subject->cancelEvent(&event); + + QVERIFY(spy.count() == 0); +} + +// test all of the set/get with both visible and invisble header, because it should work for instance +// that one sets the e.g. iconID now and makes the header visible later + +void Ut_DuiContainer::setTitleWithHeaderVisible() +{ + m_subject->setHeaderVisible(true); + m_subject->setTitle("title"); + + QCOMPARE(m_subject->title(), QString("title")); +} + +void Ut_DuiContainer::setTitleWithHeaderInvisible() +{ + m_subject->setHeaderVisible(false); + m_subject->setTitle("title"); + + QCOMPARE(m_subject->title(), QString("title")); +} + +void Ut_DuiContainer::setIconIDWithHeaderVisible() +{ + m_subject->setHeaderVisible(true); + m_subject->setIconID("Icon-close"); + + QCOMPARE(m_subject->iconID(), QString("Icon-close")); +} + +void Ut_DuiContainer::setIconIDWithHeaderInvisible() +{ + m_subject->setHeaderVisible(false); + m_subject->setIconID("Icon-close"); + + QCOMPARE(m_subject->iconID(), QString("Icon-close")); +} + +void Ut_DuiContainer::setTextWithHeaderVisible() +{ + m_subject->setHeaderVisible(true); + m_subject->setText("text"); + + QCOMPARE(m_subject->text(), QString("text")); +} + +void Ut_DuiContainer::setTextWithHeaderInvisible() +{ + m_subject->setHeaderVisible(false); + m_subject->setText("text"); + + QCOMPARE(m_subject->text(), QString("text")); +} + +void Ut_DuiContainer::setProgressIndicatorVisible() +{ + m_subject->setProgressIndicatorVisible(true); + QCOMPARE(m_subject->isProgressIndicatorVisible(), true); +} + +void Ut_DuiContainer::setProgressIndicatorInVisible() +{ + m_subject->setProgressIndicatorVisible(false); + QCOMPARE(m_subject->isProgressIndicatorVisible(), false); +} + +void Ut_DuiContainer::setProgressIndicatorWithHeaderVisible() +{ + m_subject->setHeaderVisible(true); + m_subject->setProgressIndicatorVisible(true); + QCOMPARE(m_subject->isProgressIndicatorVisible(), true); +} + +void Ut_DuiContainer::setProgressIndicatorWithHeaderInvisible() +{ + m_subject->setHeaderVisible(false); + m_subject->setProgressIndicatorVisible(true); + QCOMPARE(m_subject->isProgressIndicatorVisible(), true); +} + + +QTEST_APPLESS_MAIN(Ut_DuiContainer) diff --git a/tests/ut_duicontainer/ut_duicontainer.h b/tests/ut_duicontainer/ut_duicontainer.h new file mode 100644 index 000000000..89a27ae96 --- /dev/null +++ b/tests/ut_duicontainer/ut_duicontainer.h @@ -0,0 +1,72 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUICONTAINER_H +#define UT_DUICONTAINER_H + +#include +#include + +#include + +Q_DECLARE_METATYPE(DuiContainer *); + +class Ut_DuiContainer : public QObject +{ + Q_OBJECT + +private slots: + void init(); + void cleanup(); + void initTestCase(); + void cleanupTestCase(); + + void centralWidget(); + void setCentralWidget(); + + void title(); + void text(); + void iconID(); + void headerVisible(); + void toggleHeaderVisible(); + void testCreatingViewImmediatelyInLayout(); + void testCreatingViewImmediately(); + void testCancelEvent(); + void toggleProgressIndicatorVisible(); + + void setTitleWithHeaderVisible(); + void setTitleWithHeaderInvisible(); + + void setIconIDWithHeaderVisible(); + void setIconIDWithHeaderInvisible(); + + void setTextWithHeaderVisible(); + void setTextWithHeaderInvisible(); + + void setProgressIndicatorVisible(); + void setProgressIndicatorInVisible(); + + void setProgressIndicatorWithHeaderVisible(); + void setProgressIndicatorWithHeaderInvisible(); + +private: + DuiContainer *m_subject; +}; + +#endif diff --git a/tests/ut_duicontainer/ut_duicontainer.pro b/tests/ut_duicontainer/ut_duicontainer.pro new file mode 100644 index 000000000..886d82660 --- /dev/null +++ b/tests/ut_duicontainer/ut_duicontainer.pro @@ -0,0 +1,9 @@ +include(../common_top.pri) +INCLUDEPATH += $$DUISRCDIR/widgets $$DUISRCDIR/style + +TARGET = ut_duicontainer + +SOURCES += ut_duicontainer.cpp +HEADERS += ut_duicontainer.h + +include(../common_bot.pri) diff --git a/tests/ut_duidesktopentry/.gitignore b/tests/ut_duidesktopentry/.gitignore new file mode 100644 index 000000000..0281aa225 --- /dev/null +++ b/tests/ut_duidesktopentry/.gitignore @@ -0,0 +1 @@ +ut_duidesktopentry diff --git a/tests/ut_duidesktopentry/ut_duidesktopentry.cpp b/tests/ut_duidesktopentry/ut_duidesktopentry.cpp new file mode 100644 index 000000000..0392f9795 --- /dev/null +++ b/tests/ut_duidesktopentry/ut_duidesktopentry.cpp @@ -0,0 +1,453 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include + +#include +#include +#include "duidesktopentry_p.h" +#include "ut_duidesktopentry.h" +#include "duilocale_stub.h" + +QString gTranslationCatalog = ""; + +// qtTrId() stub +QString qtTrId(const char *id, int n) +{ + Q_UNUSED(n); + if (gTranslationCatalog.isEmpty()) { + return id; + } else { + if (gDefaultDuiLocaleStub.stubLastCallTo("installTrCatalog").parameter(0) == gTranslationCatalog) { + return QString("translated_foobar"); + } else { + return ""; + } + } +} + +// A string pair type. Used with key/value pairs in this test +typedef QPair Value; + +/* + * A simple container for Values + */ +class ValueList : public QList +{ +public: + /* + * Tests if there is a Value with the specified key. + */ + bool contains(const QString &key) const { + for (const_iterator it = constBegin(); it != constEnd(); it++) { + if (it->first == key) { + return true; + } + } + + return false; + } + + /* + * Appends a value to the container + */ + ValueList &operator<<(const Value &value) { + append(value); + return *this; + } +}; + +typedef QPair ValueGroup; +typedef QList ValueGroupList; + +// These key/value pairs are added to the desktop entry by default +// under the main (i.e. Desktop Entry) group. +const static ValueList defaultValues = (ValueList() << + Value("Type", "Application") << + Value("GenericName", "") << + Value("Exec", "Executable") << + Value("Name", "Unlocalized name")); + +// DuiDesktopEntry mock to be used as DuiDesktopEntry +class MockDuiDesktopEntry: public DuiDesktopEntry +{ +public: + MockDuiDesktopEntry(const ValueList &additionalValues = ValueList(), + const ValueGroupList &additionalGroups = ValueGroupList(), + bool includeDefaults = true) : + DuiDesktopEntry("fakefile.desktop") { + QByteArray byteArray; + + if (includeDefaults || !additionalValues.isEmpty()) { + byteArray = "[Desktop Entry]\n"; + } + + if (includeDefaults) { + // Put the default values to the desktop entry + foreach(const Value & value, defaultValues) { + if (!additionalValues.contains(value.first)) { // If a key is overwritten, don't add the default value + byteArray.append(value.first + "=" + value.second + "\n"); + } + } + } + + // Add user supplied additional values to the desktop entry + foreach(const Value & value, additionalValues) { + byteArray.append(value.first + "=" + value.second + "\n"); + } + + // Add user supplied additional groups and values to the desktop entry + foreach(const ValueGroup & group, additionalGroups) { + byteArray.append("[" + group.first + "]\n"); + foreach(const Value & value, group.second) { + byteArray.append(value.first + "=" + value.second + "\n"); + } + } + + // Parse the desktop entry + QBuffer buffer(&byteArray); + buffer.open(QIODevice::ReadOnly); + d_ptr->readDesktopFile(buffer, d_ptr->desktopEntriesMap); + + // FIXME modify the production code so that this part isn't needed in the unit test + QString TranslationCatalogKey = "Desktop Entry/X-DUI-translation-catalog"; + if (contains(TranslationCatalogKey)) { + DuiLocale locale; + // Load the catalog from disk if it's not yet loaded + locale.installTrCatalog(value(TranslationCatalogKey)); + } + } +}; + +// QFile stubs used by DuiDesktopEntry +bool QFile::exists() const +{ + return false; +} + +void Ut_DuiDesktopEntry::initTestCase() +{ + m_subject = NULL; +} + +void Ut_DuiDesktopEntry::init() +{ + gDefaultDuiLocaleStub.stubReset(); + gDefaultDuiLocaleStub.stubSetReturnValue("language", QString("fi")); + gDefaultDuiLocaleStub.stubSetReturnValue("country", QString("FI")); +} + +void Ut_DuiDesktopEntry::cleanup() +{ + delete m_subject; + m_subject = 0; + + gTranslationCatalog.clear(); +} + +void Ut_DuiDesktopEntry::testFileNameMethod() +{ + m_subject = new DuiDesktopEntry("foo.desktop"); + QCOMPARE(m_subject->fileName(), QString("foo.desktop")); +} + +void Ut_DuiDesktopEntry::testMissingType() +{ + m_subject = new MockDuiDesktopEntry(ValueList() << + Value("GenericName", "") << + Value("Exec", "Executable") << + Value("Name", "Unlocalized name"), + ValueGroupList(), false); + QCOMPARE(m_subject->isValid(), false); +} + +void Ut_DuiDesktopEntry::testMissingName() +{ + m_subject = new MockDuiDesktopEntry(ValueList() << + Value("Type", "Type") << + Value("Exec", "Executable"), + ValueGroupList(), false); + QCOMPARE(m_subject->isValid(), false); +} + +void Ut_DuiDesktopEntry::testIsHidden() +{ + m_subject = new MockDuiDesktopEntry(); + QCOMPARE(m_subject->hidden(), false); + delete m_subject; + + m_subject = new MockDuiDesktopEntry(ValueList() << Value("Hidden", "true")); + QCOMPARE(m_subject->hidden(), true); +} + +void Ut_DuiDesktopEntry::testMissingExec() +{ + m_subject = new MockDuiDesktopEntry(ValueList() << + Value("Type", "Application") << + Value("GenericName", "") << + Value("Name", "Unlocalized name"), + ValueGroupList(), false); + QCOMPARE(m_subject->isValid(), false); +} + +void Ut_DuiDesktopEntry::testApplication() +{ + m_subject = new MockDuiDesktopEntry(); + QCOMPARE(m_subject->isValid(), true); +} + +void Ut_DuiDesktopEntry::testLink() +{ + m_subject = new MockDuiDesktopEntry(ValueList() << Value("Type", "Link") << Value("URL", "http://www.foobar.org")); + QCOMPARE(m_subject->isValid(), true); + QCOMPARE(m_subject->type(), QString("Link")); + delete m_subject; + + // Type Link requires an URL key + m_subject = new MockDuiDesktopEntry(ValueList() << Value("Type", "Link")); + QCOMPARE(m_subject->isValid(), false); +} + +void Ut_DuiDesktopEntry::testVersion() +{ + m_subject = new MockDuiDesktopEntry(ValueList() << Value("Version", "")); + QCOMPARE(m_subject->version(), QString("")); + delete m_subject; + + m_subject = new MockDuiDesktopEntry(ValueList() << Value("Version", "1.0")); + QCOMPARE(m_subject->version(), QString("1.0")); +} + +void Ut_DuiDesktopEntry::testGenericName() +{ + m_subject = new MockDuiDesktopEntry(); + QCOMPARE(m_subject->genericName(), QString("")); + delete m_subject; + + m_subject = new MockDuiDesktopEntry(ValueList() << Value("GenericName", "foo")); + QCOMPARE(m_subject->genericName(), QString("foo")); +} + +void Ut_DuiDesktopEntry::testMisc() +{ + m_subject = new MockDuiDesktopEntry(ValueList() << + Value("Comment", "foo comment") << + Value("Icon", "foo icon") << + Value("TryExec", "foo tryexec") << + Value("Path", "foo path")); + QCOMPARE(m_subject->comment(), QString("foo comment")); + QCOMPARE(m_subject->icon(), QString("foo icon")); + QCOMPARE(m_subject->tryExec(), QString("foo tryexec")); + QCOMPARE(m_subject->path(), QString("foo path")); +} + +void Ut_DuiDesktopEntry::testNoDisplay() +{ + m_subject = new MockDuiDesktopEntry(); + QCOMPARE(m_subject->noDisplay(), false); + delete m_subject; + + m_subject = new MockDuiDesktopEntry(ValueList() << Value("NoDisplay", "true")); + QCOMPARE(m_subject->noDisplay(), true); +} + +void Ut_DuiDesktopEntry::testTerminal() +{ + m_subject = new MockDuiDesktopEntry(); + QCOMPARE(m_subject->terminal(), false); + delete m_subject; + + m_subject = new MockDuiDesktopEntry(ValueList() << Value("Terminal", "true")); + QCOMPARE(m_subject->terminal(), true); +} + +void Ut_DuiDesktopEntry::testStartupNotify() +{ + m_subject = new MockDuiDesktopEntry(); + QCOMPARE(m_subject->startupNotify(), false); + delete m_subject; + + m_subject = new MockDuiDesktopEntry(ValueList() << Value("StartupNotify", "true")); + QCOMPARE(m_subject->startupNotify(), true); +} + +void Ut_DuiDesktopEntry::testLocalizedNameLogicalId() +{ + ValueList additional; + additional << Value("X-DUI-logical-id", "foobar"); + m_subject = new MockDuiDesktopEntry(additional); + QCOMPARE(m_subject->name(), QString("!! Unlocalized name")); + delete m_subject; + + gTranslationCatalog = "test"; + additional << Value("X-DUI-translation-catalog", "test"); + m_subject = new MockDuiDesktopEntry(additional); + QCOMPARE(m_subject->name(), QString("translated_foobar")); +} + +void Ut_DuiDesktopEntry::testLocalizedNamePostfix() +{ + m_subject = new MockDuiDesktopEntry(ValueList() << Value("Name[fi_FI]", "testtext")); + QCOMPARE(m_subject->name(), QString("testtext")); + delete m_subject; + + gDefaultDuiLocaleStub.stubSetReturnValue("language", QString("en")); + gDefaultDuiLocaleStub.stubSetReturnValue("country", QString("GB")); + gDefaultDuiLocaleStub.stubSetReturnValue("variant", QString("")); + + m_subject = new MockDuiDesktopEntry(ValueList() << Value("Name[en_GB@unknown]", "foo")); + QCOMPARE(m_subject->name(), QString("Unlocalized name")); + delete m_subject; + + m_subject = new MockDuiDesktopEntry(ValueList() << Value("Name[en_GB]", "barfoo")); + QCOMPARE(m_subject->name(), QString("barfoo")); + delete m_subject; + + m_subject = new MockDuiDesktopEntry(ValueList() << Value("Name[en]", "barfoo")); + QCOMPARE(m_subject->name(), QString("barfoo")); + delete m_subject; + + gDefaultDuiLocaleStub.stubSetReturnValue("language", QString("en")); + gDefaultDuiLocaleStub.stubSetReturnValue("country", QString("GB")); + gDefaultDuiLocaleStub.stubSetReturnValue("variant", QString("piglatin")); + + m_subject = new MockDuiDesktopEntry(ValueList() << Value("Name[en_GB@piglatin]", "bar")); + QCOMPARE(m_subject->name(), QString("bar")); + delete m_subject; + + m_subject = new MockDuiDesktopEntry(ValueList() << Value("Name[en_GB]", "bar")); + QCOMPARE(m_subject->name(), QString("bar")); + delete m_subject; + + m_subject = new MockDuiDesktopEntry(ValueList() << Value("Name[en]", "bar")); + QCOMPARE(m_subject->name(), QString("bar")); + delete m_subject; + + m_subject = new MockDuiDesktopEntry(ValueList() << Value("Name[en@piglatin]", "bar")); + QCOMPARE(m_subject->name(), QString("bar")); + delete m_subject; + + m_subject = new MockDuiDesktopEntry(ValueList() << Value("Name[unknown]", "foobar")); + QCOMPARE(m_subject->name(), QString("Unlocalized name")); +} + +void Ut_DuiDesktopEntry::testMultipleValues() +{ + m_subject = new MockDuiDesktopEntry(ValueList() << Value("Categories", "cat1;;cat2\\;;ca\\;t3;")); + QStringList categories = m_subject->categories(); + QCOMPARE(categories.count(), 4); + QCOMPARE(categories.at(0), QString("cat1")); + QCOMPARE(categories.at(1), QString("")); + QCOMPARE(categories.at(2), QString("cat2;")); + QCOMPARE(categories.at(3), QString("ca;t3")); +} + +void Ut_DuiDesktopEntry::testMultipleValuesWithoutTrailingSemicolon() +{ + m_subject = new MockDuiDesktopEntry(ValueList() << Value("Categories", "category")); + QCOMPARE(m_subject->isValid(), false); +} + +void Ut_DuiDesktopEntry::testMultipleValuesWithEscapedTrailingSemicolon() +{ + m_subject = new MockDuiDesktopEntry(ValueList() << Value("Categories", "category\\;")); + QCOMPARE(m_subject->isValid(), false); +} + +void Ut_DuiDesktopEntry::testCommentedLine() +{ + m_subject = new MockDuiDesktopEntry(ValueList() << Value("#TestCommentedLine", "comment")); + QCOMPARE(m_subject->contains("Desktop Entry/#TestCommentedLine"), false); + QCOMPARE(m_subject->contains("Desktop Entry/TestCommentedLine"), false); +} + +void Ut_DuiDesktopEntry::testMultipleKeys() +{ + // Note the space after the key name - that is the important part here + m_subject = new MockDuiDesktopEntry(ValueList() << Value("Name ", "foo")); + // Multiple similarly named keys doesn't render the entry invalid + QCOMPARE(m_subject->isValid(), true); + // The first key is used, the second is ignored + QCOMPARE(m_subject->name(), QString("Unlocalized name")); +} + +void Ut_DuiDesktopEntry::testEqualSignValues() +{ + m_subject = new MockDuiDesktopEntry(ValueList() << Value("ExampleKey", "Type1=Type2")); + QCOMPARE(m_subject->value("Desktop Entry/ExampleKey"), QString("Type1=Type2")); +} + +void Ut_DuiDesktopEntry::testKeyStartingWithWhitespaces() +{ + m_subject = new MockDuiDesktopEntry(ValueList() << Value(" LineStartingWithSpace", "line with space")); + QCOMPARE(m_subject->contains("Desktop Entry/LineStartingWithSpace"), true); + QCOMPARE(m_subject->value("Desktop Entry/LineStartingWithSpace"), QString("line with space")); +} + +void Ut_DuiDesktopEntry::testInvalidKeys() +{ + m_subject = new MockDuiDesktopEntry(ValueList() << Value(";", ";=") << Value("?", "?") << Value("ad!", "123")); + // Invalid key names are just bypassed. Doesn't render the entry invalid + QCOMPARE(m_subject->isValid(), true); + QCOMPARE(m_subject->contains("Desktop Entry/;"), false); + QCOMPARE(m_subject->contains("Desktop Entry/?"), false); + QCOMPARE(m_subject->contains("Desktop Entry/ad!"), false); +} + +void Ut_DuiDesktopEntry::testMultipleGroupNames() +{ + ValueGroupList additionalGroups; + additionalGroups.append(ValueGroup("New Group", ValueList() << Value("StartupNotify", "true"))); + additionalGroups.append(ValueGroup("Desktop Entry", ValueList() << Value("StartupNotify", "true"))); + m_subject = new MockDuiDesktopEntry(ValueList(), additionalGroups); + // Multiple similarly named groups renders the entry invalid + QCOMPARE(m_subject->isValid(), false); + QCOMPARE(m_subject->contains("Desktop Entry/StartupNotify"), true); + QCOMPARE(m_subject->contains("New Group/StartupNotify"), true); +} + +void Ut_DuiDesktopEntry::testGroupNameLocation() +{ + ValueGroupList additionalGroups; + additionalGroups.append(ValueGroup("Test Group", ValueList() << Value("foo", "foo"))); + additionalGroups.append(ValueGroup("Desktop Entry", ValueList() << Value("bar", "bar"))); + m_subject = new MockDuiDesktopEntry(ValueList(), additionalGroups, false); + QCOMPARE(m_subject->isValid(), false); +} + +void Ut_DuiDesktopEntry::testInvalidGroupNames() +{ + { + ValueGroupList additionalGroups; + additionalGroups.append(ValueGroup("Desktop\n Entry", ValueList() << Value("bar", "bar"))); + m_subject = new MockDuiDesktopEntry(ValueList(), additionalGroups, false); + QCOMPARE(m_subject->isValid(), false); + } + delete m_subject; + + { + ValueGroupList additionalGroups; + additionalGroups.append(ValueGroup("\tDesktop Entry", ValueList() << Value("foo", "foo"))); + m_subject = new MockDuiDesktopEntry(ValueList(), additionalGroups, false); + QCOMPARE(m_subject->isValid(), false); + } +} + +QTEST_MAIN(Ut_DuiDesktopEntry) diff --git a/tests/ut_duidesktopentry/ut_duidesktopentry.h b/tests/ut_duidesktopentry/ut_duidesktopentry.h new file mode 100644 index 000000000..ca6eb0d84 --- /dev/null +++ b/tests/ut_duidesktopentry/ut_duidesktopentry.h @@ -0,0 +1,69 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIDESKTOPENTRY_H +#define UT_DUIDESKTOPENTRY_H + +#include +#include + +// the real unit/duidesktopentry class declaration +#include + +class Ut_DuiDesktopEntry : public QObject +{ + Q_OBJECT + +private: + DuiDesktopEntry *m_subject; + +private slots: + void initTestCase(); + void init(); + void cleanup(); + + void testFileNameMethod(); + void testMissingType(); + void testMissingName(); + void testMissingExec(); + void testIsHidden(); + void testApplication(); + void testLink(); + void testVersion(); + void testGenericName(); + void testMisc(); + + void testNoDisplay(); + void testTerminal(); + void testStartupNotify(); + void testLocalizedNameLogicalId(); + void testLocalizedNamePostfix(); + void testMultipleValues(); + void testMultipleValuesWithoutTrailingSemicolon(); + void testMultipleValuesWithEscapedTrailingSemicolon(); + void testCommentedLine(); + void testEqualSignValues(); + void testMultipleKeys(); + void testKeyStartingWithWhitespaces(); + void testInvalidKeys(); + void testMultipleGroupNames(); + void testGroupNameLocation(); + void testInvalidGroupNames(); +}; +#endif diff --git a/tests/ut_duidesktopentry/ut_duidesktopentry.pro b/tests/ut_duidesktopentry/ut_duidesktopentry.pro new file mode 100644 index 000000000..366ce4464 --- /dev/null +++ b/tests/ut_duidesktopentry/ut_duidesktopentry.pro @@ -0,0 +1,20 @@ +include(../common_top.pri) + +LIBS -= ../../lib/libdui.so + +TARGET = ut_duidesktopentry + +HEADERS += ut_duidesktopentry.h \ + $$DUISRCDIR/core/duidesktopentry.h \ + $$DUISRCDIR/core/duidesktopentry_p.h \ + $$DUISRCDIR/i18n/duilocale.h \ + $$STUBSDIR/stubbase.h + +SOURCES += ut_duidesktopentry.cpp \ + $$DUISRCDIR/core/duidesktopentry.cpp \ + $$STUBSDIR/stubbase.cpp + + +INCLUDEPATH += $$DUISRCDIR/core + +include(../common_bot.pri) diff --git a/tests/ut_duidialog/.gitignore b/tests/ut_duidialog/.gitignore new file mode 100644 index 000000000..893ca471e --- /dev/null +++ b/tests/ut_duidialog/.gitignore @@ -0,0 +1 @@ +ut_duidialog diff --git a/tests/ut_duidialog/ut_duidialog.cpp b/tests/ut_duidialog/ut_duidialog.cpp new file mode 100644 index 000000000..35384524b --- /dev/null +++ b/tests/ut_duidialog/ut_duidialog.cpp @@ -0,0 +1,244 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include + +#include + +#include +#include +#include + +#include "ut_duidialog.h" + +void Ut_DuiDialog::initTestCase() +{ + app = buildApp(1, "./ut_duidialog"); +} + +void Ut_DuiDialog::cleanupTestCase() +{ + delete app; +} + +void Ut_DuiDialog::init() +{ + dialog = new DuiDialog(); + + // For some reason libdui wants the controller to be notified about the existence of a + // new model (via setupModel()) only when the event processing loop is reached. + // Therefore, let's make sure setupModel() is called. + // Otherwise the controller won't know about the new model and will therefore + // lose all model::modified() signals. + QApplication::processEvents(QEventLoop::WaitForMoreEvents, 10); +} + +void Ut_DuiDialog::cleanup() +{ + delete dialog; +} + +void Ut_DuiDialog::constructorWithParameters() +{ + QString title("Title"); + DuiDialog *dlg = new DuiDialog(title, + Dui::OkButton | Dui::CancelButton | Dui::YesToAllButton | + Dui::NoButton | Dui::ResetButton); + + QCOMPARE(dlg->title(), title); + QVERIFY(dlg->button(Dui::OkButton)); + QVERIFY(dlg->button(Dui::CancelButton)); + QVERIFY(dlg->button(Dui::YesToAllButton)); + QVERIFY(dlg->button(Dui::NoButton)); + QVERIFY(dlg->button(Dui::ResetButton)); + + QVERIFY(!dlg->button(Dui::SaveButton)); + QVERIFY(!dlg->button(Dui::SaveAllButton)); + QVERIFY(!dlg->button(Dui::OpenButton)); + QVERIFY(!dlg->button(Dui::YesButton)); + QVERIFY(!dlg->button(Dui::NoToAllButton)); + QVERIFY(!dlg->button(Dui::AbortButton)); + QVERIFY(!dlg->button(Dui::RetryButton)); + QVERIFY(!dlg->button(Dui::IgnoreButton)); + QVERIFY(!dlg->button(Dui::CloseButton)); + QVERIFY(!dlg->button(Dui::DiscardButton)); + QVERIFY(!dlg->button(Dui::HelpButton)); + QVERIFY(!dlg->button(Dui::ApplyButton)); + QVERIFY(!dlg->button(Dui::RestoreDefaultsButton)); +} + +void Ut_DuiDialog::initVals() +{ + QCOMPARE(dialog->clickedButton(), (DuiButtonModel *)NULL); +} + +void Ut_DuiDialog::settersAndGetters() +{ + for (int i = 0; i < 5; i++) { + int val = i * 345; // Arbitrary + dialog->setResult(val); + QCOMPARE(dialog->result(), val); + } + + for (int i = 0; i < 4; i++) { + bool val = i % 2 ? false : true; + dialog->setButtonBoxVisible(val); + QCOMPARE(dialog->isButtonBoxVisible(), val); + } + + for (int i = 0; i < 4; i++) { + bool val = i % 2 ? false : true; + dialog->setTitleBarVisible(val); + QCOMPARE(dialog->isTitleBarVisible(), val); + } + + for (int i = 0; i < 4; i++) { + bool val = i % 2 ? false : true; + dialog->setWindowModal(val); + QCOMPARE(dialog->isWindowModal(), val); + } + + { + QString val; + val = QString("Test string 1"); + dialog->setTitle(val); + QCOMPARE(dialog->title(), val); + + val = QString("Something else"); + dialog->setTitle(val); + QCOMPARE(dialog->title(), val); + } + + { + DuiButton *button1 = new DuiButton(); + DuiButton *button2 = new DuiButton(); + + dialog->setCentralWidget(button1); + QCOMPARE(dialog->centralWidget(), button1); + dialog->setCentralWidget(button2); + QCOMPARE(dialog->centralWidget(), button2); + } +} + +void Ut_DuiDialog::addStandardButtons() +{ + DuiButtonModel *b1 = dialog->addButton(Dui::AbortButton); + DuiButtonModel *b2 = dialog->addButton(Dui::OkButton); + DuiButtonModel *b4 = dialog->addButton(Dui::NoButton); + + QCOMPARE(dialog->button(Dui::AbortButton), b1); + QCOMPARE(dialog->button(Dui::OkButton), b2); + QCOMPARE(dialog->button(Dui::NoButton), b4); + QVERIFY(dialog->button(Dui::YesToAllButton) == 0); +} + +void Ut_DuiDialog::addInvalidStandardButton() +{ + DuiButtonModel *buttonModel = dialog->addButton(Dui::NoStandardButton); + QVERIFY(buttonModel == NULL); +} + +void Ut_DuiDialog::addExistingStandardButton() +{ + DuiButtonModel *b1 = dialog->addButton(Dui::OkButton); + DuiButtonModel *b2 = dialog->addButton(Dui::OkButton); + + QCOMPARE(dialog->button(Dui::OkButton), b1); + QCOMPARE(dialog->button(Dui::OkButton), b2); + QVERIFY(b1 == b2); +} + +void Ut_DuiDialog::acceptDialog() +{ + QSignalSpy spyChanged1(dialog, SIGNAL(accepted())); + QSignalSpy spyChanged2(dialog, SIGNAL(rejected())); + QSignalSpy spyChanged3(dialog, SIGNAL(finished(int))); + + DuiButtonModel *b1 = dialog->addButton("test button 1"); + dialog->addButton("test button 2"); + b1->click(); + + QCOMPARE(spyChanged1.count(), 1); + QCOMPARE(spyChanged2.count(), 0); + QCOMPARE(spyChanged3.count(), 1); +} + +void Ut_DuiDialog::removeButton() +{ + QSignalSpy spyChanged1(dialog, SIGNAL(accepted())); + + DuiButtonModel *b1 = dialog->addButton("test button 1"); + b1->increaseReferenceCount(); // otherwise it will get deleted on removeButon() call. + dialog->addButton("test button 2"); + + dialog->removeButton(b1); + b1->click(); + delete b1; + b1 = 0; + + QCOMPARE(spyChanged1.count(), 0); +} + +void Ut_DuiDialog::rejectDialog() +{ + QSignalSpy spyChanged1(dialog, SIGNAL(accepted())); + QSignalSpy spyChanged2(dialog, SIGNAL(rejected())); + QSignalSpy spyChanged3(dialog, SIGNAL(finished(int))); + + dialog->addButton("test button 1"); + DuiButtonModel *b2 = dialog->addButton(Dui::CancelButton); + b2->click(); + + QCOMPARE(spyChanged1.count(), 0); + QCOMPARE(spyChanged2.count(), 1); + QCOMPARE(spyChanged3.count(), 1); +} + +DuiApplication *Ut_DuiDialog::buildApp(int count, const QString ¶ms) +{ + QChar sep(' '); + char *argv[MAX_PARAMS]; + int x = 0; + + QStringList list = params.split(sep); + QStringListIterator it(list); + while (it.hasNext() && x < MAX_PARAMS) { + argv[x++] = strdup(it.next().toLocal8Bit().constData()); + } + return new DuiApplication(count, argv); +} + +void Ut_DuiDialog::dismissDialog() +{ + QSignalSpy spyChanged1(dialog, SIGNAL(accepted())); + QSignalSpy spyChanged2(dialog, SIGNAL(rejected())); + QSignalSpy spyChanged3(dialog, SIGNAL(finished(int))); + + //ABI FREEZE: Release this + //dialog->dismissNow(); + dialog->close(); + + QCOMPARE(spyChanged1.count(), 0); + QCOMPARE(spyChanged2.count(), 1); + QCOMPARE(spyChanged3.count(), 1); +} + +QTEST_APPLESS_MAIN(Ut_DuiDialog); diff --git a/tests/ut_duidialog/ut_duidialog.h b/tests/ut_duidialog/ut_duidialog.h new file mode 100644 index 000000000..e116a0499 --- /dev/null +++ b/tests/ut_duidialog/ut_duidialog.h @@ -0,0 +1,59 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIDIALOG_H +#define UT_DUIDIALOG_H + +#include +#include +#include + +class DuiApplication; + +#define MAX_PARAMS 10 +class Ut_DuiDialog: public QObject +{ + Q_OBJECT + +private: + DuiDialog *dialog; + DuiApplication *app; + DuiApplication *buildApp(int count, const QString ¶ms); + +private slots: + + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + + void constructorWithParameters(); + + void initVals(); + void settersAndGetters(); + void addStandardButtons(); + void addInvalidStandardButton(); + void addExistingStandardButton(); + void acceptDialog(); + void removeButton(); + void rejectDialog(); + void dismissDialog(); +}; + +#endif diff --git a/tests/ut_duidialog/ut_duidialog.pro b/tests/ut_duidialog/ut_duidialog.pro new file mode 100644 index 000000000..00fd5f298 --- /dev/null +++ b/tests/ut_duidialog/ut_duidialog.pro @@ -0,0 +1,13 @@ +include(../common_top.pri) +INCLUDEPATH += $$DUISRCDIR/widgets $$DUISRCDIR/style + +TARGET = ut_duidialog + +# Input +HEADERS += \ + ut_duidialog.h \ + +SOURCES += \ + ut_duidialog.cpp \ + +include(../common_bot.pri) diff --git a/tests/ut_duidialogview/.gitignore b/tests/ut_duidialogview/.gitignore new file mode 100644 index 000000000..21ba583c8 --- /dev/null +++ b/tests/ut_duidialogview/.gitignore @@ -0,0 +1 @@ +ut_duidialogview diff --git a/tests/ut_duidialogview/ut_duidialogview.cpp b/tests/ut_duidialogview/ut_duidialogview.cpp new file mode 100644 index 000000000..0581a058e --- /dev/null +++ b/tests/ut_duidialogview/ut_duidialogview.cpp @@ -0,0 +1,140 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duidialogview.h" + +#include + +void Ut_DuiDialogView::init() +{ +} + +void Ut_DuiDialogView::cleanup() +{ +} + +void Ut_DuiDialogView::initTestCase() +{ + static int argc = 1; + static char *app_name[1] = { (char *) "./ut_duidialogview" }; + app = new DuiApplication(argc, app_name); + + controller = new DuiDialog(); + subject = new DuiDialogView(controller); + controller->setView(subject); + model = controller->model(); +} + +void Ut_DuiDialogView::cleanupTestCase() +{ + delete controller; + controller = 0; + + delete app; + app = 0; +} + +void Ut_DuiDialogView::closeButtonVisibility() +{ + QGraphicsWidget *dialogCloseButton; + + dialogCloseButton = fetchWidget(*controller, "DuiDialogCloseButton"); + + QVERIFY(dialogCloseButton != 0); + + QCOMPARE(dialogCloseButton->isVisible(), true); + + model->setCloseButtonVisible(false); + + QCOMPARE(dialogCloseButton->isVisible(), false); + + model->setCloseButtonVisible(true); + + QCOMPARE(dialogCloseButton->isVisible(), true); +} + +void Ut_DuiDialogView::titleBarVisibility() +{ + QGraphicsWidget *dialogTitleBar = 0; + QGraphicsWidget *widget = 0; + + dialogTitleBar = fetchWidget(*controller, "DuiDialogTitleBar"); + + QVERIFY(dialogTitleBar != 0); + + QCOMPARE(dialogTitleBar->isVisible(), true); + + model->setTitleBarVisible(false); + + QCOMPARE(dialogTitleBar->isVisible(), false); + + // title bar must also be removed from the dialog box layout, + // otherwise it will still take space in the layout + widget = fetchWidget(*controller, "DuiDialogTitleBar"); + QVERIFY(widget == 0); + + model->setTitleBarVisible(true); + + QCOMPARE(dialogTitleBar->isVisible(), true); + + // title bar must be back to dialog's layout. + widget = fetchWidget(*controller, "DuiDialogTitleBar"); + QVERIFY(widget == dialogTitleBar); +} + +QGraphicsWidget *Ut_DuiDialogView::fetchWidget(QGraphicsWidget &widget, + const QString &objectName) const +{ + QGraphicsWidget *targetWidget = 0; + + if (widget.objectName() == objectName) { + targetWidget = &widget; + } else if (widget.layout() != 0) { + targetWidget = fetchWidget(*(widget.layout()), objectName); + } + + return targetWidget; +} + +QGraphicsWidget *Ut_DuiDialogView::fetchWidget(QGraphicsLayout &layout, + const QString &objectName) const +{ + QGraphicsWidget *targetWidget = 0; + QGraphicsLayoutItem *layoutItem; + QGraphicsItem *item; + + for (int i = 0; i < layout.count() && targetWidget == 0; i++) { + layoutItem = layout.itemAt(i); + + if (layoutItem->isLayout()) { + targetWidget = fetchWidget(*static_cast(layoutItem), objectName); + } else { + item = layoutItem->graphicsItem(); + + if (item->isWidget()) { + QGraphicsWidget *widget = static_cast(item); + targetWidget = fetchWidget(*widget, objectName); + } + } + } + + return targetWidget; +} + +QTEST_APPLESS_MAIN(Ut_DuiDialogView) diff --git a/tests/ut_duidialogview/ut_duidialogview.h b/tests/ut_duidialogview/ut_duidialogview.h new file mode 100644 index 000000000..f2930d8a2 --- /dev/null +++ b/tests/ut_duidialogview/ut_duidialogview.h @@ -0,0 +1,56 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIDIALOGVIEW_H +#define UT_DUIDIALOGVIEW_H + +#include +#include + +#include +#include +#include + +//Q_DECLARE_METATYPE(DuiWidgetView*); + +class Ut_DuiDialogView : public QObject +{ + Q_OBJECT + +private slots: + void init(); + void cleanup(); + void initTestCase(); + void cleanupTestCase(); + void closeButtonVisibility(); + void titleBarVisibility(); + +private: + QGraphicsWidget *fetchWidget(QGraphicsWidget &widget, + const QString &objectName) const; + QGraphicsWidget *fetchWidget(QGraphicsLayout &layout, + const QString &objectName) const; + + DuiDialogView *subject; + DuiDialog *controller; + DuiDialogModel *model; + DuiApplication *app; +}; + +#endif diff --git a/tests/ut_duidialogview/ut_duidialogview.pro b/tests/ut_duidialogview/ut_duidialogview.pro new file mode 100644 index 000000000..09dee2efc --- /dev/null +++ b/tests/ut_duidialogview/ut_duidialogview.pro @@ -0,0 +1,15 @@ +include(../common_top.pri) + +INCLUDEPATH += $$DUISRCDIR/widgets $$DUISRCDIR/style + +TARGET = ut_duidialogview + +# unit test and unit +SOURCES += \ + ut_duidialogview.cpp \ + +# unit test and unit +HEADERS += \ + ut_duidialogview.h \ + +include(../common_bot.pri) diff --git a/tests/ut_duiextendingbackgroundview/.gitignore b/tests/ut_duiextendingbackgroundview/.gitignore new file mode 100644 index 000000000..f33d11e66 --- /dev/null +++ b/tests/ut_duiextendingbackgroundview/.gitignore @@ -0,0 +1 @@ +ut_duiextendingbackgroundview diff --git a/tests/ut_duiextendingbackgroundview/ut_duiextendingbackgroundview.cpp b/tests/ut_duiextendingbackgroundview/ut_duiextendingbackgroundview.cpp new file mode 100644 index 000000000..81807f413 --- /dev/null +++ b/tests/ut_duiextendingbackgroundview/ut_duiextendingbackgroundview.cpp @@ -0,0 +1,119 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "ut_duiextendingbackgroundview.h" + +TestExtendingBackgroundView::TestExtendingBackgroundView(DuiWidgetController *controller) : DuiExtendingBackgroundView(controller) +{ +} + +QRectF TestExtendingBackgroundView::boundingRect() +{ + return DuiExtendingBackgroundView::boundingRect(); +} + +QRectF TestExtendingBackgroundView::geometry() +{ + return DuiExtendingBackgroundView::geometry(); +} + +DuiExtendingBackgroundStyle *TestExtendingBackgroundView::modifiableStyle() +{ + DuiExtendingBackgroundStyleContainer &sc = style(); + const DuiExtendingBackgroundStyle *const_s = sc.operator ->(); + DuiExtendingBackgroundStyle *s = const_cast(const_s); + return s; +} + + +void Ut_DuiExtendingBackgroundView::initTestCase() +{ + static int argc = 1; + static char *app_name[1] = { (char *) "./ut_duiextendingbackgroundview" }; + app = new DuiApplication(argc, app_name); + appWin = new DuiApplicationWindow; +} + +void Ut_DuiExtendingBackgroundView::cleanupTestCase() +{ + delete appWin; + delete app; +} + +void Ut_DuiExtendingBackgroundView::init() +{ + controller = new DuiWidgetController; + view = new TestExtendingBackgroundView(controller); + controller->setView(view); +} + +void Ut_DuiExtendingBackgroundView::cleanup() +{ + delete controller; +} + +void Ut_DuiExtendingBackgroundView::testBoundingRect() +{ + // Use a scalable image in the view's style + int left = 10; + int right = 20; + int top = 30; + int bottom = 40; + DuiScalableImage image(new QPixmap(100, 100), left, right, top, bottom); + view->modifiableStyle()->setBackgroundImage(&image); + controller->setGeometry(QRectF(10, 10, 50, 50)); + + // Get the view's geometry + QRectF geometry = view->geometry(); + + // No background extending + view->modifiableStyle()->setExtendDirection(""); + QRectF boundingRect = view->boundingRect(); + QCOMPARE(boundingRect, QRectF(0, 0, geometry.width(), geometry.height())); + + // Background extends to the left + view->modifiableStyle()->setExtendDirection("left"); + boundingRect = view->boundingRect(); + QCOMPARE(boundingRect, QRectF(-geometry.x() - left, 0, geometry.x() + geometry.width() + left, geometry.height())); + + // Background extends to the right + view->modifiableStyle()->setExtendDirection("right"); + boundingRect = view->boundingRect(); + QCOMPARE(boundingRect, QRectF(0, 0, DuiApplication::activeApplicationWindow()->sceneManager()->visibleSceneSize().width() - geometry.x() + right, geometry.height())); + + // Background extends to top + view->modifiableStyle()->setExtendDirection("top"); + boundingRect = view->boundingRect(); + QCOMPARE(boundingRect, QRectF(0, -geometry.y() - top, geometry.width(), geometry.y() + geometry.height() + top)); + + // Background extends to bottom + view->modifiableStyle()->setExtendDirection("bottom"); + boundingRect = view->boundingRect(); + QCOMPARE(boundingRect, QRectF(0, 0, geometry.width(), DuiApplication::activeApplicationWindow()->sceneManager()->visibleSceneSize().height() - geometry.y() + bottom)); +} + +QTEST_APPLESS_MAIN(Ut_DuiExtendingBackgroundView) diff --git a/tests/ut_duiextendingbackgroundview/ut_duiextendingbackgroundview.h b/tests/ut_duiextendingbackgroundview/ut_duiextendingbackgroundview.h new file mode 100644 index 000000000..347a6ee7b --- /dev/null +++ b/tests/ut_duiextendingbackgroundview/ut_duiextendingbackgroundview.h @@ -0,0 +1,64 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIEXTENDINGBACKGROUNDVIEW_H +#define UT_DUIEXTENDINGBACKGROUNDVIEW_H + +#include +#include + +#include +#include + +class DuiApplication; +class DuiApplicationWindow; +class DuiWidgetController; +class DuiExtendingBackgroundView; + +class TestExtendingBackgroundView : public DuiExtendingBackgroundView +{ + DUI_VIEW(DuiWidgetModel, DuiExtendingBackgroundStyle) + +public: + TestExtendingBackgroundView(DuiWidgetController *controller); + QRectF boundingRect(); + QRectF geometry(); + DuiExtendingBackgroundStyle *modifiableStyle(); +}; + +class Ut_DuiExtendingBackgroundView : public QObject +{ + Q_OBJECT + +private slots: + void init(); + void cleanup(); + void initTestCase(); + void cleanupTestCase(); + + void testBoundingRect(); + +private: + DuiApplication *app; + DuiApplicationWindow *appWin; + DuiWidgetController *controller; + TestExtendingBackgroundView *view; +}; + +#endif diff --git a/tests/ut_duiextendingbackgroundview/ut_duiextendingbackgroundview.pro b/tests/ut_duiextendingbackgroundview/ut_duiextendingbackgroundview.pro new file mode 100644 index 000000000..b7f4a5a22 --- /dev/null +++ b/tests/ut_duiextendingbackgroundview/ut_duiextendingbackgroundview.pro @@ -0,0 +1,23 @@ +include(../common_top.pri) +TARGET = ut_duiextendingbackgroundview + +TEST_SOURCES = \ + +# unit test and unit +SOURCES += \ + ut_duiextendingbackgroundview.cpp \ + $$TEST_SOURCES \ + +# base classes +SOURCES += \ + + +# service classes +SOURCES += \ + $$STUBSDIR/stubbase.cpp + +# unit test and unit +HEADERS += \ + ut_duiextendingbackgroundview.h + +include(../common_bot.pri) diff --git a/tests/ut_duiextensionarea/.gitignore b/tests/ut_duiextensionarea/.gitignore new file mode 100644 index 000000000..2d5ae78ab --- /dev/null +++ b/tests/ut_duiextensionarea/.gitignore @@ -0,0 +1 @@ +ut_duiextensionarea diff --git a/tests/ut_duiextensionarea/ut_duiextensionarea.cpp b/tests/ut_duiextensionarea/ut_duiextensionarea.cpp new file mode 100644 index 000000000..3dcfb711c --- /dev/null +++ b/tests/ut_duiextensionarea/ut_duiextensionarea.cpp @@ -0,0 +1,146 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duiextensionarea.h" +#include "duiextensionarea.h" +#include "duiextensionareaview.h" +#include "duiextensionarea_p.h" +#include "duiappletid_stub.h" +#include "duiapplication.h" +#include "duiappletinstancemanager_stub.h" +#include "mockdatastore.h" +#include "duiobjectmenu_stub.h" + +#include + +#include +DUI_REGISTER_WIDGET(TestExtensionArea); + +// TestExtensionArea +class TestExtensionArea : public DuiExtensionArea +{ +public: + TestExtensionArea() : DuiExtensionArea() { } + void addWidget(DuiWidget *widget, DuiDataStore &store) { + DuiExtensionArea::addWidget(widget, store); + } + void removeWidget(DuiWidget *widget) { + DuiExtensionArea::removeWidget(widget); + } +}; + +// The test class +void Ut_DuiExtensionArea::init() +{ + area = new TestExtensionArea(); + gDuiAppletInstanceManagerStub->stubReset(); +} + +void Ut_DuiExtensionArea::cleanup() +{ + // Destroy the extension area. + delete area; +} + +void Ut_DuiExtensionArea::initTestCase() +{ + // DuiApplications must be created manually due to theme system changes + int argc = 1; + char *app_name = (char *)"./ut_duiextensionarea"; + app = new DuiApplication(argc, &app_name); +} + +void Ut_DuiExtensionArea::cleanupTestCase() +{ + // this is commented out for now, to prevent crash at exit: + // delete app; +} + +void Ut_DuiExtensionArea::testAddition() +{ + QSignalSpy spy(area->model(), SIGNAL(modified(QList))); + + DuiWidget *widget1 = new DuiWidget; + MockDataStore store1; + DuiWidget *widget2 = new DuiWidget; + MockDataStore store2; + + // Add one widget and ensure that the model was modified. + area->addWidget(widget1, store1); + QCOMPARE(spy.count(), 1); + QCOMPARE(area->model()->dataStores()->keys().count(), 1); + QVERIFY(area->model()->dataStores()->contains(widget1)); + spy.clear(); + + // Add another widget. Ensure that both widgets are in the model. + area->addWidget(widget2, store2); + QCOMPARE(spy.count(), 1); + QCOMPARE(area->model()->dataStores()->keys().count(), 2); + QVERIFY(area->model()->dataStores()->contains(widget1)); + QVERIFY(area->model()->dataStores()->contains(widget2)); + spy.clear(); + + // Add the first widget again. The model should not be modified. + area->addWidget(widget1, store1); + QCOMPARE(spy.count(), 0); + QCOMPARE(area->model()->dataStores()->keys().count(), 2); +} + +void Ut_DuiExtensionArea::testRemoval() +{ + QSignalSpy spy(area->model(), SIGNAL(modified(QList))); + + DuiWidget *widget1 = new DuiWidget; + MockDataStore store1; + DuiWidget *widget2 = new DuiWidget; + MockDataStore store2; + DuiWidget *widget3 = new DuiWidget; + MockDataStore store3; + + // Add three widgets and ensure that they're in the model. + area->addWidget(widget1, store1); + area->addWidget(widget2, store2); + area->addWidget(widget3, store3); + QCOMPARE(spy.count(), 3); + QCOMPARE(area->model()->dataStores()->keys().count(), 3); + QVERIFY(area->model()->dataStores()->contains(widget1)); + QVERIFY(area->model()->dataStores()->contains(widget2)); + QVERIFY(area->model()->dataStores()->contains(widget3)); + spy.clear(); + + // Remove widget2 and verify that the rest are in the model. + area->removeWidget(widget2); + QCOMPARE(spy.count(), 1); + QCOMPARE(area->model()->dataStores()->keys().count(), 2); + QVERIFY(area->model()->dataStores()->contains(widget1)); + QVERIFY(!area->model()->dataStores()->contains(widget2)); + QVERIFY(area->model()->dataStores()->contains(widget3)); + spy.clear(); + + // Remove widget2 again and verify that the model was not changed. + area->removeWidget(widget2); + QCOMPARE(spy.count(), 0); + QCOMPARE(area->model()->dataStores()->keys().count(), 2); + QVERIFY(area->model()->dataStores()->contains(widget1)); + QVERIFY(!area->model()->dataStores()->contains(widget2)); + QVERIFY(area->model()->dataStores()->contains(widget3)); + spy.clear(); +} + +QTEST_APPLESS_MAIN(Ut_DuiExtensionArea) diff --git a/tests/ut_duiextensionarea/ut_duiextensionarea.h b/tests/ut_duiextensionarea/ut_duiextensionarea.h new file mode 100644 index 000000000..4bc85cc83 --- /dev/null +++ b/tests/ut_duiextensionarea/ut_duiextensionarea.h @@ -0,0 +1,55 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIEXTENSIONAREA_ +#define UT_DUIEXTENSIONAREA_ + +#include + +class TestExtensionArea; +class DuiApplication; + +class Ut_DuiExtensionArea : public QObject +{ + Q_OBJECT + +private: + // TestExtensionArea is derived from DuiExtensionArea + TestExtensionArea *area; + // DuiApplication instance required by DuiWidget. + DuiApplication *app; + +private slots: + // Executed once before every test case + void init(); + + // Executed once after every test case + void cleanup(); + + // Executed once before first test case + void initTestCase(); + + // Executed once after last test case + void cleanupTestCase(); + + void testAddition(); + void testRemoval(); +}; + +#endif // UT_DUIEXTENSIONAREA_ diff --git a/tests/ut_duiextensionarea/ut_duiextensionarea.pro b/tests/ut_duiextensionarea/ut_duiextensionarea.pro new file mode 100644 index 000000000..c7f34a070 --- /dev/null +++ b/tests/ut_duiextensionarea/ut_duiextensionarea.pro @@ -0,0 +1,31 @@ +include(../common_top.pri) +TARGET = ut_duiextensionarea +INCLUDEPATH += \ + $$DUISRCDIR/applicationextension \ + $$DUISRCDIR/mashup/mashup \ + $$DUISRCDIR/widgets \ + $$DUISRCDIR/style + +# unit test and unit classes +SOURCES += \ + ut_duiextensionarea.cpp \ + $$DUISRCDIR/applicationextension/duiextensionarea.cpp \ + $$DUISRCDIR/widgets/core/duiwidgetcontroller.cpp \ + $$DUISRCDIR/widgets/core/duiwidget.cpp + +# service classes +SOURCES += \ + $$STUBSDIR/stubbase.cpp \ + +# unit test and unit classes +HEADERS += \ + ut_duiextensionarea.h \ + $$DUISRCDIR/applicationextension/duiextensionarea.h \ + $$DUISRCDIR/mashup/mashup/duiappletinstancemanager.h \ + $$DUISRCDIR/mashup/mashup/duiappletid.h \ + $$DUISRCDIR/widgets/core/duiwidgetcontroller_p.h \ + $$DUISRCDIR/widgets/core/duiwidget_p.h \ + $$DUISRCDIR/widgets/duiscenewindow_p.h \ + $$DUISRCDIR/widgets/duiobjectmenu.h + +include(../common_bot.pri) diff --git a/tests/ut_duifastlistviewgroupheader/.gitignore b/tests/ut_duifastlistviewgroupheader/.gitignore new file mode 100644 index 000000000..1e24be95a --- /dev/null +++ b/tests/ut_duifastlistviewgroupheader/.gitignore @@ -0,0 +1 @@ +ut_duifastlistviewgroupheader \ No newline at end of file diff --git a/tests/ut_duifastlistviewgroupheader/ut_duifastlistviewgroupheader.cpp b/tests/ut_duifastlistviewgroupheader/ut_duifastlistviewgroupheader.cpp new file mode 100644 index 000000000..99755421c --- /dev/null +++ b/tests/ut_duifastlistviewgroupheader/ut_duifastlistviewgroupheader.cpp @@ -0,0 +1,375 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include "../../src/widgets/views/duifastlistview_p.h" +#include "duilistmodel.h" +#include "myindexedmodel.h" +#include "ut_duifastlistviewgroupheader.h" + +using namespace DuiFastListViewPrivateNamespace; + +void Ut_DuiFastListViewGroupHeader::initTestCase() +{ + makePhoneBook(); + makePhoneBookModel(); +} + +void Ut_DuiFastListViewGroupHeader::makePhoneBook() +{ + phoneBook = new QObject; + + QObject *itemA = new QObject(phoneBook); + itemA->setObjectName("A"); + + QObject *item; + item = new QObject(itemA); + item->setObjectName("Adam"); + + item = new QObject(itemA); + item->setObjectName("Abby"); + + item = new QObject(itemA); + item->setObjectName("Ashley"); + + QObject *itemB = new QObject(phoneBook); + itemB->setObjectName("B"); + + item = new QObject(itemB); + item->setObjectName("Baby"); + + item = new QObject(itemB); + item->setObjectName("Bob"); + + item = new QObject(itemB); + item->setObjectName("Boby"); + + item = new QObject(itemB); + item->setObjectName("Britney"); + + QObject *itemC = new QObject(phoneBook); + itemC->setObjectName("C"); + + item = new QObject(itemC); + item->setObjectName("Cindy"); +} + +void Ut_DuiFastListViewGroupHeader::makePhoneBookModel() +{ + phoneBookModel = new MyIndexedModel(phoneBook); +} + +void Ut_DuiFastListViewGroupHeader::cleanupTestCase() +{ + delete phoneBookModel; +} + +void Ut_DuiFastListViewGroupHeader::init() +{ + fastListViewPrivate = new DuiFastGroupHeaderListViewPrivate; + fastListViewPrivate->model = phoneBookModel; + fastListViewPrivate->separator = new DuiWidget; + fastListViewPrivate->separator->setGeometry(0, 0, 300, 2); + fastListViewPrivate->itemHeight = 100; + + fastListViewPrivate->setHeadersCreator(new DummyHeaderCreator); + fastListViewPrivate->hdrHeight = GroupHeaderHeight; + + DuiListModel *model = new DuiListModel; + model->setItemModel(phoneBookModel); + model->setShowGroups(true); + fastListViewPrivate->controllerModel = model; + + fastListViewPrivate->updateHeadersRows(); + fastListViewPrivate->updateHeadersPositions(); +} + +void Ut_DuiFastListViewGroupHeader::cleanup() +{ + delete fastListViewPrivate; + delete fastListViewPrivate->controllerModel; +} + +void Ut_DuiFastListViewGroupHeader::testPhoneBook() +{ + // Make sure our phone book model is valid + QCOMPARE(phoneBook->children().size(), 3); + QCOMPARE(phoneBook->children().at(0)->children().size(), 3); + QCOMPARE(phoneBook->children().at(1)->children().size(), 4); + QCOMPARE(phoneBook->children().at(2)->children().size(), 1); +} + +void Ut_DuiFastListViewGroupHeader::testUpdateHeadersRows() +{ + QCOMPARE(3, fastListViewPrivate->headersRows.size()); + QCOMPARE(0, fastListViewPrivate->headersRows[0]); + QCOMPARE(4, fastListViewPrivate->headersRows[1]); + QCOMPARE(9, fastListViewPrivate->headersRows[2]); +} + +void Ut_DuiFastListViewGroupHeader::testUpdateHeadersPositions() +{ + QCOMPARE(fastListViewPrivate->headersPositions.size(), 3); + QCOMPARE(fastListViewPrivate->headersPositions[0], 0); + QCOMPARE(fastListViewPrivate->headersPositions[1], 344); + QCOMPARE(fastListViewPrivate->headersPositions[2], 790); +} + +void Ut_DuiFastListViewGroupHeader::testHeaderHeightShouldBeZeroIfNoHeadersCreatorSpecified() +{ + QSKIP("Work in progress...", SkipSingle); + fastListViewPrivate->setHeadersCreator(NULL); + QCOMPARE(0, fastListViewPrivate->headerHeight()); +} + +void Ut_DuiFastListViewGroupHeader::testHeaderHeightShouldBeZeroIfHeadersNotVisible() +{ + QSKIP("Work in progress...", SkipSingle); + fastListViewPrivate->controllerModel->setShowGroups(false); + QCOMPARE(fastListViewPrivate->headerHeight(), 0); +} + +void Ut_DuiFastListViewGroupHeader::testHeaderHeight() +{ + QCOMPARE(fastListViewPrivate->headerHeight(), GroupHeaderHeight); +} + +void Ut_DuiFastListViewGroupHeader::testGroupSize() +{ + QCOMPARE(fastListViewPrivate->groupSize(0), 304); + QCOMPARE(fastListViewPrivate->groupSize(1), 406); + QCOMPARE(fastListViewPrivate->groupSize(2), 100); +} + +void Ut_DuiFastListViewGroupHeader::testSizeHint() +{ + QCOMPARE(fastListViewPrivate->totalHeight(), 930); +} + +void Ut_DuiFastListViewGroupHeader::testItemCountIndexedModel() +{ + QCOMPARE(fastListViewPrivate->itemsCount(), 8); +} + +void Ut_DuiFastListViewGroupHeader::testItemCount() +{ + QCOMPARE(fastListViewPrivate->itemsCount(0), 3); + QCOMPARE(fastListViewPrivate->itemsCount(1), 4); + QCOMPARE(fastListViewPrivate->itemsCount(2), 1); +} + +void Ut_DuiFastListViewGroupHeader::testSeparatorsCount() +{ + QCOMPARE(fastListViewPrivate->separatorsCount(), 5); +} + +void Ut_DuiFastListViewGroupHeader::testFirstFlatRowToIndex() +{ + QModelIndex index(fastListViewPrivate->flatRowToIndex(0)); + QCOMPARE(index.row(), 0); + QCOMPARE(index.parent(), QModelIndex()); +} + +void Ut_DuiFastListViewGroupHeader::testSecondFlatRowToIndex() +{ + QModelIndex index(fastListViewPrivate->flatRowToIndex(1)); + QCOMPARE(index.row(), 0); + QVERIFY(index.parent().isValid()); + QCOMPARE(index.parent().row(), 0); +} + +void Ut_DuiFastListViewGroupHeader::testLastFlatRowToIndex() +{ + QModelIndex index(fastListViewPrivate->flatRowToIndex(10)); + QCOMPARE(index.row(), 0); + QVERIFY(index.parent().isValid()); + QCOMPARE(index.parent().row(), 2); +} + +void Ut_DuiFastListViewGroupHeader::testAfterLastFlatRowToIndex() +{ + QModelIndex index(fastListViewPrivate->flatRowToIndex(11)); + QVERIFY(index.isValid()); + QCOMPARE(index.row(), 0); + QVERIFY(index.parent().isValid()); + QCOMPARE(index.parent().row(), 2); +} + +void Ut_DuiFastListViewGroupHeader::testInvalidIndexToFlatRow() +{ + QModelIndex index; + QCOMPARE(fastListViewPrivate->indexToFlatRow(index), -1); +} + +void Ut_DuiFastListViewGroupHeader::testFirstIndexWithoutParentToFlatRow() +{ + QModelIndex index = fastListViewPrivate->model->index(1, 0); + QCOMPARE(fastListViewPrivate->indexToFlatRow(index), 4); +} + +void Ut_DuiFastListViewGroupHeader::testIndexWithParentToFlatRow() +{ + QModelIndex index = fastListViewPrivate->model->index(1, 0, fastListViewPrivate->model->index(1, 0)); + QCOMPARE(fastListViewPrivate->indexToFlatRow(index), 6); +} + +void Ut_DuiFastListViewGroupHeader::testLastIndexWithParentToFlatRow() +{ + QModelIndex index = fastListViewPrivate->model->index(0, 0, fastListViewPrivate->model->index(2, 0)); + QCOMPARE(fastListViewPrivate->indexToFlatRow(index), 10); +} + +void Ut_DuiFastListViewGroupHeader::testLocateVisibleIndexAtZero() +{ + QModelIndex index(fastListViewPrivate->locateVisibleIndexAt(0)); + QVERIFY(index.isValid()); + QCOMPARE(index.row(), 0); + QVERIFY(!index.parent().isValid()); +} + +void Ut_DuiFastListViewGroupHeader::testLocateVisibleIndexAt41() +{ + QModelIndex index(fastListViewPrivate->locateVisibleIndexAt(41)); + QVERIFY(index.isValid()); + QCOMPARE(index.row(), 0); + QVERIFY(index.parent().isValid()); + QCOMPARE(index.parent().row(), 0); +} + +void Ut_DuiFastListViewGroupHeader::testLocateVisibleIndexAtMiddleOfHeader() +{ + QModelIndex index(fastListViewPrivate->locateVisibleIndexAt(345)); + QVERIFY(index.isValid()); + QCOMPARE(index.row(), 1); + QVERIFY(!index.parent().isValid()); +} + +void Ut_DuiFastListViewGroupHeader::testLocateVisibleRowAt0() +{ + QCOMPARE(fastListViewPrivate->locateVisibleRowAt(0), 0); +} + +void Ut_DuiFastListViewGroupHeader::testLocateVisibleRowAt41() +{ + QCOMPARE(fastListViewPrivate->locateVisibleRowAt(41), 1); +} + +void Ut_DuiFastListViewGroupHeader::testLocateVisibleRowAt384() +{ + QCOMPARE(fastListViewPrivate->locateVisibleRowAt(385), 5); +} + +void Ut_DuiFastListViewGroupHeader::testLocateVisibleRowAt900() +{ + // last item + QCOMPARE(fastListViewPrivate->locateVisibleRowAt(900), 11); +} + +void Ut_DuiFastListViewGroupHeader::testLocateVisibleRowAt931() +{ + // last item + QCOMPARE(fastListViewPrivate->locateVisibleRowAt(931), 11); +} + +void Ut_DuiFastListViewGroupHeader::testLocatePosOfItemAt0Row() +{ + QCOMPARE(fastListViewPrivate->locatePosOfItem(0), 0); +} + +void Ut_DuiFastListViewGroupHeader::testLocatePosOfItemAt1Row() +{ + QCOMPARE(fastListViewPrivate->locatePosOfItem(1), 40); +} + +void Ut_DuiFastListViewGroupHeader::testLocatePosOfItemAt3Row() +{ + QCOMPARE(fastListViewPrivate->locatePosOfItem(3), 244); +} + +void Ut_DuiFastListViewGroupHeader::testLocatePosOfItemAt0Index() +{ + QModelIndex index(phoneBookModel->index(0, 0)); + QCOMPARE(fastListViewPrivate->locatePosOfItem(index), 0); +} + +void Ut_DuiFastListViewGroupHeader::testLocatePosOfItemAt3Index() +{ + QModelIndex index(phoneBookModel->index(2, 0, phoneBookModel->index(0, 0))); + QCOMPARE(fastListViewPrivate->locatePosOfItem(index), 244); +} + +void Ut_DuiFastListViewGroupHeader::testLocatePosOfItemAt10Row() +{ + QCOMPARE(fastListViewPrivate->locatePosOfItem(10), 830); +} + +void Ut_DuiFastListViewGroupHeader::testFindLowerIndexInEmptyArray() +{ + QVector vec; + QCOMPARE(dFindLowerIndex(vec, 0), 0); + QCOMPARE(dFindLowerIndex(vec, 1), 0); +} + +void Ut_DuiFastListViewGroupHeader::testFindLowerIndexIn2ItemsArray() +{ + QVector vec; + vec << 10 << 15; + QCOMPARE(dFindLowerIndex(vec, 4), 0); + QCOMPARE(dFindLowerIndex(vec, 10), 0); + QCOMPARE(dFindLowerIndex(vec, 11), 0); + QCOMPARE(dFindLowerIndex(vec, 15), 1); + QCOMPARE(dFindLowerIndex(vec, 100), 1); +} + +void Ut_DuiFastListViewGroupHeader::testFindLowerIndexIn3ItemsArray() +{ + QVector vec; + vec << 0 << 5 << 9; + QCOMPARE(dFindLowerIndex(vec, 2), 0); + QCOMPARE(dFindLowerIndex(vec, 5), 1); + QCOMPARE(dFindLowerIndex(vec, 6), 1); + QCOMPARE(dFindLowerIndex(vec, 9), 2); +} + +void Ut_DuiFastListViewGroupHeader::testPerformance() +{ + QSKIP("currently doesn't work", SkipSingle); + fastListViewPrivate->viewportTopLeft = QPoint(0, 0); + fastListViewPrivate->viewportVisibleHeight = 800; + for (int i = 0; i < 10; i++) { + if (i % 1 == 0) + fastListViewPrivate->viewportTopLeft = QPoint(0, 0); + else + fastListViewPrivate->viewportTopLeft = QPoint(0, 800); + + QModelIndex firstVisibleRow = fastListViewPrivate->locateVisibleIndexAt(fastListViewPrivate->viewportTopLeft.y()); + fastListViewPrivate->updateFirstVisibleRow(firstVisibleRow); + QModelIndex lastVisibleRow = fastListViewPrivate->locateVisibleIndexAt(fastListViewPrivate->viewportTopLeft.y() + fastListViewPrivate->viewportVisibleHeight); + fastListViewPrivate->updateLastVisibleRow(lastVisibleRow); + + QPoint firstVisibleItemPos(0, fastListViewPrivate->locatePosOfItem(firstVisibleRow)); + QPoint lastVisibleItemPos(0, fastListViewPrivate->locatePosOfItem(lastVisibleRow)); + fastListViewPrivate->removeInvisibleItems(firstVisibleItemPos, lastVisibleItemPos); + + if (fastListViewPrivate->model->rowCount() > 0) + fastListViewPrivate->createVisibleItems(firstVisibleRow, lastVisibleRow); + } +} + +QTEST_APPLESS_MAIN(Ut_DuiFastListViewGroupHeader); diff --git a/tests/ut_duifastlistviewgroupheader/ut_duifastlistviewgroupheader.h b/tests/ut_duifastlistviewgroupheader/ut_duifastlistviewgroupheader.h new file mode 100644 index 000000000..1dece4f64 --- /dev/null +++ b/tests/ut_duifastlistviewgroupheader/ut_duifastlistviewgroupheader.h @@ -0,0 +1,125 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUILABEL_H +#define UT_DUILABEL_H + +#include +#include +#include +#include "duiabstractcellcreator.h" +const int GroupHeaderHeight = 40; + +class DummyHeaderWidget : public DuiWidget +{ +public: + DummyHeaderWidget() { + } + + virtual QRectF boundingRect() const { + return QRectF(QPointF(0, 0), QSizeF(800, GroupHeaderHeight)); + } + + void setViewType(const QString &viewType) { + Q_UNUSED(viewType); + } +}; + +class DummyHeaderCreator : public DuiAbstractCellCreator +{ +public: + virtual ~DummyHeaderCreator() { + } + + virtual void updateCell(const QModelIndex &index, DuiWidget *cell) const { + Q_UNUSED(index); + Q_UNUSED(cell); + } +}; + +class DuiFastGroupHeaderListViewPrivate; +class MyIndexedModel; + +class Ut_DuiFastListViewGroupHeader : public QObject +{ + Q_OBJECT + +private: + void makePhoneBook(); + void makePhoneBookModel(); + +private slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + + void testPhoneBook(); + + void testUpdateHeadersRows(); + void testUpdateHeadersPositions(); + void testHeaderHeightShouldBeZeroIfNoHeadersCreatorSpecified(); + void testHeaderHeightShouldBeZeroIfHeadersNotVisible(); + void testHeaderHeight(); + void testGroupSize(); + void testSizeHint(); + void testItemCountIndexedModel(); + void testItemCount(); + void testSeparatorsCount(); + + void testFirstFlatRowToIndex(); + void testSecondFlatRowToIndex(); + void testLastFlatRowToIndex(); + void testAfterLastFlatRowToIndex(); + + void testInvalidIndexToFlatRow(); + void testFirstIndexWithoutParentToFlatRow(); + void testIndexWithParentToFlatRow(); + void testLastIndexWithParentToFlatRow(); + + void testLocateVisibleIndexAtZero(); + void testLocateVisibleIndexAt41(); + void testLocateVisibleIndexAtMiddleOfHeader(); + void testLocateVisibleRowAt0(); + void testLocateVisibleRowAt41(); + void testLocateVisibleRowAt384(); + void testLocateVisibleRowAt900(); + void testLocateVisibleRowAt931(); + + void testLocatePosOfItemAt0Row(); + void testLocatePosOfItemAt1Row(); + void testLocatePosOfItemAt3Row(); + void testLocatePosOfItemAt10Row(); + + void testLocatePosOfItemAt0Index(); + void testLocatePosOfItemAt3Index(); + + void testFindLowerIndexInEmptyArray(); + void testFindLowerIndexIn2ItemsArray(); + void testFindLowerIndexIn3ItemsArray(); + + void testPerformance(); + +private: + QObject *phoneBook; + MyIndexedModel *phoneBookModel; + DuiFastGroupHeaderListViewPrivate *fastListViewPrivate; +}; + +#endif diff --git a/tests/ut_duifastlistviewgroupheader/ut_duifastlistviewgroupheader.pro b/tests/ut_duifastlistviewgroupheader/ut_duifastlistviewgroupheader.pro new file mode 100644 index 000000000..189c49c31 --- /dev/null +++ b/tests/ut_duifastlistviewgroupheader/ut_duifastlistviewgroupheader.pro @@ -0,0 +1,14 @@ +include(../common_top.pri) + +TARGET = ut_duifastlistviewgroupheader + +INCLUDEPATH += ../duifastlistviewcommon +HEADERS += ut_duifastlistviewgroupheader.h \ + ../duifastlistviewcommon/myindexedmodel.h + +SOURCES += ut_duifastlistviewgroupheader.cpp \ + ../duifastlistviewcommon/myindexedmodel.cpp \ + ../../src/widgets/views/duifastlistview_p.cpp \ + ../../src/.moc/moc_duifastlistview_p.cpp + +include(../common_bot.pri) diff --git a/tests/ut_duifastlistviewmulticolumn/.gitignore b/tests/ut_duifastlistviewmulticolumn/.gitignore new file mode 100644 index 000000000..d2491accb --- /dev/null +++ b/tests/ut_duifastlistviewmulticolumn/.gitignore @@ -0,0 +1 @@ +ut_duifastlistviewmulticolumn \ No newline at end of file diff --git a/tests/ut_duifastlistviewmulticolumn/ut_duifastlistviewmulticolumn.cpp b/tests/ut_duifastlistviewmulticolumn/ut_duifastlistviewmulticolumn.cpp new file mode 100644 index 000000000..18b427ba6 --- /dev/null +++ b/tests/ut_duifastlistviewmulticolumn/ut_duifastlistviewmulticolumn.cpp @@ -0,0 +1,405 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include "../../src/widgets/views/duifastlistview_p.h" +#include "duilistmodel.h" +#include "myindexedmodel.h" +#include "ut_duifastlistviewmulticolumn.h" + +using namespace DuiFastListViewPrivateNamespace; + +void Ut_DuiFastListViewMultiColumn::initTestCase() +{ + makePhoneBook(); + makePhoneBookModel(); +} + +void Ut_DuiFastListViewMultiColumn::makePhoneBook() +{ + phoneBook = new QObject; + + QObject *itemA = new QObject(phoneBook); + itemA->setObjectName("A"); + + QObject *item; + item = new QObject(itemA); + item->setObjectName("Adam"); + + item = new QObject(itemA); + item->setObjectName("Abby"); + + item = new QObject(itemA); + item->setObjectName("Ashley"); + + QObject *itemB = new QObject(phoneBook); + itemB->setObjectName("B"); + + item = new QObject(itemB); + item->setObjectName("Baby"); + + item = new QObject(itemB); + item->setObjectName("Bob"); + + item = new QObject(itemB); + item->setObjectName("Boby"); + + item = new QObject(itemB); + item->setObjectName("Britney"); + + QObject *itemC = new QObject(phoneBook); + itemC->setObjectName("C"); + + item = new QObject(itemC); + item->setObjectName("Cindy"); +} + +void Ut_DuiFastListViewMultiColumn::makePhoneBookModel() +{ + phoneBookModel = new MyIndexedModel(phoneBook); +} + +void Ut_DuiFastListViewMultiColumn::cleanupTestCase() +{ + delete phoneBookModel; +} + +void Ut_DuiFastListViewMultiColumn::init() +{ + fastListViewPrivate = new DuiFastMultiColumnListViewPrivate; + fastListViewPrivate->model = phoneBookModel; + fastListViewPrivate->separator = new DuiWidget; + fastListViewPrivate->separator->setGeometry(0, 0, 300, 2); + fastListViewPrivate->hseparator = new DuiWidget; + fastListViewPrivate->hseparator->setGeometry(0, 0, 2, 100); + fastListViewPrivate->itemHeight = 100; + fastListViewPrivate->viewWidth = 300; + + fastListViewPrivate->setHeadersCreator(new DummyHeaderCreator); + fastListViewPrivate->hdrHeight = GroupHeaderHeight; + + DuiListModel *model = new DuiListModel; + model->setItemModel(phoneBookModel); + model->setShowGroups(true); + model->setColumns(2); + fastListViewPrivate->controllerModel = model; + + fastListViewPrivate->updateHeadersRows(); + fastListViewPrivate->updateHeadersPositions(); +} + +void Ut_DuiFastListViewMultiColumn::cleanup() +{ + delete fastListViewPrivate; + delete fastListViewPrivate->controllerModel; +} + +void Ut_DuiFastListViewMultiColumn::testPhoneBook() +{ + // Make sure our phone book model is valid + QCOMPARE(phoneBook->children().size(), 3); + QCOMPARE(phoneBook->children().at(0)->children().size(), 3); + QCOMPARE(phoneBook->children().at(1)->children().size(), 4); + QCOMPARE(phoneBook->children().at(2)->children().size(), 1); +} + +void Ut_DuiFastListViewMultiColumn::testUpdateHeadersRows() +{ + QCOMPARE(fastListViewPrivate->headersRows.size(), 3); + QCOMPARE(fastListViewPrivate->headersRows[0], 0); + QCOMPARE(fastListViewPrivate->headersRows[1], 4); + QCOMPARE(fastListViewPrivate->headersRows[2], 9); +} + +void Ut_DuiFastListViewMultiColumn::testUpdateHeadersPositions() +{ + QCOMPARE(fastListViewPrivate->headersPositions.size(), 3); + QCOMPARE(fastListViewPrivate->headersPositions[0], 0); + QCOMPARE(fastListViewPrivate->headersPositions[1], 242); + QCOMPARE(fastListViewPrivate->headersPositions[2], 484); +} + +void Ut_DuiFastListViewMultiColumn::testHeaderHeightShouldBeZeroIfNoHeadersCreatorSpecified() +{ + QSKIP("Failing already in group header tests...", SkipSingle); + fastListViewPrivate->setHeadersCreator(NULL); + QCOMPARE(0, fastListViewPrivate->headerHeight()); +} + +void Ut_DuiFastListViewMultiColumn::testHeaderHeightShouldBeZeroIfHeadersNotVisible() +{ + QSKIP("Failing already in group header tests...", SkipSingle); + fastListViewPrivate->controllerModel->setShowGroups(false); + QCOMPARE(fastListViewPrivate->headerHeight(), 0); +} + +void Ut_DuiFastListViewMultiColumn::testHeaderHeight() +{ + QCOMPARE(fastListViewPrivate->headerHeight(), GroupHeaderHeight); +} + +void Ut_DuiFastListViewMultiColumn::testGroupSize() +{ + QCOMPARE(fastListViewPrivate->groupSize(0), 202); + QCOMPARE(fastListViewPrivate->groupSize(1), 202); + QCOMPARE(fastListViewPrivate->groupSize(2), 100); +} + +void Ut_DuiFastListViewMultiColumn::testRowsInGroup() +{ + QCOMPARE(fastListViewPrivate->rowsInGroup(0), 2); + QCOMPARE(fastListViewPrivate->rowsInGroup(1), 2); + QCOMPARE(fastListViewPrivate->rowsInGroup(2), 1); +} + +void Ut_DuiFastListViewMultiColumn::testSizeHint() +{ + QCOMPARE(fastListViewPrivate->totalHeight(), 624); +} + +void Ut_DuiFastListViewMultiColumn::testItemCountIndexedModel() +{ + QCOMPARE(fastListViewPrivate->itemsCount(), 8); +} + +void Ut_DuiFastListViewMultiColumn::testItemCount() +{ + QCOMPARE(fastListViewPrivate->itemsCount(0), 3); + QCOMPARE(fastListViewPrivate->itemsCount(1), 4); + QCOMPARE(fastListViewPrivate->itemsCount(2), 1); +} + +void Ut_DuiFastListViewMultiColumn::testSeparatorsCount() +{ + QCOMPARE(fastListViewPrivate->separatorsCount(), 5); +} + +void Ut_DuiFastListViewMultiColumn::testLocateVisibleIndexAt0() +{ + QModelIndex index(fastListViewPrivate->locateVisibleIndexAt(0)); + QVERIFY(index.isValid()); + QCOMPARE(index.row(), 0); + QVERIFY(!index.parent().isValid()); +} + +void Ut_DuiFastListViewMultiColumn::testLocateVisibleIndexAt40() +{ + QModelIndex index(fastListViewPrivate->locateVisibleIndexAt(40)); + QVERIFY(index.isValid()); + QCOMPARE(index.row(), 0); + QVERIFY(index.parent().isValid()); + QCOMPARE(index.parent().row(), 0); +} + +void Ut_DuiFastListViewMultiColumn::testLocateVisibleIndexAt142() +{ + QModelIndex index(fastListViewPrivate->locateVisibleIndexAt(142)); + QVERIFY(index.isValid()); + QCOMPARE(index.row(), 2); + QVERIFY(index.parent().isValid()); + QCOMPARE(index.parent().row(), 0); +} + +void Ut_DuiFastListViewMultiColumn::testLocateVisibleIndexAt242() +{ + QModelIndex index(fastListViewPrivate->locateVisibleIndexAt(242)); + QVERIFY(index.isValid()); + QCOMPARE(index.row(), 1); + QVERIFY(!index.parent().isValid()); +} + +void Ut_DuiFastListViewMultiColumn::testLocateVisibleIndexAt282() +{ + QModelIndex index(fastListViewPrivate->locateVisibleIndexAt(282)); + QVERIFY(index.isValid()); + QCOMPARE(index.row(), 0); + QVERIFY(index.parent().isValid()); + QCOMPARE(index.parent().row(), 1); +} + +void Ut_DuiFastListViewMultiColumn::testLocateVisibleIndexAt384() +{ + QModelIndex index(fastListViewPrivate->locateVisibleIndexAt(384)); + QVERIFY(index.isValid()); + QCOMPARE(index.row(), 2); + QVERIFY(index.parent().isValid()); + QCOMPARE(index.parent().row(), 1); +} + +void Ut_DuiFastListViewMultiColumn::testLocateVisibleIndexAt484() +{ + QModelIndex index(fastListViewPrivate->locateVisibleIndexAt(484)); + QVERIFY(index.isValid()); + QCOMPARE(index.row(), 2); + QVERIFY(!index.parent().isValid()); +} + +void Ut_DuiFastListViewMultiColumn::testLocateVisibleIndexAt524() +{ + QModelIndex index(fastListViewPrivate->locateVisibleIndexAt(524)); + QVERIFY(index.isValid()); + QCOMPARE(index.row(), 0); + QVERIFY(index.parent().isValid()); + QCOMPARE(index.parent().row(), 2); +} + +void Ut_DuiFastListViewMultiColumn::testLocateVisibleRowAt0() +{ + QCOMPARE(fastListViewPrivate->locateVisibleRowAt(0), 0); +} + +void Ut_DuiFastListViewMultiColumn::testLocateVisibleRowAt40() +{ + QCOMPARE(fastListViewPrivate->locateVisibleRowAt(40), 1); +} + +void Ut_DuiFastListViewMultiColumn::testLocateVisibleRowAt40x151() +{ + QCOMPARE(fastListViewPrivate->locateVisibleRowAt(40, 151), 2); +} + +void Ut_DuiFastListViewMultiColumn::testLocateVisibleRowAt142() +{ + QCOMPARE(fastListViewPrivate->locateVisibleRowAt(142), 3); +} + +void Ut_DuiFastListViewMultiColumn::testLocateVisibleRowAt242() +{ + QCOMPARE(fastListViewPrivate->locateVisibleRowAt(242), 4); +} + +void Ut_DuiFastListViewMultiColumn::testLocateVisibleRowAt282() +{ + QCOMPARE(fastListViewPrivate->locateVisibleRowAt(282), 5); +} + +void Ut_DuiFastListViewMultiColumn::testLocateVisibleRowAt384() +{ + QCOMPARE(fastListViewPrivate->locateVisibleRowAt(384), 7); +} + +void Ut_DuiFastListViewMultiColumn::testLocateVisibleRowAt484() +{ + QCOMPARE(fastListViewPrivate->locateVisibleRowAt(484), 9); +} + +void Ut_DuiFastListViewMultiColumn::testLocateVisibleRowAt524() +{ + QCOMPARE(fastListViewPrivate->locateVisibleRowAt(524), 10); +} + + +void testLocatePosOfItemAt0Row(); +void testLocatePosOfItemAt1Row(); +void testLocatePosOfItemAt3Row(); +void testLocatePosOfItemAt4Row(); +void testLocatePosOfItemAt5Row(); +void testLocatePosOfItemAt7Row(); +void testLocatePosOfItemAt9Row(); +void testLocatePosOfItemAt10Row(); + +void Ut_DuiFastListViewMultiColumn::testLocatePosOfItemAt0Row() +{ + QCOMPARE(fastListViewPrivate->locatePosOfItem(0), 0); +} + +void Ut_DuiFastListViewMultiColumn::testLocatePosOfItemAt1Row() +{ + QCOMPARE(fastListViewPrivate->locatePosOfItem(1), 40); +} + +void Ut_DuiFastListViewMultiColumn::testLocatePosOfItemAt3Row() +{ + QCOMPARE(fastListViewPrivate->locatePosOfItem(3), 142); +} + +void Ut_DuiFastListViewMultiColumn::testLocatePosOfItemAt4Row() +{ + QCOMPARE(fastListViewPrivate->locatePosOfItem(4), 242); +} + +void Ut_DuiFastListViewMultiColumn::testLocatePosOfItemAt5Row() +{ + QCOMPARE(fastListViewPrivate->locatePosOfItem(5), 282); +} + +void Ut_DuiFastListViewMultiColumn::testLocatePosOfItemAt7Row() +{ + QCOMPARE(fastListViewPrivate->locatePosOfItem(7), 384); +} + +void Ut_DuiFastListViewMultiColumn::testLocatePosOfItemAt9Row() +{ + QCOMPARE(fastListViewPrivate->locatePosOfItem(9), 484); +} + +void Ut_DuiFastListViewMultiColumn::testLocatePosOfItemAt10Row() +{ + QCOMPARE(fastListViewPrivate->locatePosOfItem(10), 524); +} + +void Ut_DuiFastListViewMultiColumn::testLocatePosOfItemAt0Index() +{ + QModelIndex index(phoneBookModel->index(0, 0)); + QCOMPARE(fastListViewPrivate->locatePosOfItem(index), 0); +} + +void Ut_DuiFastListViewMultiColumn::testLocatePosOfItemAt1Index() +{ + QModelIndex index(phoneBookModel->index(0, 0, phoneBookModel->index(0, 0))); + QCOMPARE(fastListViewPrivate->locatePosOfItem(index), 40); +} + +void Ut_DuiFastListViewMultiColumn::testLocatePosOfItemAt3Index() +{ + QModelIndex index(phoneBookModel->index(2, 0, phoneBookModel->index(0, 0))); + QCOMPARE(fastListViewPrivate->locatePosOfItem(index), 142); +} + +void Ut_DuiFastListViewMultiColumn::testLocatePosOfItemAt4Index() +{ + QModelIndex index(phoneBookModel->index(1, 0)); + QCOMPARE(fastListViewPrivate->locatePosOfItem(index), 242); +} + +void Ut_DuiFastListViewMultiColumn::testLocatePosOfItemAt5Index() +{ + QModelIndex index(phoneBookModel->index(0, 0, phoneBookModel->index(1, 0))); + QCOMPARE(fastListViewPrivate->locatePosOfItem(index), 282); +} + +void Ut_DuiFastListViewMultiColumn::testLocatePosOfItemAt7Index() +{ + QModelIndex index(phoneBookModel->index(2, 0, phoneBookModel->index(1, 0))); + QCOMPARE(fastListViewPrivate->locatePosOfItem(index), 384); +} + +void Ut_DuiFastListViewMultiColumn::testLocatePosOfItemAt9Index() +{ + QModelIndex index(phoneBookModel->index(2, 0)); + QCOMPARE(fastListViewPrivate->locatePosOfItem(index), 484); +} + +void Ut_DuiFastListViewMultiColumn::testLocatePosOfItemAt10Index() +{ + QModelIndex index(phoneBookModel->index(0, 0, phoneBookModel->index(2, 0))); + QCOMPARE(fastListViewPrivate->locatePosOfItem(index), 524); +} + +QTEST_APPLESS_MAIN(Ut_DuiFastListViewMultiColumn); diff --git a/tests/ut_duifastlistviewmulticolumn/ut_duifastlistviewmulticolumn.h b/tests/ut_duifastlistviewmulticolumn/ut_duifastlistviewmulticolumn.h new file mode 100644 index 000000000..5a1fe1717 --- /dev/null +++ b/tests/ut_duifastlistviewmulticolumn/ut_duifastlistviewmulticolumn.h @@ -0,0 +1,131 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUILABEL_H +#define UT_DUILABEL_H + +#include +#include +#include +#include "duiabstractcellcreator.h" +const int GroupHeaderHeight = 40; + +class DummyHeaderWidget : public DuiWidget +{ +public: + DummyHeaderWidget() { + } + + virtual QRectF boundingRect() const { + return QRectF(QPointF(0, 0), QSizeF(800, GroupHeaderHeight)); + } + + void setViewType(const QString &viewType) { + Q_UNUSED(viewType); + } +}; + +class DummyHeaderCreator : public DuiAbstractCellCreator +{ +public: + virtual ~DummyHeaderCreator() { + } + + virtual void updateCell(const QModelIndex &index, DuiWidget *cell) const { + Q_UNUSED(index); + Q_UNUSED(cell); + } +}; + +class DuiFastMultiColumnListViewPrivate; +class MyIndexedModel; + +class Ut_DuiFastListViewMultiColumn : public QObject +{ + Q_OBJECT + +private: + void makePhoneBook(); + void makePhoneBookModel(); + +private slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + + void testPhoneBook(); + + void testUpdateHeadersRows(); + void testUpdateHeadersPositions(); + void testHeaderHeightShouldBeZeroIfNoHeadersCreatorSpecified(); + void testHeaderHeightShouldBeZeroIfHeadersNotVisible(); + void testHeaderHeight(); + void testGroupSize(); + void testRowsInGroup(); + void testSizeHint(); + void testItemCountIndexedModel(); + void testItemCount(); + void testSeparatorsCount(); + + void testLocateVisibleIndexAt0(); + void testLocateVisibleIndexAt40(); + void testLocateVisibleIndexAt142(); + void testLocateVisibleIndexAt242(); + void testLocateVisibleIndexAt282(); + void testLocateVisibleIndexAt384(); + void testLocateVisibleIndexAt484(); + void testLocateVisibleIndexAt524(); + + void testLocateVisibleRowAt0(); + void testLocateVisibleRowAt40(); + void testLocateVisibleRowAt40x151(); + void testLocateVisibleRowAt142(); + void testLocateVisibleRowAt242(); + void testLocateVisibleRowAt282(); + void testLocateVisibleRowAt384(); + void testLocateVisibleRowAt484(); + void testLocateVisibleRowAt524(); + + void testLocatePosOfItemAt0Row(); + void testLocatePosOfItemAt1Row(); + void testLocatePosOfItemAt3Row(); + void testLocatePosOfItemAt4Row(); + void testLocatePosOfItemAt5Row(); + void testLocatePosOfItemAt7Row(); + void testLocatePosOfItemAt9Row(); + void testLocatePosOfItemAt10Row(); + + void testLocatePosOfItemAt0Index(); + void testLocatePosOfItemAt1Index(); + void testLocatePosOfItemAt3Index(); + + void testLocatePosOfItemAt4Index(); + void testLocatePosOfItemAt5Index(); + void testLocatePosOfItemAt7Index(); + void testLocatePosOfItemAt9Index(); + void testLocatePosOfItemAt10Index(); + +private: + QObject *phoneBook; + MyIndexedModel *phoneBookModel; + DuiFastMultiColumnListViewPrivate *fastListViewPrivate; +}; + +#endif diff --git a/tests/ut_duifastlistviewmulticolumn/ut_duifastlistviewmulticolumn.pro b/tests/ut_duifastlistviewmulticolumn/ut_duifastlistviewmulticolumn.pro new file mode 100644 index 000000000..a405785d2 --- /dev/null +++ b/tests/ut_duifastlistviewmulticolumn/ut_duifastlistviewmulticolumn.pro @@ -0,0 +1,14 @@ +include(../common_top.pri) + +TARGET = ut_duifastlistviewmulticolumn + +INCLUDEPATH += ../duifastlistviewcommon +HEADERS += ut_duifastlistviewmulticolumn.h \ + ../duifastlistviewcommon/myindexedmodel.h + +SOURCES += ut_duifastlistviewmulticolumn.cpp \ + ../duifastlistviewcommon/myindexedmodel.cpp \ + ../../src/widgets/views/duifastlistview_p.cpp \ + ../../src/.moc/moc_duifastlistview_p.cpp + +include(../common_bot.pri) diff --git a/tests/ut_duifastlistviewplain/ut_duifastlistviewplain.cpp b/tests/ut_duifastlistviewplain/ut_duifastlistviewplain.cpp new file mode 100644 index 000000000..011e651f4 --- /dev/null +++ b/tests/ut_duifastlistviewplain/ut_duifastlistviewplain.cpp @@ -0,0 +1,334 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include "../../src/widgets/views/duifastlistview_p.h" +#include "duilistmodel.h" +#include "ut_duifastlistview.h" + +void Ut_DuiListNewView::initTestCase() +{ + makePhoneBook(); + makePhoneBookModel(); +} + +void Ut_DuiListNewView::makePhoneBook() +{ +} + +void Ut_DuiListNewView::makePhoneBookModel() +{ +} + +void Ut_DuiListNewView::cleanupTestCase() +{ + delete phoneBookModel; +} + +void Ut_DuiListNewView::init() +{ + fastListViewPrivate = new DuiFastGroupHeaderListViewPrivate; + fastListViewPrivate->model = phoneBookModel; + fastListViewPrivate->separator = new DuiWidget; + fastListViewPrivate->separator->setGeometry(0, 0, 300, 2); + fastListViewPrivate->itemHeight = 100; + + fastListViewPrivate->setHeadersCreator(new DummyHeaderCreator); + fastListViewPrivate->hdrHeight = GroupHeaderHeight; + + DuiListModel *model = new DuiListModel; + model->setItemModel(phoneBookModel); + model->setShowGroups(true); + fastListViewPrivate->controllerModel = model; + + fastListViewPrivate->updateHeadersRows(); + fastListViewPrivate->updateHeadersPositions(); +} + +void Ut_DuiListNewView::cleanup() +{ + delete fastListViewPrivate; + delete fastListViewPrivate->controllerModel; +} + +void Ut_DuiListNewView::testPhoneBook() +{ + // Make sure our phone book model is valid + QCOMPARE(phoneBook->children().size(), 3); + QCOMPARE(phoneBook->children().at(0)->children().size(), 3); + QCOMPARE(phoneBook->children().at(1)->children().size(), 4); + QCOMPARE(phoneBook->children().at(2)->children().size(), 1); +} + +void Ut_DuiListNewView::testUpdateHeadersRows() +{ + QCOMPARE(3, fastListViewPrivate->headersRows.size()); + QCOMPARE(0, fastListViewPrivate->headersRows[0]); + QCOMPARE(4, fastListViewPrivate->headersRows[1]); + QCOMPARE(9, fastListViewPrivate->headersRows[2]); +} + +void Ut_DuiListNewView::testUpdateHeadersPositions() +{ + QCOMPARE(fastListViewPrivate->headersPositions.size(), 3); + QCOMPARE(fastListViewPrivate->headersPositions[0], 0); + QCOMPARE(fastListViewPrivate->headersPositions[1], 344); + QCOMPARE(fastListViewPrivate->headersPositions[2], 790); +} + +void Ut_DuiListNewView::testHeaderHeightShouldBeZeroIfNoHeadersCreatorSpecified() +{ + fastListViewPrivate->setHeadersCreator(NULL); + QCOMPARE(0, fastListViewPrivate->headerHeight()); +} + +void Ut_DuiListNewView::testHeaderHeightShouldBeZeroIfHeadersNotVisible() +{ + fastListViewPrivate->controllerModel->setShowGroups(false); + QCOMPARE(fastListViewPrivate->headerHeight(), 0); +} + +void Ut_DuiListNewView::testHeaderHeight() +{ + QCOMPARE(fastListViewPrivate->headerHeight(), GroupHeaderHeight); +} + +void Ut_DuiListNewView::testGroupSize() +{ + QCOMPARE(fastListViewPrivate->groupSize(0), 304); + QCOMPARE(fastListViewPrivate->groupSize(1), 406); + QCOMPARE(fastListViewPrivate->groupSize(2), 100); +} + +void Ut_DuiListNewView::testSizeHint() +{ + QCOMPARE(fastListViewPrivate->totalHeight(), 930); +} + +void Ut_DuiListNewView::testItemCountIndexedModel() +{ + QCOMPARE(fastListViewPrivate->itemsCount(), 8); +} + +void Ut_DuiListNewView::testItemCount() +{ + QCOMPARE(fastListViewPrivate->itemsCount(0), 3); + QCOMPARE(fastListViewPrivate->itemsCount(1), 4); + QCOMPARE(fastListViewPrivate->itemsCount(2), 1); +} + +void Ut_DuiListNewView::testSeparatorsCount() +{ + QCOMPARE(fastListViewPrivate->separatorsCount(), 5); +} + +void Ut_DuiListNewView::testFirstFlatRowToIndex() +{ + QModelIndex index(fastListViewPrivate->flatRowToIndex(0)); + QCOMPARE(index.row(), 0); + QCOMPARE(index.parent(), QModelIndex()); +} + +void Ut_DuiListNewView::testSecondFlatRowToIndex() +{ + QModelIndex index(fastListViewPrivate->flatRowToIndex(1)); + QCOMPARE(index.row(), 0); + QVERIFY(index.parent().isValid()); + QCOMPARE(index.parent().row(), 0); +} + +void Ut_DuiListNewView::testLastFlatRowToIndex() +{ + QModelIndex index(fastListViewPrivate->flatRowToIndex(10)); + QCOMPARE(index.row(), 0); + QVERIFY(index.parent().isValid()); + QCOMPARE(index.parent().row(), 2); +} + +void Ut_DuiListNewView::testAfterLastFlatRowToIndex() +{ + QModelIndex index(fastListViewPrivate->flatRowToIndex(11)); + QVERIFY(index.isValid()); + QCOMPARE(index.row(), 0); + QVERIFY(index.parent().isValid()); + QCOMPARE(index.parent().row(), 2); +} + +void Ut_DuiListNewView::testInvalidIndexToFlatRow() +{ + QModelIndex index; + QCOMPARE(fastListViewPrivate->indexToFlatRow(index), -1); +} + +void Ut_DuiListNewView::testFirstIndexWithoutParentToFlatRow() +{ + QModelIndex index = fastListViewPrivate->model->index(1, 0); + QCOMPARE(fastListViewPrivate->indexToFlatRow(index), 4); +} + +void Ut_DuiListNewView::testIndexWithParentToFlatRow() +{ + QModelIndex index = fastListViewPrivate->model->index(1, 0, fastListViewPrivate->model->index(1, 0)); + QCOMPARE(fastListViewPrivate->indexToFlatRow(index), 6); +} + +void Ut_DuiListNewView::testLastIndexWithParentToFlatRow() +{ + QModelIndex index = fastListViewPrivate->model->index(0, 0, fastListViewPrivate->model->index(2, 0)); + QCOMPARE(fastListViewPrivate->indexToFlatRow(index), 10); +} + +void Ut_DuiListNewView::testLocateVisibleIndexAtZero() +{ + QModelIndex index(fastListViewPrivate->locateVisibleIndexAt(0)); + QVERIFY(index.isValid()); + QCOMPARE(index.row(), 0); + QVERIFY(!index.parent().isValid()); +} + +void Ut_DuiListNewView::testLocateVisibleIndexAt41() +{ + QModelIndex index(fastListViewPrivate->locateVisibleIndexAt(41)); + QVERIFY(index.isValid()); + QCOMPARE(index.row(), 0); + QVERIFY(index.parent().isValid()); + QCOMPARE(index.parent().row(), 0); +} + +void Ut_DuiListNewView::testLocateVisibleIndexAtMiddleOfHeader() +{ + QModelIndex index(fastListViewPrivate->locateVisibleIndexAt(345)); + QVERIFY(index.isValid()); + QCOMPARE(index.row(), 1); + QVERIFY(!index.parent().isValid()); +} + +void Ut_DuiListNewView::testLocateVisibleRowAt0() +{ + QCOMPARE(fastListViewPrivate->locateVisibleRowAt(0), 0); +} + +void Ut_DuiListNewView::testLocateVisibleRowAt41() +{ + QCOMPARE(fastListViewPrivate->locateVisibleRowAt(41), 1); +} + +void Ut_DuiListNewView::testLocateVisibleRowAt384() +{ + QCOMPARE(fastListViewPrivate->locateVisibleRowAt(385), 5); +} + +void Ut_DuiListNewView::testLocateVisibleRowAt900() +{ + // last item + QCOMPARE(fastListViewPrivate->locateVisibleRowAt(900), 11); +} + +void Ut_DuiListNewView::testLocateVisibleRowAt931() +{ + // last item + QCOMPARE(fastListViewPrivate->locateVisibleRowAt(931), 11); +} + +void Ut_DuiListNewView::testLocatePosOfItemAt0Row() +{ + QCOMPARE(fastListViewPrivate->locatePosOfItem(0), 0); +} + +void Ut_DuiListNewView::testLocatePosOfItemAt1Row() +{ + QCOMPARE(fastListViewPrivate->locatePosOfItem(1), 40); +} + +void Ut_DuiListNewView::testLocatePosOfItemAt3Row() +{ + QCOMPARE(fastListViewPrivate->locatePosOfItem(3), 244); +} + +void Ut_DuiListNewView::testLocatePosOfItemAt0Index() +{ + QModelIndex index(phoneBookModel->index(0, 0)); + QCOMPARE(fastListViewPrivate->locatePosOfItem(index), 0); +} + +void Ut_DuiListNewView::testLocatePosOfItemAt3Index() +{ + QModelIndex index(phoneBookModel->index(2, 0, phoneBookModel->index(0, 0))); + QCOMPARE(fastListViewPrivate->locatePosOfItem(index), 244); +} + +void Ut_DuiListNewView::testLocatePosOfItemAt10Row() +{ + QCOMPARE(fastListViewPrivate->locatePosOfItem(10), 830); +} + +void Ut_DuiListNewView::testFindLowerIndexInEmptyArray() +{ + QVector vec; + QCOMPARE(dFindLowerIndex(vec, 0), 0); + QCOMPARE(dFindLowerIndex(vec, 1), 0); +} + +void Ut_DuiListNewView::testFindLowerIndexIn2ItemsArray() +{ + QVector vec; + vec << 10 << 15; + QCOMPARE(dFindLowerIndex(vec, 4), 0); + QCOMPARE(dFindLowerIndex(vec, 10), 0); + QCOMPARE(dFindLowerIndex(vec, 11), 0); + QCOMPARE(dFindLowerIndex(vec, 15), 1); + QCOMPARE(dFindLowerIndex(vec, 100), 1); +} + +void Ut_DuiListNewView::testFindLowerIndexIn3ItemsArray() +{ + QVector vec; + vec << 0 << 5 << 9; + QCOMPARE(dFindLowerIndex(vec, 2), 0); + QCOMPARE(dFindLowerIndex(vec, 5), 1); + QCOMPARE(dFindLowerIndex(vec, 6), 1); + QCOMPARE(dFindLowerIndex(vec, 9), 2); +} + +void Ut_DuiListNewView::testPerformance() +{ + QSKIP("currently doesn't work", SkipSingle); + fastListViewPrivate->viewportTopLeft = QPoint(0, 0); + fastListViewPrivate->viewportVisibleHeight = 800; + for (int i = 0; i < 10; i++) { + if (i % 1 == 0) + fastListViewPrivate->viewportTopLeft = QPoint(0, 0); + else + fastListViewPrivate->viewportTopLeft = QPoint(0, 800); + + QModelIndex firstVisibleRow = fastListViewPrivate->locateVisibleIndexAt(fastListViewPrivate->viewportTopLeft.y()); + fastListViewPrivate->updateFirstVisibleRow(firstVisibleRow); + QModelIndex lastVisibleRow = fastListViewPrivate->locateVisibleIndexAt(fastListViewPrivate->viewportTopLeft.y() + fastListViewPrivate->viewportVisibleHeight); + fastListViewPrivate->updateLastVisibleRow(lastVisibleRow); + + QPoint firstVisibleItemPos(0, fastListViewPrivate->locatePosOfItem(firstVisibleRow)); + QPoint lastVisibleItemPos(0, fastListViewPrivate->locatePosOfItem(lastVisibleRow)); + fastListViewPrivate->removeInvisibleItems(firstVisibleItemPos, lastVisibleItemPos); + + if (fastListViewPrivate->model->rowCount() > 0) + fastListViewPrivate->createVisibleItems(firstVisibleRow, lastVisibleRow); + } +} + +QTEST_APPLESS_MAIN(Ut_DuiListNewView); diff --git a/tests/ut_duifastlistviewplain/ut_duifastlistviewplain.h b/tests/ut_duifastlistviewplain/ut_duifastlistviewplain.h new file mode 100644 index 000000000..f54f87b76 --- /dev/null +++ b/tests/ut_duifastlistviewplain/ut_duifastlistviewplain.h @@ -0,0 +1,49 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUILABEL_H +#define UT_DUILABEL_H + +#include +#include +#include +#include "duiabstractcellcreator.h" +const int GroupHeaderHeight = 40; + +class DuiFastPlainListViewPrivate; + +class Ut_DuiListNewView : public QObject +{ + Q_OBJECT + +private: + void makePhoneBook(); + void makePhoneBookModel(); + +private slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + +private: + DuiFastPlainListViewPrivate *fastListViewPrivate; +}; + +#endif diff --git a/tests/ut_duifastlistviewplain/ut_duifastlistviewplain.pro b/tests/ut_duifastlistviewplain/ut_duifastlistviewplain.pro new file mode 100644 index 000000000..20f1ebfb0 --- /dev/null +++ b/tests/ut_duifastlistviewplain/ut_duifastlistviewplain.pro @@ -0,0 +1,13 @@ +include(../common_top.pri) + +TARGET = ut_duifastlistviewplain + +INCLUDEPATH += ../ut_duifastlistviewcommon +HEADERS += ut_duifastlistviewplain.h + +SOURCES += ut_duifastlistviewplain.cpp \ + ../../src/widgets/views/duifastlistview_p.cpp \ + ../../src/widgets/duicell.cpp \ + ../../src/.moc/moc_duifastlistview_p.cpp + +include(../common_bot.pri) diff --git a/tests/ut_duifeedback/.gitignore b/tests/ut_duifeedback/.gitignore new file mode 100644 index 000000000..18c7ed95d --- /dev/null +++ b/tests/ut_duifeedback/.gitignore @@ -0,0 +1,5 @@ +ut_duifeedback +duifeedback.cpp +duifeedback.h +duifeedback_p.cpp +duifeedback_p.h diff --git a/tests/ut_duifeedback/duiapplication.h b/tests/ut_duifeedback/duiapplication.h new file mode 100644 index 000000000..27a9b0f0e --- /dev/null +++ b/tests/ut_duifeedback/duiapplication.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiapplication_mock.h" diff --git a/tests/ut_duifeedback/duiapplication_mock.cpp b/tests/ut_duifeedback/duiapplication_mock.cpp new file mode 100644 index 000000000..7338bd63c --- /dev/null +++ b/tests/ut_duifeedback/duiapplication_mock.cpp @@ -0,0 +1,38 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiapplication_mock.h" +#include "duifeedbackplayer_mock.h" +#include + +DuiFeedbackPlayer DuiApplication::feedbackPlayerInstance; + +DuiApplication::DuiApplication() +{ +} + +DuiApplication::~DuiApplication() +{ +} + +DuiFeedbackPlayer *DuiApplication::feedbackPlayer() +{ + return &feedbackPlayerInstance; +} + diff --git a/tests/ut_duifeedback/duiapplication_mock.h b/tests/ut_duifeedback/duiapplication_mock.h new file mode 100644 index 000000000..b0e101f6d --- /dev/null +++ b/tests/ut_duifeedback/duiapplication_mock.h @@ -0,0 +1,37 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLICATION_MOCK_H +#define DUIAPPLICATION_MOCK_H + +class DuiFeedbackPlayer; + +class DuiApplication +{ +public: + DuiApplication(); + virtual ~DuiApplication(); + + static DuiFeedbackPlayer *feedbackPlayer(); + +private: + static DuiFeedbackPlayer feedbackPlayerInstance; +}; + +#endif diff --git a/tests/ut_duifeedback/duiexport.h b/tests/ut_duifeedback/duiexport.h new file mode 100644 index 000000000..40f24e333 --- /dev/null +++ b/tests/ut_duifeedback/duiexport.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiexport_mock.h" diff --git a/tests/ut_duifeedback/duiexport_mock.h b/tests/ut_duifeedback/duiexport_mock.h new file mode 100644 index 000000000..e74bb2a20 --- /dev/null +++ b/tests/ut_duifeedback/duiexport_mock.h @@ -0,0 +1,25 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIEXPORT_H +#define DUIEXPORT_H + +#define DUI_EXPORT + +#endif // Header guard diff --git a/tests/ut_duifeedback/duifeedbackplayer.h b/tests/ut_duifeedback/duifeedbackplayer.h new file mode 100644 index 000000000..5624cb213 --- /dev/null +++ b/tests/ut_duifeedback/duifeedbackplayer.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duifeedbackplayer_mock.h" diff --git a/tests/ut_duifeedback/duifeedbackplayer_mock.cpp b/tests/ut_duifeedback/duifeedbackplayer_mock.cpp new file mode 100644 index 000000000..58035d180 --- /dev/null +++ b/tests/ut_duifeedback/duifeedbackplayer_mock.cpp @@ -0,0 +1,35 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duifeedbackplayer_mock.h" +#include + +DuiFeedbackPlayer::DuiFeedbackPlayer() +{ +} + +DuiFeedbackPlayer::~DuiFeedbackPlayer() +{ +} + +void DuiFeedbackPlayer::play(const QString &feedbackName) +{ + playedFeedbacks << feedbackName; +} + diff --git a/tests/ut_duifeedback/duifeedbackplayer_mock.h b/tests/ut_duifeedback/duifeedbackplayer_mock.h new file mode 100644 index 000000000..221877ab1 --- /dev/null +++ b/tests/ut_duifeedback/duifeedbackplayer_mock.h @@ -0,0 +1,37 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIFEEDBACKPLAYER_MOCK_H +#define DUIFEEDBACKPLAYER_MOCK_H + +#include +#include + +class DuiFeedbackPlayer +{ +public: + DuiFeedbackPlayer(); + virtual ~DuiFeedbackPlayer(); + + void play(const QString &feedbackName); + + QStringList playedFeedbacks; +}; + +#endif diff --git a/tests/ut_duifeedback/ut_duifeedback.cpp b/tests/ut_duifeedback/ut_duifeedback.cpp new file mode 100644 index 000000000..d2438a739 --- /dev/null +++ b/tests/ut_duifeedback/ut_duifeedback.cpp @@ -0,0 +1,90 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duifeedback.h" +#include "duifeedback.h" +#include "duifeedback_p.h" +#include "duiapplication_mock.h" +#include "duifeedbackplayer_mock.h" + +void Ut_DuiFeedback::init() +{ +} + +void Ut_DuiFeedback::cleanup() +{ +} + +void Ut_DuiFeedback::initTestCase() +{ +} + +void Ut_DuiFeedback::cleanupTestCase() +{ +} + +/* + * Check that DuiFeedback name is handled correctly. + */ +void Ut_DuiFeedback::name() +{ + DuiFeedback feedback1; + DuiFeedback feedback2("foo"); + + // Make sure initial values are correct + QCOMPARE(feedback1.name(), QString()); + QCOMPARE(feedback2.name(), QString("foo")); + + // Set a different name and verify + feedback2.setName("bar"); + QCOMPARE(feedback2.name(), QString("bar")); + + // Copy feedback and verify + feedback1 = feedback2; + QCOMPARE(feedback1.name(), QString("bar")); +} + +/* + * Check that DuiFeedback playing works as expected. + */ +void Ut_DuiFeedback::play() +{ + DuiFeedbackPlayer *testPlayer; + DuiFeedback feedback1("press-foo"); + DuiFeedback feedback2; + DuiFeedback feedback3("release-foo"); + DuiFeedback feedback4("cancel-foo"); + + // Play the feedbacks + feedback1.play(); + feedback2.play(); + feedback3.play(); + feedback4.play(); + + // See that the feedbacks actually got played + testPlayer = DuiApplication::feedbackPlayer(); + QCOMPARE(testPlayer->playedFeedbacks.size(), static_cast(4)); + QCOMPARE(testPlayer->playedFeedbacks.at(0), QString("press-foo")); + QCOMPARE(testPlayer->playedFeedbacks.at(1), QString()); + QCOMPARE(testPlayer->playedFeedbacks.at(2), QString("release-foo")); + QCOMPARE(testPlayer->playedFeedbacks.at(3), QString("cancel-foo")); +} + +QTEST_MAIN(Ut_DuiFeedback) + diff --git a/tests/ut_duifeedback/ut_duifeedback.h b/tests/ut_duifeedback/ut_duifeedback.h new file mode 100644 index 000000000..163f48f70 --- /dev/null +++ b/tests/ut_duifeedback/ut_duifeedback.h @@ -0,0 +1,42 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIFEEDBACK_H +#define UT_DUIFEEDBACK_H + +#include +#include + +class Ut_DuiFeedback : public QObject +{ + Q_OBJECT + +private slots: + void init(); + void cleanup(); + void initTestCase(); + void cleanupTestCase(); + + void name(); + void play(); + +private: +}; + +#endif diff --git a/tests/ut_duifeedback/ut_duifeedback.pro b/tests/ut_duifeedback/ut_duifeedback.pro new file mode 100644 index 000000000..09f246231 --- /dev/null +++ b/tests/ut_duifeedback/ut_duifeedback.pro @@ -0,0 +1,88 @@ +#include(../common_top.pri) + +# **************************************************************************** +# This is the contents of "../common_top.pri" modified so that libdui library +# is not included. (It's not needed with this test) +# **************************************************************************** +include(../check.pri) + +# for defines +include(../../mkspecs/common.pri) + +DUISRCDIR = ../../src +#STUBSDIR = ../stubs +#INCLUDEPATH += . $$DUISRCDIR/include +#DEPENDPATH = $$INCLUDEPATH +#QMAKE_LIBDIR += ../../lib /usr/local/lib +CONFIG += debug +QT += testlib +TEMPLATE = app +# DEFINES += QT_NO_DEBUG_OUTPUT +DEFINES += UNIT_TEST +target.path = $$[QT_INSTALL_LIBS]/libdui-tests +INSTALLS += target + +#win32|macx { +# macx { +# QMAKE_LFLAGS += -F../../lib +# LIBS += -framework dui +# } +# win32:LIBS += -L../../lib -ldui0 +#} else { +# LIBS += ../../lib/libdui.so +#} + +QMAKE_CXXFLAGS += -Werror + +support_files.files = +support_files.path = $$[QT_INSTALL_LIBS]/libdui-tests +INSTALLS += support_files + +# **************************************************************************** +# "../common_top.pri" ends. +# **************************************************************************** + +INCLUDEPATH += $$DUISRCDIR/feedback + +TARGET = ut_duifeedback + +TESTED_SOURCES = $$DUISRCDIR/feedback/duifeedback.cpp \ + $$DUISRCDIR/feedback/duifeedback_p.cpp + +TESTED_HEADERS = $$DUISRCDIR/feedback/duifeedback.h \ + $$DUISRCDIR/feedback/duifeedback_p.h + +copysourcefiles.input = TESTED_SOURCES +copysourcefiles.output = ${QMAKE_FILE_BASE}.cpp +copysourcefiles.commands = $$QMAKE_COPY ${QMAKE_FILE_IN} ${QMAKE_FILE_BASE}.cpp +copysourcefiles.variable_out = SOURCES +copysourcefiles.CONFIG = target_predeps no_link +QMAKE_EXTRA_COMPILERS += copysourcefiles + +copyheaderfiles.input = TESTED_HEADERS +copyheaderfiles.output = ${QMAKE_FILE_BASE}.h +copyheaderfiles.commands = $$QMAKE_COPY ${QMAKE_FILE_IN} ${QMAKE_FILE_BASE}.h +copyheaderfiles.variable_out = HEADERS +copyheaderfiles.CONFIG = target_predeps no_link +QMAKE_EXTRA_COMPILERS += copyheaderfiles + +mocheaderfiles.input = TESTED_HEADERS +mocheaderfiles.output = moc_${QMAKE_FILE_BASE}.cpp +mocheaderfiles.commands = $$QMAKE_MOC $(DEFINES) $(INCPATH) ${QMAKE_FILE_BASE}.h -o moc_${QMAKE_FILE_BASE}.cpp +mocheaderfiles.variable_out = SOURCES +mocheaderfiles.CONFIG = target_predeps no_link +QMAKE_EXTRA_COMPILERS += mocheaderfiles + +SOURCES += \ + ut_duifeedback.cpp \ + duifeedbackplayer_mock.cpp \ + duiapplication_mock.cpp + +HEADERS += \ + ut_duifeedback.h \ + duifeedbackplayer.h \ + duifeedbackplayer_mock.h \ + duiapplication.h \ + duiapplication_mock.h + +include(../common_bot.pri) diff --git a/tests/ut_duifeedbackplayer/.gitignore b/tests/ut_duifeedbackplayer/.gitignore new file mode 100644 index 000000000..c0bd069d6 --- /dev/null +++ b/tests/ut_duifeedbackplayer/.gitignore @@ -0,0 +1,5 @@ +ut_duifeedbackplayer +duifeedbackplayer.cpp +duifeedbackplayer.h +duifeedbackplayer_p.cpp +duifeedbackplayer_p.h diff --git a/tests/ut_duifeedbackplayer/QLocalSocket b/tests/ut_duifeedbackplayer/QLocalSocket new file mode 100644 index 000000000..96fe73c64 --- /dev/null +++ b/tests/ut_duifeedbackplayer/QLocalSocket @@ -0,0 +1 @@ +#include "qlocalsocket.h" diff --git a/tests/ut_duifeedbackplayer/duiapplicationprivate_mock.cpp b/tests/ut_duifeedbackplayer/duiapplicationprivate_mock.cpp new file mode 100644 index 000000000..b835aa69c --- /dev/null +++ b/tests/ut_duifeedbackplayer/duiapplicationprivate_mock.cpp @@ -0,0 +1,36 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiapplicationprivate_mock.h" +#include "duifeedbackplayer.h" +#include "duifeedbackplayer_p.h" +#include + +DuiApplicationPrivate::DuiApplicationPrivate(const QString &applicationName) +{ + feedbackPlayer = new DuiFeedbackPlayer(); + feedbackPlayer->d_ptr->init(applicationName); +} + +DuiApplicationPrivate::~DuiApplicationPrivate() +{ + delete feedbackPlayer; + feedbackPlayer = 0; +} + diff --git a/tests/ut_duifeedbackplayer/duiapplicationprivate_mock.h b/tests/ut_duifeedbackplayer/duiapplicationprivate_mock.h new file mode 100644 index 000000000..c01b5e3f7 --- /dev/null +++ b/tests/ut_duifeedbackplayer/duiapplicationprivate_mock.h @@ -0,0 +1,35 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLICATIONPRIVATE_MOCK_H +#define DUIAPPLICATIONPRIVATE_MOCK_H + +#include +class DuiFeedbackPlayer; + +class DuiApplicationPrivate +{ +public: + DuiApplicationPrivate(const QString &applicationName); + virtual ~DuiApplicationPrivate(); + + DuiFeedbackPlayer *feedbackPlayer; +}; + +#endif diff --git a/tests/ut_duifeedbackplayer/duiexport.h b/tests/ut_duifeedbackplayer/duiexport.h new file mode 100644 index 000000000..40f24e333 --- /dev/null +++ b/tests/ut_duifeedbackplayer/duiexport.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiexport_mock.h" diff --git a/tests/ut_duifeedbackplayer/duiexport_mock.h b/tests/ut_duifeedbackplayer/duiexport_mock.h new file mode 100644 index 000000000..e74bb2a20 --- /dev/null +++ b/tests/ut_duifeedbackplayer/duiexport_mock.h @@ -0,0 +1,25 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIEXPORT_H +#define DUIEXPORT_H + +#define DUI_EXPORT + +#endif // Header guard diff --git a/tests/ut_duifeedbackplayer/qlocalsocket.h b/tests/ut_duifeedbackplayer/qlocalsocket.h new file mode 100644 index 000000000..2910c10d6 --- /dev/null +++ b/tests/ut_duifeedbackplayer/qlocalsocket.h @@ -0,0 +1,20 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "qlocalsocket_mock.h" diff --git a/tests/ut_duifeedbackplayer/qlocalsocket_mock.cpp b/tests/ut_duifeedbackplayer/qlocalsocket_mock.cpp new file mode 100644 index 000000000..7d8f7d68a --- /dev/null +++ b/tests/ut_duifeedbackplayer/qlocalsocket_mock.cpp @@ -0,0 +1,122 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "qlocalsocket_mock.h" + +int QLocalSocket::failConnectCount = 0; +QLocalSocket *QLocalSocket::self = 0; + +QLocalSocket::QLocalSocket(QObject *parent) : QIODevice(parent) +{ + socketState = UnconnectedState; + attemptedConnectCount = 0; + self = this; +} + +QLocalSocket::~QLocalSocket() +{ +} + +qint64 QLocalSocket::bytesAvailable() const +{ + return QIODevice::bytesAvailable(); +} + +void QLocalSocket::connectToServer(const QString &name, OpenMode openMode) +{ + Q_UNUSED(name); + Q_UNUSED(openMode); + + attemptedConnectCount++; + + if (failConnectCount > 0) { + failConnectCount--; + emit error(ServerNotFoundError); + } else { + this->open(QIODevice::ReadWrite); + socketState = ConnectedState; + emit connected(); + } +} + +void QLocalSocket::suddenDisconnect() +{ + socketState = UnconnectedState; + bytesWritten.clear(); + this->close(); + attemptedConnectCount = 0; + emit error(UnknownSocketError); +} + +void QLocalSocket::clearReceivedData() +{ + bytesWritten.clear(); +} + +void QLocalSocket::disconnectFromServer() +{ +} + +bool QLocalSocket::flush() +{ + return 0; +} + +QLocalSocket::LocalSocketState QLocalSocket::state() const +{ + return socketState; +} + +qint64 QLocalSocket::readData(char *data, qint64 maxSize) +{ + Q_UNUSED(data); + Q_UNUSED(maxSize); + + return 0; +} + +qint64 QLocalSocket::writeData(const char *data, qint64 maxSize) +{ + bytesWritten.append(data, maxSize); + + return 0; +} + +QByteArray *QLocalSocket::getWrittenData() +{ + return &bytesWritten; +} + +int QLocalSocket::getAttemptedConnectCount() +{ + return attemptedConnectCount; +} + +void QLocalSocket::setFailConnectCount(int count) +{ + failConnectCount = count; +} + + +QLocalSocket *QLocalSocket::instance() +{ + return self; +} + + diff --git a/tests/ut_duifeedbackplayer/qlocalsocket_mock.h b/tests/ut_duifeedbackplayer/qlocalsocket_mock.h new file mode 100644 index 000000000..6ecc724a3 --- /dev/null +++ b/tests/ut_duifeedbackplayer/qlocalsocket_mock.h @@ -0,0 +1,98 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef QLOCALSOCKET_H +#define QLOCALSOCKET_H + +#include +#include +#include + +class QLocalSocket : public QIODevice +{ + Q_OBJECT + +public: + enum LocalSocketError { + ConnectionRefusedError = QAbstractSocket::ConnectionRefusedError, + PeerClosedError = QAbstractSocket::RemoteHostClosedError, + ServerNotFoundError = QAbstractSocket::HostNotFoundError, + SocketAccessError = QAbstractSocket::SocketAccessError, + SocketResourceError = QAbstractSocket::SocketResourceError, + SocketTimeoutError = QAbstractSocket::SocketTimeoutError, + DatagramTooLargeError = QAbstractSocket::DatagramTooLargeError, + ConnectionError = QAbstractSocket::NetworkError, + UnsupportedSocketOperationError = QAbstractSocket::UnsupportedSocketOperationError, + UnknownSocketError = QAbstractSocket::UnknownSocketError + }; + + enum LocalSocketState { + UnconnectedState = QAbstractSocket::UnconnectedState, + ConnectingState = QAbstractSocket::ConnectingState, + ConnectedState = QAbstractSocket::ConnectedState, + ClosingState = QAbstractSocket::ClosingState + }; + + QLocalSocket(QObject *parent = 0); + ~QLocalSocket(); + + void connectToServer(const QString &name, OpenMode openMode = ReadWrite); + void disconnectFromServer(); + + bool flush(); + LocalSocketState state() const; + qint64 bytesAvailable() const; + + static void setFailConnectCount(int count); + QByteArray *getWrittenData(); + int getAttemptedConnectCount(); + void suddenDisconnect(); + void clearReceivedData(); + + // Interface to get instance of created QLocalSocket + static QLocalSocket *instance(); + +Q_SIGNALS: + void connected(); + void disconnected(); + void error(QLocalSocket::LocalSocketError socketError); + void stateChanged(QLocalSocket::LocalSocketState socketState); + +protected: + virtual qint64 readData(char *data, qint64 maxSize); + virtual qint64 writeData(const char *data, qint64 maxSize); + + LocalSocketState socketState; + + // How many times should connecting fail before succeeding + static int failConnectCount; + int attemptedConnectCount; + + // Buffer for received data from client + QByteArray bytesWritten; + + // Created instances of created QLocalSockets + static QLocalSocket *self; + +private: + Q_DISABLE_COPY(QLocalSocket) +}; + +#endif // QLOCALSOCKET_H + diff --git a/tests/ut_duifeedbackplayer/ut_duifeedbackplayer.cpp b/tests/ut_duifeedbackplayer/ut_duifeedbackplayer.cpp new file mode 100644 index 000000000..e9da7fefd --- /dev/null +++ b/tests/ut_duifeedbackplayer/ut_duifeedbackplayer.cpp @@ -0,0 +1,120 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duifeedbackplayer.h" +#include "duifeedbackplayer.h" +#include "duifeedbackplayer_p.h" +#include "duiapplicationprivate_mock.h" +#include "qlocalsocket_mock.h" +#include + +void Ut_DuiFeedbackPlayer::init() +{ +} + +void Ut_DuiFeedbackPlayer::cleanup() +{ +} + +void Ut_DuiFeedbackPlayer::initTestCase() +{ + feedbackPlayerContainer = new DuiApplicationPrivate("fooApplication"); + feedbackPlayer = feedbackPlayerContainer->feedbackPlayer; +} + +void Ut_DuiFeedbackPlayer::cleanupTestCase() +{ + delete feedbackPlayerContainer; + feedbackPlayerContainer = 0; +} + +/* + * Check that socket connection is established and that initial + * communication is correct. + */ +void Ut_DuiFeedbackPlayer::initialCommunicaton() +{ + QLocalSocket *testSocket; + QString writtenString; + + // Get written string + testSocket = QLocalSocket::instance(); + QDataStream testStream(*testSocket->getWrittenData()); + testStream >> writtenString; + + // Make sure the socket was connected + QCOMPARE(testSocket->state(), QLocalSocket::ConnectedState); + + // Make sure the data was as expected + QCOMPARE(writtenString, QString("fooApplication")); +} + +/* + * Check that reconnection works as expected if socket is unexpectedly + * disconnected. + */ +void Ut_DuiFeedbackPlayer::reconnect() +{ + QLocalSocket *testSocket; + QString writtenString; + + // Prepare socket + testSocket = QLocalSocket::instance(); + testSocket->clearReceivedData(); + testSocket->suddenDisconnect(); + + QDataStream testStream(*testSocket->getWrittenData()); + testStream >> writtenString; + + // Make sure the socket was connected + QCOMPARE(testSocket->state(), QLocalSocket::ConnectedState); + + // Make sure the data was as expected + QCOMPARE(writtenString, QString("fooApplication")); +} + +/* + * Check that feedbacks are played as expected. + */ +void Ut_DuiFeedbackPlayer::playFeedback() +{ + QLocalSocket *testSocket; + QString writtenString; + + // Prepare socket + testSocket = QLocalSocket::instance(); + testSocket->clearReceivedData(); + + // Play a few feedbacks + feedbackPlayer->play(QString("fooFeedback")); + feedbackPlayer->play(QString()); + feedbackPlayer->play(QString("barFeedback")); + + QDataStream testStream(*testSocket->getWrittenData()); + + // Make sure the data was as expected + testStream >> writtenString; + QCOMPARE(writtenString, QString("fooFeedback")); + // Empty feedback should not be sent at all + testStream >> writtenString; + QCOMPARE(writtenString, QString("barFeedback")); +} + +QTEST_MAIN(Ut_DuiFeedbackPlayer) + diff --git a/tests/ut_duifeedbackplayer/ut_duifeedbackplayer.h b/tests/ut_duifeedbackplayer/ut_duifeedbackplayer.h new file mode 100644 index 000000000..8e01a91ad --- /dev/null +++ b/tests/ut_duifeedbackplayer/ut_duifeedbackplayer.h @@ -0,0 +1,48 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIFEEDBACKPLAYER_H +#define UT_DUIFEEDBACKPLAYER_H + +#include +#include + +class DuiFeedbackPlayer; +class DuiApplicationPrivate; + +class Ut_DuiFeedbackPlayer : public QObject +{ + Q_OBJECT + +private slots: + void init(); + void cleanup(); + void initTestCase(); + void cleanupTestCase(); + + void initialCommunicaton(); + void reconnect(); + void playFeedback(); + +private: + DuiApplicationPrivate *feedbackPlayerContainer; + DuiFeedbackPlayer *feedbackPlayer; +}; + +#endif diff --git a/tests/ut_duifeedbackplayer/ut_duifeedbackplayer.pro b/tests/ut_duifeedbackplayer/ut_duifeedbackplayer.pro new file mode 100644 index 000000000..8c63d1a05 --- /dev/null +++ b/tests/ut_duifeedbackplayer/ut_duifeedbackplayer.pro @@ -0,0 +1,90 @@ +#include(../common_top.pri) + +# **************************************************************************** +# This is the contents of "../common_top.pri" modified so that libdui library +# is not included. (It's not needed with this test) +# **************************************************************************** +include(../check.pri) + +# for defines +include(../../mkspecs/common.pri) + +DUISRCDIR = ../../src +#STUBSDIR = ../stubs +INCLUDEPATH += . $$DUISRCDIR/include +#DEPENDPATH = $$INCLUDEPATH +#QMAKE_LIBDIR += ../../lib /usr/local/lib +CONFIG += debug +QT += testlib +TEMPLATE = app +# DEFINES += QT_NO_DEBUG_OUTPUT +DEFINES += UNIT_TEST +target.path = $$[QT_INSTALL_LIBS]/libdui-tests +INSTALLS += target + +#win32|macx { +# macx { +# QMAKE_LFLAGS += -F../../lib +# LIBS += -framework dui +# } +# win32:LIBS += -L../../lib -ldui0 +#} else { +# LIBS += ../../lib/libdui.so +#} + +QMAKE_CXXFLAGS += -Werror + +support_files.files = +support_files.path = $$[QT_INSTALL_LIBS]/libdui-tests +INSTALLS += support_files + +# **************************************************************************** +# "../common_top.pri" ends. +# **************************************************************************** + +INCLUDEPATH += $$DUISRCDIR/feedback + +TARGET = ut_duifeedbackplayer + +TESTED_SOURCES = $$DUISRCDIR/feedback/duifeedbackplayer.cpp \ + $$DUISRCDIR/feedback/duifeedbackplayer_p.cpp + +TESTED_HEADERS = $$DUISRCDIR/feedback/duifeedbackplayer.h \ + $$DUISRCDIR/feedback/duifeedbackplayer_p.h + +copysourcefiles.input = TESTED_SOURCES +copysourcefiles.output = ${QMAKE_FILE_BASE}.cpp +copysourcefiles.commands = $$QMAKE_COPY ${QMAKE_FILE_IN} ${QMAKE_FILE_BASE}.cpp +copysourcefiles.variable_out = SOURCES +copysourcefiles.CONFIG = target_predeps no_link +QMAKE_EXTRA_COMPILERS += copysourcefiles + +copyheaderfiles.input = TESTED_HEADERS +copyheaderfiles.output = ${QMAKE_FILE_BASE}.h +copyheaderfiles.commands = $$QMAKE_COPY ${QMAKE_FILE_IN} ${QMAKE_FILE_BASE}.h +copyheaderfiles.variable_out = HEADERS +copyheaderfiles.CONFIG = target_predeps no_link +QMAKE_EXTRA_COMPILERS += copyheaderfiles + +mocheaderfiles.input = TESTED_HEADERS +mocheaderfiles.output = moc_${QMAKE_FILE_BASE}.cpp +mocheaderfiles.commands = $$QMAKE_MOC $(DEFINES) $(INCPATH) ${QMAKE_FILE_BASE}.h -o moc_${QMAKE_FILE_BASE}.cpp +mocheaderfiles.variable_out = SOURCES +mocheaderfiles.CONFIG = target_predeps no_link +QMAKE_EXTRA_COMPILERS += mocheaderfiles + +SOURCES += \ + ut_duifeedbackplayer.cpp \ + qlocalsocket_mock.cpp \ + duiapplicationprivate_mock.cpp + +HEADERS += \ + ut_duifeedbackplayer.h \ + QLocalSocket \ + qlocalsocket.h \ + qlocalsocket_mock.h \ + duiapplicationprivate_mock.h \ + duiexport.h \ + duiexport_mock.h + +include(../common_bot.pri) diff --git a/tests/ut_duifiledatastore/.gitignore b/tests/ut_duifiledatastore/.gitignore new file mode 100644 index 000000000..6e4a27931 --- /dev/null +++ b/tests/ut_duifiledatastore/.gitignore @@ -0,0 +1 @@ +ut_duifiledatastore diff --git a/tests/ut_duifiledatastore/ut_duifiledatastore.cpp b/tests/ut_duifiledatastore/ut_duifiledatastore.cpp new file mode 100644 index 000000000..123bad23f --- /dev/null +++ b/tests/ut_duifiledatastore/ut_duifiledatastore.cpp @@ -0,0 +1,374 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duifiledatastore.h" +#include "duifiledatastore.h" + +// Map for storing the original settings values +QMap * originalSettingsMap; +// Map for storing the changed settings values +QMap * changedSettingsMap; +// Map to use for the current settings instance values +QMap * settingsMapForNextQSettingsInstance; + +// Indicator whether QSettings object has been synchronized. +bool gIsSynchronized; +// File in which the data will be stored. +QString gStoreFile; +// Status of the QSettings +QSettings::Status gQSettingsStatus; +// Whether QSettings is writable or not +bool gQSettingsIsWritable; +// Whether QSettings should synchronize itself when sync()ed +bool gSynchronize; +// Whether a sync fails +bool gQSettingsSyncFails; + +// QMap for storing the settings object and the map for using settings values +QMap *> mapForQSettingsInstance; + +// Stubs of QSettings methods +QSettings::QSettings(const QString &fileName, Format format, QObject *parent) +{ + Q_UNUSED(format); + Q_UNUSED(parent); + gStoreFile = fileName; + mapForQSettingsInstance.insert(this, settingsMapForNextQSettingsInstance); +} +QSettings::~QSettings() +{ +} +QStringList QSettings::allKeys() const +{ + return mapForQSettingsInstance.value(this)->keys(); +} +void QSettings::setValue(const QString &key, const QVariant &value) +{ + mapForQSettingsInstance.value(this)->insert(key, value); +} +QVariant QSettings::value(const QString &key, const QVariant &defaultValue) const +{ + if (mapForQSettingsInstance.value(this)->contains(key)) { + return mapForQSettingsInstance.value(this)->value(key); + } else { + return defaultValue; + } +} + +void QSettings::sync() +{ + if (gQSettingsSyncFails) { + return; + } + gIsSynchronized = true; + if (gSynchronize) { + mapForQSettingsInstance.value(this)->clear(); + foreach(const QString & key, settingsMapForNextQSettingsInstance->keys()) { + mapForQSettingsInstance.value(this)->insert(key, settingsMapForNextQSettingsInstance->value(key)); + } + } +} + +void QSettings::remove(const QString &key) +{ + mapForQSettingsInstance.value(this)->remove(key); +} +void QSettings::clear() +{ + if (gQSettingsSyncFails) { + return; + } + mapForQSettingsInstance.value(this)->clear(); +} +bool QSettings::contains(const QString &key) const +{ + return mapForQSettingsInstance.value(this)->contains(key); +} +QSettings::Status QSettings::status() const +{ + if (gQSettingsSyncFails) { + return QSettings::AccessError; + } + return gQSettingsStatus; +} +bool QSettings::isWritable() const +{ + return gQSettingsIsWritable; +} +QString QSettings::fileName() const +{ + return gStoreFile; +} + +//! QFileSystemWatcher stubs +void QFileSystemWatcher::addPath(const QString &) +{ +} + +//! Signal Receptor class +void SignalReceptor::valueChanged(const QString &key, QVariant value) +{ + keys.append(key); + values.append(value); +} + +void Ut_DuiFileDataStore::init() +{ + gQSettingsSyncFails = false; + gIsSynchronized = false; + gSynchronize = false; + gStoreFile.clear(); + gQSettingsStatus = QSettings::NoError; + gQSettingsIsWritable = true; + + originalSettingsMap = new QMap; + settingsMapForNextQSettingsInstance = originalSettingsMap; + m_subject = new DuiFileDataStore(QString("/tmp/store.data")); +} + +void Ut_DuiFileDataStore::cleanup() +{ + delete m_subject; + m_subject = NULL; + + delete originalSettingsMap; + originalSettingsMap = NULL; +} + +void Ut_DuiFileDataStore::testFileOpening() +{ + QCOMPARE(m_subject->isReadable(), true); + QCOMPARE(m_subject->isWritable(), true); + QCOMPARE(gStoreFile, QString("/tmp/store.data")); +} + +void Ut_DuiFileDataStore::testValueSetting() +{ + SignalReceptor *receptor = new SignalReceptor; + connect(m_subject, SIGNAL(valueChanged(QString, QVariant)), receptor, SLOT(valueChanged(QString, QVariant))); + m_subject->setValue(QString("key"), QVariant(QString("value"))); + QVERIFY(!settingsMapForNextQSettingsInstance->contains("key")); + QCOMPARE(receptor->keys.count(), 0); + QCOMPARE(receptor->values.count(), 0); + + m_subject->createValue("key", "value"); + QCOMPARE(settingsMapForNextQSettingsInstance->value("key").toString(), QString("value")); + QVERIFY(gIsSynchronized); + // Verify that only one signal is sent with the given key/value + QCOMPARE(receptor->keys.count(), 1); + QCOMPARE(receptor->keys.at(0), QString("key")); + QCOMPARE(receptor->values.count(), 1); + QCOMPARE(receptor->values.at(0).toString(), QString("value")); + + m_subject->setValue(QString("key"), QVariant(QString("changed_value"))); + QCOMPARE(settingsMapForNextQSettingsInstance->value("key").toString(), QString("changed_value")); + QVERIFY(gIsSynchronized); + // Verify that another signal is sent with the new key/value + QCOMPARE(receptor->keys.count(), 2); + QCOMPARE(receptor->keys.at(1), QString("key")); + QCOMPARE(receptor->values.count(), 2); + QCOMPARE(receptor->values.at(1).toString(), QString("changed_value")); + delete receptor; +} + +void Ut_DuiFileDataStore::testValueReading() +{ + m_subject->createValue(QString("key"), QVariant(QString("value"))); + QCOMPARE(m_subject->value(QString("key")).toString(), QString("value")); +} + +void Ut_DuiFileDataStore::testGettingAllKeys() +{ + QCOMPARE(m_subject->allKeys().size(), 0); + + m_subject->createValue(QString("key1"), QVariant(QString("foo"))); + m_subject->createValue(QString("key2"), QVariant(QString("bar"))); + QCOMPARE(m_subject->allKeys().size(), 2); + QCOMPARE(m_subject->allKeys().at(0), QString("key1")); + QCOMPARE(m_subject->allKeys().at(1), QString("key2")); +} + +void Ut_DuiFileDataStore::testDataRemoval() +{ + m_subject->createValue(QString("key"), QVariant(QString("value"))); + + // Clear synchronized flag to ensure that datastore is synchronized when removing data. + gIsSynchronized = false; + + m_subject->remove("key"); + QCOMPARE(m_subject->allKeys().size(), 0); + QVERIFY(gIsSynchronized); +} + +void Ut_DuiFileDataStore::testClear() +{ + m_subject->createValue(QString("key"), QVariant(QString("value"))); + m_subject->createValue(QString("key1"), QVariant(QString("value"))); + + // Clear synchronized flag to ensure that datastore is synchronized when removing data. + gIsSynchronized = false; + + // Clear file data store + m_subject->clear(); + + // Verify that all keys were removed from file data store and that the file backend was synchronized. + QCOMPARE(m_subject->allKeys().size(), 0); + QVERIFY(gIsSynchronized); +} + +void Ut_DuiFileDataStore::testContains() +{ + m_subject->createValue(QString("key"), QVariant(QString("value"))); + QCOMPARE(m_subject->contains("key"), true); + + m_subject->setValue(QString("he-man"), QVariant(QString("value"))); + QCOMPARE(m_subject->contains("he-man"), false); +} + +void Ut_DuiFileDataStore::testFileNotReadable() +{ + gQSettingsStatus = QSettings::AccessError; + + QCOMPARE(m_subject->isReadable(), false); + m_subject->createValue("foo", "bar"); + QCOMPARE(m_subject->value("foo"), QVariant()); + QCOMPARE(m_subject->allKeys(), QStringList()); + QCOMPARE(m_subject->contains("foo"), false); +} + +void Ut_DuiFileDataStore::testFileNotWritable() +{ + m_subject->createValue("foo", "bar"); + + gQSettingsIsWritable = false; + + // Shouldn't be possible to clear + QStringList keys1 = m_subject->allKeys(); + m_subject->clear(); + QStringList keys2 = m_subject->allKeys(); + QCOMPARE(keys1, keys2); + + // Shouldn't be possible to create a new value + m_subject->createValue("bar", "bapapa"); + QCOMPARE(m_subject->contains("bar"), false); + + // Shouldn't be possible to change the value + m_subject->createValue("foo", "baz"); + QCOMPARE(m_subject->value("foo").toString(), QString("bar")); + + // Shouldn't be possible to remove a value + m_subject->remove("foo"); + QCOMPARE(m_subject->contains("foo"), true); +} + + +void Ut_DuiFileDataStore::testFileContentsInvalid() +{ + gQSettingsStatus = QSettings::FormatError; + + QCOMPARE(m_subject->isReadable(), false); + QCOMPARE(m_subject->isWritable(), false); +} + +void Ut_DuiFileDataStore::testSettingsFileModifiedExternally() +{ + + connect(this, SIGNAL(fileChanged(QString)), m_subject, SLOT(fileChanged(QString))); + QCOMPARE(m_subject->allKeys().count(), 0); + m_subject->createValue(QString("key"), QVariant(QString("value"))); + QCOMPARE(settingsMapForNextQSettingsInstance->value("key").toString(), QString("value")); + changedSettingsMap = new QMap; + changedSettingsMap->insert("key1", QVariant(QString("value1"))); + changedSettingsMap->insert("key2", QVariant(QString("value2"))); + + qRegisterMetaType("QVariant"); + QSignalSpy valueSpy(m_subject, SIGNAL(valueChanged(QString, QVariant))); + // Check nothing happens when fileChanged signal is emitted with wrong file name + emit fileChanged(QString("nonExistingFile")); + QCOMPARE(valueSpy.count(), 0); + + settingsMapForNextQSettingsInstance = changedSettingsMap; + gSynchronize = true; + + // note: the following tests don't need stubbing for the file operations, + // because DuiFileDataStore's file change notification merely compares + // an internal snaphot to internal QSettings. Thus the following tests + // actually unit test what happens when a file is modified. The QSettings + // is automatically updated, so the fileChanged slot merely compares + // those QSettings to the internal snapshot map. + + // Now signal emitted with correct file name. This will remove "key", + // and add "key1" and "key2" + emit fileChanged(gStoreFile); + QCOMPARE(valueSpy.count(), 3); + QCOMPARE(m_subject->contains("key"), false); + QCOMPARE(m_subject->contains("key1"), true); + QCOMPARE(m_subject->contains("key2"), true); + + // removal of a key from the file + changedSettingsMap->remove("key1"); + emit fileChanged(gStoreFile); + QCOMPARE(valueSpy.count(), 4); + QCOMPARE(m_subject->contains("key1"), false); + + // change of a value in the file + (*changedSettingsMap)["key2"] = "newValue"; + emit fileChanged(gStoreFile); + QCOMPARE(valueSpy.count(), 5); + QCOMPARE(m_subject->contains("key2"), true); + QCOMPARE(m_subject->value("key2").toString(), QString("newValue")); +} + +void Ut_DuiFileDataStore::testSyncFailure() +{ + m_subject->createValue("foo", "bar"); + gQSettingsSyncFails = true; + + // Shouldn't be possible to clear + QStringList keys1 = m_subject->allKeys(); + m_subject->clear(); + QStringList keys2 = m_subject->allKeys(); + QCOMPARE(keys1, keys2); + + // Shouldn't be possible to create a new value + m_subject->createValue("bar", "bapapa"); + QCOMPARE(m_subject->contains("bar"), false); + + // Shouldn't be possible to change the value + m_subject->setValue("foo", "baz"); + QCOMPARE(m_subject->value("foo").toString(), QString("bar")); + + // Shouldn't be possible to remove a value + m_subject->remove("foo"); + QCOMPARE(m_subject->contains("foo"), true); + + // Removing nonexistent value should not result in + // the value being present + m_subject->remove("nonexistent"); + QCOMPARE(m_subject->contains("nonexistent"), false); + + // Setting nonexistent value should not result in + // the value being present + m_subject->setValue("nonexistent", "badvalue"); + QCOMPARE(m_subject->contains("nonexistent"), false); + + gQSettingsSyncFails = false; +} + +QTEST_APPLESS_MAIN(Ut_DuiFileDataStore) diff --git a/tests/ut_duifiledatastore/ut_duifiledatastore.h b/tests/ut_duifiledatastore/ut_duifiledatastore.h new file mode 100644 index 000000000..1b077f836 --- /dev/null +++ b/tests/ut_duifiledatastore/ut_duifiledatastore.h @@ -0,0 +1,70 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIFILEDATASTORE_H +#define UT_DUIFILEDATASTORE_H + +#include +#include + +class DuiFileDataStore; + +class SignalReceptor : public QObject +{ + Q_OBJECT + +public slots: + void valueChanged(const QString &key, QVariant value); + +public: + QList keys; + QList values; +}; + +// Test case must inherit QObject +class Ut_DuiFileDataStore : public QObject +{ + Q_OBJECT + + DuiFileDataStore *m_subject; + +signals: + void fileChanged(const QString &fileName); + +private slots: + + void init(); + void cleanup(); + + void testFileOpening(); + void testValueSetting(); + void testValueReading(); + void testGettingAllKeys(); + void testDataRemoval(); + void testClear(); + void testContains(); + + void testFileNotReadable(); + void testFileNotWritable(); + void testFileContentsInvalid(); + void testSettingsFileModifiedExternally(); + void testSyncFailure(); +}; + +#endif // UT_DUIFILEDATASTORE_H diff --git a/tests/ut_duifiledatastore/ut_duifiledatastore.pro b/tests/ut_duifiledatastore/ut_duifiledatastore.pro new file mode 100644 index 000000000..ebba1fb5c --- /dev/null +++ b/tests/ut_duifiledatastore/ut_duifiledatastore.pro @@ -0,0 +1,11 @@ +include(../common_top.pri) +TARGET = ut_duifiledatastore +INCLUDEPATH += $$DUISRCDIR/mashup/appletcommunication $$DUISRCDIR/mashup/appletinterface $$DUISRCDIR/mashup/mashup + +SOURCES += \ + ut_duifiledatastore.cpp \ + +HEADERS += \ + ut_duifiledatastore.h \ + +include(../common_bot.pri) diff --git a/tests/ut_duiflowlayoutpolicy/.gitignore b/tests/ut_duiflowlayoutpolicy/.gitignore new file mode 100644 index 000000000..d037b40bc --- /dev/null +++ b/tests/ut_duiflowlayoutpolicy/.gitignore @@ -0,0 +1 @@ +ut_duiflowlayoutpolicy diff --git a/tests/ut_duiflowlayoutpolicy/ut_duiflowlayoutpolicy.cpp b/tests/ut_duiflowlayoutpolicy/ut_duiflowlayoutpolicy.cpp new file mode 100644 index 000000000..2b4b401eb --- /dev/null +++ b/tests/ut_duiflowlayoutpolicy/ut_duiflowlayoutpolicy.cpp @@ -0,0 +1,701 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duiflowlayoutpolicy.h" + +#include +#include +#include +#include +#include +#include +#include +#include +/** + MockLayoutItem objects are layed out with the layout policy to test. + MockLayoutItems are then investigated for the correct geometry values + assigned by the test layout. +*/ +class MockLayoutItem : public QGraphicsLayoutItem +{ +protected: + QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint) const { + Q_UNUSED(which); + Q_UNUSED(constraint); + switch (which) { + case Qt::MinimumSize: + return QSizeF(1, 1); + case Qt::PreferredSize: + return QSizeF(7, 7); + case Qt::MaximumSize: + return QSizeF(19, 19); + default: + return QSizeF(11, 11); + } + } +}; + + +Ut_DuiFlowLayoutPolicy::Ut_DuiFlowLayoutPolicy() + : m_mockLayout(0) + , m_policy(0) + , m_mockItem100(0) + , m_mockItem200(0) + , m_mockItem300(0) +{ } + +Ut_DuiFlowLayoutPolicy::~Ut_DuiFlowLayoutPolicy() +{ } + +DuiApplication *app; +DuiApplicationWindow *appWin; +void Ut_DuiFlowLayoutPolicy::initTestCase() +{ + static int argc = 1; + static char *argv[1] = { (char *) "./ut_duiflowlayoutpolicy" }; + app = new DuiApplication(argc, argv); + app->setLayoutDirection(Qt::LeftToRight); + appWin = new DuiApplicationWindow; +} + +void Ut_DuiFlowLayoutPolicy::cleanupTestCase() +{ + delete appWin; + delete app; +} + +void Ut_DuiFlowLayoutPolicy::init() +{ + Q_ASSERT(0 == m_mockLayout); + m_mockLayout = new DuiLayout(); + m_mockLayout->setContentsMargins(0, 0, 0, 0); + m_form = new QGraphicsWidget; + m_form->setLayout(m_mockLayout); + Q_ASSERT(0 == m_policy); + m_policy = new DuiFlowLayoutPolicy(m_mockLayout); + m_policy->setSpacing(0); + + // set up some mock items + Q_ASSERT(0 == m_mockItem100); + m_mockItem100 = new MockLayoutItem; + m_mockItem100->setPreferredSize(100, 100); + + Q_ASSERT(0 == m_mockItem200); + m_mockItem200 = new MockLayoutItem; + m_mockItem200->setPreferredSize(200, 100); + + Q_ASSERT(0 == m_mockItem300); + m_mockItem300 = new MockLayoutItem; + m_mockItem300->setPreferredSize(300, 100); + + m_mockLayout->setPolicy(m_policy); + m_mockLayout->setAnimation(0); // turn off animation +} + +void Ut_DuiFlowLayoutPolicy::cleanup() +{ + Q_ASSERT(0 != m_mockItem100); + m_mockLayout->removeItem(m_mockItem100); + m_mockItem100 = 0; + + Q_ASSERT(0 != m_mockItem200); + m_mockLayout->removeItem(m_mockItem200); + m_mockItem200 = 0; + + Q_ASSERT(0 != m_mockItem300); + m_mockLayout->removeItem(m_mockItem300); + m_mockItem300 = 0; + + Q_ASSERT(0 != m_policy); + delete m_policy; + m_policy = 0; + + //FIXME Without this processEvents, we get a segmentation fault as a deleted object gets + //an event sent to it. This needs to be fixed + qApp->processEvents(); + Q_ASSERT(0 != m_mockLayout); + delete m_mockLayout; + m_mockLayout = 0; +} + +/** Simplest test with one item, layout's preferred size is determined by the + preferred size of the item. */ +void Ut_DuiFlowLayoutPolicy::testOneItemLayout() +{ + m_policy->addItem(m_mockItem100); + qApp->processEvents(); //for spacing change to trigger relayout + + // item moved to the correct place? + QCOMPARE(m_mockItem100->geometry(), QRectF(QPointF(0, 0), + m_mockItem100->preferredSize())); + + // check layout size hints + //QCOMPARE(m_mockLayout->minimumSize(), m_mockItem100->minimumSize()); + QCOMPARE(m_mockLayout->minimumSize(), m_mockItem100->preferredSize()); + QCOMPARE(m_mockLayout->preferredSize(), m_mockItem100->preferredSize()); + QCOMPARE(m_mockLayout->maximumSize(), QSizeF(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX)); + + QCOMPARE(m_policy->rowCount(), 1); +} + +/** Test with two items, layout is wide enough to keep both items in a single + row. */ +void Ut_DuiFlowLayoutPolicy::testTwoItemsHorizontally() +{ + QCOMPARE(m_mockLayout->sizePolicy().horizontalPolicy(), QSizePolicy::Expanding); + QCOMPARE(m_mockLayout->sizePolicy().verticalPolicy(), QSizePolicy::Expanding); + QCOMPARE(m_mockLayout->sizePolicy().hasHeightForWidth(), true); + m_policy->addItem(m_mockItem100); + m_policy->addItem(m_mockItem200); + + m_form->setGeometry(QRectF(0, 0, m_mockItem100->preferredWidth() + + m_mockItem200->preferredWidth(), 500)); + QCOMPARE(m_mockLayout->geometry(), QRectF(0, 0, m_mockItem100->preferredWidth() + + m_mockItem200->preferredWidth(), 500)); + + // items moved to the correct place? + QCOMPARE(m_mockItem100->geometry(), QRectF(QPointF(0, 0), + m_mockItem100->preferredSize())); + QCOMPARE(m_mockItem200->geometry(), QRectF( + QPointF(m_mockItem100->preferredWidth(), 0), + m_mockItem200->preferredSize())); + + // check layout size hints + /* QCOMPARE(m_mockLayout->minimumSize(), + QSizeF(m_mockItem100->preferredWidth() + m_mockItem200->preferredWidth(), + qMax(m_mockItem100->preferredHeight(), m_mockItem200->preferredHeight())));*/ + QCOMPARE(m_mockLayout->minimumSize(), + QSizeF(qMax(m_mockItem100->preferredWidth(), m_mockItem200->preferredWidth()), + qMax(m_mockItem100->preferredHeight(), m_mockItem200->preferredHeight()))); + + QCOMPARE(m_mockLayout->preferredSize(), + QSizeF(m_mockItem100->preferredWidth() + m_mockItem200->preferredWidth(), + qMax(m_mockItem100->preferredHeight(), m_mockItem200->preferredHeight()))); + QCOMPARE(m_mockLayout->maximumSize(), QSizeF(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX)); + QCOMPARE(m_policy->rowCount(), 1); +} + +/** Test with two items, layout is so narrow that each item should end up in + its own row. */ +void Ut_DuiFlowLayoutPolicy::testTwoItemsVertically() +{ + m_policy->addItem(m_mockItem100); + m_policy->addItem(m_mockItem200); + m_form->setGeometry(QRectF(0, 0, m_mockItem100->preferredWidth() + + m_mockItem200->preferredWidth() - 1, 500)); + + // items moved to the correct place? + QCOMPARE(m_mockItem100->geometry(), QRectF(QPointF(0, 0), + m_mockItem100->preferredSize())); + QCOMPARE(m_mockItem200->geometry(), QRectF( + QPointF(0, m_mockItem100->preferredHeight()), + m_mockItem200->preferredSize())); + + // check layout size hints. Setting geometry shouldn't affect size hint, so the items should still layout out on the same row + //QCOMPARE(m_mockLayout->minimumSize(), QSizeF(2,1)); + QCOMPARE(m_mockLayout->minimumSize(), + QSizeF(qMax(m_mockItem100->preferredWidth(), m_mockItem200->preferredWidth()), + m_mockItem100->preferredHeight() + m_mockItem200->preferredHeight())); + + QCOMPARE(m_mockLayout->maximumSize(), QSizeF(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX)); + + // Now set the maximum width. This time the size hint should respect the maximum width + m_mockLayout->setMaximumWidth(m_mockItem100->preferredWidth() + + m_mockItem200->preferredWidth() - 100); + m_mockLayout->setPreferredWidth(m_mockItem100->preferredWidth() + + m_mockItem200->preferredWidth() - 100); + //QCOMPARE(m_mockLayout->minimumSize(), QSizeF(2,1)); + QCOMPARE(m_mockLayout->minimumSize(), + QSizeF(qMax(m_mockItem100->preferredWidth(), m_mockItem200->preferredWidth()), + m_mockItem100->preferredHeight() + m_mockItem200->preferredHeight())); + + QCOMPARE(m_mockLayout->preferredSize(), + QSizeF(qMax(m_mockItem100->preferredWidth(), m_mockItem200->preferredWidth()), + m_mockItem100->preferredHeight() + m_mockItem200->preferredHeight())); + QCOMPARE(m_mockLayout->maximumSize(), + QSizeF(m_mockItem100->preferredWidth() + + m_mockItem200->preferredWidth() - 100, + QWIDGETSIZE_MAX)); + + QCOMPARE(m_policy->rowCount(), 2); +} + +/** Test with three items, layout is so narrow that the items should end up in + two rows. */ +void Ut_DuiFlowLayoutPolicy::testHorizontallyAndVertically() +{ + m_policy->addItem(m_mockItem100); + m_policy->addItem(m_mockItem200); + m_policy->addItem(m_mockItem300); + + m_form->setGeometry(QRectF(0, 0, m_mockItem100->preferredWidth() + + m_mockItem200->preferredWidth(), 500)); + + // items moved to the correct place? + QCOMPARE(m_mockItem100->geometry(), QRectF(QPointF(0, 0), + m_mockItem100->preferredSize())); + QCOMPARE(m_mockItem200->geometry(), QRectF( + QPointF(m_mockItem100->preferredWidth(), 0), + m_mockItem200->preferredSize())); + QCOMPARE(m_mockItem300->geometry(), QRectF( + QPointF(0, qMax(m_mockItem100->preferredHeight(), + m_mockItem200->preferredHeight())), + m_mockItem300->preferredSize())); + + // check layout size hints. These should just ignore the current geometry + //QCOMPARE(m_mockLayout->minimumSize(), QSizeF(3, 1)); + QCOMPARE(m_mockLayout->minimumSize(), + QSizeF(qMax(qMax(m_mockItem100->preferredWidth(), m_mockItem200->preferredWidth()), m_mockItem300->preferredWidth()), + qMax(m_mockItem100->preferredHeight(), m_mockItem200->preferredHeight()) + m_mockItem300->preferredHeight())); + + QCOMPARE(m_mockLayout->preferredSize(), + QSizeF(m_mockItem100->preferredWidth() + m_mockItem200->preferredWidth(), //current geometry + qMax(m_mockItem100->preferredHeight(), m_mockItem200->preferredHeight()) + m_mockItem300->preferredHeight())); + QCOMPARE(m_mockLayout->maximumSize(), QSizeF(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX)); + + m_mockLayout->setMaximumWidth(m_mockItem100->preferredWidth() + m_mockItem200->preferredWidth()); + m_mockLayout->setPreferredWidth(m_mockItem100->preferredWidth() + m_mockItem200->preferredWidth()); + //Now lets set the geometry to something with a large width and small height then let it resize with setMaximumWidth + m_form->setGeometry(QRectF(0, 0, 10000, 0)); + QCOMPARE(m_mockLayout->geometry(), QRectF(0, 0, m_mockItem100->preferredWidth() + m_mockItem200->preferredWidth(), qMax(m_mockItem100->preferredHeight(), m_mockItem200->preferredHeight()) + m_mockItem300->preferredHeight())); + QCOMPARE(m_policy->rowCount(), 2); +} +void Ut_DuiFlowLayoutPolicy::testReorderingFlow() +{ + //This specifically tests bug report 110604 + m_mockLayout->setContentsMargins(1, 1, 1, 1); + + QList items; + for (int i = 0; i < 3; i++) { + QGraphicsWidget *item = new QGraphicsWidget; + item->setMinimumWidth(250); + item->setPreferredWidth(250); + item->setMaximumWidth(250); + item->setMinimumHeight(10); + item->setPreferredHeight(10); + m_policy->addItem(item); + items << item; + } + // Make the parent widget big enough to fit all 3 widgets + m_form->setMinimumWidth(864); + m_form->setMaximumWidth(864); + qApp->processEvents(); //for spacing change to trigger relayout + //All three children should be on one row + QCOMPARE(items[0]->geometry(), QRectF(1, 1, 250, 10)); + QCOMPARE(items[1]->geometry(), QRectF(251, 1, 250, 10)); + QCOMPARE(items[2]->geometry(), QRectF(501, 1, 250, 10)); + QCOMPARE(m_policy->rowCount(), 1); + + // Make the parent widget big enough to fit only 1 widget per row + m_form->setMinimumWidth(267); + m_form->setMaximumWidth(267); + qApp->processEvents(); + QCOMPARE(items[0]->geometry(), QRectF(1, 1, 250, 10)); + QCOMPARE(items[1]->geometry(), QRectF(1, 11, 250, 10)); + QCOMPARE(items[2]->geometry(), QRectF(1, 21, 250, 10)); + + QCOMPARE(m_form->minimumHeight(), 32.0); + QCOMPARE(m_policy->rowCount(), 3); +} + +/** Test with margins and three items, layout is so narrow that the items should end up in + two rows. */ +void Ut_DuiFlowLayoutPolicy::testMargins() +{ + m_policy->addItem(m_mockItem100); + m_policy->addItem(m_mockItem200); + m_policy->addItem(m_mockItem300); + + m_mockLayout->setContentsMargins(1, 1, 1, 1); + m_form->setGeometry(QRectF(0, 0, m_mockItem100->preferredWidth() + + m_mockItem200->preferredWidth() + 2, 500)); + + // items moved to the correct place? + QCOMPARE(m_mockItem100->geometry(), QRectF(QPointF(1, 1), + m_mockItem100->preferredSize())); + QCOMPARE(m_mockItem200->geometry(), QRectF( + QPointF(m_mockItem100->preferredWidth() + 1, 1), + m_mockItem200->preferredSize())); + QCOMPARE(m_mockItem300->geometry(), QRectF( + QPointF(1, 1 + qMax(m_mockItem100->preferredHeight(), + m_mockItem200->preferredHeight())), + m_mockItem300->preferredSize())); + + // check layout size hints. These should just ignore the current geometry + //QCOMPARE(m_mockLayout->minimumSize(), QSizeF(5, 3)); + QCOMPARE(m_mockLayout->minimumSize(), + QSizeF(qMax(qMax(m_mockItem100->preferredWidth(), m_mockItem200->preferredWidth()), m_mockItem300->preferredWidth()) + 2, + qMax(m_mockItem100->preferredHeight(), m_mockItem200->preferredHeight()) + m_mockItem300->preferredHeight() + 2)); + + QCOMPARE(m_mockLayout->preferredSize(), + QSizeF(m_mockItem100->preferredWidth() + m_mockItem200->preferredWidth() + 2, //current geometry + qMax(m_mockItem100->preferredHeight(), m_mockItem200->preferredHeight()) + m_mockItem300->preferredHeight() + 2)); + QCOMPARE(m_mockLayout->maximumSize(), QSizeF(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX)); + QCOMPARE(m_policy->rowCount(), 2); + + m_mockLayout->setMaximumWidth(m_mockItem100->preferredWidth() + m_mockItem200->preferredWidth() + 2); + m_mockLayout->setPreferredWidth(m_mockItem100->preferredWidth() + m_mockItem200->preferredWidth() + 2); + //Now lets set the geometry to something with a large width and small height then let it resize with setMaximumWidth + m_form->setGeometry(QRectF(0, 0, 10000, 0)); + QCOMPARE(m_policy->rowCount(), 2); + QCOMPARE(m_mockLayout->geometry(), QRectF(0, 0, m_mockItem100->preferredWidth() + m_mockItem200->preferredWidth() + 2, 2 + qMax(m_mockItem100->preferredHeight(), m_mockItem200->preferredHeight()) + m_mockItem300->preferredHeight())); +} + +/** Test with margins and two items, layout is so narrow that the items should end up in + two rows. */ +void Ut_DuiFlowLayoutPolicy::testMarginsAndTwoItems() +{ + m_policy->addItem(m_mockItem100); + m_policy->addItem(m_mockItem200); + + m_mockLayout->setContentsMargins(1, 1, 1, 1); + m_form->setGeometry(QRectF(0, 0, m_mockItem100->preferredWidth() + + m_mockItem200->preferredWidth() + 1, 500)); //exactly 1 pixel too small + QCOMPARE(m_policy->rowCount(), 2); + + // items moved to the correct place? + QCOMPARE(m_mockItem100->geometry(), QRectF(QPointF(1, 1), + m_mockItem100->preferredSize())); + QCOMPARE(m_mockItem200->geometry(), QRectF( + QPointF(1, 1 + m_mockItem100->preferredHeight()), + m_mockItem200->preferredSize())); +} + +/** Test with three items with spacing. The first and second items should be on one row with a space between them. The third item on the second row */ +void Ut_DuiFlowLayoutPolicy::testSpacing() +{ + m_policy->addItem(m_mockItem100); + m_policy->addItem(m_mockItem200); + m_policy->addItem(m_mockItem300); + qApp->processEvents(); //for spacing change to trigger relayout + + m_form->setGeometry(QRectF(0, 0, m_mockItem100->preferredWidth() + + m_mockItem200->preferredWidth() + 15, 500)); + m_policy->setSpacing(15); + QCOMPARE(m_policy->rowCount(), 2); + qApp->processEvents(); //for spacing change to trigger relayout + + // items moved to the correct place? + QCOMPARE(m_mockItem100->geometry(), QRectF(QPointF(0, 0), + m_mockItem100->preferredSize())); + QCOMPARE(m_mockItem200->geometry(), QRectF( + QPointF(m_mockItem100->preferredWidth() + 15, 0), + m_mockItem200->preferredSize())); + QCOMPARE(m_mockItem300->geometry(), QRectF( + QPointF(0, qMax(m_mockItem100->preferredHeight(), + m_mockItem200->preferredHeight()) + 15), + m_mockItem300->preferredSize())); + + // check layout size hints. + //QCOMPARE(m_mockLayout->minimumSize(), QSizeF(3, 1)); + QCOMPARE(m_mockLayout->minimumSize(), + QSizeF(qMax(qMax(m_mockItem100->preferredWidth(), m_mockItem200->preferredWidth()), m_mockItem300->preferredWidth()), + qMax(m_mockItem100->preferredHeight(), m_mockItem200->preferredHeight() + 15 + m_mockItem300->preferredHeight()))); + + QCOMPARE(m_mockLayout->preferredSize(), + QSizeF(m_mockItem100->preferredWidth() + m_mockItem200->preferredWidth() + 15, //current width + qMax(m_mockItem100->preferredHeight(), m_mockItem200->preferredHeight()) + 15 + m_mockItem300->preferredHeight())); + QCOMPARE(m_mockLayout->maximumSize(), QSizeF(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX)); + QCOMPARE(m_policy->rowCount(), 2); + + m_form->setMinimumWidth(m_mockItem100->preferredWidth() + m_mockItem200->preferredWidth() + 15); + m_form->setMaximumWidth(m_mockItem100->preferredWidth() + m_mockItem200->preferredWidth() + 15); + m_form->setPreferredWidth(m_mockItem100->preferredWidth() + m_mockItem200->preferredWidth() + 15); + //Now lets set the geometry to something with a large width and small height then let it resize with setMaximumWidth + m_form->setGeometry(QRectF(0, 0, 10000, 0)); + QCOMPARE(m_mockLayout->geometry(), QRectF(0, 0, m_mockItem100->preferredWidth() + m_mockItem200->preferredWidth() + 15, m_mockItem200->preferredHeight() + m_mockItem300->preferredHeight() + 15)); + QCOMPARE(m_policy->rowCount(), 2); +} + +/** Test with three items with different horizontal and vertical spacing. The first and second items should be on one row with a space between them. The third item on the second row */ +void Ut_DuiFlowLayoutPolicy::testHorizontalVerticalSpacing() +{ + m_policy->addItem(m_mockItem100); + m_policy->addItem(m_mockItem200); + m_policy->addItem(m_mockItem300); + qApp->processEvents(); //for spacing change to trigger relayout + + m_form->setGeometry(QRectF(0, 0, m_mockItem100->preferredWidth() + + m_mockItem200->preferredWidth() + 15, 500)); + m_policy->setHorizontalSpacing(15); + m_policy->setVerticalSpacing(10); + qApp->processEvents(); //for spacing change to trigger relayout + + // items moved to the correct place? + QCOMPARE(m_mockItem100->geometry(), QRectF(QPointF(0, 0), + m_mockItem100->preferredSize())); + QCOMPARE(m_mockItem200->geometry(), QRectF( + QPointF(m_mockItem100->preferredWidth() + 15, 0), + m_mockItem200->preferredSize())); + QCOMPARE(m_mockItem300->geometry(), QRectF( + QPointF(0, qMax(m_mockItem100->preferredHeight(), + m_mockItem200->preferredHeight()) + 10), + m_mockItem300->preferredSize())); + + // check layout size hints. These should just ignore the current geometry + //QCOMPARE(m_mockLayout->minimumSize(), QSizeF(3, 1)); + QCOMPARE(m_mockLayout->minimumSize(), + QSizeF(qMax(qMax(m_mockItem100->preferredWidth(), m_mockItem200->preferredWidth()), m_mockItem300->preferredWidth()), + qMax(m_mockItem100->preferredHeight(), m_mockItem200->preferredHeight() + 10 + m_mockItem300->preferredHeight()))); + + QCOMPARE(m_mockLayout->preferredSize(), + QSizeF(m_mockItem100->preferredWidth() + m_mockItem200->preferredWidth() + 15, //current geometry + qMax(m_mockItem100->preferredHeight(), m_mockItem200->preferredHeight()) + 10 + m_mockItem300->preferredHeight())); + QCOMPARE(m_mockLayout->maximumSize(), QSizeF(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX)); + + m_form->setMinimumWidth(m_mockItem100->preferredWidth() + m_mockItem200->preferredWidth() + 15); + m_form->setMaximumWidth(m_mockItem100->preferredWidth() + m_mockItem200->preferredWidth() + 15); + m_form->setPreferredWidth(m_mockItem100->preferredWidth() + m_mockItem200->preferredWidth() + 15); + //Now lets set the geometry to something with a large width and small height then let it resize with setMaximumWidth + m_form->setGeometry(QRectF(0, 0, 10000, 0)); + QCOMPARE(m_mockLayout->geometry(), QRectF(0, 0, m_mockItem100->preferredWidth() + m_mockItem200->preferredWidth() + 15, m_mockItem200->preferredHeight() + m_mockItem300->preferredHeight() + 10)); + QCOMPARE(m_policy->rowCount(), 2); +} + +Q_DECLARE_METATYPE(QSizePolicy::Policy); +void Ut_DuiFlowLayoutPolicy::testHorizontalJustification_data() +{ + qRegisterMetaType("QSizePolicy::Policy"); + QTest::addColumn("horizontalPolicy"); + QTest::addColumn("verticalPolicy"); + QTest::addColumn("numItems"); + + //Test with 3x3 items + QTest::newRow("Horizontal: Fixed, Vertical: Fixed, 9 items") << QSizePolicy::Fixed << QSizePolicy::Fixed << 9; + QTest::newRow("Horizontal: Maximum, Vertical: Maximum, 9 items") << QSizePolicy::Maximum << QSizePolicy::Maximum << 9; + QTest::newRow("Horizontal: Expanding, Vertical: Maximum, 9 items") << QSizePolicy::Expanding << QSizePolicy::Maximum << 9; + QTest::newRow("Horizontal: Expanding, Vertical: Expanding, 9 items") << QSizePolicy::Expanding << QSizePolicy::Expanding << 9; + QTest::newRow("Horizontal: Fixed, Vertical: Expanding, 9 items") << QSizePolicy::Expanding << QSizePolicy::Expanding << 9; + + //Test with 3x3 items, plus 1 that is stretched across the entire row + QTest::newRow("Horizontal: Fixed, Vertical: Fixed, 10 items") << QSizePolicy::Fixed << QSizePolicy::Fixed << 10; + QTest::newRow("Horizontal: Maximum, Vertical: Maximum, 10 items") << QSizePolicy::Maximum << QSizePolicy::Maximum << 10; + QTest::newRow("Horizontal: Expanding, Vertical: Maximum, 10 items") << QSizePolicy::Expanding << QSizePolicy::Maximum << 10; + QTest::newRow("Horizontal: Expanding, Vertical: Expanding, 10 items") << QSizePolicy::Expanding << QSizePolicy::Expanding << 10; + QTest::newRow("Horizontal: Fixed, Vertical: Expanding, 10 items") << QSizePolicy::Expanding << QSizePolicy::Expanding << 10; + + //Test with 3x3 items, plus 2 that are equally stretched across the row + QTest::newRow("Horizontal: Fixed, Vertical: Fixed, 11 items") << QSizePolicy::Fixed << QSizePolicy::Fixed << 11; + QTest::newRow("Horizontal: Maximum, Vertical: Maximum, 11 items") << QSizePolicy::Maximum << QSizePolicy::Maximum << 11; + QTest::newRow("Horizontal: Expanding, Vertical: Maximum, 11 items") << QSizePolicy::Expanding << QSizePolicy::Maximum << 11; + QTest::newRow("Horizontal: Expanding, Vertical: Expanding, 11 items") << QSizePolicy::Expanding << QSizePolicy::Expanding << 11; + QTest::newRow("Horizontal: Fixed, Vertical: Expanding, 11 items") << QSizePolicy::Expanding << QSizePolicy::Expanding << 11; + +} +void Ut_DuiFlowLayoutPolicy::testEmptyCount() +{ + QCOMPARE(m_policy->rowCount(), 0); +} +void Ut_DuiFlowLayoutPolicy::testHorizontalJustification() +{ + QFETCH(QSizePolicy::Policy, horizontalPolicy); + QFETCH(QSizePolicy::Policy, verticalPolicy); + QFETCH(int, numItems); + for (int i = 0; i < numItems; ++i) { + QGraphicsWidget *widget = new QGraphicsWidget; + if (i % 2) //make one tall, one short, one tall, one short, etc.. + widget->setPreferredSize(100, 100); + else + widget->setPreferredSize(100, 50); + + widget->setSizePolicy(horizontalPolicy, verticalPolicy); + m_policy->addItem(widget); + qApp->processEvents(); //for spacing change to trigger relayout + } + //test with all three items set to + m_form->setGeometry(QRectF(0, 0, 300 /*preferred sizes */ + 2 /*spacing*/ + 6 /*expandable size */, 10000)); + m_policy->setHorizontalSpacing(1); + m_policy->setVerticalSpacing(0); + qApp->processEvents(); //for spacing change to trigger relayout + + for (int i = 0; i < numItems; ++i) { + QPointF position; + QSizeF size; + //the items should have expanded and moved horizontally to fill up the extra space + if (horizontalPolicy & QSizePolicy::GrowFlag) { + position = QPointF(103 * (i % 3), 100 * (i / 3)); + if (i == 10) { + position.setX(153.5 + 1); + size.setWidth(153.5); + } else if (i == 9 && numItems == 11) + size.setWidth(153.5); + else if (i == 9 && numItems == 10) + size.setWidth(300 + 2 + 6); + else + size.setWidth(102); + } else { + position = QPointF(101 * (i % 3), 100 * (i / 3)); + size.setWidth(100); + } + + if (verticalPolicy & QSizePolicy::GrowFlag) + size.setHeight(100); + else + size.setHeight((i % 2) ? 100 : 50); + QCOMPARE(m_mockLayout->itemAt(i)->geometry(), QRectF(position, size)); + } + if (numItems == 9) + QCOMPARE(m_policy->rowCount(), 3); + else + QCOMPARE(m_policy->rowCount(), 4); +} + +void Ut_DuiFlowLayoutPolicy::testTwoByTwoThenRemoveThird_data() +{ + QTest::addColumn("deleteItem"); + QTest::addColumn("removeFromLayout"); + QTest::addColumn("removeFromPolicy"); + + //test every combination, except all of them false + for (int removeFromLayout = 0; removeFromLayout < 2; removeFromLayout++) + for (int removeFromPolicy = 0; removeFromPolicy < 2; removeFromPolicy++) + for (int deleteItem = (removeFromLayout || removeFromPolicy) ? 0 : 1; deleteItem < 2; deleteItem++) { + QString description = QString("") + + (removeFromLayout ? "Remove from layout. " : "") + + (removeFromPolicy ? "Remove from policy. " : "") + + (deleteItem ? "Delete." : ""); + QTest::newRow(description.toLatin1()) << (bool)deleteItem << (bool)removeFromLayout << (bool)removeFromPolicy; + } +} +void Ut_DuiFlowLayoutPolicy::testTwoByTwoThenRemoveThird() +{ + //This tests specifically for NB#140106 + //We add four items of size 25x25 in a 2x2 order, then remove the third + QFETCH(bool, deleteItem); + QFETCH(bool, removeFromLayout); + QFETCH(bool, removeFromPolicy); + + m_form->setMaximumWidth(54); + m_form->setMinimumWidth(54); + m_mockLayout->setContentsMargins(2, 2, 2, 2); + for (int i = 0; i < 4; i++) { + QGraphicsWidget *item = new QGraphicsWidget; + item->setMinimumSize(25, 25); + item->setMaximumSize(25, 25); + m_policy->addItem(item); + } + qApp->processEvents(); + QCOMPARE(m_form->geometry(), QRectF(0, 0, 54, 54)); + QCOMPARE(m_mockLayout->geometry(), QRectF(0, 0, 54, 54)); + for (int i = 0; i < 4; i++) { + QCOMPARE(m_policy->itemAt(i)->geometry(), QRectF((i % 2) * 25 + 2, (i / 2) * 25 + 2, 25, 25)); + QVERIFY(m_mockLayout->itemAt(i) == m_policy->itemAt(i)); + } + QGraphicsLayoutItem *thirdItem = m_mockLayout->itemAt(2); + if (removeFromPolicy) + m_policy->removeAt(2); + if (removeFromLayout) + m_mockLayout->removeAt(2); + if (deleteItem) + delete thirdItem; + + QCOMPARE(m_form->geometry(), QRectF(0, 0, 54, 54)); + QCOMPARE(m_mockLayout->geometry(), QRectF(0, 0, 54, 54)); + + qApp->processEvents(); + QCOMPARE(m_form->geometry(), QRectF(0, 0, 54, 54)); + QCOMPARE(m_mockLayout->geometry(), QRectF(0, 0, 54, 54)); + for (int i = 0; i < 3; i++) { + QCOMPARE(m_policy->itemAt(i)->geometry(), QRectF((i % 2) * 25 + 2, (i / 2) * 25 + 2, 25, 25)); + if (deleteItem || removeFromLayout || i != 2) + QVERIFY(m_mockLayout->itemAt(i) == m_policy->itemAt(i)); + else + QVERIFY(m_mockLayout->itemAt(3) == m_policy->itemAt(2)); + } + +} +void Ut_DuiFlowLayoutPolicy::testBigItemInSmallLayout() +{ + m_form->setMaximumSize(QSizeF(40, 40)); + m_policy->addItem(m_mockItem100); + m_policy->addItem(m_mockItem200); + qApp->processEvents(); + QCOMPARE(m_form->geometry(), QRectF(0, 0, 40, 40)); + QCOMPARE(m_mockLayout->geometry(), QRectF(0, 0, 200, 200)); + QCOMPARE(m_mockItem100->geometry(), QRectF(0, 0, 100, 100)); + QCOMPARE(m_mockItem200->geometry(), QRectF(0, 100, 200, 100)); + + //Now try setting the layout's maximumSize to be smaller than its maximumSize + //This causes contradictory behaviour, but it should not crash at least + m_mockLayout->setMaximumSize(QSizeF(40, 40)); + qApp->processEvents(); + QCOMPARE(m_form->geometry(), QRectF(0, 0, 40, 40)); + QCOMPARE(m_mockLayout->geometry(), QRectF(0, 0, 40, 40)); + QCOMPARE(m_mockItem100->geometry(), QRectF(0, 0, 40, 100)); + QCOMPARE(m_mockItem200->geometry(), QRectF(0, 100, 40, 100)); +} + +void Ut_DuiFlowLayoutPolicy::testMarginsAndMinimumHeight() +{ + m_form->setMinimumWidth(128); + m_form->setMaximumWidth(128); + m_form->setContentsMargins(1, 0, 0, 0); + // Create a child widget and put the child inside the parent + for (int j = 0; j < 3; j++) { + // Create a child widget and put the child inside the parent 1 + MockLayoutItem *childWidget = new MockLayoutItem; + childWidget->setMinimumSize(64, 64); + m_policy->addItem(childWidget); + } + qApp->processEvents(); + QCOMPARE(m_form->geometry(), QRectF(0, 0, 128, 64 * 3)); + QCOMPARE(m_mockLayout->geometry(), QRectF(1, 0, 127, 64 * 3)); +} + +void Ut_DuiFlowLayoutPolicy::testAddingRemovingAdding() +{ + new DuiBasicLayoutAnimation(m_mockLayout); + QPointer w1 = new QGraphicsWidget; + QPointer w2 = new QGraphicsWidget; + QPointer w3 = new QGraphicsWidget; + QPointer w4 = new QGraphicsWidget; + w1->setMinimumSize(64, 64); + w2->setMinimumSize(64, 64); + w3->setMinimumSize(64, 64); + w4->setMinimumSize(64, 64); + m_policy->addItem(w1); + m_policy->addItem(w2); + m_policy->addItem(w3); + qApp->processEvents(); + + //Remove them all and readd them + m_mockLayout->removeAt(0); + m_mockLayout->removeAt(0); + m_mockLayout->removeAt(0); + QCOMPARE(m_mockLayout->count(), 0); + QCOMPARE(m_policy->count(), 0); + m_policy->addItem(w1); + m_policy->addItem(w2); + m_policy->addItem(w3); + m_policy->addItem(w4); + QCOMPARE(m_mockLayout->count(), 4); + QCOMPARE(m_policy->count(), 4); + qApp->processEvents(); + + QCOMPARE(w1.isNull(), false); + QCOMPARE(w2.isNull(), false); + QCOMPARE(w3.isNull(), false); + QCOMPARE(w4.isNull(), false); + + QCOMPARE(w1->isVisible(), true); + QCOMPARE(w2->isVisible(), true); + QCOMPARE(w3->isVisible(), true); + QCOMPARE(w4->isVisible(), true); +} +QTEST_APPLESS_MAIN(Ut_DuiFlowLayoutPolicy) diff --git a/tests/ut_duiflowlayoutpolicy/ut_duiflowlayoutpolicy.h b/tests/ut_duiflowlayoutpolicy/ut_duiflowlayoutpolicy.h new file mode 100644 index 000000000..f9828fc2b --- /dev/null +++ b/tests/ut_duiflowlayoutpolicy/ut_duiflowlayoutpolicy.h @@ -0,0 +1,72 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIFLOWLAYOUTPOLICY_H +#define UT_DUIFLOWLAYOUTPOLICY_H + +#include +#include + +class QGraphicsLayoutItem; +class DuiLayout; +class DuiFlowLayoutPolicy; +class QGraphicsWidget; + +class Ut_DuiFlowLayoutPolicy : public QObject +{ + Q_OBJECT + +public: + Ut_DuiFlowLayoutPolicy(); + virtual ~Ut_DuiFlowLayoutPolicy(); + +private slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + + void testHorizontalJustification_data(); + void testHorizontalJustification(); + void testReorderingFlow(); + void testOneItemLayout(); + void testTwoItemsHorizontally(); + void testTwoItemsVertically(); + void testHorizontallyAndVertically(); + void testMargins(); + void testMarginsAndTwoItems(); + void testSpacing(); + void testHorizontalVerticalSpacing(); + void testEmptyCount(); + void testTwoByTwoThenRemoveThird_data(); + void testTwoByTwoThenRemoveThird(); + void testBigItemInSmallLayout(); + void testMarginsAndMinimumHeight(); + void testAddingRemovingAdding(); +private: + + DuiLayout *m_mockLayout; + DuiFlowLayoutPolicy *m_policy; + QGraphicsLayoutItem *m_mockItem100; + QGraphicsLayoutItem *m_mockItem200; + QGraphicsLayoutItem *m_mockItem300; + QGraphicsWidget *m_form; +}; + +#endif // Header guard diff --git a/tests/ut_duiflowlayoutpolicy/ut_duiflowlayoutpolicy.pro b/tests/ut_duiflowlayoutpolicy/ut_duiflowlayoutpolicy.pro new file mode 100644 index 000000000..2ef53abc3 --- /dev/null +++ b/tests/ut_duiflowlayoutpolicy/ut_duiflowlayoutpolicy.pro @@ -0,0 +1,12 @@ +include(../common_top.pri) +TARGET = ut_duiflowlayoutpolicy + +# unit test and unit +SOURCES += \ + ut_duiflowlayoutpolicy.cpp \ + +# unit test and unit +HEADERS += \ + ut_duiflowlayoutpolicy.h \ + +include(../common_bot.pri) diff --git a/tests/ut_duifreestylelayoutpolicy/.gitignore b/tests/ut_duifreestylelayoutpolicy/.gitignore new file mode 100644 index 000000000..2bc0d4804 --- /dev/null +++ b/tests/ut_duifreestylelayoutpolicy/.gitignore @@ -0,0 +1 @@ +ut_duifreestylelayoutpolicy diff --git a/tests/ut_duifreestylelayoutpolicy/ut_duifreestylelayoutpolicy.cpp b/tests/ut_duifreestylelayoutpolicy/ut_duifreestylelayoutpolicy.cpp new file mode 100644 index 000000000..651392370 --- /dev/null +++ b/tests/ut_duifreestylelayoutpolicy/ut_duifreestylelayoutpolicy.cpp @@ -0,0 +1,199 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duifreestylelayoutpolicy.h" + +#include +#include +#include +#include +#include +#include +#include +/** + MockLayoutItem objects are layed out with the layout policy to test. + MockLayoutItems are then investigated for the correct geometry values + assigned by the test layout. +*/ +class MockLayoutItem : public QGraphicsLayoutItem +{ +protected: + QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint) const { + Q_UNUSED(which); + Q_UNUSED(constraint); + switch (which) { + case Qt::MinimumSize: + return QSizeF(1, 1); + case Qt::PreferredSize: + return QSizeF(7, 7); + case Qt::MaximumSize: + return QSizeF(19, 19); + default: + return QSizeF(11, 11); + } + } +}; + + +Ut_DuiFreestyleLayoutPolicy::Ut_DuiFreestyleLayoutPolicy() + : m_mockLayout(0) + , m_policy(0) + , m_mockItem100(0) + , m_mockItem200(0) + , m_mockItem300(0) +{ } + +Ut_DuiFreestyleLayoutPolicy::~Ut_DuiFreestyleLayoutPolicy() +{ } + +DuiApplication *app; +void Ut_DuiFreestyleLayoutPolicy::initTestCase() +{ + static int argc = 1; + static char *argv[1] = { (char *) "./ut_duifreestylelayoutpolicy" }; + app = new DuiApplication(argc, argv); +} + +void Ut_DuiFreestyleLayoutPolicy::cleanupTestCase() +{ + delete app; +} + +void Ut_DuiFreestyleLayoutPolicy::init() +{ + Q_ASSERT(0 == m_mockLayout); + m_form = new QGraphicsWidget; + m_mockLayout = new DuiLayout(m_form); + m_mockLayout->setContentsMargins(0, 0, 0, 0); + Q_ASSERT(0 == m_policy); + m_policy = new DuiFreestyleLayoutPolicy(m_mockLayout); + m_policy->setSpacing(0); + + // set up some mock items + Q_ASSERT(0 == m_mockItem100); + m_mockItem100 = new MockLayoutItem; + m_mockItem100->setPreferredSize(100, 100); + + Q_ASSERT(0 == m_mockItem200); + m_mockItem200 = new MockLayoutItem; + m_mockItem200->setPreferredSize(200, 200); + + Q_ASSERT(0 == m_mockItem300); + m_mockItem300 = new MockLayoutItem; + m_mockItem300->setPreferredSize(300, 300); + + m_mockLayout->setPolicy(m_policy); + m_mockLayout->setAnimation(0); // turn off animation +} + +void Ut_DuiFreestyleLayoutPolicy::cleanup() +{ + Q_ASSERT(0 != m_mockItem100); + m_mockLayout->removeItem(m_mockItem100); + m_mockItem100 = 0; + + Q_ASSERT(0 != m_mockItem200); + m_mockLayout->removeItem(m_mockItem200); + m_mockItem200 = 0; + + Q_ASSERT(0 != m_mockItem300); + m_mockLayout->removeItem(m_mockItem300); + m_mockItem300 = 0; + + Q_ASSERT(0 != m_policy); + delete m_policy; + m_policy = 0; + + //FIXME Without this processEvents, we get a segmentation fault as a deleted object gets + //an event sent to it. This needs to be fixed + qApp->processEvents(); + Q_ASSERT(0 != m_mockLayout); + delete m_mockLayout; + m_mockLayout = 0; +} + +void Ut_DuiFreestyleLayoutPolicy::testOneItemLayout() +{ + //Test size of layout with no items + QCOMPARE(m_mockLayout->minimumSize(), QSizeF(0, 0)); + QCOMPARE(m_mockLayout->preferredSize(), QSizeF(0, 0)); + QCOMPARE(m_mockLayout->maximumSize(), QSizeF(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX)); + m_form->setGeometry(QRectF(0, 0, 100, 100)); + + // Add an item + m_policy->addItem(m_mockItem100); + qApp->processEvents(); //for change to trigger relayout + // item moved to the correct place? + QCOMPARE(m_mockItem100->geometry(), QRectF(QPointF(0, 0), + m_mockItem100->preferredSize())); + + // check layout size hints + //QCOMPARE(m_mockLayout->minimumSize(), m_mockItem100->minimumSize()); + QCOMPARE(m_mockLayout->minimumSize(), m_mockItem100->preferredSize()); + QCOMPARE(m_mockLayout->preferredSize(), m_mockItem100->preferredSize()); + QCOMPARE(m_mockLayout->maximumSize(), QSizeF(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX)); + + //Now remove item. Layout sizehints should go back to how they were + //m_mockLayout->removeItem(m_mockItem100); + m_policy->removeItem(m_mockItem100); + QCOMPARE(m_mockLayout->minimumSize(), QSizeF(0, 0)); + QCOMPARE(m_mockLayout->preferredSize(), QSizeF(0, 0)); + QCOMPARE(m_mockLayout->maximumSize(), QSizeF(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX)); +} +void Ut_DuiFreestyleLayoutPolicy::testThreeItemLayout() +{ + //Test size of layout with no items + QCOMPARE(m_mockLayout->minimumSize(), QSizeF(0, 0)); + QCOMPARE(m_mockLayout->preferredSize(), QSizeF(0, 0)); + QCOMPARE(m_mockLayout->maximumSize(), QSizeF(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX)); + m_form->setGeometry(QRectF(0, 0, 300, 100)); + + // Add an item + m_policy->addItem(m_mockItem100); + m_policy->addItem(m_mockItem200); + m_policy->addItem(m_mockItem300); + qApp->processEvents(); //for change to trigger relayout + // item moved to the correct place? + /* QCOMPARE(m_mockItem100->geometry(), QRectF(0,200,100,100)); + QCOMPARE(m_mockItem200->geometry(), QRectF(0,300,200,200)); + QCOMPARE(m_mockItem300->geometry(), QRectF(0,500,300,300)); + QCOMPARE(m_mockLayout->geometry(), QRectF(0,0,300,800));*/ +} + +void Ut_DuiFreestyleLayoutPolicy::testThreeItemLayoutWithGivenGeometry() +{ + //Test size of layout with no items + QCOMPARE(m_mockLayout->minimumSize(), QSizeF(0, 0)); + QCOMPARE(m_mockLayout->preferredSize(), QSizeF(0, 0)); + QCOMPARE(m_mockLayout->maximumSize(), QSizeF(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX)); + m_form->setGeometry(QRectF(10, 10, 300, 100)); + + // Add an item + m_policy->addItemAtGeometry(m_mockItem100, QRectF(0, 0, 100, 100)); + m_policy->addItemAtGeometry(m_mockItem200, QRectF(100, 0, 200, 200)); + m_policy->addItemAtGeometry(m_mockItem300, QRectF(0, 200, 300, 300)); + qApp->processEvents(); //for change to trigger relayout + // item moved to the correct place? + /* QCOMPARE(m_mockItem100->geometry(), QRectF(0,0,100,100)); + QCOMPARE(m_mockItem200->geometry(), QRectF(100,0,200,200)); + QCOMPARE(m_mockItem300->geometry(), QRectF(0,200,300,300)); + QCOMPARE(m_mockLayout->geometry(), QRectF(0,0,300,500));*/ +} + +QTEST_APPLESS_MAIN(Ut_DuiFreestyleLayoutPolicy) diff --git a/tests/ut_duifreestylelayoutpolicy/ut_duifreestylelayoutpolicy.h b/tests/ut_duifreestylelayoutpolicy/ut_duifreestylelayoutpolicy.h new file mode 100644 index 000000000..55a28c0ca --- /dev/null +++ b/tests/ut_duifreestylelayoutpolicy/ut_duifreestylelayoutpolicy.h @@ -0,0 +1,57 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIFREESTYLELAYOUTPOLICY_H +#define UT_DUIFREESTYLELAYOUTPOLICY_H + +#include +#include + +class QGraphicsLayoutItem; +class DuiLayout; +class DuiFreestyleLayoutPolicy; +class QGraphicsWidget; + +class Ut_DuiFreestyleLayoutPolicy : public QObject +{ + Q_OBJECT + +public: + Ut_DuiFreestyleLayoutPolicy(); + virtual ~Ut_DuiFreestyleLayoutPolicy(); + +private slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + void testOneItemLayout(); + void testThreeItemLayout(); + void testThreeItemLayoutWithGivenGeometry(); +private: + + DuiLayout *m_mockLayout; + DuiFreestyleLayoutPolicy *m_policy; + QGraphicsLayoutItem *m_mockItem100; + QGraphicsLayoutItem *m_mockItem200; + QGraphicsLayoutItem *m_mockItem300; + QGraphicsWidget *m_form; +}; + +#endif // Header guard diff --git a/tests/ut_duifreestylelayoutpolicy/ut_duifreestylelayoutpolicy.pro b/tests/ut_duifreestylelayoutpolicy/ut_duifreestylelayoutpolicy.pro new file mode 100644 index 000000000..72bd5c99a --- /dev/null +++ b/tests/ut_duifreestylelayoutpolicy/ut_duifreestylelayoutpolicy.pro @@ -0,0 +1,12 @@ +include(../common_top.pri) +TARGET = ut_duifreestylelayoutpolicy + +# unit test and unit +SOURCES += \ + ut_duifreestylelayoutpolicy.cpp \ + +# unit test and unit +HEADERS += \ + ut_duifreestylelayoutpolicy.h \ + +include(../common_bot.pri) diff --git a/tests/ut_duigconfdatastore/.gitignore b/tests/ut_duigconfdatastore/.gitignore new file mode 100644 index 000000000..8a5b065f1 --- /dev/null +++ b/tests/ut_duigconfdatastore/.gitignore @@ -0,0 +1 @@ +ut_duigconfdatastore diff --git a/tests/ut_duigconfdatastore/ut_duigconfdatastore.cpp b/tests/ut_duigconfdatastore/ut_duigconfdatastore.cpp new file mode 100644 index 000000000..c45ff8ed3 --- /dev/null +++ b/tests/ut_duigconfdatastore/ut_duigconfdatastore.cpp @@ -0,0 +1,234 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duigconfdatastore.h" +#include + +#include +#include + +// DuiGConfItem stubs +struct DuiGConfItemPrivate { + QString key; + QVariant value; +}; + +QMultiHash gDuiGConfItems; +QList gUnsetDuiGconfItems; + +DuiGConfItem::DuiGConfItem(const QString &key, QObject *parent) + : QObject(parent) +{ + priv = new DuiGConfItemPrivate; + priv->key = key; + + // Set default value + if (priv->key == "/gconf/key") { + priv->value = QVariant("value"); + } else if (priv->key == "/gconf/key1") { + priv->value = QVariant("value1"); + } else if (priv->key == "/gconf/key2") { + priv->value = QVariant("value2"); + } + + gDuiGConfItems.insert(key, this); +} + +DuiGConfItem::~DuiGConfItem() +{ + gDuiGConfItems.remove(priv->key, this); + delete priv; +} + +QList DuiGConfItem::listEntries() const +{ + QList entries; + entries.append("/gconf/key"); + entries.append("/gconf/key1"); + entries.append("/gconf/key2"); + + return entries; +} + +QVariant DuiGConfItem::value() const +{ + return priv->value; +} + +void DuiGConfItem::set(const QVariant &val) +{ + priv->value = val; +} + +void DuiGConfItem::unset() +{ + gUnsetDuiGconfItems.append(priv->key); + set(QVariant()); +} + +// Test class +void Ut_DuiGConfDataStore::initTestCase() +{ +} + +void Ut_DuiGConfDataStore::cleanupTestCase() +{ +} + +void Ut_DuiGConfDataStore::init() +{ + stringVariantSlotArguments.clear(); + gDuiGConfItems.clear(); + gUnsetDuiGconfItems.clear(); + + m_subject = new DuiGConfDataStore("/gconf"); +} + +void Ut_DuiGConfDataStore::cleanup() +{ + delete m_subject; + m_subject = NULL; + + // Check after deleting the test subject that it didn't leave any memory reserved + QCOMPARE(gDuiGConfItems.count(), 0); +} + +void Ut_DuiGConfDataStore::testReading() +{ + QCOMPARE(m_subject->value("key").toString(), QString("value")); +} + +void Ut_DuiGConfDataStore::testWriting() +{ + QCOMPARE(m_subject->setValue("key", "newValue"), true); + QCOMPARE(m_subject->value("key").toString(), QString("newValue")); + QCOMPARE(m_subject->createValue("foo", "bar"), true); + QCOMPARE(m_subject->value("foo").toString(), QString("bar")); +} + +void Ut_DuiGConfDataStore::testReadingNonExistingKey() +{ + // Try to read from an empty container + QCOMPARE(m_subject->value("nonexisting"), QVariant(QVariant::Invalid)); + + // Add something to the container but try to read a different key + QCOMPARE(m_subject->value("nonexisting"), QVariant(QVariant::Invalid)); +} + +void Ut_DuiGConfDataStore::testWritingNonExistingKey() +{ + // Try to write to an empty container + QCOMPARE(m_subject->setValue("nonexisting", "newValue"), false); + + // Add something to the container but try to write a different key + QCOMPARE(m_subject->setValue("nonexisting", "newValue"), false); +} + +void Ut_DuiGConfDataStore::testSignalReceivedWhenValueChanges() +{ + // Set a new value for the item + DuiGConfItem *gconfItem = gDuiGConfItems.value("/gconf/key"); + gconfItem->set(QString("newValue")); + + // Set up signals + connect(this, SIGNAL(valueChanged()), gconfItem, SIGNAL(valueChanged())); + connect(m_subject, SIGNAL(valueChanged(QString, QVariant)), this, SLOT(stringVariantSlot(QString, QVariant))); + emit valueChanged(); + + QCOMPARE(stringVariantSlotArguments.count(), 1); + { + const QPair& arguments = stringVariantSlotArguments.at(0); + QCOMPARE(arguments.first, QString("key")); + QCOMPARE(arguments.second.type(), QVariant::String); + QCOMPARE(arguments.second.toString(), QString("newValue")); + } + + // Add a second key, change the first and check that the correct information is signaled + gconfItem->set(QString("secondNewValue")); + stringVariantSlotArguments.clear(); + emit valueChanged(); + + QCOMPARE(stringVariantSlotArguments.count(), 1); + { + const QPair& arguments = stringVariantSlotArguments.at(0); + QCOMPARE(arguments.first, QString("key")); + QCOMPARE(arguments.second.type(), QVariant::String); + QCOMPARE(arguments.second.toString(), QString("secondNewValue")); + } + + // Now change the second value and check that the correct information is signaled + disconnect(this, SIGNAL(valueChanged()), gconfItem, SIGNAL(valueChanged())); + gconfItem = gDuiGConfItems.value("/gconf/key1"); + gconfItem->set(QString("newValue1")); + stringVariantSlotArguments.clear(); + // Set up signals + connect(this, SIGNAL(valueChanged()), gconfItem, SIGNAL(valueChanged())); + emit valueChanged(); + + QCOMPARE(stringVariantSlotArguments.count(), 1); + { + const QPair& arguments = stringVariantSlotArguments.at(0); + QCOMPARE(arguments.first, QString("key1")); + QCOMPARE(arguments.second.type(), QVariant::String); + QCOMPARE(arguments.second.toString(), QString("newValue1")); + } +} + +void Ut_DuiGConfDataStore::stringVariantSlot(const QString &string, const QVariant &variant) +{ + stringVariantSlotArguments.append(qMakePair(string, variant)); +} + +void Ut_DuiGConfDataStore::testAllKeys() +{ + QStringList keys = m_subject->allKeys(); + QCOMPARE(keys.count(), 3); + QVERIFY(keys.contains("key")); + QVERIFY(keys.contains("key1")); + QVERIFY(keys.contains("key2")); +} + +void Ut_DuiGConfDataStore::testRemove() +{ + QVERIFY(m_subject->setValue("key", "newValue")); + m_subject->remove("key"); + QCOMPARE(m_subject->value("key"), QVariant(QVariant::Invalid)); +} + +void Ut_DuiGConfDataStore::testClear() +{ + QCOMPARE(gDuiGConfItems.count(), 3); + m_subject->clear(); + QCOMPARE(gDuiGConfItems.count(), 0); +} + +void Ut_DuiGConfDataStore::testContains() +{ + QVERIFY(m_subject->contains("key")); + QVERIFY(!m_subject->contains("bar")); +} + +void Ut_DuiGConfDataStore::testSubPathsNotSupported() +{ + QVERIFY(!m_subject->setValue("key/subkey", 123)); + QVERIFY(!m_subject->createValue("key/subkey", 123)); +} + + +QTEST_APPLESS_MAIN(Ut_DuiGConfDataStore) diff --git a/tests/ut_duigconfdatastore/ut_duigconfdatastore.h b/tests/ut_duigconfdatastore/ut_duigconfdatastore.h new file mode 100644 index 000000000..12eaa3b60 --- /dev/null +++ b/tests/ut_duigconfdatastore/ut_duigconfdatastore.h @@ -0,0 +1,68 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIAPPLETGCONFDATASTORE_H +#define UT_DUIAPPLETGCONFDATASTORE_H + +#include +#include + +class DuiGConfDataStore; + +class Ut_DuiGConfDataStore : public QObject +{ + Q_OBJECT + +private slots: + // Called before the first testfunction is executed + void initTestCase(); + // Called after the last testfunction was executed + void cleanupTestCase(); + // Called before each testfunction is executed + void init(); + // Called after every testfunction + void cleanup(); + + // Tests + void testReading(); + void testWriting(); + void testReadingNonExistingKey(); + void testWritingNonExistingKey(); + + void testSignalReceivedWhenValueChanges(); + + void testAllKeys(); + void testRemove(); + void testClear(); + void testContains(); + void testSubPathsNotSupported(); + +signals: + void valueChanged(); + +private slots: + void stringVariantSlot(const QString &string, const QVariant &variant); + +private: + DuiGConfDataStore *m_subject; + + QList > stringVariantSlotArguments; +}; + +#endif // UT_DUIAPPLETGCONFDATASTORE_H diff --git a/tests/ut_duigconfdatastore/ut_duigconfdatastore.pro b/tests/ut_duigconfdatastore/ut_duigconfdatastore.pro new file mode 100644 index 000000000..e08b4dad8 --- /dev/null +++ b/tests/ut_duigconfdatastore/ut_duigconfdatastore.pro @@ -0,0 +1,14 @@ +include(../common_top.pri) +TARGET = ut_duigconfdatastore + +INCLUDEPATH += $$DUISRCDIR/mashup/mashup + +SOURCES += \ + ut_duigconfdatastore.cpp \ + $$DUISRCDIR/mashup/mashup/duigconfdatastore.cpp + +HEADERS += \ + ut_duigconfdatastore.h \ + $$DUISRCDIR/mashup/mashup/duigconfdatastore.h + +include(../common_bot.pri) diff --git a/tests/ut_duigridlayoutpolicy/.gitignore b/tests/ut_duigridlayoutpolicy/.gitignore new file mode 100644 index 000000000..8c3f46445 --- /dev/null +++ b/tests/ut_duigridlayoutpolicy/.gitignore @@ -0,0 +1 @@ +ut_duigridlayoutpolicy diff --git a/tests/ut_duigridlayoutpolicy/ut_duigridlayoutpolicy.cpp b/tests/ut_duigridlayoutpolicy/ut_duigridlayoutpolicy.cpp new file mode 100644 index 000000000..1c16790ff --- /dev/null +++ b/tests/ut_duigridlayoutpolicy/ut_duigridlayoutpolicy.cpp @@ -0,0 +1,416 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duigridlayoutpolicy.h" + +#include +#include +#include + +#include +#include + +/** + MockLayoutItem objects are laid out with the layout policy to test. + MockLayoutItems are then investigated for the correct geometry values + assigned by the test layout. +*/ +class MockLayoutItem : public QGraphicsLayoutItem +{ +protected: + QSizeF sizeHint(Qt::SizeHint , const QSizeF &) const { + return QSize(-1, -1); + } +}; + + +Ut_DuiGridLayoutPolicy::Ut_DuiGridLayoutPolicy() + : m_mockLayout(0) + , m_policy(0) + , m_mockItem100(0) + , m_mockItem200(0) + , m_mockItem300(0) + , m_mockItem400(0) +{ } + +Ut_DuiGridLayoutPolicy::~Ut_DuiGridLayoutPolicy() +{ } + +DuiApplication *app; +void Ut_DuiGridLayoutPolicy::initTestCase() +{ + static int argc = 1; + static char *argv[1] = { (char *) "./ut_duigridlayoutpolicy" }; + app = new DuiApplication(argc, argv); + app->setLayoutDirection(Qt::LeftToRight); +} + +void Ut_DuiGridLayoutPolicy::cleanupTestCase() +{ + delete app; +} + +void Ut_DuiGridLayoutPolicy::init() +{ + Q_ASSERT(0 == m_mockLayout); + m_mockLayout = new DuiLayout(); + m_form = new QGraphicsWidget; + m_form->setLayout(m_mockLayout); + Q_ASSERT(0 == m_policy); + m_policy = new DuiGridLayoutPolicy(m_mockLayout); + m_policy->setSpacing(0); + m_mockLayout->setContentsMargins(0, 0, 0, 0); + + // set up some mock items + Q_ASSERT(0 == m_mockItem100); + m_mockItem100 = new MockLayoutItem; + m_mockItem100->setMinimumSize(100.0, 100.0); + m_mockItem100->setPreferredSize(100.0, 100.0); + m_mockItem100->setMaximumSize(100.0, 100.0); + + Q_ASSERT(0 == m_mockItem200); + m_mockItem200 = new MockLayoutItem; + m_mockItem200->setMinimumSize(200.0, 200.0); + m_mockItem200->setPreferredSize(200.0, 200.0); + m_mockItem200->setMaximumSize(200.0, 200.0); + + Q_ASSERT(0 == m_mockItem300); + m_mockItem300 = new MockLayoutItem; + m_mockItem300->setMinimumSize(300.0, 300.0); + m_mockItem300->setPreferredSize(300.0, 300.0); + m_mockItem300->setMaximumSize(300.0, 300.0); + + Q_ASSERT(0 == m_mockItem400); + m_mockItem400 = new MockLayoutItem; + m_mockItem400->setMinimumSize(400.0, 400.0); + m_mockItem400->setPreferredSize(400.0, 400.0); + m_mockItem400->setMaximumSize(400.0, 400.0); + + m_mockLayout->setPolicy(m_policy); + m_mockLayout->setAnimation(0); // turn off animation +} + +void Ut_DuiGridLayoutPolicy::cleanup() +{ + Q_ASSERT(0 != m_mockItem100); + m_mockLayout->removeItem(m_mockItem100); + m_mockItem100 = 0; + + Q_ASSERT(0 != m_mockItem200); + m_mockLayout->removeItem(m_mockItem200); + m_mockItem200 = 0; + + Q_ASSERT(0 != m_mockItem300); + m_mockLayout->removeItem(m_mockItem300); + m_mockItem300 = 0; + + Q_ASSERT(0 != m_mockItem400); + m_mockLayout->removeItem(m_mockItem400); + m_mockItem400 = 0; + + Q_ASSERT(0 != m_policy); + delete m_policy; + m_policy = 0; + + Q_ASSERT(0 != m_mockLayout); + delete m_form; //should delete layout too + m_mockLayout = 0; + m_form = 0; +} + +void Ut_DuiGridLayoutPolicy::testDeletingLayout() +{ + DuiLayout *layout = new DuiLayout; + DuiGridLayoutPolicy *policy = new DuiGridLayoutPolicy(layout); + policy->addItem(m_mockItem100, 0, 0); + delete policy; + delete layout; + qApp->processEvents(); + +} + +/** Simplest test with one item, all the layout's sizes are determined by the + sizes of the item. */ +void Ut_DuiGridLayoutPolicy::testOneItemLayout() +{ + m_policy->addItem(m_mockItem100, 0, 0); + qApp->processEvents(); + + // item moved to the correct place? + QCOMPARE(m_mockItem100->geometry(), QRectF(QPointF(0.0, 0.0), + m_mockItem100->preferredSize())); + + // check layout size hints + QCOMPARE(m_mockLayout->minimumSize(), QSizeF(100.0, 100.0)); + QCOMPARE(m_mockLayout->preferredSize(), QSizeF(100.0, 100.0)); + QCOMPARE(m_mockLayout->maximumSize(), QSizeF(100.0, 100.0)); +} + +/** Test with two items in one row. */ +void Ut_DuiGridLayoutPolicy::testHorizontally() +{ + m_policy->setSpacing(0.0); + m_policy->addItem(m_mockItem100, 0, 0); + m_policy->addItem(m_mockItem200, 0, 1); + qApp->processEvents(); //let relayout happen + + // items moved to the correct place? + QCOMPARE(m_mockItem100->geometry(), QRectF(QPointF(0.0, 0.0), QSize(100.0, 100.0))); + QCOMPARE(m_mockItem200->geometry(), QRectF(QPointF(100.0, 0.0), QSize(200.0, 200.0))); + + // check layout size hints + QCOMPARE(m_mockLayout->minimumSize(), QSizeF(300.0, 200.0)); + QCOMPARE(m_mockLayout->preferredSize(), QSizeF(300.0, 200.0)); + QCOMPARE(m_mockLayout->maximumSize(), QSizeF(300.0, 200.0)); +} + +/** Test with two items in one column. */ +void Ut_DuiGridLayoutPolicy::testVertically() +{ + m_policy->setSpacing(0.0); + m_policy->addItem(m_mockItem100, 0, 0); + m_policy->addItem(m_mockItem200, 1, 0); + qApp->processEvents(); //let relayout happen + + // items moved to the correct place? + QCOMPARE(m_mockItem100->geometry(), QRectF(QPointF(0.0, 0.0), QSize(100.0, 100.0))); + QCOMPARE(m_mockItem200->geometry(), QRectF(QPointF(0.0, 100.0), QSize(200.0, 200.0))); + + // check layout size hints + QCOMPARE(m_mockLayout->minimumSize(), QSizeF(200.0, 300.0)); + QCOMPARE(m_mockLayout->preferredSize(), QSizeF(200.0, 300.0)); + QCOMPARE(m_mockLayout->maximumSize(), QSizeF(200.0, 300.0)); +} + +/** Test with three items in two columns and rows. */ +void Ut_DuiGridLayoutPolicy::testHorizontallyAndVertically() +{ + m_policy->setSpacing(0.0); + m_policy->addItem(m_mockItem100, 0, 0); + m_policy->addItem(m_mockItem200, 0, 1); + m_policy->addItem(m_mockItem300, 1, 1); + qApp->processEvents(); //let relayout happen + + // items moved to the correct place? + QCOMPARE(m_mockItem100->geometry(), QRectF(QPointF(0.0, 0.0), QSize(100.0, 100.0))); + QCOMPARE(m_mockItem200->geometry(), QRectF(QPointF(100.0, 0.0), QSize(200.0, 200.0))); + QCOMPARE(m_mockItem300->geometry(), QRectF(QPointF(100.0, 200.0), QSize(300.0, 300.0))); + + // check layout size hints + QCOMPARE(m_mockLayout->minimumSize(), QSizeF(400.0, 500.0)); + QCOMPARE(m_mockLayout->preferredSize(), QSizeF(400.0, 500.0)); + QCOMPARE(m_mockLayout->maximumSize(), QSizeF(400.0, 500.0)); +} + + +/** Test with four items in two columns and rows and varying spacing values. */ +void Ut_DuiGridLayoutPolicy::testSpacing() +{ + // general spacing + qreal general_spacing = 12.0; + m_policy->setSpacing(general_spacing); + m_policy->addItem(m_mockItem100, 0, 0); + m_policy->addItem(m_mockItem200, 0, 1); + m_policy->addItem(m_mockItem300, 1, 0); + m_policy->addItem(m_mockItem400, 1, 1); + qApp->processEvents(); //let relayout happen + + // items moved to the correct place? + QCOMPARE(m_mockItem100->geometry(), QRectF(QPointF(0.0, 0.0), QSize(100.0, 100.0))); + QCOMPARE(m_mockItem200->geometry(), QRectF(QPointF(300.0 + general_spacing, 0.0), + QSize(200.0, 200.0))); + QCOMPARE(m_mockItem300->geometry(), QRectF(QPointF(0.0, 200.0 + general_spacing), + QSize(300.0, 300.0))); + QCOMPARE(m_mockItem400->geometry(), QRectF(QPointF(300.0 + general_spacing, + 200.0 + general_spacing), + QSize(400.0, 400.0))); + + // row spacing + qreal row_spacing = 17.0; + m_policy->setVerticalSpacing(row_spacing); //trigger a relayout + qApp->processEvents(); //let relayout happen + + // items moved to the correct place? + QCOMPARE(m_mockItem100->geometry(), QRectF(QPointF(0.0, 0.0), QSize(100.0, 100.0))); + QCOMPARE(m_mockItem200->geometry(), QRectF(QPointF(300.0 + general_spacing, 0.0), + QSize(200.0, 200.0))); + QCOMPARE(m_mockItem300->geometry(), QRectF(QPointF(0.0, 200.0 + row_spacing), + QSize(300.0, 300.0))); + QCOMPARE(m_mockItem400->geometry(), QRectF(QPointF(300.0 + general_spacing, + 200.0 + row_spacing), + QSize(400.0, 400.0))); + + // column spacing + qreal col_spacing = 7.0; + m_policy->setHorizontalSpacing(col_spacing); + qApp->processEvents(); + + // items moved to the correct place? + QCOMPARE(m_mockItem100->geometry(), QRectF(QPointF(0.0, 0.0), QSize(100.0, 100.0))); + QCOMPARE(m_mockItem200->geometry(), QRectF(QPointF(300.0 + col_spacing, 0.0), + QSize(200.0, 200.0))); + QCOMPARE(m_mockItem300->geometry(), QRectF(QPointF(0.0, 200.0 + row_spacing), + QSize(300.0, 300.0))); + QCOMPARE(m_mockItem400->geometry(), QRectF(QPointF(300.0 + col_spacing, + 200.0 + row_spacing), + QSize(400.0, 400.0))); + + // explicit spacing of single row + qreal single_row_spacing = 33.0; + m_policy->setRowSpacing(0.0, single_row_spacing); + qApp->processEvents(); + + // items moved to the correct place? + QCOMPARE(m_mockItem100->geometry(), QRectF(QPointF(0.0, 0.0), QSize(100.0, 100.0))); + QCOMPARE(m_mockItem200->geometry(), QRectF(QPointF(300.0 + col_spacing, 0.0), + QSize(200.0, 200.0))); + QCOMPARE(m_mockItem300->geometry(), QRectF(QPointF(0.0, 200.0 + single_row_spacing), + QSize(300.0, 300.0))); + QCOMPARE(m_mockItem400->geometry(), QRectF(QPointF(300.0 + col_spacing, + 200.0 + single_row_spacing), + QSize(400.0, 400.0))); + + // explicit spacing of single column + qreal single_col_spacing = 14.0; + m_policy->setColumnSpacing(0.0, single_col_spacing); + qApp->processEvents(); + + // items moved to the correct place? + QCOMPARE(m_mockItem100->geometry(), QRectF(QPointF(0.0, 0.0), QSize(100.0, 100.0))); + QCOMPARE(m_mockItem200->geometry(), QRectF(QPointF(300.0 + single_col_spacing, 0.0), + QSize(200.0, 200.0))); + QCOMPARE(m_mockItem300->geometry(), QRectF(QPointF(0.0, 200.0 + single_row_spacing), + QSize(300.0, 300.0))); + QCOMPARE(m_mockItem400->geometry(), QRectF(QPointF(300.0 + single_col_spacing, + 200.0 + single_row_spacing), + QSize(400.0, 400.0))); +} + + +/** Test with four items in two columns and rows and varying alignment values. */ +void Ut_DuiGridLayoutPolicy::testAlignment() +{ + // general spacing + m_policy->setSpacing(0.0); + m_policy->addItem(m_mockItem100, 0, 0); + m_policy->addItem(m_mockItem200, 0, 1); + m_policy->addItem(m_mockItem300, 1, 0); + m_policy->addItem(m_mockItem400, 1, 1); + qApp->processEvents(); + + // default is left/top aligned + QCOMPARE(m_mockItem100->geometry(), QRectF(QPointF(0.0, 0.0), QSize(100.0, 100.0))); + QCOMPARE(m_mockItem200->geometry(), QRectF(QPointF(300.0, 0.0), QSize(200.0, 200.0))); + QCOMPARE(m_mockItem300->geometry(), QRectF(QPointF(0.0, 200.0), QSize(300.0, 300.0))); + QCOMPARE(m_mockItem400->geometry(), QRectF(QPointF(300.0, 200.0), QSize(400.0, 400.0))); + + // switch first column to center and second column to right alignment + // (the comparisons assume, that mock item 100 is smaller than mock item 200 + // and so on) + m_policy->setColumnAlignment(0, Qt::AlignCenter); + m_policy->setColumnAlignment(1, Qt::AlignRight); + qApp->processEvents(); + + QCOMPARE(m_mockItem100->geometry(), QRectF(QPointF(100.0, 0.0), QSize(100.0, 100.0))); + QCOMPARE(m_mockItem200->geometry(), QRectF(QPointF(500.0, 0.0), QSize(200.0, 200.0))); + QCOMPARE(m_mockItem300->geometry(), QRectF(QPointF(0.0, 200.0), QSize(300.0, 300.0))); + QCOMPARE(m_mockItem400->geometry(), QRectF(QPointF(300.0, 200.0), QSize(400.0, 400.0))); + + // switch first row to bottom and second row to center alignment + // (the comparisons assume, that mock item 100 is smaller than mock item 200 + // and so on) + m_policy->setRowAlignment(0, Qt::AlignBottom); + m_policy->setRowAlignment(1, Qt::AlignVCenter); + qApp->processEvents(); + + QCOMPARE(m_mockItem100->geometry(), QRectF(QPointF(100.0, 100.0), QSize(100.0, 100.0))); + QCOMPARE(m_mockItem200->geometry(), QRectF(QPointF(500.0, 0.0), QSize(200.0, 200.0))); + QCOMPARE(m_mockItem300->geometry(), QRectF(QPointF(0.0, 250.0), QSize(300.0, 300.0))); + QCOMPARE(m_mockItem400->geometry(), QRectF(QPointF(300.0, 200.0), QSize(400.0, 400.0))); + + // override alignment for single items + m_policy->setAlignment(m_mockItem100, Qt::AlignLeft | Qt::AlignTop); + m_policy->setAlignment(m_mockItem300, Qt::AlignLeft | Qt::AlignTop); + qApp->processEvents(); + + QCOMPARE(m_mockItem100->geometry(), QRectF(QPointF(0.0, 0.0), QSize(100.0, 100.0))); + QCOMPARE(m_mockItem200->geometry(), QRectF(QPointF(500.0, 0.0), QSize(200.0, 200.0))); + QCOMPARE(m_mockItem300->geometry(), QRectF(QPointF(0.0, 200.0), QSize(300.0, 300.0))); + QCOMPARE(m_mockItem400->geometry(), QRectF(QPointF(300.0, 200.0), QSize(400.0, 400.0))); +} + + +/** Test that the alignment works on sub layouts, too. */ +void Ut_DuiGridLayoutPolicy::testAlignmentSubLayouts() +{ + // general spacing + m_policy->setSpacing(0.0); + + // create two sublayouts + DuiLayout *subLayout100 = new DuiLayout; + subLayout100->setAnimation(0); + DuiGridLayoutPolicy *subPolicy100 = new DuiGridLayoutPolicy(subLayout100); + m_policy->addItem(subLayout100, 0, 0); + subPolicy100->setSpacing(0.0); + subPolicy100->addItem(m_mockItem100, 0, 0); + + DuiLayout *subLayout200 = new DuiLayout; + subLayout200->setAnimation(0); + DuiGridLayoutPolicy *subPolicy200 = new DuiGridLayoutPolicy(subLayout200); + m_policy->addItem(subLayout200, 1, 0); + subPolicy200->setSpacing(0.0); + subPolicy200->addItem(m_mockItem200, 0, 0); + + m_policy->addItem(m_mockItem300, 2, 0); + qApp->processEvents(); + + // default is left/top aligned + QCOMPARE(subLayout100->geometry(), QRectF(QPointF(0.0, 0.0), QSize(100.0, 100.0))); + QCOMPARE(subLayout200->geometry(), QRectF(QPointF(0.0, 100.0), QSize(200.0, 200.0))); + QCOMPARE(m_mockItem300->geometry(), QRectF(QPointF(0.0, 300.0), QSize(300.0, 300.0))); + + // now change some alignments + m_policy->setAlignment(subLayout100, Qt::AlignRight); + m_policy->setAlignment(subLayout200, Qt::AlignCenter); + qApp->processEvents(); + + QCOMPARE(subLayout100->geometry(), QRectF(QPointF(200.0, 0.0), QSize(100.0, 100.0))); + QCOMPARE(subLayout200->geometry(), QRectF(QPointF(50.0, 100.0), QSize(200.0, 200.0))); + QCOMPARE(m_mockItem300->geometry(), QRectF(QPointF(0.0, 300.0), QSize(300.0, 300.0))); +} + +void Ut_DuiGridLayoutPolicy::testRowCount() +{ + /* QGraphicsGridLayout layout; + layout.setColumnFixedWidth(0, 100); + layout.setColumnFixedWidth(1, 100); + layout.setColumnFixedWidth(2, 100); + layout.setColumnFixedWidth(3, 100); + QCOMPARE(layout.rowCount(), 0); + QCOMPARE(layout.columnCount(), 0); */ + + m_policy->setColumnFixedWidth(0, 100); + m_policy->setColumnFixedWidth(1, 100); + m_policy->setColumnFixedWidth(2, 100); + m_policy->setColumnFixedWidth(3, 100); + QCOMPARE(m_policy->rowCount(), 0); + QCOMPARE(m_policy->columnCount(), 0); +} + +QTEST_APPLESS_MAIN(Ut_DuiGridLayoutPolicy) diff --git a/tests/ut_duigridlayoutpolicy/ut_duigridlayoutpolicy.h b/tests/ut_duigridlayoutpolicy/ut_duigridlayoutpolicy.h new file mode 100644 index 000000000..120e578a8 --- /dev/null +++ b/tests/ut_duigridlayoutpolicy/ut_duigridlayoutpolicy.h @@ -0,0 +1,65 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIGRIDLAYOUTPOLICY_H +#define UT_DUIGRIDLAYOUTPOLICY_H + +#include +#include + +class QGraphicsLayoutItem; +class QGraphicsWidget; +class DuiLayout; +class DuiGridLayoutPolicy; + +class Ut_DuiGridLayoutPolicy : public QObject +{ + Q_OBJECT + +public: + Ut_DuiGridLayoutPolicy(); + virtual ~Ut_DuiGridLayoutPolicy(); + +private slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + + void testDeletingLayout(); + void testOneItemLayout(); + void testHorizontally(); + void testVertically(); + void testHorizontallyAndVertically(); + void testSpacing(); + void testAlignment(); + void testAlignmentSubLayouts(); + void testRowCount(); +private: + + DuiLayout *m_mockLayout; + DuiGridLayoutPolicy *m_policy; + QGraphicsLayoutItem *m_mockItem100; + QGraphicsLayoutItem *m_mockItem200; + QGraphicsLayoutItem *m_mockItem300; + QGraphicsLayoutItem *m_mockItem400; + QGraphicsWidget *m_form; +}; + +#endif // Header guard diff --git a/tests/ut_duigridlayoutpolicy/ut_duigridlayoutpolicy.pro b/tests/ut_duigridlayoutpolicy/ut_duigridlayoutpolicy.pro new file mode 100644 index 000000000..0528bf05f --- /dev/null +++ b/tests/ut_duigridlayoutpolicy/ut_duigridlayoutpolicy.pro @@ -0,0 +1,12 @@ +include(../common_top.pri) +TARGET = ut_duigridlayoutpolicy + +# unit test and unit +SOURCES += \ + ut_duigridlayoutpolicy.cpp \ + +# unit test and unit +HEADERS += \ + ut_duigridlayoutpolicy.h \ + +include(../common_bot.pri) diff --git a/tests/ut_duiimage/.gitignore b/tests/ut_duiimage/.gitignore new file mode 100644 index 000000000..5c7097a6b --- /dev/null +++ b/tests/ut_duiimage/.gitignore @@ -0,0 +1 @@ +ut_duiimage diff --git a/tests/ut_duiimagewidget/.gitignore b/tests/ut_duiimagewidget/.gitignore new file mode 100644 index 000000000..7cea0ef03 --- /dev/null +++ b/tests/ut_duiimagewidget/.gitignore @@ -0,0 +1 @@ +ut_duiimagewidget diff --git a/tests/ut_duiimagewidget/ut_duiimagewidget-test.png b/tests/ut_duiimagewidget/ut_duiimagewidget-test.png new file mode 100644 index 000000000..6c86c6a2b Binary files /dev/null and b/tests/ut_duiimagewidget/ut_duiimagewidget-test.png differ diff --git a/tests/ut_duiimagewidget/ut_duiimagewidget.cpp b/tests/ut_duiimagewidget/ut_duiimagewidget.cpp new file mode 100644 index 000000000..34a26a9bd --- /dev/null +++ b/tests/ut_duiimagewidget/ut_duiimagewidget.cpp @@ -0,0 +1,308 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include +#include "duicomponentdata.h" + +#include "ut_duiimagewidget.h" + +void Ut_DuiImageWidget::initTestCase() +{ + QImage img(qApp->applicationDirPath() + "/ut_duiimagewidget-test.png"); + + if (! DuiComponentData::instance()) { + char *argv = 0; + int argc = 0; + new DuiComponentData(argc, &argv, QString("ut_duiimagewidget"), NULL); + } + + m_subject = new DuiImageWidget(&img); + QVERIFY(m_subject != 0); +} + +void Ut_DuiImageWidget::cleanupTestCase() +{ + delete m_subject; + m_subject = 0; + + delete DuiComponentData::instance(); +} + +void Ut_DuiImageWidget::testConstructor_data() +{ + QTest::addColumn("fname"); + + QTest::newRow("png") << qApp->applicationDirPath() + "/ut_duiimagewidget-test.png"; +} + +void Ut_DuiImageWidget::testConstructor() +{ + QFETCH(QString, fname); + + QSize s; + + QPixmap pixmap(fname); + s = pixmap.size(); + + // test load image files + QImage img(fname); + DuiImageWidget *myImage = new DuiImageWidget(&img); + QCOMPARE(myImage->imageSize(), s); + + // test constructor from pixmap + QPixmap *source = new QPixmap(s); + source->fill(QColor(0, 0, 0, 0)); + DuiImageWidget *myImage3 = new DuiImageWidget(source); + QCOMPARE(myImage3->imageSize(), s); + delete myImage3; + + // test copy constructor + DuiImageWidget *myImage4 = new DuiImageWidget(*myImage); + QCOMPARE(myImage4->imageSize(), myImage->imageSize()); + delete myImage4; + + DuiImageWidget myImage5 = *myImage; + QCOMPARE(myImage5.imageSize(), myImage->imageSize()); + + delete source; + delete myImage; +} + +void Ut_DuiImageWidget::testImageDataSize_data() +{ + QTest::addColumn("fname"); + + QTest::newRow("png") << qApp->applicationDirPath() + "/ut_duiimagewidget-test.png"; +} + +void Ut_DuiImageWidget::testImageDataSize() +{ + QFETCH(QString, fname); + + QImage img(fname); + DuiImageWidget *myImage = new DuiImageWidget(&img); + + QSize imgSize; + QPixmap pixmap(fname); + imgSize = pixmap.size(); + + const QPixmap *p = myImage->pixmap(); + QCOMPARE(imgSize, p->size()); + QCOMPARE(imgSize, myImage->imageSize()); + + // test setPixmap + myImage->setPixmap(pixmap); + p = myImage->pixmap(); + QCOMPARE(pixmap.toImage(), p->toImage()); + + // test setImage + QImage image = pixmap.toImage(); + myImage->setImage(image); + p = myImage->pixmap(); + QCOMPARE(image, p->toImage()); + +// // test imageDataSize after set crop section +// QSizeF half = imgSize*0.5; +// myImage->setCropSize(half); +// QCOMPARE(half, myImage->imageDataSize()); + + delete myImage; +} + +void Ut_DuiImageWidget::testSetZoomFactor_data() +{ + QTest::addColumn("fname"); + QTest::addColumn("factor"); + QTest::addColumn("f2"); + + QTest::newRow("png1") << qApp->applicationDirPath() + "/ut_duiimagewidget-test.png" << static_cast(1.0) << static_cast(2.0); + QTest::newRow("png2") << qApp->applicationDirPath() + "/ut_duiimagewidget-test.png" << static_cast(0.0001) << static_cast(2.0); +} + +void Ut_DuiImageWidget::testSetZoomFactor() +{ + QFETCH(QString, fname); + QFETCH(qreal, factor); + QFETCH(qreal, f2); + + Q_UNUSED(factor) + Q_UNUSED(f2) + + QImage img(fname); + DuiImageWidget *myImage = new DuiImageWidget(&img); + myImage->setZoomFactor(factor); + + qreal fx, fy; + myImage->zoomFactor(&fx, &fy); + + QSize size = myImage->imageSize(); + if (size.width() * factor > 2.0) { + QCOMPARE(fx, factor); + QCOMPARE(fy, factor); + + // test zoom in & zoom out + myImage->zoomIn(); + myImage->zoomFactor(&fx, &fy); + + QCOMPARE(fx, factor * 2.0f); + QCOMPARE(fy, factor * 2.0f); + + myImage->zoomOut(); + myImage->zoomFactor(&fx, &fy); + + QCOMPARE(fx, factor); + QCOMPARE(fy, factor); + + // test AspectRatioMode + myImage->setZoomFactor(factor, f2); + QCOMPARE(Qt::IgnoreAspectRatio, myImage->aspectRatioMode()); + + } else { + myImage->setZoomFactor(factor, factor); + myImage->zoomFactor(&fx, &fy); + + QVERIFY(fx != factor); + QVERIFY(fy != factor); + } + + delete myImage; +} + +void Ut_DuiImageWidget::testSetNegativeZoomFactor() +{ + qreal posvalue = 2.0f; + qreal negvalue = -2.0f; + qreal zx, zy; + + QImage img(qApp->applicationDirPath() + "/ut_duiimagewidget-test.png"); + DuiImageWidget *myImage = new DuiImageWidget(&img); + myImage->setZoomFactor(posvalue, posvalue); + myImage->zoomFactor(&zx, &zy); + + QVERIFY(qAbs(zx - posvalue) < 1e-3); + QVERIFY(qAbs(zy - posvalue) < 1e-3); + + myImage->setZoomFactor(negvalue, negvalue); + myImage->zoomFactor(&zx, &zy); + + QVERIFY(qAbs(zx - posvalue) < 1e-3); + QVERIFY(qAbs(zy - posvalue) < 1e-3); + + delete myImage; +} + +void Ut_DuiImageWidget::testSetCropSize_data() +{ + QTest::addColumn("fname"); + QTest::addColumn("crop"); + + QTest::newRow("png1") << qApp->applicationDirPath() + "/ut_duiimagewidget-test.png" << QSizeF(-10.0, -10.0); + QTest::newRow("png2") << qApp->applicationDirPath() + "/ut_duiimagewidget-test.png" << QSizeF(10.0, 10.0); + QTest::newRow("png3") << qApp->applicationDirPath() + "/ut_duiimagewidget-test.png" << QSizeF(10000.0, 10000.0); +} + +void Ut_DuiImageWidget::testSetCropSize() +{ + QFETCH(QString, fname); + QFETCH(QSizeF, crop); + + QImage img(fname); + DuiImageWidget *myImage = new DuiImageWidget(&img); + + QRectF rect(QPointF(0.0, 0.0), crop); + myImage->setCrop(rect); + + QSize imgSize = myImage->imageSize(); + QSizeF t = myImage->crop().size(); + + if (crop.width() < 0.0) + QCOMPARE(t, QSizeF(0.0, 0.0)); + else if (crop.width() > imgSize.width()) + QCOMPARE(t, QSizeF(imgSize)); + else + QCOMPARE(t, crop); + + delete myImage; +} + +void Ut_DuiImageWidget::testSetCropTopLeftPoint_data() +{ + QTest::addColumn("fname"); + QTest::addColumn("topLeft"); + + QTest::newRow("png1") << qApp->applicationDirPath() + "/ut_duiimagewidget-test.png" << QPointF(-10.0, -10.0); + QTest::newRow("png2") << qApp->applicationDirPath() + "/ut_duiimagewidget-test.png" << QPointF(-1.0, -1.0); + QTest::newRow("png3") << qApp->applicationDirPath() + "/ut_duiimagewidget-test.png" << QPointF(0.0, 0.0); + QTest::newRow("png4") << qApp->applicationDirPath() + "/ut_duiimagewidget-test.png" << QPointF(10.0, 10.0); + QTest::newRow("png5") << qApp->applicationDirPath() + "/ut_duiimagewidget-test.png" << QPointF(10000.0, 10000.0); +} + +void Ut_DuiImageWidget::testSetCropTopLeftPoint() +{ + QFETCH(QString, fname); + QFETCH(QPointF, topLeft); + + QImage img(fname); + DuiImageWidget *myImage = new DuiImageWidget(&img); + + QRectF rect(topLeft, QSize(10.0, 10.0)); + myImage->setCrop(rect); + + QPointF point = myImage->crop().topLeft(); + QSize imgSize = myImage->imageSize(); + + // This is default value in DuiImageWidget + if (topLeft.x() < 0.0 || topLeft.x() < 0.0) + QCOMPARE(point, QPointF(-1.0, -1.0)); + else if (topLeft.x() > imgSize.width() || topLeft.y() > imgSize.height()) + QCOMPARE(point, QPointF(-1.0, -1.0)); + else + QCOMPARE(point, topLeft); + + delete myImage; +} + +void Ut_DuiImageWidget::testImageNotExist_data() +{ + QTest::addColumn("fname"); + QTest::newRow("png") << "doesnotexist.png"; +} + +void Ut_DuiImageWidget::testImageNotExist() +{ + QFETCH(QString, fname); + QImage img(fname); + DuiImageWidget *myImage = new DuiImageWidget(&img); + + QSize imageSize = myImage->imageSize(); + QVERIFY(imageSize.isEmpty()); + + delete myImage; +} + + +QTEST_MAIN(Ut_DuiImageWidget); + diff --git a/tests/ut_duiimagewidget/ut_duiimagewidget.h b/tests/ut_duiimagewidget/ut_duiimagewidget.h new file mode 100644 index 000000000..60db56500 --- /dev/null +++ b/tests/ut_duiimagewidget/ut_duiimagewidget.h @@ -0,0 +1,61 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIIMAGEWIDGET_H +#define UT_DUIIMAGEWIDGET_H + +#include +#include + +class DuiImageWidget; + +class Ut_DuiImageWidget : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase(); + void cleanupTestCase(); + + void testConstructor_data(); + void testConstructor(); + + void testImageDataSize_data(); + void testImageDataSize(); + + void testSetZoomFactor_data(); + void testSetZoomFactor(); + + void testSetNegativeZoomFactor(); + + void testSetCropSize_data(); + void testSetCropSize(); + + void testSetCropTopLeftPoint_data(); + void testSetCropTopLeftPoint(); + + void testImageNotExist_data(); + void testImageNotExist(); + +private: + DuiImageWidget *m_subject; +}; + +#endif + diff --git a/tests/ut_duiimagewidget/ut_duiimagewidget.pro b/tests/ut_duiimagewidget/ut_duiimagewidget.pro new file mode 100644 index 000000000..7254f00f9 --- /dev/null +++ b/tests/ut_duiimagewidget/ut_duiimagewidget.pro @@ -0,0 +1,14 @@ +include(../common_top.pri) + +TARGET = ut_duiimagewidget + +SOURCES += \ + ut_duiimagewidget.cpp \ + $$STUBSDIR/stubbase.cpp \ + +HEADERS += \ + ut_duiimagewidget.h \ + +support_files.files += ut_duiimagewidget-test.png + +include(../common_bot.pri) diff --git a/tests/ut_duiinfobanner/.gitignore b/tests/ut_duiinfobanner/.gitignore new file mode 100644 index 000000000..19c083f35 --- /dev/null +++ b/tests/ut_duiinfobanner/.gitignore @@ -0,0 +1 @@ +ut_duiinfobanner diff --git a/tests/ut_duiinfobanner/ut_duiinfobanner.cpp b/tests/ut_duiinfobanner/ut_duiinfobanner.cpp new file mode 100644 index 000000000..584964bb7 --- /dev/null +++ b/tests/ut_duiinfobanner/ut_duiinfobanner.cpp @@ -0,0 +1,148 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include + +#include +#include + +#include "duiapplication.h" +#include "duiinfobanner.h" +#include "duiinfobannereventview.h" +#include "ut_duiinfobanner.h" + +Q_DECLARE_METATYPE(DuiInfoBanner::BannerType); +Q_DECLARE_METATYPE(DuiTheme::ViewType); + +DuiApplication *app; + +void Ut_DuiInfoBanner::init() +{ +} + +void Ut_DuiInfoBanner::cleanup() +{ +} + +void Ut_DuiInfoBanner::initTestCase() +{ + static int argc = 1; + static char *argv[1] = { (char *) "./ut_duiinfobanner" }; + app = new DuiApplication(argc, argv); +} + + +void Ut_DuiInfoBanner::cleanupTestCase() +{ + delete app; + app = NULL; +} + +void Ut_DuiInfoBanner::testCreation_data() +{ + QTest::addColumn("type"); + QTest::addColumn("variant"); + QTest::addColumn("icon"); + QTest::addColumn("body"); + QTest::addColumn("buttonIconId"); + + QTest::newRow("info") << DuiInfoBanner::Information + << DuiTheme::ViewType(DuiInfoBanner::informationType) + << QString("Icon-close") + << QString("Battery is running low") + << QString(""); + + QTest::newRow("event") << DuiInfoBanner::Event + << DuiTheme::ViewType(DuiInfoBanner::eventType) + << QString("ebf7db7b6ab73c6cba8fc87da2d1fdcf") + << QString("Ida Taipale
Have you seen my dog?") + << QString("Icon-new-SMS"); + + QTest::newRow("invalid") << (DuiInfoBanner::BannerType)10 + << DuiTheme::ViewType(DuiInfoBanner::eventType) + << QString("XXXXXXX invalid image XXXXXXX") + << QString("XXXXXXX invalid contents XXXXXXXX") + << QString("XXXXXXX invalid icon XXXXXXXXXXX"); +} + +void Ut_DuiInfoBanner::testCreation() +{ + QFETCH(DuiInfoBanner::BannerType, type); + QFETCH(DuiTheme::ViewType, variant); + QFETCH(QString, icon); + QFETCH(QString, body); + QFETCH(QString, buttonIconId); + + DuiInfoBanner *banner = new DuiInfoBanner(type); + banner->setImageID(icon); + banner->setBodyText(body); + banner->setIconID(buttonIconId); + + // verify that model has been set + QVERIFY(banner->model() != 0); + QVERIFY(banner->viewType() == variant); + + delete banner; +} + +void Ut_DuiInfoBanner::testUpdate() +{ + DuiInfoBanner *banner = new DuiInfoBanner(DuiInfoBanner::Information); + + banner->setImageID("image1"); + banner->setIconID("icon1"); + banner->setBodyText("body1"); + banner->setButtonText("button"); + + QCOMPARE(banner->bannerType(), DuiInfoBanner::Information); + QCOMPARE(banner->imageID(), QString("image1")); + QCOMPARE(banner->bodyText(), QString("body1")); + QCOMPARE(banner->iconID(), QString("icon1")); + QCOMPARE(banner->buttonText(), QString("button")); + QCOMPARE(banner->pixmap().isNull(), true); + + banner->setPixmap(QPixmap(50, 50)); + QCOMPARE(banner->pixmap().size(), QSize(50, 50)); + QCOMPARE(banner->pixmap().isNull(), false); + QCOMPARE(banner->imageID(), QString()); + + delete banner; +} + +void Ut_DuiInfoBanner::testClicking() +{ + DuiInfoBanner *banner = new DuiInfoBanner(DuiInfoBanner::Information); + banner->setIconID("ButtonIconId"); + + // click the banner + QSignalSpy clickedSpy(banner, SIGNAL(clicked())); + banner->click(); + QCOMPARE(clickedSpy.count(), 1); + + // click the button in the banner + QSignalSpy buttonClickedSpy(banner, SIGNAL(buttonClicked())); + banner->setButtonText("test"); + banner->buttonClicked(); + QCOMPARE(buttonClickedSpy.count(), 1); + + delete banner; +} + +QTEST_APPLESS_MAIN(Ut_DuiInfoBanner) diff --git a/tests/ut_duiinfobanner/ut_duiinfobanner.h b/tests/ut_duiinfobanner/ut_duiinfobanner.h new file mode 100644 index 000000000..05ac40709 --- /dev/null +++ b/tests/ut_duiinfobanner/ut_duiinfobanner.h @@ -0,0 +1,42 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIINFOBANNER_H +#define UT_DUIINFOBANNER_H + +#include +#include + +class Ut_DuiInfoBanner : public QObject +{ + Q_OBJECT + +private slots: + void init(); + void cleanup(); + void initTestCase(); + void cleanupTestCase(); + + void testCreation_data(); + void testCreation(); + void testUpdate(); + void testClicking(); +}; + +#endif diff --git a/tests/ut_duiinfobanner/ut_duiinfobanner.pro b/tests/ut_duiinfobanner/ut_duiinfobanner.pro new file mode 100644 index 000000000..b80cc1237 --- /dev/null +++ b/tests/ut_duiinfobanner/ut_duiinfobanner.pro @@ -0,0 +1,24 @@ +include(../common_top.pri) +INCLUDEPATH += $$DUISRCDIR/style +TARGET = ut_duiinfobanner + +# unit + +# unit test and unit +SOURCES += \ + ut_duiinfobanner.cpp \ + +# service classes +SOURCES += \ +# $$STUBSDIR/stubbase.cpp \ + +# unit test and unit +HEADERS += \ + ut_duiinfobanner.h + +# service classes +HEADERS += \ +# $$STUBSDIR/duistyle_stub.h \ +# $$STUBSDIR/duitheme_stub.h \ + +include(../common_bot.pri) diff --git a/tests/ut_duiinputmethodstate/.gitignore b/tests/ut_duiinputmethodstate/.gitignore new file mode 100644 index 000000000..7edcb52db --- /dev/null +++ b/tests/ut_duiinputmethodstate/.gitignore @@ -0,0 +1 @@ +ut_duiinputmethodstate diff --git a/tests/ut_duiinputmethodstate/ut_duiinputmethodstate.cpp b/tests/ut_duiinputmethodstate/ut_duiinputmethodstate.cpp new file mode 100644 index 000000000..0e6dcc26e --- /dev/null +++ b/tests/ut_duiinputmethodstate/ut_duiinputmethodstate.cpp @@ -0,0 +1,85 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include + +#include "ut_duiinputmethodstate.h" +#include "duiinputmethodstate.h" + +Q_DECLARE_METATYPE(Dui::OrientationAngle) + +void Ut_DuiInputMethodState::initTestCase() +{ + qRegisterMetaType("Dui::OrientationAngle"); +} + +void Ut_DuiInputMethodState::cleanupTestCase() +{ +} + +void Ut_DuiInputMethodState::init() +{ +} + +void Ut_DuiInputMethodState::cleanup() +{ +} + +void Ut_DuiInputMethodState::testActiveWindowOrientationAngle() +{ + DuiInputMethodState *state = DuiInputMethodState::instance(); + QSignalSpy spy(state, SIGNAL(activeWindowOrientationAngleChanged(Dui::OrientationAngle))); + + // Initial state + QCOMPARE(state->activeWindowOrientationAngle(), Dui::Angle0); + + + // Set, get, get notified + state->setActiveWindowOrientationAngle(Dui::Angle270); + QCOMPARE(state->activeWindowOrientationAngle(), Dui::Angle270); + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.first().first().value(), Dui::Angle270); + + // Set the same orientation again, don't get notified + state->setActiveWindowOrientationAngle(Dui::Angle270); + QCOMPARE(spy.count(), 1); +} + +void Ut_DuiInputMethodState::testInputMethodArea() +{ + DuiInputMethodState *state = DuiInputMethodState::instance(); + QSignalSpy spy(state, SIGNAL(inputMethodAreaChanged(QRect))); + + // Initial state + QCOMPARE(state->inputMethodArea(), QRect()); + + // Set, get, get notified + const QRect rect(0, 0, 10, 10); + state->setInputMethodArea(rect); + QCOMPARE(state->inputMethodArea(), rect); + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.first().first().value(), rect); + + // Set the same orientation again, don't get notified + state->setInputMethodArea(rect); + QCOMPARE(spy.count(), 1); +} + + +QTEST_APPLESS_MAIN(Ut_DuiInputMethodState) diff --git a/tests/ut_duiinputmethodstate/ut_duiinputmethodstate.h b/tests/ut_duiinputmethodstate/ut_duiinputmethodstate.h new file mode 100644 index 000000000..3ea873dde --- /dev/null +++ b/tests/ut_duiinputmethodstate/ut_duiinputmethodstate.h @@ -0,0 +1,44 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIINPUTMETHODSTATE_H +#define UT_DUIINPUTMETHODSTATE_H + +#include +#include + +class Ut_DuiInputMethodState : public QObject +{ + Q_OBJECT + +private slots: + // Called before the first testfunction is executed + void initTestCase(); + // Called after the last testfunction was executed + void cleanupTestCase(); + // Called before each testfunction is executed + void init(); + // Called after every testfunction + void cleanup(); + + void testActiveWindowOrientationAngle(); + void testInputMethodArea(); +}; + +#endif diff --git a/tests/ut_duiinputmethodstate/ut_duiinputmethodstate.pro b/tests/ut_duiinputmethodstate/ut_duiinputmethodstate.pro new file mode 100644 index 000000000..911d78aef --- /dev/null +++ b/tests/ut_duiinputmethodstate/ut_duiinputmethodstate.pro @@ -0,0 +1,15 @@ +include(../common_top.pri) +TARGET = ut_duiinputmethodstate + +# unit test and unit classes +SOURCES += \ + ut_duiinputmethodstate.cpp \ + $$DUISRCDIR/core/duiinputmethodstate.cpp + +# unit test and unit classes +HEADERS += \ + ut_duiinputmethodstate.h \ + $$DUISRCDIR/core/duiinputmethodstate.h \ + $$DUISRCDIR/core/duiinputmethodstate_p.h + +include(../common_bot.pri) diff --git a/tests/ut_duilabel/.gitignore b/tests/ut_duilabel/.gitignore new file mode 100644 index 000000000..7bcd58930 --- /dev/null +++ b/tests/ut_duilabel/.gitignore @@ -0,0 +1 @@ +ut_duilabel diff --git a/tests/ut_duilabel/ut_duilabel.cpp b/tests/ut_duilabel/ut_duilabel.cpp new file mode 100644 index 000000000..701e771b7 --- /dev/null +++ b/tests/ut_duilabel/ut_duilabel.cpp @@ -0,0 +1,494 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duilabel.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define SAVE_IMAGE(fileName, image) \ + do{ \ + QFile f(fileName); f.open(QIODevice::WriteOnly); image.save(&f, "PNG"); f.close(); \ + } while(0) + +// Subclass of DuiLabel in order to simulate clicks +TestDuiLabel::TestDuiLabel(): DuiLabel() +{ +} + +TestDuiLabel::~TestDuiLabel() +{ +} + +void TestDuiLabel::simulateClick(const QPointF &pos) +{ + QGraphicsSceneMouseEvent *pressevent = new QGraphicsSceneMouseEvent(); + QGraphicsSceneMouseEvent *releaseevent = new QGraphicsSceneMouseEvent(); + pressevent->setPos(pos); + releaseevent->setPos(pos); + mousePressEvent(pressevent); + mouseReleaseEvent(releaseevent); + delete pressevent; + delete releaseevent; +} + +QImage TestDuiLabel::getLabelImage() +{ + QPixmap pixmap(size().toSize()); + pixmap.fill(Qt::transparent); + QPainter painter(&pixmap); + DuiWidgetController::paint(&painter, NULL, NULL); + + return pixmap.toImage(); +} + +DuiApplication *app; + +void Ut_DuiLabel::initTestCase() +{ + static int argc = 1; + static char *app_name[1] = { (char *) "./ut_duilabel" }; + app = new DuiApplication(argc, app_name); + + DuiTheme::loadCSS(qApp->applicationDirPath() + "/ut_duilabel.css"); +} + +void Ut_DuiLabel::init() +{ + label = new TestDuiLabel; + label->setGeometry(QRectF(0, 0, 400, 20)); + QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents, 10); +} + +void Ut_DuiLabel::cleanup() +{ + delete label; +} + +void Ut_DuiLabel::cleanupTestCase() +{ + delete app; +} + +void Ut_DuiLabel::testTestConstruction() +{ + DuiLabel *label = new DuiLabel(); + delete label; + + label = new DuiLabel("this is plain text!"); + delete label; + + label = new DuiLabel("this is rich text!"); + delete label; + + label = new DuiLabel(); + label->setText("this is rich text!"); + DuiLabelModel *model = new DuiLabelModel(); + model->setText("this is plain text!"); + label->setModel(model); + delete label; +} + + +void Ut_DuiLabel::testTextAlignment_data() +{ + QTest::addColumn("text"); + + QTest::newRow("plain") << "this is plain text!"; + QTest::newRow("rich") << "this is rich text!"; +} +void Ut_DuiLabel::testTextAlignment() +{ + QVector alignments; + alignments.push_back(Qt::AlignLeft | Qt::AlignTop); + alignments.push_back(Qt::AlignRight | Qt::AlignTop); + alignments.push_back(Qt::AlignHCenter | Qt::AlignTop); + alignments.push_back(Qt::AlignLeft | Qt::AlignVCenter); + alignments.push_back(Qt::AlignRight | Qt::AlignVCenter); + alignments.push_back(Qt::AlignHCenter | Qt::AlignVCenter); + alignments.push_back(Qt::AlignLeft | Qt::AlignBottom); + alignments.push_back(Qt::AlignRight | Qt::AlignBottom); + alignments.push_back(Qt::AlignHCenter | Qt::AlignBottom); + + label->setMinimumSize(500, 500); + label->setMaximumSize(500, 500); + label->setPreferredSize(500, 500); + label->setGeometry(QRectF(0, 0, 500, 500)); + + QFETCH(QString, text); + label->setText(text); + QVERIFY(text == label->text()); + + QVector images; + + for (int i = 0; i < alignments.count(); i++) { + label->setAlignment(alignments[i]); + QVERIFY(label->alignment() == alignments[i]); + + QImage image = captureImage(label); + images.push_back(image); + //image.save(QString("0x") + QString::number(alignments[i], 16), "PNG"); + } + + for (int i = 0; i < alignments.count(); i++) { + for (int j = i + 1; j < alignments.count(); j++) { + if (images[i] == images[j]) { + qDebug() << "Images are similar with alignments:" << + QString("0x") + QString::number(alignments[i], 16) << + "and" << + QString("0x") + QString::number(alignments[j], 16); + } + + QVERIFY(images[i] != images[j]); + } + } +} + +void Ut_DuiLabel::testLayoutDirection_data() +{ + QTest::addColumn("text"); + + QTest::newRow("plain") << "this is plain text!"; + QTest::newRow("rich") << "this is rich text!"; +} + +void Ut_DuiLabel::testLayoutDirection() +{ + QFETCH(QString, text); + label->setText(text); + QVERIFY(text == label->text()); + + label->setLayoutDirection(Qt::LeftToRight); + QVERIFY(label->layoutDirection() == Qt::LeftToRight); + QImage ltr = captureImage(label); + + label->setLayoutDirection(Qt::RightToLeft); + QVERIFY(label->layoutDirection() == Qt::RightToLeft); + QImage rtl = captureImage(label); + + //ltr.save("ltr", "PNG"); + //rtl.save("rtl", "PNG"); + + QVERIFY(ltr != rtl); +} + +void Ut_DuiLabel::testTextWordWrap_data() +{ + QTest::addColumn("text"); + QTest::addColumn("equal"); + + QTest::newRow("plain") << "David Michael Hasselhoff (born July 17, 1952) is an American actor and singer.He is best known for his lead roles as Michael Knight in the popular 1980s U.S. series Knight Rider and as L.A. County Lifeguard Mitch Buchannon in the series Baywatch. Hasselhoff also produced Baywatch for a number of series in the 1990s up until 2001 when the series ended with Baywatch Hawaii. Hasselhoff also crossed over to a music career during the end of the 1980s and the early 1990s and was noted for his performance when the Berlin Wall was brought down in 1989. He enjoyed a short lived success as a singer primarily in German-speaking Europe, particularly in Germany and Austria. More recently Hasselhoff has been involved with talent shows such as NBC's America's Got Talent in 2006. Hasselhoff's autobiography, Making Waves, was released in the United Kingdom in September 2006." << true; + QTest::newRow("rich") << "David Michael Hasselhoff (born July 17, 1952) is an American actor and singer. He is best known for his lead roles as Michael Knight in the popular 1980s U.S. series Knight Rider and as L.A. County Lifeguard Mitch Buchannon in the series Baywatch. Hasselhoff also produced Baywatch for a number of series in the 1990s up until 2001 when the series ended with Baywatch Hawaii. Hasselhoff also crossed over to a music career during the end of the 1980s and the early 1990s and was noted for his performance when the Berlin Wall was brought down in 1989. He enjoyed a short lived success as a singer primarily in German-speaking Europe, particularly in Germany and Austria. More recently Hasselhoff has been involved with talent shows such as NBC's America's Got Talent in 2006. Hasselhoff's autobiography, Making Waves, was released in the United Kingdom in September 2006." << false; +} + +void Ut_DuiLabel::testTextWordWrap() +{ + QFETCH(QString, text); + QFETCH(bool, equal); + + label->setText(text); + QVERIFY(text == label->text()); + + label->setWordWrap(true); + QVERIFY(label->wordWrap() == true); + QImage wrapped = captureImage(label); + + label->setWordWrap(false); + QVERIFY(label->wordWrap() == false); + QImage unwrapped = captureImage(label); + + //wrapped.save("wrapped", "PNG"); + //unwrapped.save("unwrapped", "PNG"); + + // + QVERIFY(((wrapped == unwrapped) == equal)); +} + +void Ut_DuiLabel::testTextElide_data() +{ + QTest::addColumn("text"); + + QTest::newRow("plain") << "David Michael Hasselhoff (born July 17, 1952) is an American actor and singer.He is best known for his lead roles as Michael Knight in the popular 1980s U.S. series Knight Rider and as L.A. County Lifeguard Mitch Buchannon in the series Baywatch. Hasselhoff also produced Baywatch for a number of series in the 1990s up until 2001 when the series ended with Baywatch Hawaii. Hasselhoff also crossed over to a music career during the end of the 1980s and the early 1990s and was noted for his performance when the Berlin Wall was brought down in 1989. He enjoyed a short lived success as a singer primarily in German-speaking Europe, particularly in Germany and Austria. More recently Hasselhoff has been involved with talent shows such as NBC's America's Got Talent in 2006. Hasselhoff's autobiography, Making Waves, was released in the United Kingdom in September 2006."; + // For some reason this doesn't work in CC -> solve why + //QTest::newRow("rich") << "David Michael Hasselhoff (born July 17, 1952) is an American actor and singer. He is best known for his lead roles as Michael Knight in the popular 1980s U.S. series Knight Rider and as L.A. County Lifeguard Mitch Buchannon in the series Baywatch. Hasselhoff also produced Baywatch for a number of series in the 1990s up until 2001 when the series ended with Baywatch Hawaii. Hasselhoff also crossed over to a music career during the end of the 1980s and the early 1990s and was noted for his performance when the Berlin Wall was brought down in 1989. He enjoyed a short lived success as a singer primarily in German-speaking Europe, particularly in Germany and Austria. More recently Hasselhoff has been involved with talent shows such as NBC's America's Got Talent in 2006. Hasselhoff's autobiography, Making Waves, was released in the United Kingdom in September 2006."; +} + +void Ut_DuiLabel::testTextElide() +{ + QFETCH(QString, text); + label->setText(text); + QVERIFY(text == label->text()); + + label->setWordWrap(false); + label->setTextElide(true); + QVERIFY(label->textElide() == true); + QImage elided = captureImage(label); + + label->setTextElide(false); + QVERIFY(label->textElide() == false); + QImage unelided = captureImage(label); + + label->setLayoutDirection(Qt::RightToLeft); + QImage elidedRtl = captureImage(label); + + //elided.save("elided", "PNG"); + //unelided.save("unelided", "PNG"); + //elidedRtl.save("elidedrtl", "PNG"); + + QVERIFY(elided != unelided); + QVERIFY(elided != elidedRtl); +} + +void Ut_DuiLabel::testHighlighting() +{ + label->setText("Label rich"); + + QImage nonhighlighted = captureImage(label); + + DuiCommonLabelHighlighter *h = new DuiCommonLabelHighlighter(QRegExp("Label")); + label->addHighlighter(h); + QImage highlighted = captureImage(label); + + QVERIFY(nonhighlighted != highlighted); + + QSignalSpy spy(h, SIGNAL(clicked(QString))); + //QSignalSpy spy(h, SIGNAL(longPress(QString))); + label->simulateClick(QPoint(15, 5)); + QCOMPARE(spy.count(), 1); + + label->removeHighlighter(NULL); + label->removeHighlighter(h); + delete h; +} + +void Ut_DuiLabel::testAnchor() +{ + label->setText("www.nokia.com"); + anchorHitTest(QPointF(15, 5), 1); + anchorHitTest(QPointF(200, 0), 0); +} + +void Ut_DuiLabel::anchorHitTest(const QPointF &point, int expectedHits) +{ + QSignalSpy spy(label, SIGNAL(linkActivated(QString))); + label->simulateClick(point); + QCOMPARE(spy.count(), expectedHits); +} + + + +QImage Ut_DuiLabel::captureImage(DuiLabel *label) +{ + QPixmap pixmap(label->size().toSize()); + pixmap.fill(Qt::transparent); + QPainter painter(&pixmap); + label->paint(&painter, NULL, NULL); + + return pixmap.toImage(); +} + +void Ut_DuiLabel::testClear_data() +{ + QTest::addColumn("text"); + + QTest::newRow("plain") << "this is just some plain text"; + QTest::newRow("rich") << "this is just some rich text."; +} + +void Ut_DuiLabel::testClear() +{ + QFETCH(QString, text); + + QImage emptyLabel = captureImage(label); + label->setText(text); + QImage xxxxLabel = captureImage(label); + QVERIFY(emptyLabel != xxxxLabel); + + label->setText(""); + QImage clearedLabel = captureImage(label); + + QVERIFY(label->text().isEmpty()); + QVERIFY(xxxxLabel != clearedLabel); +} + +void Ut_DuiLabel::testPlainTextColor_data() +{ + QTest::addColumn("text"); + + QTest::newRow("plain") << "this is just some plain text"; + QTest::newRow("rich") << "this is just some rich text."; +} + +void Ut_DuiLabel::testPlainTextColor() +{ + QFETCH(QString, text); + + TestDuiLabel *label = new TestDuiLabel(); + label->setText(text); + label->setGeometry(QRectF(0, 0, 400, 20)); + QImage imageLabel = captureImage(label); + + TestDuiLabel *anotherLabel = new TestDuiLabel(); + anotherLabel->setText(text); + anotherLabel->setGeometry(QRectF(0, 0, 400, 20)); + QImage anotherLabelImage = captureImage(anotherLabel); + QVERIFY2(imageLabel == anotherLabelImage, "Images should be equal, until we set name for second label."); + anotherLabel->setObjectName("greyLabel"); + anotherLabel->setText(text); + anotherLabelImage = captureImage(anotherLabel); + QVERIFY2(imageLabel != anotherLabelImage, "Images shoudn't be equal, because in css colors are different"); + delete label; + delete anotherLabel; +} +void Ut_DuiLabel::testSizeHint_data() +{ + QTest::addColumn("text"); + + QTest::newRow("plain") << "this is just some plain text"; + QTest::newRow("rich") << "this is just some rich text."; +} + +void Ut_DuiLabel::testSizeHint() +{ + QFETCH(QString, text); + + TestDuiLabel *label = new TestDuiLabel(); + label->setText(text); + label->setGeometry(QRectF(0, 0, 400, 20)); + + label->setWordWrap(true); + { + QSizeF minSizeHint = label->sizeHint(Qt::MinimumSize); + QSizeF prefSizeHint = label->sizeHint(Qt::PreferredSize); + QSizeF maxSizeHint = label->sizeHint(Qt::MaximumSize); + } + + { + qreal width = 100.0; + QSizeF constraint(width, -1); + QSizeF minSizeHint = label->sizeHint(Qt::MinimumSize, constraint); + QSizeF prefSizeHint = label->sizeHint(Qt::PreferredSize, constraint); + QSizeF maxSizeHint = label->sizeHint(Qt::MaximumSize, constraint); + + QVERIFY(minSizeHint.width() <= width); + QVERIFY(prefSizeHint.width() <= width); + } + + { + qreal width = 80.0; + QSizeF constraint(width, -1); + QSizeF minSizeHint = label->sizeHint(Qt::MinimumSize, constraint); + QSizeF prefSizeHint = label->sizeHint(Qt::PreferredSize, constraint); + QSizeF maxSizeHint = label->sizeHint(Qt::MaximumSize, constraint); + + QVERIFY(minSizeHint.width() <= width); + QVERIFY(prefSizeHint.width() <= width); + } + + { + qreal width = 50.0; + QSizeF constraint(width, -1); + QSizeF minSizeHint = label->sizeHint(Qt::MinimumSize, constraint); + QSizeF prefSizeHint = label->sizeHint(Qt::PreferredSize, constraint); + QSizeF maxSizeHint = label->sizeHint(Qt::MaximumSize, constraint); + + QVERIFY(minSizeHint.width() <= width); + QVERIFY(prefSizeHint.width() <= width); + } + + { + QSizeF hint = label->sizeHint((Qt::SizeHint)12345); + } +} + +void Ut_DuiLabel::testFont_data() +{ + QTest::addColumn("text"); + + QTest::newRow("plain") << "this is just some plain text"; + QTest::newRow("rich") << "this is just some rich text."; +} + +void Ut_DuiLabel::testFont() +{ + QFETCH(QString, text); + + DuiLabel *label = new TestDuiLabel(); + label->setText(text); + + // this will create the view and load CSS font + label->preferredSize(); + + QFont newFont("Times", 30, QFont::Bold); + label->setFont(newFont); + + QVERIFY(label->font() == newFont); + + // make style reload + label->setActive(true); + label->setActive(false); + + QVERIFY(label->font() == newFont); +} + +void Ut_DuiLabel::testColor_data() +{ + QTest::addColumn("text"); + + QTest::newRow("plain") << "this is just some plain text"; + QTest::newRow("rich") << "this is just some rich text."; +} + +void Ut_DuiLabel::testColor() +{ + QFETCH(QString, text); + + DuiLabel *label = new TestDuiLabel(); + label->setText(text); + + // this will create the view and load CSS font + label->preferredSize(); + + QColor color("#FF00FF"); + label->setColor(color); + + QVERIFY(label->color() == color); + + // make style reload + label->setActive(true); + label->setActive(false); + + QVERIFY(label->color() == color); +} + +QTEST_APPLESS_MAIN(Ut_DuiLabel); diff --git a/tests/ut_duilabel/ut_duilabel.css b/tests/ut_duilabel/ut_duilabel.css new file mode 100644 index 000000000..64d213bb7 --- /dev/null +++ b/tests/ut_duilabel/ut_duilabel.css @@ -0,0 +1,30 @@ +DuiLabelStyle { + font: "sans" 11; + color: #FF0000; + + margin-left: 0; + margin-right: 0; + margin-top: 0; + margin-bottom: 0; + + padding-left: 0; + padding-right: 0; + padding-top: 0; + padding-bottom: 0; +} + +DuiLabelStyle#greyLabel { + font: "sans" 16; + color: #00FF00; +} + +DuiLabelStyle#size10 { + font: "sans" 10px; +} +DuiLabelStyle#size16 { + font: "sans" 16px; +} +DuiLabelStyle#size100 { + font: "sans" 100px; +} + diff --git a/tests/ut_duilabel/ut_duilabel.h b/tests/ut_duilabel/ut_duilabel.h new file mode 100644 index 000000000..e9554a59c --- /dev/null +++ b/tests/ut_duilabel/ut_duilabel.h @@ -0,0 +1,92 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUILABEL_H +#define UT_DUILABEL_H + + +#include "duilabel.h" +#include +#include + +class TestDuiLabel; + +class TestDuiLabel: public DuiLabel +{ + Q_OBJECT + +public: + TestDuiLabel(); + virtual ~TestDuiLabel(); + + void simulateClick(const QPointF &pos = QPointF(0, 0)); + QImage getLabelImage(); +}; + + +class Ut_DuiLabel : public QObject +{ + Q_OBJECT + +private: + + void anchorHitTest(const QPointF &point, int expectedHits); + QImage captureImage(DuiLabel *label); + +private slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + + void testTextAlignment_data(); + void testLayoutDirection_data(); + void testTextWordWrap_data(); + void testTextElide_data(); + void testClear_data(); + void testPlainTextColor_data(); + + void testTestConstruction(); + void testTextAlignment(); + void testLayoutDirection(); + void testTextWordWrap(); + void testTextElide(); + + void testHighlighting(); + + void testAnchor(); + + void testClear(); + void testPlainTextColor(); + + void testSizeHint_data(); + void testSizeHint(); + + void testFont_data(); + void testFont(); + + void testColor_data(); + void testColor(); + + +private: + TestDuiLabel *label; +}; + +#endif diff --git a/tests/ut_duilabel/ut_duilabel.pro b/tests/ut_duilabel/ut_duilabel.pro new file mode 100644 index 000000000..a1c2cf82a --- /dev/null +++ b/tests/ut_duilabel/ut_duilabel.pro @@ -0,0 +1,12 @@ +include(../common_top.pri) + +TARGET = ut_duilabel + +HEADERS += ut_duilabel.h + +SOURCES += ut_duilabel.cpp + +support_files.files += \ + ut_duilabel.css \ + +include(../common_bot.pri ) diff --git a/tests/ut_duilayout/.gitignore b/tests/ut_duilayout/.gitignore new file mode 100644 index 000000000..983bd7193 --- /dev/null +++ b/tests/ut_duilayout/.gitignore @@ -0,0 +1 @@ +ut_duilayout diff --git a/tests/ut_duilayout/ut_duilayout.cpp b/tests/ut_duilayout/ut_duilayout.cpp new file mode 100644 index 000000000..bbbd76b67 --- /dev/null +++ b/tests/ut_duilayout/ut_duilayout.cpp @@ -0,0 +1,3406 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duilayout.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../src/layout/duilayout_p.h" + +#include +#include +#include +#include +class TestPolicy : public DuiAbstractLayoutPolicy +{ +public: + TestPolicy(DuiLayout *l) : + DuiAbstractLayoutPolicy(l) { + reset(); + } + + virtual ~TestPolicy() { } + + void relayout() { + ++relayout_calls; + items_in_last_relayout = count(); + for (int i = 0; i < items_in_last_relayout; i++) + setItemGeometry(i, QRectF(0, 0, 0, 0)); + } + + QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const { + Q_UNUSED(constraint); + if (which == Qt::MaximumSize) + return QSizeF(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); + return QSizeF(0, 0); + } + virtual void addItem(QGraphicsLayoutItem *item) { + DuiAbstractLayoutPolicy::addItem(item); + } + + void reset() { + relayout_calls = 0; + items_in_last_relayout = 0; + removed_items.clear(); + } + + int relayout_calls; + int items_in_last_relayout; + QList removed_items; +}; + +class TestAnimation : public DuiBasicLayoutAnimation +{ +public: + TestAnimation(DuiLayout *layout) : + DuiBasicLayoutAnimation(layout) { + reset(); + } + + virtual ~TestAnimation() + { } + + void reset() { + layout_started = layout_to_animate = layout_done = false; + } + + void animate(DuiItemState &i) { + QVERIFY(!i.isAnimationDone() || (i.flags() != 0)); + layout_to_animate = true; + if (i.geometryProgress() == 0) { + i.setGeometryProgress(0.5); + return; + } + i.item()->setGeometry(i.targetGeometry()); + i.animationDone(); + } + + void layoutAnimationStarted(DuiItemState *itemstate) { + layout_started = true; + DuiBasicLayoutAnimation::layoutAnimationStarted(itemstate); + } + + void layoutAnimationFinished() { + QVERIFY(layout_started); + DuiBasicLayoutAnimation::layoutAnimationFinished(); + layout_done = true; + } + bool layout_started; + bool layout_to_animate; + bool layout_done; +}; + +class DuiLayoutTest : public DuiLayout +{ +public: + DuiLayoutTest(QGraphicsLayoutItem *parent = NULL) : DuiLayout(parent) { + if (!animation()) + new DuiBasicLayoutAnimation(this); + } + virtual int addItem(QGraphicsLayoutItem *item) { + return DuiLayout::addItem(item); + } +}; +//This class lets us check for layout requests +class GraphicsWidgetTest : public QGraphicsWidget +{ +public: + virtual void updateGeometry() { + QGraphicsWidget::updateGeometry(); + } +}; + +DuiApplication *app; +DuiWindow *appWin; + +Ut_DuiLayout::Ut_DuiLayout() : + m_button(0), + m_scene(0), + m_proxy(0) +{ + static int argc = 1; + static char *argv[1] = { (char *) "./ut_duilayout" }; + app = new DuiApplication(argc, argv); + appWin = new DuiWindow; +} + +Ut_DuiLayout::~Ut_DuiLayout() +{ + Q_ASSERT(0 == m_button); + Q_ASSERT(0 == m_scene); + Q_ASSERT(0 == m_proxy); +} + +void Ut_DuiLayout::cleanupTestCase() +{ + delete appWin; + delete app; +} + +void Ut_DuiLayout::init() +{ + Q_ASSERT(0 == m_button); + Q_ASSERT(0 == m_scene); + Q_ASSERT(0 == m_proxy); + + // setup a QGraphicsLayoutItem: + m_scene = new DuiScene; + m_button = new QPushButton("Test"); + m_proxy = m_scene->addWidget(m_button); + + Q_ASSERT(0 != m_button); + Q_ASSERT(0 != m_scene); + Q_ASSERT(0 != m_proxy); + DuiTheme::loadCSS(qApp->applicationDirPath() + "/ut_duilayout.css"); +} + +void Ut_DuiLayout::cleanup() +{ + delete m_scene; // Deletes the items in the scene, too! + m_scene = 0; + m_proxy = 0; + m_button = 0; +} + +void Ut_DuiLayout::itemState() +{ + // ------------------------------------------------------------------ + // Construction: + // ------------------------------------------------------------------ + + // Null item state: + DuiItemState null_state; + QVERIFY(null_state.isNull()); + QVERIFY(null_state.item() == 0); + QVERIFY(null_state.targetGeometry() == QRectF()); + QVERIFY(null_state.sourceGeometry() == QRectF()); + QVERIFY(null_state.flags() == DuiItemState::STATE_FLAG_NONE); + + QVERIFY(null_state.isAnimationDone()); + + // Ignore setting stuff on null items: + null_state.setTargetGeometry(QRectF(QPointF(1.0, 2.0), QSizeF(91.0, 92.0))); + QVERIFY(null_state.targetGeometry() == QRectF()); + QVERIFY(null_state.sourceGeometry() == QRectF()); + QVERIFY(null_state.flags() == DuiItemState::STATE_FLAG_NONE); + + // item state: + QRectF geometry(m_proxy->geometry()); + DuiItemState state1(m_proxy); + QVERIFY(!state1.isNull()); + QVERIFY(state1.item() == m_proxy); + QCOMPARE(state1.geometryProgress(), 1.0); + QCOMPARE(state1.opacityProgress(), 1.0); + QCOMPARE(state1.item()->geometry(), geometry); + QVERIFY(state1.flags() == DuiItemState::STATE_FLAG_NONE); + + QVERIFY(state1.isAnimationDone()); + + // Copy itemstate: + DuiItemState state2(state1); + QVERIFY(!state2.isNull()); + QVERIFY(state2.item() == m_proxy); + QCOMPARE(state2.targetGeometry(), state1.targetGeometry()); + QCOMPARE(state2.item()->geometry(), state1.item()->geometry()); + QCOMPARE(state2.sourceGeometry(), state1.sourceGeometry()); + QCOMPARE(state2.flags(), state1.flags()); + QVERIFY(state2 == state1); + + QCOMPARE(state2.isAnimationDone(), state1.isAnimationDone()); + + // Flag handling: + QVERIFY(state1.isSet(DuiItemState::STATE_FLAG_TO_BE_DELETED) == false); + + state1.setFlags(DuiItemState::STATE_FLAG_TO_BE_DELETED); + QVERIFY(state1.isSet(DuiItemState::STATE_FLAG_TO_BE_DELETED) == true); + + QVERIFY(state1.hasIdenticalLayout(state2) == false); + QVERIFY((state1 == state2) == true); + + state1.removeFlags(DuiItemState::STATE_FLAG_TO_BE_DELETED); + QCOMPARE(state1.isSet(DuiItemState::STATE_FLAG_TO_BE_DELETED), false); + + // Move state1 and setTargetGeometry(): + QRectF new_target(state1.targetGeometry()); + new_target.moveTop(state1.targetGeometry().height() + 5.0); + + QRectF source(state1.item()->geometry()); + state1.setTargetGeometry(new_target); + + QCOMPARE(state1.targetGeometry(), new_target); + QCOMPARE(state1.item()->geometry(), geometry); + QCOMPARE(state1.sourceGeometry(), source); + QCOMPARE(state1.flags(), DuiItemState::STATE_FLAG_TO_BE_SHOWN); + + // Comparisons: + QCOMPARE(state1.hasIdenticalLayout(null_state), false); + QCOMPARE(state1.hasIdenticalLayout(state1), true); + QCOMPARE(state1.hasIdenticalLayout(state2), false); + QCOMPARE((state1 == state2), true); + QCOMPARE((state1 == null_state), false); + + // assignment: + state2 = state1; + QVERIFY(state1.hasIdenticalLayout(state2) == true); + QVERIFY((state1 == state2) == true); + state2.setTargetGeometry(source); + QCOMPARE(state2.targetGeometry(), source); + QCOMPARE(state1.item()->geometry(), geometry); + QCOMPARE(state1.sourceGeometry(), source); + QCOMPARE(state1.flags(), DuiItemState::STATE_FLAG_TO_BE_SHOWN); + + // animation: + state1.setTargetGeometry(new_target); + + QRectF animation_target(source); + animation_target.moveTop(source.height() + 2.5); + state1.item()->setGeometry(animation_target); + QCOMPARE(state1.targetGeometry(), new_target); + QCOMPARE(state1.item()->geometry(), animation_target); + QCOMPARE(state1.sourceGeometry(), source); + QCOMPARE(state1.flags(), DuiItemState::STATE_FLAG_TO_BE_SHOWN); +} + +void Ut_DuiLayout::testTakeAt() +{ + // Setup layout: + QGraphicsWidget *form = new QGraphicsWidget; + DuiLayoutTest *layout = new DuiLayoutTest; + form->setLayout(layout); + QVERIFY(layout->policy() == 0); + QVERIFY(layout->registeredPolicies().isEmpty()); + + //Use a qpointer to make sure that the objects are not deleted + QPointer button_pointer = m_button; + QPointer proxy_pointer = m_proxy; + QVERIFY(!button_pointer.isNull()); + QVERIFY(!proxy_pointer.isNull()); + + // Create a policy: + TestPolicy *policy1(new TestPolicy(layout)); + + // Add graphics item: + layout->addItem(m_proxy); + QCOMPARE(layout->count(), 1); + + // Remove graphics item again, testing takeAt(0) + QGraphicsLayoutItem *item = layout->takeAt(0); // first position. + QVERIFY(item == m_proxy); + + QVERIFY(!proxy_pointer.isNull()); + QVERIFY(!button_pointer.isNull()); + QCOMPARE(layout->count(), 0); + + layout->addItem(m_proxy); + QCOMPARE(layout->count(), 1); + + layout->animatedDeleteAt(0); + QGraphicsLayoutItem *deletedItem = layout->takeAt(0); //This should cause it to be deleted + + QVERIFY(deletedItem == NULL); + QCOMPARE(layout->count(), 0); + QVERIFY(proxy_pointer.isNull()); + QVERIFY(button_pointer.isNull()); + + // Delete policy1 + delete policy1; + QVERIFY(layout->policy() == NULL); + QVERIFY(layout->registeredPolicies().isEmpty()); + delete form; +} + +void Ut_DuiLayout::testDeletingItem() +{ + // Setup layout: + QGraphicsWidget *form = new QGraphicsWidget; + DuiLayoutTest *layout = new DuiLayoutTest; + form->setLayout(layout); + + //Use a qpointer to make sure that the objects are not deleted + QPointer button_pointer = m_button; + QPointer proxy_pointer = m_proxy; + + // Create a policy: + TestPolicy *policy1(new TestPolicy(layout)); + + // Add graphics item: + layout->addItem(m_proxy); + QCOMPARE(layout->count(), 1); + + + // Delete item directly, removing it from the layout + delete layout->itemAt(0); + + QVERIFY(proxy_pointer.isNull()); + QVERIFY(button_pointer.isNull()); + QCOMPARE(layout->count(), 0); + + // Delete policy1 + delete policy1; + QVERIFY(layout->policy() == NULL); + QVERIFY(layout->registeredPolicies().isEmpty()); + delete form; +} + +void Ut_DuiLayout::policyInteraction() +{ + // Setup layout: + QGraphicsWidget *form = new QGraphicsWidget; + DuiLayoutTest *layout = new DuiLayoutTest; + form->setLayout(layout); + layout->setAnimation(0); // turn of animation so that it does not delay + // item creation/removal. + QVERIFY(layout->policy() == 0); + QVERIFY(layout->registeredPolicies().isEmpty()); + + //Use a qpointer to make sure that the objects are not deleted + QPointer button_pointer = m_button; + QPointer proxy_pointer = m_proxy; + QVERIFY(!button_pointer.isNull()); + QVERIFY(!proxy_pointer.isNull()); + + // Create a policy: + TestPolicy *policy1(new TestPolicy(layout)); + QVERIFY(policy1->relayout_calls == 0); + QVERIFY(layout->policy() == policy1); + QVERIFY(layout->registeredPolicies().size() == 1); + QVERIFY(layout->registeredPolicies().contains(policy1)); + + // Set policy: + layout->setPolicy(policy1); + QVERIFY(policy1->relayout_calls == 0); + QVERIFY(layout->policy() == policy1); + QVERIFY(layout->registeredPolicies().size() == 1); + QVERIFY(layout->registeredPolicies().contains(policy1)); + + // Add graphics item: + layout->addItem(m_proxy); + QCOMPARE(layout->count(), 1); + QCOMPARE(policy1->relayout_calls, 0); + + QVERIFY(layout->policy() == policy1); + QVERIFY(layout->registeredPolicies().size() == 1); + QVERIFY(layout->registeredPolicies().contains(policy1)); + + policy1->reset(); + + // Remove graphics item again: + layout->removeAt(0); // first position. + QVERIFY(!proxy_pointer.isNull()); + QVERIFY(!button_pointer.isNull()); + + qApp->processEvents(); + QCOMPARE(layout->count(), 0); + QCOMPARE(policy1->relayout_calls, 1); + + QVERIFY(layout->policy() == policy1); + QVERIFY(layout->registeredPolicies().size() == 1); + QVERIFY(layout->registeredPolicies().contains(policy1)); + + policy1->reset(); + + // Add second policy: + TestPolicy *policy2(new TestPolicy(layout)); + + QVERIFY(policy1 != policy2); + QVERIFY(policy2->relayout_calls == 0); + QVERIFY(layout->policy() == policy1); + QVERIFY(layout->registeredPolicies().size() == 2); + QVERIFY(layout->registeredPolicies().contains(policy1)); + QVERIFY(layout->registeredPolicies().contains(policy2)); + + // Switch to second policy: + layout->setPolicy(policy2); + QVERIFY(layout->policy() == policy2); + qApp->processEvents(); + + QCOMPARE(policy1->relayout_calls, 0); + + QCOMPARE(policy2->relayout_calls, 1); + + QVERIFY(layout->registeredPolicies().size() == 2); + QVERIFY(layout->registeredPolicies().contains(policy1)); + QVERIFY(layout->registeredPolicies().contains(policy2)); + + policy1->reset(); + policy2->reset(); + // Add graphics item: + layout->addItem(m_proxy); + QCOMPARE(layout->count(), 1); + QCOMPARE(policy1->relayout_calls, 0); + + QCOMPARE(policy2->relayout_calls, 0); + + QVERIFY(layout->policy() == policy2); + QVERIFY(layout->registeredPolicies().size() == 2); + QVERIFY(layout->registeredPolicies().contains(policy1)); + QVERIFY(layout->registeredPolicies().contains(policy2)); + + // Remove graphics item again: + layout->removeAt(0); // first position. + QVERIFY(!proxy_pointer.isNull()); + QVERIFY(!button_pointer.isNull()); + delete m_proxy; //This deletes m_button too + qApp->processEvents(); + QCOMPARE(layout->count(), 0); + QCOMPARE(policy1->relayout_calls, 0); + + QVERIFY(layout->policy() == policy2); + QCOMPARE(layout->registeredPolicies().size(), 2); + QVERIFY(layout->registeredPolicies().contains(policy1)); + QVERIFY(layout->registeredPolicies().contains(policy2)); + + // Delete policy2 + delete policy2; + QVERIFY(layout->policy() == policy1); + QCOMPARE(layout->registeredPolicies().size(), 1); + QVERIFY(layout->registeredPolicies().contains(policy1)); + + // Delete policy1 + delete policy1; + QVERIFY(layout->policy() == NULL); + QVERIFY(layout->registeredPolicies().isEmpty()); + delete form; +} + +void Ut_DuiLayout::testReorderingItemsWithoutAnimation() +{ + DuiLayoutTest layout1; + + QPointer proxy_item1 = m_scene->addWidget(new QPushButton); + QPointer proxy_item2 = m_scene->addWidget(new QPushButton); + layout1.addItem(proxy_item1); + layout1.addItem(proxy_item2); + QCOMPARE(layout1.count(), 2); + QVERIFY(layout1.itemAt(0) == proxy_item1); + QVERIFY(layout1.itemAt(1) == proxy_item2); + layout1.removeItem(proxy_item1); + layout1.removeItem(proxy_item2); + QVERIFY(!proxy_item1.isNull()); + QVERIFY(!proxy_item2.isNull()); + QCOMPARE(layout1.count(), 0); + layout1.addItem(proxy_item2); + layout1.addItem(proxy_item1); + QCOMPARE(layout1.count(), 2); + QVERIFY(layout1.itemAt(0) == proxy_item2); + QVERIFY(layout1.itemAt(1) == proxy_item1); + layout1.removeItem(proxy_item1); + layout1.removeItem(proxy_item2); + delete proxy_item1; + delete proxy_item2; +} + +void Ut_DuiLayout::testDeletingLayoutDuringAnimation() +{ + QPointer proxy_item1 = m_scene->addWidget(new QPushButton); + QPointer proxy_item2 = m_scene->addWidget(new QPushButton); + + //Test deleting layout during adding animation + { + DuiLayoutTest layout1; + new TestAnimation(&layout1); + DuiLinearLayoutPolicy *policy = new DuiLinearLayoutPolicy(&layout1, Qt::Horizontal); + policy->addItem(proxy_item1); + policy->addItem(proxy_item2); + QCOMPARE(layout1.count(), 2); + static_cast(&layout1)->setGeometry(QRectF(0, 0, 100, 100)); // force a relayout now + } + QVERIFY(!proxy_item1.isNull()); + QVERIFY(!proxy_item2.isNull()); + + //Test deleting layout during deleting animation + { + DuiLayoutTest layout1; + DuiLinearLayoutPolicy *policy = new DuiLinearLayoutPolicy(&layout1, Qt::Horizontal); + new TestAnimation(&layout1); + policy->addItem(proxy_item1); + policy->addItem(proxy_item2); + QCOMPARE(layout1.count(), 2); + static_cast(&layout1)->setGeometry(QRectF(0, 0, 100, 100)); // force a relayout now + layout1.animatedDeleteAt(1); + layout1.animatedDeleteAt(0); + } + QVERIFY(proxy_item1.isNull()); + QVERIFY(proxy_item2.isNull()); + //create the proxy items again + proxy_item1 = m_scene->addWidget(new QPushButton); + proxy_item2 = m_scene->addWidget(new QPushButton); + //Test deleting items in layout with no policy + { + DuiLayoutTest layout1; + TestAnimation *animation = new TestAnimation(&layout1); + layout1.addItem(proxy_item1); + layout1.addItem(proxy_item2); + QCOMPARE(layout1.count(), 2); + //The items should be hidden, since there's no policy to show them + QCOMPARE(proxy_item1->isVisible(), false); + + layout1.animatedDeleteAt(1); + layout1.animatedDeleteAt(0); + + QVERIFY(!animation->isAnimating()); + QVERIFY(proxy_item1.isNull()); + QVERIFY(proxy_item2.isNull()); + } +} + +void Ut_DuiLayout::testDeletingThenHiding() +{ + QPointer proxy_item1 = m_scene->addWidget(new QPushButton); + QPointer proxy_item2 = m_scene->addWidget(new QPushButton); + + DuiLayoutTest layout1; + TestAnimation *animation = new TestAnimation(&layout1); + DuiLinearLayoutPolicy *policy = new DuiLinearLayoutPolicy(&layout1, Qt::Horizontal); + policy->addItem(proxy_item1); + policy->addItem(proxy_item2); + QCOMPARE(layout1.count(), 2); + static_cast(&layout1)->setGeometry(layout1.geometry()); // force a relayout now + layout1.animatedDeleteAt(1); + layout1.animatedDeleteAt(0); + //If they have not been deleted yet + if (!proxy_item1.isNull()) + policy->removeItem(proxy_item1); + if (!proxy_item2.isNull()) + policy->removeItem(proxy_item2); + while (animation->isAnimating()) + QTest::qWait(50); + QVERIFY(proxy_item1.isNull()); + QVERIFY(proxy_item2.isNull()); + qApp->processEvents(); + QVERIFY(!animation->isAnimating()); +} + +void Ut_DuiLayout::testDeletingLayoutDuringAnimationWithMultiplyPolicies() +{ + QPointer proxy_item1 = m_scene->addWidget(new QPushButton); + QPointer proxy_item2 = m_scene->addWidget(new QPushButton); + QPointer animation; + //Test deleting layout during adding animation + { + DuiWidget *form = new DuiWidget; + DuiLayoutTest *layout1 = new DuiLayoutTest; + form->setLayout(layout1); + TestPolicy *policy1(new TestPolicy(layout1)); + QVERIFY(layout1->policy() == policy1); + + layout1->addItem(proxy_item1); + layout1->addItem(proxy_item2); + animation = new TestAnimation(layout1); + policy1->addItem(proxy_item1); + policy1->addItem(proxy_item2); + layout1->activate(); //for a relayout now so that the items become visible + + proxy_item1->setParentItem(NULL); //we don't want to delete the proxy_items yet + proxy_item2->setParentItem(NULL); + delete form; + } + QVERIFY(animation.isNull()); + QVERIFY(!proxy_item1.isNull()); + QVERIFY(!proxy_item2.isNull()); + + //Test deleting layout during deleting animation + { + DuiWidget *form = new DuiWidget; + DuiLayoutTest *layout1 = new DuiLayoutTest; + form->setLayout(layout1); + TestPolicy *policy1(new TestPolicy(layout1)); + QVERIFY(layout1->policy() == policy1); + + animation = new TestAnimation(layout1); + policy1->addItem(proxy_item1); + policy1->addItem(proxy_item2); + layout1->activate(); //for a relayout now so that the items become visible + proxy_item1->setParentItem(NULL); // the items should be deleted even if they weren't a parent of form, since we marked them as to be deleted + proxy_item2->setParentItem(NULL); + layout1->animatedDeleteAt(1); + layout1->animatedDeleteAt(0); + delete form; + } + QVERIFY(animation.isNull()); + QVERIFY(proxy_item1.isNull()); + QVERIFY(proxy_item2.isNull()); +} + +void Ut_DuiLayout::testReorderingItemsWithAnimationWithMultiplePolicies() +{ + DuiLayoutTest layout1; + TestAnimation *animation = new TestAnimation(&layout1); + + TestPolicy *policy1(new TestPolicy(&layout1)); + TestPolicy *policy2(new TestPolicy(&layout1)); + QVERIFY(layout1.policy() == policy1); + + QPointer proxy_item1 = m_scene->addWidget(new QPushButton); + QPointer proxy_item2 = m_scene->addWidget(new QPushButton); + layout1.addItem(proxy_item1); + layout1.addItem(proxy_item2); + QCOMPARE(layout1.count(), 2); + QVERIFY(layout1.itemAt(0) == proxy_item1); + QVERIFY(layout1.itemAt(1) == proxy_item2); + layout1.removeItem(proxy_item1); + layout1.removeItem(proxy_item2); + QVERIFY(!proxy_item1.isNull()); + QVERIFY(!proxy_item2.isNull()); + QCOMPARE(layout1.count(), 0); + layout1.addItem(proxy_item2); + layout1.addItem(proxy_item1); + QCOMPARE(layout1.count(), 2); + QVERIFY(layout1.itemAt(0) == proxy_item2); + QVERIFY(layout1.itemAt(1) == proxy_item1); + //don't give the animation a chance to finish adding the items. Delete now. + layout1.animatedDeleteAt(0); + while (animation->isAnimating()) + QTest::qWait(50); + QVERIFY(!animation->isAnimating()); + QCOMPARE(layout1.count(), 1); // Item should be removed and deleted + QVERIFY(proxy_item2.isNull()); + layout1.animatedDeleteAt(0); + + while (animation->isAnimating()) + QTest::qWait(50); + QVERIFY(!animation->isAnimating()); + QCOMPARE(layout1.count(), 0); // Item should be removed and deleted + QVERIFY(proxy_item1.isNull()); + + delete policy1; + delete policy2; +} + +void Ut_DuiLayout::testReorderingItemsWithAnimation() +{ + DuiLayoutTest layout1; + TestAnimation *animation = new TestAnimation(&layout1); + + QPointer proxy_item1 = m_scene->addWidget(new QPushButton); + QPointer proxy_item2 = m_scene->addWidget(new QPushButton); + layout1.addItem(proxy_item1); + layout1.addItem(proxy_item2); + QCOMPARE(layout1.count(), 2); + QVERIFY(layout1.itemAt(0) == proxy_item1); + QVERIFY(layout1.itemAt(1) == proxy_item2); + layout1.removeItem(proxy_item1); + layout1.removeItem(proxy_item2); + QVERIFY(!proxy_item1.isNull()); + QVERIFY(!proxy_item2.isNull()); + QCOMPARE(layout1.count(), 0); + layout1.addItem(proxy_item2); + layout1.addItem(proxy_item1); + QCOMPARE(layout1.count(), 2); + QVERIFY(layout1.itemAt(0) == proxy_item2); + QVERIFY(layout1.itemAt(1) == proxy_item1); + //don't give the animation a chance to finish adding the items. Delete now. + layout1.animatedDeleteAt(0); + + while (animation->isAnimating()) + QTest::qWait(50); + QVERIFY(!animation->isAnimating()); + QCOMPARE(layout1.count(), 1); // Item should be removed and deleted + QVERIFY(proxy_item2.isNull()); + layout1.animatedDeleteAt(0); + while (animation->isAnimating()) + QTest::qWait(50); + QVERIFY(!animation->isAnimating()); + QCOMPARE(layout1.count(), 0); // Item should be removed and deleted + QVERIFY(proxy_item1.isNull()); + +} + +void Ut_DuiLayout::testRemoveItemFromLayout() +{ + QPointer proxy_item1 = m_scene->addWidget(new QPushButton); + QGraphicsLinearLayout *layout_item = new QGraphicsLinearLayout; + QPointer proxy_item2 = m_scene->addWidget(new QPushButton); + layout_item->addItem(proxy_item2); + + DuiLayoutTest layout1; + layout1.addItem(proxy_item1); + layout1.addItem(layout_item); + QCOMPARE(layout1.count(), 2); + layout1.removeItem(proxy_item1); + QCOMPARE(layout1.count(), 1); + layout1.removeItem(proxy_item2); //This should fail since proxy_item2 isn't directly in the layout + QCOMPARE(layout1.count(), 1); + layout1.removeItem(layout_item); + QCOMPARE(layout1.count(), 0); + QVERIFY(!proxy_item1.isNull()); + QVERIFY(!proxy_item2.isNull()); + //We can't directly check whether layout_item has been deleted + //but since we only removed the item, it shouldn't be deleted + //so proxy_item2 should still have it as a parent + //If the below verify fails, DuiLayoutTest is deleting the item when it shouldn't + QVERIFY(proxy_item2->parentLayoutItem() != NULL); + + //If the below verify fails, DuiLayoutTest isn't setting the parent to NULL + QVERIFY(proxy_item1->parentLayoutItem() == NULL); +} + +void Ut_DuiLayout::testDeletingLayout() +{ + QPointer proxy_item1 = m_scene->addWidget(new QPushButton); + QGraphicsLinearLayout *layout_item = new QGraphicsLinearLayout; + QPointer proxy_item2 = m_scene->addWidget(new QPushButton); + layout_item->addItem(proxy_item2); + + QCOMPARE(proxy_item1->ownedByLayout(), false); + QCOMPARE(proxy_item2->ownedByLayout(), false); + QCOMPARE(layout_item->ownedByLayout(), true); + { + DuiLayoutTest layout1; + layout1.addItem(proxy_item1); + layout1.addItem(layout_item); + } + //Layout is now deleted. It should only delete the layout + QVERIFY(!proxy_item1.isNull()); + QVERIFY(!proxy_item2.isNull()); + + //We can't directly check whether layout_item has been deleted + //but if its deleted, proxy_item2 shouldn't have a layout parent + //If the below verify fails, DuiLayoutTest isn't deleting items that are ownerByLayout + QVERIFY(proxy_item2->parentLayoutItem() == NULL); + //If the below verify fails, DuiLayoutTest isn't setting the parent to NULL + QVERIFY(proxy_item1->parentLayoutItem() == NULL); +} + +void Ut_DuiLayout::testDeletingItemWithAnimation() +{ + QPointer proxy_item1 = m_scene->addWidget(new QPushButton); + QGraphicsLinearLayout *layout_item = new QGraphicsLinearLayout; + QPointer proxy_item2 = m_scene->addWidget(new QPushButton); + layout_item->addItem(proxy_item2); + + QGraphicsWidget *form = new QGraphicsWidget; + DuiLayoutTest *layout1 = new DuiLayoutTest(); + form->setLayout(layout1); + form->setGeometry(0, 0, 300, 300); + + //If this test fails, then it means that the layout.count() does not immediately + //decrease after the item is removed. + TestAnimation *animation = new TestAnimation(layout1);; + TestPolicy *policy1(new TestPolicy(layout1)); + new TestPolicy(layout1); //Create a dummy policy - just for testing + QVERIFY(layout1->policy() == policy1); + policy1->addItem(proxy_item1); + policy1->addItem(layout_item); + QCOMPARE(layout1->count(), 2); + qApp->processEvents(); //required for the items to be shown + + //Note that we do not wait for the animation to finish adding the item before removing it + layout1->animatedDeleteAt(1); + layout1->animatedDeleteAt(0); + if (!animation->isAnimating()) + QCOMPARE(layout1->count(), 0); + while (animation->isAnimating()) + QTest::qWait(50); + QVERIFY(!animation->isAnimating()); + QCOMPARE(layout1->count(), 0); // Item should be removed and deleted + + QVERIFY(proxy_item1.isNull()); + QVERIFY(!proxy_item2.isNull()); // proxy_item2 is inside a layout that was deleted, so although the layout was deleted, proxy_item2 should not + QVERIFY(proxy_item2->parentLayoutItem() == NULL); + delete form; +} +void Ut_DuiLayout::testRemovingItemWithAnimation() +{ + //If this test fails, then it means that the layout.count() does not immediately + //decrease after the item is removed. + DuiLayoutTest layout1; + new TestAnimation(&layout1); + + TestPolicy *policy1(new TestPolicy(&layout1)); + new TestPolicy(&layout1); + QVERIFY(layout1.policy() == policy1); + + layout1.addItem(m_proxy); + QCOMPARE(layout1.count(), 1); + //Note that we do not wait for the animation to finish adding the item before removing it + layout1.removeItem(m_proxy); + QCOMPARE(layout1.count(), 0); +} +void Ut_DuiLayout::animationInteraction() +{ + DuiLayoutTest layout1; + // Setup layouts: + QVERIFY(layout1.animation() != 0); + DuiLayoutTest layout2; + QVERIFY(layout2.animation() != 0); + + //Use a qpointer to make sure that the objects are not deleted + QPointer button_pointer = m_button; + QPointer proxy_pointer = m_proxy; + QVERIFY(!button_pointer.isNull()); + QVERIFY(!proxy_pointer.isNull()); + + // Set animation: + TestAnimation *animation1 = new TestAnimation(&layout1); + QVERIFY(!animation1->isAnimating()); + QVERIFY(layout1.animation() == animation1); + + TestAnimation *animation2 = new TestAnimation(&layout2); + QVERIFY(layout2.animation() == animation2); + QVERIFY(!animation2->isAnimating()); + + // Setup Policy: + TestPolicy *policy2(new TestPolicy(&layout2)); + TestPolicy *policy1(new TestPolicy(&layout1)); + QVERIFY(layout1.policy() == policy1); + QVERIFY(layout2.policy() == policy2); + + // Add item to layout1: + QCOMPARE(layout1.count(), 0); + layout1.addItem(m_proxy); + QCOMPARE(layout1.count(), 1); + QVERIFY(!animation1->layout_started); + QVERIFY(!animation1->layout_done); + QVERIFY(!animation1->isAnimating()); + QVERIFY(m_proxy->parentLayoutItem() == &layout1); + + // Remove item from layout1 + layout1.removeItem(m_proxy); + QVERIFY(!button_pointer.isNull()); + QVERIFY(!proxy_pointer.isNull()); + m_proxy->setParentLayoutItem(NULL); + QVERIFY(m_proxy->parentLayoutItem() != &layout1); + + //Make sure that the count decreases immediately, + //i.e. not waiting for it to be animatedly hidden + QCOMPARE(layout1.count(), 0); + + // Set animation back to 0: + layout1.setAnimation(0); + QVERIFY(layout1.animation() == 0); + layout2.setAnimation(0); + QVERIFY(layout2.animation() == 0); + + delete policy1; + delete policy2; +} + +void Ut_DuiLayout::testEmptyAnimation() +{ + DuiLayoutTest layout; + layout.setAnimation(0); + QVERIFY(layout.animation() == 0); + + QPointer proxy_item1 = m_scene->addWidget(new QPushButton); + QPointer proxy_item2 = m_scene->addWidget(new QPushButton); + + QCOMPARE(layout.count(), 0); + layout.addItem(proxy_item1); + QCOMPARE(layout.count(), 1); + layout.addItem(proxy_item2); + QCOMPARE(layout.count(), 2); + + layout.removeItem(proxy_item2); + QCOMPARE(layout.count(), 1); + layout.removeItem(proxy_item1); + QCOMPARE(layout.count(), 0); + QVERIFY(!proxy_item1.isNull()); + QVERIFY(!proxy_item2.isNull()); + delete proxy_item1; + delete proxy_item2; +} + +void Ut_DuiLayout::testDuiLabelOnLayout() +{ + //This is to test specifically for BUG 117346 - DuiLayout scales oddly. This was + //due to two separate issues: + // + //1) DuiLabelView had a messed up implementation of sizeHint. It should be using + //the width constraint to determine the height. Instead it invalidates the + //geometry (and thus invalidates the layout) every time the size changes. This + //means that when the layout changes size, the animation resizes the widget which + //in turn invalidates the layout, meaning that the layout has to start all over + //again. + // + //2) When the layout is invalidated, DuiBasicLayoutAnimation counted the item as + //being added again, retriggering the addItem animation. + QGraphicsWidget *form = new QGraphicsWidget; + DuiLayout *layout = new DuiLayoutTest(); + DuiLinearLayoutPolicy *mainLayoutPolicy = new DuiLinearLayoutPolicy(layout, Qt::Vertical); + form->setLayout(layout); + DuiLabel *labelTitle = new DuiLabel("Label title"); + mainLayoutPolicy->addItem(labelTitle); + form->resize(860, 480); + m_scene->addItem(form); + QSizeF size; + do { + QVERIFY(labelTitle->size().width() >= size.width()); + QVERIFY(labelTitle->size().height() >= size.height()); + size = labelTitle->size(); + QTest::qWait(50); + } while (layout->animation() && layout->animation()->isAnimating()); +} + +void Ut_DuiLayout::testHidingShowingWidgets_data() +{ + QTest::addColumn("reverse"); //Whether to use rtl layout direction + + QTest::newRow("LTR") << false; + QTest::newRow("RTL") << true; +} + +void Ut_DuiLayout::testHidingShowingWidgets() +{ + QFETCH(bool, reverse); //Whether to use rtl layout + qApp->setLayoutDirection(reverse ? Qt::RightToLeft : Qt::LeftToRight); + + QGraphicsWidget *form = new QGraphicsWidget; + DuiLayoutTest *layout = new DuiLayoutTest; + form->setLayout(layout); + + int w = 212; + + // here we save the expected geometries in different geomXY QRectF + // variables. the X gives the column index starting at one, + // and Y gives the row index starting at one + + QRectF geom11; + QRectF geom12; + QRectF geom21; + QRectF geom22; + + if (reverse) { + geom11 = QRectF(w - 104, 4, 100, 100); + geom12 = QRectF(w - 104, 108, 100, 100); + geom21 = QRectF(w - 208, 4, 100, 100); + geom22 = QRectF(w - 208, 108, 100, 100); + } else { + geom11 = QRectF(4, 4, 100, 100); + geom12 = QRectF(4, 108, 100, 100); + geom21 = QRectF(108, 4, 100, 100); + geom22 = QRectF(108, 108, 100, 100); + } + + form->setGeometry(QRectF(0, 0, w, 212)); + layout->setMinimumSize(QSizeF(w, 212)); + m_scene->addItem(form); + DuiLinearLayoutPolicy *policy1 = new DuiLinearLayoutPolicy(layout, Qt::Vertical); + DuiLinearLayoutPolicy *policy2 = new DuiLinearLayoutPolicy(layout, Qt::Horizontal); + policy1->setSpacing(4); + policy2->setSpacing(4); + layout->setContentsMargins(4, 4, 4, 4); + policy1->setContentsMargins(-1, -1, -1, -1); + policy2->setContentsMargins(-1, -1, -1, -1); + + QCOMPARE(form->geometry(), QRectF(0, 0, w, 212)); + QCOMPARE(layout->geometry(), QRectF(0, 0, w, 212)); + + QGraphicsWidget *item1 = new QGraphicsWidget; + QGraphicsWidget *item2 = new QGraphicsWidget; + QGraphicsWidget *item3 = new QGraphicsWidget; + + item1->setPreferredSize(100, 100); + item2->setPreferredSize(100, 100); + item3->setPreferredSize(100, 100); + item1->setMaximumSize(100, 100); + item2->setMaximumSize(100, 100); + item3->setMaximumSize(100, 100); + + //Items 1 & 2 only in the first policy + policy1->addItem(item1); + policy1->addItem(item2); + + //Items 2 & 3 only in the second policy + policy2->addItem(item2); + policy2->addItem(item3); + qApp->processEvents(); + QCOMPARE(layout->d_ptr->states.at(2).isAnimationDone(), true); + + if (layout->d_ptr->states.at(0).isAnimationDone()) //probably wont be done, but if system really slow (e.g. running in valgrind) it can be finished + QCOMPARE(layout->d_ptr->states.at(0).flags(), DuiItemState::STATE_FLAG_SHOWING); + else { + QVERIFY(layout->d_ptr->states.at(0).isSet(DuiItemState::STATE_FLAG_SHOWING) || + layout->d_ptr->states.at(0).isSet(DuiItemState::STATE_FLAG_TO_BE_SHOWN)); + } + + if (layout->d_ptr->states.at(1).isAnimationDone()) + QCOMPARE(layout->d_ptr->states.at(0).flags(), DuiItemState::STATE_FLAG_SHOWING); + else { + QVERIFY(layout->d_ptr->states.at(0).isSet(DuiItemState::STATE_FLAG_SHOWING) || + layout->d_ptr->states.at(0).isSet(DuiItemState::STATE_FLAG_TO_BE_SHOWN)); + } + QCOMPARE(layout->d_ptr->states.at(2).flags(), DuiItemState::STATE_FLAG_NONE); + + QCOMPARE(layout->d_ptr->states.at(0).targetGeometry(), geom11); + QCOMPARE(layout->d_ptr->states.at(1).targetGeometry(), geom12); + + QCOMPARE(item3->isVisible(), false); + + //After processing events, item1 and item2 won't be fully expanded but should have their center correct already + QCOMPARE(item1->geometry().center(), geom11.center()); + QCOMPARE(item2->geometry().center(), geom12.center()); + + while (layout->animation()->isAnimating()) + QTest::qWait(50); + QCOMPARE(layout->d_ptr->states.at(0).flags(), DuiItemState::STATE_FLAG_SHOWING); + QCOMPARE(layout->d_ptr->states.at(1).flags(), DuiItemState::STATE_FLAG_SHOWING); + QCOMPARE(layout->d_ptr->states.at(2).flags(), DuiItemState::STATE_FLAG_NONE); + + layout->setPolicy(policy2); + qApp->processEvents(); + + QCOMPARE(form->geometry(), QRectF(0, 0, 212, 212)); + QCOMPARE(layout->geometry(), QRectF(0, 0, 212, 212)); + + QCOMPARE(layout->d_ptr->states.at(1).targetGeometry(), geom11); + QCOMPARE(layout->d_ptr->states.at(2).targetGeometry(), geom21); + + while (layout->animation()->isAnimating()) + QTest::qWait(50); + + QCOMPARE(layout->d_ptr->states.at(0).flags(), DuiItemState::STATE_FLAG_NONE); + QCOMPARE(layout->d_ptr->states.at(1).flags(), DuiItemState::STATE_FLAG_SHOWING); + QCOMPARE(layout->d_ptr->states.at(2).flags(), DuiItemState::STATE_FLAG_SHOWING); + + QCOMPARE(item2->geometry(), geom11); + QCOMPARE(item3->geometry(), geom21); + + QCOMPARE(item1->isVisible(), false); +} + +/* We are testing a layout inside of a layout. We test four combinations + * to make sure that DuiLayout behaves exactly like QGraphicsLinearLayout + */ +void Ut_DuiLayout::testLayoutInsideLayout_data() +{ + QTest::addColumn("firstLayoutIsQ"); //Whether first Layout is QGraphicsLinearLayout + QTest::addColumn("secondLayoutIsQ"); //Whether second (inner) Layout is QGraphicsLinearLayout + QTest::addColumn("usewidget"); //Whether to put second layout inside a widget and put the widget in a layout, as opposed to putting the second layout directly into the first layout + QTest::addColumn("scale"); //Whether to scale the form widget + QTest::addColumn("reverse"); //Whether to use rtl layout direction + //Test every combination + for (int firstLayoutIsQ = 0; firstLayoutIsQ < 2; firstLayoutIsQ++) + for (int secondLayoutIsQ = 0; secondLayoutIsQ < 2; secondLayoutIsQ++) + for (int usewidget = 0; usewidget < 2; usewidget++) + for (int scale = 0; scale < 2; scale++) + for (int reverse = 0; reverse < 2; reverse++) { + QString description = QString("%1 and %2 inside%3%4%5").arg( + firstLayoutIsQ ? "QGraphicsLinearLayout" : "DuiLayout", + secondLayoutIsQ ? "QGraphicsLinearLayout" : "DuiLayout", + usewidget ? " with widget" : "", + reverse ? ", reversed" : "", + scale ? " (scaled)" : ""); + QTest::newRow(description.toLatin1()) << bool(firstLayoutIsQ) << bool(secondLayoutIsQ) << bool(usewidget) << bool(scale) << bool(reverse); + } +} + +void Ut_DuiLayout::testLayoutInsideLayout() +{ + QFETCH(bool, firstLayoutIsQ); //Whether first Layout is QGraphicsLinearLayout + QFETCH(bool, secondLayoutIsQ); //Whether second Layout is QGraphicsLinearLayout + QFETCH(bool, usewidget); //Whether to put second layout inside a widget and put the widget in a layout + QFETCH(bool, scale); //Whether to scale the form widget + QFETCH(bool, reverse); //Whether to use rtl layout + qApp->setLayoutDirection(reverse ? Qt::RightToLeft : Qt::LeftToRight); + + QGraphicsWidget *form = new QGraphicsWidget; + m_scene->addItem(form); + + qreal scalefactor = 1; + if (scale) { + scalefactor = 2; + form->scale(scalefactor, scalefactor); + } + QGraphicsLayout *layout; + DuiLinearLayoutPolicy *policy = NULL; + if (firstLayoutIsQ) { + layout = new QGraphicsLinearLayout; + static_cast(layout)->setSpacing(4); + } else { + layout = new DuiLayoutTest; + policy = new DuiLinearLayoutPolicy(static_cast(layout), Qt::Horizontal); + policy->setSpacing(4); + } + layout->setContentsMargins(4, 4, 4, 4); + form->setLayout(layout); + QGraphicsWidget *item = new QGraphicsWidget; + item->setMinimumSize(100, 100); + item->setMaximumSize(100, 100); + if (firstLayoutIsQ) + static_cast(layout)->addItem(item); + else + policy->addItem(item); + QPointF form_origin(40, 40); + form->setGeometry(QRectF(form_origin.x(), form_origin.y(), 316, 108)); + + //Create another layout and put it inside of this layout + QGraphicsLayout *layout2; + DuiLinearLayoutPolicy *policy2 = NULL; + if (secondLayoutIsQ) { + layout2 = new QGraphicsLinearLayout; + static_cast(layout2)->setSpacing(4); + } else { + layout2 = new DuiLayoutTest; + policy2 = new DuiLinearLayoutPolicy(static_cast(layout2), Qt::Horizontal); + policy2->setSpacing(4); + } + layout2->setContentsMargins(0, 0, 0, 0); + //If "usewidget" has been set by the _data() function, then we put the second (inner) layout + //inside of a widget, then put that widget into the outer layout + QGraphicsWidget *inner_layout_widget = NULL; + if (usewidget) { + inner_layout_widget = new QGraphicsWidget; + inner_layout_widget->setLayout(layout2); + + if (firstLayoutIsQ) + static_cast(layout)->addItem(inner_layout_widget); + else + policy->addItem(inner_layout_widget); + } else { + if (firstLayoutIsQ) + static_cast(layout)->addItem(layout2); + else + policy->addItem(layout2); + } + + //Create 2 new items and put it inside the 'layout2' which is inside 'layout' + QGraphicsWidget *itemInside1 = new QGraphicsWidget; + itemInside1->setMinimumSize(100, 100); + itemInside1->setPreferredSize(100, 100); + itemInside1->setMaximumSize(100, 100); + if (secondLayoutIsQ) + static_cast(layout2)->addItem(itemInside1); + else + policy2->addItem(itemInside1); + QGraphicsWidget *itemInside2 = new QGraphicsWidget; + itemInside2->setMinimumSize(100, 100); + itemInside2->setPreferredSize(100, 100); + itemInside2->setMaximumSize(100, 100); + if (secondLayoutIsQ) + static_cast(layout2)->addItem(itemInside2); + else + policy2->addItem(itemInside2); + + qreal left, top, right, bottom; + //Layout by itself should have a default margin of 4, according to QStyle + layout->getContentsMargins(&left, &top, &right, &bottom); + QCOMPARE(left, 4.0); QCOMPARE(top, 4.0); QCOMPARE(right, 4.0); QCOMPARE(bottom, 4.0); + //Layout inside a layout should have a default margin of 0, according to QStyle + layout2->getContentsMargins(&left, &top, &right, &bottom); + QCOMPARE(left, 0.0); QCOMPARE(top, 0.0); QCOMPARE(right, 0.0); QCOMPARE(bottom, 0.0); + + //Check the relationships + QVERIFY(itemInside1->parentLayoutItem() == layout2); + QVERIFY(itemInside2->parentLayoutItem() == layout2); + QVERIFY(item->parentLayoutItem() == layout); + if (usewidget) { + QVERIFY(layout2->parentLayoutItem() == inner_layout_widget); + QVERIFY(inner_layout_widget->parentLayoutItem() == layout); + } else + QVERIFY(layout2->parentLayoutItem() == layout); + QVERIFY(layout->parentLayoutItem() == form); + + //Check that the items are on the scene + QVERIFY(form->scene() == m_scene); + QVERIFY(item->scene() == m_scene); + QVERIFY(itemInside1->scene() == m_scene); + QVERIFY(itemInside2->scene() == m_scene); + if (usewidget) + QVERIFY(inner_layout_widget->scene() == m_scene); + //Wait for all the animations to finish + qApp->processEvents(); + while ((!firstLayoutIsQ && dynamic_cast(layout)->animation()->isAnimating()) || + (!secondLayoutIsQ && dynamic_cast(layout2)->animation()->isAnimating())) + QTest::qWait(50); + + // we calculate x values for tests with this formula in a rtl-supporting way: + // x = orig + ( directionFactor * oldXValue ) + ( widthFactor * widthOfElement ) + + int orig = 0; // the origin x value for calculations, left side (zero) in ltr + int wF = 0; // the width factor for the element to check, zero for ltr, + int dF = 1; // the direction factor for the element, 1 for ltr + + int origI = 0; // origin of inner layout + + if (reverse) { + orig = 316; // right side of the outer widget aka width of it + wF = -1; // subtract width from orig here + dF = -1; // calculate in rtl direction + + origI = 204; + } + + //Check the positions of the items + QCOMPARE(form->geometry(), QRectF(form_origin.x(), form_origin.y(), 316, 108)); + QCOMPARE(layout->geometry(), QRectF(0, 0, 316, 108)); + QCOMPARE(item->geometry(), QRectF(orig + (dF * 4) + (wF * 100), 4, 100, 100)); + QCOMPARE(layout2->effectiveSizeHint(Qt::MinimumSize), QSizeF(204, 100)); + QCOMPARE(form->mapToScene(0, 0), form_origin); + QVERIFY(form->sceneTransform() == QTransform(scalefactor, 0, 0, 0, scalefactor, 0, form_origin.x(), form_origin.y(), 1)); + //Because geometry coordinates are relative to the parent QGraphicsItem, the coordinates + //are different for the inner items depending on whether we put the inner layout inside of + //QGraphicsWidget or not + if (usewidget) { + QCOMPARE(inner_layout_widget->geometry(), QRectF(orig + (dF * 108) + (wF * 204), 4, 204, 100)); + QCOMPARE(layout2->geometry(), QRectF(0, 0, 204, 100)); + QCOMPARE(itemInside1->geometry(), QRectF(origI + (wF * 100), 0, 100, 100)); + QCOMPARE(itemInside2->geometry(), QRectF(origI + (wF * 100) + (dF * 104), 0, 100, 100)); + QCOMPARE(form->mapRectToScene(inner_layout_widget->geometry()), + QRectF(QPointF(orig + (wF * 204) + (dF * 108), 4)*scalefactor + form_origin, + QSizeF(204, 100)*scalefactor)); + QCOMPARE(inner_layout_widget->mapRectToScene(itemInside1->geometry()), + QRectF(QPointF(orig + (wF * 100) + (dF * 108), 4)*scalefactor + form_origin, + QSizeF(100, 100)*scalefactor)); + QCOMPARE(inner_layout_widget->mapRectToScene(itemInside2->geometry()), + QRectF(QPointF(orig + (wF * 100) + (dF*(108 + 104)), 4)*scalefactor + form_origin, + QSizeF(100, 100)*scalefactor)); + } else { + QCOMPARE(layout2->geometry(), QRectF(orig + (dF * 108) + (wF * 204), 4, 204, 100)); + QCOMPARE(itemInside1->geometry(), QRectF(orig + (dF * 108) + (wF * 100), 4, 100, 100)); + QCOMPARE(itemInside2->geometry(), QRectF(orig + (dF * 212) + (wF * 100), 4, 100, 100)); + QCOMPARE(form->mapRectToScene(layout2->geometry()), + QRectF(QPointF(orig + (dF * 108) + (wF * 204), 4)*scalefactor + form_origin, + QSizeF(204, 100)*scalefactor)); + QCOMPARE(form->mapRectToScene(itemInside1->geometry()), + QRectF(QPointF(orig + (dF * 108) + (wF * 100), 4)*scalefactor + form_origin, + QSizeF(100, 100)*scalefactor)); + QCOMPARE(form->mapRectToScene(itemInside2->geometry()), + QRectF(QPointF(orig + (dF*(108 + 104)) + (wF * 100), 4)*scalefactor + form_origin, + QSizeF(100, 100)*scalefactor)); + } +} + +void Ut_DuiLayout::testReparenting() +{ + //create a widget with a layout inside a layout and an item in the layout + QGraphicsWidget *form = new QGraphicsWidget; + DuiLayoutTest *layout = new DuiLayoutTest; + form->setLayout(layout); + m_scene->addItem(form); + + DuiLayoutTest *layout2 = new DuiLayoutTest; + + QGraphicsWidget *item = new QGraphicsWidget; + layout2->addItem(item); + QVERIFY(!item->scene()); + //So we have a layout2 with an item inside, and now we add that to the outer layout + layout->addItem(layout2); + //This should have added all the items inside layout2 to the scene + QVERIFY(item->scene()); +} + +//Test reparenting item but this time make item originally belong to the form. +void Ut_DuiLayout::testReparentingWithPreviousParent() +{ + //create a widget with a layout inside a layout and an item in the layout + QGraphicsWidget *form = new QGraphicsWidget; + DuiLayoutTest *layout = new DuiLayoutTest; + form->setLayout(layout); + m_scene->addItem(form); + + DuiLayoutTest *layout2 = new DuiLayoutTest; + + //Make the item a child of form + QGraphicsWidget *item = new QGraphicsWidget(form); + //Now when we add the item to the layout, it has to be removed as a parent of form first + layout2->addItem(item); + //So we have a layout2 with an item inside, and now we add that to the outer layout + layout->addItem(layout2); + //This should have added all the items inside layout2 to the scene + QVERIFY(item->scene()); +} + +void Ut_DuiLayout::testLinearPolicyChangingOrientationBasic() +{ + GraphicsWidgetTest *form = new GraphicsWidgetTest; + DuiLayoutTest *layout = new DuiLayoutTest; + form->setLayout(layout); + form->setGeometry(QRectF(0, 0, 204, 204)); + form->setMinimumWidth(204);//don't let it shrink when we have fixed sized items inside + m_scene->addItem(form); + DuiLinearLayoutPolicy *policy = new DuiLinearLayoutPolicy(layout, Qt::Vertical); + QCOMPARE(policy->orientation(), Qt::Vertical); + qreal vertical_spacing = 3; + policy->setSpacing(3); + layout->setContentsMargins(4, 4, 4, 4); + + const int num_items = 5; + //Add items to policy, vertically + for (int i = 0; i < num_items; i++) { + QGraphicsWidget *item = new QGraphicsWidget; + item->setMinimumSize(100, 100); + policy->addItem(item); + item->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); + } + + qApp->processEvents(); + //After processing events, the animation should have started, but probably not finished + QCOMPARE(layout->effectiveSizeHint(Qt::MinimumSize), QSizeF(100 + 4 + 4, 4 + 4 + 100 * num_items + vertical_spacing*(num_items - 1))); + QCOMPARE(form->effectiveSizeHint(Qt::MinimumSize), QSizeF(204, 4 + 4 + 100 * num_items + vertical_spacing*(num_items - 1))); + QCOMPARE(form->geometry(), QRectF(0, 0, 204, 4 + 4 + 100 * num_items + vertical_spacing*(num_items - 1))); + for (int i = 0; i < num_items; i++) { + if (layout->d_ptr->states.at(i).isAnimationDone()) //probably wont be done, but if system really slow (e.g. running in valgrind) it can be finished + QCOMPARE(layout->d_ptr->states.at(i).flags(), DuiItemState::STATE_FLAG_SHOWING); + else { + QVERIFY(layout->d_ptr->states.at(i).isSet(DuiItemState::STATE_FLAG_SHOWING) || + layout->d_ptr->states.at(i).isSet(DuiItemState::STATE_FLAG_TO_BE_SHOWN)); + } + QRectF targetGeometry; + //If the item can expand, its width will be expanded to the width of the layout - i.e. 204 pixels minus margins + if (layout->d_ptr->states.at(i).item()->sizePolicy().horizontalPolicy() & (QSizePolicy::GrowFlag | QSizePolicy::IgnoreFlag)) + targetGeometry = QRectF(4, 4 + i * (100 + vertical_spacing), 204 - 4 - 4, 100); + else + targetGeometry = QRectF(4, 4 + i * (100 + vertical_spacing), 100, 100); + + QCOMPARE(layout->d_ptr->states.at(i).targetGeometry(), targetGeometry); + QCOMPARE(dynamic_cast(layout->d_ptr->states.at(i).item())->isVisible(), true); + QCOMPARE(layout->d_ptr->states.at(i).item()->geometry().center(), targetGeometry.center()); + } +} +void Ut_DuiLayout::testLinearPolicyChangingOrientation_data() +{ + QTest::addColumn("waitForFirstAnimation"); + QTest::addColumn("useFixedSizePolicy"); + QTest::addColumn("reverse"); + + QTest::newRow("LTR Wait for first animation to be completed") << true << false << false; + QTest::newRow("LTR Wait for first animation to be completed and use fixed size policy") << true << true << false; + QTest::newRow("LTR Use fixed size policy") << false << true << false; + QTest::newRow("LTR Use expanding size policy") << false << true << false; + + QTest::newRow("RTL Wait for first animation to be completed") << true << false << true; + QTest::newRow("RTL Wait for first animation to be completed and use fixed size policy") << true << true << true; + QTest::newRow("RTL Use fixed size policy") << false << true << true; + QTest::newRow("RTL Use expanding size policy") << false << true << true; +} + +void Ut_DuiLayout::testLinearPolicyChangingOrientation() +{ + QFETCH(bool, waitForFirstAnimation); //Whether to wait for the Qt::Vertical animation to complete before changing to Qt::Horizontal + QFETCH(bool, useFixedSizePolicy); //Whether to set the items size policy to fixed + QFETCH(bool, reverse); //Whether to use RTL layout direction + qApp->setLayoutDirection(reverse ? Qt::RightToLeft : Qt::LeftToRight); + + GraphicsWidgetTest *form = new GraphicsWidgetTest; + DuiLayoutTest *layout = new DuiLayoutTest; + form->setLayout(layout); + form->setGeometry(QRectF(0, 0, 204, 204)); + form->setMinimumWidth(204);//don't let it shrink when we have fixed sized items inside + m_scene->addItem(form); + DuiLinearLayoutPolicy *policy = new DuiLinearLayoutPolicy(layout, Qt::Vertical); + QCOMPARE(policy->orientation(), Qt::Vertical); + qreal vertical_spacing = 3; + qreal horizontal_spacing = 3; + policy->setSpacing(3); + layout->setContentsMargins(4, 4, 4, 4); + + const int num_items = 5; + //Add items to policy, vertically + for (int i = 0; i < num_items; i++) { + QGraphicsWidget *item = new QGraphicsWidget; + item->setMinimumSize(100, 100); + policy->addItem(item); + if (useFixedSizePolicy) + item->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); + } + + qApp->processEvents(); + //After processing events, the animation should have started, but probably not finished + QCOMPARE(layout->effectiveSizeHint(Qt::MinimumSize), QSizeF(100 + 4 + 4, 4 + 4 + 100 * num_items + vertical_spacing*(num_items - 1))); + QCOMPARE(form->effectiveSizeHint(Qt::MinimumSize), QSizeF(204, 4 + 4 + 100 * num_items + vertical_spacing*(num_items - 1))); + QCOMPARE(form->geometry(), QRectF(0, 0, 204, 4 + 4 + 100 * num_items + vertical_spacing*(num_items - 1))); + for (int i = 0; i < num_items; i++) { + if (layout->d_ptr->states.at(i).isAnimationDone()) //probably wont be done, but if system really slow (e.g. running in valgrind) it can be finished + QCOMPARE(layout->d_ptr->states.at(i).flags(), DuiItemState::STATE_FLAG_SHOWING); + else { + QVERIFY(layout->d_ptr->states.at(i).isSet(DuiItemState::STATE_FLAG_SHOWING) || + layout->d_ptr->states.at(i).isSet(DuiItemState::STATE_FLAG_TO_BE_SHOWN)); + } + QRectF targetGeometry; + //If the item can expand, its width will be expanded to the width of the layout - i.e. 204 pixels minus margins + if (layout->d_ptr->states.at(i).item()->sizePolicy().horizontalPolicy() & (QSizePolicy::GrowFlag | QSizePolicy::IgnoreFlag)) + targetGeometry = QRectF(4, 4 + i * (100 + vertical_spacing), 204 - 4 - 4, 100); + else + targetGeometry = QRectF(4, 4 + i * (100 + vertical_spacing), 100, 100); + + QCOMPARE(layout->d_ptr->states.at(i).targetGeometry(), targetGeometry); + QCOMPARE(dynamic_cast(layout->d_ptr->states.at(i).item())->isVisible(), true); + QCOMPARE(layout->d_ptr->states.at(i).item()->geometry().center(), targetGeometry.center()); + } + if (waitForFirstAnimation) { + while (layout->animation()->isAnimating()) { + QTest::qWait(50); + } + //Animation is now done - the items should be in the correct place + for (int i = 0; i < num_items; i++) { + QCOMPARE(layout->d_ptr->states.at(i).geometryProgress(), 1.0); + QCOMPARE(layout->d_ptr->states.at(i).opacityProgress(), 1.0); + QCOMPARE(layout->d_ptr->states.at(i).flags(), DuiItemState::STATE_FLAG_SHOWING); + if (layout->d_ptr->states.at(i).item()->sizePolicy().horizontalPolicy() & (QSizePolicy::GrowFlag | QSizePolicy::IgnoreFlag)) { + //If the item can expand, its width will be expanded to the width of the layout - i.e. 204 pixels minus margins + QCOMPARE(layout->d_ptr->states.at(i).targetGeometry(), QRectF(4, 4 + i*(100 + vertical_spacing), 204 - 4 - 4, 100)); + QCOMPARE(layout->d_ptr->states.at(i).item()->geometry().center(), QRectF(4, 4 + i*(100 + vertical_spacing), 204 - 4 - 4, 100).center()); + } else { + QCOMPARE(layout->d_ptr->states.at(i).targetGeometry(), QRectF(4, 4 + i*(100 + vertical_spacing), 100, 100)); + QCOMPARE(layout->d_ptr->states.at(i).item()->geometry().center(), QRectF(4, 4 + i*(100 + vertical_spacing), 100, 100).center()); + } + + } + } + + //Now we change the orientation, and make sure that we move all the items to the new position + policy->setOrientation(Qt::Horizontal); + QCOMPARE(policy->orientation(), Qt::Horizontal); + + qApp->processEvents(); + + for (int i = 0; i < num_items; i++) { + if (waitForFirstAnimation) + QCOMPARE(layout->d_ptr->states.at(i).flags(), DuiItemState::STATE_FLAG_SHOWING); + if (layout->d_ptr->states.at(i).item()->sizePolicy().horizontalPolicy() & (QSizePolicy::GrowFlag | QSizePolicy::IgnoreFlag)) { + //If the item can expand, its height will be expanded to the height of the layout which was made larger when in horizontal mode + qreal height = 100 * num_items + vertical_spacing * (num_items - 1); + if (! reverse) { + QCOMPARE(layout->d_ptr->states.at(i).targetGeometry(), + QRectF(4 + i*(100 + horizontal_spacing), 4, 100, height)); + } else { + QCOMPARE(layout->d_ptr->states.at(i).targetGeometry(), + QRectF(4 + (num_items - i - 1) *(100 + horizontal_spacing), 4, 100, height)); + } + } else { + if (! reverse) { + QCOMPARE(layout->d_ptr->states.at(i).targetGeometry(), + QRectF(4 + i*(100 + horizontal_spacing), 4, 100, 100)); + } else { + QCOMPARE(layout->d_ptr->states.at(i).targetGeometry(), + QRectF(4 + (num_items - 1 - i)*(100 + horizontal_spacing), 4, 100, 100)); + } + } + } + + //wait for the animation to finish, so that the items should now be in the right position + while (layout->animation()->isAnimating()) + QTest::qWait(50); + + for (int i = 0; i < num_items; i++) { + QCOMPARE(layout->d_ptr->states.at(i).geometryProgress(), 1.0); + QCOMPARE(layout->d_ptr->states.at(i).opacityProgress(), 1.0); + QCOMPARE(layout->d_ptr->states.at(i).flags(), DuiItemState::STATE_FLAG_SHOWING); + if (layout->d_ptr->states.at(i).item()->sizePolicy().horizontalPolicy() & (QSizePolicy::GrowFlag | QSizePolicy::IgnoreFlag)) { + //If the item can expand, its height will be expanded to the height of the layout which was made larger when in horizontal mode + qreal height = 100 * num_items + vertical_spacing * (num_items - 1); + if (! reverse) { + QCOMPARE(layout->d_ptr->states.at(i).targetGeometry(), QRectF(4 + i*(100 + horizontal_spacing), 4, 100, height)); + QCOMPARE(layout->d_ptr->states.at(i).item()->geometry(), QRectF(4 + i*(100 + horizontal_spacing), 4, 100, height)); + } else { + QCOMPARE(layout->d_ptr->states.at(i).targetGeometry(), QRectF(4 + (num_items - i - 1)*(100 + horizontal_spacing), 4, 100, height)); + QCOMPARE(layout->d_ptr->states.at(i).item()->geometry(), QRectF(4 + (num_items - i - 1)*(100 + horizontal_spacing), 4, 100, height)); + } + } else { + if (! reverse) { + QCOMPARE(layout->d_ptr->states.at(i).targetGeometry(), QRectF(4 + i*(100 + horizontal_spacing), 4, 100, 100)); + QCOMPARE(layout->d_ptr->states.at(i).item()->geometry(), QRectF(4 + i*(100 + horizontal_spacing), 4, 100, 100)); + } else { + QCOMPARE(layout->d_ptr->states.at(i).targetGeometry(), QRectF(4 + (num_items - i - 1)*(100 + horizontal_spacing), 4, 100, 100)); + QCOMPARE(layout->d_ptr->states.at(i).item()->geometry(), QRectF(4 + (num_items - i - 1)*(100 + horizontal_spacing), 4, 100, 100)); + } + } + + } +} + +void Ut_DuiLayout::testGridLayoutShaking_data() +{ + QTest::addColumn("testMinimumSize"); //Whether to test the minimum size or preferred size + QTest::addColumn("reverse"); //Whether to test RTL layout direction + QTest::newRow("LTR testing layout grows to correct minimum size") << true << false; + QTest::newRow("LTR testing layouting in preferred size") << false << false; + QTest::newRow("RTL testing layout grows to correct minimum size") << true << true; + QTest::newRow("RTL testing layouting in preferred size") << false << true; +} + +void Ut_DuiLayout::testGridLayoutShaking() +{ + QFETCH(bool, testMinimumSize); //Whether to test the minimum size or preferred size + QFETCH(bool, reverse); //Whether to use RTL layout direction + qApp->setLayoutDirection(reverse ? Qt::RightToLeft : Qt::LeftToRight); + + QGraphicsWidget form; + QPixmap pixmap(10, 10); + DuiLayoutTest *layout = new DuiLayoutTest(); + form.setLayout(layout); + layout->setContentsMargins(1, 1, 1, 1); + DuiGridLayoutPolicy *policy = new DuiGridLayoutPolicy(layout); + policy->setSpacing(1); + int num_rows = 6; + + int orig = 0; // the origin x value for calculations, left side (zero) in ltr + int wF = 0; // the width factor for the element to check, zero for ltr, + int dF = 1; // the direction factor for the element, 1 for ltr + + if (reverse) { + orig = 203; // right side of the outer widget aka width of it + wF = -1; // subtract width from orig here + dF = -1; // calculate in rtl direction + } + + /* Basically we are creating a grid with 2 columns and num_rows rows. + * The items in the first row determine the minimum width of the column + * and the items in the first column determine the minimum height of the rows + */ + for (int y = 0; y < num_rows; y++) { + QGraphicsWidget *widget = new DuiLabel; + QGraphicsWidget *widget2 = new DuiLabel; + widget->setMinimumSize(0, 0); + widget2->setMinimumSize(0, 0); + + if (testMinimumSize) { + if (y == 0) { //let the first item determine the size for all of them in the row + widget->setMinimumSize(100, 10); + widget2->setMinimumWidth(100); + } else + widget->setMinimumHeight(10); + } else { + widget->setPreferredSize(100, 10); + widget2->setPreferredSize(100, 20); + } + + policy->addItem(widget, y, 0); + policy->addItem(widget2, y, 1); + + widget->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred)); + widget2->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred)); + } + /* Test and set the size. If testing the minimum size, the form will grow by itself + * in the event loop. + * For testing preferred size, we set the size explicitly */ + int itemHeight; + if (testMinimumSize) { + itemHeight = 10; + QRectF expectedGeometry(0, 0, 1 + 100 + 1 + 100 + 1, 1 + num_rows * 10 + (num_rows - 1) * 1 + 1); + QCOMPARE(layout->minimumSize(), expectedGeometry.size()); + QCOMPARE(layout->effectiveSizeHint(Qt::MinimumSize), expectedGeometry.size()); + qApp->processEvents(); + QCOMPARE(layout->geometry(), expectedGeometry); + QCOMPARE(form.geometry(), expectedGeometry); + } else { + itemHeight = 20; + QRectF preferredGeometry(0, 0, 1 + 100 + 1 + 100 + 1, 1 + num_rows * 20 + (num_rows - 1) * 1 + 1); + QCOMPARE(layout->effectiveSizeHint(Qt::PreferredSize), preferredGeometry.size()); + QCOMPARE(form.effectiveSizeHint(Qt::PreferredSize), preferredGeometry.size()); + form.setGeometry(preferredGeometry); + QCOMPARE(layout->geometry(), preferredGeometry); + } + + /* Check that all the items were laid out correctly + * The animation is still being done, so just check target geometries and centers + */ + for (int y = 0; y < num_rows; y++) { + QGraphicsWidget *widget = dynamic_cast(policy->itemAt(y, 0)); + DuiItemState itemState = layout->d_ptr->states.at(layout->indexOf((QGraphicsItem *)widget)); + QVERIFY(itemState.item() == widget); + + QCOMPARE(itemState.targetGeometry(), QRectF(orig + (wF * 100) + (dF * 1), 1 + (itemHeight + 1)*y, 100, itemHeight)); + QCOMPARE(widget->geometry().center(), QRectF(orig + (wF * 100) + (dF * 1), 1 + (itemHeight + 1)*y, 100, itemHeight).center()); + + QGraphicsWidget *widget2 = dynamic_cast(policy->itemAt(y, 1)); + DuiItemState itemState2 = layout->d_ptr->states.at(layout->indexOf((QGraphicsItem *)widget2)); + QVERIFY(itemState2.item() == widget2); + + QCOMPARE(itemState2.targetGeometry(), QRectF(orig + (wF * 100) + (dF*(1 + 100 + 1)), 1 + (itemHeight + 1)*y, 100, itemHeight)); + QCOMPARE(widget2->geometry().center(), QRectF(orig + (wF * 100) + (dF*(1 + 100 + 1)), 1 + (itemHeight + 1)*y, 100, itemHeight).center()); + } + while (layout->animation()->isAnimating()) + QTest::qWait(50); + qApp->processEvents(); //make sure that there really are no outstanding events + Q_ASSERT(!layout->animation()->isAnimating()); + /* Check that all the items are laid are correctly, this time the animation is finished so their + * actual geometry should be correct */ + for (int y = 0; y < num_rows; y++) { + QGraphicsWidget *widget = dynamic_cast(policy->itemAt(y, 0)); + DuiItemState itemState = layout->d_ptr->states.at(layout->indexOf((QGraphicsItem *)widget)); + QVERIFY(itemState.item() == widget); + QCOMPARE(itemState.geometryProgress(), 1.0); + QCOMPARE(widget->geometry(), QRectF(orig + (wF * 100) + (dF * 1), 1 + (itemHeight + 1)*y, 100, itemHeight)); + + QGraphicsWidget *widget2 = dynamic_cast(policy->itemAt(y, 1)); + DuiItemState itemState2 = layout->d_ptr->states.at(layout->indexOf((QGraphicsItem *)widget2)); + QVERIFY(itemState2.item() == widget2); + QCOMPARE(itemState2.geometryProgress(), 1.0); + QCOMPARE(widget2->geometry(), QRectF(orig + (wF * 100) + (dF*(1 + 100 + 1)), 1 + (itemHeight + 1)*y, 100, itemHeight)); + } +} + +void Ut_DuiLayout::testBasicAnimationWithLayoutInsideLayout() +{ + bool useFixedSizePolicy = false; + GraphicsWidgetTest *form = new GraphicsWidgetTest; + DuiLayoutTest *layout = new DuiLayoutTest; + QVERIFY(layout->animation()); + QVERIFY(dynamic_cast(layout->animation())); + form->setLayout(layout); + form->setGeometry(QRectF(0, 0, 204, 204)); + form->setMinimumWidth(204);//don't let it shrink when we have fixed sized items inside + m_scene->addItem(form); + DuiLinearLayoutPolicy *policy = new DuiLinearLayoutPolicy(layout, Qt::Vertical); + qreal vertical_spacing = 3; + //qreal horizontal_spacing = 3; + policy->setSpacing(vertical_spacing); + policy->setContentsMargins(4, 4, 4, 4); + + int num_items = 5; + //Add items to policy, vertically + for (int i = 0; i < num_items - 1; i++) { + QGraphicsWidget *item = new QGraphicsWidget; + item->setMinimumSize(100, 100); + policy->addItem(item); + if (useFixedSizePolicy) + item->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); + } + + //Add one more item that is inside a layout + DuiLayoutTest *layout_inside_layout = new DuiLayoutTest; + QVERIFY(layout_inside_layout->animation()); + DuiLinearLayoutPolicy *inside_policy = new DuiLinearLayoutPolicy(layout_inside_layout, Qt::Vertical); + inside_policy->setContentsMargins(0, 0, 0, 0); + + QGraphicsWidget *inside_item = new QGraphicsWidget; + inside_item->setMinimumSize(100, 100); + inside_policy->addItem(inside_item); + if (useFixedSizePolicy) + inside_item->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); + policy->addItem(layout_inside_layout); + + //We now have 5 items plus 1 item inside its own layout + //We want to check that the item inside its own layout behaves the same as the others + + qApp->processEvents(); + //After processing events, the animation should have started, but probably not finished + QCOMPARE(layout_inside_layout->effectiveSizeHint(Qt::MinimumSize), QSizeF(100, 100)); + QCOMPARE(policy->count(), num_items); + QCOMPARE(layout->effectiveSizeHint(Qt::MinimumSize), QSizeF(100 + 4 + 4, 4 + 4 + 100 * num_items + vertical_spacing*(num_items - 1))); + QCOMPARE(form->effectiveSizeHint(Qt::MinimumSize), QSizeF(204, 4 + 4 + 100 * num_items + vertical_spacing*(num_items - 1))); + QCOMPARE(form->geometry(), QRectF(0, 0, 204, 4 + 4 + 100 * num_items + vertical_spacing*(num_items - 1))); + for (int i = 0; i < num_items; i++) { + if (layout->d_ptr->states.at(i).isAnimationDone()) //probably wont be done, but if system really slow (e.g. running in valgrind) it can be finished + QCOMPARE(layout->d_ptr->states.at(i).flags(), DuiItemState::STATE_FLAG_SHOWING); + else { + QVERIFY(layout->d_ptr->states.at(i).isSet(DuiItemState::STATE_FLAG_SHOWING) || + layout->d_ptr->states.at(i).isSet(DuiItemState::STATE_FLAG_TO_BE_SHOWN)); + } + if (layout->d_ptr->states.at(i).item()->sizePolicy().horizontalPolicy() & (QSizePolicy::GrowFlag | QSizePolicy::IgnoreFlag)) { + //If the item can expand, its width will be expanded to the width of the layout - i.e. 204 pixels minus margins + QCOMPARE(layout->d_ptr->states.at(i).targetGeometry(), QRectF(4, 4 + i*(100 + vertical_spacing), 204 - 4 - 4, 100)); + QCOMPARE(layout->d_ptr->states.at(i).item()->geometry().center(), QRectF(4, 4 + i*(100 + vertical_spacing), 204 - 4 - 4, 100).center()); + } else { + QCOMPARE(layout->d_ptr->states.at(i).targetGeometry(), QRectF(4, 4 + i*(100 + vertical_spacing), 100, 100)); + QCOMPARE(layout->d_ptr->states.at(i).item()->geometry().center(), QRectF(4, 4 + i*(100 + vertical_spacing), 100, 100).center()); + } + } + while (layout->animation()->isAnimating()) { + qApp->processEvents(); + } + //Animation is now done - the items should be in the correct place + for (int i = 0; i < num_items; i++) { + QCOMPARE(layout->d_ptr->states.at(i).geometryProgress(), 1.0); + QCOMPARE(layout->d_ptr->states.at(i).opacityProgress(), 1.0); + QCOMPARE(layout->d_ptr->states.at(i).flags(), DuiItemState::STATE_FLAG_SHOWING); + if (layout->d_ptr->states.at(i).item()->sizePolicy().horizontalPolicy() & (QSizePolicy::GrowFlag | QSizePolicy::IgnoreFlag)) { + //If the item can expand, its width will be expanded to the width of the layout - i.e. 204 pixels minus margins + QCOMPARE(layout->d_ptr->states.at(i).targetGeometry(), QRectF(4, 4 + i*(100 + vertical_spacing), 204 - 4 - 4, 100)); + QCOMPARE(layout->d_ptr->states.at(i).item()->geometry().center(), QRectF(4, 4 + i*(100 + vertical_spacing), 204 - 4 - 4, 100).center()); + } else { + QCOMPARE(layout->d_ptr->states.at(i).targetGeometry(), QRectF(4, 4 + i*(100 + vertical_spacing), 100, 100)); + QCOMPARE(layout->d_ptr->states.at(i).item()->geometry().center(), QRectF(4, 4 + i*(100 + vertical_spacing), 100, 100).center()); + } + + } +} +void Ut_DuiLayout::testBasicAnimationWithLayoutInsideLayout2_data() +{ + QTest::addColumn("withAnimation"); + QTest::addColumn("withInnerAnimation"); + for (int i = 0; i < 4; i++) { + bool withAnimation = i & 1; + bool withInnerAnimation = i & (1 << 1); + QString description = QString("outer ") + (withAnimation ? "with" : "without") + " animation, inner " + (withInnerAnimation ? "with" : "without") + " animation"; + QTest::newRow(description.toLatin1()) << withAnimation << withInnerAnimation; + } +} +void Ut_DuiLayout::testBasicAnimationWithLayoutInsideLayout2() +{ + /* Test the case of a layout within a layout using DuiLayout with animations. + * Note that the next unit test, testQGraphicsLinearLayoutWithLayoutInsideLayout2(), + * does the same thing but with QGraphicsLinearLayout, to check that we do the same + * as Qt. */ + QFETCH(bool, withAnimation); + QFETCH(bool, withInnerAnimation); + GraphicsWidgetTest *form = new GraphicsWidgetTest; + DuiLayoutTest *layout = new DuiLayoutTest; + if (withAnimation) { + QVERIFY(layout->animation()); + QVERIFY(dynamic_cast(layout->animation())); + } else { + layout->setAnimation(NULL); + } + form->setLayout(layout); + form->setGeometry(QRectF(0, 0, 204, 204)); + form->setMinimumWidth(204); + form->setMaximumWidth(204); + m_scene->addItem(form); + + DuiLinearLayoutPolicy *policy = new DuiLinearLayoutPolicy(layout, Qt::Horizontal); + layout->setContentsMargins(0, 0, 0, 0); + + /* Setup inner layout with a label */ + DuiLayoutTest *labelLayout = new DuiLayoutTest; + if (!withInnerAnimation) + labelLayout->setAnimation(NULL); + labelLayout->setContentsMargins(0, 0, 0, 0); + DuiLinearLayoutPolicy *labelPolicy = new DuiLinearLayoutPolicy(labelLayout, Qt::Horizontal); + QGraphicsWidget *widget = new QGraphicsWidget; + widget->setMinimumSize(10, 10); + labelLayout->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + labelPolicy->addItem(widget); + + policy->addItem(labelLayout); + + QCOMPARE(layout->count(), 1); + QCOMPARE(labelLayout->count(), 1); + QVERIFY(labelLayout->parentLayoutItem() == layout); + + qApp->processEvents(); //Start laying out items + while (withAnimation && layout->animation()->isAnimating()) + QTest::qWait(50); //Wait for animation to finish if there is one + + QCOMPARE(form->geometry(), QRectF(0, 0, 204, 204)); + QCOMPARE(layout->geometry(), QRectF(0, 0, 204, 204)); + QCOMPARE(labelLayout->geometry(), QRectF(0, 0, 204, 204)); + + qApp->processEvents(); //make sure the inner layout is laid out + while (withInnerAnimation && labelLayout->animation()->isAnimating()) + QTest::qWait(50); + + QCOMPARE(widget->geometry().width(), 204.0); +} +void Ut_DuiLayout::testQGraphicsLinearLayoutWithLayoutInsideLayout2() +{ + //This test does the same thing as testBasicAnimationWithLayoutInsideLayout2 but + //using QGraphicsLinearLayout instead of DuiLayout, to compare results + GraphicsWidgetTest *form = new GraphicsWidgetTest; + QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(Qt::Horizontal); + + form->setLayout(layout); + form->setGeometry(QRectF(0, 0, 204, 204)); + form->setMinimumWidth(204); + form->setMaximumWidth(204); + m_scene->addItem(form); + + layout->setContentsMargins(0, 0, 0, 0); + + /* Setup inner layout */ + QGraphicsLinearLayout *labelLayout = new QGraphicsLinearLayout(Qt::Horizontal); + labelLayout->setContentsMargins(0, 0, 0, 0); + labelLayout->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + + QGraphicsWidget *widget = new QGraphicsWidget; + widget->setMinimumSize(10, 10); + labelLayout->addItem(widget); + + layout->addItem(labelLayout); + + QCOMPARE(layout->count(), 1); + QCOMPARE(labelLayout->count(), 1); + QVERIFY(labelLayout->parentLayoutItem() == layout); + + qApp->processEvents(); + + QCOMPARE(form->geometry(), QRectF(0, 0, 204, 204)); + QCOMPARE(layout->geometry(), QRectF(0, 0, 204, 204)); + QCOMPARE(labelLayout->geometry(), QRectF(0, 0, 204, 204)); + QCOMPARE(widget->geometry().width(), 204.0); +} + +void Ut_DuiLayout::testLayoutPolicyStyling_data() +{ + // Whether the policy is a DuiLinearLayoutPolicy, DuiGridLayoutPolicy, ... + QTest::addColumn("policyType"); + QTest::addColumn("isCurrent"); + QTest::newRow("DuiLinearLayoutPolicy, Horizontal as current") << "linearHorizontal" << true; + QTest::newRow("DuiLinearLayoutPolicy, Vertical as current") << "linearVertical" << true; + QTest::newRow("DuiGridLayoutPolicy as current") << "grid" << true; + QTest::newRow("DuiFlowLayoutPolicy as current") << "flow" << true; + QTest::newRow("DuiLinearLayoutPolicy, Horizontal not current") << "linearHorizontal" << false; + QTest::newRow("DuiLinearLayoutPolicy, Vertical not current") << "linearVertical" << false; + QTest::newRow("DuiGridLayoutPolicy not current") << "grid" << false; + QTest::newRow("DuiFlowLayoutPolicy not current") << "flow" << false; +} + +void checkPolicies(DuiLayoutTest *layout, DuiAbstractLayoutPolicy *policy, bool isCurrent, const QString &policyType, qreal marginLeft, qreal marginTop, qreal marginRight, qreal marginBottom, qreal verticalSpacing, qreal horizontalSpacing) +{ + qreal left, top, right, bottom; + // set the contentsMargins of the layout to find out whether the + // policy inherits these. The values for the contents + // margins of the DuiAbstractLayoutPolicy in css are negative + // which means to use the margins of the DuiLayout. + policy->getContentsMargins(&left, &top, &right, &bottom); + QCOMPARE(left, marginLeft); + QCOMPARE(top, marginTop); + QCOMPARE(right, marginRight); + QCOMPARE(bottom, marginBottom); + //We may have some negative numbers meaning that layout should ignore them + layout->setContentsMargins(3.0, 3.0, 3.0, 3.0); + if (!isCurrent) + layout->policy()->setContentsMargins(-1, -1, -1, -1); + layout->getContentsMargins(&left, &top, &right, &bottom); + if (isCurrent) { + QCOMPARE(left, (marginLeft < 0) ? 3.0 : marginLeft); + QCOMPARE(top, (marginTop < 0) ? 3.0 : marginTop); + QCOMPARE(right, (marginRight < 0) ? 3.0 : marginRight); + QCOMPARE(bottom, (marginBottom < 0) ? 3.0 : marginBottom); + } else { + QCOMPARE(left, 3.0); + QCOMPARE(top, 3.0); + QCOMPARE(right, 3.0); // The policy values override + QCOMPARE(bottom, 3.0); + } + + // now set the contentsMargins in code and see if the values from + // the css can be overridden: + policy->setContentsMargins(9.0, 9.0, 9.0, -9.0); + policy->getContentsMargins(&left, &top, &right, &bottom); + QCOMPARE(left, 9.0); + QCOMPARE(top, 9.0); + QCOMPARE(right, 9.0); + QCOMPARE(bottom, -9.0); + layout->getContentsMargins(&left, &top, &right, &bottom); + if (isCurrent) { + QCOMPARE(left, 9.0); + QCOMPARE(top, 9.0); + QCOMPARE(right, 9.0); // The policy values override + QCOMPARE(bottom, 3.0); + } else { + QCOMPARE(left, 3.0); + QCOMPARE(top, 3.0); + QCOMPARE(right, 3.0); // The policy values override + QCOMPARE(bottom, 3.0); + } + + // check whether the spacings are read correctly from the css style file: + if (policyType == "linearHorizontal") { + QCOMPARE(dynamic_cast(policy)->spacing(), horizontalSpacing); + QCOMPARE(policy->horizontalSpacing(), horizontalSpacing); + QCOMPARE(policy->verticalSpacing(), verticalSpacing); + dynamic_cast(policy)->setOrientation(Qt::Vertical); + QCOMPARE(dynamic_cast(policy)->spacing(), verticalSpacing); + QCOMPARE(policy->horizontalSpacing(), horizontalSpacing); + QCOMPARE(policy->verticalSpacing(), verticalSpacing); + dynamic_cast(policy)->setOrientation(Qt::Horizontal); + } else if (policyType == "linearVertical") { + QCOMPARE(dynamic_cast(policy)->spacing(), verticalSpacing); + QCOMPARE(policy->horizontalSpacing(), horizontalSpacing); + QCOMPARE(policy->verticalSpacing(), verticalSpacing); + dynamic_cast(policy)->setOrientation(Qt::Horizontal); + QCOMPARE(dynamic_cast(policy)->spacing(), horizontalSpacing); + QCOMPARE(policy->horizontalSpacing(), horizontalSpacing); + QCOMPARE(policy->verticalSpacing(), verticalSpacing); + dynamic_cast(policy)->setOrientation(Qt::Vertical); + } + + QCOMPARE(policy->horizontalSpacing(), horizontalSpacing); + QCOMPARE(policy->verticalSpacing(), verticalSpacing); + + //Reset back to the original values + policy->unsetContentsMargins(); + //Check that they were restored correctly + policy->getContentsMargins(&left, &top, &right, &bottom); + QCOMPARE(left, marginLeft); + QCOMPARE(top, marginTop); + QCOMPARE(right, marginRight); + QCOMPARE(bottom, marginBottom); + +} + +void Ut_DuiLayout::testLayoutPolicyStyling() +{ + QFETCH(QString, policyType); // Whether the policy is a DuiLinearLayoutPolicy, DuiGridLayoutPolicy, ... + QFETCH(bool, isCurrent); + + DuiLayoutTest *layout = new DuiLayoutTest(); + DuiAbstractLayoutPolicy *policy; + if (!isCurrent) { + // with out a setPolicy, the policy added to the layout first + // is the current policy + DuiLinearLayoutPolicy *otherPolicy = new DuiLinearLayoutPolicy(layout, Qt::Horizontal); + otherPolicy->setContentsMargins(-1, -1, -1, -1); + } + if (policyType == "grid") + policy = new DuiGridLayoutPolicy(layout); + else if (policyType == "linearHorizontal") + policy = new DuiLinearLayoutPolicy(layout, Qt::Horizontal); + else if (policyType == "linearVertical") + policy = new DuiLinearLayoutPolicy(layout, Qt::Vertical); + else if (policyType == "flow") + policy = new DuiFlowLayoutPolicy(layout); + else { + QVERIFY(false); + return; + } + + QCOMPARE(isCurrent, policy->isActive()); + + // The objectName of the policy should be empty be default, make sure it is: + QVERIFY(policy->objectName().isEmpty()); + + // The numbers which follow here are taken from the ut_duilayout.css file + // if you change the css file, you need to keep them in sync: + checkPolicies(layout, policy, isCurrent, policyType, -1.0, -1.0, -1.0, -1.0, 6.0, 7.0); + policy->setObjectName("packed"); + QCOMPARE(policy->objectName(), QString("packed")); + checkPolicies(layout, policy, isCurrent, policyType, -1, 0.0, 0.0, 0.0, 0.0, 0.0); + policy->setObjectName("spacing"); + QCOMPARE(policy->objectName(), QString("spacing")); + checkPolicies(layout, policy, isCurrent, policyType, -1, 0.0, 0.0, 0.0, 10.0, 11.0); + policy->setObjectName("margins"); + QCOMPARE(policy->objectName(), QString("margins")); + checkPolicies(layout, policy, isCurrent, policyType, 10.0, 10.0, -1.0, 10.0, 0.0, 0.0); + policy->setObjectName("spacing+margins"); + QCOMPARE(policy->objectName(), QString("spacing+margins")); + checkPolicies(layout, policy, isCurrent, policyType, 10.0, -1.0, 10.0, 10.0, 10.0, 11.0); + policy->setObjectName(QString::null); + QVERIFY(policy->objectName().isEmpty()); + checkPolicies(layout, policy, isCurrent, policyType, -1.0, -1.0, -1.0, -1.0, 6.0, 7.0); + + // Now rotate to portrait + DuiApplication::activeWindow()->setOrientationAngle(Dui::Angle90); + checkPolicies(layout, policy, isCurrent, policyType, 4.0, 5.0, 2.0, 6.0, 2.0, 3.0); + policy->setObjectName("packed"); + QCOMPARE(policy->objectName(), QString("packed")); + checkPolicies(layout, policy, isCurrent, policyType, 1, 2.0, 3.0, 4.0, 5.0, 6.0); + + DuiApplication::activeWindow()->setOrientationAngle(Dui::Angle180); + QCOMPARE(policy->objectName(), QString("packed")); + checkPolicies(layout, policy, isCurrent, policyType, -1, 0.0, 0.0, 0.0, 0.0, 0.0); + policy->setObjectName("spacing"); + QCOMPARE(policy->objectName(), QString("spacing")); + checkPolicies(layout, policy, isCurrent, policyType, -1, 0.0, 0.0, 0.0, 10.0, 11.0); + + DuiApplication::activeWindow()->setOrientationAngle(Dui::Angle270); + QCOMPARE(policy->objectName(), QString("spacing")); + checkPolicies(layout, policy, isCurrent, policyType, -1, 0.0, 0.0, 0.0, 10.0, 11.0); + + policy->setObjectName("packed"); + QCOMPARE(policy->objectName(), QString("packed")); + checkPolicies(layout, policy, isCurrent, policyType, 1, 2.0, 3.0, 4.0, 5.0, 6.0); + + DuiApplication::activeWindow()->setOrientationAngle(Dui::Angle0); + policy->setObjectName(QString::null); + QVERIFY(policy->objectName().isEmpty()); + checkPolicies(layout, policy, isCurrent, policyType, -1.0, -1.0, -1.0, -1.0, 6.0, 7.0); + + delete layout; +} + +void Ut_DuiLayout::testLayoutSwitchingWithOrientation() +{ + //Test rotating the screen to make sure that the landscape/portrait policy is always correctly set + //This was written in response to NB#144347 but the test passes, without finding any problems + QCOMPARE(DuiApplication::activeWindow()->orientationAngle(), Dui::Angle0); + DuiLayoutTest *layout = new DuiLayoutTest(); + DuiAbstractLayoutPolicy *landscape_policy = new DuiLinearLayoutPolicy(layout, Qt::Horizontal); + QVERIFY(layout->policy() == landscape_policy); //Only policy, so it must be this one + DuiApplication::activeWindow()->setOrientationAngle(Dui::Angle90); + QCOMPARE(DuiApplication::activeWindow()->orientationAngle(), Dui::Angle90); + DuiAbstractLayoutPolicy *portrait_policy = new DuiGridLayoutPolicy(layout); + QVERIFY(layout->policy() == landscape_policy); //Still only policy, so it must be this one + + layout->setPortraitPolicy(portrait_policy); + QVERIFY(layout->policy() == portrait_policy); + + layout->setLandscapePolicy(landscape_policy); + QVERIFY(layout->policy() == portrait_policy); + + DuiApplication::activeWindow()->setOrientationAngle(Dui::Angle90); //Set it to 90, again + QCOMPARE(DuiApplication::activeWindow()->orientationAngle(), Dui::Angle90); + QVERIFY(layout->policy() == portrait_policy); + DuiApplication::activeWindow()->setOrientationAngle(Dui::Angle180); + QCOMPARE(DuiApplication::activeWindow()->orientationAngle(), Dui::Angle180); + QVERIFY(layout->policy() == landscape_policy); + DuiApplication::activeWindow()->setOrientationAngle(Dui::Angle270); + QCOMPARE(DuiApplication::activeWindow()->orientationAngle(), Dui::Angle270); + QVERIFY(layout->policy() == portrait_policy); + DuiApplication::activeWindow()->setOrientationAngle(Dui::Angle90); + QCOMPARE(DuiApplication::activeWindow()->orientationAngle(), Dui::Angle90); + QVERIFY(layout->policy() == portrait_policy); + DuiApplication::activeWindow()->setOrientationAngle(Dui::Angle0); + QCOMPARE(DuiApplication::activeWindow()->orientationAngle(), Dui::Angle0); + QVERIFY(layout->policy() == landscape_policy); + DuiApplication::activeWindow()->setOrientationAngle(Dui::Angle0); + QCOMPARE(DuiApplication::activeWindow()->orientationAngle(), Dui::Angle0); + QVERIFY(layout->policy() == landscape_policy); + DuiApplication::activeWindow()->setOrientationAngle(Dui::Angle180); + QCOMPARE(DuiApplication::activeWindow()->orientationAngle(), Dui::Angle180); + QVERIFY(layout->policy() == landscape_policy); + +} +void Ut_DuiLayout::testLayoutBoundingBox_data() +{ + // Whether the policy is a DuiLinearLayoutPolicy, DuiGridLayoutPolicy, ... + QTest::addColumn("policyType"); + QTest::newRow("DuiLinearLayoutPolicy, Horizontal") << "linearHorizontal"; + QTest::newRow("DuiLinearLayoutPolicy, Vertical") << "linearVertical"; + QTest::newRow("DuiGridLayoutPolicy") << "grid"; + QTest::newRow("DuiFlowLayoutPolicy") << "flow"; + QTest::newRow("DuiFreestyleLayoutPolicy") << "freestyle"; +} + +void Ut_DuiLayout::testLayoutBoundingBox() +{ + QFETCH(QString, policyType); // Whether the policy is a DuiLinearLayoutPolicy, DuiGridLayoutPolicy, ... + + qsrand(0); + QGraphicsWidget *layoutContainer = new QGraphicsWidget(); + QRectF rect(100.0, 100.0, 1.0, 1.0); + // size will grow as needed when adding items + layoutContainer->setGeometry(rect); + QCOMPARE(rect, layoutContainer->geometry()); + m_scene->addItem(layoutContainer); + QGraphicsLinearLayout *outerLayout = new QGraphicsLinearLayout(); + outerLayout->setContentsMargins(10.0, 10.0, 10.0, 10.0); + DuiLayoutTest *layout = new DuiLayoutTest(); + layout->setAnimation(NULL); + layoutContainer->setLayout(outerLayout); + outerLayout->addItem(layout); + DuiAbstractLayoutPolicy *policy; + if (policyType == "grid") + policy = new DuiGridLayoutPolicy(layout); + else if (policyType == "flow") + policy = new DuiFlowLayoutPolicy(layout); + else if (policyType == "linearHorizontal") + policy = new DuiLinearLayoutPolicy(layout, Qt::Horizontal); + else if (policyType == "linearVertical") + policy = new DuiLinearLayoutPolicy(layout, Qt::Vertical); + else if (policyType == "freestyle") + policy = new DuiFreestyleLayoutPolicy(layout); + else { + QVERIFY(false); // should never happen + return; + } + + policy->setContentsMargins(20.0, 20.0, 20.0, 20.0); + QList widgets; + int widgetsMax = 10; + for (int i = 0; i < widgetsMax; ++i) { + widgets << new QGraphicsWidget(); + qreal width = ((100.0 * qrand()) / RAND_MAX) + 1; + qreal height = ((100.0 * qrand()) / RAND_MAX) + 1; + widgets[i]->setMinimumSize(QSizeF(width, height)); + if (policyType == "grid") { + int row = i % 3; + int col = i / 3; + dynamic_cast(policy)->addItem( + widgets[i], row, col); + } else if (policyType == "linearHorizontal" || policyType == "linearVertical") + dynamic_cast(policy)->addItem(widgets[i]); + else if (policyType == "flow") + dynamic_cast(policy)->addItem(widgets[i]); + else if (policyType == "freestyle") { + // I use a geometry with a fixed width and height here on purpose. + // The item has a randomized minimum width and height (see above), + // i.e. the item might resize if I add it to the layout using a + // fixed geometry. + // + // I also use a fixed position in the geometry on purpose, + // if an item is added at a geometry overlapping an + // already existing item, the layout policy should move + // the items so that they don't overlap anymore. In this + // unit test we check that the final geometry of the items + // is still within the contents area of the layout. + QRectF geom(20.0, 20.0, 20, 20.0); + dynamic_cast(policy)->addItemAtGeometry( + widgets[i], geom); + } else + QVERIFY(false); // should never happen + } + qApp->processEvents(); + qApp->processEvents(); + qreal marginLeft, marginRight, marginTop, marginBottom; + layout->getContentsMargins(&marginLeft, &marginRight, + &marginTop, &marginBottom); + // layoutContentsRect is area in the layout within the margins, i.e. the + // area which should contain the items. We remove a tiny amount from + // the margins because otherwise the test sometimes fails because of rounding + // errors. + QRectF layoutContentsRect = + layout->geometry().adjusted(marginLeft - 0.0001, + marginTop - 0.0001, + -marginRight + 0.0001, + -marginBottom + 0.0001); + + foreach(QGraphicsWidget * w, widgets) { + //qDebug() << "Ut_DuiLayout::testLayoutBoundingBox: policyType, outerLayout, layout, layoutContentsRect, widget geometry" << policyType << outerLayout->geometry() << layout->geometry() << layoutContentsRect << w->geometry(); + QCOMPARE(w->geometry(), layout->d_ptr->states.at(layout->indexOf(w)).targetGeometry()); + QVERIFY(layoutContentsRect.contains(w->geometry())); + } + delete(layoutContainer); +} + +void Ut_DuiLayout::testLayoutAddItemWithTwoPolicies_data() +{ + // Whether the policy is a DuiLinearLayoutPolicy, DuiGridLayoutPolicy, ... + QTest::addColumn("policyType1"); + QTest::addColumn("policyType2"); + QTest::newRow("linearHorizontal, linearHorizontal") << "linearHorizontal" << "linearHorizontal"; + QTest::newRow("linearHorizontal, linearVertical") << "linearHorizontal" << "linearVertical"; + QTest::newRow("linearHorizontal, grid") << "linearHorizontal" << "grid"; + QTest::newRow("linearHorizontal, flow") << "linearHorizontal" << "flow"; + QTest::newRow("linearHorizontal, freestyle") << "linearHorizontal" << "freestyle"; + + QTest::newRow("linearVertical, linearVertical") << "linearVertical" << "linearVertical"; + QTest::newRow("linearVertical, linearHorizontal") << "linearVertical" << "linearHorizontal"; + QTest::newRow("linearVertical, grid") << "linearVertical" << "grid"; + QTest::newRow("linearVertical, flow") << "linearVertical" << "flow"; + QTest::newRow("linearVertical, freestyle") << "linearVertical" << "freestyle"; + + QTest::newRow("grid, grid") << "grid" << "grid"; + QTest::newRow("grid, linearHorizontal") << "grid" << "linearHorizontal"; + QTest::newRow("grid, linearVertical") << "grid" << "linearVertical"; + QTest::newRow("grid, flow") << "grid" << "flow"; + QTest::newRow("grid, freestyle") << "grid" << "freestyle"; + + QTest::newRow("flow, flow") << "flow" << "flow"; + QTest::newRow("flow, linearHorizontal") << "flow" << "linearHorizontal"; + QTest::newRow("flow, linearVertical") << "flow" << "linearVertical"; + QTest::newRow("flow, grid") << "flow" << "grid"; + QTest::newRow("flow, freestyle") << "flow" << "freestyle"; + + QTest::newRow("freestyle, freestyle") << "freestyle" << "freestyle"; + QTest::newRow("freestyle, linearHorizontal") << "freestyle" << "linearHorizontal"; + QTest::newRow("freestyle, linearVertical") << "freestyle" << "linearVertical"; + QTest::newRow("freestyle, grid") << "freestyle" << "grid"; + QTest::newRow("freestyle, flow") << "freestyle" << "flow"; +} + +void Ut_DuiLayout::testLayoutAddItemWithTwoPolicies() +{ + QFETCH(QString, policyType1); + QFETCH(QString, policyType2); + + QList policyTypes; + policyTypes << policyType1; + policyTypes << policyType2; + + QGraphicsWidget *layoutContainer = new QGraphicsWidget(); + QRectF rect(100.0, 100.0, 1.0, 1.0); + // size will grow as needed when adding items + layoutContainer->setGeometry(rect); + QCOMPARE(rect, layoutContainer->geometry()); + m_scene->addItem(layoutContainer); + DuiLayoutTest *layout = new DuiLayoutTest(); + layout->setAnimation(NULL); + layoutContainer->setLayout(layout); + + QList policies; + for (int i = 0; i <= 1; ++i) { + if (policyTypes[i] == "grid") + policies << new DuiGridLayoutPolicy(layout); + else if (policyTypes[i] == "flow") + policies << new DuiFlowLayoutPolicy(layout); + else if (policyTypes[i] == "linearHorizontal") + policies << new DuiLinearLayoutPolicy(layout, Qt::Horizontal); + else if (policyTypes[i] == "linearVertical") + policies << new DuiLinearLayoutPolicy(layout, Qt::Vertical); + else if (policyTypes[i] == "freestyle") + policies << new DuiFreestyleLayoutPolicy(layout); + } + + QGraphicsWidget *widget = new QGraphicsWidget(); + + // Neither of the two policies should have any items at the beginning: + for (int i = 0; i <= 1; ++i) { + if (policyTypes[i] == "grid") { + QCOMPARE(dynamic_cast(policies[i])->rowCount(), 0); + QCOMPARE(dynamic_cast(policies[i])->columnCount(), 0); + } else if (policyTypes[i] == "linearHorizontal" || policyTypes[i] == "linearVertical") { + QCOMPARE(dynamic_cast(policies[i])->count(), 0); + } else if (policyTypes[i] == "flow") { + QCOMPARE(dynamic_cast(policies[i])->count(), 0); + } else if (policyTypes[i] == "freestyle") { + QCOMPARE(dynamic_cast(policies[i])->count(), 0); + } else + QVERIFY(false); // should never happen + } + + // add item: + layout->setPolicy(policies[0]); + if (policyTypes[0] == "grid") + dynamic_cast(policies[0])->addItem(widget, 0, 0); + else if (policyTypes[0] == "linearHorizontal" || policyTypes[0] == "linearVertical") + dynamic_cast(policies[0])->addItem(widget); + else if (policyTypes[0] == "flow") + dynamic_cast(policies[0])->addItem(widget); + else if (policyTypes[0] == "freestyle") + dynamic_cast(policies[0])->addItemAtGeometry(widget, QRectF(20, 20, 20, 20)); + else + QVERIFY(false); // should never happen + + // check whether the item has been added correctly to the first policy: + if (policyTypes[0] == "grid") { + QCOMPARE(dynamic_cast(policies[0])->rowCount(), 1); + QCOMPARE(dynamic_cast(policies[0])->columnCount(), 1); + QVERIFY(NULL != dynamic_cast(policies[0])->itemAt(0, 0)); + } else if (policyTypes[0] == "linearHorizontal" || policyTypes[0] == "linearVertical") { + QCOMPARE(dynamic_cast(policies[0])->count(), 1); + QVERIFY(NULL != dynamic_cast(policies[0])->itemAt(0)); + } else if (policyTypes[0] == "flow") { + QCOMPARE(dynamic_cast(policies[0])->count(), 1); + QVERIFY(NULL != dynamic_cast(policies[0])->itemAt(0)); + } else if (policyTypes[0] == "freestyle") { + QCOMPARE(dynamic_cast(policies[0])->count(), 1); + QVERIFY(NULL != dynamic_cast(policies[0])->itemAt(0)); + } else + QVERIFY(false); // should never happen + + // check if the item has been mistakenly added to the second policy: + if (policyTypes[1] == "grid") { + QCOMPARE(dynamic_cast(policies[1])->rowCount(), 0); + QCOMPARE(dynamic_cast(policies[1])->columnCount(), 0); + } else if (policyTypes[1] == "linearHorizontal" || policyTypes[1] == "linearVertical") { + QCOMPARE(dynamic_cast(policies[1])->count(), 0); + } else if (policyTypes[1] == "flow") { + QCOMPARE(dynamic_cast(policies[1])->count(), 0); + } else if (policyTypes[1] == "freestyle") { + //stateless policies show all the items in the layout + } else + QVERIFY(false); // should never happen + + delete(layoutContainer); +} + +void Ut_DuiLayout::testLayoutRemoveItemWithTwoPolicies_data() +{ + // Whether the policy is a DuiLinearLayoutPolicy, DuiGridLayoutPolicy, ... + QTest::addColumn("policyType1"); + QTest::addColumn("policyType2"); + QTest::newRow("linearHorizontal, linearHorizontal") << "linearHorizontal" << "linearHorizontal"; + QTest::newRow("linearHorizontal, linearVertical") << "linearHorizontal" << "linearVertical"; + QTest::newRow("linearHorizontal, grid") << "linearHorizontal" << "grid"; + QTest::newRow("linearHorizontal, flow") << "linearHorizontal" << "flow"; + QTest::newRow("linearHorizontal, freestyle") << "linearHorizontal" << "freestyle"; + + + QTest::newRow("linearVertical, linearVertical") << "linearVertical" << "linearVertical"; + QTest::newRow("linearVertical, linearHorizontal") << "linearVertical" << "linearHorizontal"; + QTest::newRow("linearVertical, grid") << "linearVertical" << "grid"; + QTest::newRow("linearVertical, flow") << "linearVertical" << "flow"; + QTest::newRow("linearVertical, freestyle") << "linearVertical" << "freestyle"; + QTest::newRow("grid, grid") << "grid" << "grid"; + QTest::newRow("grid, linearHorizontal") << "grid" << "linearHorizontal"; + QTest::newRow("grid, linearVertical") << "grid" << "linearVertical"; + QTest::newRow("grid, flow") << "grid" << "flow"; + QTest::newRow("grid, freestyle") << "grid" << "freestyle"; + + QTest::newRow("flow, flow") << "flow" << "flow"; + QTest::newRow("flow, linearHorizontal") << "flow" << "linearHorizontal"; + QTest::newRow("flow, linearVertical") << "flow" << "linearVertical"; + QTest::newRow("flow, grid") << "flow" << "grid"; + QTest::newRow("flow, freestyle") << "flow" << "freestyle"; +} + +void Ut_DuiLayout::testLayoutRemoveItemWithTwoPolicies() +{ + QFETCH(QString, policyType1); + QFETCH(QString, policyType2); + + QList policyTypes; + policyTypes << policyType1; + policyTypes << policyType2; + + QGraphicsWidget *layoutContainer = new QGraphicsWidget(); + QRectF rect(100.0, 100.0, 1.0, 1.0); + // size will grow as needed when adding items + layoutContainer->setGeometry(rect); + QCOMPARE(rect, layoutContainer->geometry()); + m_scene->addItem(layoutContainer); + DuiLayoutTest *layout = new DuiLayoutTest(); + layout->setAnimation(NULL); + layoutContainer->setLayout(layout); + + QList policies; + for (int i = 0; i <= 1; ++i) { + if (policyTypes[i] == "grid") + policies << new DuiGridLayoutPolicy(layout); + else if (policyTypes[i] == "flow") + policies << new DuiFlowLayoutPolicy(layout); + else if (policyTypes[i] == "linearHorizontal") + policies << new DuiLinearLayoutPolicy(layout, Qt::Horizontal); + else if (policyTypes[i] == "linearVertical") + policies << new DuiLinearLayoutPolicy(layout, Qt::Vertical); + else if (policyTypes[i] == "freestyle") + policies << new DuiFreestyleLayoutPolicy(layout); + } + // make first policy the current policy of the layout (it is already by default): + layout->setPolicy(policies[0]); + + QGraphicsWidget *widget = new QGraphicsWidget(); + + // Neither of the two policies should have any items at the beginning: + for (int i = 0; i <= 1; ++i) { + if (policyTypes[i] == "grid") { + QCOMPARE(dynamic_cast(policies[i])->rowCount(), 0); + QCOMPARE(dynamic_cast(policies[i])->columnCount(), 0); + } else if (policyTypes[i] == "linearHorizontal" || policyTypes[i] == "linearVertical") { + QCOMPARE(dynamic_cast(policies[i])->count(), 0); + } else if (policyTypes[i] == "flow") { + QCOMPARE(dynamic_cast(policies[i])->count(), 0); + } else if (policyTypes[i] == "freestyle") { + QCOMPARE(dynamic_cast(policies[i])->count(), 0); + } else + QVERIFY(false); // should never happen + } + + // add item to both policies: + for (int i = 0; i <= 1; ++i) { + if (policyTypes[i] == "grid") + dynamic_cast(policies[i])->addItem(widget, 0, 0); + else if (policyTypes[i] == "linearHorizontal" || policyTypes[i] == "linearVertical") + dynamic_cast(policies[i])->addItem(widget); + else if (policyTypes[i] == "flow") + dynamic_cast(policies[i])->addItem(widget); + else if (policyTypes[i] == "freestyle") + dynamic_cast(policies[i])->addItemAtGeometry(widget, QRectF(20, 20, 20, 20)); + else + QVERIFY(false); // should never happen + } + + // check whether the item has been added correctly to both policies: + for (int i = 0; i <= 1; ++i) { + if (policyTypes[i] == "grid") { + QCOMPARE(dynamic_cast(policies[i])->rowCount(), 1); + QCOMPARE(dynamic_cast(policies[i])->columnCount(), 1); + } else if (policyTypes[i] == "linearHorizontal" || policyTypes[i] == "linearVertical") { + QCOMPARE(dynamic_cast(policies[i])->count(), 1); + QVERIFY(NULL != dynamic_cast(policies[i])->itemAt(0)); + } else if (policyTypes[i] == "flow") { + QCOMPARE(dynamic_cast(policies[i])->count(), 1); + QVERIFY(NULL != dynamic_cast(policies[i])->itemAt(0)); + } else if (policyTypes[i] == "freestyle") { + QCOMPARE(dynamic_cast(policies[i])->count(), 1); + QVERIFY(NULL != dynamic_cast(policies[i])->itemAt(0)); + } else + QVERIFY(false); // should never happen + } + + // remove item from the layout and check whether this removes + // it correctly from both policies: + layout->removeItem(widget); + // Both policies should again have no items now:: + for (int i = 0; i <= 1; ++i) { + if (policyTypes[i] == "grid") { + } else if (policyTypes[i] == "linearHorizontal" || policyTypes[i] == "linearVertical") { + // the count of a linear layout policy doesn't go back + // to 0 if all items are removed. Looks like a bug: + QCOMPARE(dynamic_cast(policies[i])->count(), 0); + } else if (policyTypes[i] == "flow") { + QCOMPARE(dynamic_cast(policies[i])->count(), 0); + } else if (policyTypes[i] == "freestyle") { + QCOMPARE(dynamic_cast(policies[i])->count(), 0); + } else + QVERIFY(false); // should never happen + } + + // add item to both policies again: + for (int i = 0; i <= 1; ++i) { + if (policyTypes[i] == "grid") + dynamic_cast(policies[i])->addItem(widget, 0, 0); + else if (policyTypes[i] == "linearHorizontal" || policyTypes[i] == "linearVertical") + dynamic_cast(policies[i])->addItem(widget); + else if (policyTypes[i] == "flow") + dynamic_cast(policies[i])->addItem(widget); + else if (policyTypes[i] == "freestyle") + dynamic_cast(policies[i])->addItemAtGeometry(widget, QRectF(20, 20, 20, 20)); + else + QVERIFY(false); // should never happen + } + + // check whether the item has been again been added correctly to both policies: + for (int i = 0; i <= 1; ++i) { + QCOMPARE(policies[i]->count(), 1); + QVERIFY(NULL != policies[i]->itemAt(0)); + if (policyTypes[i] == "grid") { + QCOMPARE(dynamic_cast(policies[i])->rowCount(), 1); + QCOMPARE(dynamic_cast(policies[i])->columnCount(), 1); + QVERIFY(NULL != dynamic_cast(policies[i])->itemAt(0, 0)); + } else if (policyTypes[i] == "linearHorizontal" || policyTypes[i] == "linearVertical") { + QCOMPARE(dynamic_cast(policies[i])->count(), 1); + QVERIFY(NULL != dynamic_cast(policies[i])->itemAt(0)); + } else if (policyTypes[i] == "flow") { + QCOMPARE(dynamic_cast(policies[i])->count(), 1); + QVERIFY(NULL != dynamic_cast(policies[i])->itemAt(0)); + } else if (policyTypes[i] == "freestyle") { + QCOMPARE(dynamic_cast(policies[i])->count(), 1); + QVERIFY(NULL != dynamic_cast(policies[i])->itemAt(0)); + } else + QVERIFY(false); // should never happen + } + + // remove the item only from the first policy and check whether it has been + // correctly removed: + layout->setPolicy(policies[0]); + policies[0]->removeItem(widget); + QCOMPARE(policies[0]->count(), 0); + + // Currently there is no policy where removing items without + // removing them from other policies as well works. + // + // The grid layout policy and the linear layout policy don't even + // have a method to remove items at all, one can only call the + // remove methods of the layout and as we already know this + // removes the item from all policies. This is apparently + // intentional and we even tested above that this works. + // + // check if the item has been mistakenly removed from the second policy as well: + if (policyTypes[1] == "grid") { + QCOMPARE(dynamic_cast(policies[1])->rowCount(), 1); + QCOMPARE(dynamic_cast(policies[1])->columnCount(), 1); + QVERIFY(NULL != dynamic_cast(policies[1])->itemAt(0, 0)); + } else if (policyTypes[1] == "linearHorizontal" || policyTypes[1] == "linearVertical") { + QCOMPARE(dynamic_cast(policies[1])->count(), 1); + QVERIFY(NULL != dynamic_cast(policies[1])->itemAt(0)); + } else if (policyTypes[1] == "flow") { + QCOMPARE(dynamic_cast(policies[1])->count(), 1); + } else if (policyTypes[1] == "freestyle") { + QCOMPARE(dynamic_cast(policies[1])->count(), 1); + } else + QVERIFY(false); // should never happen + + delete widget; + delete layoutContainer; +} +void Ut_DuiLayout::testForCrash() +{ + QGraphicsWidget *layoutContainer = new QGraphicsWidget(); + QRectF rect(100.0, 100.0, 1.0, 1.0); + // size will grow as needed when adding items + layoutContainer->setGeometry(rect); + QCOMPARE(rect, layoutContainer->geometry()); + m_scene->addItem(layoutContainer); + DuiLayoutTest *layout = new DuiLayoutTest(); + layout->setAnimation(NULL); + layoutContainer->setLayout(layout); + + DuiLinearLayoutPolicy *policy1 = new DuiLinearLayoutPolicy(layout, Qt::Horizontal); + DuiLinearLayoutPolicy *policy2 = new DuiLinearLayoutPolicy(layout, Qt::Horizontal); + Q_UNUSED(policy2); + + QGraphicsWidget *widget = new QGraphicsWidget(); + policy1->addItem(widget); + + delete(layoutContainer); + qApp->processEvents(); +} + +void Ut_DuiLayout::testLayoutItemPositionRestoreWhenSwitchingPolicies_data() +{ + // Whether the policy is a DuiLinearLayoutPolicy, DuiGridLayoutPolicy, ... + QTest::addColumn("policyType1"); + QTest::addColumn("policyType2"); + QTest::newRow("linearHorizontal, linearHorizontal") << "linearHorizontal" << "linearHorizontal"; + QTest::newRow("linearHorizontal, linearVertical") << "linearHorizontal" << "linearVertical"; + QTest::newRow("linearHorizontal, grid") << "linearHorizontal" << "grid"; + QTest::newRow("linearHorizontal, flow") << "linearHorizontal" << "flow"; + QTest::newRow("linearHorizontal, freestyle") << "linearHorizontal" << "freestyle"; + + QTest::newRow("linearVertical, linearVertical") << "linearVertical" << "linearVertical"; + QTest::newRow("linearVertical, linearHorizontal") << "linearVertical" << "linearHorizontal"; + QTest::newRow("linearVertical, grid") << "linearVertical" << "grid"; + QTest::newRow("linearVertical, flow") << "linearVertical" << "flow"; + QTest::newRow("linearVertical, freestyle") << "linearVertical" << "freestyle"; + QTest::newRow("grid, grid") << "grid" << "grid"; + QTest::newRow("grid, linearHorizontal") << "grid" << "linearHorizontal"; + QTest::newRow("grid, linearVertical") << "grid" << "linearVertical"; + QTest::newRow("grid, flow") << "grid" << "flow"; + QTest::newRow("grid, freestyle") << "grid" << "freestyle"; + + QTest::newRow("flow, flow") << "flow" << "flow"; + QTest::newRow("flow, linearHorizontal") << "flow" << "linearHorizontal"; + QTest::newRow("flow, linearVertical") << "flow" << "linearVertical"; + QTest::newRow("flow, grid") << "flow" << "grid"; + QTest::newRow("flow, freestyle") << "flow" << "freestyle"; +} + +void Ut_DuiLayout::testLayoutItemPositionRestoreWhenSwitchingPolicies() +{ + QFETCH(QString, policyType1); + QFETCH(QString, policyType2); + + QList policyTypes; + policyTypes << policyType1; + policyTypes << policyType2; + + qsrand(0); + QGraphicsWidget *layoutContainer = new QGraphicsWidget(); + QRectF rect(100.0, 100.0, 1.0, 1.0); + // size will grow as needed when adding items + layoutContainer->setGeometry(rect); + QCOMPARE(rect, layoutContainer->geometry()); + m_scene->addItem(layoutContainer); + DuiLayoutTest *layout = new DuiLayoutTest(); + layout->setAnimation(NULL); + layoutContainer->setLayout(layout); + + QList policies; + for (int i = 0; i <= 1; ++i) { + if (policyTypes[i] == "grid") + policies << new DuiGridLayoutPolicy(layout); + else if (policyTypes[i] == "flow") + policies << new DuiFlowLayoutPolicy(layout); + else if (policyTypes[i] == "linearHorizontal") + policies << new DuiLinearLayoutPolicy(layout, Qt::Horizontal); + else if (policyTypes[i] == "linearVertical") + policies << new DuiLinearLayoutPolicy(layout, Qt::Vertical); + else if (policyTypes[i] == "freestyle") + policies << new DuiFreestyleLayoutPolicy(layout); + else + QVERIFY(false); + } + policies[0]->setContentsMargins(20.0, 20.0, 20.0, 20.0); + policies[1]->setContentsMargins(20.0, 20.0, 20.0, 20.0); + + int widgetsMax = 10; + QList widgets; + for (int policyIndex = 0; policyIndex <= 1; ++policyIndex) { + // if items are added to a non-active policy, they should get negative + // coordinates to be invisible. That does not seem to work, at least I found + // that it does not work for the DuiGridLayoutPolicy. This is probably a bug. + // I wrote an extra unittest for that bug. + // For the test here, I make the policies active before adding items. + layout->setPolicy(policies[policyIndex]); + for (int i = 0; i < widgetsMax; ++i) { + int widgetIndex = i + policyIndex * widgetsMax; + widgets << new QGraphicsWidget(); + qreal width = ((100.0 * qrand()) / RAND_MAX) + 1; + qreal height = ((100.0 * qrand()) / RAND_MAX) + 1; + widgets[widgetIndex]->setMinimumSize(QSizeF(width, height)); + if (policyTypes[policyIndex] == "grid") { + int row = i % 3; + int col = i / 3; + dynamic_cast(policies[policyIndex])->addItem( + widgets[widgetIndex], row, col); + qApp->processEvents(); + } else if (policyTypes[policyIndex] == "linearHorizontal" + || policyTypes[policyIndex] == "linearVertical") { + dynamic_cast(policies[policyIndex])->addItem(widgets[widgetIndex]); + } else if (policyTypes[policyIndex] == "flow") { + dynamic_cast(policies[policyIndex])->addItem(widgets[widgetIndex]); + } else if (policyTypes[policyIndex] == "freestyle") { + // I use a geometry with a fixed width and height here on purpose. + // The item has a randomized minimum width and height (see above), + // i.e. the item might resize if I add it to the layout using a + // fixed geometry. + // + // I also use a fixed position in the geometry on purpose, + // if an item is added at a geometry overlapping an + // already existing item, the layout policy should move + // the items so that they don't overlap anymore. + QRectF geom(20.0, 20.0, 20, 20.0); + dynamic_cast(policies[policyIndex])->addItemAtGeometry( + widgets[widgetIndex], geom); + } else + QVERIFY(false); // should never happen + } + } + + // remember the geometry of all widgets when policy 0 is active: + layout->setPolicy(policies[0]); + layoutContainer->setGeometry(rect); + rect = layoutContainer->geometry(); + qApp->processEvents(); + QList geometries0; + foreach(QGraphicsWidget * w, widgets) { + geometries0 << w->geometry(); + } + + layout->setPolicy(policies[1]); + qApp->processEvents(); + + // Switch back to policy 0 and test whether the visible item's geometries are restored. + layout->setPolicy(policies[0]); + layout->setMinimumWidth(rect.width()); + layoutContainer->setGeometry(rect); + qApp->processEvents(); + for (int i = 0; i < widgetsMax; ++i) + QCOMPARE(widgets[i]->geometry(), geometries0[i]); +} + +void Ut_DuiLayout::testLayoutGeometryOfItemsAddedToInactivePolicies_data() +{ + // Whether the policy is a DuiLinearLayoutPolicy, DuiGridLayoutPolicy, ... + QTest::addColumn("policyType1"); + QTest::addColumn("policyType2"); + QTest::newRow("linearHorizontal, linearHorizontal") << "linearHorizontal" << "linearHorizontal"; + QTest::newRow("linearHorizontal, linearVertical") << "linearHorizontal" << "linearVertical"; + QTest::newRow("linearHorizontal, grid") << "linearHorizontal" << "grid"; + QTest::newRow("linearHorizontal, flow") << "linearHorizontal" << "flow"; + QTest::newRow("linearHorizontal, freestyle") << "linearHorizontal" << "freestyle"; + + QTest::newRow("linearVertical, linearVertical") << "linearVertical" << "linearVertical"; + QTest::newRow("linearVertical, linearHorizontal") << "linearVertical" << "linearHorizontal"; + QTest::newRow("linearVertical, grid") << "linearVertical" << "grid"; + QTest::newRow("linearVertical, flow") << "linearVertical" << "flow"; + QTest::newRow("linearVertical, freestyle") << "linearVertical" << "freestyle"; + + QTest::newRow("grid, grid") << "grid" << "grid"; + QTest::newRow("grid, linearHorizontal") << "grid" << "linearHorizontal"; + QTest::newRow("grid, linearVertical") << "grid" << "linearVertical"; + QTest::newRow("grid, flow") << "grid" << "flow"; + QTest::newRow("grid, freestyle") << "grid" << "freestyle"; + + QTest::newRow("flow, flow") << "flow" << "flow"; + QTest::newRow("flow, linearHorizontal") << "flow" << "linearHorizontal"; + QTest::newRow("flow, linearVertical") << "flow" << "linearVertical"; + QTest::newRow("flow, grid") << "flow" << "grid"; + QTest::newRow("flow, freestyle") << "flow" << "freestyle"; + QTest::newRow("freestyle, freestyle") << "freestyle" << "freestyle"; + QTest::newRow("freestyle, linearHorizontal") << "freestyle" << "linearHorizontal"; + QTest::newRow("freestyle, linearVertical") << "freestyle" << "linearVertical"; + QTest::newRow("freestyle, grid") << "freestyle" << "grid"; + QTest::newRow("freestyle, flow") << "freestyle" << "flow"; +} + +void Ut_DuiLayout::testLayoutGeometryOfItemsAddedToInactivePolicies() +{ + QFETCH(QString, policyType1); + QFETCH(QString, policyType2); + + QList policyTypes; + policyTypes << policyType1; + policyTypes << policyType2; + + qsrand(0); + QGraphicsWidget *layoutContainer = new QGraphicsWidget(); + QRectF rect(100.0, 100.0, 1.0, 1.0); + // size will grow as needed when adding items + layoutContainer->setGeometry(rect); + QCOMPARE(rect, layoutContainer->geometry()); + m_scene->addItem(layoutContainer); + DuiLayoutTest *layout = new DuiLayoutTest(); + layout->setAnimation(NULL); + layoutContainer->setLayout(layout); + + QList policies; + for (int i = 0; i <= 1; ++i) { + if (policyTypes[i] == "grid") + policies << new DuiGridLayoutPolicy(layout); + else if (policyTypes[i] == "flow") + policies << new DuiFlowLayoutPolicy(layout); + else if (policyTypes[i] == "linearHorizontal") + policies << new DuiLinearLayoutPolicy(layout, Qt::Horizontal); + else if (policyTypes[i] == "linearVertical") + policies << new DuiLinearLayoutPolicy(layout, Qt::Vertical); + else if (policyTypes[i] == "freestyle") + policies << new DuiFreestyleLayoutPolicy(layout); + } + policies[0]->setContentsMargins(20.0, 20.0, 20.0, 20.0); + policies[1]->setContentsMargins(20.0, 20.0, 20.0, 20.0); + + // add items to two policies, while doing this the first policy is active, the second + // is not active. + int widgetsMax = 1; + QList widgets; + layout->setPolicy(policies[0]); + QVERIFY(policies[0]->isActive()); + QVERIFY(!policies[1]->isActive()); + for (int policyIndex = 0; policyIndex <= 1; ++policyIndex) { + for (int i = 0; i < widgetsMax; ++i) { + int widgetIndex = i + policyIndex * widgetsMax; + widgets << new QGraphicsWidget(); + qreal width = ((100.0 * qrand()) / RAND_MAX) + 1; + qreal height = ((100.0 * qrand()) / RAND_MAX) + 1; + widgets[widgetIndex]->setMinimumSize(QSizeF(width, height)); + if (policyTypes[policyIndex] == "grid") { + int row = i % 3; + int col = i / 3; + dynamic_cast(policies[policyIndex])->addItem( + widgets[widgetIndex], row, col); + qApp->processEvents(); + } else if (policyTypes[policyIndex] == "linearHorizontal" + || policyTypes[policyIndex] == "linearVertical") { + dynamic_cast(policies[policyIndex])->addItem(widgets[widgetIndex]); + static_cast(layout)->setGeometry(layout->geometry()); + } else if (policyTypes[policyIndex] == "flow") { + dynamic_cast(policies[policyIndex])->addItem(widgets[widgetIndex]); + static_cast(layout)->setGeometry(layout->geometry()); + } else if (policyTypes[policyIndex] == "freestyle") { + // I use a geometry with a fixed width and height here on purpose. + // The item has a randomized minimum width and height (see above), + // i.e. the item might resize if I add it to the layout using a + // fixed geometry. + // + // I also use a fixed position in the geometry on purpose, + // if an item is added at a geometry overlapping an + // already existing item, the layout policy should move + // the items so that they don't overlap anymore. + QRectF geom(20.0, 20.0, 20, 20.0); + dynamic_cast(policies[policyIndex])->addItemAtGeometry( + widgets[widgetIndex], geom); + } else + QVERIFY(false); // should never happen + } + } + QCOMPARE(policies[0]->count(), widgetsMax); + QCOMPARE(policies[1]->count(), widgetsMax); + QCOMPARE(layout->count(), 2 * widgetsMax); + for (int i = 0; i < layout->count(); i++) { + bool inFirstPolicy = i < widgetsMax; + QVERIFY(policies[inFirstPolicy?0:1]->indexOf(layout->itemAt(i)) != -1); + QVERIFY(policies[inFirstPolicy?1:0]->indexOf(layout->itemAt(i)) == -1); + } + + qApp->processEvents(); + + // As the first policy was active while the items were added and + // the second policy was not and has never been made active, all + // the items in the first policy should have positive coordinates + // now and all the items in the second policy should have negative + // coordinates. Having negative coordinates makes sure the items + // are not visible, items in an inactive policy should be + // invisible. + for (int policyIndex = 0; policyIndex <= 1; ++policyIndex) { + for (int i = 0; i < widgetsMax; ++i) { + int widgetIndex = i + policyIndex * widgetsMax; + qreal x1, y1, x2, y2; + widgets[widgetIndex]->geometry().getCoords(&x1, &y1, &x2, &y2); + //qDebug() << "policyIndex,i,geo:"<geometry(); + if (policyIndex == 0) { + QVERIFY(x1 >= 0); + QVERIFY(y1 >= 0); + QVERIFY(x2 >= 0); + QVERIFY(y2 >= 0); + QCOMPARE(widgets[widgetIndex]->isVisible(), true); + } else { + QCOMPARE(widgets[widgetIndex]->isVisible(), false); + } + } + } +} + +void Ut_DuiLayout::testLayoutItemOverlap_data() +{ + // Whether the policy is a DuiLinearLayoutPolicy, DuiGridLayoutPolicy, ... + QTest::addColumn("policyType"); + QTest::newRow("DuiLinearLayoutPolicy, Horizontal") << "linearHorizontal"; + QTest::newRow("DuiLinearLayoutPolicy, Vertical") << "linearVertical"; + QTest::newRow("DuiGridLayoutPolicy") << "grid"; + QTest::newRow("DuiFlowLayoutPolicy") << "flow"; + QTest::newRow("DuiFreestyleLayoutPolicy") << "freestyle"; +} + +void Ut_DuiLayout::testLayoutItemOverlap() +{ + QFETCH(QString, policyType); // Whether the policy is a DuiLinearLayoutPolicy, DuiGridLayoutPolicy, ... + + qsrand(0); + QGraphicsWidget *layoutContainer = new QGraphicsWidget(); + QRectF rect(100.0, 100.0, 1.0, 1.0); + // size will grow as needed when adding items + layoutContainer->setGeometry(rect); + QCOMPARE(rect, layoutContainer->geometry()); + m_scene->addItem(layoutContainer); + QGraphicsLinearLayout *outerLayout = new QGraphicsLinearLayout(); + outerLayout->setContentsMargins(10.0, 10.0, 10.0, 10.0); + DuiLayoutTest *layout = new DuiLayoutTest(); + layout->setAnimation(NULL); + layoutContainer->setLayout(outerLayout); + outerLayout->addItem(layout); + DuiAbstractLayoutPolicy *policy; + if (policyType == "grid") + policy = new DuiGridLayoutPolicy(layout); + else if (policyType == "flow") + policy = new DuiFlowLayoutPolicy(layout); + else if (policyType == "linearHorizontal") + policy = new DuiLinearLayoutPolicy(layout, Qt::Horizontal); + else if (policyType == "linearVertical") + policy = new DuiLinearLayoutPolicy(layout, Qt::Vertical); + else if (policyType == "freestyle") + policy = new DuiFreestyleLayoutPolicy(layout); + else { + QVERIFY(false); // should never happen + return; + } + + policy->setContentsMargins(20.0, 20.0, 20.0, 20.0); + policy->setSpacing(0.01); //we need a non-zero size spacing to avoid rounding errors when testing for intersection + QList widgets; + int widgetsMax = 10; + for (int i = 0; i < widgetsMax; ++i) { + widgets << new QGraphicsWidget(); + qreal width = ((100.0 * qrand()) / RAND_MAX) + 1; + qreal height = ((100.0 * qrand()) / RAND_MAX) + 1; + + widgets[i]->setMinimumSize(QSizeF(width, height)); + if (policyType == "grid") { + int row = i % 3; + int col = i / 3; + dynamic_cast(policy)->addItem( + widgets[i], row, col); + } else if (policyType == "linearHorizontal" || policyType == "linearVertical") + dynamic_cast(policy)->addItem(widgets[i]); + else if (policyType == "flow") + dynamic_cast(policy)->addItem(widgets[i]); + else if (policyType == "freestyle") { + // I use a geometry with a fixed width and height here on purpose. + // The item has a randomized minimum width and height (see above), + // i.e. the item might resize if I add it to the layout using a + // fixed geometry. + // + // I also use a fixed position in the geometry on purpose, + // if an item is added at a geometry overlapping an + // already existing item, the freestyle layout policy should move + // the items so that they don't overlap anymore, which is what + // we want to test here. + QRectF geom(20.0, 20.0, 20.0, 20.0); + dynamic_cast(policy)->addItemAtGeometry( + widgets[i], geom); + } else + QVERIFY(false); // should never happen + } + qApp->processEvents(); + foreach(QGraphicsWidget * w1, widgets) { + foreach(QGraphicsWidget * w2, widgets) { + if (w1 == w2) + continue; +// qDebug() << "Ut_DuiLayout::testLayoutItemOverlap: policyType, outerLayout, layout, layoutContentsRect, widget1 geometry, widget2 geometry" << policyType << outerLayout->geometry() << layout->geometry() << w1->geometry() << w2->geometry(); +// qDebug() << layout->d_ptr->states.at(layout->indexOf(w1)).targetGeometry(); +// qDebug() << layout->d_ptr->states.at(layout->indexOf(w2)).targetGeometry(); + + QCOMPARE(layout->d_ptr->states.at(layout->indexOf(w1)).targetGeometry(), w1->geometry()); + QCOMPARE(layout->d_ptr->states.at(layout->indexOf(w2)).targetGeometry(), w2->geometry()); + + QVERIFY(! w1->geometry().intersects(w2->geometry())); + } + } + delete(layoutContainer); +} + +void Ut_DuiLayout::testChildItems_data() +{ + QTest::addColumn("addLayoutFirst"); + QTest::addColumn("useQtClass"); + QTest::addColumn("innerLayoutInWidget"); + for (int i = 0; i < 1 << 3; i++) { + bool addLayoutFirst = i & 1; + bool useQtClass = i & (1 << 1); + bool innerLayoutInWidget = i & (1 << 2); + QString description = (useQtClass) ? "Qt Class - " : ""; + description += "Adding layout "; + description += (addLayoutFirst) ? "first" : "last"; + description += (innerLayoutInWidget) ? " (inside widget)" : ""; + QTest::newRow(description.toLatin1()) << addLayoutFirst << useQtClass << innerLayoutInWidget; + } +} + + +void Ut_DuiLayout::testChildItems() +{ + //Check that childItems() and children() are correct + //The Qt class is compared as well, to check that we do the same Qt + QFETCH(bool, addLayoutFirst); + QFETCH(bool, useQtClass); + QFETCH(bool, innerLayoutInWidget); + + QGraphicsWidget *form = new QGraphicsWidget; + QGraphicsLayout *layout = NULL; + DuiLinearLayoutPolicy *policy = NULL; + + QGraphicsWidget *widget1 = new QGraphicsWidget; + QGraphicsWidget *widget2 = new QGraphicsWidget; + + QGraphicsLinearLayout *innerLayout = new QGraphicsLinearLayout(Qt::Horizontal); + QGraphicsWidget *widget3 = new QGraphicsWidget; + innerLayout->addItem(widget3); + + QGraphicsWidget *innerLayoutForm; + if (innerLayoutInWidget) { + innerLayoutForm = new QGraphicsWidget; + innerLayoutForm->setLayout(innerLayout); + } + + if (!useQtClass) { + layout = new DuiLayoutTest(addLayoutFirst ? form : NULL); + policy = new DuiLinearLayoutPolicy(static_cast(layout), Qt::Horizontal); + policy->addItem(widget1); + policy->addItem(widget2); + if (innerLayoutInWidget) + policy->addItem(innerLayoutForm); + else + policy->addItem(innerLayout); + } else { + QGraphicsLinearLayout *gridlayout = new QGraphicsLinearLayout(Qt::Horizontal, addLayoutFirst ? form : NULL); + gridlayout->addItem(widget1); + gridlayout->addItem(widget2); + if (innerLayoutInWidget) + gridlayout->addItem(innerLayoutForm); + else + gridlayout->addItem(innerLayout); + + layout = gridlayout; + } + + QVERIFY(widget1->parent() == NULL); + QVERIFY(widget2->parent() == NULL); + QVERIFY(form->parent() == NULL); + + QVERIFY(widget1->parentItem() == (addLayoutFirst ? form : NULL)); + QVERIFY(widget2->parentItem() == (addLayoutFirst ? form : NULL)); + + if (!addLayoutFirst) + form->setLayout(layout); + + /* Test the QGraphicsItem::childItems() */ + QCOMPARE(form->childItems().count(), 3); + QCOMPARE(form->childItems().at(0), widget1); + QCOMPARE(form->childItems().at(1), widget2); + if (innerLayoutInWidget) { + QCOMPARE(form->childItems().at(2), innerLayoutForm); + QCOMPARE(innerLayoutForm->childItems().count(), 1); + QCOMPARE(innerLayoutForm->childItems().at(0), widget3); + } else { + QCOMPARE(form->childItems().at(2), widget3); + } + QVERIFY(widget1->parent() == NULL); + QVERIFY(widget2->parent() == NULL); + QVERIFY(form->parent() == NULL); + QVERIFY(widget1->parentItem() == form); + QVERIFY(widget2->parentItem() == form); + + /* Test the QObject::children() */ + QCOMPARE(form->children().count(), 0); + if (innerLayoutInWidget) + QCOMPARE(innerLayoutForm->children().count(), 0); +} + +void compareContentsMargins(DuiAbstractLayoutPolicy *policy, qreal _left, qreal _top, qreal _right, qreal _bottom) +{ + qreal left, top, right, bottom; + policy->getContentsMargins(&left, &top, &right, &bottom); + QCOMPARE(left, _left); QCOMPARE(top, _top); QCOMPARE(right, _right); QCOMPARE(bottom, _bottom); +} +void compareContentsMargins(DuiLayout *layout, qreal _left, qreal _top, qreal _right, qreal _bottom) +{ + qreal left, top, right, bottom; + layout->getContentsMargins(&left, &top, &right, &bottom); + QCOMPARE(left, _left); QCOMPARE(top, _top); QCOMPARE(right, _right); QCOMPARE(bottom, _bottom); +} + +void Ut_DuiLayout::testUserChangingValues() +{ + //This is to test for BUG 144705 Items are not visible after they're removed from and readded to a DuiFlowLayoutPolicy + //Which was due to animationDone() being called if the start and end geometries were the saying, even if the visibility was not, + //thus clearing the TO_BE_SHOWN flag + QGraphicsWidget *form = new QGraphicsWidget; + DuiLayout *layout = new DuiLayoutTest(form); + DuiLinearLayoutPolicy *policy = new DuiLinearLayoutPolicy(layout, Qt::Horizontal); + //Set contents margins first, then set object name (to reload style) + policy->setContentsMargins(12, 12, 12, 12); + policy->setHorizontalSpacing(7); + + compareContentsMargins(policy, 12, 12, 12, 12); + compareContentsMargins(layout, 12, 12, 12, 12); + QCOMPARE(policy->horizontalSpacing(), 7.0); + QCOMPARE(policy->verticalSpacing(), 6.0); //From CSS + + policy->setObjectName("packed"); //This should not change the margins since we, the, user specified them manually + compareContentsMargins(policy, 12, 12, 12, 12); + compareContentsMargins(layout, 12, 12, 12, 12); + QCOMPARE(policy->horizontalSpacing(), 7.0); + QCOMPARE(policy->verticalSpacing(), 0.0); // From CSS + + policy->setObjectName(""); + compareContentsMargins(policy, 12, 12, 12, 12); + compareContentsMargins(layout, 12, 12, 12, 12); + QCOMPARE(policy->horizontalSpacing(), 7.0); + QCOMPARE(policy->verticalSpacing(), 6.0); // From CSS + + policy->setVerticalSpacing(6); + QCOMPARE(policy->verticalSpacing(), 6.0); // Now manually set + policy->setObjectName("packed"); + QCOMPARE(policy->verticalSpacing(), 6.0); +} +void Ut_DuiLayout::testAddingAndRemovingWithSpacing() +{ + QGraphicsWidget *form = new QGraphicsWidget; + m_scene->addItem(form); + DuiLayout *layout = new DuiLayoutTest(form); + layout->setContentsMargins(0, 0, 0, 0); + DuiLinearLayoutPolicy *policy = new DuiLinearLayoutPolicy(layout, Qt::Vertical); + policy->setContentsMargins(-1, -1, -1, -1); + policy->setSpacing(6); + + QList widgets; + for (int i = 0; i < 4; i++) { + QGraphicsWidget *widget = new QGraphicsWidget; + widget->setMinimumSize(100, 100); + widget->setPreferredSize(100, 100); + policy->addItem(widget); + widgets << widget; + } + QCOMPARE(form->minimumSize(), QSizeF(100, 400 + 6 * 3)); + QCOMPARE(form->preferredSize(), QSizeF(100, 400 + 6 * 3)); + qApp->processEvents(); + for (int i = 0; i < 4; i++) + QCOMPARE(widgets[i]->isVisible(), true); + + //Remove the first item, and check that the layout shrinks by the size of widget and the vertical spacing + layout->removeAt(0); + QCOMPARE(form->minimumSize(), QSizeF(100, 300 + 6 * 2)); + QCOMPARE(form->preferredSize(), QSizeF(100, 300 + 6 * 2)); + //Now remove them all and readd them + for (int i = 0; i < 4; i++) + layout->removeAt(0); + + QCOMPARE(form->minimumSize(), QSizeF(0, 0)); + QCOMPARE(form->preferredSize(), QSizeF(0, 0)); + + for (int i = 0; i < 4; i++) + policy->addItem(widgets[i]); + + QCOMPARE(form->minimumSize(), QSizeF(100, 400 + 6 * 3)); + QCOMPARE(form->preferredSize(), QSizeF(100, 400 + 6 * 3)); + + //Check that they are visible + qApp->processEvents(); + + while (layout->animation()->isAnimating()) + QTest::qWait(50); + + for (int i = 0; i < 4; i++) + QCOMPARE(widgets[i]->isVisible(), true); + + //Cleanup test + for (int i = 0; i < 4; i++) + delete layout->takeAt(0); + delete form; +} + +void Ut_DuiLayout::testSwitchingPoliciesHidesItems() +{ + QGraphicsWidget *form = new QGraphicsWidget; + m_scene->addItem(form); + DuiLayout *layout = new DuiLayoutTest(form); + DuiFlowLayoutPolicy *policy1 = new DuiFlowLayoutPolicy(layout); + DuiFlowLayoutPolicy *policy2 = new DuiFlowLayoutPolicy(layout); + + QList widgets; + for (int i = 0; i < 4; i++) { + QGraphicsWidget *widget = new QGraphicsWidget; + widget->setMinimumSize(100, 100); + widget->setPreferredSize(100, 100); + if (i < 2) + policy1->addItem(widget); + else + policy2->addItem(widget); + widgets << widget; + } + + qApp->processEvents(); + while (layout->animation()->isAnimating()) + QTest::qWait(50); + + QCOMPARE(widgets[0]->isVisible(), true); + QCOMPARE(widgets[1]->isVisible(), true); + QCOMPARE(widgets[2]->isVisible(), false); + QCOMPARE(widgets[3]->isVisible(), false); + + policy2->activate(); + qApp->processEvents(); + while (layout->animation()->isAnimating()) + QTest::qWait(50); + + QCOMPARE(widgets[0]->isVisible(), false); + QCOMPARE(widgets[1]->isVisible(), false); + QCOMPARE(widgets[2]->isVisible(), true); + QCOMPARE(widgets[3]->isVisible(), true); + + layout->setLandscapePolicy(policy1); + layout->setPortraitPolicy(policy2); + + qApp->processEvents(); + while (layout->animation()->isAnimating()) + QTest::qWait(50); + + QCOMPARE(widgets[0]->isVisible(), true); + QCOMPARE(widgets[1]->isVisible(), true); + QCOMPARE(widgets[2]->isVisible(), false); + QCOMPARE(widgets[3]->isVisible(), false); + + //Rotate, to switch to policy2 + DuiApplication::activeWindow()->setOrientationAngle(Dui::Angle90); + + qApp->processEvents(); + while (layout->animation()->isAnimating()) + QTest::qWait(50); + + QCOMPARE(widgets[0]->isVisible(), false); + QCOMPARE(widgets[1]->isVisible(), false); + QCOMPARE(widgets[2]->isVisible(), true); + QCOMPARE(widgets[3]->isVisible(), true); + + while (!widgets.isEmpty()) + delete widgets.takeAt(0); + delete form; +} + +void Ut_DuiLayout::testSwitchingPoliciesInsidePolicyHidesItems() +{ + //Test a layout with policies inside of another layout with policies. + //Switching policies should show/hide the items correctly. Note that + //currently adding the inner layout to only one outer policy is not supported. + QGraphicsWidget *form = new QGraphicsWidget; + m_scene->addItem(form); + DuiLayout *layout = new DuiLayoutTest(form); + DuiFlowLayoutPolicy *policy1 = new DuiFlowLayoutPolicy(layout); + DuiFlowLayoutPolicy *policy2 = new DuiFlowLayoutPolicy(layout); + + DuiLayout *innerLayout = new DuiLayoutTest; + DuiFlowLayoutPolicy *innerPolicy1 = new DuiFlowLayoutPolicy(innerLayout); + DuiFlowLayoutPolicy *innerPolicy2 = new DuiFlowLayoutPolicy(innerLayout); + + //Add inner layout to both policies. Anything else is not supported :-/ + policy1->addItem(innerLayout); + policy2->addItem(innerLayout); + + QList widgets; + for (int i = 0; i < 4; i++) { + QGraphicsWidget *widget = new QGraphicsWidget; + widget->setMinimumSize(100, 100); + widget->setPreferredSize(100, 100); + if (i < 2) + innerPolicy1->addItem(widget); + else + innerPolicy2->addItem(widget); + widgets << widget; + } + + qApp->processEvents(); + while (layout->animation()->isAnimating() || innerLayout->animation()->isAnimating()) + QTest::qWait(50); + + QCOMPARE(widgets[0]->isVisible(), true); + QCOMPARE(widgets[1]->isVisible(), true); + QCOMPARE(widgets[2]->isVisible(), false); + QCOMPARE(widgets[3]->isVisible(), false); + + innerPolicy2->activate(); + qApp->processEvents(); + while (layout->animation()->isAnimating() || innerLayout->animation()->isAnimating()) + QTest::qWait(50); + + QCOMPARE(widgets[0]->isVisible(), false); + QCOMPARE(widgets[1]->isVisible(), false); + QCOMPARE(widgets[2]->isVisible(), true); + QCOMPARE(widgets[3]->isVisible(), true); + + DuiApplication::activeWindow()->setOrientationAngle(Dui::Angle0); + + innerLayout->setLandscapePolicy(innerPolicy1); + innerLayout->setPortraitPolicy(innerPolicy2); + + qApp->processEvents(); + while (layout->animation()->isAnimating() || innerLayout->animation()->isAnimating()) + QTest::qWait(50); + + QCOMPARE(widgets[0]->isVisible(), true); + QCOMPARE(widgets[1]->isVisible(), true); + QCOMPARE(widgets[2]->isVisible(), false); + QCOMPARE(widgets[3]->isVisible(), false); + + //Rotate, to switch to innerPolicy2 + DuiApplication::activeWindow()->setOrientationAngle(Dui::Angle90); + + qApp->processEvents(); + while (layout->animation()->isAnimating() || innerLayout->animation()->isAnimating()) + QTest::qWait(50); + + QCOMPARE(widgets[0]->isVisible(), false); + QCOMPARE(widgets[1]->isVisible(), false); + QCOMPARE(widgets[2]->isVisible(), true); + QCOMPARE(widgets[3]->isVisible(), true); + + //Switch the outer layout policy. This shouldn't affect the inner one's item's visibility + policy2->activate(); + QCOMPARE(widgets[0]->isVisible(), false); + QCOMPARE(widgets[1]->isVisible(), false); + QCOMPARE(widgets[2]->isVisible(), true); + QCOMPARE(widgets[3]->isVisible(), true); + + qApp->processEvents(); + while (layout->animation()->isAnimating() || innerLayout->animation()->isAnimating()) + QTest::qWait(50); + + QCOMPARE(widgets[0]->isVisible(), false); + QCOMPARE(widgets[1]->isVisible(), false); + QCOMPARE(widgets[2]->isVisible(), true); + QCOMPARE(widgets[3]->isVisible(), true); + + while (!widgets.isEmpty()) + delete widgets.takeAt(0); + delete form; +} + +void Ut_DuiLayout::testAddingRemovingAddingToPolicy() +{ + //Add an item to a policy, then remove it, then readd it. It should be visible at the end + QGraphicsWidget *form = new QGraphicsWidget; + m_scene->addItem(form); + DuiLayout *layout = new DuiLayoutTest(form); + DuiFlowLayoutPolicy *policy = new DuiFlowLayoutPolicy(layout); + QGraphicsWidget *widget = new QGraphicsWidget; + policy->addItem(widget); + qApp->processEvents(); + + QCOMPARE(widget->isVisible(), true); + + policy->removeItem(widget); + policy->addItem(widget); + qApp->processEvents(); + QCOMPARE(widget->isVisible(), true); + while (layout->animation()->isAnimating()) + QTest::qWait(50); + + QCOMPARE(widget->isVisible(), true); +} + +void Ut_DuiLayout::testExplicitlyHidingItems_data() +{ + QTest::addColumn("withAnimation"); + QTest::newRow("Without Animation") << false; + QTest::newRow("With Animation") << true; +} +void Ut_DuiLayout::testExplicitlyHidingItems() +{ + /* Test calling widget->hide() on a widget and check that it remains hidden even when switching between policies. + * Also test widget->show() on a widget and check that it only shows if not hidden by the layout. + * Note that this only works for a DuiWidget */ + + QFETCH(bool, withAnimation); + + QGraphicsWidget *form = new QGraphicsWidget; + m_scene->addItem(form); + DuiLayout *layout = new DuiLayoutTest(form); + if (!withAnimation) + layout->setAnimation(NULL); + DuiFlowLayoutPolicy *flowPolicy = new DuiFlowLayoutPolicy(layout); + DuiLinearLayoutPolicy *linearPolicy = new DuiLinearLayoutPolicy(layout, Qt::Horizontal); + DuiGridLayoutPolicy *gridPolicy = new DuiGridLayoutPolicy(layout); + + DuiWidget *widget = new DuiWidget; + widget->hide(); //Explicitly hide it + flowPolicy->addItem(widget); + linearPolicy->addItem(widget); + // we do not add it to the grid layout policy + + //It's currently in a visible policy but explicitly hidden. + QCOMPARE(widget->isVisible(), false); + qApp->processEvents(); + QCOMPARE(widget->isVisible(), false); + while (withAnimation && layout->animation()->isAnimating()) + QTest::qWait(50); + QCOMPARE(widget->isVisible(), false); + //Check that switching policies to a policy containing the item does not make it show + linearPolicy->activate(); + qApp->processEvents(); + QCOMPARE(widget->isVisible(), false); + //Check that switching policies to a policy not containing the item does not make it show + gridPolicy->activate(); + qApp->processEvents(); + QCOMPARE(widget->isVisible(), false); + //Check that switching back to a policy containing the item does not make it show + flowPolicy->activate(); + qApp->processEvents(); + QCOMPARE(widget->isVisible(), false); + + //Now show it explicitly again, it should show in the flow and linear, but not grid + widget->show(); + QCOMPARE(widget->isVisible(), true); + linearPolicy->activate(); + qApp->processEvents(); + while (withAnimation && layout->animation()->isAnimating()) + QTest::qWait(50); + QCOMPARE(widget->isVisible(), true); + QCOMPARE(widget->opacity(), qreal(1.0)); + gridPolicy->activate(); + qApp->processEvents(); + while (withAnimation && layout->animation()->isAnimating()) + QTest::qWait(50); + QCOMPARE(widget->isVisible(), false); + // Now test hiding, while the object is currently hiding + widget->hide(); + QCOMPARE(widget->isVisible(), false); + linearPolicy->activate(); + QCOMPARE(widget->isVisible(), false); + qApp->processEvents(); + QCOMPARE(widget->isVisible(), false); + gridPolicy->activate(); + QCOMPARE(widget->isVisible(), false); + qApp->processEvents(); + QCOMPARE(widget->isVisible(), false); + // And now test showing again, while the object is in a policy not showing it + widget->show(); + QCOMPARE(widget->isVisible(), false); + linearPolicy->activate(); + qApp->processEvents(); + QCOMPARE(widget->isVisible(), true); + while (withAnimation && layout->animation()->isAnimating()) + QTest::qWait(50); + QCOMPARE(widget->isVisible(), true); + QCOMPARE(widget->opacity(), qreal(1.0)); + + // Switch to a policy without the item and remove it. It should be still visible + layout->removeItem(widget); + QCOMPARE(widget->isVisible(), true); + QCOMPARE(widget->opacity(), qreal(1.0)); + + // Readd - linear is currently activated + flowPolicy->addItem(widget); + qApp->processEvents(); + QCOMPARE(widget->isVisible(), false); + linearPolicy->addItem(widget); + qApp->processEvents(); + QCOMPARE(widget->isVisible(), true); + while (withAnimation && layout->animation()->isAnimating()) + QTest::qWait(50); + QCOMPARE(widget->isVisible(), true); + QCOMPARE(widget->opacity(), qreal(1.0)); + + //Remove from current policy (linear), forcing it to hide + linearPolicy->removeItem(widget); + qApp->processEvents(); + while (withAnimation && layout->animation()->isAnimating()) + QTest::qWait(50); + QCOMPARE(widget->isVisible(), false); + QCOMPARE(widget->opacity(), qreal(1.0)); + +} + +QTEST_APPLESS_MAIN(Ut_DuiLayout) diff --git a/tests/ut_duilayout/ut_duilayout.css b/tests/ut_duilayout/ut_duilayout.css new file mode 100644 index 000000000..16c093cd9 --- /dev/null +++ b/tests/ut_duilayout/ut_duilayout.css @@ -0,0 +1,70 @@ +DuiLayoutStyle { + margin-left: 0.0; + margin-top: 0.0; + margin-right: 0.0; + margin-bottom: 0.0; +} +DuiAbstractLayoutPolicyStyle { + margin-left: -1.0; + margin-top: -1.0; + margin-right: -1.0; + margin-bottom: -1.0; + vertical-spacing: 6.0; + horizontal-spacing: 7.0; +} +DuiAbstractLayoutPolicyStyle#packed { + margin-left: -1.0; + margin-top: 0.0; + margin-right: 0.0; + margin-bottom: 0.0; + vertical-spacing: 0.0; + horizontal-spacing: 0.0; +} +DuiAbstractLayoutPolicyStyle#spacing { + margin-left: -1.0; + margin-top: 0.0; + margin-right: 0.0; + margin-bottom: 0.0; + vertical-spacing: 10.0; + horizontal-spacing: 11.0; +} +DuiAbstractLayoutPolicyStyle#margins { + margin-left: 10.0; + margin-top: 10.0; + margin-right: -1.0; + margin-bottom: 10.0; + vertical-spacing: 0.0; + horizontal-spacing: 0.0; +} +DuiAbstractLayoutPolicyStyle#spacing+margins { + margin-left: 10.0; + margin-top: -1.0; + margin-right: 10.0; + margin-bottom: 10.0; + vertical-spacing: 10.0; + horizontal-spacing: 11.0; +} + +DuiAbstractLayoutPolicyStyle.Portrait { + margin-left: 4.0; + margin-top: 5.0; + margin-right: 2.0; + margin-bottom: 6.0; + vertical-spacing: 2.0; + horizontal-spacing: 3.0; +} +DuiAbstractLayoutPolicyStyle#packed.Portrait { + margin-left: 1; + margin-top: 2; + margin-right: 3; + margin-bottom: 4; + vertical-spacing: 5; + horizontal-spacing: 6; +} + +/* For testing, keep the easing curves simple and the duration very short */ +DuiBasicLayoutAnimationStyle { + geometry-easing-curve: linear; + opacity-easing-curve: linear; + duration: 40; +} diff --git a/tests/ut_duilayout/ut_duilayout.h b/tests/ut_duilayout/ut_duilayout.h new file mode 100644 index 000000000..b46c2ae16 --- /dev/null +++ b/tests/ut_duilayout/ut_duilayout.h @@ -0,0 +1,109 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUILAYOUT_H +#define UT_DUILAYOUT_H + +#include +#include + +#include + +class QGraphicsScene; +class QGraphicsProxyWidget; +class QPushButton; + +class Ut_DuiLayout : public QObject +{ + Q_OBJECT + +public: + Ut_DuiLayout(); + virtual ~Ut_DuiLayout(); + +private slots: + void cleanupTestCase(); + void init(); + void cleanup(); + + void itemState(); + void testTakeAt(); + void testDeletingItem(); + void policyInteraction(); + void animationInteraction(); + void testDeletingLayout(); + void testRemoveItemFromLayout(); + void testEmptyAnimation(); + void testRemovingItemWithAnimation(); + void testReorderingItemsWithoutAnimation(); + void testReorderingItemsWithAnimation(); + void testReorderingItemsWithAnimationWithMultiplePolicies(); + void testDeletingItemWithAnimation(); + void testDeletingLayoutDuringAnimation(); + void testDeletingLayoutDuringAnimationWithMultiplyPolicies(); + void testDeletingThenHiding(); + void testDuiLabelOnLayout(); + void testHidingShowingWidgets_data(); + void testHidingShowingWidgets(); + void testLayoutInsideLayout_data(); + void testLayoutInsideLayout(); + void testReparenting(); + void testReparentingWithPreviousParent(); + void testLinearPolicyChangingOrientation_data(); + void testLinearPolicyChangingOrientation(); + void testGridLayoutShaking(); + void testGridLayoutShaking_data(); + void testLayoutBoundingBox_data(); + void testLayoutBoundingBox(); + void testBasicAnimationWithLayoutInsideLayout(); + void testBasicAnimationWithLayoutInsideLayout2_data(); + void testBasicAnimationWithLayoutInsideLayout2(); + void testQGraphicsLinearLayoutWithLayoutInsideLayout2(); + void testLayoutAddItemWithTwoPolicies_data(); + void testLayoutAddItemWithTwoPolicies(); + void testLayoutRemoveItemWithTwoPolicies_data(); + void testLayoutRemoveItemWithTwoPolicies(); + void testForCrash(); + void testLayoutItemPositionRestoreWhenSwitchingPolicies_data(); + void testLayoutItemPositionRestoreWhenSwitchingPolicies(); + void testLayoutGeometryOfItemsAddedToInactivePolicies_data(); + void testLayoutGeometryOfItemsAddedToInactivePolicies(); + void testLayoutItemOverlap_data(); + void testLayoutItemOverlap(); + void testLayoutPolicyStyling_data(); + void testLayoutPolicyStyling(); + void testChildItems_data(); + void testChildItems(); + void testUserChangingValues(); + void testLayoutSwitchingWithOrientation(); + void testAddingAndRemovingWithSpacing(); + void testLinearPolicyChangingOrientationBasic(); + void testSwitchingPoliciesHidesItems(); + void testSwitchingPoliciesInsidePolicyHidesItems(); + void testAddingRemovingAddingToPolicy(); + void testExplicitlyHidingItems_data(); + void testExplicitlyHidingItems(); +private: + QPushButton *m_button; + QGraphicsScene *m_scene; + QGraphicsProxyWidget *m_proxy; +}; + +#endif // Header guard + diff --git a/tests/ut_duilayout/ut_duilayout.pro b/tests/ut_duilayout/ut_duilayout.pro new file mode 100644 index 000000000..f4de44c99 --- /dev/null +++ b/tests/ut_duilayout/ut_duilayout.pro @@ -0,0 +1,15 @@ +include(../common_top.pri) +TARGET = ut_duilayout + +# unit test and unit +SOURCES += \ + ut_duilayout.cpp \ + +# unit test and unit +HEADERS += \ + ut_duilayout.h + +support_files.files += \ + ut_duilayout.css + +include(../common_bot.pri) diff --git a/tests/ut_duilinearlayoutpolicy/.gitignore b/tests/ut_duilinearlayoutpolicy/.gitignore new file mode 100644 index 000000000..c107fab6f --- /dev/null +++ b/tests/ut_duilinearlayoutpolicy/.gitignore @@ -0,0 +1 @@ +ut_duilinearlayoutpolicy diff --git a/tests/ut_duilinearlayoutpolicy/ut_duilinearlayoutpolicy.cpp b/tests/ut_duilinearlayoutpolicy/ut_duilinearlayoutpolicy.cpp new file mode 100644 index 000000000..91b515554 --- /dev/null +++ b/tests/ut_duilinearlayoutpolicy/ut_duilinearlayoutpolicy.cpp @@ -0,0 +1,334 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duilinearlayoutpolicy.h" + +#include +#include +#include + +#include +#include + +/** + MockLayoutItem objects are layed out with the layout policy to test. + MockLayoutItems are then investigated for the correct geometry values + assigned by the test layout. +*/ +class MockLayoutItem : public QGraphicsLayoutItem +{ +protected: + QSizeF sizeHint(Qt::SizeHint , const QSizeF &) const { + return QSize(-1, -1); + } +}; + + +Ut_DuiLinearLayoutPolicy::Ut_DuiLinearLayoutPolicy() + : m_mockLayout(0) + , m_policy(0) + , m_mockItem100(0) + , m_mockItem200(0) + , m_mockItem300(0) + , m_mockItem400(0) +{ } + +Ut_DuiLinearLayoutPolicy::~Ut_DuiLinearLayoutPolicy() +{ } + +DuiApplication *app; +void Ut_DuiLinearLayoutPolicy::initTestCase() +{ + static int argc = 1; + static char *argv[1] = { (char *) "./ut_duilinearlayoutpolicy" }; + app = new DuiApplication(argc, argv); + app->setLayoutDirection(Qt::LeftToRight); +} + +void Ut_DuiLinearLayoutPolicy::cleanupTestCase() +{ + delete app; +} + +void Ut_DuiLinearLayoutPolicy::init() +{ + Q_ASSERT(0 == m_mockLayout); + Q_ASSERT(0 == m_policy); + + m_form = new QGraphicsWidget; + m_mockLayout = new DuiLayout(m_form); + m_policy = new DuiLinearLayoutPolicy(m_mockLayout, Qt::Horizontal); + m_policy->setSpacing(0); + m_mockLayout->setContentsMargins(0, 0, 0, 0); + + // set up some mock items + Q_ASSERT(0 == m_mockItem100); + m_mockItem100 = new MockLayoutItem; + m_mockItem100->setMinimumSize(100.0, 100.0); + m_mockItem100->setPreferredSize(100.0, 100.0); + m_mockItem100->setMaximumSize(100.0, 100.0); + + Q_ASSERT(0 == m_mockItem200); + m_mockItem200 = new MockLayoutItem; + m_mockItem200->setMinimumSize(200.0, 200.0); + m_mockItem200->setPreferredSize(200.0, 200.0); + m_mockItem200->setMaximumSize(200.0, 200.0); + + Q_ASSERT(0 == m_mockItem300); + m_mockItem300 = new MockLayoutItem; + m_mockItem300->setMinimumSize(300.0, 300.0); + m_mockItem300->setPreferredSize(300.0, 300.0); + m_mockItem300->setMaximumSize(300.0, 300.0); + + Q_ASSERT(0 == m_mockItem400); + m_mockItem400 = new MockLayoutItem; + m_mockItem400->setMinimumSize(400.0, 400.0); + m_mockItem400->setPreferredSize(400.0, 400.0); + m_mockItem400->setMaximumSize(400.0, 400.0); + + m_mockLayout->setAnimation(0); // turn off animation +} + +void Ut_DuiLinearLayoutPolicy::cleanup() +{ + Q_ASSERT(0 != m_mockItem100); + m_mockLayout->removeItem(m_mockItem100); + m_mockItem100 = 0; + + Q_ASSERT(0 != m_mockItem200); + m_mockLayout->removeItem(m_mockItem200); + m_mockItem200 = 0; + + Q_ASSERT(0 != m_mockItem300); + m_mockLayout->removeItem(m_mockItem300); + m_mockItem300 = 0; + + Q_ASSERT(0 != m_mockItem400); + m_mockLayout->removeItem(m_mockItem400); + m_mockItem400 = 0; + + Q_ASSERT(0 != m_policy); + delete m_policy; + m_policy = 0; + + Q_ASSERT(0 != m_mockLayout); + delete m_form; //should delete layout too + m_mockLayout = 0; + m_form = 0; +} + +void Ut_DuiLinearLayoutPolicy::testSpacing() +{ + // general spacing + qreal general_spacing = 12.0; + m_policy->setSpacing(general_spacing); + m_policy->addItem(m_mockItem100); + m_policy->addItem(m_mockItem200); + m_policy->addItem(m_mockItem300); + m_policy->addItem(m_mockItem400); + m_policy->setOrientation(Qt::Horizontal); + m_mockLayout->activate(); + qApp->processEvents(); //let relayout happen + + QCOMPARE(m_form->geometry(), QRectF(0, 0, 100 + 200 + 300 + 400 + 3 * general_spacing, 400)); + QCOMPARE(m_mockLayout->geometry(), QRectF(0, 0, 100 + 200 + 300 + 400 + 3 * general_spacing, 400)); + + // items moved to the correct place? + QCOMPARE(m_mockItem100->geometry(), QRectF(QPointF(0.0, 0.0), QSize(100.0, 100.0))); + QCOMPARE(m_mockItem200->geometry(), QRectF(QPointF(100 + general_spacing, 0), + QSizeF(200.0, 200.0))); + QCOMPARE(m_mockItem300->geometry(), QRectF(QPointF(100 + 200 + 2 * general_spacing, 0), + QSizeF(300.0, 300.0))); + QCOMPARE(m_mockItem400->geometry(), QRectF(QPointF(100 + 200 + 300 + 3 * general_spacing, 0), + QSizeF(400.0, 400.0))); + + //Since we are horizontal, vertical spacing should do nothing + m_policy->setVerticalSpacing(17); //trigger a relayout + qApp->processEvents(); //let relayout happen + + //we should have no change + QCOMPARE(m_mockItem100->geometry(), QRectF(QPointF(0.0, 0.0), QSize(100.0, 100.0))); + QCOMPARE(m_mockItem200->geometry(), QRectF(QPointF(100 + general_spacing, 0), + QSizeF(200.0, 200.0))); + QCOMPARE(m_mockItem300->geometry(), QRectF(QPointF(100 + 200 + 2 * general_spacing, 0), + QSizeF(300.0, 300.0))); + QCOMPARE(m_mockItem400->geometry(), QRectF(QPointF(100 + 200 + 300 + 3 * general_spacing, 0), + QSizeF(400.0, 400.0))); + + general_spacing = 0; + m_policy->setHorizontalSpacing(general_spacing); //trigger a relayout + qApp->processEvents(); //let relayout happen + //set horizontal spacing to 0 - this should change the spacing + QCOMPARE(m_mockItem100->geometry(), QRectF(QPointF(0.0, 0.0), QSize(100.0, 100.0))); + QCOMPARE(m_mockItem200->geometry(), QRectF(QPointF(100 + general_spacing, 0), + QSizeF(200.0, 200.0))); + QCOMPARE(m_mockItem300->geometry(), QRectF(QPointF(100 + 200 + 2 * general_spacing, 0), + QSizeF(300.0, 300.0))); + QCOMPARE(m_mockItem400->geometry(), QRectF(QPointF(100 + 200 + 300 + 3 * general_spacing, 0), + QSizeF(400.0, 400.0))); + + //now switch to vertical orientation. It should now follow the vertical spacing of 17 + general_spacing = 17; + m_policy->setOrientation(Qt::Vertical); + qApp->processEvents(); //let relayout happen + QCOMPARE(m_mockItem100->geometry(), QRectF(QPointF(0.0, 0.0), QSize(100.0, 100.0))); + QCOMPARE(m_mockItem200->geometry(), QRectF(QPointF(0, 100 + general_spacing), + QSizeF(200.0, 200.0))); + QCOMPARE(m_mockItem300->geometry(), QRectF(QPointF(0, 100 + 200 + 2 * general_spacing), + QSizeF(300.0, 300.0))); + QCOMPARE(m_mockItem400->geometry(), QRectF(QPointF(0, 100 + 200 + 300 + 3 * general_spacing), + QSizeF(400.0, 400.0))); +} + +void Ut_DuiLinearLayoutPolicy::testStretch_data() +{ + //Run the test one with QGraphicsLinearLayout to check that the test itself is + //correct, then again with libdui to check DuiLinearLayoutPolicy is correct + QTest::addColumn("useQt"); + QTest::newRow("QGraphicsLinearLayout") << true; + QTest::newRow("DuiLinearLayoutPolicy") << false; +} +void Ut_DuiLinearLayoutPolicy::testStretch() +{ + QFETCH(bool, useQt); + QGraphicsLinearLayout *qt_layout; + QGraphicsWidget *form; + if (useQt) { + form = new QGraphicsWidget; + form->setMinimumSize(600, 600); + form->setMaximumSize(600, 600); + qt_layout = new QGraphicsLinearLayout(Qt::Horizontal, form); + qt_layout->setSpacing(0); + qt_layout->setContentsMargins(0, 0, 0, 0); + } else { + m_form->setMinimumSize(600, 600); + m_form->setMaximumSize(600, 600); + m_form->setContentsMargins(0, 0, 0, 0); + m_mockLayout->setContentsMargins(0, 0, 0, 0); + m_policy->setSpacing(0); + } + + if (useQt) { + qt_layout->addItem(m_mockItem100); + qt_layout->addStretch(2); + qt_layout->addItem(m_mockItem200); + QCOMPARE(qt_layout->count(), 2); + QVERIFY(qt_layout->itemAt(0) == m_mockItem100); + QVERIFY(qt_layout->itemAt(1) == m_mockItem200); + } else { + m_policy->addItem(m_mockItem100); + m_policy->addStretch(2); + m_policy->addItem(m_mockItem200); + QCOMPARE(m_policy->count(), 2); + QVERIFY(m_policy->itemAt(0) == m_mockItem100); + QVERIFY(m_policy->itemAt(1) == m_mockItem200); + } + if (useQt) + qt_layout->activate(); + else + m_mockLayout->activate(); + + QCOMPARE(m_mockItem100->geometry(), QRectF(0, 0, 100, 100)); + QCOMPARE(m_mockItem200->geometry(), QRectF(400, 0, 200, 200)); + + //Add a third item and check that it does go at the end + if (useQt) { + qt_layout->insertItem(2, m_mockItem300); + QVERIFY(qt_layout->itemAt(0) == m_mockItem100); + QVERIFY(qt_layout->itemAt(1) == m_mockItem200); + QVERIFY(qt_layout->itemAt(2) == m_mockItem300); + } else { + m_policy->insertItem(2, m_mockItem300); + QVERIFY(m_policy->itemAt(0) == m_mockItem100); + QVERIFY(m_policy->itemAt(1) == m_mockItem200); + QVERIFY(m_policy->itemAt(2) == m_mockItem300); + } + + //Add a bunch of stretches + if (useQt) { + qt_layout->insertStretch(2); + qt_layout->insertStretch(2); + qt_layout->insertStretch(2); + } else { + m_policy->insertStretch(2); + m_policy->insertStretch(2); + m_policy->insertStretch(2); + } + + //Even though we have a bunch of stretches, adding an item to position 3 should place + //the new item after the mock item at 2 + if (useQt) { + qt_layout->insertItem(3, m_mockItem400); + QVERIFY(qt_layout->itemAt(0) == m_mockItem100); + QVERIFY(qt_layout->itemAt(1) == m_mockItem200); + QVERIFY(qt_layout->itemAt(2) == m_mockItem300); + QVERIFY(qt_layout->itemAt(3) == m_mockItem400); + } else { + m_policy->insertItem(3, m_mockItem400); + QVERIFY(m_policy->itemAt(0) == m_mockItem100); + QVERIFY(m_policy->itemAt(1) == m_mockItem200); + QVERIFY(m_policy->itemAt(2) == m_mockItem300); + QVERIFY(m_policy->itemAt(3) == m_mockItem400); + } + + if (useQt) { + qt_layout->removeItem(m_mockItem200); + qt_layout->insertItem(-1, m_mockItem200); + } else { + m_policy->removeItem(m_mockItem200); + m_policy->insertItem(-1, m_mockItem200); + } +} + +void Ut_DuiLinearLayoutPolicy::testInsertingItems() +{ + m_form->setGeometry(0, 0, 700, 100); //4 items of size 100, plus 3 spacers that should become size 100 + QList widgets; + for (int i = 0; i < 4; i++) { + QGraphicsLayoutItem *widget = new MockLayoutItem; + widgets << widget; + m_policy->addItem(widget); + } + QList spacers; + //Now add some spacer widgets + for (int i = 0; i < 3; i++) { + QGraphicsLayoutItem *spacer = new MockLayoutItem; + spacers << spacer; + + int index = (i << 1) + 1; + QCOMPARE(m_policy->itemAt(index - 1), widgets.at(i)); + QCOMPARE(m_policy->itemAt(index), widgets.at(i + 1)); + m_policy->insertItem(index, spacer); + QCOMPARE(m_policy->count(), 5 + i); + QCOMPARE(m_policy->itemAt(index - 1), widgets.at(i)); + QCOMPARE(m_policy->itemAt(index), spacer); + QCOMPARE(m_policy->itemAt(index + 1), widgets.at(i + 1)); + } + + QCOMPARE(m_policy->itemAt(0), widgets.at(0)); + QCOMPARE(m_policy->itemAt(1), spacers.at(0)); + QCOMPARE(m_policy->itemAt(2), widgets.at(1)); + QCOMPARE(m_policy->itemAt(3), spacers.at(1)); + QCOMPARE(m_policy->itemAt(4), widgets.at(2)); + QCOMPARE(m_policy->itemAt(5), spacers.at(2)); + QCOMPARE(m_policy->itemAt(6), widgets.at(3)); + +} + +QTEST_APPLESS_MAIN(Ut_DuiLinearLayoutPolicy) diff --git a/tests/ut_duilinearlayoutpolicy/ut_duilinearlayoutpolicy.h b/tests/ut_duilinearlayoutpolicy/ut_duilinearlayoutpolicy.h new file mode 100644 index 000000000..a6e48ed7f --- /dev/null +++ b/tests/ut_duilinearlayoutpolicy/ut_duilinearlayoutpolicy.h @@ -0,0 +1,61 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUILINEARLAYOUTPOLICY_H +#define UT_DUILINEARLAYOUTPOLICY_H + +#include +#include + +class QGraphicsLayoutItem; +class QGraphicsWidget; +class DuiLayout; +class DuiLinearLayoutPolicy; + +class Ut_DuiLinearLayoutPolicy : public QObject +{ + Q_OBJECT + +public: + Ut_DuiLinearLayoutPolicy(); + virtual ~Ut_DuiLinearLayoutPolicy(); + +private slots: + void initTestCase(); + void cleanupTestCase(); + + void testStretch_data(); + void testStretch(); + void testSpacing(); + void testInsertingItems(); + + void init(); + void cleanup(); +private: + + DuiLayout *m_mockLayout; + DuiLinearLayoutPolicy *m_policy; + QGraphicsLayoutItem *m_mockItem100; + QGraphicsLayoutItem *m_mockItem200; + QGraphicsLayoutItem *m_mockItem300; + QGraphicsLayoutItem *m_mockItem400; + QGraphicsWidget *m_form; +}; + +#endif // Header guard diff --git a/tests/ut_duilinearlayoutpolicy/ut_duilinearlayoutpolicy.pro b/tests/ut_duilinearlayoutpolicy/ut_duilinearlayoutpolicy.pro new file mode 100644 index 000000000..38d557ee3 --- /dev/null +++ b/tests/ut_duilinearlayoutpolicy/ut_duilinearlayoutpolicy.pro @@ -0,0 +1,12 @@ +include(../common_top.pri) +TARGET = ut_duilinearlayoutpolicy + +# unit test and unit +SOURCES += \ + ut_duilinearlayoutpolicy.cpp \ + +# unit test and unit +HEADERS += \ + ut_duilinearlayoutpolicy.h \ + +include(../common_bot.pri) diff --git a/tests/ut_duilogicalvalues/.gitignore b/tests/ut_duilogicalvalues/.gitignore new file mode 100644 index 000000000..e362dae90 --- /dev/null +++ b/tests/ut_duilogicalvalues/.gitignore @@ -0,0 +1 @@ +ut_duilogicalvalues diff --git a/tests/ut_duilogicalvalues/test.ini b/tests/ut_duilogicalvalues/test.ini new file mode 100644 index 000000000..bca49372b --- /dev/null +++ b/tests/ut_duilogicalvalues/test.ini @@ -0,0 +1,8 @@ +[Palette] +COLOR_DEFAULT = #000000 +COLOR_OVERRIDDEN = #00000000 + +[Fonts] +FONT_DEFAULT = "Arial" 20px +FONT_OVERRIDDEN = "Arial" 50px + diff --git a/tests/ut_duilogicalvalues/test2.ini b/tests/ut_duilogicalvalues/test2.ini new file mode 100644 index 000000000..801ae7d76 --- /dev/null +++ b/tests/ut_duilogicalvalues/test2.ini @@ -0,0 +1,12 @@ +[Palette] +COLOR_OVERRIDDEN = #ffffff +COLOR_ADDED = #00ff00 + +[Fonts] +; this is a test comment for parser +FONT_OVERRIDDEN = "Arial" 100px; this is overridden from test1.ini + FONT_ADDED = "Arial" 10px ;this is not defined in test1.ini, so it's added in here +;FONT_DEFAULT = "Arial" 40px + +[Misc] ;this is another test comment + ;yet another test comment diff --git a/tests/ut_duilogicalvalues/ut_duilogicalvalues.cpp b/tests/ut_duilogicalvalues/ut_duilogicalvalues.cpp new file mode 100644 index 000000000..7e5ff4426 --- /dev/null +++ b/tests/ut_duilogicalvalues/ut_duilogicalvalues.cpp @@ -0,0 +1,59 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include +#include "ut_duilogicalvalues.h" + +Ut_DuiLogicalValues::Ut_DuiLogicalValues() +{ +} + +void Ut_DuiLogicalValues::init() +{ + m_subject = new DuiLogicalValues(); +} + +void Ut_DuiLogicalValues::cleanup() +{ + delete m_subject; +} + +void Ut_DuiLogicalValues::testFontsAndColors() +{ + QCOMPARE(m_subject->append(qApp->applicationDirPath() + QDir::separator() + "test2.ini"), true); + QCOMPARE(m_subject->append(qApp->applicationDirPath() + QDir::separator() + "test.ini"), true); + + QCOMPARE(m_subject->color("Palette", "COLOR_DEFAULT"), QColor("#000000")); + QCOMPARE(m_subject->color("Palette", "COLOR_OVERRIDDEN"), QColor("#ffffff")); + QCOMPARE(m_subject->color("Palette", "COLOR_ADDED"), QColor("#00ff00")); + + QFont FontArial20px("Arial"), FontArial100px("Arial"), FontArial10px("Arial"); + FontArial20px.setPixelSize(20); + FontArial100px.setPixelSize(100); + FontArial10px.setPixelSize(10); + + QCOMPARE(m_subject->font("Fonts", "FONT_DEFAULT"), FontArial20px); + QCOMPARE(m_subject->font("Fonts", "FONT_OVERRIDDEN"), FontArial100px); + QCOMPARE(m_subject->font("Fonts", "FONT_ADDED"), FontArial10px); +} + +QTEST_MAIN(Ut_DuiLogicalValues) + diff --git a/tests/ut_duilogicalvalues/ut_duilogicalvalues.h b/tests/ut_duilogicalvalues/ut_duilogicalvalues.h new file mode 100644 index 000000000..5312cebe9 --- /dev/null +++ b/tests/ut_duilogicalvalues/ut_duilogicalvalues.h @@ -0,0 +1,44 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUILOGICALVALUES_H +#define UT_DUILOGICALVALUES_H + +#include +#include "../../src/theme/duilogicalvalues.h" + +class Ut_DuiLogicalValues : public QObject +{ + Q_OBJECT +public: + Ut_DuiLogicalValues(); + +private slots: + void init(); + void cleanup(); + + void testFontsAndColors(); + +private: + + DuiLogicalValues *m_subject; +}; + +#endif + diff --git a/tests/ut_duilogicalvalues/ut_duilogicalvalues.pro b/tests/ut_duilogicalvalues/ut_duilogicalvalues.pro new file mode 100644 index 000000000..65bb81d57 --- /dev/null +++ b/tests/ut_duilogicalvalues/ut_duilogicalvalues.pro @@ -0,0 +1,19 @@ +include(../common_top.pri) +TARGET = ut_duilogicalvalues +QT += dbus svg network +LIBRARYPATH += $$DUISRCDIR + +SOURCES += \ + ut_duilogicalvalues.cpp \ + ../../src/theme/duilogicalvalues.cpp \ + ../../src/style/duistylesheetattribute.cpp + +HEADERS += \ + ut_duilogicalvalues.h \ + ../../src/theme/duilogicalvalues.h \ + ../../src/theme/duilogicalvalues_p.h \ + ../../src/style/duistylesheetattribute.h + +support_files.files += *.ini + +include(../common_bot.pri) diff --git a/tests/ut_duimashupcanvas/.gitignore b/tests/ut_duimashupcanvas/.gitignore new file mode 100644 index 000000000..ff3e5a0fa --- /dev/null +++ b/tests/ut_duimashupcanvas/.gitignore @@ -0,0 +1 @@ +ut_duimashupcanvas diff --git a/tests/ut_duimashupcanvas/ut_duimashupcanvas.cpp b/tests/ut_duimashupcanvas/ut_duimashupcanvas.cpp new file mode 100644 index 000000000..96dd49a48 --- /dev/null +++ b/tests/ut_duimashupcanvas/ut_duimashupcanvas.cpp @@ -0,0 +1,204 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duimashupcanvas.h" +#include "duimashupcanvas.h" +#include "duiapplication.h" +#include "duicomponentdata.h" +#include "duiappletinstancemanager_stub.h" +#include "duiappletid_stub.h" +#include "duiobjectmenu_stub.h" +#include "mockdatastore.h" + +#include + +#include +DUI_REGISTER_WIDGET(TestMashupCanvas); + +// TestMashupCanvas +class TestMashupCanvas : public DuiMashupCanvas +{ +public: + TestMashupCanvas() : DuiMashupCanvas("testcanvas") {} + void addWidget(DuiWidget *widget, DuiDataStore &store) { + DuiMashupCanvas::addWidget(widget, store); + } + void removeWidget(DuiWidget *widget) { + DuiMashupCanvas::removeWidget(widget); + } +}; + +// DuiComponentData stubs +QString gDuiComponentDataServiceName = "com.nokia.testapp"; +QString DuiComponentData::serviceName() +{ + return gDuiComponentDataServiceName; +} + +// The test class +void Ut_DuiMashupCanvas::init() +{ + canvas = new TestMashupCanvas(); + view = new TestMashupCanvasView(canvas); + canvas->setView(view); + gDuiAppletInstanceManagerStub->stubReset(); +} + +void Ut_DuiMashupCanvas::cleanup() +{ + // Destroy the mashup canvas. + delete canvas; +} + +void Ut_DuiMashupCanvas::initTestCase() +{ + // DuiApplications must be created manually due to theme system changes + static int argc = 1; + static char *app_name[1] = { (char *)"./ut_duimashupcanvas" }; + app = new DuiApplication(argc, app_name); +} + +void Ut_DuiMashupCanvas::cleanupTestCase() +{ + // this is commented out for now, to prevent crash at exit: + // delete app; +} + +void Ut_DuiMashupCanvas::testAddition() +{ + QSignalSpy spy(canvas->model(), SIGNAL(modified(QList))); + + DuiWidget *widget1 = new DuiWidget; + MockDataStore store1; + DuiWidget *widget2 = new DuiWidget; + MockDataStore store2; + + // Add one widget and ensure that the model was modified. + canvas->addWidget(widget1, store1); + QCOMPARE(spy.count(), 1); + QCOMPARE(canvas->model()->dataStores()->keys().count(), 1); + QVERIFY(canvas->model()->dataStores()->contains(widget1)); + spy.clear(); + + // Add another widget. Ensure that both widgets are in the model. + canvas->addWidget(widget2, store2); + QCOMPARE(spy.count(), 1); + QCOMPARE(canvas->model()->dataStores()->keys().count(), 2); + QVERIFY(canvas->model()->dataStores()->contains(widget1)); + QVERIFY(canvas->model()->dataStores()->contains(widget2)); + spy.clear(); + + // Add the first widget again. The model should not be modified. + canvas->addWidget(widget1, store1); + QCOMPARE(spy.count(), 0); + QCOMPARE(canvas->model()->dataStores()->keys().count(), 2); +} + +void Ut_DuiMashupCanvas::testRemoval() +{ + QSignalSpy spy(canvas->model(), SIGNAL(modified(QList))); + + DuiWidget *widget1 = new DuiWidget; + MockDataStore store1; + DuiWidget *widget2 = new DuiWidget; + MockDataStore store2; + DuiWidget *widget3 = new DuiWidget; + MockDataStore store3; + + // Add three widgets and ensure that they're in the model. + canvas->addWidget(widget1, store1); + canvas->addWidget(widget2, store2); + canvas->addWidget(widget3, store3); + QCOMPARE(spy.count(), 3); + QCOMPARE(canvas->model()->dataStores()->keys().count(), 3); + QVERIFY(canvas->model()->dataStores()->contains(widget1)); + QVERIFY(canvas->model()->dataStores()->contains(widget2)); + QVERIFY(canvas->model()->dataStores()->contains(widget3)); + spy.clear(); + + // Remove widget2 and verify that the rest are in the model. + canvas->removeWidget(widget2); + QCOMPARE(spy.count(), 1); + QCOMPARE(canvas->model()->dataStores()->keys().count(), 2); + QVERIFY(canvas->model()->dataStores()->contains(widget1)); + QVERIFY(!canvas->model()->dataStores()->contains(widget2)); + QVERIFY(canvas->model()->dataStores()->contains(widget3)); + spy.clear(); + + // Remove widget2 again and verify that the model was not changed. + canvas->removeWidget(widget2); + QCOMPARE(spy.count(), 0); + QCOMPARE(canvas->model()->dataStores()->keys().count(), 2); + QVERIFY(canvas->model()->dataStores()->contains(widget1)); + QVERIFY(!canvas->model()->dataStores()->contains(widget2)); + QVERIFY(canvas->model()->dataStores()->contains(widget3)); + spy.clear(); +} + +void Ut_DuiMashupCanvas::testCategories() +{ + QCOMPARE(canvas->categories(), QStringList()); + + QStringList categories; + categories.append("Category1"); + categories.append("Category2"); + canvas->setCategories(categories); + + QCOMPARE(canvas->categories(), categories); +} + +void Ut_DuiMashupCanvas::testUniqueCanvasIdentifiers() +{ + // Create two canvases with the same name + DuiMashupCanvas c1("foo"); + DuiMashupCanvas c2("foo"); + + // Ensure that the canvas names are unique + QStringList identifiers; + foreach(MethodCall * call, gDuiAppletInstanceManagerStub->stubCallHistory()) { + if (call->name() == "constructor") { + identifiers.append(call->parameter(0)); + } + } + QCOMPARE(identifiers.count(), 2); + QVERIFY(identifiers.at(0) != identifiers.at(1)); +} + +void Ut_DuiMashupCanvas::testEmptyCanvasIdentifier() +{ + DuiMashupCanvas emptyCanvas(""); + QStringList identifiers; + foreach(MethodCall * call, gDuiAppletInstanceManagerStub->stubCallHistory()) { + if (call->name() == "constructor") { + identifiers.append(call->parameter(0)); + } + } + QCOMPARE(identifiers.count(), 1); + QVERIFY(identifiers.at(0) != ""); +} + +void Ut_DuiMashupCanvas::testServiceAddress() +{ + DuiMashupCanvas canvas("meh"); + + QCOMPARE(canvas.serviceAddress(), gDuiComponentDataServiceName + "/DuiAppletInstanceManager/meh"); +} + + +QTEST_APPLESS_MAIN(Ut_DuiMashupCanvas) diff --git a/tests/ut_duimashupcanvas/ut_duimashupcanvas.h b/tests/ut_duimashupcanvas/ut_duimashupcanvas.h new file mode 100644 index 000000000..94c34e80b --- /dev/null +++ b/tests/ut_duimashupcanvas/ut_duimashupcanvas.h @@ -0,0 +1,74 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIMASHUPCANVAS_ +#define UT_DUIMASHUPCANVAS_ + +#include +#include +#include "duimashupcanvasmodel.h" +#include "duimashupcanvasstyle.h" + +class TestMashupCanvas; +class DuiApplication; +class DuiApplicationWindow; + + +class TestMashupCanvasView : public DuiWidgetView +{ + DUI_VIEW(DuiMashupCanvasModel, DuiMashupCanvasStyle) + +public: + TestMashupCanvasView(DuiWidgetController *canvas) : DuiWidgetView(canvas) {} + +}; + +class Ut_DuiMashupCanvas : public QObject +{ + Q_OBJECT + +private: + // TestMashupCanvas is derived from DuiMashupCanvas + TestMashupCanvas *canvas; + // TestMashupCanvasView is derived from DuiMashupCanvasView + TestMashupCanvasView *view; + // DuiApplication instance required by DuiWidget. + DuiApplication *app; + +private slots: + // Executed once before every test case + void init(); + + // Executed once after every test case + void cleanup(); + + // Executed once before first test case + void initTestCase(); + + // Executed once after last test case + void cleanupTestCase(); + + void testAddition(); + void testRemoval(); + void testCategories(); + void testUniqueCanvasIdentifiers(); + void testEmptyCanvasIdentifier(); + void testServiceAddress(); +}; +#endif // UT_DUIMASHUPCANVAS_ diff --git a/tests/ut_duimashupcanvas/ut_duimashupcanvas.pro b/tests/ut_duimashupcanvas/ut_duimashupcanvas.pro new file mode 100644 index 000000000..1cf020b2d --- /dev/null +++ b/tests/ut_duimashupcanvas/ut_duimashupcanvas.pro @@ -0,0 +1,31 @@ +include(../common_top.pri) +TARGET = ut_duimashupcanvas +INCLUDEPATH += \ + $$DUISRCDIR/mashup/mashup \ + $$DUISRCDIR/widgets \ + $$DUISRCDIR/style + +# unit test and unit classes +SOURCES += \ + ut_duimashupcanvas.cpp \ + $$DUISRCDIR/mashup/mashup/duimashupcanvas.cpp \ + $$DUISRCDIR/widgets/core/duiwidgetcontroller.cpp \ + $$DUISRCDIR/widgets/core/duiwidget.cpp \ + $$DUISRCDIR/applicationextension/duiextensionarea.cpp + +# service classes +SOURCES += \ + $$STUBSDIR/stubbase.cpp \ + +# unit test and unit classes +HEADERS += \ + ut_duimashupcanvas.h \ + $$DUISRCDIR/mashup/mashup/duimashupcanvas.h \ + $$DUISRCDIR/mashup/mashup/duiappletinstancemanager.h \ + $$DUISRCDIR/mashup/mashup/duiappletid.h \ + $$DUISRCDIR/widgets/core/duiwidgetcontroller_p.h \ + $$DUISRCDIR/widgets/core/duiwidget_p.h \ + $$DUISRCDIR/widgets/duiscenewindow_p.h \ + $$DUISRCDIR/widgets/duiobjectmenu.h + +include(../common_bot.pri) diff --git a/tests/ut_duimashupcanvasview/.gitignore b/tests/ut_duimashupcanvasview/.gitignore new file mode 100644 index 000000000..dd73ecdd5 --- /dev/null +++ b/tests/ut_duimashupcanvasview/.gitignore @@ -0,0 +1 @@ +ut_duimashupcanvasview diff --git a/tests/ut_duimashupcanvasview/ut_duimashupcanvasview.cpp b/tests/ut_duimashupcanvasview/ut_duimashupcanvasview.cpp new file mode 100644 index 000000000..11601cd24 --- /dev/null +++ b/tests/ut_duimashupcanvasview/ut_duimashupcanvasview.cpp @@ -0,0 +1,317 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duimashupcanvasview.h" + +#include "duimashupcanvas.h" +#include "duiappletinventory.h" +#include "../stubs/mockdatastore.h" + +#include +#include +#include +#include +#include +#include + +#include +#include + +void QFileSystemWatcher::addPath(const QString &) +{ +} + +QStringList QDir::entryList(const QStringList &, Filters, SortFlags) const +{ + return QStringList(); +} + +bool QDBusConnection::registerObject(const QString &, QObject *, RegisterOptions) +{ + return true; +} + +void Ut_DuiMashupCanvasView::initTestCase() +{ + // DuiApplications must be created manually due to theme system changes + static int argc = 1; + static char *app_name[1] = { (char *)"./ut_duimashupcanvasview" }; + app = new DuiApplication(argc, app_name); + appWindow = new DuiApplicationWindow; +} + +void Ut_DuiMashupCanvasView::cleanupTestCase() +{ + delete appWindow; + delete app; +} + +void Ut_DuiMashupCanvasView::init() +{ + mashupCanvas = new DuiMashupCanvas("test"); + m_subject = new TestDuiMashupCanvasView(mashupCanvas); + mashupCanvas->setView(m_subject); +} + +void Ut_DuiMashupCanvasView::cleanup() +{ + delete m_subject; +} + +void Ut_DuiMashupCanvasView::addWidgetToMashupCanvas(DuiWidget *widget, DuiDataStore *dataStore) +{ + QMap *dataStores = const_cast *>(mashupCanvas->model()->dataStores()); + (*dataStores)[widget] = dataStore; + mashupCanvas->model()->dataStoresModified(); +} + +void Ut_DuiMashupCanvasView::removeWidgetFromMashupCanvas(DuiWidget *widget) +{ + QMap *dataStores = const_cast *>(mashupCanvas->model()->dataStores()); + dataStores->remove(widget); + mashupCanvas->model()->dataStoresModified(); +} + +DuiContainer *Ut_DuiMashupCanvasView::container(QGraphicsWidget *widget) +{ + DuiContainer *container = NULL; + + if (widget) { + QGraphicsWidget *parentWidget = widget->parentWidget(); + if (parentWidget != NULL) { + container = dynamic_cast(parentWidget); + } + } + + return container; +} + +bool Ut_DuiMashupCanvasView::isWidgetInContainer(QGraphicsWidget *widget) +{ + return (container(widget) != NULL); +} + +void Ut_DuiMashupCanvasView::verifyWidgetContainerVisibility(QList *widgetList, bool visible) +{ + QListIterator iterator(*widgetList); + while (iterator.hasNext()) { + DuiWidget *widget = iterator.next(); + DuiContainer *theContainer = container(widget); + QVERIFY(isWidgetInContainer(widget)); + if (visible) { + QCOMPARE(theContainer->objectName(), QString("")); + QVERIFY(theContainer->headerVisible()); + } else { + QCOMPARE(theContainer->objectName(), QString("DuiExtensionAreaInvisibleContainer")); + QVERIFY(!theContainer->headerVisible()); + } + } + QGraphicsLayout *appletLayout = dynamic_cast(mashupCanvas->layout()->itemAt(0)); + QVERIFY(appletLayout != NULL); + QCOMPARE(appletLayout->count(), widgetList->size()); +} + +QList *Ut_DuiMashupCanvasView::createWidgets(int numberOfWidgets, bool containerMode) +{ + m_subject->modifiableStyle()->setContainerMode(containerMode); + m_subject->applyStyle(); + QList *widgetList = new QList; + for (int i = 0; i < numberOfWidgets; ++i) { + DuiWidget *widget = new DuiWidget; + MockDataStore *store = new MockDataStore; + addWidgetToMashupCanvas(widget, store); + widgetList->append(widget); + } + return widgetList; +} + +void Ut_DuiMashupCanvasView::testLayoutPolicy() +{ + QGraphicsLinearLayout *mainLayout = dynamic_cast(mashupCanvas->layout()); + QVERIFY(mainLayout != NULL); + DuiLayout *layout = dynamic_cast(mainLayout->itemAt(0)); + QVERIFY(layout != NULL); + DuiAbstractLayoutPolicy *policy = layout->policy(); + QVERIFY(policy != NULL); +} + +void Ut_DuiMashupCanvasView::testAdditionWithFlowLayoutPolicy() +{ + DuiWidget *widget1 = new DuiWidget; + MockDataStore store1; + DuiWidget *widget2 = new DuiWidget; + MockDataStore store2; + + // Add one widget. + addWidgetToMashupCanvas(widget1, &store1); + + // Check that it was added into the layout. + QVERIFY(widgetInLayout(widget1)); + + // Ensure that the layout data is written to data store. + QVERIFY(store1.contains("layoutIndex")); + + // Add another widget. Addition will change layout data of both widgets. + addWidgetToMashupCanvas(widget2, &store2); + + // Check that it was added into the layout. + QVERIFY(widgetInLayout(widget2)); + + // Ensure that new layout data is stored into data store. + QVERIFY(store1.contains("layoutIndex")); + QVERIFY(store2.contains("layoutIndex")); + + delete widget1; + delete widget2; +} + + +void Ut_DuiMashupCanvasView::testRemovalWithFlowLayoutPolicy() +{ + + QList *widgetList = createWidgets(3); + + // Remove widget2 + removeWidgetFromMashupCanvas(widgetList->at(1)); + + // Ensure that widget1 and widget3 are still in the layout but widget2 is not. + QVERIFY(widgetInLayout(widgetList->at(0))); + QVERIFY(!widgetInLayout(widgetList->at(1))); + QVERIFY(widgetInLayout(widgetList->at(2))); + + while (!widgetList->isEmpty()) + delete widgetList->takeFirst(); + +} + + +bool Ut_DuiMashupCanvasView::widgetInLayout(DuiWidget *widget) +{ + QGraphicsLinearLayout *mainLayout = dynamic_cast(mashupCanvas->layout()); + DuiLayout *layout = dynamic_cast(mainLayout->itemAt(0)); + DuiAbstractLayoutPolicy *policy = layout->policy(); + + bool found = false; + for (int i = 0; i < policy->count(); ++i) { + DuiWidget *w = NULL; + + DuiContainer *container = dynamic_cast(policy->itemAt(i)); + if (container != NULL) { + // Widget has a container, take the centralWidget data + w = container->centralWidget(); + } else { + // No container + w = dynamic_cast(policy->itemAt(i)); + } + + found |= w == widget; + } + + return found; +} + +void Ut_DuiMashupCanvasView::testSettingContainerModeOff() +{ + QList *widgetList = createWidgets(2, true); + + // Check that the containers are visible + verifyWidgetContainerVisibility(widgetList, true); + + m_subject->modifiableStyle()->setContainerMode(false); + m_subject->applyStyle(); + + // Check that the containers are not visible + verifyWidgetContainerVisibility(widgetList, false); + + while (!widgetList->isEmpty()) + delete widgetList->takeFirst(); +} + +void Ut_DuiMashupCanvasView::testSettingContainerModeOn() +{ + QList *widgetList = createWidgets(2, false); + verifyWidgetContainerVisibility(widgetList, false); + + m_subject->modifiableStyle()->setContainerMode(true); + m_subject->applyStyle(); + + verifyWidgetContainerVisibility(widgetList, true); + + while (!widgetList->isEmpty()) + delete widgetList->takeFirst(); +} + +void Ut_DuiMashupCanvasView::testSettingContainerModeOnWhenContainerModeIsOn() +{ + QList *widgetList = createWidgets(2, true); + + verifyWidgetContainerVisibility(widgetList, true); + + m_subject->modifiableStyle()->setContainerMode(true); + m_subject->applyStyle(); + + verifyWidgetContainerVisibility(widgetList, true); + + while (!widgetList->isEmpty()) + delete widgetList->takeFirst(); +} + +void Ut_DuiMashupCanvasView::testSettingContainerModeOffWhenContainerModeIsOff() +{ + QList *widgetList = createWidgets(2, false); + verifyWidgetContainerVisibility(widgetList, false); + + m_subject->modifiableStyle()->setContainerMode(false); + m_subject->applyStyle(); + + verifyWidgetContainerVisibility(widgetList, false); + + while (!widgetList->isEmpty()) + delete widgetList->takeFirst(); +} + + +void Ut_DuiMashupCanvasView::testSettingContainerModeOffWidgetsHaveCorrectLayoutOrder() +{ + QList *widgetList = createWidgets(2, true); + + m_subject->modifiableStyle()->setContainerMode(false); + m_subject->applyStyle(); + + // Get the widgets from the layout of mashup canvas + QGraphicsLinearLayout *mainLayout = dynamic_cast(mashupCanvas->layout()); + DuiLayout *layout = dynamic_cast(mainLayout->itemAt(0)); + DuiAbstractLayoutPolicy *policy = layout->policy(); + + DuiContainer *container1 = dynamic_cast(policy->itemAt(0)); + DuiContainer *container2 = dynamic_cast(policy->itemAt(1)); + + QCOMPARE(widgetList->count(), 2); + QCOMPARE(layout->count(), 2); + QCOMPARE(policy->count(), 2); + + // and check if the order is the same. + QCOMPARE(widgetList->at(0), container1->centralWidget()); + QCOMPARE(widgetList->at(1), container2->centralWidget()); + + while (!widgetList->isEmpty()) + delete widgetList->takeFirst(); +} + +QTEST_APPLESS_MAIN(Ut_DuiMashupCanvasView) diff --git a/tests/ut_duimashupcanvasview/ut_duimashupcanvasview.h b/tests/ut_duimashupcanvasview/ut_duimashupcanvasview.h new file mode 100644 index 000000000..99a680d7e --- /dev/null +++ b/tests/ut_duimashupcanvasview/ut_duimashupcanvasview.h @@ -0,0 +1,99 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIMASHUPCANVASVIEW_H +#define UT_DUIMASHUPCANVASVIEW_H + +#include +#include "duimashupcanvasview.h" + +class DuiApplicationWindow; +class DuiApplication; +class DuiMashupCanvasView; +class DuiMashupCanvas; +class DuiWidget; +class DuiDataStore; + +class TestDuiMashupCanvasView : public DuiMashupCanvasView +{ + DUI_VIEW(DuiMashupCanvasModel, DuiMashupCanvasStyle) + +public: + TestDuiMashupCanvasView(DuiMashupCanvas *canvas) : DuiMashupCanvasView(canvas) {} + + DuiMashupCanvasStyle *modifiableStyle() { + DuiMashupCanvasStyleContainer &sc = style(); + const DuiMashupCanvasStyle *const_s = sc.operator ->(); + DuiMashupCanvasStyle *s = const_cast(const_s); + return s; + } + + void applyStyle() { + DuiMashupCanvasView::applyStyle(); + } +}; + +class Ut_DuiMashupCanvasView : public QObject +{ + Q_OBJECT + +private slots: + // Called before the first testfunction is executed + void initTestCase(); + // Called after the last testfunction was executed + void cleanupTestCase(); + // Called before each testfunction is executed + void init(); + // Called after every testfunction + void cleanup(); + + // Test that the layout is set up as expected + void testLayoutPolicy(); + // Test widget addition with flow layout policy + void testAdditionWithFlowLayoutPolicy(); + // Test widget removal with flow layout policy + void testRemovalWithFlowLayoutPolicy(); + // Test container mode + void testSettingContainerModeOff(); + void testSettingContainerModeOn(); + void testSettingContainerModeOnWhenContainerModeIsOn(); + void testSettingContainerModeOffWhenContainerModeIsOff(); + void testSettingContainerModeOffWidgetsHaveCorrectLayoutOrder(); + +private: + bool widgetInLayout(DuiWidget *widget); + void addWidgetToMashupCanvas(DuiWidget *widget, DuiDataStore *dataStore); + void removeWidgetFromMashupCanvas(DuiWidget *widget); + DuiContainer *container(QGraphicsWidget *widget); + bool isWidgetInContainer(QGraphicsWidget *widget); + void verifyWidgetContainerVisibility(QList *widgetList, bool visible); + + // Widget creation helpers + QList *createWidgets(int numberOfWidgets, bool containerMode = true); + // DuiApplication instance required by DuiWidget. + DuiApplication *app; + // DuiApplicationWindow instance required to get the scene and scene manager. + DuiApplicationWindow *appWindow; + // The object being tested + TestDuiMashupCanvasView *m_subject; + // Controller for the view + DuiMashupCanvas *mashupCanvas; +}; + +#endif diff --git a/tests/ut_duimashupcanvasview/ut_duimashupcanvasview.pro b/tests/ut_duimashupcanvasview/ut_duimashupcanvasview.pro new file mode 100644 index 000000000..b12e57ba3 --- /dev/null +++ b/tests/ut_duimashupcanvasview/ut_duimashupcanvasview.pro @@ -0,0 +1,15 @@ +include(../common_top.pri) +TARGET = ut_duimashupcanvasview +INCLUDEPATH += $$DUISRCDIR/mashup/appletcommunication $$DUISRCDIR/mashup/appletinterface $$DUISRCDIR/mashup/mashup $$DUISRCDIR/layout $$DUISRCDIR/style + +QT += core network gui svg dbus + +# unit test and unit classes +SOURCES += \ + ut_duimashupcanvasview.cpp \ + +# unit test and unit classes +HEADERS += \ + ut_duimashupcanvasview.h \ + +include(../common_bot.pri) diff --git a/tests/ut_duimodalscenewindow/.gitignore b/tests/ut_duimodalscenewindow/.gitignore new file mode 100644 index 000000000..2506d88b8 --- /dev/null +++ b/tests/ut_duimodalscenewindow/.gitignore @@ -0,0 +1 @@ +ut_duimodalscenewindow diff --git a/tests/ut_duimodalscenewindow/ut_duimodalscenewindow.cpp b/tests/ut_duimodalscenewindow/ut_duimodalscenewindow.cpp new file mode 100644 index 000000000..b082bb0d5 --- /dev/null +++ b/tests/ut_duimodalscenewindow/ut_duimodalscenewindow.cpp @@ -0,0 +1,71 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include + +#include +#include + +#include +#include + +#include "ut_duimodalscenewindow.h" + +void Ut_DuiModalSceneWindow::init() +{ + app = buildApp(1, "./ut_duimodalscenewindow"); + modalscenewindow = new DuiModalSceneWindow(); +} + +void Ut_DuiModalSceneWindow::cleanup() +{ + delete modalscenewindow; + delete app; +} + +void Ut_DuiModalSceneWindow::populate() +{ + DuiButton *button1 = new DuiButton(); + DuiButton *button2 = new DuiButton(); + + QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(); + layout->addItem(button1); + layout->addItem(button2); + modalscenewindow->setLayout(layout); + + modalscenewindow->appearNow(); + modalscenewindow->disappearNow(); +} + +DuiApplication *Ut_DuiModalSceneWindow::buildApp(int count, const QString ¶ms) +{ + QChar sep(' '); + char *argv[MAX_PARAMS]; + int x = 0; + + QStringList list = params.split(sep); + QStringListIterator it(list); + while (it.hasNext() && x < MAX_PARAMS) { + argv[x++] = strdup(it.next().toLocal8Bit().constData()); + } + return new DuiApplication(count, argv); +} + +QTEST_APPLESS_MAIN(Ut_DuiModalSceneWindow); diff --git a/tests/ut_duimodalscenewindow/ut_duimodalscenewindow.h b/tests/ut_duimodalscenewindow/ut_duimodalscenewindow.h new file mode 100644 index 000000000..5a467816a --- /dev/null +++ b/tests/ut_duimodalscenewindow/ut_duimodalscenewindow.h @@ -0,0 +1,47 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIMODALSCENEWINDOW_H +#define UT_DUIMODALSCENEWINDOW_H + +#include +#include +#include + +class DuiApplication; + +#define MAX_PARAMS 10 +class Ut_DuiModalSceneWindow: public QObject +{ + Q_OBJECT + +private: + DuiModalSceneWindow *modalscenewindow; + DuiApplication *app; + DuiApplication *buildApp(int count, const QString ¶ms); + +private slots: + + void init(); + void cleanup(); + + void populate(); +}; + +#endif diff --git a/tests/ut_duimodalscenewindow/ut_duimodalscenewindow.pro b/tests/ut_duimodalscenewindow/ut_duimodalscenewindow.pro new file mode 100644 index 000000000..8ef5a11d2 --- /dev/null +++ b/tests/ut_duimodalscenewindow/ut_duimodalscenewindow.pro @@ -0,0 +1,13 @@ +include(../common_top.pri) +INCLUDEPATH += $$DUISRCDIR/widgets $$DUISRCDIR/style + +TARGET = ut_duimodalscenewindow + +# Input +HEADERS += \ + ut_duimodalscenewindow.h \ + +SOURCES += \ + ut_duimodalscenewindow.cpp \ + +include(../common_bot.pri) diff --git a/tests/ut_duimulticolumnfastlistview/.gitignore b/tests/ut_duimulticolumnfastlistview/.gitignore new file mode 100644 index 000000000..418322e09 --- /dev/null +++ b/tests/ut_duimulticolumnfastlistview/.gitignore @@ -0,0 +1 @@ +ut_duifastlistview diff --git a/tests/ut_duimulticolumnfastlistview/myindexedmodel.cpp b/tests/ut_duimulticolumnfastlistview/myindexedmodel.cpp new file mode 100644 index 000000000..2859bfa9d --- /dev/null +++ b/tests/ut_duimulticolumnfastlistview/myindexedmodel.cpp @@ -0,0 +1,86 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "myindexedmodel.h" + +MyIndexedModel::MyIndexedModel(QObject *r) : root(r) +{ +} + +MyIndexedModel::~MyIndexedModel() +{ + delete root; +} + +QModelIndex MyIndexedModel::index(int row, int column, const QModelIndex &parent) const +{ + QObject *parentObject; + + if (!parent.isValid()) + parentObject = root; + else + parentObject = static_cast(parent.internalPointer()); + + if (row >= 0 && row < parentObject->children().size()) + return createIndex(row, column, parentObject->children().at(row)); + else + return QModelIndex(); +} + +QModelIndex MyIndexedModel::parent(const QModelIndex &child) const +{ + if (child == QModelIndex() || !child.isValid()) + return QModelIndex(); + + QObject *object = static_cast(child.internalPointer()); + QObject *parent = object->parent(); + + if (parent == root) + return QModelIndex(); + + QObject *grandParent = parent->parent(); + + return createIndex(grandParent->children().indexOf(parent), 0, parent); +} + +int MyIndexedModel::rowCount(const QModelIndex &parent) const +{ + if (!parent.isValid()) + return root->children().size(); + + QObject *parentObject = static_cast(parent.internalPointer()); + return parentObject->children().size(); +} + +int MyIndexedModel::columnCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent); + return 1; +} + +QVariant MyIndexedModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + if (role == Qt::DisplayRole) + return (static_cast(index.internalPointer()))->objectName(); + + return QVariant(); +} diff --git a/tests/ut_duimulticolumnfastlistview/myindexedmodel.h b/tests/ut_duimulticolumnfastlistview/myindexedmodel.h new file mode 100644 index 000000000..c48e2dd96 --- /dev/null +++ b/tests/ut_duimulticolumnfastlistview/myindexedmodel.h @@ -0,0 +1,41 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef MYINDEXEDMODEL_H +#define MYINDEXEDMODEL_H + +#include + +class MyIndexedModel : public QAbstractItemModel +{ +public: + MyIndexedModel(QObject *root); + virtual ~MyIndexedModel(); + + virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; + virtual QModelIndex parent(const QModelIndex &child) const; + virtual int rowCount(const QModelIndex &parent = QModelIndex()) const; + virtual int columnCount(const QModelIndex &parent = QModelIndex()) const; + virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + +private: + QObject *root; +}; + +#endif // MYINDEXEDMODEL_H diff --git a/tests/ut_duimulticolumnfastlistview/ut_duimulticolumnfastlistview.cpp b/tests/ut_duimulticolumnfastlistview/ut_duimulticolumnfastlistview.cpp new file mode 100644 index 000000000..a50da7c4b --- /dev/null +++ b/tests/ut_duimulticolumnfastlistview/ut_duimulticolumnfastlistview.cpp @@ -0,0 +1,371 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include "../../src/widgets/views/duifastlistview_p.h" +#include "duilistmodel.h" +#include "myindexedmodel.h" +#include "ut_duifastlistview.h" + +void Ut_DuiListNewView::initTestCase() +{ + makePhoneBook(); + makePhoneBookModel(); +} + +void Ut_DuiListNewView::makePhoneBook() +{ + phoneBook = new QObject; + + QObject *itemA = new QObject(phoneBook); + itemA->setObjectName("A"); + + QObject *item; + item = new QObject(itemA); + item->setObjectName("Adam"); + + item = new QObject(itemA); + item->setObjectName("Abby"); + + item = new QObject(itemA); + item->setObjectName("Ashley"); + + QObject *itemB = new QObject(phoneBook); + itemB->setObjectName("B"); + + item = new QObject(itemB); + item->setObjectName("Baby"); + + item = new QObject(itemB); + item->setObjectName("Bob"); + + item = new QObject(itemB); + item->setObjectName("Boby"); + + item = new QObject(itemB); + item->setObjectName("Britney"); + + QObject *itemC = new QObject(phoneBook); + itemC->setObjectName("C"); + + item = new QObject(itemC); + item->setObjectName("Cindy"); +} + +void Ut_DuiListNewView::makePhoneBookModel() +{ + phoneBookModel = new MyIndexedModel(phoneBook); +} + +void Ut_DuiListNewView::cleanupTestCase() +{ + delete phoneBookModel; +} + +void Ut_DuiListNewView::init() +{ + fastListViewPrivate = new DuiFastGroupHeaderListViewPrivate; + fastListViewPrivate->model = phoneBookModel; + fastListViewPrivate->separator = new DuiWidget; + fastListViewPrivate->separator->setGeometry(0, 0, 300, 2); + fastListViewPrivate->itemHeight = 100; + + fastListViewPrivate->setHeadersCreator(new DummyHeaderCreator); + fastListViewPrivate->hdrHeight = GroupHeaderHeight; + + DuiListModel *model = new DuiListModel; + model->setItemModel(phoneBookModel); + model->setShowGroups(true); + fastListViewPrivate->controllerModel = model; + + fastListViewPrivate->updateHeadersRows(); + fastListViewPrivate->updateHeadersPositions(); +} + +void Ut_DuiListNewView::cleanup() +{ + delete fastListViewPrivate; + delete fastListViewPrivate->controllerModel; +} + +void Ut_DuiListNewView::testPhoneBook() +{ + // Make sure our phone book model is valid + QCOMPARE(phoneBook->children().size(), 3); + QCOMPARE(phoneBook->children().at(0)->children().size(), 3); + QCOMPARE(phoneBook->children().at(1)->children().size(), 4); + QCOMPARE(phoneBook->children().at(2)->children().size(), 1); +} + +void Ut_DuiListNewView::testUpdateHeadersRows() +{ + QCOMPARE(3, fastListViewPrivate->headersRows.size()); + QCOMPARE(0, fastListViewPrivate->headersRows[0]); + QCOMPARE(4, fastListViewPrivate->headersRows[1]); + QCOMPARE(9, fastListViewPrivate->headersRows[2]); +} + +void Ut_DuiListNewView::testUpdateHeadersPositions() +{ + QCOMPARE(fastListViewPrivate->headersPositions.size(), 3); + QCOMPARE(fastListViewPrivate->headersPositions[0], 0); + QCOMPARE(fastListViewPrivate->headersPositions[1], 344); + QCOMPARE(fastListViewPrivate->headersPositions[2], 790); +} + +void Ut_DuiListNewView::testHeaderHeightShouldBeZeroIfNoHeadersCreatorSpecified() +{ + fastListViewPrivate->setHeadersCreator(NULL); + QCOMPARE(0, fastListViewPrivate->headerHeight()); +} + +void Ut_DuiListNewView::testHeaderHeightShouldBeZeroIfHeadersNotVisible() +{ + fastListViewPrivate->controllerModel->setShowGroups(false); + QCOMPARE(fastListViewPrivate->headerHeight(), 0); +} + +void Ut_DuiListNewView::testHeaderHeight() +{ + QCOMPARE(fastListViewPrivate->headerHeight(), GroupHeaderHeight); +} + +void Ut_DuiListNewView::testGroupSize() +{ + QCOMPARE(fastListViewPrivate->groupSize(0), 304); + QCOMPARE(fastListViewPrivate->groupSize(1), 406); + QCOMPARE(fastListViewPrivate->groupSize(2), 100); +} + +void Ut_DuiListNewView::testSizeHint() +{ + QCOMPARE(fastListViewPrivate->totalHeight(), 930); +} + +void Ut_DuiListNewView::testItemCountIndexedModel() +{ + QCOMPARE(fastListViewPrivate->itemsCount(), 8); +} + +void Ut_DuiListNewView::testItemCount() +{ + QCOMPARE(fastListViewPrivate->itemsCount(0), 3); + QCOMPARE(fastListViewPrivate->itemsCount(1), 4); + QCOMPARE(fastListViewPrivate->itemsCount(2), 1); +} + +void Ut_DuiListNewView::testSeparatorsCount() +{ + QCOMPARE(fastListViewPrivate->separatorsCount(), 5); +} + +void Ut_DuiListNewView::testFirstFlatRowToIndex() +{ + QModelIndex index(fastListViewPrivate->flatRowToIndex(0)); + QCOMPARE(index.row(), 0); + QCOMPARE(index.parent(), QModelIndex()); +} + +void Ut_DuiListNewView::testSecondFlatRowToIndex() +{ + QModelIndex index(fastListViewPrivate->flatRowToIndex(1)); + QCOMPARE(index.row(), 0); + QVERIFY(index.parent().isValid()); + QCOMPARE(index.parent().row(), 0); +} + +void Ut_DuiListNewView::testLastFlatRowToIndex() +{ + QModelIndex index(fastListViewPrivate->flatRowToIndex(10)); + QCOMPARE(index.row(), 0); + QVERIFY(index.parent().isValid()); + QCOMPARE(index.parent().row(), 2); +} + +void Ut_DuiListNewView::testAfterLastFlatRowToIndex() +{ + QModelIndex index(fastListViewPrivate->flatRowToIndex(11)); + QVERIFY(index.isValid()); + QCOMPARE(index.row(), 0); + QVERIFY(index.parent().isValid()); + QCOMPARE(index.parent().row(), 2); +} + +void Ut_DuiListNewView::testInvalidIndexToFlatRow() +{ + QModelIndex index; + QCOMPARE(fastListViewPrivate->indexToFlatRow(index), -1); +} + +void Ut_DuiListNewView::testFirstIndexWithoutParentToFlatRow() +{ + QModelIndex index = fastListViewPrivate->model->index(1, 0); + QCOMPARE(fastListViewPrivate->indexToFlatRow(index), 4); +} + +void Ut_DuiListNewView::testIndexWithParentToFlatRow() +{ + QModelIndex index = fastListViewPrivate->model->index(1, 0, fastListViewPrivate->model->index(1, 0)); + QCOMPARE(fastListViewPrivate->indexToFlatRow(index), 6); +} + +void Ut_DuiListNewView::testLastIndexWithParentToFlatRow() +{ + QModelIndex index = fastListViewPrivate->model->index(0, 0, fastListViewPrivate->model->index(2, 0)); + QCOMPARE(fastListViewPrivate->indexToFlatRow(index), 10); +} + +void Ut_DuiListNewView::testLocateVisibleIndexAtZero() +{ + QModelIndex index(fastListViewPrivate->locateVisibleIndexAt(0)); + QVERIFY(index.isValid()); + QCOMPARE(index.row(), 0); + QVERIFY(!index.parent().isValid()); +} + +void Ut_DuiListNewView::testLocateVisibleIndexAt41() +{ + QModelIndex index(fastListViewPrivate->locateVisibleIndexAt(41)); + QVERIFY(index.isValid()); + QCOMPARE(index.row(), 0); + QVERIFY(index.parent().isValid()); + QCOMPARE(index.parent().row(), 0); +} + +void Ut_DuiListNewView::testLocateVisibleIndexAtMiddleOfHeader() +{ + QModelIndex index(fastListViewPrivate->locateVisibleIndexAt(345)); + QVERIFY(index.isValid()); + QCOMPARE(index.row(), 1); + QVERIFY(!index.parent().isValid()); +} + +void Ut_DuiListNewView::testLocateVisibleRowAt0() +{ + QCOMPARE(fastListViewPrivate->locateVisibleRowAt(0), 0); +} + +void Ut_DuiListNewView::testLocateVisibleRowAt41() +{ + QCOMPARE(fastListViewPrivate->locateVisibleRowAt(41), 1); +} + +void Ut_DuiListNewView::testLocateVisibleRowAt384() +{ + QCOMPARE(fastListViewPrivate->locateVisibleRowAt(385), 5); +} + +void Ut_DuiListNewView::testLocateVisibleRowAt900() +{ + // last item + QCOMPARE(fastListViewPrivate->locateVisibleRowAt(900), 11); +} + +void Ut_DuiListNewView::testLocateVisibleRowAt931() +{ + // last item + QCOMPARE(fastListViewPrivate->locateVisibleRowAt(931), 11); +} + +void Ut_DuiListNewView::testLocatePosOfItemAt0Row() +{ + QCOMPARE(fastListViewPrivate->locatePosOfItem(0), 0); +} + +void Ut_DuiListNewView::testLocatePosOfItemAt1Row() +{ + QCOMPARE(fastListViewPrivate->locatePosOfItem(1), 40); +} + +void Ut_DuiListNewView::testLocatePosOfItemAt3Row() +{ + QCOMPARE(fastListViewPrivate->locatePosOfItem(3), 244); +} + +void Ut_DuiListNewView::testLocatePosOfItemAt0Index() +{ + QModelIndex index(phoneBookModel->index(0, 0)); + QCOMPARE(fastListViewPrivate->locatePosOfItem(index), 0); +} + +void Ut_DuiListNewView::testLocatePosOfItemAt3Index() +{ + QModelIndex index(phoneBookModel->index(2, 0, phoneBookModel->index(0, 0))); + QCOMPARE(fastListViewPrivate->locatePosOfItem(index), 244); +} + +void Ut_DuiListNewView::testLocatePosOfItemAt10Row() +{ + QCOMPARE(fastListViewPrivate->locatePosOfItem(10), 830); +} + +void Ut_DuiListNewView::testFindLowerIndexInEmptyArray() +{ + QVector vec; + QCOMPARE(dFindLowerIndex(vec, 0), 0); + QCOMPARE(dFindLowerIndex(vec, 1), 0); +} + +void Ut_DuiListNewView::testFindLowerIndexIn2ItemsArray() +{ + QVector vec; + vec << 10 << 15; + QCOMPARE(dFindLowerIndex(vec, 4), 0); + QCOMPARE(dFindLowerIndex(vec, 10), 0); + QCOMPARE(dFindLowerIndex(vec, 11), 0); + QCOMPARE(dFindLowerIndex(vec, 15), 1); + QCOMPARE(dFindLowerIndex(vec, 100), 1); +} + +void Ut_DuiListNewView::testFindLowerIndexIn3ItemsArray() +{ + QVector vec; + vec << 0 << 5 << 9; + QCOMPARE(dFindLowerIndex(vec, 2), 0); + QCOMPARE(dFindLowerIndex(vec, 5), 1); + QCOMPARE(dFindLowerIndex(vec, 6), 1); + QCOMPARE(dFindLowerIndex(vec, 9), 2); +} + +void Ut_DuiListNewView::testPerformance() +{ + QSKIP("currently doesn't work", SkipSingle); + fastListViewPrivate->viewportTopLeft = QPoint(0, 0); + fastListViewPrivate->viewportVisibleHeight = 800; + for (int i = 0; i < 10; i++) { + if (i % 1 == 0) + fastListViewPrivate->viewportTopLeft = QPoint(0, 0); + else + fastListViewPrivate->viewportTopLeft = QPoint(0, 800); + + QModelIndex firstVisibleRow = fastListViewPrivate->locateVisibleIndexAt(fastListViewPrivate->viewportTopLeft.y()); + fastListViewPrivate->updateFirstVisibleRow(firstVisibleRow); + QModelIndex lastVisibleRow = fastListViewPrivate->locateVisibleIndexAt(fastListViewPrivate->viewportTopLeft.y() + fastListViewPrivate->viewportVisibleHeight); + fastListViewPrivate->updateLastVisibleRow(lastVisibleRow); + + QPoint firstVisibleItemPos(0, fastListViewPrivate->locatePosOfItem(firstVisibleRow)); + QPoint lastVisibleItemPos(0, fastListViewPrivate->locatePosOfItem(lastVisibleRow)); + fastListViewPrivate->removeInvisibleItems(firstVisibleItemPos, lastVisibleItemPos); + + if (fastListViewPrivate->model->rowCount() > 0) + fastListViewPrivate->createVisibleItems(firstVisibleRow, lastVisibleRow); + } +} + +QTEST_APPLESS_MAIN(Ut_DuiListNewView); diff --git a/tests/ut_duimulticolumnfastlistview/ut_duimulticolumnfastlistview.h b/tests/ut_duimulticolumnfastlistview/ut_duimulticolumnfastlistview.h new file mode 100644 index 000000000..a16375cc3 --- /dev/null +++ b/tests/ut_duimulticolumnfastlistview/ut_duimulticolumnfastlistview.h @@ -0,0 +1,118 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUILABEL_H +#define UT_DUILABEL_H + +#include +#include +#include +#include "duilistcellcreator.h" +const int GroupHeaderHeight = 40; + +class DummyHeaderWidget : public DuiWidget +{ +public: + DummyHeaderWidget() { + } + + virtual QRectF boundingRect() const { + return QRectF(QPointF(0, 0), QSizeF(800, GroupHeaderHeight)); + } +}; + +class DummyHeaderCreator : public DuiListBaseCellCreator +{ +public: + virtual void updateCell(const QModelIndex &index, DuiWidget *cell) const { + Q_UNUSED(index); + Q_UNUSED(cell); + } +}; + +class DuiFastGroupHeaderListViewPrivate; +class MyIndexedModel; + +class Ut_DuiListNewView : public QObject +{ + Q_OBJECT + +private: + void makePhoneBook(); + void makePhoneBookModel(); + +private slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + + void testPhoneBook(); + + void testUpdateHeadersRows(); + void testUpdateHeadersPositions(); + void testHeaderHeightShouldBeZeroIfNoHeadersCreatorSpecified(); + void testHeaderHeightShouldBeZeroIfHeadersNotVisible(); + void testHeaderHeight(); + void testGroupSize(); + void testSizeHint(); + void testItemCountIndexedModel(); + void testItemCount(); + void testSeparatorsCount(); + + void testFirstFlatRowToIndex(); + void testSecondFlatRowToIndex(); + void testLastFlatRowToIndex(); + void testAfterLastFlatRowToIndex(); + + void testInvalidIndexToFlatRow(); + void testFirstIndexWithoutParentToFlatRow(); + void testIndexWithParentToFlatRow(); + void testLastIndexWithParentToFlatRow(); + + void testLocateVisibleIndexAtZero(); + void testLocateVisibleIndexAt41(); + void testLocateVisibleIndexAtMiddleOfHeader(); + void testLocateVisibleRowAt0(); + void testLocateVisibleRowAt41(); + void testLocateVisibleRowAt384(); + void testLocateVisibleRowAt900(); + void testLocateVisibleRowAt931(); + + void testLocatePosOfItemAt0Row(); + void testLocatePosOfItemAt1Row(); + void testLocatePosOfItemAt3Row(); + void testLocatePosOfItemAt10Row(); + + void testLocatePosOfItemAt0Index(); + void testLocatePosOfItemAt3Index(); + + void testFindLowerIndexInEmptyArray(); + void testFindLowerIndexIn2ItemsArray(); + void testFindLowerIndexIn3ItemsArray(); + + void testPerformance(); + +private: + QObject *phoneBook; + MyIndexedModel *phoneBookModel; + DuiFastGroupHeaderListViewPrivate *fastListViewPrivate; +}; + +#endif diff --git a/tests/ut_duimulticolumnfastlistview/ut_duimulticolumnfastlistview.pro b/tests/ut_duimulticolumnfastlistview/ut_duimulticolumnfastlistview.pro new file mode 100644 index 000000000..081c12549 --- /dev/null +++ b/tests/ut_duimulticolumnfastlistview/ut_duimulticolumnfastlistview.pro @@ -0,0 +1,8 @@ +include(../common_top.pri) + +TARGET = ut_duimulticolumnfastlistview + +HEADERS += ut_duimulticolumnfastlistview.h myindexedmodel.h +SOURCES += ut_duimulticolumnfastlistview.cpp myindexedmodel.cpp ../../src/widgets/views/duifastlistview_p.cpp ../../src/.moc/moc_duifastlistview_p.cpp + +include(../common_bot.pri) diff --git a/tests/ut_duinavigationbar/.gitignore b/tests/ut_duinavigationbar/.gitignore new file mode 100644 index 000000000..cb7e1929c --- /dev/null +++ b/tests/ut_duinavigationbar/.gitignore @@ -0,0 +1 @@ +ut_duinavigationbar diff --git a/tests/ut_duinavigationbar/ut_duinavigationbar.cpp b/tests/ut_duinavigationbar/ut_duinavigationbar.cpp new file mode 100644 index 000000000..22d99dfbf --- /dev/null +++ b/tests/ut_duinavigationbar/ut_duinavigationbar.cpp @@ -0,0 +1,111 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duinavigationbar.h" + +#include +#include +#include + +#include + +DuiApplication *app; + +void Ut_DuiNavigationBar::initTestCase() +{ + static int argc = 1; + static char *app_name[1] = { (char *) "./ut_duinavigationbar" }; + app = new DuiApplication(argc, app_name); +} + +void Ut_DuiNavigationBar::cleanupTestCase() +{ + delete app; +} + +void Ut_DuiNavigationBar::init() +{ + subject = new DuiNavigationBar(); +} + +void Ut_DuiNavigationBar::cleanup() +{ + delete subject; + subject = 0; +} + +void Ut_DuiNavigationBar::testConstructor() +{ + QString name("test"); + subject->setViewMenuIconID(name); + QCOMPARE(subject->viewMenuIconID(), name); + +} + +void Ut_DuiNavigationBar::testToolbar() +{ + QVERIFY(!subject->model()->toolBar()); + + DuiToolBar *toolbar = new DuiToolBar(); + subject->dockToolBar(toolbar); + QCOMPARE(subject->model()->toolBar(), toolbar); + + delete toolbar; + subject->undockToolBar(); + QVERIFY(!subject->model()->toolBar()); +} + +void Ut_DuiNavigationBar::testViewMenuIconID() +{ + QString iconID("Icon-back"); + + // this is the default value from model + QCOMPARE(subject->viewMenuIconID(), QString("")); + + subject->setViewMenuIconID(iconID); + QCOMPARE(subject->viewMenuIconID(), iconID); +} + +/* + * In this test I want to verify that when someone taps onto the navigation bar, + * widgets on the application page behind it won't get activated. + * + * In practice this means that the navigation bar should handle/accept ALL the + * input events that come to him. + */ +void Ut_DuiNavigationBar::noMouseEventPropagation() +{ + bool handledEvent; + QGraphicsSceneMouseEvent *mouseEvent = new QGraphicsSceneMouseEvent(QEvent::GraphicsSceneMousePress); + + mouseEvent->setButtons(Qt::LeftButton); + + // Add it to the scene + QGraphicsScene *scene = new QGraphicsScene; + scene->addItem(subject); + + handledEvent = subject->scene()->sendEvent(subject, mouseEvent); + scene->removeItem(subject); + delete scene; + + QVERIFY(mouseEvent->isAccepted()); + QVERIFY(handledEvent); +} + +QTEST_APPLESS_MAIN(Ut_DuiNavigationBar) diff --git a/tests/ut_duinavigationbar/ut_duinavigationbar.h b/tests/ut_duinavigationbar/ut_duinavigationbar.h new file mode 100644 index 000000000..8602b0a48 --- /dev/null +++ b/tests/ut_duinavigationbar/ut_duinavigationbar.h @@ -0,0 +1,49 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUITEXTEDIT_H +#define UT_DUITEXTEDIT_H + +#include +#include + +class DuiNavigationBar; + +class Ut_DuiNavigationBar : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase(); + void cleanupTestCase(); + + void init(); + void cleanup(); + + void testConstructor(); + void testToolbar(); + void testViewMenuIconID(); + void noMouseEventPropagation(); + +private: + DuiNavigationBar *subject; +}; + +#endif // UT_DUINAVIGATIONBAR_H + diff --git a/tests/ut_duinavigationbar/ut_duinavigationbar.pro b/tests/ut_duinavigationbar/ut_duinavigationbar.pro new file mode 100644 index 000000000..cc0d46453 --- /dev/null +++ b/tests/ut_duinavigationbar/ut_duinavigationbar.pro @@ -0,0 +1,13 @@ +include(../common_top.pri) + +TARGET = ut_duinavigationbar + +INCLUDEPATH += $$DUISRCDIR/widgets $$DUISRCDIR/style $$DUISRCDIR/scene + +SOURCES += \ + ut_duinavigationbar.cpp \ + +HEADERS += \ + ut_duinavigationbar.h + +include(../common_bot.pri) diff --git a/tests/ut_duinotification/.gitignore b/tests/ut_duinotification/.gitignore new file mode 100644 index 000000000..453d60a89 --- /dev/null +++ b/tests/ut_duinotification/.gitignore @@ -0,0 +1 @@ +ut_duinotification diff --git a/tests/ut_duinotification/ut_duinotification.cpp b/tests/ut_duinotification/ut_duinotification.cpp new file mode 100644 index 000000000..c8c34c934 --- /dev/null +++ b/tests/ut_duinotification/ut_duinotification.cpp @@ -0,0 +1,56 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duinotification.h" +#include "duinotification.h" +#include +#include +#include +#include + +void Ut_DuiNotification::initTestCase() +{ +} + +void Ut_DuiNotification::cleanupTestCase() +{ +} + +void Ut_DuiNotification::init() +{ +} + +void Ut_DuiNotification::cleanup() +{ +} + +void Ut_DuiNotification::testGettingAllNotifications() +{ + QList idList; + idList << 1 << 5 << 3 << 42 << 100; + gDefaultDuiNotificationManagerStub.stubSetReturnValue("notificationIdList", idList); + + QList notificationList = DuiNotification::notifications(); + QCOMPARE(notificationList.count(), idList.count()); + foreach(DuiNotification * notification, notificationList) { + QVERIFY(idList.contains(notification->id())); + } +} + +QTEST_APPLESS_MAIN(Ut_DuiNotification) diff --git a/tests/ut_duinotification/ut_duinotification.h b/tests/ut_duinotification/ut_duinotification.h new file mode 100644 index 000000000..2aa379ab6 --- /dev/null +++ b/tests/ut_duinotification/ut_duinotification.h @@ -0,0 +1,48 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUINOTIFICATION_H +#define UT_DUINOTIFICATION_H + +#include +#include +#include +#include + +class DuiNotification; + +class Ut_DuiNotification : public QObject +{ + Q_OBJECT + +private slots: + // Called before the first testfunction is executed + void initTestCase(); + // Called after the last testfunction was executed + void cleanupTestCase(); + // Called before each testfunction is executed + void init(); + // Called after every testfunction + void cleanup(); + // Test quering of notifications + void testGettingAllNotifications(); +}; + +#endif + diff --git a/tests/ut_duinotification/ut_duinotification.pro b/tests/ut_duinotification/ut_duinotification.pro new file mode 100644 index 000000000..1665112e7 --- /dev/null +++ b/tests/ut_duinotification/ut_duinotification.pro @@ -0,0 +1,23 @@ +include(../common_top.pri) +TARGET = ut_duinotification +INCLUDEPATH += $$DUISRCDIR/notification + +# unit test and unit +SOURCES += \ + ut_duinotification.cpp \ + $$DUISRCDIR/notification/duinotification.cpp + +# service classes +SOURCES += \ + $$STUBSDIR/stubbase.cpp \ + +# unit test and unit +HEADERS += \ + ut_duinotification.h \ + $$DUISRCDIR/notification/duinotification.h \ + $$DUISRCDIR/notification/duinotificationmanager.h \ + $$DUISRCDIR/notification/duinotificationmanagerproxy.h \ + $$DUISRCDIR/core/duiremoteaction.h \ + $$DUISRCDIR/core/duiaction.h + +include(../common_bot.pri) diff --git a/tests/ut_duinotificationmanager/.gitignore b/tests/ut_duinotificationmanager/.gitignore new file mode 100644 index 000000000..74299fe6f --- /dev/null +++ b/tests/ut_duinotificationmanager/.gitignore @@ -0,0 +1 @@ +ut_duinotificationmanager diff --git a/tests/ut_duinotificationmanager/ut_duinotificationmanager.cpp b/tests/ut_duinotificationmanager/ut_duinotificationmanager.cpp new file mode 100644 index 000000000..582500f00 --- /dev/null +++ b/tests/ut_duinotificationmanager/ut_duinotificationmanager.cpp @@ -0,0 +1,400 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duinotificationmanager.h" +#include "duinotificationmanager.h" +#include "duinotification.h" +#include "duinotificationgroup.h" +#include "duiremoteaction.h" +#include "duifiledatastore.h" +#include + +bool Ut_DuiNotificationManager::captureCalls = false; +QList Ut_DuiNotificationManager::asyncCallMethods; +QList< QList > Ut_DuiNotificationManager::asyncCallArguments; +QHash Ut_DuiNotificationManager::mockStore; + +DuiApplication *DuiApplication::instance() +{ + return reinterpret_cast(1); +} + +QString DuiApplication::appName() +{ + static QString name("ut_duinotificationmanager"); + return name; +} + + +DuiFileDataStore::DuiFileDataStore(const QString &) +{ +} + +bool DuiFileDataStore::isReadable() const +{ + return true; +} + +bool DuiFileDataStore::isWritable() const +{ + return true; +} + +bool DuiFileDataStore::contains(const QString &key) const +{ + return Ut_DuiNotificationManager::mockStore.contains(key); +} + +bool DuiFileDataStore::createValue(const QString &key, const QVariant &value) +{ + Ut_DuiNotificationManager::mockStore.insert(key, value); + return true; +} + +QVariant DuiFileDataStore::value(const QString &key) const +{ + return Ut_DuiNotificationManager::mockStore.value(key); +} + +bool QDir::mkdir(const QString &) const +{ + return true; +} + +bool QDir::exists(const QString &) const +{ + return true; +} + +class TestRemoteAction : public DuiRemoteAction +{ +public: + TestRemoteAction(const QString &serviceName, const QString &objectPath, const QString &interface, const QString &methodName, const QList &arguments, QObject *parent = NULL); +}; + +TestRemoteAction::TestRemoteAction(const QString &serviceName, const QString &objectPath, const QString &interface, const QString &methodName, const QList &arguments, QObject *parent) : DuiRemoteAction(serviceName, objectPath, interface, methodName, arguments, parent) +{ +} + +// QDBusInterface stubs (used by DuiRemoteAction) +QDBusInterface::QDBusInterface(const QString &service, const QString &path, const QString &interface, const QDBusConnection &connection, QObject *parent) : QDBusAbstractInterface(service, path, interface.toUtf8().constData(), connection, parent) +{ +} + +QDBusInterface::~QDBusInterface() +{ +} + +// DuiNotificationManagerProxy stubs (used by DuiNotificationManager) +DuiNotificationManagerProxy::DuiNotificationManagerProxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) + : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) +{ +} + +DuiNotificationManagerProxy::~DuiNotificationManagerProxy() +{ +} + +// QDBusAbstractInterface stubs (used by DuiNotificationManagerProxy) +QDBusPendingCall QDBusAbstractInterface::asyncCallWithArgumentList(const QString &method, const QList & args) +{ + if (Ut_DuiNotificationManager::captureCalls) { + Ut_DuiNotificationManager::asyncCallMethods.append(method); + Ut_DuiNotificationManager::asyncCallArguments.append(args); + } + + QDBusPendingReply reply; + return reply; +} + +QDBusMessage QDBusAbstractInterface::callWithArgumentList(QDBus::CallMode, const QString &, const QList &) +{ + return QDBusMessage(); +} + +// QDBusPendingReplyData stubs (used by DuiNotificationManagerProxy) +QVariant QDBusPendingReplyData::argumentAt(int) const +{ + return QVariant(1); +} + +void QDBusPendingReplyData::setMetaTypes(int, const int *) +{ +} + +void Ut_DuiNotificationManager::initTestCase() +{ + // Clear the static members + captureCalls = true; + asyncCallMethods.clear(); + asyncCallArguments.clear(); + + // The manager should ask for the notification user ID (which will be stubbed to be 1) + DuiNotification notification1("event"); + QCOMPARE(asyncCallMethods.count(), 2); + QCOMPARE(asyncCallMethods.at(0), QString("notificationUserId")); + QCOMPARE(asyncCallArguments.count(), 2); + QCOMPARE(asyncCallArguments.at(0).count(), 0); + + // Check that the new user id was saved correctly + QCOMPARE(mockStore.value("id/ut_duinotificationmanager").toUInt(), (uint)1); + + notificationUserId = 1; +} + +void Ut_DuiNotificationManager::cleanupTestCase() +{ +} + +void Ut_DuiNotificationManager::init() +{ + // Clear the static members + captureCalls = true; + asyncCallMethods.clear(); + asyncCallArguments.clear(); +} + +void Ut_DuiNotificationManager::cleanup() +{ +} + +void Ut_DuiNotificationManager::testAddNotification() +{ + DuiNotification notification1("event"); + QCOMPARE(asyncCallMethods.count(), 1); + QCOMPARE(asyncCallMethods.at(0), QString("addNotification")); + QCOMPARE(asyncCallArguments.count(), 1); + QCOMPARE(asyncCallArguments.at(0).count(), 4); + QCOMPARE(asyncCallArguments.at(0).at(0), QVariant(notificationUserId)); + QCOMPARE(asyncCallArguments.at(0).at(1), QVariant(0)); + QCOMPARE(asyncCallArguments.at(0).at(2), QVariant("event")); + QCOMPARE(asyncCallArguments.at(0).at(3), QVariant(false)); + + asyncCallMethods.clear(); + asyncCallArguments.clear(); + + QList arguments; + TestRemoteAction action("serviceName", "objectPath", "interface", "methodName", arguments); + DuiNotification notification2("event", "summary", "body", "imageURI", action, 42, true); + QCOMPARE(asyncCallMethods.count(), 1); + QCOMPARE(asyncCallMethods.at(0), QString("addNotification")); + QCOMPARE(asyncCallArguments.count(), 1); + QCOMPARE(asyncCallArguments.at(0).count(), 9); + QCOMPARE(asyncCallArguments.at(0).at(0), QVariant(notificationUserId)); + QCOMPARE(asyncCallArguments.at(0).at(1), QVariant(0)); + QCOMPARE(asyncCallArguments.at(0).at(2), QVariant("event")); + QCOMPARE(asyncCallArguments.at(0).at(3), QVariant("summary")); + QCOMPARE(asyncCallArguments.at(0).at(4), QVariant("body")); + QCOMPARE(asyncCallArguments.at(0).at(5), QVariant(action.toString())); + QCOMPARE(asyncCallArguments.at(0).at(6), QVariant("imageURI")); + QCOMPARE(asyncCallArguments.at(0).at(7), QVariant("42")); + QCOMPARE(asyncCallArguments.at(0).at(8), QVariant(true)); +} + +void Ut_DuiNotificationManager::testUpdateNotification() +{ + DuiNotification notification1("event"); + asyncCallMethods.clear(); + asyncCallArguments.clear(); + + notification1.update("event"); + QCOMPARE(asyncCallMethods.count(), 1); + QCOMPARE(asyncCallMethods.at(0), QString("updateNotification")); + QCOMPARE(asyncCallArguments.count(), 1); + QCOMPARE(asyncCallArguments.at(0).count(), 3); + QCOMPARE(asyncCallArguments.at(0).at(0), QVariant(notificationUserId)); + QCOMPARE(asyncCallArguments.at(0).at(1), QVariant(notification1.id())); + QCOMPARE(asyncCallArguments.at(0).at(2), QVariant("event")); + + asyncCallMethods.clear(); + asyncCallArguments.clear(); + + DuiNotification notification2("event"); + asyncCallMethods.clear(); + asyncCallArguments.clear(); + + QList arguments; + TestRemoteAction action("serviceName", "objectPath", "interface", "methodName", arguments); + notification2.update("event", "summary", "body", "imageURI", 42, action); + QCOMPARE(asyncCallMethods.count(), 1); + QCOMPARE(asyncCallMethods.at(0), QString("updateNotification")); + QCOMPARE(asyncCallArguments.count(), 1); + QCOMPARE(asyncCallArguments.at(0).count(), 8); + QCOMPARE(asyncCallArguments.at(0).at(0), QVariant(notificationUserId)); + QCOMPARE(asyncCallArguments.at(0).at(1), QVariant(notification2.id())); + QCOMPARE(asyncCallArguments.at(0).at(2), QVariant("event")); + QCOMPARE(asyncCallArguments.at(0).at(3), QVariant("summary")); + QCOMPARE(asyncCallArguments.at(0).at(4), QVariant("body")); + QCOMPARE(asyncCallArguments.at(0).at(5), QVariant(action.toString())); + QCOMPARE(asyncCallArguments.at(0).at(6), QVariant("imageURI")); + QCOMPARE(asyncCallArguments.at(0).at(7), QVariant("42")); +} + +void Ut_DuiNotificationManager::testRemoveNotification() +{ + DuiNotification notification("event"); + asyncCallMethods.clear(); + asyncCallArguments.clear(); + + int id = notification.id(); + notification.remove(); + QCOMPARE(asyncCallMethods.count(), 1); + QCOMPARE(asyncCallMethods.at(0), QString("removeNotification")); + QCOMPARE(asyncCallArguments.count(), 1); + QCOMPARE(asyncCallArguments.at(0).count(), 2); + QCOMPARE(asyncCallArguments.at(0).at(0), QVariant(notificationUserId)); + QCOMPARE(asyncCallArguments.at(0).at(1), QVariant(id)); +} + +void Ut_DuiNotificationManager::testAddGroup() +{ + DuiNotificationGroup group1("event"); + QCOMPARE(asyncCallMethods.count(), 1); + QCOMPARE(asyncCallMethods.at(0), QString("addGroup")); + QCOMPARE(asyncCallArguments.count(), 1); + QCOMPARE(asyncCallArguments.at(0).count(), 3); + QCOMPARE(asyncCallArguments.at(0).at(0), QVariant(notificationUserId)); + QCOMPARE(asyncCallArguments.at(0).at(1), QVariant("event")); + QCOMPARE(asyncCallArguments.at(0).at(2), QVariant(false)); + + asyncCallMethods.clear(); + asyncCallArguments.clear(); + + QList arguments; + TestRemoteAction action("serviceName", "objectPath", "interface", "methodName", arguments); + DuiNotificationGroup group2("event", "summary", "body", "imageURI", action, 42, false); + QCOMPARE(asyncCallMethods.count(), 1); + QCOMPARE(asyncCallMethods.at(0), QString("addGroup")); + QCOMPARE(asyncCallArguments.count(), 1); + QCOMPARE(asyncCallArguments.at(0).count(), 8); + QCOMPARE(asyncCallArguments.at(0).at(0), QVariant(notificationUserId)); + QCOMPARE(asyncCallArguments.at(0).at(1), QVariant("event")); + QCOMPARE(asyncCallArguments.at(0).at(2), QVariant("summary")); + QCOMPARE(asyncCallArguments.at(0).at(3), QVariant("body")); + QCOMPARE(asyncCallArguments.at(0).at(4), QVariant(action.toString())); + QCOMPARE(asyncCallArguments.at(0).at(5), QVariant("imageURI")); + QCOMPARE(asyncCallArguments.at(0).at(6), QVariant("42")); + QCOMPARE(asyncCallArguments.at(0).at(7), QVariant(false)); +} + +void Ut_DuiNotificationManager::testUpdateGroup() +{ + DuiNotificationGroup group1("event"); + asyncCallMethods.clear(); + asyncCallArguments.clear(); + + group1.update("event"); + QCOMPARE(asyncCallMethods.count(), 1); + QCOMPARE(asyncCallMethods.at(0), QString("updateGroup")); + QCOMPARE(asyncCallArguments.count(), 1); + QCOMPARE(asyncCallArguments.at(0).count(), 3); + QCOMPARE(asyncCallArguments.at(0).at(0), QVariant(notificationUserId)); + QCOMPARE(asyncCallArguments.at(0).at(1), QVariant(group1.id())); + QCOMPARE(asyncCallArguments.at(0).at(2), QVariant("event")); + + asyncCallMethods.clear(); + asyncCallArguments.clear(); + + QList arguments; + TestRemoteAction action("serviceName", "objectPath", "interface", "methodName", arguments); + DuiNotificationGroup group2("event", "summary", "body", "imageURI", action); + asyncCallMethods.clear(); + asyncCallArguments.clear(); + + group2.update("event", "summary", "body", "imageURI", 42, action); + QCOMPARE(asyncCallMethods.count(), 1); + QCOMPARE(asyncCallMethods.at(0), QString("updateGroup")); + QCOMPARE(asyncCallArguments.count(), 1); + QCOMPARE(asyncCallArguments.at(0).count(), 8); + QCOMPARE(asyncCallArguments.at(0).at(0), QVariant(notificationUserId)); + QCOMPARE(asyncCallArguments.at(0).at(1), QVariant(group2.id())); + QCOMPARE(asyncCallArguments.at(0).at(2), QVariant("event")); + QCOMPARE(asyncCallArguments.at(0).at(3), QVariant("summary")); + QCOMPARE(asyncCallArguments.at(0).at(4), QVariant("body")); + QCOMPARE(asyncCallArguments.at(0).at(5), QVariant(action.toString())); + QCOMPARE(asyncCallArguments.at(0).at(6), QVariant("imageURI")); + QCOMPARE(asyncCallArguments.at(0).at(7), QVariant("42")); +} + +void Ut_DuiNotificationManager::testRemoveGroup() +{ + QList arguments; + TestRemoteAction action("serviceName", "objectPath", "interface", "methodName", arguments); + DuiNotificationGroup group("event", "summary", "body", "imageURI", action); + asyncCallMethods.clear(); + asyncCallArguments.clear(); + + int id = group.id(); + group.remove(); + QCOMPARE(asyncCallMethods.count(), 1); + QCOMPARE(asyncCallMethods.at(0), QString("removeGroup")); + QCOMPARE(asyncCallArguments.count(), 1); + QCOMPARE(asyncCallArguments.at(0).count(), 2); + QCOMPARE(asyncCallArguments.at(0).at(0), QVariant(notificationUserId)); + QCOMPARE(asyncCallArguments.at(0).at(1), QVariant(id)); +} + +void Ut_DuiNotificationManager::testAddToGroup() +{ + DuiNotificationGroup group1("event"); + asyncCallMethods.clear(); + asyncCallArguments.clear(); + + DuiNotification notification1(group1, "event"); + QCOMPARE(asyncCallMethods.count(), 1); + QCOMPARE(asyncCallMethods.at(0), QString("addNotification")); + QCOMPARE(asyncCallArguments.count(), 1); + QCOMPARE(asyncCallArguments.at(0).count(), 4); + QCOMPARE(asyncCallArguments.at(0).at(0), QVariant(notificationUserId)); + QCOMPARE(asyncCallArguments.at(0).at(1), QVariant(group1.id())); + QCOMPARE(asyncCallArguments.at(0).at(2), QVariant("event")); + QCOMPARE(asyncCallArguments.at(0).at(3), QVariant(false)); + + QList arguments; + TestRemoteAction action("serviceName", "objectPath", "interface", "methodName", arguments); + DuiNotificationGroup group2("event", "summary", "body", "imageURI", action); + asyncCallMethods.clear(); + asyncCallArguments.clear(); + + DuiNotification notification2(group2, "event", "summary", "body", "imageURI", action); + QCOMPARE(asyncCallMethods.count(), 1); + QCOMPARE(asyncCallMethods.at(0), QString("addNotification")); + QCOMPARE(asyncCallArguments.count(), 1); + QCOMPARE(asyncCallArguments.at(0).count(), 9); + QCOMPARE(asyncCallArguments.at(0).at(0), QVariant(notificationUserId)); + QCOMPARE(asyncCallArguments.at(0).at(1), QVariant(group2.id())); + QCOMPARE(asyncCallArguments.at(0).at(2), QVariant("event")); + QCOMPARE(asyncCallArguments.at(0).at(3), QVariant("summary")); + QCOMPARE(asyncCallArguments.at(0).at(4), QVariant("body")); + QCOMPARE(asyncCallArguments.at(0).at(5), QVariant(action.toString())); + QCOMPARE(asyncCallArguments.at(0).at(6), QVariant("imageURI")); + QCOMPARE(asyncCallArguments.at(0).at(7), QVariant("1")); + QCOMPARE(asyncCallArguments.at(0).at(8), QVariant(false)); +} + +void Ut_DuiNotificationManager::testNotificationIdList() +{ + DuiNotificationManager::instance()->notificationIdList(); + QCOMPARE(asyncCallMethods.count(), 1); + QCOMPARE(asyncCallMethods.at(0), QString("notificationIdList")); + QCOMPARE(asyncCallArguments.count(), 1); + QCOMPARE(asyncCallArguments.at(0).at(0), QVariant(1)); +} + +QTEST_APPLESS_MAIN(Ut_DuiNotificationManager) diff --git a/tests/ut_duinotificationmanager/ut_duinotificationmanager.h b/tests/ut_duinotificationmanager/ut_duinotificationmanager.h new file mode 100644 index 000000000..1ab7081b6 --- /dev/null +++ b/tests/ut_duinotificationmanager/ut_duinotificationmanager.h @@ -0,0 +1,71 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUINOTIFICATIONMANAGER_H +#define UT_DUINOTIFICATIONMANAGER_H + +#include +#include +#include +#include +#include + +class Ut_DuiNotificationManager : public QObject +{ + Q_OBJECT + +public: + static bool captureCalls; + static QList asyncCallMethods; + static QList< QList > asyncCallArguments; + static QHash mockStore; + +private: + // The notification user ID returned by the manager + uint notificationUserId; + +private slots: + // Called before the first testfunction is executed + void initTestCase(); + // Called after the last testfunction was executed + void cleanupTestCase(); + // Called before each testfunction is executed + void init(); + // Called after every testfunction + void cleanup(); + + // Test notification adding + void testAddNotification(); + // Test notification updating + void testUpdateNotification(); + // Test notification removal + void testRemoveNotification(); + // Test notification group adding + void testAddGroup(); + // Test notification group updating + void testUpdateGroup(); + // Test notification group removal + void testRemoveGroup(); + // Test adding a notification into a notification group + void testAddToGroup(); + // Test quering of notifications + void testNotificationIdList(); +}; + +#endif diff --git a/tests/ut_duinotificationmanager/ut_duinotificationmanager.pro b/tests/ut_duinotificationmanager/ut_duinotificationmanager.pro new file mode 100644 index 000000000..0d669fce3 --- /dev/null +++ b/tests/ut_duinotificationmanager/ut_duinotificationmanager.pro @@ -0,0 +1,24 @@ +include(../common_top.pri) +TARGET = ut_duinotificationmanager +INCLUDEPATH += $$DUISRCDIR/notification \ + $$DUISRCDIR/mashup/mashup + +# unit test and unit +SOURCES += \ + ut_duinotificationmanager.cpp \ + $$DUISRCDIR/notification/duinotificationmanager.cpp \ + $$DUISRCDIR/notification/duinotification.cpp \ + $$DUISRCDIR/notification/duinotificationgroup.cpp + +# unit test and unit +HEADERS += \ + ut_duinotificationmanager.h \ + $$DUISRCDIR/notification/duinotificationmanager.h \ + $$DUISRCDIR/notification/duinotification.h \ + $$DUISRCDIR/notification/duinotificationgroup.h + +# service classes +HEADERS += \ + $$DUISRCDIR/notification/duinotificationmanagerproxy.h + +include(../common_bot.pri) diff --git a/tests/ut_duiobjectmenu/.gitignore b/tests/ut_duiobjectmenu/.gitignore new file mode 100644 index 000000000..19ca8be43 --- /dev/null +++ b/tests/ut_duiobjectmenu/.gitignore @@ -0,0 +1,2 @@ +ut_duiobjectmenu + diff --git a/tests/ut_duiobjectmenu/ut_duiobjectmenu.cpp b/tests/ut_duiobjectmenu/ut_duiobjectmenu.cpp new file mode 100644 index 000000000..f99b75b7e --- /dev/null +++ b/tests/ut_duiobjectmenu/ut_duiobjectmenu.cpp @@ -0,0 +1,130 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duiobjectmenu.h" + +#include +#include +#include + +void Ut_DuiObjectMenu::init() +{ +} + +void Ut_DuiObjectMenu::cleanup() +{ +} + +DuiApplication *app; + +void Ut_DuiObjectMenu::initTestCase() +{ + int argc = 1; + char *app_name = (char *) "./ut_duiobjectmenu"; + app = new DuiApplication(argc, &app_name); +} + +void Ut_DuiObjectMenu::cleanupTestCase() +{ + delete app; +} + +void Ut_DuiObjectMenu::testConstructionAndDestruction() +{ + DuiWidget *widget = new DuiWidget(); + DuiObjectMenu *menu = new DuiObjectMenu(widget); + DuiObjectMenuModel *model = dynamic_cast(menu->model()); + + // check that the model has been created. + QVERIFY(model != NULL); + + // check that the action count is zero + QVERIFY(model->actions().count() == 0); + + delete menu; + delete widget; +} + +void Ut_DuiObjectMenu::testActionsAddingAndRemoving() +{ + DuiWidget *widget = new DuiWidget(); + DuiAction *action1 = new DuiAction("Test1", widget); + action1->setLocation(DuiAction::ObjectMenuLocation); + widget->addAction(action1); + + DuiObjectMenu *menu = new DuiObjectMenu(widget); + DuiObjectMenuModel *model = dynamic_cast(menu->model()); + + // check that the model has the action + QCOMPARE(model->actions().count(), 1); + QCOMPARE(model->actions().at(0), action1); + + QSignalSpy addedSpy(model, SIGNAL(actionAdded(DuiAction *))); + QSignalSpy removedSpy(model, SIGNAL(actionRemoved(DuiAction *))); + QSignalSpy modifiedSpy(model, SIGNAL(actionModified(DuiAction *))); + + DuiAction *action2 = new DuiAction("Test2", widget); + + // check that we don't get the signal yet. + QCOMPARE(addedSpy.count(), 0); + + action2->setLocation(DuiAction::ObjectMenuLocation); + + widget->addAction(action2); + QCOMPARE(addedSpy.count(), 1); + QCOMPARE(removedSpy.count(), 0); + QCOMPARE(modifiedSpy.count(), 0); + QCOMPARE(model->actions().count(), 2); + QCOMPARE(model->actions().at(0), action1); + QCOMPARE(model->actions().at(1), action2); + + widget->removeAction(action1); + QCOMPARE(addedSpy.count(), 1); + QCOMPARE(removedSpy.count(), 1); + QCOMPARE(modifiedSpy.count(), 0); + QCOMPARE(model->actions().count(), 1); + QCOMPARE(model->actions().at(0), action2); + + widget->addAction(action1); + QCOMPARE(addedSpy.count(), 2); + QCOMPARE(removedSpy.count(), 1); + QCOMPARE(modifiedSpy.count(), 0); + QCOMPARE(model->actions().count(), 2); + QCOMPARE(model->actions().at(0), action2); + QCOMPARE(model->actions().at(1), action1); + + action2->setText("Test123"); + QCOMPARE(addedSpy.count(), 2); + QCOMPARE(removedSpy.count(), 1); + QCOMPARE(modifiedSpy.count(), 1); + QCOMPARE(model->actions().count(), 2); + QCOMPARE(model->actions().at(0), action2); + QCOMPARE(model->actions().at(1), action1); + + + action1->setText("Test234"); + QCOMPARE(addedSpy.count(), 2); + QCOMPARE(removedSpy.count(), 1); + QCOMPARE(modifiedSpy.count(), 2); + QCOMPARE(model->actions().count(), 2); + QCOMPARE(model->actions().at(0), action2); + QCOMPARE(model->actions().at(1), action1); +} + +QTEST_APPLESS_MAIN(Ut_DuiObjectMenu) diff --git a/tests/ut_duiobjectmenu/ut_duiobjectmenu.h b/tests/ut_duiobjectmenu/ut_duiobjectmenu.h new file mode 100644 index 000000000..fcce39ecd --- /dev/null +++ b/tests/ut_duiobjectmenu/ut_duiobjectmenu.h @@ -0,0 +1,48 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIBUTTON_H +#define UT_DUIBUTTON_H + +#include +#include + +#include +#include +#include + +Q_DECLARE_METATYPE(DuiAction *); + +class Ut_DuiObjectMenu : public QObject +{ + Q_OBJECT + +private slots: + void init(); + void cleanup(); + void initTestCase(); + void cleanupTestCase(); + + void testConstructionAndDestruction(); + void testActionsAddingAndRemoving(); + +private: +}; + +#endif diff --git a/tests/ut_duiobjectmenu/ut_duiobjectmenu.pro b/tests/ut_duiobjectmenu/ut_duiobjectmenu.pro new file mode 100644 index 000000000..9c1737999 --- /dev/null +++ b/tests/ut_duiobjectmenu/ut_duiobjectmenu.pro @@ -0,0 +1,17 @@ +include(../common_top.pri) +INCLUDEPATH += $$DUISRCDIR/widgets $$DUISRCDIR/style + +TARGET = ut_duiobjectmenu + +# unit +TEST_SOURCES = \ + +# unit test and unit +SOURCES += \ + ut_duiobjectmenu.cpp \ + +# unit test and unit +HEADERS += \ + ut_duiobjectmenu.h \ + +include(../common_bot.pri) diff --git a/tests/ut_duioverlay/.gitignore b/tests/ut_duioverlay/.gitignore new file mode 100644 index 000000000..32350546c --- /dev/null +++ b/tests/ut_duioverlay/.gitignore @@ -0,0 +1 @@ +ut_duioverlay diff --git a/tests/ut_duioverlay/ut_duioverlay.cpp b/tests/ut_duioverlay/ut_duioverlay.cpp new file mode 100644 index 000000000..b1839a4ec --- /dev/null +++ b/tests/ut_duioverlay/ut_duioverlay.cpp @@ -0,0 +1,77 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include +#include "duioverlay_p.h" +#include +#include "ut_duioverlay.h" +#include "duiapplication.h" +#include "duioverlaystyle.h" + +void Ut_DuiOverlay::init() +{ + m_subject = new DuiOverlay(); +} + +void Ut_DuiOverlay::cleanup() +{ + delete m_subject; + m_subject = 0; +} + +DuiApplication *app; + +void Ut_DuiOverlay::initTestCase() +{ + static int argc = 1; + static char *app_name[1] = { (char *) "./ut_duioverlay" }; + app = new DuiApplication(argc, app_name); +} + +void Ut_DuiOverlay::cleanupTestCase() +{ + delete app; + app = 0; +} + +void Ut_DuiOverlay::constructor() +{ + QVERIFY(m_subject); + + // verify that model has been set + QVERIFY(m_subject->model()); + // verify that view has been set + QVERIFY(m_subject->view()); + + // verify that the widget was instantiated + QVERIFY(m_subject->widget()); +} + +void Ut_DuiOverlay::setWidget() +{ + DuiWidget *widget = new DuiWidget(); + m_subject->setWidget(widget); + + QCOMPARE(m_subject->widget(), widget); + delete widget; +} + +QTEST_APPLESS_MAIN(Ut_DuiOverlay) diff --git a/tests/ut_duioverlay/ut_duioverlay.h b/tests/ut_duioverlay/ut_duioverlay.h new file mode 100644 index 000000000..d0341f6d5 --- /dev/null +++ b/tests/ut_duioverlay/ut_duioverlay.h @@ -0,0 +1,48 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIOVERLAY_H +#define UT_DUIOVERLAY_H + +#include +#include + +#include + +Q_DECLARE_METATYPE(DuiOverlay *); + +class Ut_DuiOverlay : public QObject +{ + Q_OBJECT + +private slots: + void init(); + void cleanup(); + void initTestCase(); + void cleanupTestCase(); + + void constructor(); + + void setWidget(); + +private: + DuiOverlay *m_subject; +}; + +#endif diff --git a/tests/ut_duioverlay/ut_duioverlay.pro b/tests/ut_duioverlay/ut_duioverlay.pro new file mode 100644 index 000000000..e588c2ca0 --- /dev/null +++ b/tests/ut_duioverlay/ut_duioverlay.pro @@ -0,0 +1,18 @@ +include(../common_top.pri) +INCLUDEPATH += $$DUISRCDIR/widgets $$DUISRCDIR/style + +TARGET = ut_duioverlay + +# unit +TEST_SOURCES = \ +# $$DUISRCDIR/duioverlay.cpp \ + +# unit test and unit +SOURCES += \ + ut_duioverlay.cpp \ + +# unit test and unit +HEADERS += \ + ut_duioverlay.h \ + +include(../common_bot.pri) diff --git a/tests/ut_duipannableviewport/.gitignore b/tests/ut_duipannableviewport/.gitignore new file mode 100644 index 000000000..4848ab1be --- /dev/null +++ b/tests/ut_duipannableviewport/.gitignore @@ -0,0 +1 @@ +ut_duipannableviewport diff --git a/tests/ut_duipannableviewport/ut_duipannableviewport.cpp b/tests/ut_duipannableviewport/ut_duipannableviewport.cpp new file mode 100644 index 000000000..9b78ebd28 --- /dev/null +++ b/tests/ut_duipannableviewport/ut_duipannableviewport.cpp @@ -0,0 +1,249 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duipannableviewport.h" +#include +#include +#include "../../src/widgets/duipannableviewport_p.h" +#include +#include +#include +#include +#include + +DuiApplication *app; + +void Ut_DuiPannableViewport::initTestCase() +{ + static int argc = 1; + static char *app_name[1] = { (char *) "./ut_duipannableviewport" }; + app = new DuiApplication(argc, app_name); +} + + +void Ut_DuiPannableViewport::cleanupTestCase() +{ + delete app; +} + + +void Ut_DuiPannableViewport::init() +{ + subject = new DuiPannableViewport(); +} + +void Ut_DuiPannableViewport::cleanup() +{ + delete subject; + subject = 0; +} + +void Ut_DuiPannableViewport::constructor() +{ + QCOMPARE(subject->flags(), QGraphicsItem::ItemClipsChildrenToShape); +} + +void Ut_DuiPannableViewport::setWidget() +{ + QGraphicsWidget *widget = new QGraphicsWidget(); + subject->setWidget(widget); + + widget->setZValue(1); + QCOMPARE(widget->zValue(), 1.0); + + QCOMPARE(static_cast(subject->d_ptr)->pannedWidget, widget); + QCOMPARE(static_cast(subject->d_ptr)->pannedWidget->parentItem(), subject); + + /* There is a bug in duipannableviewport that causes this testcase to crash + * randomly, deleting widget and setting it to 0 seems to make this + * testcase to work but it might hide the actual bug from test! So, this + * code is here just for a reference - Jani Mikkonen + * + * delete widget; + * widget = 0; + * */ +} + +void Ut_DuiPannableViewport::setGeometry_data() +{ + QTest::addColumn< QSizeF >("viewportSize"); + QTest::addColumn< QSizeF >("pannedSize"); + QTest::addColumn< QSizeF >("physicsRange"); + + QTest::newRow("set 1") << QSizeF(100, 50) << QSizeF(400, 200) << QSizeF(300, 150); + QTest::newRow("set 2") << QSizeF(400, 50) << QSizeF(100, 200) << QSizeF(0, 150); + QTest::newRow("set 3") << QSizeF(100, 200) << QSizeF(400, 50) << QSizeF(300, 0); +} + +void Ut_DuiPannableViewport::setGeometry() +{ + QFETCH(QSizeF, viewportSize); + QFETCH(QSizeF, pannedSize); + QFETCH(QSizeF, physicsRange); + + QGraphicsWidget *widget = new QGraphicsWidget(); + widget->setMinimumSize(pannedSize); + widget->setMaximumSize(pannedSize); + + subject->setWidget(widget); + subject->setGeometry(QRectF(QPointF(), viewportSize)); + + QCOMPARE(subject->physics()->range().size(), physicsRange); + + /* There is a bug in duipannableviewport that causes this testcase to crash + * randomly, deleting widget and setting it to 0 seems to make this + * testcase to work but it might hide the actual bug from test! So, this + * code is here just for a reference - Jani Mikkonen + * + * delete widget; + * widget = 0; + * */ +} + +void Ut_DuiPannableViewport::event_data() +{ + QTest::addColumn< QSizeF >("viewportSize"); + QTest::addColumn< QSizeF >("pannedSize"); + QTest::addColumn< QSizeF >("physicsRange"); + + QTest::newRow("set 1") << QSizeF(100, 50) << QSizeF(400, 200) << QSizeF(300, 150); + QTest::newRow("set 2") << QSizeF(400, 50) << QSizeF(100, 200) << QSizeF(0, 150); + QTest::newRow("set 3") << QSizeF(100, 200) << QSizeF(400, 50) << QSizeF(300, 0); +} + +void Ut_DuiPannableViewport::event() +{ + QEvent *event = new QEvent(QEvent::LayoutRequest); + + QFETCH(QSizeF, viewportSize); + QFETCH(QSizeF, pannedSize); + QFETCH(QSizeF, physicsRange); + + QGraphicsWidget *widget = new QGraphicsWidget(); + // Forcing the size of panned widget + widget->setMinimumSize(pannedSize); + widget->setPreferredSize(pannedSize); + widget->setMaximumSize(pannedSize); + + // Forcing the size of subject + subject->setMinimumSize(viewportSize); + subject->setPreferredSize(viewportSize); + subject->setMaximumSize(viewportSize); + + subject->setWidget(widget); + + subject->event(event); + + QCOMPARE(subject->physics()->range().size(), physicsRange); +} + +void Ut_DuiPannableViewport::updatePosition() +{ + + QGraphicsWidget *widget = new QGraphicsWidget(); + subject->setWidget(widget); + + // Forcing the size of subject to some value + subject->setMinimumSize(QSizeF(500, 300)); + subject->setMaximumSize(QSizeF(500, 300)); + + QSignalSpy spy(subject, SIGNAL(sizePosChanged(QSizeF, QRectF, QPointF))); + + subject->updatePosition(QPointF(-50, 75)); + + QCOMPARE(static_cast(subject->d_ptr)->pannedWidget->pos(), -QPointF(-50, 75)); + + QCOMPARE(spy.count(), 1); + + /* There is a bug in duipannableviewport that causes this testcase to crash + * randomly, deleting widget and setting it to 0 seems to make this + * testcase to work but it might hide the actual bug from test! So, this + * code is here just for a reference - Jani Mikkonen + * + * delete widget; + * widget = 0; + * */ +} + +void Ut_DuiPannableViewport::updateSamePosition() +{ + QGraphicsWidget *mainWidget = new QGraphicsWidget(); + QPointF point(0.0, 0.0); + + subject->setMinimumSize(100, 480); + subject->setPreferredSize(100, 480); + subject->setMaximumSize(100, 480); + + mainWidget->setMinimumSize(100, 1000); + mainWidget->setPreferredSize(100, 1000); + mainWidget->setMaximumSize(100, 1000); + + subject->setWidget(mainWidget); + + subject->updatePosition(point); + + QSignalSpy spy(subject, + SIGNAL(sizePosChanged(QSizeF, QRectF, QPointF))); + + subject->updatePosition(point); + + // Should not have emitted anything since nothing changed + QCOMPARE(spy.count(), 0); +} + +/* + * While the pannedWidget is populated, sizePosChanged() signal should be + * emitted only once for each actual change in pannedWidget's size. + * + * See NB#143428 + */ +void Ut_DuiPannableViewport::sizePosChangedAfterPopulatingPannedWidget() +{ + QGraphicsWidget *mainWidget = new QGraphicsWidget(); + QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(Qt::Vertical); + QGraphicsWidget *childWidget; + + mainWidget->setLayout(layout); + + subject->setWidget(mainWidget); + + QSignalSpy spy(subject, + SIGNAL(sizePosChanged(QSizeF, QRectF, QPointF))); + + for (int i = 0; i < 30; i++) { + childWidget = new QGraphicsWidget; + + childWidget->setMinimumSize(100, 200); + childWidget->setPreferredSize(100, 200); + + layout->addItem(childWidget); + } + + // Force layout to work. + subject->adjustSize(); + + // Check consecutive signals (if any), are different from each other. + // We don't want to send out the very same event twice. + for (int i = 1; i < spy.size(); i++) { + QVERIFY(spy.at(i) != spy.at(i - 1)); + } +} + + +QTEST_APPLESS_MAIN(Ut_DuiPannableViewport) diff --git a/tests/ut_duipannableviewport/ut_duipannableviewport.h b/tests/ut_duipannableviewport/ut_duipannableviewport.h new file mode 100644 index 000000000..a75b29bb7 --- /dev/null +++ b/tests/ut_duipannableviewport/ut_duipannableviewport.h @@ -0,0 +1,52 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIPANNABLEVIEWPORT_H +#define UT_DUIPANNABLEVIEWPORT_H + +#include + +#include + +class Ut_DuiPannableViewport : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase(); + void cleanupTestCase(); + + void init(); + void cleanup(); + + void constructor(); + void setWidget(); + void setGeometry_data(); + void setGeometry(); + void event_data(); + void event(); + void updatePosition(); + void updateSamePosition(); + void sizePosChangedAfterPopulatingPannedWidget(); + +private: + DuiPannableViewport *subject; +}; + +#endif diff --git a/tests/ut_duipannableviewport/ut_duipannableviewport.pro b/tests/ut_duipannableviewport/ut_duipannableviewport.pro new file mode 100644 index 000000000..c2c12a271 --- /dev/null +++ b/tests/ut_duipannableviewport/ut_duipannableviewport.pro @@ -0,0 +1,20 @@ +include(../common_top.pri) + +TARGET = ut_duipannableviewport + + +support_files.files += \ + ut_duipannableviewport_image.svg \ + ut_duipannableviewport_template.css\ + +TEST_SOURCES += \ + +# unit test and unit classes +SOURCES += \ + ut_duipannableviewport.cpp \ + +# unit test and unit classes +HEADERS += \ + ut_duipannableviewport.h \ + +include(../common_bot.pri) diff --git a/tests/ut_duipannableviewport/ut_duipannableviewport_image.svg b/tests/ut_duipannableviewport/ut_duipannableviewport_image.svg new file mode 100644 index 000000000..17b44a3af --- /dev/null +++ b/tests/ut_duipannableviewport/ut_duipannableviewport_image.svg @@ -0,0 +1,19615 @@ + + +image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Scroll-indicator + + + + + + + + + + + + + + + + + + + + + + Single Dots + + + + + + + + + Dot-accented + + Dot-empty + + Dot-default + + + + + + + \ No newline at end of file diff --git a/tests/ut_duipannablewidget/.gitignore b/tests/ut_duipannablewidget/.gitignore new file mode 100644 index 000000000..baa4c315e --- /dev/null +++ b/tests/ut_duipannablewidget/.gitignore @@ -0,0 +1 @@ +ut_duipannablewidget diff --git a/tests/ut_duipannablewidget/ut_duipannablewidget.cpp b/tests/ut_duipannablewidget/ut_duipannablewidget.cpp new file mode 100644 index 000000000..9f0570e81 --- /dev/null +++ b/tests/ut_duipannablewidget/ut_duipannablewidget.cpp @@ -0,0 +1,495 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duipannablewidget.h" +#include "duiapplication.h" +#include +#include +#include "../../src/widgets/duipannablewidget_p.h" +#include "../../src/widgets/duiphysics2dpanning_p.h" +#include + +#include +#include +#include + +/** Events that the test widget emits */ +typedef enum { +// START_TIMER, +// STOP_TIMER, + PHYS_STOP, + PHYS_MOUSE_PRESS, + PHYS_MOUSE_MOVE, + PHYS_MOUSE_RELEASE, + MOUSE_BUTTON_PRESS, + MOUSE_BUTTON_RELEASE, + MOUSE_MOVE, + UNGRAB_MOUSE +} StateTransitionEvent; + +/** Class indicating state of the pannable widget after a state transition. */ +class StateTransitionResult +{ +public: + StateTransitionResult(int targetState = 0) : + _targetState(targetState), _outputEvents(QList()) {} + StateTransitionResult(int targetState, QList expectedEvents) : + _targetState(targetState), _outputEvents(expectedEvents) {} + + /** Compares this result with another result using QTestLib compare. */ + void compare(const StateTransitionResult &result) const; + + /** State where the pannable widget should be. */ + int _targetState; + /** List of output events from test widget. */ + QList _outputEvents; +}; + +void StateTransitionResult::compare(const StateTransitionResult &result) const +{ + // Iterate through the output events and see that they match + QCOMPARE(_outputEvents.size(), result._outputEvents.size()); + QListIterator outputEvent(_outputEvents); + QListIterator resultEvent(result._outputEvents); + while (outputEvent.hasNext()) { + QCOMPARE(outputEvent.next(), resultEvent.next()); + } +} + +// Required to insert StateTransitionResult instances to the test data. +Q_DECLARE_METATYPE(StateTransitionResult); + +static Ut_DuiPannableWidget *gTester = 0; + +/* Using the QT timer methods rather than the stubbed ones. + * +// Mock methods of the services required by pannable widget. +void QTimer::start() +{ + qDebug("QTimer::start() - called."); + gTester->_currentResult->_outputEvents.push_back(START_TIMER); +} + + +void QTimer::stop() +{ + qDebug("QTimer::stop() - called."); + gTester->_currentResult->_outputEvents.push_back(STOP_TIMER); +} +*/ + +void DuiPhysics2DPanning::start() +{ + qDebug("Physics2DPanning::start() - called."); +} + +void QTimeLine::start() +{ + qDebug("QTimeLine::start() - called."); +} + +QWidget::QWidget(QWidget* /*parent*/, Qt::WindowFlags /*f*/) +{ + qDebug("QWidget::QWidget() - called."); +} + +QFrame::QFrame(QWidget* /*parent*/, Qt::WindowFlags /*f*/) +{ + qDebug("QFrame::QFrame() - called."); +} + +QAbstractScrollArea::QAbstractScrollArea(QWidget* /*parent*/) +{ + qDebug("QAbstractScrollArea::QAbstractScrollArea() - called."); +} + +QGraphicsView::QGraphicsView(QWidget* /*parent*/) +{ + qDebug("QGraphicsView::QGraphicsView() - called."); +} + +QGraphicsScene *QGraphicsItem::scene() const +{ + qDebug("QGraphicsItem::scene() - called."); + return 0; +} + +QGraphicsItem *QGraphicsScene::mouseGrabberItem() const +{ + qDebug("QGraphicsScene::mouseGrabberItem() - called"); + return 0; +} + +QList QGraphicsScene::items() const +{ + qDebug("QGraphicsScene::items() - called"); + QList list; + return list; +} + +QPointF QGraphicsItem::mapFromItem(const QGraphicsItem */*item*/, const QPointF &/*point*/) const +{ + qDebug("QGraphicsScene::mapFromItem() - called"); + return QPointF(); +} + +QList QGraphicsScene::views() const +{ + qDebug("QGraphicsScene::views() - called."); + return QList(); +} + +QPoint QGraphicsView::mapFromScene(const QPointF& /*point*/) const +{ + qDebug("QGraphicsView::mapFromScene() - called."); + return QPoint(); +} + +QWidget *QAbstractScrollArea::viewport() const +{ + qDebug("QAbstractScrollArea::viewport() - called."); + return 0; +} + +bool QGraphicsScene::sendEvent(QGraphicsItem *item, QEvent *event) +{ + Q_UNUSED(item); + Q_UNUSED(event); + qDebug("QGraphicsScene::sendEvent() - called."); + return true; +} + +void QCoreApplication::postEvent(QObject* /*receiver*/, QEvent *event) +{ + qDebug("QCoreApplication::postEvent() - called"); + if (event->type() == QEvent::MouseButtonPress) { + gTester->_currentResult->_outputEvents.push_back(MOUSE_BUTTON_PRESS); + } + if (event->type() == QEvent::MouseButtonRelease) { + gTester->_currentResult->_outputEvents.push_back(MOUSE_BUTTON_RELEASE); + } + if (event->type() == QEvent::MouseMove) { + gTester->_currentResult->_outputEvents.push_back(MOUSE_MOVE); + } +} + +void DuiPhysics2DPanning::stop() +{ + gTester->_currentResult->_outputEvents.push_back(PHYS_STOP); +} + +void DuiPhysics2DPanning::pointerPress(const QPointF& /*pos*/) +{ + gTester->_currentResult->_outputEvents.push_back(PHYS_MOUSE_PRESS); +} + +void DuiPhysics2DPanning::pointerMove(const QPointF& /*pos*/) +{ + gTester->_currentResult->_outputEvents.push_back(PHYS_MOUSE_MOVE); +} + +void DuiPhysics2DPanning::pointerRelease() +{ + gTester->_currentResult->_outputEvents.push_back(PHYS_MOUSE_RELEASE); +} + +void DuiPhysics2DPanning::integrator(int /*frame*/) +{ +} + +DuiApplication *app; + +void QGraphicsItem::ungrabMouse() +{ + gTester->_currentResult->_outputEvents.push_back(UNGRAB_MOUSE); +} + +void Ut_DuiPannableWidget::initTestCase() +{ + static int argc = 1; + static char *app_name[1] = { (char *) "./ut_pannablewidget" }; + app = new DuiApplication(argc, app_name); + Q_UNUSED(app); + + gTester = this; + +} + +void Ut_DuiPannableWidget::cleanupTestCase() +{ + gTester = 0; + delete app; +} + + +void Ut_DuiPannableWidget::init() +{ + _widget = new DuiPannableWidget(); + _currentResult = new StateTransitionResult(); +} + +void Ut_DuiPannableWidget::cleanup() +{ + delete _currentResult; + delete _widget; + _widget = 0; + _currentResult = 0; +} + +void Ut_DuiPannableWidget::testWaitState_data() +{ + QList expectedEvents; + + // Create a list of results that the widget should reach to + // when receiving events. + QList results; + + // Result after no events + results.push_back(StateTransitionResult(int(DuiPannableWidgetPrivate::Wait))); + + // Result after mouse press event + expectedEvents.push_back(UNGRAB_MOUSE); + expectedEvents.push_back(PHYS_MOUSE_PRESS); + results.push_back(StateTransitionResult(int(DuiPannableWidgetPrivate::Evaluate), expectedEvents)); + expectedEvents.clear(); + + // Result after mouse release event + results.push_back(StateTransitionResult(int(DuiPannableWidgetPrivate::Wait), expectedEvents)); + + // Result after mouse move event + results.push_back(StateTransitionResult(int(DuiPannableWidgetPrivate::Wait), expectedEvents)); + + // Result after move over passive threshold event + results.push_back(StateTransitionResult(int(DuiPannableWidgetPrivate::Wait), expectedEvents)); + + // Result after move over active threshold event + results.push_back(StateTransitionResult(int(DuiPannableWidgetPrivate::Wait), expectedEvents)); + + createTestData(results); +} + +void Ut_DuiPannableWidget::testWaitState() +{ + // Set the pannable widget into wait state + static_cast(_widget->d_ptr)->state = DuiPannableWidgetPrivate::Wait; + + testStateTransitions(); +} + +void Ut_DuiPannableWidget::testEvaluateState_data() +{ + QList expectedEvents; + + // Create a list of results that the widget should reach to + // when receiving events. + QList results; + + // Result after no events + results.push_back(StateTransitionResult(int(DuiPannableWidgetPrivate::Evaluate))); + + // Result after mouse press event + results.push_back(StateTransitionResult(int(DuiPannableWidgetPrivate::Evaluate))); + + // Result after mouse release event + expectedEvents.push_back(UNGRAB_MOUSE); + results.push_back(StateTransitionResult(int(DuiPannableWidgetPrivate::Wait), expectedEvents)); + expectedEvents.clear(); + + // Result after mouse move event + results.push_back(StateTransitionResult(int(DuiPannableWidgetPrivate::Evaluate))); + + // Result after move over passive threshold event + expectedEvents.push_back(PHYS_MOUSE_RELEASE); + expectedEvents.push_back(UNGRAB_MOUSE); + results.push_back(StateTransitionResult(int(DuiPannableWidgetPrivate::Wait), expectedEvents)); + expectedEvents.clear(); + + // Result after move over active threshold event + expectedEvents.push_back(PHYS_MOUSE_MOVE); + results.push_back(StateTransitionResult(int(DuiPannableWidgetPrivate::Pan), expectedEvents)); + expectedEvents.clear(); + + createTestData(results); +} + +void Ut_DuiPannableWidget::testEvaluateState() +{ + // Set the pannable widget into evaluate state + static_cast(_widget->d_ptr)->state = DuiPannableWidgetPrivate::Evaluate; + + testStateTransitions(); +} + +void Ut_DuiPannableWidget::testPanState_data() +{ + QList expectedEvents; + + // Create a list of results that the widget should reach to + // when receiving events. + QList results; + + // Result after no events + results.push_back(StateTransitionResult(int(DuiPannableWidgetPrivate::Pan))); + + // Result after mouse press event + results.push_back(StateTransitionResult(int(DuiPannableWidgetPrivate::Pan))); + + // Result after mouse release event + expectedEvents.push_back(PHYS_MOUSE_RELEASE); + results.push_back(StateTransitionResult(int(DuiPannableWidgetPrivate::Wait), expectedEvents)); + expectedEvents.clear(); + + // Result after mouse move event + expectedEvents.push_back(PHYS_MOUSE_MOVE); + results.push_back(StateTransitionResult(int(DuiPannableWidgetPrivate::Pan), expectedEvents)); + expectedEvents.clear(); + + // Result after move over passive threshold event + expectedEvents.push_back(PHYS_MOUSE_MOVE); + results.push_back(StateTransitionResult(int(DuiPannableWidgetPrivate::Pan), expectedEvents)); + expectedEvents.clear(); + + // Result after move over active threshold event + expectedEvents.push_back(PHYS_MOUSE_MOVE); + results.push_back(StateTransitionResult(int(DuiPannableWidgetPrivate::Pan), expectedEvents)); + expectedEvents.clear(); + + createTestData(results); +} + +void Ut_DuiPannableWidget::testPanState() +{ + // Set the pannable widget into pan state + static_cast(_widget->d_ptr)->state = DuiPannableWidgetPrivate::Pan; + + testStateTransitions(); +} + +void Ut_DuiPannableWidget::createTestData(QList results) +{ + qRegisterMetaType< QList >(); + qRegisterMetaType< StateTransitionResult >(); + + Q_ASSERT(results.size() == 6); + + QTest::addColumn< QList >("events"); + QTest::addColumn("result"); + + // Sequence of events to be passed to the test widget. + QList sequence; + + // Iterator to results that the widget should reach when + // input events are send to the test widget. + QListIterator resIt(results); + + // No events sent to the widget + QTest::newRow("initial") << sequence << resIt.next(); + + QGraphicsSceneMouseEvent *mouseEvent; + + // Send a mouse press event + mouseEvent = new QGraphicsSceneMouseEvent(QEvent::GraphicsSceneMousePress); + mouseEvent->setButton(Qt::LeftButton); + sequence.push_back(mouseEvent); + QTest::newRow("left mouse button pressed") << sequence << resIt.next(); + sequence.clear(); + + // Send a mouse release event + mouseEvent = new QGraphicsSceneMouseEvent(QEvent::GraphicsSceneMouseRelease); + mouseEvent->setButton(Qt::LeftButton); + sequence.push_back(mouseEvent); + QTest::newRow("left mouse button released") << sequence << resIt.next(); + sequence.clear(); + + // Send a mouse move event + mouseEvent = new QGraphicsSceneMouseEvent(QEvent::GraphicsSceneMouseMove); + mouseEvent->setButton(Qt::LeftButton); + mouseEvent->setScreenPos(QPoint(0, 1)); + sequence.push_back(mouseEvent); + QTest::newRow("mouse move") << sequence << resIt.next(); + sequence.clear(); + + // Send a mouse move over passive threshold + mouseEvent = new QGraphicsSceneMouseEvent(QEvent::GraphicsSceneMouseMove); + mouseEvent->setButton(Qt::LeftButton); + mouseEvent->setPos(QPoint(31, 0)); + sequence.push_back(mouseEvent); + QTest::newRow("mouse move over passive") << sequence << resIt.next(); + sequence.clear(); + + // Send a mouse move over active threshold + mouseEvent = new QGraphicsSceneMouseEvent(QEvent::GraphicsSceneMouseMove); + mouseEvent->setButton(Qt::LeftButton); + mouseEvent->setPos(QPoint(0, 31)); + sequence.push_back(mouseEvent); + QTest::newRow("mouse move over active") << sequence << resIt.next(); + sequence.clear(); +} + + +void Ut_DuiPannableWidget::testStateTransitions() +{ + QFETCH(QList, events); + QFETCH(StateTransitionResult, result); + + // Iterate through the events in the event list + QListIterator i(events); + while (i.hasNext()) { + QEvent *event = i.next(); + switch (event->type()) { + case QEvent::GraphicsSceneMousePress: + _widget->glassMousePressEvent(static_cast(event)); + break; + case QEvent::GraphicsSceneMouseMove: + _widget->glassMouseMoveEvent(static_cast(event)); + break; + case QEvent::GraphicsSceneMouseRelease: + _widget->glassMouseReleaseEvent(static_cast(event)); + break; + default: + break; + } + } + + QCOMPARE(static_cast(_widget->d_ptr)->state, result._targetState); + + _currentResult->compare(result); +} + +void Ut_DuiPannableWidget::testRightMouseButton() +{ + QGraphicsSceneMouseEvent *mouseEvent; + mouseEvent = new QGraphicsSceneMouseEvent(QEvent::GraphicsSceneMousePress); + mouseEvent->setButton(Qt::RightButton); + mouseEvent->setScenePos(QPoint(100, 100)); + _widget->glassMousePressEvent(mouseEvent); + delete mouseEvent; + // State should not change with right mousebutton + QVERIFY(static_cast(_widget->d_ptr)->state == DuiPannableWidgetPrivate::Wait); + + mouseEvent = new QGraphicsSceneMouseEvent(QEvent::GraphicsSceneMouseRelease); + mouseEvent->setButton(Qt::RightButton); + mouseEvent->setScenePos(QPoint(100, 100)); + _widget->glassMouseReleaseEvent(mouseEvent); + delete mouseEvent; + // State should stay the same after button release + QVERIFY(static_cast(_widget->d_ptr)->state == DuiPannableWidgetPrivate::Wait); +} + +QTEST_APPLESS_MAIN(Ut_DuiPannableWidget); diff --git a/tests/ut_duipannablewidget/ut_duipannablewidget.h b/tests/ut_duipannablewidget/ut_duipannablewidget.h new file mode 100644 index 000000000..47b51d450 --- /dev/null +++ b/tests/ut_duipannablewidget/ut_duipannablewidget.h @@ -0,0 +1,84 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIPANNABLEWIDGET_HH +#define UT_DUIPANNABLEWIDGET_HH + + +#include +#include +#include "duiapplication.h" +class DuiPannableWidget; +class QGraphicsWidget; +class StateTransitionResult; + +// Required to insert QList instances to the test data. +Q_DECLARE_METATYPE(QList); + +class Ut_DuiPannableWidget : public QObject +{ + Q_OBJECT + +public: + + /** Result generated by running a test case. */ + StateTransitionResult *_currentResult; + +private: + DuiApplication *app; + + /** Pannable widget instance under testing. */ + DuiPannableWidget *_widget; + +// /** Event enumerator for timeout events. */ +// int _timeoutType; + +private slots: + void initTestCase(); + void cleanupTestCase(); + + void init(); + void cleanup(); + + void testWaitState_data(); + void testEvaluateState_data(); + void testPanState_data(); + void testWaitState(); + void testEvaluateState(); + void testPanState(); + void testRightMouseButton(); + +private: + + /** + * Helper method to create test data with all possible input events + * @param results List of results that the test widget should reach + * when events are triggered. + */ + void createTestData(QList results); + + /** + * Helper method which tests state transitions using the already set-up + * test data and already set-up test widget. + */ + void testStateTransitions(); +}; + + +#endif diff --git a/tests/ut_duipannablewidget/ut_duipannablewidget.pro b/tests/ut_duipannablewidget/ut_duipannablewidget.pro new file mode 100644 index 000000000..bde998351 --- /dev/null +++ b/tests/ut_duipannablewidget/ut_duipannablewidget.pro @@ -0,0 +1,23 @@ +include(../common_top.pri) + +TARGET = ut_duipannablewidget + +support_files.files += \ + ut_duipannablewidget_image.svg \ + ut_duipannablewidget_template.css \ + +# Input +HEADERS += \ + ut_duipannablewidget.h \ +# $$STUBSDIR/duipannableviewport_stub.h \ +# $$STUBSDIR/duistyledescription_stub.h \ +# $$STUBSDIR/duistyle_stub.h \ +# $$STUBSDIR/duitheme_stub.h \ + +TEST_SOURCES += \ +# $$DUISRCDIR/duipannablewidget.cpp \ + +SOURCES += ut_duipannablewidget.cpp \ +# stubbase.cpp \ + +include(../common_bot.pri) diff --git a/tests/ut_duipannablewidget/ut_duipannablewidget_image.svg b/tests/ut_duipannablewidget/ut_duipannablewidget_image.svg new file mode 100644 index 000000000..17b44a3af --- /dev/null +++ b/tests/ut_duipannablewidget/ut_duipannablewidget_image.svg @@ -0,0 +1,19615 @@ + + +image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Scroll-indicator + + + + + + + + + + + + + + + + + + + + + + Single Dots + + + + + + + + + Dot-accented + + Dot-empty + + Dot-default + + + + + + + \ No newline at end of file diff --git a/tests/ut_duiphysics2dpanning/.gitignore b/tests/ut_duiphysics2dpanning/.gitignore new file mode 100644 index 000000000..4820a3507 --- /dev/null +++ b/tests/ut_duiphysics2dpanning/.gitignore @@ -0,0 +1 @@ +ut_duiphysics2dpanning diff --git a/tests/ut_duiphysics2dpanning/ut_duiphysics2dpanning.cpp b/tests/ut_duiphysics2dpanning/ut_duiphysics2dpanning.cpp new file mode 100644 index 000000000..492baf7d9 --- /dev/null +++ b/tests/ut_duiphysics2dpanning/ut_duiphysics2dpanning.cpp @@ -0,0 +1,581 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include "../../src/widgets/duiphysics2dpanning_p.h" +#include +#include + +#include "ut_duiphysics2dpanning.h" + +#define QFLOATCOMPARE(x,y) QCOMPARE(x+1.0,y+1.0) + +QList Ut_DuiPhysics2DPanning::timeLineActions; +QTimeLine::State Ut_DuiPhysics2DPanning::timeLineState; + +void QTimeLine::setDuration(int duration) +{ + QString str = "setDuration"; + str.append("_"); + str.append(QString::number(duration)); + Ut_DuiPhysics2DPanning::timeLineActions.push_back(str); +} + + +void QTimeLine::setUpdateInterval(int interval) +{ + QString str = "setUpdateInterval"; + str.append("_"); + str.append(QString::number(interval)); + Ut_DuiPhysics2DPanning::timeLineActions.push_back(str); +} + + +void QTimeLine::setFrameRange(int startFrame, int endFrame) +{ + QString str = "setFrameRange"; + str.append("_"); + str.append(QString::number(startFrame)); + str.append("_"); + str.append(QString::number(endFrame)); + Ut_DuiPhysics2DPanning::timeLineActions.push_back(str); +} + + +void QTimeLine::setCurrentTime(int msec) +{ + QString str = "setCurrentTime"; + str.append("_"); + str.append(QString::number(msec)); + Ut_DuiPhysics2DPanning::timeLineActions.push_back(str); +} + + +void QTimeLine::setCurveShape(CurveShape shape) +{ + QString str = "setCurveShape"; + str.append("_"); + str.append(QString::number(shape)); + Ut_DuiPhysics2DPanning::timeLineActions.push_back(str); +} + + +void QTimeLine::start() +{ + QString str = "start"; + Ut_DuiPhysics2DPanning::timeLineActions.push_back(str); +} + + +void QTimeLine::stop() +{ + QString str = "stop"; + Ut_DuiPhysics2DPanning::timeLineActions.push_back(str); +} + + +QTimeLine::State QTimeLine::state() const +{ + return Ut_DuiPhysics2DPanning::timeLineState; +} + +void Ut_DuiPhysics2DPanning::initTestCase() +{ + static int argc = 1; + static char *app_name[1] = { (char *) "./ut_pannablewidget" }; + app = new DuiApplication(argc, app_name); + Q_UNUSED(app); +} + + +void Ut_DuiPhysics2DPanning::cleanupTestCase() +{ + delete app; +} + + +void Ut_DuiPhysics2DPanning::init() +{ + DuiPannableWidget *pannable = new DuiPannableWidget(); + pannable->setPanDirection(Qt::Vertical | Qt::Horizontal); + + physics = new DuiPhysics2DPanning(pannable); + + // no style object available, just set some default values + physics->d_ptr->integrationData.pointerSpringK = 0.09; + physics->d_ptr->integrationData.frictionC = 0.6; + physics->d_ptr->integrationData.slideFrictionC = 0.02; + physics->d_ptr->integrationData.borderSpringK = 0.09; + physics->d_ptr->integrationData.borderFrictionC = 0.6; + + Ut_DuiPhysics2DPanning::timeLineActions.clear(); + Ut_DuiPhysics2DPanning::timeLineState = QTimeLine::NotRunning; +} + + +void Ut_DuiPhysics2DPanning::cleanup() +{ + delete physics; +} + + +void Ut_DuiPhysics2DPanning::initValues() +{ + QCOMPARE(physics->d_ptr->range, QRectF(0, 0, 0, 0)); + QCOMPARE(physics->d_ptr->posX, 0.0); + QCOMPARE(physics->d_ptr->posY, 0.0); + QCOMPARE(physics->d_ptr->velX, 0.0); + QCOMPARE(physics->d_ptr->velY, 0.0); + QCOMPARE(physics->d_ptr->integrationData.pointerSpringK, 0.09); + QCOMPARE(physics->d_ptr->integrationData.frictionC, 0.6); + QCOMPARE(physics->d_ptr->integrationData.slideFrictionC, 0.6 / 30.0); + QCOMPARE(physics->d_ptr->integrationData.borderSpringK, 0.09); + QCOMPARE(physics->d_ptr->integrationData.borderFrictionC, 0.6); + QCOMPARE(physics->d_ptr->integrationData.pointer, false); + QCOMPARE(physics->d_ptr->pointerSpringX, 0.0); + QCOMPARE(physics->d_ptr->pointerSpringY, 0.0); + QCOMPARE(physics->d_ptr->sceneLastPos, QPointF()); + QCOMPARE(physics->d_ptr->timeLine != NULL, true); + QCOMPARE(physics->d_ptr->currFrame, 0); +} + + +void Ut_DuiPhysics2DPanning::timeLineInStart1() +{ + // Checks that timeline is initialized correctly in case it was not running + + Ut_DuiPhysics2DPanning::timeLineState = QTimeLine::NotRunning; + + physics->d_ptr->velX = -1.0; + physics->d_ptr->velY = -1.0; + physics->start(); + + QCOMPARE(physics->d_ptr->velX, 0.0); + QCOMPARE(physics->d_ptr->velY, 0.0); + QCOMPARE(timeLineActions.size(), 6); + QCOMPARE(timeLineActions[0], QString("setDuration_1000000")); + QCOMPARE(timeLineActions[1], QString("setUpdateInterval_20")); + QCOMPARE(timeLineActions[2], QString("setFrameRange_0_29999")); + QCOMPARE(timeLineActions[3], QString("setCurrentTime_0")); + QCOMPARE(timeLineActions[4], + QString("setCurveShape_").append(QString::number(QTimeLine::LinearCurve))); + QCOMPARE(timeLineActions[5], QString("start")); +} + + +void Ut_DuiPhysics2DPanning::timeLineInStart2() +{ + // Checks that timeline is not initialized in case it was already running + + Ut_DuiPhysics2DPanning::timeLineState = QTimeLine::Running; + + physics->d_ptr->velX = -1.0; + physics->d_ptr->velY = -1.0; + physics->start(); + + QCOMPARE(physics->d_ptr->velX, -1.0); + QCOMPARE(physics->d_ptr->velY, -1.0); + QCOMPARE(timeLineActions.size(), 0); +} + + +void Ut_DuiPhysics2DPanning::timeLineInStop() +{ + physics->stop(); + + QCOMPARE(timeLineActions.size(), 1); + QCOMPARE(timeLineActions[0], QString("stop")); +} + + +void Ut_DuiPhysics2DPanning::setAndGetQSizeF_data() +{ + QTest::addColumn("value"); + + QTest::newRow("value 1") << QSizeF(300.003, -40122112); + QTest::newRow("value 2") << QSizeF(-300.003, 0.0003000003); + QTest::newRow("value 3") << QSizeF(0.0000000001, -0.003273218); + QTest::newRow("value 4") << QSizeF(7654321000.9, 2130.0); + QTest::newRow("value 5") << QSizeF(-12121212.5, -1010101.11); + QTest::newRow("value 6") << QSizeF(0.0, -40123112); + QTest::newRow("value 7") << QSizeF(-300.003, 0.0); +} + + +void Ut_DuiPhysics2DPanning::setAndGetQSizeF() +{ + QSizeF readvalue; + + QFETCH(QSizeF, value); + + physics->setRange(QRectF(QPointF(), value)); + readvalue = physics->range().size(); + QCOMPARE(readvalue, value); +} + + +void Ut_DuiPhysics2DPanning::setAndGetQPointF_data() +{ + QTest::addColumn("value"); + + QTest::newRow("value 1") << QPointF(300.003, -40102112); + QTest::newRow("value 2") << QPointF(-300.003, 0.0003000003); + QTest::newRow("value 3") << QPointF(0.0000000001, -0.003273218); + QTest::newRow("value 4") << QPointF(7654321000.9, 2130.0); + QTest::newRow("value 5") << QPointF(-12121212.5, -1010101.11); + QTest::newRow("value 6") << QPointF(0.0, -40122112); + QTest::newRow("value 7") << QPointF(-300.003, 0.0); +} + + +void Ut_DuiPhysics2DPanning::setAndGetQPointF() +{ + QPointF readvalue; + + QFETCH(QPointF, value); + + physics->setPosition(value); + readvalue = physics->position(); + QCOMPARE(readvalue, value); + + physics->start(); +} + + +void Ut_DuiPhysics2DPanning::timeLineStateQuery() +{ + Ut_DuiPhysics2DPanning::timeLineState = QTimeLine::NotRunning; + QCOMPARE(physics->inMotion(), false); + + Ut_DuiPhysics2DPanning::timeLineState = QTimeLine::Paused; + QCOMPARE(physics->inMotion(), false); + + Ut_DuiPhysics2DPanning::timeLineState = QTimeLine::Running; + QCOMPARE(physics->inMotion(), true); +} + + +void Ut_DuiPhysics2DPanning::pointerPress() +{ + physics->pointerPress(QPointF(-5.0, 10.5)); + + QCOMPARE(physics->d_ptr->integrationData.pointer, true); + QCOMPARE(physics->d_ptr->sceneLastPos, QPointF(-5.0, 10.5)); + QFLOATCOMPARE(physics->d_ptr->pointerSpringX, 0.0); + QFLOATCOMPARE(physics->d_ptr->pointerSpringY, 0.0); +} + + +void Ut_DuiPhysics2DPanning::pointerMove() +{ + QPointF currSpring = QPointF(0.0, 0.0); + QPointF delta; + QPointF sceneLastPos = QPointF(0.0, 0.0); + QPointF pos; + + physics->d_ptr->pointerSpringX = 0.0; + physics->d_ptr->pointerSpringY = 0.0; + + physics->d_ptr->sceneLastPos = sceneLastPos; + + QFLOATCOMPARE(physics->d_ptr->pointerSpringX, currSpring.x()); + QFLOATCOMPARE(physics->d_ptr->pointerSpringY, currSpring.y()); + + pos = QPointF(100.0, -50.0); + physics->pointerMove(pos); + currSpring += (pos - sceneLastPos); + sceneLastPos = pos; + QFLOATCOMPARE(physics->d_ptr->pointerSpringX, currSpring.x()); + QFLOATCOMPARE(physics->d_ptr->pointerSpringY, currSpring.y()); + + pos = QPointF(0.01, -0.0000001); + physics->pointerMove(pos); + currSpring += (pos - sceneLastPos); + sceneLastPos = pos; + QFLOATCOMPARE(physics->d_ptr->pointerSpringX, currSpring.x()); + QFLOATCOMPARE(physics->d_ptr->pointerSpringY, currSpring.y()); + + pos = QPointF(-33.0, 51.0); + physics->pointerMove(pos); + currSpring += (pos - sceneLastPos); + sceneLastPos = pos; + QFLOATCOMPARE(physics->d_ptr->pointerSpringX, currSpring.x()); + QFLOATCOMPARE(physics->d_ptr->pointerSpringY, currSpring.y()); + + pos = QPointF(10.0, 10.0); + physics->pointerMove(pos); + currSpring += (pos - sceneLastPos); + sceneLastPos = pos; + QFLOATCOMPARE(physics->d_ptr->pointerSpringX, currSpring.x()); + QFLOATCOMPARE(physics->d_ptr->pointerSpringY, currSpring.y()); +} + + +void Ut_DuiPhysics2DPanning::pointerRelease() +{ + QCOMPARE(physics->d_ptr->integrationData.pointer, false); +} + + +enum actionType { + tick, // int argument + press, // QPointF argument + move, // QPointF argument + release, // no argument + setRange // QSizeF argument +}; + +class integratingAction +{ +public: + integratingAction(actionType type, + int value) : + type(type), + value_int(value) {} + integratingAction(actionType type, + QPointF value) : + type(type), + value_QPointF(value) {} + integratingAction(actionType type, + QSizeF value) : + type(type), + value_QSizeF(value) {} + integratingAction(actionType type) : + type(type) {} + + enum actionType type; + int value_int; + QPointF value_QPointF; + QSizeF value_QSizeF; +}; + +Q_DECLARE_METATYPE(QList); + +void Ut_DuiPhysics2DPanning::integrating_data() +{ + QList actionList; + + QTest::addColumn< QList >("actionList"); + QTest::addColumn< QPointF >("endPosition"); + + actionList.clear(); + actionList.push_back(integratingAction(press, QPointF(0.0, 0.0))); + actionList.push_back(integratingAction(tick, 7)); + actionList.push_back(integratingAction(move, QPointF(50.0, 10.0))); + actionList.push_back(integratingAction(tick, 7)); + actionList.push_back(integratingAction(move, QPointF(80.0, 10.0))); + actionList.push_back(integratingAction(tick, 7)); + actionList.push_back(integratingAction(release)); + actionList.push_back(integratingAction(tick, 7)); + + // End position is rounded to nearest 0.001 + QTest::newRow("actionList 1") << actionList << QPointF(-22.348, -2.793); + + actionList.clear(); + actionList.push_back(integratingAction(setRange, QSizeF(100, 100))); + actionList.push_back(integratingAction(press, QPointF(0.0, 0.0))); + actionList.push_back(integratingAction(tick, 7)); + actionList.push_back(integratingAction(move, QPointF(-59.0, -10.0))); + actionList.push_back(integratingAction(tick, 7)); + actionList.push_back(integratingAction(move, QPointF(-83.0, -20.0))); + actionList.push_back(integratingAction(tick, 7)); + actionList.push_back(integratingAction(release)); + actionList.push_back(integratingAction(tick, 7)); + + // End position is rounded to nearest 0.001 + QTest::newRow("actionList 2") << actionList << QPointF(83, 20); +} + + +void Ut_DuiPhysics2DPanning::integrating() +{ + int i, j; + qreal x, y; + int frame = 0; + + QFETCH(QList, actionList); + + for (i = 0; i < actionList.size(); i++) { + switch (actionList[i].type) { + case tick: + for (j = 0; j < actionList[i].value_int; j++) { + physics->integrator(frame++); + } + break; + case press: + physics->pointerPress(actionList[i].value_QPointF); + break; + case move: + physics->pointerMove(actionList[i].value_QPointF); + break; + case release: + physics->pointerRelease(); + break; + case setRange: + physics->setRange(QRectF(QPointF(), actionList[i].value_QSizeF)); + break; + default: + break; + } + } + + QFETCH(QPointF, endPosition); + + x = physics->position().x(); + y = physics->position().y(); + + // Rounds to nearest 0.001 + + x *= 1000.0; + x = qRound(x); + x /= 1000.0; + y *= 1000.0; + y = qRound(y); + y /= 1000.0; + + QCOMPARE(QPointF(x, y), endPosition); +} + +class CustomIntegrationStrategy : public DuiPhysics2DIntegrationStrategy +{ +public: + CustomIntegrationStrategy() { + integrateMethodExecuted = false; + } + + virtual void integrate(qreal &position, + qreal &velocity, + qreal &pointerSpring, + qreal &acceleration, + qreal rangeStart, + qreal rangeEnd, + IntegrationData &data); + + bool integrateMethodExecuted; +}; + +void CustomIntegrationStrategy::integrate(qreal &, + qreal &, + qreal &, + qreal &, + qreal, + qreal, + IntegrationData &) +{ + integrateMethodExecuted = true; +} + +void Ut_DuiPhysics2DPanning::usingCustomIntegrationPolicy() +{ + CustomIntegrationStrategy *strategyObject = new CustomIntegrationStrategy(); + physics->setIntegrationStrategy(strategyObject); + physics->integrator(1); + + QVERIFY(strategyObject->integrateMethodExecuted); + + physics->setIntegrationStrategy(new DuiPhysics2DIntegrationStrategy()); +} + +void Ut_DuiPhysics2DPanning::settingIntegrationPolicyToNULLShouldNotBreakThePhysics() +{ + physics->setIntegrationStrategy(NULL); + physics->integrator(1); +} + +void Ut_DuiPhysics2DPanning::positionShouldReturnToStartRangeAfterMovingViewportBeyondStartRange() +{ + physics->setRange(QRectF(10, 10, 100, 100)); + physics->setPosition(QPointF(10, -30)); + + QCOMPARE(physics->range(), QRectF(10, 10, 100, 100)); + QCOMPARE(physics->position(), QPointF(10, -30)); + + for (int i = 1; i < 500; i++) { + physics->integrator(i); + } + + + QVERIFY2(abs(physics->position().y() - 10) < 1, "Position (rounded to 1px) should be equal 10"); + + physics->setPosition(QPointF(10, -30)); + QCOMPARE(physics->range(), QRectF(10, 10, 100, 100)); + QCOMPARE(physics->position(), QPointF(10, -30)); + + for (int i = 1; i < 500; i++) { + physics->integrator(i); + } + + QVERIFY2(abs(physics->position().y() - 10) < 1, "Position (rounded to 1px) should be equal 10"); +} + +void Ut_DuiPhysics2DPanning::positionShouldReturnToEndRangeAfterMovingViewportBeyondEndRange() +{ + physics->setRange(QRectF(10, 10, 100, 100)); + physics->setPosition(QPointF(10, 130)); + + QCOMPARE(physics->range(), QRectF(10, 10, 100, 100)); + QCOMPARE(physics->position(), QPointF(10, 130)); + + for (int i = 1; i < 500; i++) { + physics->integrator(i); + } + + QVERIFY2(abs(physics->position().y() - 110) < 1, "Position (rounded to 1px) should be equal 110"); + + physics->setPosition(QPointF(10, 130)); + QCOMPARE(physics->range(), QRectF(10, 10, 100, 100)); + QCOMPARE(physics->position(), QPointF(10, 130)); + + for (int i = 1; i < 500; i++) { + physics->integrator(i); + } + + QVERIFY2(abs(physics->position().y() - 110) < 1, "Position (rounded to 1px) should be equal 110"); +} + +void Ut_DuiPhysics2DPanning::integrationShouldStopAfterReachingPositionInsideRange() +{ + physics->setRange(QRectF(10, 10, 100, 100)); + physics->setPosition(QPointF(10, -30)); + + QCOMPARE(physics->range(), QRectF(10, 10, 100, 100)); + QCOMPARE(physics->position(), QPointF(10, -30)); + + for (int i = 1; i < 500; i++) { + physics->integrator(i); + } + + QVERIFY2(abs(physics->velocity().y()) < 1, "Velocity should be smaller than 1px"); + + physics->setPosition(QPointF(10, -30)); + QCOMPARE(physics->position(), QPointF(10, -30)); + + for (int i = 1; i < 500; i++) { + physics->integrator(i); + } + + QVERIFY2(abs(physics->velocity().y()) < 1, "Velocity should be smaller than 1px"); +} + +QTEST_APPLESS_MAIN(Ut_DuiPhysics2DPanning); diff --git a/tests/ut_duiphysics2dpanning/ut_duiphysics2dpanning.h b/tests/ut_duiphysics2dpanning/ut_duiphysics2dpanning.h new file mode 100644 index 000000000..ca1eac81e --- /dev/null +++ b/tests/ut_duiphysics2dpanning/ut_duiphysics2dpanning.h @@ -0,0 +1,98 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_PHYSICS2DPANNING_H +#define UT_PHYSICS2DPANNING_H + + +#include +#include +#include +#include "duiapplication.h" + +class DuiPhysics2DPanning; + +class Ut_DuiPhysics2DPanning : public QObject +{ + Q_OBJECT; + +public: + static QList timeLineActions; + static QTimeLine::State timeLineState; + +private: + DuiApplication *app; + + DuiPhysics2DPanning *physics; + +private slots: + void initTestCase(); + void cleanupTestCase(); + + void init(); + void cleanup(); + + // Init values + + void initValues(); + + // QTimeLine actions in start and stop (1=QTimeLine not running, 2=running) + + void timeLineInStart1(); + void timeLineInStart2(); + void timeLineInStop(); + + // Setters and getters which take QSizeF + + void setAndGetQSizeF_data(); + void setAndGetQSizeF(); + + // Setters and getters which take QPointF + + void setAndGetQPointF_data(); + void setAndGetQPointF(); + + // Passing the state of the TimeLine + + void timeLineStateQuery(); + + // Pointer press, move and release actions + + void pointerPress(); + void pointerMove(); + void pointerRelease(); + + // Integrating + + void integrating_data(); + void integrating(); + + // Custom integration policy + void usingCustomIntegrationPolicy(); + void settingIntegrationPolicyToNULLShouldNotBreakThePhysics(); + + // Integration algorithm convergence and border behaviour + void positionShouldReturnToStartRangeAfterMovingViewportBeyondStartRange(); + void positionShouldReturnToEndRangeAfterMovingViewportBeyondEndRange(); + void integrationShouldStopAfterReachingPositionInsideRange(); + +}; + + +#endif diff --git a/tests/ut_duiphysics2dpanning/ut_duiphysics2dpanning.pro b/tests/ut_duiphysics2dpanning/ut_duiphysics2dpanning.pro new file mode 100644 index 000000000..8c200e975 --- /dev/null +++ b/tests/ut_duiphysics2dpanning/ut_duiphysics2dpanning.pro @@ -0,0 +1,14 @@ +include(../common_top.pri) + +TARGET = ut_duiphysics2dpanning + +# unit test and unit +SOURCES += \ + ut_duiphysics2dpanning.cpp \ + + +# unit test and unit +HEADERS += \ + ut_duiphysics2dpanning.h \ + +include(../common_bot.pri) diff --git a/tests/ut_duipopuplist/.gitignore b/tests/ut_duipopuplist/.gitignore new file mode 100644 index 000000000..279dfa2f9 --- /dev/null +++ b/tests/ut_duipopuplist/.gitignore @@ -0,0 +1 @@ +ut_duipopuplist diff --git a/tests/ut_duipopuplist/ut_duipopuplist.cpp b/tests/ut_duipopuplist/ut_duipopuplist.cpp new file mode 100644 index 000000000..16f670981 --- /dev/null +++ b/tests/ut_duipopuplist/ut_duipopuplist.cpp @@ -0,0 +1,167 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "duipopuplistview.h" +#include "duipopuplistview_p.h" +#include "duipopuplistview.cpp" +#include "duigriditem.h" + +#include "ut_duipopuplist.h" + +DuiApplication *app; + +void Ut_DuiPopupList::initTestCase() +{ + static int argc = 1; + static char *argv[1] = { (char *) "./ut_duipopuplist" }; + app = new DuiApplication(argc, argv); + m_popuplist = new DuiPopupList(); +} + + +void Ut_DuiPopupList::cleanupTestCase() +{ + delete m_popuplist; + m_popuplist = NULL; + delete app; + app = NULL; +} + +void Ut_DuiPopupList::setContent() +{ + QStringList buffer; + buffer << "Just a test1"; + + QStringListModel model; + model.setStringList(buffer); + + qRegisterMetaType("QAbstractItemModel*"); + QSignalSpy modelChangedSpy(m_popuplist, SIGNAL(itemModelChanged(QAbstractItemModel *))); + // Check the signal does actually exist still + QVERIFY(modelChangedSpy.isValid()); + + model.setStringList(m_stringList); + m_popuplist->setItemModel(&model); + // Check that setModel worked for an empty model + QCOMPARE(&model, m_popuplist->itemModel()); + // Check a modelChanged signal was sent + QCOMPARE(modelChangedSpy.count(), 1); + + m_stringList << "one" << "two"; + m_model.setStringList(m_stringList); + m_popuplist->setItemModel(&m_model); + + // Check that changing the model works and doesn't delete our old model + QCOMPARE(&m_model, m_popuplist->itemModel()); + // Check another modelChanged signal was sent + QCOMPARE(modelChangedSpy.count(), 2); + + // Check selectionModel + qRegisterMetaType("QItemSelectionModel*"); + QSignalSpy selectionChangedSpy(m_popuplist, SIGNAL(selectionModelChanged(QItemSelectionModel *))); + + QItemSelectionModel *smodel = new QItemSelectionModel(&m_model, m_popuplist); + m_popuplist->setSelectionModel(smodel); + QCOMPARE(smodel, m_popuplist->selectionModel()); + QCOMPARE(selectionChangedSpy.count(), 1); +} + +void Ut_DuiPopupList::testCurrentIndex() +{ + QSignalSpy currentIndexChangedSpy(m_popuplist, SIGNAL(currentIndexChanged(QModelIndex))); + // Check the signals do actually exist still + QVERIFY(currentIndexChangedSpy.isValid()); + + // Check if we have NULL item model, test current index + m_popuplist->setItemModel(NULL); + QCOMPARE(m_popuplist->currentIndex(), QModelIndex()); + + m_popuplist->setCurrentIndex(m_model.index(1, 0)); + QCOMPARE(m_popuplist->currentIndex(), QModelIndex()); + + m_popuplist->setItemModel(&m_model); + + // Check that we have the right number of items + QCOMPARE(m_popuplist->itemModel()->rowCount(), 2); + + // We haven't set a current row yet - so should be invalid + QCOMPARE(m_popuplist->currentIndex(), QModelIndex()); + + //Check that changing rows works okay + m_popuplist->setCurrentIndex(m_model.index(1, 0)); + QCOMPARE(m_popuplist->currentIndex().row(), 1); + m_popuplist->setCurrentIndex(m_model.index(0, 0)); + QCOMPARE(m_popuplist->currentIndex().row(), 0); + m_popuplist->setCurrentIndex(QModelIndex()); + QCOMPARE(m_popuplist->currentIndex(), QModelIndex()); + // Check we got three indexChanged signals + QCOMPARE(currentIndexChangedSpy.count(), 3); + + m_popuplist->setCurrentIndex(m_model.index(0, 0, QModelIndex())); + QCOMPARE(m_popuplist->currentIndex().row(), 0); + m_popuplist->setCurrentIndex(m_model.index(1, 0, QModelIndex())); + QCOMPARE(m_popuplist->currentIndex().row(), 1); + // Check we got two more indexChanged signals + QCOMPARE(currentIndexChangedSpy.count(), 5); + + //Change it to what it should already be on + m_popuplist->setCurrentIndex(m_model.index(1, 0, QModelIndex())); + QCOMPARE(m_popuplist->currentIndex().row(), 1); + // Since we didn't change the current index, no new signals should have been sent + QCOMPARE(currentIndexChangedSpy.count(), 5); +} + +void Ut_DuiPopupList::testSetItemIconID() +{ + DuiPopupListViewPrivate *view = new DuiPopupListViewPrivate; + QStandardItemModel *itemModel = new QStandardItemModel; + view->itemModel = itemModel; + view->selectionModel = new QItemSelectionModel(itemModel); + + DuiGridItem *item; + + // First add item with text to model and build it + itemModel->appendRow(new QStandardItem("Item")); + item = (DuiGridItem *)(view->buildItem(itemModel->index(0, 0))); + // no icon was set to model, so it should be invisible + QCOMPARE(item->isImageVisible(), false); + + // Add icon to previously set item + itemModel->setData(itemModel->index(0, 0), "Icon-music", Qt::DecorationRole); + // do like DuiPopupListView::dataChanged() do, remove old widget then create new + view->recycleWidget(item); + item = (DuiGridItem *)(view->buildItem(itemModel->index(0, 0))); + // now, icon should be visible + QCOMPARE(item->isImageVisible(), true); + + delete itemModel; + delete view; +} + +QTEST_APPLESS_MAIN(Ut_DuiPopupList) diff --git a/tests/ut_duipopuplist/ut_duipopuplist.h b/tests/ut_duipopuplist/ut_duipopuplist.h new file mode 100644 index 000000000..c7665ce5b --- /dev/null +++ b/tests/ut_duipopuplist/ut_duipopuplist.h @@ -0,0 +1,51 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIPOPUPLIST_H +#define UT_DUIPOPUPLIST_H + +#include +#include +#include +#include + +#include + + +Q_DECLARE_METATYPE(DuiPopupList *); + +class Ut_DuiPopupList : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase(); + void cleanupTestCase(); + + void setContent(); + void testCurrentIndex(); + void testSetItemIconID(); + +private: + DuiPopupList *m_popuplist; + QStringListModel m_model; + QStringList m_stringList; +}; + +#endif diff --git a/tests/ut_duipopuplist/ut_duipopuplist.pro b/tests/ut_duipopuplist/ut_duipopuplist.pro new file mode 100644 index 000000000..0a35ecb2f --- /dev/null +++ b/tests/ut_duipopuplist/ut_duipopuplist.pro @@ -0,0 +1,29 @@ +include(../common_top.pri) +TARGET = ut_duipopuplist + +# unit + +# unit test and unit +SOURCES += \ + ut_duipopuplist.cpp \ + ../../src/widgets/views/duidialogview.cpp \ + ../../src/widgets/views/duibuttongrouplayoutpolicy_p.cpp \ + ../../src/widgets/views/duiscenewindowview.cpp \ + ../../src/widgets/core/duiwidgetview.cpp \ + ../../src/animation/widget/core/duiabstractwidgetanimation.cpp \ + ../../src/.moc/moc_duiabstractwidgetanimation.cpp \ + +# unit test and unit +HEADERS += \ + ut_duipopuplist.h + +INCLUDEPATH += \ + ../../src/style \ + ../../src/widgets \ + ../../src/.moc \ + ../../src/animation/widget/core \ + ../../src/animation/core \ + ../../src/core \ + ../../src/widgets/views \ + +include(../common_bot.pri) diff --git a/tests/ut_duipositionindicator/.gitignore b/tests/ut_duipositionindicator/.gitignore new file mode 100644 index 000000000..2cb6d1d1e --- /dev/null +++ b/tests/ut_duipositionindicator/.gitignore @@ -0,0 +1 @@ +ut_duipositionindicator diff --git a/tests/ut_duipositionindicator/ut_duipositionindicator.cpp b/tests/ut_duipositionindicator/ut_duipositionindicator.cpp new file mode 100644 index 000000000..8ccf84026 --- /dev/null +++ b/tests/ut_duipositionindicator/ut_duipositionindicator.cpp @@ -0,0 +1,80 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duipositionindicator.h" +#include +#include "../../src/widgets/duipositionindicator_p.h" +#include +#include + +#include + +DuiApplication *app; + +void Ut_DuiPositionIndicator::initTestCase() +{ + static int argc = 1; + static char *app_name[1] = { (char *) "./ut_duipositionindicator" }; + app = new DuiApplication(argc, app_name); +} + + +void Ut_DuiPositionIndicator::cleanupTestCase() +{ + delete app; +} + +void Ut_DuiPositionIndicator::init() +{ + m_subject = new DuiPositionIndicator(0); +} + +void Ut_DuiPositionIndicator::cleanup() +{ + delete m_subject; + m_subject = 0; +} + +void Ut_DuiPositionIndicator::updateSizePosData_data() +{ + QTest::addColumn("viewportSize"); + QTest::addColumn("pannedRange"); + QTest::addColumn("pannedPos"); + + QTest::newRow("position 1") << QSizeF(10.003, 466.011) << QRectF(0, 0, 122.090, 500.98798) << QPointF(300.003, -40102112); + QTest::newRow("position 2") << QSizeF(500.292, 0.00033) << QRectF(0, 0, 690.784, 9.1910) << QPointF(-300.003, 0.0003000003); + QTest::newRow("position 3") << QSizeF(0.0000000001, 200.003273218) << QRectF(0, 0, 122.93847, 943.1991918) << QPointF(0.0000000001, -0.003273218); +} + +//Update new position of position indicator +void Ut_DuiPositionIndicator::updateSizePosData() +{ + QFETCH(QSizeF, viewportSize); + QFETCH(QRectF, pannedRange); + QFETCH(QPointF, pannedPos); + + m_subject->updateSizePosData(viewportSize, pannedRange, pannedPos); + + QCOMPARE(m_subject->viewportSize(), viewportSize); + QCOMPARE(m_subject->pannedRange(), pannedRange); + QCOMPARE(m_subject->pannedPos(), pannedPos); + +} + +QTEST_APPLESS_MAIN(Ut_DuiPositionIndicator) diff --git a/tests/ut_duipositionindicator/ut_duipositionindicator.h b/tests/ut_duipositionindicator/ut_duipositionindicator.h new file mode 100644 index 000000000..71778b3c7 --- /dev/null +++ b/tests/ut_duipositionindicator/ut_duipositionindicator.h @@ -0,0 +1,46 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIPOSITIONINDICATOR_H +#define UT_DUIPOSITIONINDICATOR_H + +#include + +#include +Q_DECLARE_METATYPE(DuiPositionIndicator *); + +class Ut_DuiPositionIndicator : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase(); + void cleanupTestCase(); + + void init(); + void cleanup(); + + void updateSizePosData_data(); + void updateSizePosData(); + +private: + DuiPositionIndicator *m_subject; +}; + +#endif diff --git a/tests/ut_duipositionindicator/ut_duipositionindicator.pro b/tests/ut_duipositionindicator/ut_duipositionindicator.pro new file mode 100644 index 000000000..75a1544e8 --- /dev/null +++ b/tests/ut_duipositionindicator/ut_duipositionindicator.pro @@ -0,0 +1,18 @@ +include(../common_top.pri) + +TARGET = ut_duipositionindicator + + +TEST_SOURCES += \ +# $$DUISRCDIR/duipositionindicator.cpp \ + +# unit test and unit classes +SOURCES += \ + ut_duipositionindicator.cpp \ +# $$TEST_SOURCES \ + +# unit test and unit classes +HEADERS += \ + ut_duipositionindicator.h \ + +include(../common_bot.pri) diff --git a/tests/ut_duipositionindicatorview/.gitignore b/tests/ut_duipositionindicatorview/.gitignore new file mode 100644 index 000000000..ce169e009 --- /dev/null +++ b/tests/ut_duipositionindicatorview/.gitignore @@ -0,0 +1 @@ +ut_duipositionindicatorview diff --git a/tests/ut_duipositionindicatorview/ut_duipositionindicatorview.cpp b/tests/ut_duipositionindicatorview/ut_duipositionindicatorview.cpp new file mode 100644 index 000000000..233fb7a5b --- /dev/null +++ b/tests/ut_duipositionindicatorview/ut_duipositionindicatorview.cpp @@ -0,0 +1,61 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include "views/duipositionindicatorview_p.h" +#include +#include +#include + +#include "ut_duipositionindicatorview.h" + +DuiApplication *app; + +void Ut_DuiPositionIndicatorView::initTestCase() +{ + static int argc = 1; + static char *app_name[1] = { (char *) "./ut_duipositionindicatorview" }; + app = new DuiApplication(argc, app_name); + + m_controller = new DuiPositionIndicator(0); + m_subject = new DuiPositionIndicatorView(m_controller); + m_controller->setView(m_subject); +} + + +void Ut_DuiPositionIndicatorView::cleanupTestCase() +{ + delete m_controller; // ~duiwidgetcontroller calls duiwidgetview.destroy() which deletes view (ie m_subject) + m_controller = 0; + m_subject = 0; + delete app; +} + +void Ut_DuiPositionIndicatorView::init() +{ +} + +void Ut_DuiPositionIndicatorView::cleanup() +{ +} + + +QTEST_APPLESS_MAIN(Ut_DuiPositionIndicatorView) + diff --git a/tests/ut_duipositionindicatorview/ut_duipositionindicatorview.h b/tests/ut_duipositionindicatorview/ut_duipositionindicatorview.h new file mode 100644 index 000000000..00aed6507 --- /dev/null +++ b/tests/ut_duipositionindicatorview/ut_duipositionindicatorview.h @@ -0,0 +1,49 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIPOSITIONINDICATORVIEW_H +#define UT_DUIPOSITIONINDICATORVIEW_H + +#include +#include +#include +#include + +#include +#include + +Q_DECLARE_METATYPE(DuiPositionIndicatorView *); + +class Ut_DuiPositionIndicatorView : public QObject +{ + Q_OBJECT + +private slots: + void init(); + void cleanup(); + void initTestCase(); + void cleanupTestCase(); + +private: + DuiPositionIndicator *m_controller; + DuiPositionIndicatorView *m_subject; +}; + + +#endif diff --git a/tests/ut_duipositionindicatorview/ut_duipositionindicatorview.pro b/tests/ut_duipositionindicatorview/ut_duipositionindicatorview.pro new file mode 100644 index 000000000..2f7d7b857 --- /dev/null +++ b/tests/ut_duipositionindicatorview/ut_duipositionindicatorview.pro @@ -0,0 +1,16 @@ +include(../common_top.pri) + +INCLUDEPATH += $$DUISRCDIR/widgets $$DUISRCDIR/style + +TARGET = ut_duipositionindicatorview +CONFIG += DEBUG + +# unit test and unit classes +SOURCES += \ + ut_duipositionindicatorview.cpp \ + +# unit test and unit classes +HEADERS += \ + ut_duipositionindicatorview.h \ + +include(../common_bot.pri) diff --git a/tests/ut_duiremoteaction/.gitignore b/tests/ut_duiremoteaction/.gitignore new file mode 100644 index 000000000..f1ab6d54a --- /dev/null +++ b/tests/ut_duiremoteaction/.gitignore @@ -0,0 +1 @@ +ut_duiremoteaction diff --git a/tests/ut_duiremoteaction/ut_duiremoteaction.cpp b/tests/ut_duiremoteaction/ut_duiremoteaction.cpp new file mode 100644 index 000000000..fa2823783 --- /dev/null +++ b/tests/ut_duiremoteaction/ut_duiremoteaction.cpp @@ -0,0 +1,150 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duiremoteaction.h" +#include +#include +#include "duiaction_p.h" + +bool Ut_DuiRemoteAction::captureCalls = false; +QString Ut_DuiRemoteAction::callServiceName; +QString Ut_DuiRemoteAction::callObjectPath; +QString Ut_DuiRemoteAction::callInterface; +QList Ut_DuiRemoteAction::callMethods; +QList< QList > Ut_DuiRemoteAction::callArguments; + +// DuiActionPrivate stubs +DuiActionPrivate::DuiActionPrivate() +{ +} + +DuiActionPrivate::~DuiActionPrivate() +{ +} + +// QDBusInterface stubs (used by DuiRemoteAction) +QDBusInterface::QDBusInterface(const QString &service, const QString &path, const QString &interface, const QDBusConnection &connection, QObject *parent) : QDBusAbstractInterface(service, path, interface.toUtf8().constData(), connection, parent) +{ + Ut_DuiRemoteAction::callServiceName = service; + Ut_DuiRemoteAction::callObjectPath = path; + Ut_DuiRemoteAction::callInterface = interface; +} + +QDBusInterface::~QDBusInterface() +{ +} + +// QDBusAbstractInterface stubs (used by DuiRemoteAction) +QDBusMessage QDBusAbstractInterface::callWithArgumentList(QDBus::CallMode, const QString &method, const QList &args) +{ + if (Ut_DuiRemoteAction::captureCalls) { + Ut_DuiRemoteAction::callMethods.append(method); + Ut_DuiRemoteAction::callArguments.append(args); + } + + return QDBusMessage(); +} + +void Ut_DuiRemoteAction::init() +{ + captureCalls = false; + callServiceName = QString(); + callObjectPath = QString(); + callInterface = QString(); + callMethods.clear(); + callArguments.clear(); +} + +void Ut_DuiRemoteAction::cleanup() +{ +} + +void Ut_DuiRemoteAction::initTestCase() +{ +} + +void Ut_DuiRemoteAction::cleanupTestCase() +{ +} + +void Ut_DuiRemoteAction::testSerialization() +{ + // Create two arguments as QVariants + QVariant arg1("arg1"); + QVariant arg2(2); + + // Serialize the QVariants into QBuffers + QBuffer buffer1; + QBuffer buffer2; + buffer1.open(QIODevice::ReadWrite); + buffer2.open(QIODevice::ReadWrite); + QDataStream stream1(&buffer1); + QDataStream stream2(&buffer2); + stream1 << arg1; + stream2 << arg2; + buffer1.close(); + buffer2.close(); + + // Encode the contents of the QBuffers in Base64 + QString arg1String(buffer1.buffer().toBase64().data()); + QString arg2String(buffer2.buffer().toBase64().data()); + + // Test that an empty action serializes into an empty action + DuiRemoteAction action1; + QCOMPARE(action1.toString(), QString()); + + // Test that a class deserialized from a string serializes into the same string + QString action2String("serviceName objectPath interface methodName "); + action2String.append(arg1String); + action2String.append(' '); + action2String.append(arg2String); + DuiRemoteAction action2(action2String); + QCOMPARE(action2.toString(), action2String); + + // Test that passing the parameters separately will result in the same string + QList args; + args.append(arg1); + args.append(arg2); + DuiRemoteAction action3("serviceName", "objectPath", "interface", "methodName", args); + QCOMPARE(action3.toString(), action2String); +} + +void Ut_DuiRemoteAction::testTrigger() +{ + // Create an action with a method call and some QVariant arguments + QList args; + args.append(QVariant("arg1")); + args.append(QVariant(2)); + DuiRemoteAction action("serviceName", "objectPath", "interface", "methodName", args); + captureCalls = true; + action.trigger(); + + // Make sure the corrent method was called with the corrent arguments + QCOMPARE(callServiceName, QString("serviceName")); + QCOMPARE(callObjectPath, QString("objectPath")); + QCOMPARE(callInterface, QString("interface")); + QCOMPARE(callMethods.count(), 1); + QCOMPARE(callMethods.at(0), QString("methodName")); + QCOMPARE(callArguments.count(), 1); + QCOMPARE(callArguments.at(0).count(), 2); + QCOMPARE(callArguments.at(0).at(0), QVariant("arg1")); + QCOMPARE(callArguments.at(0).at(1), QVariant(2)); +} + +QTEST_MAIN(Ut_DuiRemoteAction) diff --git a/tests/ut_duiremoteaction/ut_duiremoteaction.h b/tests/ut_duiremoteaction/ut_duiremoteaction.h new file mode 100644 index 000000000..957b7e8b6 --- /dev/null +++ b/tests/ut_duiremoteaction/ut_duiremoteaction.h @@ -0,0 +1,56 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIREMOTEACTION_H +#define UT_DUIREMOTEACTION_H + +#include +#include +#include +#include +#include + +// the real unit/DuiRemoteAction class declaration +#include + +Q_DECLARE_METATYPE(DuiRemoteAction *); + +class Ut_DuiRemoteAction : public QObject +{ + Q_OBJECT + +public: + static bool captureCalls; + static QString callServiceName; + static QString callObjectPath; + static QString callInterface; + static QList callMethods; + static QList< QList > callArguments; + +private slots: + void init(); + void cleanup(); + void initTestCase(); + void cleanupTestCase(); + + void testSerialization(); + void testTrigger(); +}; + +#endif diff --git a/tests/ut_duiremoteaction/ut_duiremoteaction.pro b/tests/ut_duiremoteaction/ut_duiremoteaction.pro new file mode 100644 index 000000000..ff4e76d0a --- /dev/null +++ b/tests/ut_duiremoteaction/ut_duiremoteaction.pro @@ -0,0 +1,23 @@ +include(../common_top.pri) +TARGET = ut_duiremoteaction +INCLUDEPATH += $$DUISRCDIR/core + +TEST_SOURCES = \ + $$DUISRCDIR/core/duiremoteaction.cpp \ + +# unit test and unit +SOURCES += \ + ut_duiremoteaction.cpp \ + $$TEST_SOURCES \ + +# service classes +SOURCES += \ + $$STUBSDIR/stubbase.cpp \ + +# unit test and unit +HEADERS += \ + ut_duiremoteaction.h \ + $$DUISRCDIR/core/duiaction.h \ + $$DUISRCDIR/core/duiremoteaction.h + +include(../common_bot.pri) diff --git a/tests/ut_duiscene/.gitignore b/tests/ut_duiscene/.gitignore new file mode 100644 index 000000000..704f5eeb4 --- /dev/null +++ b/tests/ut_duiscene/.gitignore @@ -0,0 +1 @@ +ut_duiscene diff --git a/tests/ut_duiscene/duiapplication.cpp b/tests/ut_duiscene/duiapplication.cpp new file mode 100644 index 000000000..9e6b3843b --- /dev/null +++ b/tests/ut_duiscene/duiapplication.cpp @@ -0,0 +1,60 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include + +DuiApplication::DuiApplication(int &argc, char **argv) + : QApplication(argc, argv) +{ +} + +bool DuiApplication::x11EventFilter(XEvent *event) +{ + Q_UNUSED(event); + return false; +} + + +DuiApplication::~DuiApplication() +{ +} + +bool DuiApplication::showBoundingRect() +{ + return false; +} + +bool DuiApplication::showFps() +{ + return false; +} + +bool DuiApplication::softwareRendering() +{ + return false; +} + +bool DuiApplication::portrait() +{ + return false; +} + +void DuiApplication::updateSettings() +{ +} diff --git a/tests/ut_duiscene/ut_duiscene.cpp b/tests/ut_duiscene/ut_duiscene.cpp new file mode 100644 index 000000000..be666ee5a --- /dev/null +++ b/tests/ut_duiscene/ut_duiscene.cpp @@ -0,0 +1,88 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "ut_duiscene.h" +#include + + +#define MAX_PARAMS 10 + +void Ut_DuiScene::initTestCase() +{ + + +} +void Ut_DuiScene::cleanupTestCase() +{ +} + + +void Ut_DuiScene::init() +{ + QChar sep(' '); + char *argv[MAX_PARAMS]; + int x = 0; + QString params("./ut_duiscene -software -show-br -show-fps -show-size -show-position"); + + QStringList list = params.split(sep); + QStringListIterator it(list); + while (it.hasNext() && x < MAX_PARAMS) { + argv[x++] = strdup(it.next().toLocal8Bit().constData()); + } + x = 6; + app = new DuiApplication(x, argv); + + m_subject = new DuiScene(); +} + +void Ut_DuiScene::cleanup() +{ + delete m_subject; + m_subject = 0; + + delete app; + app = 0; +} + +void Ut_DuiScene::drawForeground() +{ + QPixmap *p = new QPixmap(300, 300); + p->fill(QColor(255, 255, 255, 0)); + QPainter *myPainter = new QPainter(p); + + m_subject->drawForeground(myPainter, QRect(0, 0, 300, 300)); + QImage img1 = p->toImage(); + + m_subject->addItem(new DuiButton("foobar")); + m_subject->drawForeground(myPainter, QRect(0, 0, 300, 300)); + QImage img2 = p->toImage(); + QVERIFY(img1 != img2); + + QVERIFY(img1 == img1); +} + +QTEST_APPLESS_MAIN(Ut_DuiScene) diff --git a/tests/ut_duiscene/ut_duiscene.h b/tests/ut_duiscene/ut_duiscene.h new file mode 100644 index 000000000..efdc922e0 --- /dev/null +++ b/tests/ut_duiscene/ut_duiscene.h @@ -0,0 +1,43 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUISCENE_H +#define UT_DUISCENE_H +#include "duiapplication.h" +#include +#include +#include + +class Ut_DuiScene : public QObject +{ + Q_OBJECT + +private slots: + void init(); + void cleanup(); + void initTestCase(); + void cleanupTestCase(); + void drawForeground(); + +private: + DuiApplication *app; + DuiScene *m_subject; +}; + +#endif diff --git a/tests/ut_duiscene/ut_duiscene.pro b/tests/ut_duiscene/ut_duiscene.pro new file mode 100644 index 000000000..e444df34d --- /dev/null +++ b/tests/ut_duiscene/ut_duiscene.pro @@ -0,0 +1,31 @@ +include(../common_top.pri) + +TARGET = ut_duiscene + +TEST_SOURCES = \ + +support_files.files += \ + ut_duiscene_image.svg \ + ut_duiscene_template.css \ + +# unit test and unit +SOURCES += \ + ut_duiscene.cpp \ + +# base classes +SOURCES += \ + +# service classes +SOURCES += \ + +# unit test and unit +HEADERS += \ + ut_duiscene.h \ + +# base classes +HEADERS += \ + +# service classes +HEADERS += \ + +include(../common_bot.pri) diff --git a/tests/ut_duiscene/ut_duiscene_image.svg b/tests/ut_duiscene/ut_duiscene_image.svg new file mode 100644 index 000000000..17b44a3af --- /dev/null +++ b/tests/ut_duiscene/ut_duiscene_image.svg @@ -0,0 +1,19615 @@ + + +image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Scroll-indicator + + + + + + + + + + + + + + + + + + + + + + Single Dots + + + + + + + + + Dot-accented + + Dot-empty + + Dot-default + + + + + + + \ No newline at end of file diff --git a/tests/ut_duiscenemanager/.gitignore b/tests/ut_duiscenemanager/.gitignore new file mode 100644 index 000000000..9daacac3d --- /dev/null +++ b/tests/ut_duiscenemanager/.gitignore @@ -0,0 +1 @@ +ut_duiscenemanager diff --git a/tests/ut_duiscenemanager/ut_duiscenemanager.cpp b/tests/ut_duiscenemanager/ut_duiscenemanager.cpp new file mode 100644 index 000000000..eb1f6d99c --- /dev/null +++ b/tests/ut_duiscenemanager/ut_duiscenemanager.cpp @@ -0,0 +1,402 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include + +#include +#include + +#include "ut_duiscenemanager.h" + +#include +#include +#include +#include +#include +#include +#include "duidockwidget.h" +#include +#include "duiscenemanager_p.h" + +#include +#include + +// DuiWidgetController stubs +const DuiWidgetView *DuiWidgetController::view() const +{ + return 0; +} + +// DuiDeviceProfile stubs +class DuiDeviceProfile +{ +public: + static DuiDeviceProfile *instance(); + QSize resolution() const; +}; + +DuiDeviceProfile *DuiDeviceProfile::instance() +{ + static DuiDeviceProfile p; + return &p; +} + +QSize DuiDeviceProfile::resolution() const +{ + return QSize(1000, 500); +} + +// DuiComponentData stubs +DuiWindow *gActiveWindow = 0; +bool DuiComponentData::softwareRendering() +{ + return true; +} + +bool DuiComponentData::fullScreen() +{ + return false; +} + +void DuiComponentData::setActiveWindow(DuiWindow *window) +{ + gActiveWindow = window; +} + +DuiWindow *DuiComponentData::activeWindow() +{ + return gActiveWindow; +} + +DuiApplicationWindow *DuiComponentData::activeApplicationWindow() +{ + return qobject_cast(gActiveWindow); +} + +void DuiComponentData::registerWindow(DuiWindow *window) +{ + if (gActiveWindow == 0) + setActiveWindow(window); +} + +void DuiComponentData::unregisterWindow(DuiWindow *window) +{ + if (gActiveWindow == window) + setActiveWindow(0); +} + +// Avoid creating unnecessary OpenGL stuff +void DuiWindow::setTranslucentBackground(bool enable) +{ + Q_UNUSED(enable); +} + + +// Test class implementation + +void Ut_DuiSceneManager::initTestCase() +{ + qRegisterMetaType("Dui::Orientation"); + qRegisterMetaType("Dui::OrientationAngle"); + duiWindow = new DuiWindow; +} + +void Ut_DuiSceneManager::cleanupTestCase() +{ + delete duiWindow; +} + +void Ut_DuiSceneManager::init() +{ + sm = new DuiSceneManager; + duiWindow->setSceneManager(sm); +} + +void Ut_DuiSceneManager::cleanup() +{ + duiWindow->setSceneManager(0); +} + +void Ut_DuiSceneManager::testConstructorWithNoScene() +{ + QVERIFY(sm->scene()); +} + +void Ut_DuiSceneManager::testConstructorWithSceneSpecified() +{ + DuiScene *scene = new DuiScene; + DuiSceneManager *manager = new DuiSceneManager(scene); + QCOMPARE(manager->scene(), scene); + delete manager; +} + +void Ut_DuiSceneManager::testSceneWindowAttaching() +{ + DuiOverlay *p = new DuiOverlay(); + sm->showWindowNow(p); + + QCOMPARE(sm->d_ptr->windows->size(), 1); + delete p; +} + +void Ut_DuiSceneManager::testSceneWindowDetaching() +{ + DuiOverlay *p = new DuiOverlay(); + sm->showWindowNow(p); + + QCOMPARE(sm->d_ptr->windows->size(), 1); + delete p; + QCOMPARE(sm->d_ptr->windows->size(), 0); +} + +void Ut_DuiSceneManager::testSceneWindowShowNow() +{ + DuiOverlay *p = new DuiOverlay(); + sm->showWindowNow(p); + + QCOMPARE((int)p->zValue(), (int)DuiSceneManagerPrivate::Overlay); + QCOMPARE(p->scene(), qobject_cast(sm->scene())); + QCOMPARE(p->isVisible(), true); + + delete p; +} + +void Ut_DuiSceneManager::testSceneWindowShow() +{ + DuiNavigationBar *p = new DuiNavigationBar(); + sm->showWindow(p); + + QCOMPARE((int)p->zValue(), (int)DuiSceneManagerPrivate::NavigationBar); + QCOMPARE(p->scene(), qobject_cast(sm->scene())); + QCOMPARE(p->isVisible(), true); + + delete p; +} + +void Ut_DuiSceneManager::testSceneWindowHideNow() +{ + DuiNavigationBar *p = new DuiNavigationBar(); + + sm->showWindowNow(p); + sm->hideWindowNow(p); + + QCOMPARE(sm->d_ptr->navBar, (DuiNavigationBar *)0); + QCOMPARE(p->isVisible(), false); + + delete p; +} + +void Ut_DuiSceneManager::testSceneWindowHide() +{ + DuiNavigationBar *p = new DuiNavigationBar(); + sm->showWindow(p); + sm->hideWindow(p); + + QCOMPARE(sm->d_ptr->navBar, (DuiNavigationBar *)0); + QCOMPARE(p->isVisible(), false); + + delete p; +} + +void Ut_DuiSceneManager::testSceneLayerEffect() +{ + DuiDialog *m = new DuiMessageBox("test"); + DuiNavigationBar *n = new DuiNavigationBar(); + + m->appearNow(); + n->appearNow(); + + QVERIFY(m->parentItem() != 0); + QVERIFY(n->parentItem() == sm->d_ptr->rootElement); + + QCOMPARE((int)m->parentItem()->zValue(), (int)DuiSceneManagerPrivate::MessageBox); + + sm->hideWindowNow(m); + sm->hideWindowNow(n); + + delete m; + delete n; +} + +void Ut_DuiSceneManager::testInitialOrientation() +{ + Dui::Orientation initialOrientation = sm->orientation(); + QCOMPARE(initialOrientation, Dui::Landscape); +} + +void Ut_DuiSceneManager::testOrientationChangedSignal() +{ + QSignalSpy spy(sm, SIGNAL(orientationChanged(Dui::Orientation))); + + int newAngle = sm->orientationAngle() + Dui::Angle90; + newAngle %= 360; + + sm->setOrientationAngle((Dui::OrientationAngle) newAngle, + Dui::ImmediateOrientationChange); + Dui::Orientation newOrientation = (newAngle == Dui::Angle0 || newAngle == Dui::Angle180) + ? Dui::Landscape + : Dui::Portrait; + + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.at(0).at(0).value(), newOrientation); +} + +// Test uses non-exported symbol "DuiDockWidget". +/* +void Ut_DuiSceneManager::testNavBarDockWidgetVisibility() +{ + DuiNavigationBar *p = new DuiNavigationBar(); + DuiDockWidget *d = new DuiDockWidget(); + + p->appearNow(); + d->appearNow(); + + int newAngle = sm->orientationAngle() + Dui::Angle90; + newAngle %= 360; + + sm->setOrientationAngle( (Dui::OrientationAngle) newAngle ); + + QCOMPARE(p->isVisible(), true); + QCOMPARE(d->isVisible(), true); + + sm->hideWindowNow(p); + sm->hideWindowNow(d); + + delete p; + delete d; +} +*/ + +void Ut_DuiSceneManager::testAngleBoundaryCases() +{ + QSignalSpy spyChanged(sm, SIGNAL(orientationChanged(Dui::Orientation))); + + int newAngle = sm->orientationAngle() + Dui::Angle270; + newAngle %= 360; + sm->setOrientationAngle((Dui::OrientationAngle) newAngle, + Dui::ImmediateOrientationChange); + + newAngle = sm->orientationAngle() + Dui::Angle90; + newAngle %= 360; + sm->setOrientationAngle((Dui::OrientationAngle) newAngle, + Dui::ImmediateOrientationChange); + + QCOMPARE(spyChanged.count(), 2); + +} + +void Ut_DuiSceneManager::testSceneSizes() +{ + QSize vSR = sm->visibleSceneSize(); + + // check scene rects are non-zero + QVERIFY(vSR.width() > 0); + QVERIFY(vSR.height() > 0); + + sm->setOrientationAngle(Dui::Angle90); + + // check scenerects are in correct orientation + // what about square? + QCOMPARE(sm->orientation(), Dui::Portrait); + QCOMPARE(sm->visibleSceneSize(), sm->visibleSceneSize(Dui::Portrait)); + vSR = sm->visibleSceneSize(); + QVERIFY(vSR.width() < vSR.height()); + + // test other orientation + vSR = sm->visibleSceneSize(Dui::Landscape); + QVERIFY(vSR.width() > vSR.height()); + + sm->setOrientationAngle(Dui::Angle180); + + QCOMPARE(sm->orientation(), Dui::Landscape); + QCOMPARE(sm->visibleSceneSize(), sm->visibleSceneSize(Dui::Landscape)); + vSR = sm->visibleSceneSize(); + QVERIFY(vSR.width() > vSR.height()); + + // test other orientation + vSR = sm->visibleSceneSize(Dui::Portrait); + QVERIFY(vSR.width() < vSR.height()); +} + +void Ut_DuiSceneManager::testWindowAnimationDone() +{ + DuiSceneWindow *window1 = new DuiOverlay; + DuiSceneWindow *window2 = new DuiOverlay; + QSignalSpy spyWindow1Shown(window1, SIGNAL(windowShown())); + QSignalSpy spyWindow1Hidden(window1, SIGNAL(windowHidden())); + QSignalSpy spyWindow2Shown(window2, SIGNAL(windowShown())); + window1->appearNow(); + QCOMPARE(spyWindow1Shown.count(), 1); + QCOMPARE(spyWindow1Hidden.count(), 0); + QCOMPARE(spyWindow2Shown.count(), 0); + sm->hideWindowNow(window1); + QCOMPARE(spyWindow1Shown.count(), 1); + QCOMPARE(spyWindow1Hidden.count(), 1); + QCOMPARE(spyWindow2Shown.count(), 0); + delete window1; + delete window2; +} + +void Ut_DuiSceneManager::testPageSwitchingOnAppearNow() +{ + DuiApplicationPage firstPage; + DuiApplicationPage secondPage; + + QSignalSpy firstPageShown(&firstPage, SIGNAL(windowShown())); + QSignalSpy firstPageHidden(&firstPage, SIGNAL(windowHidden())); + QSignalSpy secondPageShown(&secondPage, SIGNAL(windowShown())); + + sm->showWindowNow(&firstPage); + + QCOMPARE(firstPageShown.count(), 1); + QCOMPARE(firstPageHidden.count(), 0); + QCOMPARE(secondPageShown.count(), 0); + firstPageShown.clear(); + + sm->showWindowNow(&secondPage); + + QCOMPARE(firstPageShown.count(), 0); + QCOMPARE(firstPageHidden.count(), 1); + QCOMPARE(secondPageShown.count(), 1); +} + +void Ut_DuiSceneManager::testPageSwitchingOnDismissNow() +{ + DuiApplicationPage firstPage; + DuiApplicationPage secondPage; + + sm->showWindowNow(&firstPage); + sm->showWindowNow(&secondPage); + + QSignalSpy firstPageShown(&firstPage, SIGNAL(windowShown())); + QSignalSpy firstPageHidden(&firstPage, SIGNAL(windowHidden())); + QSignalSpy secondPageShown(&secondPage, SIGNAL(windowShown())); + QSignalSpy secondPageHidden(&secondPage, SIGNAL(windowHidden())); + + sm->closeWindowNow(&secondPage); + + QCOMPARE(firstPageShown.count(), 1); + QCOMPARE(firstPageHidden.count(), 0); + QCOMPARE(secondPageShown.count(), 0); + QCOMPARE(secondPageHidden.count(), 1); +} + +QTEST_MAIN(Ut_DuiSceneManager); diff --git a/tests/ut_duiscenemanager/ut_duiscenemanager.h b/tests/ut_duiscenemanager/ut_duiscenemanager.h new file mode 100644 index 000000000..26dff4223 --- /dev/null +++ b/tests/ut_duiscenemanager/ut_duiscenemanager.h @@ -0,0 +1,68 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUISCENEMANAGER_H +#define UT_DUISCENEMANAGER_H + +#include +#include + +#include +#include +#include + +class DuiWindow; + +#define MAX_PARAMS 10 +class Ut_DuiSceneManager: public QObject +{ + Q_OBJECT + +private: + DuiSceneManager *sm; + DuiWindow *duiWindow; + +private slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + + void testConstructorWithNoScene(); + void testConstructorWithSceneSpecified(); + void testSceneWindowAttaching(); + void testSceneWindowDetaching(); + void testSceneWindowShowNow(); + void testSceneWindowShow(); + void testSceneWindowHideNow(); + void testSceneWindowHide(); + void testSceneLayerEffect(); + void testInitialOrientation(); + void testOrientationChangedSignal(); + //void testNavBarDockWidgetVisibility(); + void testAngleBoundaryCases(); + void testSceneSizes(); + void testWindowAnimationDone(); + void testPageSwitchingOnAppearNow(); + void testPageSwitchingOnDismissNow(); +}; + +Q_DECLARE_METATYPE(Dui::Orientation) + +#endif diff --git a/tests/ut_duiscenemanager/ut_duiscenemanager.pro b/tests/ut_duiscenemanager/ut_duiscenemanager.pro new file mode 100644 index 000000000..b043076fb --- /dev/null +++ b/tests/ut_duiscenemanager/ut_duiscenemanager.pro @@ -0,0 +1,13 @@ +include(../common_top.pri) +INCLUDEPATH += $$DUISRCDIR/scene $$DUISRCDIR/widgets $$DUISRCDIR/style $$DUISRCDIR/events + +TARGET = ut_duiscenemanager + +# Input +HEADERS += \ + ut_duiscenemanager.h \ + +SOURCES += \ + ut_duiscenemanager.cpp \ + +include(../common_bot.pri) diff --git a/tests/ut_duiscenewindow/.gitignore b/tests/ut_duiscenewindow/.gitignore new file mode 100644 index 000000000..695a6184a --- /dev/null +++ b/tests/ut_duiscenewindow/.gitignore @@ -0,0 +1 @@ +ut_duiscenewindow diff --git a/tests/ut_duiscenewindow/ut_duiscenewindow.cpp b/tests/ut_duiscenewindow/ut_duiscenewindow.cpp new file mode 100644 index 000000000..b40c39ecf --- /dev/null +++ b/tests/ut_duiscenewindow/ut_duiscenewindow.cpp @@ -0,0 +1,295 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duiscenewindow.h" + +#include +#include +#include +#include +#include +#include +#include + +class MyDuiDismissEventFilter : public QObject +{ +public: + MyDuiDismissEventFilter() : QObject(0) { + count = 0; + } + + bool eventFilter(QObject *watched, QEvent *event) { + Q_UNUSED(watched) + if (event->type() == DuiDismissEvent::eventType()) { + count++; + } + return false; + } + + int count; +}; + +// DuiWidgetController stubs +const DuiWidgetView *DuiWidgetController::view() const +{ + return 0; +} + +// DuiDeviceProfile stubs +class DuiDeviceProfile +{ +public: + static DuiDeviceProfile *instance(); + QSize resolution() const; +}; + +DuiDeviceProfile *DuiDeviceProfile::instance() +{ + static DuiDeviceProfile p; + return &p; +} + +QSize DuiDeviceProfile::resolution() const +{ + return QSize(1000, 500); +} + +// DuiComponentData stubs +DuiWindow *gActiveWindow = 0; +bool DuiComponentData::softwareRendering() +{ + return true; +} + +bool DuiComponentData::fullScreen() +{ + return false; +} + +void DuiComponentData::setActiveWindow(DuiWindow *window) +{ + gActiveWindow = window; +} + +DuiWindow *DuiComponentData::activeWindow() +{ + return gActiveWindow; +} + +DuiApplicationWindow *DuiComponentData::activeApplicationWindow() +{ + return qobject_cast(gActiveWindow); +} + +void DuiComponentData::registerWindow(DuiWindow *window) +{ + if (gActiveWindow == 0) + setActiveWindow(window); +} + +void DuiComponentData::unregisterWindow(DuiWindow *window) +{ + if (gActiveWindow == window) + setActiveWindow(0); +} + +// Test class implementation + +void Ut_DuiSceneWindow::init() +{ + m_subject = new DuiOverlay; +} + +void Ut_DuiSceneWindow::cleanup() +{ + delete m_subject; + m_subject = 0; +} + +void Ut_DuiSceneWindow::initTestCase() +{ + window = new DuiWindow(new DuiSceneManager); +} + +void Ut_DuiSceneWindow::cleanupTestCase() +{ + delete window; + window = 0; +} + +void Ut_DuiSceneWindow::testAccessors() +{ + m_subject->setManagedManually(true); + + QCOMPARE(m_subject->windowType(), DuiSceneWindow::Overlay); + QCOMPARE(m_subject->isManagedManually(), true); +} + +void Ut_DuiSceneWindow::testAppear() +{ + m_subject->appear(window); + + QCOMPARE(m_subject->sceneManager(), window->sceneManager()); + QVERIFY(m_subject->scene() == static_cast(window->scene())); +} + +/* + * Appearing on a DuiWindow without a scene manager should just work. + * Scene manager should be created on the fly. + */ +void Ut_DuiSceneWindow::testAppearWithoutSceneManager() +{ + window->setSceneManager(0); + + m_subject->appear(window); + + QVERIFY(m_subject->sceneManager() == window->sceneManager()); + QVERIFY(m_subject->scene() == static_cast(window->scene())); +} + +void Ut_DuiSceneWindow::testWindowAnimationDone() +{ + QSignalSpy spyWindowVisible(m_subject, SIGNAL(windowShown())); + QSignalSpy spyWindowHidden(m_subject, SIGNAL(windowHidden())); + m_subject->appearNow(); + QCOMPARE(spyWindowVisible.count(), 1); + QCOMPARE(spyWindowHidden.count(), 0); + m_subject->disappearNow(); + QCOMPARE(spyWindowVisible.count(), 1); + QCOMPARE(spyWindowHidden.count(), 1); +} + +void Ut_DuiSceneWindow::opacityAfterAppearNow() +{ + m_subject->setOpacity(0.0); + m_subject->appearNow(); + QCOMPARE(m_subject->opacity(), 1.0); +} + +void Ut_DuiSceneWindow::opacityAfterAppear() +{ + m_subject->setOpacity(0.0); + m_subject->appear(); + QCOMPARE(m_subject->opacity(), 1.0); +} + +void Ut_DuiSceneWindow::testDismiss() +{ + MyDuiDismissEventFilter dismissEventFilter; + m_subject->installEventFilter(&dismissEventFilter); + + m_subject->appearNow(); + + QSignalSpy spyWindowShown(m_subject, SIGNAL(windowShown())); + QSignalSpy spyWindowHidden(m_subject, SIGNAL(windowHidden())); + + m_subject->dismissNow(); + + QCOMPARE(spyWindowShown.count(), 0); + QCOMPARE(spyWindowHidden.count(), 1); + // QCOMPARE(dismissEventFilter.count, 1); FIXME: Dismiss events are disabled in 0.18 due to ABI freeze +} + +void Ut_DuiSceneWindow::testDestroyWhenDoneCallingDisappear() +{ + m_subject->appearNow(DuiSceneWindow::DestroyWhenDone); + + QSignalSpy spyDestroyed(m_subject, SIGNAL(destroyed())); + + m_subject->disappearNow(); + + processPendingEvents(); + + QCOMPARE(spyDestroyed.count(), 1); + + m_subject = 0; +} + +void Ut_DuiSceneWindow::testDestroyWhenDoneCallingDismiss() +{ + m_subject->appearNow(DuiSceneWindow::DestroyWhenDone); + + QSignalSpy spyDestroyed(m_subject, SIGNAL(destroyed())); + + m_subject->dismissNow(); + + processPendingEvents(); + + QCOMPARE(spyDestroyed.count(), 1); + + m_subject = 0; +} + +void Ut_DuiSceneWindow::testDestroyWhenDismissedCallingDisappear() +{ + m_subject->appearNow(DuiSceneWindow::DestroyWhenDismissed); + + QSignalSpy spyDestroyed(m_subject, SIGNAL(destroyed())); + + m_subject->disappearNow(); + + processPendingEvents(); + + QCOMPARE(spyDestroyed.count(), 0); +} + +void Ut_DuiSceneWindow::testDestroyWhenDismissedCallingDismiss() +{ + m_subject->appearNow(DuiSceneWindow::DestroyWhenDismissed); + + QSignalSpy spyDestroyed(m_subject, SIGNAL(destroyed())); + + m_subject->dismissNow(); + + processPendingEvents(); + + QCOMPARE(spyDestroyed.count(), 1); + + m_subject = 0; +} + +void Ut_DuiSceneWindow::testDismissedStateReset() +{ + m_subject->appearNow(); + m_subject->dismissNow(); + + // internal "dismissed" state should be reset to false on next reappearance + // Therefore the disappearance below should not cause self-destruction + + m_subject->appearNow(DuiSceneWindow::DestroyWhenDismissed); + QSignalSpy spyDestroyed(m_subject, SIGNAL(destroyed())); + m_subject->disappearNow(); + + processPendingEvents(); + + QCOMPARE(spyDestroyed.count(), 0); +} + +void Ut_DuiSceneWindow::processPendingEvents() +{ + // Send the posted QEvent::DeferredDelete from deleteLater(). + QCoreApplication::sendPostedEvents(); + + // Quit when there are no more pending events (like DeferredDelete) + QTimer::singleShot(0, QCoreApplication::instance(), SLOT(quit())); + + QCoreApplication::instance()->exec(); +} + +QTEST_MAIN(Ut_DuiSceneWindow) diff --git a/tests/ut_duiscenewindow/ut_duiscenewindow.h b/tests/ut_duiscenewindow/ut_duiscenewindow.h new file mode 100644 index 000000000..19ee46448 --- /dev/null +++ b/tests/ut_duiscenewindow/ut_duiscenewindow.h @@ -0,0 +1,66 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUISCENEWINDOW_H +#define UT_DUISCENEWINDOW_H + +#include +#include +#include + +class DuiWindow; + +class Ut_DuiSceneWindow : public QObject +{ + Q_OBJECT + +private slots: + void init(); + void cleanup(); + void initTestCase(); + void cleanupTestCase(); + + void testAccessors(); + + void testAppear(); + void testAppearWithoutSceneManager(); + + void testWindowAnimationDone(); + void opacityAfterAppearNow(); + void opacityAfterAppear(); + + void testDismiss(); + + void testDestroyWhenDoneCallingDisappear(); + void testDestroyWhenDoneCallingDismiss(); + void testDestroyWhenDismissedCallingDisappear(); + void testDestroyWhenDismissedCallingDismiss(); + void testDismissedStateReset(); + +private: + void processPendingEvents(); + + DuiSceneWindow *m_subject; + DuiWindow *window; +}; + +Q_DECLARE_METATYPE(DuiSceneWindow::WindowType); +Q_DECLARE_METATYPE(DuiSceneWindow::DeletionPolicy); + +#endif diff --git a/tests/ut_duiscenewindow/ut_duiscenewindow.pro b/tests/ut_duiscenewindow/ut_duiscenewindow.pro new file mode 100644 index 000000000..9c5aac9c7 --- /dev/null +++ b/tests/ut_duiscenewindow/ut_duiscenewindow.pro @@ -0,0 +1,10 @@ +include(../common_top.pri) +TARGET = ut_duiscenewindow + +SOURCES += \ + ut_duiscenewindow.cpp + +HEADERS += \ + ut_duiscenewindow.h + +include(../common_bot.pri) diff --git a/tests/ut_duiseekbar/.gitignore b/tests/ut_duiseekbar/.gitignore new file mode 100644 index 000000000..a44ce2c78 --- /dev/null +++ b/tests/ut_duiseekbar/.gitignore @@ -0,0 +1 @@ +ut_duiseekbar diff --git a/tests/ut_duiseekbar/ut_duiseekbar.cpp b/tests/ut_duiseekbar/ut_duiseekbar.cpp new file mode 100644 index 000000000..96e75d43e --- /dev/null +++ b/tests/ut_duiseekbar/ut_duiseekbar.cpp @@ -0,0 +1,161 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duiseekbar.h" + +#include + +void Ut_DuiSeekBar::seekbarSetLoadedContentMinimum() +{ + DuiSeekBar *s = new DuiSeekBar(); + + int max = s->loadedContentMaximum(); + + s->setLoadedContentMinimum(max - 1); + + QCOMPARE(s->loadedContentMinimum(), max - 1); + QCOMPARE(s->loadedContentMaximum(), max); + + s->setLoadedContentMinimum(s->loadedContentMaximum() + 1); + QVERIFY(s->loadedContentMinimum() <= s->loadedContentMaximum()); + + s->setLoadedContentMaximum(1); + s->setLoadedContentMinimum(2); + QCOMPARE(s->loadedContentMinimum(), 2); + QCOMPARE(s->loadedContentMaximum(), 2); + + delete s; +} + +void Ut_DuiSeekBar::seekbarSetLoadedContentMaximum() +{ + DuiSeekBar *s = new DuiSeekBar(); + + int min = s->loadedContentMinimum(); + + s->setLoadedContentMaximum(min + 1); + + QCOMPARE(s->loadedContentMaximum(), min + 1); + QCOMPARE(s->loadedContentMinimum(), min); + + s->setLoadedContentMaximum(s->loadedContentMinimum() - 1); + QVERIFY(s->loadedContentMinimum() <= s->loadedContentMaximum()); + + s->setLoadedContentMinimum(1); + s->setLoadedContentMaximum(1); + QCOMPARE(s->loadedContentMinimum(), 1); + QCOMPARE(s->loadedContentMaximum(), 1); + + delete s; +} + +void Ut_DuiSeekBar::seekbarSetLoadedContentRange() +{ + DuiSeekBar *s = new DuiSeekBar(); + + s->setRange(10, 20); + s->setLoadedContentRange(1, 3); + + QCOMPARE(s->minimum(), 10); + QCOMPARE(s->maximum(), 20); + + QCOMPARE(s->loadedContentMinimum(), 1); + QCOMPARE(s->loadedContentMaximum(), 3); + + s->setLoadedContentRange(3, 1); + + QCOMPARE(s->loadedContentMinimum(), 3); + QCOMPARE(s->loadedContentMaximum(), 3); + + delete s; +} + +void Ut_DuiSeekBar::seekbarTestOutOfLoadedContentRange() +{ + DuiSeekBar *s = new DuiSeekBar(); + + QSignalSpy spy(s, SIGNAL(outOfLoadedContentRange())); + + s->setRange(10, 20); + s->setValue(15); + s->setLoadedContentMinimum(1); + s->setLoadedContentMaximum(3); + + QCOMPARE(s->minimum(), 10); + QCOMPARE(s->maximum(), 20); + QCOMPARE(s->value(), 15); + QCOMPARE(s->loadedContentMinimum(), 1); + QCOMPARE(s->loadedContentMaximum(), 3); + + QCOMPARE(spy.count(), 3); + + spy.clear(); + + s->setRange(0, 20); + QCOMPARE(s->minimum(), 0); + QCOMPARE(s->maximum(), 20); + + s->setValue(2); + QCOMPARE(s->value(), 2); + QCOMPARE(spy.count(), 0); + + s->setLoadedContentMinimum(2); + QCOMPARE(s->loadedContentMinimum(), 2); + QCOMPARE(spy.count(), 0); + + s->setLoadedContentMaximum(2); + QCOMPARE(s->loadedContentMaximum(), 2); + QCOMPARE(spy.count(), 0); + + s->setValue(4); + QCOMPARE(s->value(), 4); + QCOMPARE(spy.count(), 1); + + spy.clear(); + + s->setLoadedContentRange(2, 7); + QCOMPARE(s->loadedContentMinimum(), 2); + QCOMPARE(s->loadedContentMaximum(), 7); + QCOMPARE(spy.count(), 0); + + s->setLoadedContentMinimum(5); + QCOMPARE(s->loadedContentMinimum(), 5); + QCOMPARE(spy.count(), 1); + + spy.clear(); + + s->setLoadedContentMinimum(2); + QCOMPARE(s->loadedContentMinimum(), 2); + QCOMPARE(spy.count(), 0); + + s->setLoadedContentMaximum(3); + QCOMPARE(s->loadedContentMaximum(), 3); + QCOMPARE(spy.count(), 1); + + spy.clear(); + + s->setLoadedContentMaximum(6); + QCOMPARE(s->loadedContentMaximum(), 6); + QCOMPARE(spy.count(), 0); + + delete s; +} + +QTEST_APPLESS_MAIN(Ut_DuiSeekBar) + diff --git a/tests/ut_duiseekbar/ut_duiseekbar.h b/tests/ut_duiseekbar/ut_duiseekbar.h new file mode 100644 index 000000000..8e63fc83c --- /dev/null +++ b/tests/ut_duiseekbar/ut_duiseekbar.h @@ -0,0 +1,39 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUISEEKBAR_H +#define UT_DUISEEKBAR_H + +#include +#include +#include +#include + +class Ut_DuiSeekBar : public QObject +{ + Q_OBJECT + +private slots: + void seekbarSetLoadedContentMinimum(); + void seekbarSetLoadedContentMaximum(); + void seekbarSetLoadedContentRange(); + void seekbarTestOutOfLoadedContentRange(); +}; + +#endif diff --git a/tests/ut_duiseekbar/ut_duiseekbar.pro b/tests/ut_duiseekbar/ut_duiseekbar.pro new file mode 100644 index 000000000..3b5f7a058 --- /dev/null +++ b/tests/ut_duiseekbar/ut_duiseekbar.pro @@ -0,0 +1,11 @@ +include(../common_top.pri) + +TARGET = ut_duiseekbar + +SOURCES += \ + ut_duiseekbar.cpp \ + +HEADERS += \ + ut_duiseekbar.h \ + +include(../common_bot.pri) diff --git a/tests/ut_duiserviceaction/.gitignore b/tests/ut_duiserviceaction/.gitignore new file mode 100644 index 000000000..0cb7af0b9 --- /dev/null +++ b/tests/ut_duiserviceaction/.gitignore @@ -0,0 +1 @@ +ut_duiserviceaction diff --git a/tests/ut_duiserviceaction/ut_duiserviceaction.cpp b/tests/ut_duiserviceaction/ut_duiserviceaction.cpp new file mode 100644 index 000000000..68435c616 --- /dev/null +++ b/tests/ut_duiserviceaction/ut_duiserviceaction.cpp @@ -0,0 +1,60 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duiserviceaction.h" +#include +#include +#include +#include +#include "duiaction_p.h" + +// DuiActionPrivate stubs +DuiActionPrivate::DuiActionPrivate() +{ +} + +DuiActionPrivate::~DuiActionPrivate() +{ +} + +void Ut_DuiServiceAction::init() +{ + m_subject = new DuiServiceAction(NULL); +} + +void Ut_DuiServiceAction::cleanup() +{ + delete m_subject; +} + +void Ut_DuiServiceAction::initTestCase() +{ +} + +void Ut_DuiServiceAction::cleanupTestCase() +{ +} + +void Ut_DuiServiceAction::testAction() +{ + m_subject->trigger(); + QCOMPARE(gDefaultDuiServiceInvokerStub.stubCallCount("invoke"), 1); +} + +QTEST_APPLESS_MAIN(Ut_DuiServiceAction) diff --git a/tests/ut_duiserviceaction/ut_duiserviceaction.h b/tests/ut_duiserviceaction/ut_duiserviceaction.h new file mode 100644 index 000000000..fb570c1bc --- /dev/null +++ b/tests/ut_duiserviceaction/ut_duiserviceaction.h @@ -0,0 +1,44 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUISERVICEACTION_H +#define UT_DUISERVICEACTION_H + +#include +#include + +class DuiServiceAction; + +class Ut_DuiServiceAction : public QObject +{ + Q_OBJECT + +private slots: + void init(); + void cleanup(); + void initTestCase(); + void cleanupTestCase(); + + void testAction(); + +private: + DuiServiceAction *m_subject; +}; + +#endif diff --git a/tests/ut_duiserviceaction/ut_duiserviceaction.pro b/tests/ut_duiserviceaction/ut_duiserviceaction.pro new file mode 100644 index 000000000..40b0d049b --- /dev/null +++ b/tests/ut_duiserviceaction/ut_duiserviceaction.pro @@ -0,0 +1,26 @@ +include(../common_top.pri) +TARGET = ut_duiserviceaction + +INCLUDEPATH += $$DUISRCDIR/service +INCLUDEPATH += $$DUISRCDIR/core + +TEST_SOURCES = \ + $$DUISRCDIR/service/duiserviceaction.cpp + +# unit test and unit +SOURCES += \ + ut_duiserviceaction.cpp \ + $$TEST_SOURCES + +# service classes +SOURCES += \ + $$STUBSDIR/stubbase.cpp \ + +# unit test and unit +HEADERS += \ + ut_duiserviceaction.h \ + $$DUISRCDIR/core/duiaction.h \ + $$DUISRCDIR/service/duiserviceaction.h \ + $$DUISRCDIR/service/duiserviceinvoker.h + +include(../common_bot.pri) diff --git a/tests/ut_duiservicefwbaseif/.gitignore b/tests/ut_duiservicefwbaseif/.gitignore new file mode 100644 index 000000000..db39de3aa --- /dev/null +++ b/tests/ut_duiservicefwbaseif/.gitignore @@ -0,0 +1 @@ +ut_duiservicefwbaseif diff --git a/tests/ut_duiservicefwbaseif/duiservicefwproxy.cpp b/tests/ut_duiservicefwbaseif/duiservicefwproxy.cpp new file mode 100644 index 000000000..14f7e03e8 --- /dev/null +++ b/tests/ut_duiservicefwbaseif/duiservicefwproxy.cpp @@ -0,0 +1,53 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiservicefwproxy.h" +#include "ut_duiservicefwbaseif.h" + +DuiServiceFwProxy::DuiServiceFwProxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) : + QObject(parent) +{ + Q_UNUSED(service); + Q_UNUSED(path); + Q_UNUSED(connection); + Q_UNUSED(parent); +} + +DuiServiceFwProxy::~DuiServiceFwProxy() +{ +} + +QString DuiServiceFwProxy::serviceName(const QString &interfaceName) +{ + Q_UNUSED(interfaceName); + return QString(Ut_DuiServiceFwBaseIf::serviceFwService); +} + +QStringList DuiServiceFwProxy::serviceNames(const QString &interfaceName) +{ + Q_UNUSED(interfaceName); + return QStringList(); +} + +QString DuiServiceFwProxy::servicePath(const QString &interfaceName) +{ + Q_UNUSED(interfaceName); + return QString(); +} + diff --git a/tests/ut_duiservicefwbaseif/duiservicefwproxy.h b/tests/ut_duiservicefwbaseif/duiservicefwproxy.h new file mode 100644 index 000000000..c9940a61c --- /dev/null +++ b/tests/ut_duiservicefwbaseif/duiservicefwproxy.h @@ -0,0 +1,73 @@ +/* + * This file was generated by qdbusxml2cpp version 0.7 + * Command line was: qdbusxml2cpp -c DuiServiceFwProxy -p duiservicefwproxy.h:duiservicefwproxy.cpp duiservicefw.xml + * + * qdbusxml2cpp is Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#ifndef DUISERVICEFWPROXY_H_LOCAL +#define DUISERVICEFWPROXY_H_LOCAL + +#include +#include +#include +#include +#include +#include +#include + +class QDBusConnection; + +class MockQDBusConnection +{ +public: + bool isConnected() const { + return true; + }; +}; + +/* + * Proxy class for interface com.nokia.ServiceFwIf + */ +class DuiServiceFwProxy : public QObject +{ + Q_OBJECT +public: + static inline const char *staticInterfaceName() { + return "com.nokia.ServiceFwIf"; + } + +public: + DuiServiceFwProxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0); + + virtual ~DuiServiceFwProxy(); + + MockQDBusConnection connection() { + static MockQDBusConnection myConnection; + return myConnection; + }; + +public Q_SLOTS: // METHODS + QString serviceName(const QString &interfaceName); + + QStringList serviceNames(const QString &interfaceName); + + QString servicePath(const QString &interfaceName); + +Q_SIGNALS: // SIGNALS + void serviceAvailable(const QString &service, const QString &interface); + void serviceUnavailable(const QString &service); + +}; + +namespace com +{ + namespace nokia + { + typedef ::DuiServiceFwProxy DuiServiceFwIf; + } +} +#endif diff --git a/tests/ut_duiservicefwbaseif/ut_duiservicefwbaseif.cpp b/tests/ut_duiservicefwbaseif/ut_duiservicefwbaseif.cpp new file mode 100644 index 000000000..f3d78342d --- /dev/null +++ b/tests/ut_duiservicefwbaseif/ut_duiservicefwbaseif.cpp @@ -0,0 +1,254 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include +#include "ut_duiservicefwbaseif.h" + +QString Ut_DuiServiceFwBaseIf::serviceFwService; + +class EmailServiceIfProxy : public QDBusAbstractInterface +{ +public: + static inline const char *staticInterfaceName() { + return "com.nokia.EmailServiceIf"; + } + +public: + EmailServiceIfProxy() : QDBusAbstractInterface(QString(), QString(), EmailServiceIfProxy::staticInterfaceName(), QDBusConnection::sessionBus(), 0) { + }; + + virtual ~EmailServiceIfProxy() {}; + +Q_SIGNALS: // SIGNALS + void messageSent(const QString &message); +}; + +class MyServiceFwIf : public DuiServiceFwBaseIf +{ +public: + MyServiceFwIf() : + DuiServiceFwBaseIf("com.nokia.TextProcessorIf", 0) { + }; + + virtual ~MyServiceFwIf() { + }; + + virtual void setService(const QString &service) { + Q_UNUSED(service); + }; +}; + +void Ut_DuiServiceFwBaseIf::init() +{ + Ut_DuiServiceFwBaseIf::serviceFwService = ""; + + m_subject = new MyServiceFwIf(); + + QDBusAbstractInterface *x = new EmailServiceIfProxy(); + m_subject->interfaceProxy = x; + + // no point in testing these + m_subject->isValid(); + m_subject->serviceNames("com.nokia.TextProcessorIf"); + m_subject->serviceName(); + m_subject->serviceFwProxy(); +} + +void Ut_DuiServiceFwBaseIf::cleanup() +{ + delete m_subject; + m_subject = 0; +} + +void Ut_DuiServiceFwBaseIf::initTestCase() +{ +} + +void Ut_DuiServiceFwBaseIf::cleanupTestCase() +{ +} + +// no current service; new service for other if +// should not get signal:serviceAvailable +// should not get signal:serviceChanged +void Ut_DuiServiceFwBaseIf::testHandleServiceAvailable0() +{ + QSignalSpy serviceAvailableSpy(m_subject, + SIGNAL(serviceAvailable(QString))); + QSignalSpy serviceChangedSpy(m_subject, + SIGNAL(serviceChanged(QString))); + + m_subject->service = ""; + + m_subject->handleServiceAvailable("com.google.TextProcessor", "com.google.TexrProcessorIf"); + QCOMPARE(serviceAvailableSpy.count(), 0); + QCOMPARE(serviceChangedSpy.count(), 0); +} + +// no current service; new service for this if +// should get signal:serviceAvailable +// should get signal:serviceChanged +void Ut_DuiServiceFwBaseIf::testHandleServiceAvailable1() +{ + QSignalSpy serviceAvailableSpy(m_subject, + SIGNAL(serviceAvailable(QString))); + QSignalSpy serviceChangedSpy(m_subject, + SIGNAL(serviceChanged(QString))); + + m_subject->service = ""; + + QString thisService = "org.maemo.TextProcessor"; + serviceFwService = thisService; + + m_subject->handleServiceAvailable(thisService, m_subject->interface); + QCOMPARE(serviceAvailableSpy.count(), 1); + QCOMPARE(serviceChangedSpy.count(), 1); +} + +// current service; new preferred service for other if +// should not get signal:serviceAvilable +// should not get signal:serviceChanged +void Ut_DuiServiceFwBaseIf::testHandleServiceAvailable2() +{ + QSignalSpy serviceAvailableSpy(m_subject, + SIGNAL(serviceAvailable(QString))); + QSignalSpy serviceChangedSpy(m_subject, + SIGNAL(serviceChanged(QString))); + + m_subject->service = "org.maemo.TextProcessor"; + + QString thisService = "com.nokia.TextProcessor"; + serviceFwService = thisService; + + m_subject->handleServiceAvailable(thisService, "org.maemo.MailService"); + QCOMPARE(serviceAvailableSpy.count(), 0); + QCOMPARE(serviceChangedSpy.count(), 0); +} + +// current service; new preferred service for this if +// should not get signal:serviceAvilable +// should get signal:serviceChanged +void Ut_DuiServiceFwBaseIf::testHandleServiceAvailable3() +{ + QSignalSpy serviceAvailableSpy(m_subject, + SIGNAL(serviceAvailable(QString))); + QSignalSpy serviceChangedSpy(m_subject, + SIGNAL(serviceChanged(QString))); + + m_subject->service = "org.maemo.TextProcessor"; + + QString thisService = "com.nokia.TextProcessor"; + serviceFwService = thisService; + + m_subject->handleServiceAvailable(thisService, m_subject->interface); + QCOMPARE(serviceAvailableSpy.count(), 0); + QCOMPARE(serviceChangedSpy.count(), 1); +} + +// no current service; dead service is for other if +// should not get serviceUnavailable +// should not get serviceChanged +void Ut_DuiServiceFwBaseIf::testHandleServiceUnavailable0() +{ + QSignalSpy serviceUnavailableSpy(m_subject, + SIGNAL(serviceUnavailable(QString))); + QSignalSpy serviceChangedSpy(m_subject, + SIGNAL(serviceChanged(QString))); + + m_subject->service = ""; + + QString thisService = "com.nokia.TextProcessor"; + serviceFwService = ""; + + m_subject->handleServiceUnavailable(thisService); + QCOMPARE(serviceUnavailableSpy.count(), 0); + QCOMPARE(serviceChangedSpy.count(), 0); +} + +// current service; dead service is for other if +// should not get serviceUnavailable +// should not get serviceChanged +void Ut_DuiServiceFwBaseIf::testHandleServiceUnavailable1() +{ + QSignalSpy serviceUnavailableSpy(m_subject, + SIGNAL(serviceUnavailable(QString))); + QSignalSpy serviceChangedSpy(m_subject, + SIGNAL(serviceChanged(QString))); + + m_subject->service = "com.nokia.TextProcessor"; + + serviceFwService = m_subject->service; + + m_subject->handleServiceUnavailable("com.nokia.EmailService"); + QCOMPARE(serviceUnavailableSpy.count(), 0); + QCOMPARE(serviceChangedSpy.count(), 0); +} + +// current service; dead service is not last for this if +// should not get serviceUnavailable +// should get serviceChanged +void Ut_DuiServiceFwBaseIf::testHandleServiceUnavailable2() +{ + QSignalSpy serviceUnavailableSpy(m_subject, + SIGNAL(serviceUnavailable(QString))); + QSignalSpy serviceChangedSpy(m_subject, + SIGNAL(serviceChanged(QString))); + + m_subject->service = "com.nokia.TextProcessor"; + + serviceFwService = "org.maemo.TextProcessor"; + + m_subject->handleServiceUnavailable(m_subject->service); + QCOMPARE(serviceUnavailableSpy.count(), 0); + QCOMPARE(serviceChangedSpy.count(), 1); +} + +// current service; dead service is last for this if +// should get serviceUnavailable +// should not get serviceChanged +void Ut_DuiServiceFwBaseIf::testHandleServiceUnavailable3() +{ + QSignalSpy serviceUnavailableSpy(m_subject, + SIGNAL(serviceUnavailable(QString))); + QSignalSpy serviceChangedSpy(m_subject, + SIGNAL(serviceChanged(QString))); + + m_subject->service = "com.nokia.TextProcessor"; + + serviceFwService = ""; + + m_subject->handleServiceUnavailable(m_subject->service); + QCOMPARE(serviceUnavailableSpy.count(), 1); + QCOMPARE(serviceChangedSpy.count(), 0); +} + +void Ut_DuiServiceFwBaseIf::testResolveServiceName() +{ + serviceFwService = "com.nokia.TextProcessor"; + + QString thisService = m_subject->resolveServiceName("com.nokia.TextProcessorIf", ""); + QCOMPARE(thisService, serviceFwService); + + thisService = m_subject->resolveServiceName("com.nokia.TextProcessorIf", "org.maemo.TextProcessor"); + QCOMPARE(thisService, QString("org.maemo.TextProcessor")); +} + +QTEST_APPLESS_MAIN(Ut_DuiServiceFwBaseIf) diff --git a/tests/ut_duiservicefwbaseif/ut_duiservicefwbaseif.h b/tests/ut_duiservicefwbaseif/ut_duiservicefwbaseif.h new file mode 100644 index 000000000..e0b7cc4d8 --- /dev/null +++ b/tests/ut_duiservicefwbaseif/ut_duiservicefwbaseif.h @@ -0,0 +1,106 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUISERVICEFWBASEIF_H +#define UT_DUISERVICEFWBASEIF_H + +#include +#include + +#include "duiservicefwbaseif.h" + + +Q_DECLARE_METATYPE(DuiServiceFwBaseIf *); + +class Ut_DuiServiceFwBaseIf : public QObject +{ + Q_OBJECT + +public: + static QString serviceFwService; + +private slots: + void init(); + void cleanup(); + void initTestCase(); + void cleanupTestCase(); + + /* + * no current service; new service for other if + * should not get signal:serviceAvailable + * should not get signal:serviceChanged + */ + void testHandleServiceAvailable0(); + + /* + * no current service; new service for this if + * should get signal:serviceAvailable + * should get signal:serviceChanged + */ + void testHandleServiceAvailable1(); + + /* + * current service; new preferred service for other if + * should not get signal:serviceAvilable + * should get signal:serviceChanged + */ + void testHandleServiceAvailable2(); + + /* + * current service; new preferred service for this if + * should not get signal:serviceAvilable + * should get signal:serviceChanged + */ + void testHandleServiceAvailable3(); + + /* + * no current service; dead service is for other if + * should not get serviceUnavailable + * should not get serviceChanged + */ + void testHandleServiceUnavailable0(); + + /* + * current service; dead service is for other if + * should not get serviceUnavailable + * should not get serviceChanged + */ + void testHandleServiceUnavailable1(); + + /* + * current service; dead service is not last for this if + * should not get serviceUnavailable + * should not get serviceChanged + */ + void testHandleServiceUnavailable2(); + + /* + * current service; dead service is last for this if + * should not get serviceUnavailable + * should not get serviceChanged + */ + void testHandleServiceUnavailable3(); + + void testResolveServiceName(); + +private: + DuiServiceFwBaseIf *m_subject; + +}; +#endif diff --git a/tests/ut_duiservicefwbaseif/ut_duiservicefwbaseif.pro b/tests/ut_duiservicefwbaseif/ut_duiservicefwbaseif.pro new file mode 100644 index 000000000..cf9fbadfc --- /dev/null +++ b/tests/ut_duiservicefwbaseif/ut_duiservicefwbaseif.pro @@ -0,0 +1,33 @@ +include(../common_top.pri) + +# need to copy the units here in order to avoid force the inclusion of the local duiservicefwproxy.h +# which contains the stubbed proxy that does not rely on qdbus +# see further down for a failed attempt to get this to work some other way +SFWDIR = $$DUISRCDIR/servicefwif +TEST_SOURCE = duiservicefwbaseif.cpp +TEST_SRC_FROM = $$SFWDIR/$$TEST_SOURCE +TEST_HEADER = duiservicefwbaseif.h +TEST_HDR_FROM = $$SFWDIR/$$TEST_HEADER + +QMAKE_CLEAN += $$TEST_HEADER $$TEST_SOURCE + +INCLUDEPATH = \ + . \ + $$DUISRCDIR/include \ + $$SFWDIR/include \ + +DEPENDPATH = $$INCLUDEPATH + +TARGET = ut_duiservicefwbaseif + +SOURCES += \ + ut_duiservicefwbaseif.cpp \ + duiservicefwproxy.cpp \ + $$SFWDIR/$$TEST_SOURCE \ + +HEADERS += \ + ut_duiservicefwbaseif.h \ + duiservicefwproxy.h \ + $$SFWDIR/$$TEST_HEADER \ + +include(../common_bot.pri) diff --git a/tests/ut_duiserviceinvoker/.gitignore b/tests/ut_duiserviceinvoker/.gitignore new file mode 100644 index 000000000..b23ec33ac --- /dev/null +++ b/tests/ut_duiserviceinvoker/.gitignore @@ -0,0 +1 @@ +ut_duiserviceinvoker diff --git a/tests/ut_duiserviceinvoker/ut_duiserviceinvoker.cpp b/tests/ut_duiserviceinvoker/ut_duiserviceinvoker.cpp new file mode 100644 index 000000000..0e9471548 --- /dev/null +++ b/tests/ut_duiserviceinvoker/ut_duiserviceinvoker.cpp @@ -0,0 +1,74 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duiserviceinvoker.h" + +#include + +void DuiServiceAction::executeService() +{ +} + +MockServiceAction::MockServiceAction() : + DuiServiceAction(NULL), + executeServiceCalled(false) +{ +} + +void MockServiceAction::trigger() +{ + emit triggered(); +} + +void MockServiceAction::executeService() +{ + executeServiceCalled = true; +} + + +// Called before the first testfunction is executed +void Ut_DuiServiceInvoker::initTestCase() +{ +} + +// Called after the last testfunction was executed +void Ut_DuiServiceInvoker::cleanupTestCase() +{ +} + +// Called before each testfunction is executed +void Ut_DuiServiceInvoker::init() +{ +} + +// Called after every testfunction +void Ut_DuiServiceInvoker::cleanup() +{ +} + +void Ut_DuiServiceInvoker::testInvoke() +{ + MockServiceAction *action = new MockServiceAction(); + action->executeServiceCalled = false; + action->trigger(); + delete action; + QVERIFY(action->executeServiceCalled); +} + +QTEST_MAIN(Ut_DuiServiceInvoker) diff --git a/tests/ut_duiserviceinvoker/ut_duiserviceinvoker.h b/tests/ut_duiserviceinvoker/ut_duiserviceinvoker.h new file mode 100644 index 000000000..9dce4553f --- /dev/null +++ b/tests/ut_duiserviceinvoker/ut_duiserviceinvoker.h @@ -0,0 +1,57 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUISERVICEINVOKER_H +#define UT_DUISERVICEINVOKER_H + +#include +#include +#include + +class MockServiceAction : public DuiServiceAction +{ + Q_OBJECT; + +public: + MockServiceAction(); + + void trigger(); + + virtual void executeService(); + + bool executeServiceCalled; + +}; + + +class Ut_DuiServiceInvoker : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + + void testInvoke(); + +}; + +#endif diff --git a/tests/ut_duiserviceinvoker/ut_duiserviceinvoker.pro b/tests/ut_duiserviceinvoker/ut_duiserviceinvoker.pro new file mode 100644 index 000000000..9c12d798b --- /dev/null +++ b/tests/ut_duiserviceinvoker/ut_duiserviceinvoker.pro @@ -0,0 +1,20 @@ +include(../common_top.pri) +TARGET = ut_duiserviceinvoker + +INCLUDEPATH += $$DUISRCDIR/service + +TEST_SOURCES = \ + $$DUISRCDIR/service/duiserviceinvoker.cpp + +# unit test and unit +SOURCES += \ + ut_duiserviceinvoker.cpp \ + $$TEST_SOURCES + +# unit test and unit +HEADERS += \ + ut_duiserviceinvoker.h \ + $$DUISRCDIR/service/duiserviceinvoker.h \ + $$DUISRCDIR/service/duiserviceaction.h + +include(../common_bot.pri) diff --git a/tests/ut_duiservicemapper/.gitignore b/tests/ut_duiservicemapper/.gitignore new file mode 100644 index 000000000..4c4a4ae3a --- /dev/null +++ b/tests/ut_duiservicemapper/.gitignore @@ -0,0 +1 @@ +ut_duiservicemapper diff --git a/tests/ut_duiservicemapper/ut_duiservicemapper.cpp b/tests/ut_duiservicemapper/ut_duiservicemapper.cpp new file mode 100644 index 000000000..4048c3b93 --- /dev/null +++ b/tests/ut_duiservicemapper/ut_duiservicemapper.cpp @@ -0,0 +1,227 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include +#include "ut_duiservicemapper.h" + +#include "duiservicemapper_p.h" + +const int Ut_DuiServiceMapper::noAllFiles; +QTextStream Ut_DuiServiceMapper::globalDummy; +int Ut_DuiServiceMapper::noFiles; +int Ut_DuiServiceMapper::lineNo; +int Ut_DuiServiceMapper::fileNo; +QString Ut_DuiServiceMapper::lines[4][2]; +QString Ut_DuiServiceMapper::services[3]; +QString Ut_DuiServiceMapper::interfaces[3]; + +QStringList DuiServiceMapperPrivate::fillServiceFileList() const +{ + QStringList retVal; + for (int thisFileNo = 0; thisFileNo < Ut_DuiServiceMapper::noFiles; ++thisFileNo) { + QString filename = QString("services/%1.service").arg(thisFileNo); + retVal << filename; + } + + return retVal; +} + +bool DuiServiceMapperPrivate::fileExistsAndReadable(const QString &fileName) const +{ + Q_UNUSED(fileName); + bool retVal; + + QString baseName = QFileInfo(fileName).baseName(); + int thisFileNo = baseName.toInt(); + retVal = thisFileNo < Ut_DuiServiceMapper::noFiles; + + return retVal; +} + +QIODevice *DuiServiceMapperPrivate::accessFile(const QString &fileName) const +{ + Q_UNUSED(fileName); + QBuffer *thisFile = new QBuffer(); + thisFile->open(QIODevice::ReadWrite); + + int lastFileNo = Ut_DuiServiceMapper::noFiles - 1; + + QString baseName = QFileInfo(fileName).baseName(); + int thisFileNo = baseName.toInt(); + + bool thisFileShouldExist = thisFileNo <= lastFileNo; + if (thisFileShouldExist) { + for (int thisLineNo = 0; thisLineNo < 2; ++thisLineNo) { + QTextStream output(thisFile); + output << Ut_DuiServiceMapper::lines[ thisFileNo ][ thisLineNo ] << endl; + } + } + thisFile->seek(0); + + return thisFile; +} + +void Ut_DuiServiceMapper::init() +{ + // always start with two files + //mkFiles( 2 ); + noFiles = 2; + + // reset to beginning of first file for each test + // difficult to keep track otherwise + lineNo = 0; + fileNo = 0; + + m_subject = new DuiServiceMapper("/"); +} + +void Ut_DuiServiceMapper::cleanup() +{ + delete m_subject; + m_subject = 0; +} + +void Ut_DuiServiceMapper::initTestCase() +{ + services[0] = "com.nokia.EmailService"; + interfaces[0] = "com.nokia.EmailServiceIf"; + services[1] = "org.maemo.EmailService"; + interfaces[1] = "org.maemo.EmailServiceIf"; + services[2] = "com.google.EmailService"; + interfaces[2] = "com.google.EmailServiceIf"; + + lines[0][0] = "Interface=" + interfaces[0]; + lines[0][1] = "Name=" + services[0]; + lines[1][0] = "Interface=" + interfaces[1]; + lines[1][1] = "Name=" + services[1]; + lines[2][0] = "Interface=" + interfaces[2]; + lines[2][1] = "Name=" + services[2]; + lines[3][0] = "Interface=not provided"; + lines[3][1] = "Name=not provided"; + + //QDir(".").mkdir( "services" ); +} + +void Ut_DuiServiceMapper::cleanupTestCase() +{ + //mkFiles(0); + noFiles = 0; + QDir(".").rmdir("services"); +} + +void Ut_DuiServiceMapper::mkFiles(int noFiles) +{ + int lastFileNo = noFiles - 1; + + for (int thisFileNo = 0; thisFileNo < noAllFiles; ++thisFileNo) { + QString filename = QString("services/%1.service").arg(thisFileNo); + + QFile thisFile(filename); + bool thisFileShouldExist = thisFileNo <= lastFileNo; + if (thisFile.exists()) { + if (!thisFileShouldExist) { + thisFile.remove(); + } + } else { + if (thisFileShouldExist) { + bool openFailed = !thisFile.open(QIODevice::WriteOnly | QIODevice::Text); + if (openFailed) { + qCritical() << "Could not open file for writing"; + } + + for (int thisLineNo = 0; thisLineNo < 2; ++thisLineNo) { + QTextStream output(&thisFile); + output << lines[ thisFileNo ][ thisLineNo ] << endl; + } + } + } + + thisFile.close(); + } +} + +void Ut_DuiServiceMapper::checkServiceNamesNoIf() +{ + // check without interface - should list all + QStringList myServices = m_subject->serviceNames(); + + QCOMPARE(myServices.size(), 2); + QCOMPARE(myServices[0], services[0]); + QCOMPARE(myServices[1], services[1]); +} + +void Ut_DuiServiceMapper::checkServiceNamesIf() +{ + // check with interface + QStringList myServices = m_subject->serviceNames("com.nokia.EmailServiceIf"); + + QCOMPARE(myServices.size(), 1); + QCOMPARE(myServices[0], services[0]); +} + +void Ut_DuiServiceMapper::checkServiceName() +{ + QString myService = m_subject->serviceName(interfaces[0]); + QCOMPARE(myService, services[0]); +} + +void Ut_DuiServiceMapper::checkServicePath() +{ + QString myPath = m_subject->servicePath(interfaces[0]); + QCOMPARE(myPath, QString("/")); +} + +void Ut_DuiServiceMapper::checkHandleServiceChangedAddLastFile() +{ + QSignalSpy serviceAvailableSpy(m_subject, + SIGNAL(serviceAvailable(QString, QString))); + + // add a file - constructed with 2 files + //mkFiles( 3 ); + noFiles = 3; + m_subject->handleServiceChanged("/"); + + QCOMPARE(serviceAvailableSpy.count(), 1); +} + +void Ut_DuiServiceMapper::checkHandleServiceChangedRmLastFile() +{ + QSignalSpy serviceUnavailableSpy(m_subject, + SIGNAL(serviceUnavailable(QString))); + + // remove a file - constructed with 2 files + //mkFiles( 1 ); + noFiles = 1; + m_subject->handleServiceChanged("/"); + + QCOMPARE(serviceUnavailableSpy.count(), 1); +} + +void Ut_DuiServiceMapper::checkServiceNameBadIf() +{ + //mkFiles( 4 ); + noFiles = 4; + lineNo = 3; + QString myService = m_subject->serviceName("not provided"); + QVERIFY(myService.isEmpty()); +} + +QTEST_MAIN(Ut_DuiServiceMapper) diff --git a/tests/ut_duiservicemapper/ut_duiservicemapper.h b/tests/ut_duiservicemapper/ut_duiservicemapper.h new file mode 100644 index 000000000..3d3a02721 --- /dev/null +++ b/tests/ut_duiservicemapper/ut_duiservicemapper.h @@ -0,0 +1,62 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_SERVICEMAPPER_H +#define UT_SERVICEMAPPER_H + +#include +#include + +#include + +Q_DECLARE_METATYPE(DuiServiceMapper *); + +class Ut_DuiServiceMapper : public QObject +{ + Q_OBJECT + +public: + static const int noAllFiles = 3; + static int noFiles; + static QTextStream globalDummy; + static int lineNo; + static int fileNo; + static QString lines[4][2]; + static QString services[3]; + static QString interfaces[3]; + +private slots: + void init(); + void cleanup(); + void initTestCase(); + void cleanupTestCase(); + void checkHandleServiceChangedRmLastFile(); + void checkServiceNamesNoIf(); + void checkServiceNamesIf(); + void checkServiceName(); + void checkServicePath(); + void checkHandleServiceChangedAddLastFile(); + void checkServiceNameBadIf(); + +private: + DuiServiceMapper *m_subject; + void mkFiles(int noFiles); + +}; +#endif diff --git a/tests/ut_duiservicemapper/ut_duiservicemapper.pro b/tests/ut_duiservicemapper/ut_duiservicemapper.pro new file mode 100644 index 000000000..4867b665a --- /dev/null +++ b/tests/ut_duiservicemapper/ut_duiservicemapper.pro @@ -0,0 +1,24 @@ +include(../common_top.pri) + +SFWDIR = ../../duiservicemapper +INCLUDEPATH += $$SFWDIR +DEPENDPATH += $$INCLUDEPATH +QT -= dbus svg network gui + +TARGET = ut_duiservicemapper + +# unit +TEST_SOURCES = \ + $$SFWDIR/duiservicemapper.cpp \ + +# unit test and unit +SOURCES += \ + $$TEST_SOURCES \ + ut_duiservicemapper.cpp \ + +# unit test and unit +HEADERS += \ + ut_duiservicemapper.h \ + $$SFWDIR/duiservicemapper.h \ + +include(../common_bot.pri) diff --git a/tests/ut_duisettings/.gitignore b/tests/ut_duisettings/.gitignore new file mode 100644 index 000000000..e6cd77409 --- /dev/null +++ b/tests/ut_duisettings/.gitignore @@ -0,0 +1 @@ +ut_duisettings diff --git a/tests/ut_duisettings/ut_duisettings.cpp b/tests/ut_duisettings/ut_duisettings.cpp new file mode 100644 index 000000000..6afd449fb --- /dev/null +++ b/tests/ut_duisettings/ut_duisettings.cpp @@ -0,0 +1,59 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include + +#include + + +#include "ut_duisettings.h" + +void Ut_DuiSettings::init() +{ + QString doesNotExist("/root/createdByUt_DuiSettings"); + QString exists("/dev/null"); + + m_subject = new DuiSettings(doesNotExist); + delete m_subject; + m_subject = new DuiSettings(exists); +} + +void Ut_DuiSettings::cleanup() +{ + delete m_subject; + m_subject = 0; +} + +void Ut_DuiSettings::initTestCase() +{ +} + +void Ut_DuiSettings::globalSettings() +{ + m_subject->globalValue(DuiSettings::ThemeNameSetting); + m_subject->globalValue(DuiSettings::FrameworkSvgSetting); + m_subject->globalValue(DuiSettings::FrameworkCssSetting); +} + +void Ut_DuiSettings::cleanupTestCase() +{ +} + +QTEST_MAIN(Ut_DuiSettings) diff --git a/tests/ut_duisettings/ut_duisettings.h b/tests/ut_duisettings/ut_duisettings.h new file mode 100644 index 000000000..148e943cc --- /dev/null +++ b/tests/ut_duisettings/ut_duisettings.h @@ -0,0 +1,47 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUISETTINGS_H +#define UT_DUISETTINGS_H + +#include +#include + +// the real unit/DuiSettings class declaration +#include + +Q_DECLARE_METATYPE(DuiSettings *); + +class Ut_DuiSettings : public QObject +{ + Q_OBJECT + +private slots: + void init(); + void cleanup(); + void initTestCase(); + void cleanupTestCase(); + + void globalSettings(); + +private: + DuiSettings *m_subject; +}; + +#endif diff --git a/tests/ut_duisettings/ut_duisettings.pro b/tests/ut_duisettings/ut_duisettings.pro new file mode 100644 index 000000000..f6da9e92a --- /dev/null +++ b/tests/ut_duisettings/ut_duisettings.pro @@ -0,0 +1,31 @@ +include(../common_top.pri) + +TARGET = ut_duisettings + +TEST_SOURCES = \ +# $$DUISRCDIR/duisettings.cpp \ + +# unit test and unit +SOURCES += \ + ut_duisettings.cpp \ +# $$TEST_SOURCES \ + +# base classes +SOURCES += \ + +# service classes +SOURCES += \ + $$STUBSDIR/stubbase.cpp \ + +# unit test and unit +HEADERS += \ + ut_duisettings.h \ +# $$DUISRCDIR/duisettings.h \ + +# base classes +HEADERS += \ + +# service classes +HEADERS += \ + +include(../common_bot.pri) diff --git a/tests/ut_duisettingslanguagebinary/.gitignore b/tests/ut_duisettingslanguagebinary/.gitignore new file mode 100644 index 000000000..5132d9830 --- /dev/null +++ b/tests/ut_duisettingslanguagebinary/.gitignore @@ -0,0 +1,2 @@ +ut_duisettingslanguagebinary + diff --git a/tests/ut_duisettingslanguagebinary/ut_duisettingslanguagebinary.cpp b/tests/ut_duisettingslanguagebinary/ut_duisettingslanguagebinary.cpp new file mode 100644 index 000000000..2dc36db67 --- /dev/null +++ b/tests/ut_duisettingslanguagebinary/ut_duisettingslanguagebinary.cpp @@ -0,0 +1,84 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duisettingslanguagebinary.h" + +#include +#include +#include +#include +#include +#include + +// Called before the first testfunction is executed +void Ut_DuiSettingsLanguageBinary::initTestCase() +{ +} + +// Called after the last testfunction was executed +void Ut_DuiSettingsLanguageBinary::cleanupTestCase() +{ +} + +// Called before each testfunction is executed +void Ut_DuiSettingsLanguageBinary::init() +{ + m_subject = new DuiSettingsLanguageBinary(); +} + +// Called after every testfunction +void Ut_DuiSettingsLanguageBinary::cleanup() +{ + delete m_subject; + m_subject = NULL; +} + +void Ut_DuiSettingsLanguageBinary::testKeys() +{ + // Create some test nodes with keys + gDuiSettingsLanguageSelectionStub->stubSetReturnValue("key", QString("enumKey")); + gDuiSettingsLanguageTextStub->stubSetReturnValue("key", QString("textKey")); + gDuiSettingsLanguageBooleanStub->stubSetReturnValue("key", QString("boolKey")); + gDuiSettingsLanguageIntegerStub->stubSetReturnValue("key", QString("intKey")); + DuiSettingsLanguageSettings *child = new DuiSettingsLanguageSettings(); + DuiSettingsLanguageSelection *aEnum = new DuiSettingsLanguageSelection("enumKey"); + DuiSettingsLanguageText *aText = new DuiSettingsLanguageText("textKey", "bar"); + DuiSettingsLanguageBoolean *aBool = new DuiSettingsLanguageBoolean("boolKey", "boolBar"); + DuiSettingsLanguageInteger *aInteger = new DuiSettingsLanguageInteger("intKey", "foo"); + QCOMPARE(m_subject->numChildren(), uint(0)); + m_subject->addChild(child); + child->addChild(aEnum); + child->addChild(aText); + child->addChild(aBool); + child->addChild(aInteger); + QList children = m_subject->children(); + QCOMPARE(children.count(), 1); + QCOMPARE(children.at(0), child); + QCOMPARE(child->numChildren(), uint(4)); + + // Get the keys + QList keys = m_subject->keys(); + QCOMPARE(keys.count(), 4); + QVERIFY(keys.contains(QString("enumKey"))); + QVERIFY(keys.contains(QString("textKey"))); + QVERIFY(keys.contains(QString("boolKey"))); + QVERIFY(keys.contains(QString("intKey"))); +} + +QTEST_MAIN(Ut_DuiSettingsLanguageBinary) diff --git a/tests/ut_duisettingslanguagebinary/ut_duisettingslanguagebinary.h b/tests/ut_duisettingslanguagebinary/ut_duisettingslanguagebinary.h new file mode 100644 index 000000000..6b12b81ab --- /dev/null +++ b/tests/ut_duisettingslanguagebinary/ut_duisettingslanguagebinary.h @@ -0,0 +1,44 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUISETTINGSLANGUAGEBINARY_H +#define UT_DUISETTINGSLANGUAGEBINARY_H + +#include +#include + +class DuiSettingsLanguageBinary; + +class Ut_DuiSettingsLanguageBinary : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + + void testKeys(); + +private: + DuiSettingsLanguageBinary *m_subject; +}; + +#endif diff --git a/tests/ut_duisettingslanguagebinary/ut_duisettingslanguagebinary.pro b/tests/ut_duisettingslanguagebinary/ut_duisettingslanguagebinary.pro new file mode 100644 index 000000000..e4926629d --- /dev/null +++ b/tests/ut_duisettingslanguagebinary/ut_duisettingslanguagebinary.pro @@ -0,0 +1,25 @@ +include(../common_top.pri) + +INCLUDEPATH += $$DUISRCDIR/settingslanguage + +TARGET = ut_duisettingslanguagebinary + +# unit test and unit +SOURCES += \ + ut_duisettingslanguagebinary.cpp \ + $$DUISRCDIR/settingslanguage/duisettingslanguagebinary.cpp \ + $$DUISRCDIR/settingslanguage/duisettingslanguagenode.cpp \ + $$DUISRCDIR/settingslanguage/duisettingslanguagesettings.cpp + +# service classes +SOURCES += \ + $$STUBSDIR/stubbase.cpp \ + +# unit test and unit +HEADERS += \ + ut_duisettingslanguagebinary.h \ + $$DUISRCDIR/settingslanguage/duisettingslanguagebinary.h \ + $$DUISRCDIR/settingslanguage/duisettingslanguagenode.h \ + $$DUISRCDIR/settingslanguage/duisettingslanguagesettings.h + +include(../common_bot.pri) diff --git a/tests/ut_duisettingslanguageboolean/.gitignore b/tests/ut_duisettingslanguageboolean/.gitignore new file mode 100644 index 000000000..298c49d9e --- /dev/null +++ b/tests/ut_duisettingslanguageboolean/.gitignore @@ -0,0 +1 @@ +ut_duisettingslanguageboolean diff --git a/tests/ut_duisettingslanguageboolean/ut_duisettingslanguageboolean.cpp b/tests/ut_duisettingslanguageboolean/ut_duisettingslanguageboolean.cpp new file mode 100644 index 000000000..4739aac81 --- /dev/null +++ b/tests/ut_duisettingslanguageboolean/ut_duisettingslanguageboolean.cpp @@ -0,0 +1,78 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include + +#include + +#include "ut_duisettingslanguageboolean.h" + +bool gLocalizeStrings = false; +QString qtTrId(const char *id, int) +{ + if (gLocalizeStrings) { + return QString(id) + "Localized"; + } else { + return id; + } +} + +void Ut_DuiSettingsLanguageBoolean::init() +{ + m_subject = new DuiSettingsLanguageBoolean("key", "title1"); +} + +void Ut_DuiSettingsLanguageBoolean::cleanup() +{ + delete m_subject; + m_subject = 0; +} + +void Ut_DuiSettingsLanguageBoolean::initTestCase() +{ + gLocalizeStrings = false; +} + +void Ut_DuiSettingsLanguageBoolean::cleanupTestCase() +{ +} + +void Ut_DuiSettingsLanguageBoolean::testBooleanKey() +{ + QCOMPARE(m_subject->key(), QString("key")); +} + +void Ut_DuiSettingsLanguageBoolean::testBooleanTitle() +{ + QCOMPARE(m_subject->title(), QString("title1")); +} + +void Ut_DuiSettingsLanguageBoolean::testNodeType() +{ + QVERIFY((dynamic_cast(m_subject))); +} + +void Ut_DuiSettingsLanguageBoolean::testBooleanTitleLocalized() +{ + gLocalizeStrings = true; + QCOMPARE(m_subject->title(), QString("title1Localized")); +} + +QTEST_MAIN(Ut_DuiSettingsLanguageBoolean) diff --git a/tests/ut_duisettingslanguageboolean/ut_duisettingslanguageboolean.h b/tests/ut_duisettingslanguageboolean/ut_duisettingslanguageboolean.h new file mode 100644 index 000000000..1504d394e --- /dev/null +++ b/tests/ut_duisettingslanguageboolean/ut_duisettingslanguageboolean.h @@ -0,0 +1,49 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUISETTINGSLANGUAGESELECTION_H +#define UT_DUISETTINGSLANGUAGESELECTION_H + +#include +#include + +#include + +Q_DECLARE_METATYPE(DuiSettingsLanguageBoolean *); + +class Ut_DuiSettingsLanguageBoolean : public QObject +{ + Q_OBJECT + +private slots: + void init(); + void cleanup(); + void initTestCase(); + void cleanupTestCase(); + + void testBooleanKey(); + void testBooleanTitle(); + void testNodeType(); + void testBooleanTitleLocalized(); + +private: + DuiSettingsLanguageBoolean *m_subject; +}; + +#endif diff --git a/tests/ut_duisettingslanguageboolean/ut_duisettingslanguageboolean.pro b/tests/ut_duisettingslanguageboolean/ut_duisettingslanguageboolean.pro new file mode 100644 index 000000000..85658c8fa --- /dev/null +++ b/tests/ut_duisettingslanguageboolean/ut_duisettingslanguageboolean.pro @@ -0,0 +1,23 @@ +include(../common_top.pri) + +INCLUDEPATH += $$DUISRCDIR/settingslanguage + +TARGET = ut_duisettingslanguageboolean + +# unit test and unit +SOURCES += \ + ut_duisettingslanguageboolean.cpp \ + $$DUISRCDIR/settingslanguage/duisettingslanguageboolean.cpp \ + $$DUISRCDIR/settingslanguage/duisettingslanguagenode.cpp + +# service classes +SOURCES += \ + $$STUBSDIR/stubbase.cpp \ + +# unit test and unit +HEADERS += \ + ut_duisettingslanguageboolean.h \ + $$DUISRCDIR/settingslanguage/duisettingslanguageboolean.h \ + $$DUISRCDIR/settingslanguage/duisettingslanguagenode.h + +include(../common_bot.pri) diff --git a/tests/ut_duisettingslanguagebooleancontroller/.gitignore b/tests/ut_duisettingslanguagebooleancontroller/.gitignore new file mode 100644 index 000000000..5c03556cd --- /dev/null +++ b/tests/ut_duisettingslanguagebooleancontroller/.gitignore @@ -0,0 +1 @@ +ut_duisettingslanguagebooleancontroller diff --git a/tests/ut_duisettingslanguagebooleancontroller/ut_duisettingslanguagebooleancontroller.cpp b/tests/ut_duisettingslanguagebooleancontroller/ut_duisettingslanguagebooleancontroller.cpp new file mode 100644 index 000000000..4c2a88d5a --- /dev/null +++ b/tests/ut_duisettingslanguagebooleancontroller/ut_duisettingslanguagebooleancontroller.cpp @@ -0,0 +1,93 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duisettingslanguagebooleancontroller.h" +#include "duisettingslanguagebooleancontroller.h" +#include "duisettingslanguagebooleanfactory.h" +#include "duisettingslanguageboolean.h" +#include "duisettingslanguagewidget.h" + +#include +#include +#include +#include +#include +#include "../stubs/mockdatastore.h" + +// QCoreApplication stubs to avoid crashing in processEvents() +QStringList QCoreApplication::arguments() +{ + return QStringList(); +} + +void Ut_DuiSettingsLanguageBooleanController::init() +{ +} + +void Ut_DuiSettingsLanguageBooleanController::cleanup() +{ +} + +void Ut_DuiSettingsLanguageBooleanController::initTestCase() +{ + static int argc = 1; + static char *app_name[1] = { (char *)"./ut_duisettingslanguagebooleancontroller" }; + app = new DuiApplication(argc, app_name); +} + +void Ut_DuiSettingsLanguageBooleanController::cleanupTestCase() +{ + delete app; +} + +void Ut_DuiSettingsLanguageBooleanController::testToggleButton() +{ + // Create a settings boolean + DuiSettingsLanguageBoolean se("testKey", "Toggle Button1"); + DuiSettingsLanguageWidget dds; + MockDataStore ddatas; + ddatas.createValue(se.key(), QVariant(false)); + + DuiWidgetController *widget = DuiSettingsLanguageBooleanFactory::createWidget(se, dds, &ddatas); + QVERIFY(widget != NULL); + + // Just find the toggle button + DuiButton *button = NULL; + foreach(QGraphicsItem * child, widget->childItems()) { + button = static_cast(child); + if (button != NULL && button->objectName() == "SettingsLanguageBooleanValueButton") { + break; + } + } + QVERIFY(button != NULL); + + // Wait for button model events.. shouldn't be needed, but known problem. + // TODO: can be removed after fixed to dui. + QApplication::processEvents(QEventLoop::WaitForMoreEvents, 10); + + DuiDataStore *dataStore = static_cast(button->property("dataStore").value()); + QVERIFY(!button->isChecked()); + + button->toggle(); + + QVERIFY(button->isChecked()); + QCOMPARE(dataStore->value("testKey").toBool(), true); +} + +QTEST_APPLESS_MAIN(Ut_DuiSettingsLanguageBooleanController) diff --git a/tests/ut_duisettingslanguagebooleancontroller/ut_duisettingslanguagebooleancontroller.h b/tests/ut_duisettingslanguagebooleancontroller/ut_duisettingslanguagebooleancontroller.h new file mode 100644 index 000000000..cca8e1643 --- /dev/null +++ b/tests/ut_duisettingslanguagebooleancontroller/ut_duisettingslanguagebooleancontroller.h @@ -0,0 +1,44 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUISETTINGSLANGUAGEBOOLEANCONTROLLER_H +#define UT_DUISETTINGSLANGUAGEBOOLEANCONTROLLER_H + +#include +#include + +class DuiApplication; + +class Ut_DuiSettingsLanguageBooleanController : public QObject +{ + Q_OBJECT + +private slots: + void init(); + void cleanup(); + void initTestCase(); + void cleanupTestCase(); + + void testToggleButton(); + +private: + DuiApplication *app; +}; + +#endif diff --git a/tests/ut_duisettingslanguagebooleancontroller/ut_duisettingslanguagebooleancontroller.pro b/tests/ut_duisettingslanguagebooleancontroller/ut_duisettingslanguagebooleancontroller.pro new file mode 100644 index 000000000..715d23849 --- /dev/null +++ b/tests/ut_duisettingslanguagebooleancontroller/ut_duisettingslanguagebooleancontroller.pro @@ -0,0 +1,24 @@ +include(../common_top.pri) + +INCLUDEPATH += $$DUISRCDIR/settingslanguage + +TARGET = ut_duisettingslanguagebooleancontroller + +# unit test and unit +SOURCES += \ + ut_duisettingslanguagebooleancontroller.cpp \ + $$DUISRCDIR/settingslanguage/duisettingslanguageboolean.cpp \ + $$DUISRCDIR/settingslanguage/duisettingslanguagebooleancontroller.cpp \ + $$DUISRCDIR/settingslanguage/duisettingslanguagebooleanfactory.cpp \ + $$DUISRCDIR/settingslanguage/duisettingslanguagenode.cpp + +# unit test and unit +HEADERS += \ + ut_duisettingslanguagebooleancontroller.h \ + $$DUISRCDIR/settingslanguage/duisettingslanguageboolean.h \ + $$DUISRCDIR/settingslanguage/duisettingslanguagebooleancontroller.h \ + $$DUISRCDIR/settingslanguage/duisettingslanguagebooleanfactory.h \ + $$DUISRCDIR/settingslanguage/duisettingslanguagenode.h + +include(../common_bot.pri) + diff --git a/tests/ut_duisettingslanguagebooleanfactory/.gitignore b/tests/ut_duisettingslanguagebooleanfactory/.gitignore new file mode 100644 index 000000000..e56d6cafd --- /dev/null +++ b/tests/ut_duisettingslanguagebooleanfactory/.gitignore @@ -0,0 +1 @@ +ut_duisettingslanguagebooleanfactory diff --git a/tests/ut_duisettingslanguagebooleanfactory/ut_duisettingslanguagebooleanfactory.cpp b/tests/ut_duisettingslanguagebooleanfactory/ut_duisettingslanguagebooleanfactory.cpp new file mode 100644 index 000000000..ecc45fbd2 --- /dev/null +++ b/tests/ut_duisettingslanguagebooleanfactory/ut_duisettingslanguagebooleanfactory.cpp @@ -0,0 +1,100 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duisettingslanguagebooleanfactory.h" + +#include "duisettingslanguagebooleanfactory.h" +#include "duisettingslanguagewidget_stub.h" +#include "duisettingslanguageboolean_stub.h" +#include "duisettingslanguagebooleancontroller_stub.h" +#include "mockdatastore.h" +#include +#include +#include +#include +#include +#include +#include + +// Tests +void Ut_DuiSettingsLanguageBooleanFactory::initTestCase() +{ + static int argc = 1; + static char *app_name[1] = { (char *)"./ut_duisettingslanguagebooleanfactory" }; + app = new DuiApplication(argc, app_name); +} + +void Ut_DuiSettingsLanguageBooleanFactory::cleanupTestCase() +{ + delete app; +} + +void Ut_DuiSettingsLanguageBooleanFactory::init() +{ +} + +void Ut_DuiSettingsLanguageBooleanFactory::cleanup() +{ +} + +void Ut_DuiSettingsLanguageBooleanFactory::testBuildWidget() +{ + // widget build as button checked + testBuildWidgetButtonCheck(true); + + // widget build as button unchecked + testBuildWidgetButtonCheck(false); +} + +void Ut_DuiSettingsLanguageBooleanFactory::testBuildWidgetButtonCheck(bool aIsChecked) +{ + // Create a settings boolean + DuiSettingsLanguageBoolean se("testKey", "ToggleButton1"); + gDuiSettingsLanguageBooleanStub->stubSetReturnValue("key", QString("testKey")); + gDuiSettingsLanguageBooleanStub->stubSetReturnValue("title", QString("ToggleButton1")); + DuiSettingsLanguageWidget dds; + MockDataStore ddatas; + ddatas.createValue(se.key(), QVariant(aIsChecked)); + + DuiWidgetController *widget = DuiSettingsLanguageBooleanFactory::createWidget(se, dds, &ddatas); + QVERIFY(widget != NULL); + + // Just find the toggle button + DuiButton *button = NULL; + foreach(QGraphicsItem * child, widget->childItems()) { + button = static_cast(child); + if (button != NULL && button->objectName() == "SettingsLanguageBooleanValueButton") { + break; + } + } + QVERIFY(button != NULL); + + QVERIFY(button->isCheckable()); + QVERIFY(button->isChecked() == aIsChecked); + QCOMPARE(button->objectName(), QString("SettingsLanguageBooleanValueButton")); + QCOMPARE(button->property("key").toString(), QString("testKey")); + QCOMPARE(button->text(), QString("ToggleButton1")); + + DuiDataStore *dataStore = static_cast(button->property("dataStore").value()); + QCOMPARE(dataStore->value("testKey").toBool(), aIsChecked); + + delete widget; +} + +QTEST_APPLESS_MAIN(Ut_DuiSettingsLanguageBooleanFactory) diff --git a/tests/ut_duisettingslanguagebooleanfactory/ut_duisettingslanguagebooleanfactory.h b/tests/ut_duisettingslanguagebooleanfactory/ut_duisettingslanguagebooleanfactory.h new file mode 100644 index 000000000..a70f156b0 --- /dev/null +++ b/tests/ut_duisettingslanguagebooleanfactory/ut_duisettingslanguagebooleanfactory.h @@ -0,0 +1,50 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUISETTINGSLANGUAGEBOOLEANFACTORY_H +#define UT_DUISETTINGSLANGUAGEBOOLEANFACTORY_H + +#include + +class DuiApplication; + +class Ut_DuiSettingsLanguageBooleanFactory : public QObject +{ + Q_OBJECT + +private slots: + // Executed once before every test case + void init(); + // Executed once after every test case + void cleanup(); + // Executed once before first test case + void initTestCase(); + // Executed once after last test case + void cleanupTestCase(); + + void testBuildWidget(); + +private: + void testBuildWidgetButtonCheck(bool aIsChecked); + +private: + DuiApplication *app; +}; + +#endif // UT_DUISETTINGSLANGUAGEBOOLEANFACTORY_H diff --git a/tests/ut_duisettingslanguagebooleanfactory/ut_duisettingslanguagebooleanfactory.pro b/tests/ut_duisettingslanguagebooleanfactory/ut_duisettingslanguagebooleanfactory.pro new file mode 100644 index 000000000..6b0f31271 --- /dev/null +++ b/tests/ut_duisettingslanguagebooleanfactory/ut_duisettingslanguagebooleanfactory.pro @@ -0,0 +1,22 @@ +include(../common_top.pri) +TARGET = ut_duisettingslanguagebooleanfactory +INCLUDEPATH += $$DUISRCDIR/settingslanguage + +# unit test and unit classes +SOURCES += \ + ut_duisettingslanguagebooleanfactory.cpp \ + $$DUISRCDIR/settingslanguage/duisettingslanguagebooleanfactory.cpp \ + $$DUISRCDIR/settingslanguage/duisettingslanguagenode.cpp + +# service classes +SOURCES += \ + $$STUBSDIR/stubbase.cpp \ + +# unit test and unit classes +HEADERS += \ + ut_duisettingslanguagebooleanfactory.h \ + $$DUISRCDIR/settingslanguage/duisettingslanguagebooleanfactory.h \ + $$DUISRCDIR/settingslanguage/duisettingslanguagebooleancontroller.h \ + $$DUISRCDIR/settingslanguage/duisettingslanguagenode.h + +include(../common_bot.pri) diff --git a/tests/ut_duisettingslanguageinteger/.gitignore b/tests/ut_duisettingslanguageinteger/.gitignore new file mode 100644 index 000000000..ebdb2ec6b --- /dev/null +++ b/tests/ut_duisettingslanguageinteger/.gitignore @@ -0,0 +1 @@ +ut_duisettingslanguageinteger diff --git a/tests/ut_duisettingslanguageinteger/ut_duisettingslanguageinteger.cpp b/tests/ut_duisettingslanguageinteger/ut_duisettingslanguageinteger.cpp new file mode 100644 index 000000000..a83814577 --- /dev/null +++ b/tests/ut_duisettingslanguageinteger/ut_duisettingslanguageinteger.cpp @@ -0,0 +1,83 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include + +#include + + +#include "ut_duisettingslanguageinteger.h" + +bool gLocalizeStrings = false; +QString qtTrId(const char *id, int) +{ + if (gLocalizeStrings) { + return QString(id) + "Localized"; + } else { + return id; + } +} + +void Ut_DuiSettingsLanguageInteger::init() +{ + m_subject = new DuiSettingsLanguageInteger("key", "title"); + m_subject->setMinValue(-100); + m_subject->setMaxValue(100); +} + +void Ut_DuiSettingsLanguageInteger::cleanup() +{ + delete m_subject; + m_subject = 0; +} + +void Ut_DuiSettingsLanguageInteger::initTestCase() +{ + gLocalizeStrings = false; +} + +void Ut_DuiSettingsLanguageInteger::cleanupTestCase() +{ +} + +void Ut_DuiSettingsLanguageInteger::testIntegerKeyTitle() +{ + QCOMPARE(m_subject->key(), QString("key")); + QCOMPARE(m_subject->title(), QString("title")); + int minVal; + QVERIFY(m_subject->minValue(minVal)); + QCOMPARE(minVal, -100); + int maxVal; + QVERIFY(m_subject->maxValue(maxVal)); + QCOMPARE(maxVal, 100); +} + +void Ut_DuiSettingsLanguageInteger::testNodeType() +{ + QVERIFY((dynamic_cast(m_subject))); +} + +void Ut_DuiSettingsLanguageInteger::testIntegerTitleLocalized() +{ + gLocalizeStrings = true; + QCOMPARE(m_subject->title(), QString("titleLocalized")); +} + +QTEST_MAIN(Ut_DuiSettingsLanguageInteger) diff --git a/tests/ut_duisettingslanguageinteger/ut_duisettingslanguageinteger.h b/tests/ut_duisettingslanguageinteger/ut_duisettingslanguageinteger.h new file mode 100644 index 000000000..f1e6401ed --- /dev/null +++ b/tests/ut_duisettingslanguageinteger/ut_duisettingslanguageinteger.h @@ -0,0 +1,48 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUISETTINGSLANGUAGEINTEGER_H +#define UT_DUISETTINGSLANGUAGEINTEGER_H + +#include +#include + +#include + +Q_DECLARE_METATYPE(DuiSettingsLanguageInteger *); + +class Ut_DuiSettingsLanguageInteger : public QObject +{ + Q_OBJECT + +private slots: + void init(); + void cleanup(); + void initTestCase(); + void cleanupTestCase(); + + void testIntegerKeyTitle(); + void testNodeType(); + void testIntegerTitleLocalized(); + +private: + DuiSettingsLanguageInteger *m_subject; +}; + +#endif diff --git a/tests/ut_duisettingslanguageinteger/ut_duisettingslanguageinteger.pro b/tests/ut_duisettingslanguageinteger/ut_duisettingslanguageinteger.pro new file mode 100644 index 000000000..aa52f8ed6 --- /dev/null +++ b/tests/ut_duisettingslanguageinteger/ut_duisettingslanguageinteger.pro @@ -0,0 +1,21 @@ +include(../common_top.pri) +TARGET = ut_duisettingslanguageinteger +INCLUDEPATH += $$DUISRCDIR/settingslanguage + +# unit test and unit classes +SOURCES += \ + ut_duisettingslanguageinteger.cpp \ + $$DUISRCDIR/settingslanguage/duisettingslanguageinteger.cpp \ + $$DUISRCDIR/settingslanguage/duisettingslanguagenode.cpp + +# service classes +SOURCES += \ + $$STUBSDIR/stubbase.cpp \ + +# unit test and unit classes +HEADERS += \ + ut_duisettingslanguageinteger.h \ + $$DUISRCDIR/settingslanguage/duisettingslanguageinteger.h \ + $$DUISRCDIR/settingslanguage/duisettingslanguagenode.h + +include(../common_bot.pri) diff --git a/tests/ut_duisettingslanguageintegercontroller/.gitignore b/tests/ut_duisettingslanguageintegercontroller/.gitignore new file mode 100644 index 000000000..e9490cdd7 --- /dev/null +++ b/tests/ut_duisettingslanguageintegercontroller/.gitignore @@ -0,0 +1 @@ +ut_duisettingslanguageintegercontroller diff --git a/tests/ut_duisettingslanguageintegercontroller/ut_duisettingslanguageintegercontroller.cpp b/tests/ut_duisettingslanguageintegercontroller/ut_duisettingslanguageintegercontroller.cpp new file mode 100644 index 000000000..8be3bf823 --- /dev/null +++ b/tests/ut_duisettingslanguageintegercontroller/ut_duisettingslanguageintegercontroller.cpp @@ -0,0 +1,73 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duisettingslanguageintegercontroller.h" +#include + +#include +#include +#include +#include "../stubs/mockdatastore.h" + +void TestSlider::changeValue(int newValue) +{ + emit valueChanged(newValue); +} + +void Ut_DuiSettingsLanguageIntegerController::init() +{ + m_subject = new DuiSettingsLanguageIntegerController(); +} + +void Ut_DuiSettingsLanguageIntegerController::cleanup() +{ + delete m_subject; +} + +void Ut_DuiSettingsLanguageIntegerController::initTestCase() +{ + static int argc = 1; + static char *argv[1] = { (char *) "./ut_duisettingslanguageintegercontroller" }; + app = new DuiApplication(argc, argv); +} + +void Ut_DuiSettingsLanguageIntegerController::cleanupTestCase() +{ + delete app; +} + +void Ut_DuiSettingsLanguageIntegerController::testValueChanged() +{ + MockDataStore dataStore; + dataStore.createValue(QString("integerKey"), 12); + + TestSlider slider; + slider.setValue(10); + + m_subject->setProperty("key", QString("integerKey")); + m_subject->setProperty("dataStore", qVariantFromValue(static_cast(&dataStore))); + + connect(&slider, SIGNAL(valueChanged(int)), m_subject, SLOT(changeValue(int))); + + QCOMPARE(dataStore.value("integerKey").toInt(), 12); + slider.changeValue(25); + QCOMPARE(dataStore.value("integerKey").toInt(), 25); +} + +QTEST_APPLESS_MAIN(Ut_DuiSettingsLanguageIntegerController) diff --git a/tests/ut_duisettingslanguageintegercontroller/ut_duisettingslanguageintegercontroller.h b/tests/ut_duisettingslanguageintegercontroller/ut_duisettingslanguageintegercontroller.h new file mode 100644 index 000000000..906d60436 --- /dev/null +++ b/tests/ut_duisettingslanguageintegercontroller/ut_duisettingslanguageintegercontroller.h @@ -0,0 +1,52 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUISETTINGSLANGUAGEINTEGERCONTROLLER_H +#define UT_DUISETTINGSLANGUAGEINTEGERCONTROLLER_H + +#include +#include + +class DuiApplication; +class DuiSettingsLanguageIntegerController; + +class TestSlider: public DuiSlider +{ +public: + void changeValue(int newValue); +}; + +class Ut_DuiSettingsLanguageIntegerController : public QObject +{ + Q_OBJECT + +private slots: + void init(); + void cleanup(); + void initTestCase(); + void cleanupTestCase(); + + void testValueChanged(); + +private: + DuiApplication *app; + DuiSettingsLanguageIntegerController *m_subject; +}; + +#endif diff --git a/tests/ut_duisettingslanguageintegercontroller/ut_duisettingslanguageintegercontroller.pro b/tests/ut_duisettingslanguageintegercontroller/ut_duisettingslanguageintegercontroller.pro new file mode 100644 index 000000000..550d0d1f1 --- /dev/null +++ b/tests/ut_duisettingslanguageintegercontroller/ut_duisettingslanguageintegercontroller.pro @@ -0,0 +1,18 @@ +include(../common_top.pri) + +INCLUDEPATH += $$DUISRCDIR/settingslanguage + +TARGET = ut_duisettingslanguageintegercontroller + +# unit test and unit +SOURCES += \ + ut_duisettingslanguageintegercontroller.cpp \ + $$DUISRCDIR/settingslanguage/duisettingslanguageintegercontroller.cpp + +# unit test and unit +HEADERS += \ + ut_duisettingslanguageintegercontroller.h \ + $$DUISRCDIR/settingslanguage/duisettingslanguageintegercontroller.h + +include(../common_bot.pri) + diff --git a/tests/ut_duisettingslanguageintegerfactory/.gitignore b/tests/ut_duisettingslanguageintegerfactory/.gitignore new file mode 100644 index 000000000..76dca47df --- /dev/null +++ b/tests/ut_duisettingslanguageintegerfactory/.gitignore @@ -0,0 +1 @@ +ut_duisettingslanguageintegerfactory diff --git a/tests/ut_duisettingslanguageintegerfactory/ut_duisettingslanguageintegerfactory.cpp b/tests/ut_duisettingslanguageintegerfactory/ut_duisettingslanguageintegerfactory.cpp new file mode 100644 index 000000000..5e8ad3b67 --- /dev/null +++ b/tests/ut_duisettingslanguageintegerfactory/ut_duisettingslanguageintegerfactory.cpp @@ -0,0 +1,134 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ut_duisettingslanguageintegerfactory.h" +#include "mockdatastore.h" + +class DuiSettingsLanguageInteger; + +void Ut_DuiSettingsLanguageIntegerFactory::initTestCase() +{ + // DuiApplication must exist + static int argc = 1; + static char *app_name[1] = { (char *)"./ut_duisettingslanguageintegerfactory" }; + app = new DuiApplication(argc, app_name); +} + +void Ut_DuiSettingsLanguageIntegerFactory::cleanupTestCase() +{ + // Destroy the DuiApplication + delete app; +} + +void Ut_DuiSettingsLanguageIntegerFactory::init() +{ +} + +void Ut_DuiSettingsLanguageIntegerFactory::cleanup() +{ +} + +void Ut_DuiSettingsLanguageIntegerFactory::testCreateWidget() +{ + // Create a settings integer + DuiSettingsLanguageInteger settingsInteger("TestKey", "Title"); + settingsInteger.setMinValue(0); + settingsInteger.setMaxValue(1000); + gDuiSettingsLanguageIntegerStub->stubSetReturnValue("minValue", true); + gDuiSettingsLanguageIntegerStub->stubSetReturnValue("maxValue", true); + gDuiSettingsLanguageIntegerStub->stubSetReturnValue("minValueValue", 0); + gDuiSettingsLanguageIntegerStub->stubSetReturnValue("maxValueValue", 1000); + DuiSettingsLanguageWidget dds; + MockDataStore dataStore; + DuiWidget *widget = DuiSettingsLanguageIntegerFactory::createWidget(settingsInteger, dds, &dataStore); + QVERIFY(widget != NULL); + + // Expecting the widget to have a QGraphicsLinearLayout + QGraphicsLinearLayout *layout = dynamic_cast(widget->layout()); + QVERIFY(layout != NULL); + + // Expecting the layout to contain a DuiLabel and a DuiSlider + QCOMPARE(layout->count(), 2); + + // The label's text should be the SettingsInteger's title + DuiLabel *label = dynamic_cast(layout->itemAt(0)); + QVERIFY(label != NULL); + QCOMPARE(label->text(), settingsInteger.title()); + + // The slider's value should be the specified key's value + DuiSlider *slider = dynamic_cast(layout->itemAt(1)); + QVERIFY(slider != NULL); + QCOMPARE(slider->value(), dataStore.value("TestKey").toInt()); + QCOMPARE(slider->minimum(), 0); + QCOMPARE(slider->maximum(), 1000); +} + +void Ut_DuiSettingsLanguageIntegerFactory::testCreateWidgetWithKeyValueSet() +{ + MockDataStore dataStore; + // Create the key value before creating the setting and the widget + dataStore.createValue(QString("AnotherTestKey"), 12); + + // Create a settings integer + DuiSettingsLanguageInteger settingsInteger("AnotherTestKey", "Title"); + settingsInteger.setMinValue(0); + settingsInteger.setMaxValue(1000); + gDuiSettingsLanguageIntegerStub->stubSetReturnValue("key", QString("AnotherTestKey")); + gDuiSettingsLanguageIntegerStub->stubSetReturnValue("title", QString("Title")); + DuiSettingsLanguageWidget dds; + DuiWidget *widget = DuiSettingsLanguageIntegerFactory::createWidget(settingsInteger, dds, &dataStore); + QVERIFY(widget != NULL); + + // Expecting the widget to have a QGraphicsLinearLayout + QGraphicsLinearLayout *layout = dynamic_cast(widget->layout()); + QVERIFY(layout != NULL); + + // Expecting the layout to contain a DuiLabel and a DuiSlider + QCOMPARE(layout->count(), 2); + + // The label's text should be the SettingsInteger's title + DuiLabel *label = dynamic_cast(layout->itemAt(0)); + QVERIFY(label != NULL); + QCOMPARE(label->text(), settingsInteger.title()); + + // The slider's value should be the specified key's value + DuiSlider *slider = dynamic_cast(layout->itemAt(1)); + QVERIFY(slider != NULL); + QCOMPARE(slider->value(), dataStore.value("AnotherTestKey").toInt()); + int minVal; + QVERIFY(settingsInteger.minValue(minVal)); + QCOMPARE(slider->minimum(), minVal); + int maxVal; + QVERIFY(settingsInteger.maxValue(maxVal)); + QCOMPARE(slider->maximum(), maxVal); +} + +QTEST_APPLESS_MAIN(Ut_DuiSettingsLanguageIntegerFactory) diff --git a/tests/ut_duisettingslanguageintegerfactory/ut_duisettingslanguageintegerfactory.h b/tests/ut_duisettingslanguageintegerfactory/ut_duisettingslanguageintegerfactory.h new file mode 100644 index 000000000..f15464aaf --- /dev/null +++ b/tests/ut_duisettingslanguageintegerfactory/ut_duisettingslanguageintegerfactory.h @@ -0,0 +1,45 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUISETTINGSLANGUAGEINTEGERFACTORY_H +#define UT_DUISETTINGSLANGUAGEINTEGERFACTORY_H + +#include +#include + +class DuiApplication; + +class Ut_DuiSettingsLanguageIntegerFactory : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + + void testCreateWidget(); + void testCreateWidgetWithKeyValueSet(); + +private: + DuiApplication *app; +}; + +#endif diff --git a/tests/ut_duisettingslanguageintegerfactory/ut_duisettingslanguageintegerfactory.pro b/tests/ut_duisettingslanguageintegerfactory/ut_duisettingslanguageintegerfactory.pro new file mode 100644 index 000000000..895363855 --- /dev/null +++ b/tests/ut_duisettingslanguageintegerfactory/ut_duisettingslanguageintegerfactory.pro @@ -0,0 +1,25 @@ +include(../common_top.pri) +TARGET = ut_duisettingslanguageintegerfactory +INCLUDEPATH += $$DUISRCDIR/settingslanguage + +TEST_SOURCES = \ + $$DUISRCDIR/settingslanguage/duisettingslanguageintegerfactory.cpp \ + +# unit test and unit +SOURCES += \ + ut_duisettingslanguageintegerfactory.cpp \ + $$DUISRCDIR/settingslanguage/duisettingslanguagenode.cpp \ + $$TEST_SOURCES \ + +# service classes +SOURCES += \ + $$STUBSDIR/stubbase.cpp \ + +# unit test and unit +HEADERS += \ + ut_duisettingslanguageintegerfactory.h \ + $$DUISRCDIR/settingslanguage/duisettingslanguageintegerfactory.h \ + $$DUISRCDIR/settingslanguage/duisettingslanguageintegercontroller.h \ + $$DUISRCDIR/settingslanguage/duisettingslanguagenode.h \ + +include(../common_bot.pri) diff --git a/tests/ut_duisettingslanguageoption/.gitignore b/tests/ut_duisettingslanguageoption/.gitignore new file mode 100644 index 000000000..0d3ea9989 --- /dev/null +++ b/tests/ut_duisettingslanguageoption/.gitignore @@ -0,0 +1 @@ +ut_duisettingslanguageoption diff --git a/tests/ut_duisettingslanguageoption/ut_duisettingslanguageoption.cpp b/tests/ut_duisettingslanguageoption/ut_duisettingslanguageoption.cpp new file mode 100644 index 000000000..1bfe83b66 --- /dev/null +++ b/tests/ut_duisettingslanguageoption/ut_duisettingslanguageoption.cpp @@ -0,0 +1,72 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include + +#include "ut_duisettingslanguageoption.h" + +bool gLocalizeStrings = false; +QString qtTrId(const char *id, int) +{ + if (gLocalizeStrings) { + return QString(id) + "Localized"; + } else { + return id; + } +} + +void Ut_DuiSettingsLanguageOption::init() +{ + m_subject = new DuiSettingsLanguageOption("foo", 1); +} + +void Ut_DuiSettingsLanguageOption::cleanup() +{ + delete m_subject; + m_subject = 0; +} + +void Ut_DuiSettingsLanguageOption::initTestCase() +{ + gLocalizeStrings = false; +} + +void Ut_DuiSettingsLanguageOption::cleanupTestCase() +{ +} + +void Ut_DuiSettingsLanguageOption::testOptionInitialization() +{ + QCOMPARE(m_subject->title(), QString("foo")); + QCOMPARE(m_subject->value(), 1); +} + +void Ut_DuiSettingsLanguageOption::testNodeType() +{ + QVERIFY((dynamic_cast(m_subject))); +} + +void Ut_DuiSettingsLanguageOption::testOptionTitleLocalized() +{ + gLocalizeStrings = true; + QCOMPARE(m_subject->title(), QString("fooLocalized")); +} + +QTEST_MAIN(Ut_DuiSettingsLanguageOption) diff --git a/tests/ut_duisettingslanguageoption/ut_duisettingslanguageoption.h b/tests/ut_duisettingslanguageoption/ut_duisettingslanguageoption.h new file mode 100644 index 000000000..00d50a0e7 --- /dev/null +++ b/tests/ut_duisettingslanguageoption/ut_duisettingslanguageoption.h @@ -0,0 +1,48 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUISETTINGSLANGUAGEOPTION_H +#define UT_DUISETTINGSLANGUAGEOPTION_H + +#include +#include + +#include + +Q_DECLARE_METATYPE(DuiSettingsLanguageOption *); + +class Ut_DuiSettingsLanguageOption : public QObject +{ + Q_OBJECT + +private slots: + void init(); + void cleanup(); + void initTestCase(); + void cleanupTestCase(); + + void testOptionInitialization(); + void testNodeType(); + void testOptionTitleLocalized(); + +private: + DuiSettingsLanguageOption *m_subject; +}; + +#endif diff --git a/tests/ut_duisettingslanguageoption/ut_duisettingslanguageoption.pro b/tests/ut_duisettingslanguageoption/ut_duisettingslanguageoption.pro new file mode 100644 index 000000000..3559f7ad2 --- /dev/null +++ b/tests/ut_duisettingslanguageoption/ut_duisettingslanguageoption.pro @@ -0,0 +1,23 @@ +include(../common_top.pri) + +INCLUDEPATH += $$DUISRCDIR/settingslanguage + +TARGET = ut_duisettingslanguageoption + +# unit test and unit +SOURCES += \ + ut_duisettingslanguageoption.cpp \ + $$DUISRCDIR/settingslanguage/duisettingslanguageoption.cpp \ + $$DUISRCDIR/settingslanguage/duisettingslanguagenode.cpp + +# service classes +SOURCES += \ + $$STUBSDIR/stubbase.cpp \ + +# unit test and unit +HEADERS += \ + ut_duisettingslanguageoption.h \ + $$DUISRCDIR/settingslanguage/duisettingslanguageoption.h \ + $$DUISRCDIR/settingslanguage/duisettingslanguagenode.h + +include(../common_bot.pri) diff --git a/tests/ut_duisettingslanguageparser/.gitignore b/tests/ut_duisettingslanguageparser/.gitignore new file mode 100644 index 000000000..a69d4e3cf --- /dev/null +++ b/tests/ut_duisettingslanguageparser/.gitignore @@ -0,0 +1,2 @@ +ut_duisettingslanguageparser + diff --git a/tests/ut_duisettingslanguageparser/ut_duisettingslanguageparser.cpp b/tests/ut_duisettingslanguageparser/ut_duisettingslanguageparser.cpp new file mode 100644 index 000000000..a1544cf59 --- /dev/null +++ b/tests/ut_duisettingslanguageparser/ut_duisettingslanguageparser.cpp @@ -0,0 +1,391 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duisettingslanguageparser.h" + +#include "duisettingslanguageparser.h" +#include "duisettingslanguagebinary.h" +#include +#include +#include +#include +#include +#include +#include +#include + +// A QIODevice that we can control nicely for testing purposes +class InaccessibleDevice : public QIODevice +{ +public: + InaccessibleDevice() : + dataSize(-1), + openable(true) { + } + + // The return value that readData() and writeData() returns + qint64 dataSize; + // A flag to control if a call to open() succeeds or not + bool openable; + + bool open(OpenMode mode) { + QIODevice::open(mode); + return openable; + } + +protected: + qint64 readData(char *data, qint64 maxSize) { + Q_UNUSED(data); + Q_UNUSED(maxSize); + return dataSize; + } + + qint64 writeData(const char *data, qint64 maxSize) { + Q_UNUSED(data); + Q_UNUSED(maxSize); + return dataSize; + } +}; + + +// Called before the first testfunction is executed +void Ut_DuiSettingsLanguageParser::initTestCase() +{ + m_subject = NULL; + m_testSettingsBinary = NULL; +} + +// Called after the last testfunction was executed +void Ut_DuiSettingsLanguageParser::cleanupTestCase() +{ +} + +// Called before each testfunction is executed +void Ut_DuiSettingsLanguageParser::init() +{ + m_subject = new DuiSettingsLanguageParser(); + gDuiSettingsLanguageSelectionStub->stubReset(); + gDuiSettingsLanguageOptionStub->stubReset(); + gDuiSettingsLanguageBooleanStub->stubReset(); + gDuiSettingsLanguageIntegerStub->stubReset(); +} + +// Called after every testfunction +void Ut_DuiSettingsLanguageParser::cleanup() +{ + delete m_subject; + m_subject = NULL; + delete m_testSettingsBinary; + m_testSettingsBinary = NULL; +} + +void Ut_DuiSettingsLanguageParser::executeParsingTest(const char *xml) +{ + QByteArray ba(xml); + QBuffer b(&ba); + m_subject->readFrom(b); + delete m_testSettingsBinary; + m_testSettingsBinary = m_subject->createSettingsBinary(); +} + +void Ut_DuiSettingsLanguageParser::EtestReadFromInaccessibleSource() +{ + InaccessibleDevice inaccessibleDevice; + + // A source where reading fails + m_subject->readFrom(inaccessibleDevice); + QCOMPARE(m_subject->createSettingsBinary(), (DuiSettingsLanguageBinary *)NULL); + + // A source that fails to open and reading fails + inaccessibleDevice.openable = false; + m_subject->readFrom(inaccessibleDevice); + QCOMPARE(m_subject->createSettingsBinary(), (DuiSettingsLanguageBinary *)NULL); + + // A source that fails to open but reading succeeds (which actually should never happen, but let's still test it) + inaccessibleDevice.dataSize = 10; + m_subject->readFrom(inaccessibleDevice); + QCOMPARE(m_subject->createSettingsBinary(), (DuiSettingsLanguageBinary *)NULL); +} + +void Ut_DuiSettingsLanguageParser::EtestCallCreateSettingsBinaryBeforeReadFrom() +{ + QCOMPARE(m_subject->createSettingsBinary(), (DuiSettingsLanguageBinary *)NULL); +} + +void Ut_DuiSettingsLanguageParser::EtestParseEmptyXML() +{ + executeParsingTest(""); + QCOMPARE(m_testSettingsBinary, (DuiSettingsLanguageBinary *)NULL); +} + +void Ut_DuiSettingsLanguageParser::EtestParseInvalidRootElement() +{ + executeParsingTest(""); + QCOMPARE(m_testSettingsBinary, (DuiSettingsLanguageBinary *)NULL); + + executeParsingTest(""); + QCOMPARE(m_testSettingsBinary, (DuiSettingsLanguageBinary *)NULL); +} + +void Ut_DuiSettingsLanguageParser::testParseSettingsNode() +{ + executeParsingTest(""); + QVERIFY(dynamic_cast(m_testSettingsBinary->children().at(0))); +} + +void Ut_DuiSettingsLanguageParser::testParseSelectionInSettings() +{ + executeParsingTest("\n" + " \n" + ""); + DuiSettingsLanguageSettings *si = dynamic_cast(m_testSettingsBinary->children().at(0)); + QCOMPARE(si->numChildren(), uint(1)); + QVERIFY((dynamic_cast(si->children().at(0)))); + QCOMPARE(gDuiSettingsLanguageSelectionStub->stubLastCallTo("constructor").parameter(0), QString("key")); +} + +void Ut_DuiSettingsLanguageParser::EtestParseSelectionWithoutKey() +{ + executeParsingTest("\n" + " \n" + ""); + QCOMPARE(m_testSettingsBinary, (DuiSettingsLanguageBinary *)NULL); +} + +void Ut_DuiSettingsLanguageParser::testParseSelectionOneValue() +{ + executeParsingTest("\n" + " \n" + " \n" + " \n" + ""); + QCOMPARE(gDuiSettingsLanguageSelectionStub->stubCallCount("addOption"), 1); + QCOMPARE(gDuiSettingsLanguageSelectionStub->stubLastCallTo("addOption").parameter(0), QString("Title")); + QCOMPARE(gDuiSettingsLanguageSelectionStub->stubLastCallTo("addOption").parameter(1), 5); +} + +void Ut_DuiSettingsLanguageParser::EtestParseSelectionWithInvalidValue() +{ + // value element doesn't have a required title attribute + executeParsingTest("\n" + " \n" + " \n" + " \n" + ""); + QCOMPARE(m_testSettingsBinary, (DuiSettingsLanguageBinary *)NULL); + + // value element has invalid content (should be an integer) + executeParsingTest("\n" + " \n" + " \n" + " \n" + ""); + QCOMPARE(m_testSettingsBinary, (DuiSettingsLanguageBinary *)NULL); +} + +void Ut_DuiSettingsLanguageParser::testParseSelectionManyValues() +{ + executeParsingTest("\n" + " \n" + " \n" + " \n" + " \n" + ""); + QCOMPARE(gDuiSettingsLanguageSelectionStub->stubCallCount("addOption"), 2); + QCOMPARE(gDuiSettingsLanguageSelectionStub->stubLastCallTo("addOption").parameter(0), QString("Title2")); + QCOMPARE(gDuiSettingsLanguageSelectionStub->stubLastCallTo("addOption").parameter(1), 6); +} + +void Ut_DuiSettingsLanguageParser::testParseTextInSettings() +{ + executeParsingTest("\n" + " \n" + ""); + DuiSettingsLanguageSettings *si = dynamic_cast(m_testSettingsBinary->children().at(0)); + QCOMPARE(si->numChildren(), uint(1)); + QCOMPARE(gDuiSettingsLanguageTextStub->stubLastCallTo("constructor").parameter(0), QString("aKey")); + QCOMPARE(gDuiSettingsLanguageTextStub->stubLastCallTo("constructor").parameter(1), QString("aTitle")); +} + +void Ut_DuiSettingsLanguageParser::EtestParseTextWithoutKey() +{ + executeParsingTest("\n" + " \n" + ""); + QCOMPARE(m_testSettingsBinary, (DuiSettingsLanguageBinary *)NULL); +} + +void Ut_DuiSettingsLanguageParser::EtestParseTextWithoutTitle() +{ + executeParsingTest("\n" + " \n" + ""); + QCOMPARE(m_testSettingsBinary, (DuiSettingsLanguageBinary *)NULL); +} + +void Ut_DuiSettingsLanguageParser::testParseBooleanInSettings() +{ + executeParsingTest("\n" + " \n" + ""); + DuiSettingsLanguageSettings *si = dynamic_cast(m_testSettingsBinary->children().at(0)); + QCOMPARE(si->numChildren(), uint(1)); + QCOMPARE(gDuiSettingsLanguageBooleanStub->stubLastCallTo("constructor").parameter(0), QString("key")); + QCOMPARE(gDuiSettingsLanguageBooleanStub->stubLastCallTo("constructor").parameter(1), QString("titleBoolean")); +} + +void Ut_DuiSettingsLanguageParser::EtestParseBooleanWithoutTitle() +{ + executeParsingTest("\n" + " \n" + ""); + QCOMPARE(m_testSettingsBinary, (DuiSettingsLanguageBinary *)NULL); +} + +void Ut_DuiSettingsLanguageParser::EtestParseBooleanWithoutKey() +{ + executeParsingTest("\n" + " \n" + ""); + QCOMPARE(m_testSettingsBinary, (DuiSettingsLanguageBinary *)NULL); +} + +void Ut_DuiSettingsLanguageParser::EtestParseBooleanEmpty() +{ + executeParsingTest("\n" + " \n" + ""); + QCOMPARE(m_testSettingsBinary, (DuiSettingsLanguageBinary *)NULL); +} + +void Ut_DuiSettingsLanguageParser::testParseIntegerInSettings() +{ + executeParsingTest("\n" + " \n" + ""); + DuiSettingsLanguageSettings *si = dynamic_cast(m_testSettingsBinary->children().at(0)); + QCOMPARE(si->numChildren(), uint(1)); + QCOMPARE(gDuiSettingsLanguageIntegerStub->stubLastCallTo("constructor").parameter(0), QString("aKey")); + QCOMPARE(gDuiSettingsLanguageIntegerStub->stubLastCallTo("constructor").parameter(1), QString("aTitle")); + QCOMPARE(gDuiSettingsLanguageIntegerStub->stubLastCallTo("setMinValue").parameter(0), -90); + QCOMPARE(gDuiSettingsLanguageIntegerStub->stubLastCallTo("setMaxValue").parameter(0), 90); +} + +void Ut_DuiSettingsLanguageParser::testParseIntegerWithoutMax() +{ + executeParsingTest("\n" + " \n" + ""); + QCOMPARE(gDuiSettingsLanguageIntegerStub->stubLastCallTo("setMinValue").parameter(0), 80); + QCOMPARE(gDuiSettingsLanguageIntegerStub->stubCallCount("setMaxValue"), 0); +} + +void Ut_DuiSettingsLanguageParser::testParseIntegerWithoutMin() +{ + executeParsingTest("\n" + " \n" + ""); + QCOMPARE(gDuiSettingsLanguageIntegerStub->stubCallCount("setMinValue"), 0); + QCOMPARE(gDuiSettingsLanguageIntegerStub->stubLastCallTo("setMaxValue").parameter(0), -180); +} + +void Ut_DuiSettingsLanguageParser::testParseIntegerWithoutMinOrMax() +{ + executeParsingTest("\n" + " \n" + ""); + DuiSettingsLanguageSettings *si = dynamic_cast(m_testSettingsBinary->children().at(0)); + + int val; + // no min value + QVERIFY(! dynamic_cast(si->children().at(0))->minValue(val)); + // no max value + QVERIFY(! dynamic_cast(si->children().at(0))->maxValue(val)); +} + +void Ut_DuiSettingsLanguageParser::EtestParseIntegerWithoutKey() +{ + executeParsingTest("\n" + " \n" + ""); + + QCOMPARE(m_testSettingsBinary, (DuiSettingsLanguageBinary *)NULL); +} + +void Ut_DuiSettingsLanguageParser::EtestParseIntegerWithoutTitle() +{ + executeParsingTest("\n" + " \n" + ""); + + QCOMPARE(m_testSettingsBinary, (DuiSettingsLanguageBinary *)NULL); +} + +void Ut_DuiSettingsLanguageParser::EtestParseIntegerWithInsaneMinMax() +{ + executeParsingTest("\n" + " \n" + ""); + DuiSettingsLanguageSettings *si = dynamic_cast(m_testSettingsBinary->children().at(0)); + + int val; + // no min value + QVERIFY(! dynamic_cast(si->children().at(0))->minValue(val)); + // no max value + QVERIFY(! dynamic_cast(si->children().at(0))->maxValue(val)); +} + +void Ut_DuiSettingsLanguageParser::testParseGroupInSettings() +{ + executeParsingTest("\n" + " \n" + " \n" + " \n" + ""); + DuiSettingsLanguageSettings *si = dynamic_cast(m_testSettingsBinary->children().at(0)); + QCOMPARE(si->numChildren(), uint(1)); + QVERIFY((dynamic_cast(si->children().at(0)))); + QVERIFY((dynamic_cast(si->children().at(0)->children().at(0)))); +} + +void Ut_DuiSettingsLanguageParser::testParseMultipleGroupsInSettings() +{ + executeParsingTest("\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + ""); + DuiSettingsLanguageSettings *si = dynamic_cast(m_testSettingsBinary->children().at(0)); + QCOMPARE(si->numChildren(), uint(3)); + QVERIFY((dynamic_cast(si->children().at(0)))); + + QVERIFY((dynamic_cast(si->children().at(1)))); + QCOMPARE(si->children().at(1)->numChildren(), uint(1)); + QVERIFY((dynamic_cast(si->children().at(1)->children().at(0)))); + + QVERIFY((dynamic_cast(si->children().at(2)))); + QCOMPARE(si->children().at(2)->numChildren(), uint(1)); + QVERIFY((dynamic_cast(si->children().at(2)->children().at(0)))); +} + +QTEST_MAIN(Ut_DuiSettingsLanguageParser) diff --git a/tests/ut_duisettingslanguageparser/ut_duisettingslanguageparser.h b/tests/ut_duisettingslanguageparser/ut_duisettingslanguageparser.h new file mode 100644 index 000000000..43ac81e27 --- /dev/null +++ b/tests/ut_duisettingslanguageparser/ut_duisettingslanguageparser.h @@ -0,0 +1,78 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUISETTINGSLANGUAGEPARSER_H +#define UT_DUISETTINGSLANGUAGEPARSER_H + +#include +#include + +class DuiSettingsLanguageParser; +class DuiSettingsLanguageBinary; + +class Ut_DuiSettingsLanguageParser : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + + // Test methods starting with E test error cases + void EtestReadFromInaccessibleSource(); + void EtestCallCreateSettingsBinaryBeforeReadFrom(); + void EtestParseEmptyXML(); + void EtestParseInvalidRootElement(); + void testParseSettingsNode(); + void testParseSelectionInSettings(); + void EtestParseSelectionWithoutKey(); + void testParseSelectionOneValue(); + void EtestParseSelectionWithInvalidValue(); + void testParseSelectionManyValues(); + + void testParseTextInSettings(); + void EtestParseTextWithoutKey(); + void EtestParseTextWithoutTitle(); + void testParseBooleanInSettings(); + void EtestParseBooleanWithoutTitle(); + void EtestParseBooleanWithoutKey(); + void EtestParseBooleanEmpty(); + + void testParseIntegerInSettings(); + void testParseIntegerWithoutMax() ; + void testParseIntegerWithoutMin(); + void testParseIntegerWithoutMinOrMax(); + void EtestParseIntegerWithoutKey(); + void EtestParseIntegerWithoutTitle(); + void EtestParseIntegerWithInsaneMinMax(); + + void testParseGroupInSettings(); + void testParseMultipleGroupsInSettings(); + +private: + void executeParsingTest(const char *xml); + + DuiSettingsLanguageParser *m_subject; + // A settings binary helper used for verifying the test results + DuiSettingsLanguageBinary *m_testSettingsBinary; +}; + +#endif diff --git a/tests/ut_duisettingslanguageparser/ut_duisettingslanguageparser.pro b/tests/ut_duisettingslanguageparser/ut_duisettingslanguageparser.pro new file mode 100644 index 000000000..babf68301 --- /dev/null +++ b/tests/ut_duisettingslanguageparser/ut_duisettingslanguageparser.pro @@ -0,0 +1,26 @@ +include(../common_top.pri) +QT += xml + +INCLUDEPATH += $$DUISRCDIR/settingslanguage + +TARGET = ut_duisettingslanguageparser + +# unit test and unit +SOURCES += \ + ut_duisettingslanguageparser.cpp \ + $$DUISRCDIR/settingslanguage/duisettingslanguageparser.cpp \ + $$DUISRCDIR/settingslanguage/duisettingslanguagebinary.cpp \ + $$DUISRCDIR/settingslanguage/duisettingslanguagenode.cpp + +# service classes +SOURCES += \ + $$STUBSDIR/stubbase.cpp \ + +# unit test and unit +HEADERS += \ + ut_duisettingslanguageparser.h \ + $$DUISRCDIR/settingslanguage/duisettingslanguageparser.h \ + $$DUISRCDIR/settingslanguage/duisettingslanguagebinary.h \ + $$DUISRCDIR/settingslanguage/duisettingslanguagenode.h + +include(../common_bot.pri) diff --git a/tests/ut_duisettingslanguageselection/.gitignore b/tests/ut_duisettingslanguageselection/.gitignore new file mode 100644 index 000000000..e30abaae4 --- /dev/null +++ b/tests/ut_duisettingslanguageselection/.gitignore @@ -0,0 +1 @@ +ut_duisettingslanguageselection diff --git a/tests/ut_duisettingslanguageselection/ut_duisettingslanguageselection.cpp b/tests/ut_duisettingslanguageselection/ut_duisettingslanguageselection.cpp new file mode 100644 index 000000000..72972f9a4 --- /dev/null +++ b/tests/ut_duisettingslanguageselection/ut_duisettingslanguageselection.cpp @@ -0,0 +1,79 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include + +#include +#include +#include "ut_duisettingslanguageselection.h" + +void Ut_DuiSettingsLanguageSelection::init() +{ + m_subject = new DuiSettingsLanguageSelection("key"); +} + +void Ut_DuiSettingsLanguageSelection::cleanup() +{ + delete m_subject; + m_subject = 0; +} + +void Ut_DuiSettingsLanguageSelection::initTestCase() +{ +} + +void Ut_DuiSettingsLanguageSelection::cleanupTestCase() +{ +} + +void Ut_DuiSettingsLanguageSelection::testEnumKey() +{ + QCOMPARE(m_subject->key(), QString("key")); +} + +void Ut_DuiSettingsLanguageSelection::testAddEnumValuesToEnum() +{ + QCOMPARE(m_subject->numOptions(), uint(0)); + DuiSettingsLanguageOption *value = m_subject->addOption("title1", 0); + QVERIFY(value != NULL); + QCOMPARE(m_subject->numOptions(), uint(1)); + + DuiSettingsLanguageOption *eValue = new DuiSettingsLanguageOption("title2", 1); + DuiSettingsLanguageOption *eValue2 = m_subject->addOption(eValue); + QCOMPARE(eValue, eValue2); + QCOMPARE(m_subject->numOptions(), uint(2)); +} + +void Ut_DuiSettingsLanguageSelection::testGetValuesFromEnum() +{ + DuiSettingsLanguageOption *value1 = m_subject->addOption("title1", 1); + DuiSettingsLanguageOption *value2 = m_subject->addOption("title2", 2); + QList values = m_subject->options(); + QCOMPARE(values.count(), 2); + QCOMPARE(values.at(0), value1); + QCOMPARE(values.at(1), value2); +} + +void Ut_DuiSettingsLanguageSelection::testNodeType() +{ + QVERIFY((dynamic_cast(m_subject))); +} + +QTEST_MAIN(Ut_DuiSettingsLanguageSelection) diff --git a/tests/ut_duisettingslanguageselection/ut_duisettingslanguageselection.h b/tests/ut_duisettingslanguageselection/ut_duisettingslanguageselection.h new file mode 100644 index 000000000..6081d5147 --- /dev/null +++ b/tests/ut_duisettingslanguageselection/ut_duisettingslanguageselection.h @@ -0,0 +1,49 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUISETTINGSLANGUAGESELECTION_H +#define UT_DUISETTINGSLANGUAGESELECTION_H + +#include +#include + +#include + +Q_DECLARE_METATYPE(DuiSettingsLanguageSelection *); + +class Ut_DuiSettingsLanguageSelection : public QObject +{ + Q_OBJECT + +private slots: + void init(); + void cleanup(); + void initTestCase(); + void cleanupTestCase(); + + void testEnumKey(); + void testAddEnumValuesToEnum(); + void testGetValuesFromEnum(); + void testNodeType(); + +private: + DuiSettingsLanguageSelection *m_subject; +}; + +#endif diff --git a/tests/ut_duisettingslanguageselection/ut_duisettingslanguageselection.pro b/tests/ut_duisettingslanguageselection/ut_duisettingslanguageselection.pro new file mode 100644 index 000000000..5d9eda6fc --- /dev/null +++ b/tests/ut_duisettingslanguageselection/ut_duisettingslanguageselection.pro @@ -0,0 +1,24 @@ +include(../common_top.pri) + +INCLUDEPATH += $$DUISRCDIR/settingslanguage + +TARGET = ut_duisettingslanguageselection + +# unit test and unit +SOURCES += \ + ut_duisettingslanguageselection.cpp \ + $$DUISRCDIR/settingslanguage/duisettingslanguageselection.cpp \ + $$DUISRCDIR/settingslanguage/duisettingslanguagenode.cpp + +# service classes +SOURCES += \ + $$STUBSDIR/stubbase.cpp \ + +# unit test and unit +HEADERS += \ + ut_duisettingslanguageselection.h \ + $$DUISRCDIR/settingslanguage/duisettingslanguageselection.h \ + $$DUISRCDIR/settingslanguage/duisettingslanguagenode.h \ + $$DUISRCDIR/settingslanguage/duisettingslanguageoption.h + +include(../common_bot.pri) diff --git a/tests/ut_duisettingslanguageselectioncontroller/.gitignore b/tests/ut_duisettingslanguageselectioncontroller/.gitignore new file mode 100644 index 000000000..880a14ccf --- /dev/null +++ b/tests/ut_duisettingslanguageselectioncontroller/.gitignore @@ -0,0 +1 @@ +ut_duisettingslanguageselectioncontroller diff --git a/tests/ut_duisettingslanguageselectioncontroller/ut_duisettingslanguageselectioncontroller.cpp b/tests/ut_duisettingslanguageselectioncontroller/ut_duisettingslanguageselectioncontroller.cpp new file mode 100644 index 000000000..4eb5b02b6 --- /dev/null +++ b/tests/ut_duisettingslanguageselectioncontroller/ut_duisettingslanguageselectioncontroller.cpp @@ -0,0 +1,59 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duisettingslanguageselectioncontroller.h" +#include + +#include +#include +#include +#include "../stubs/mockdatastore.h" + +void Ut_DuiSettingsLanguageSelectionController::init() +{ + m_subject = new DuiSettingsLanguageSelectionController(); +} + +void Ut_DuiSettingsLanguageSelectionController::cleanup() +{ + delete m_subject; + m_subject = 0; +} + +void Ut_DuiSettingsLanguageSelectionController::initTestCase() +{ + +} + +void Ut_DuiSettingsLanguageSelectionController::cleanupTestCase() +{ +} + +void Ut_DuiSettingsLanguageSelectionController::testButtonClicked() +{ + MockDataStore dataStore; + DuiButton button; + button.setProperty("key", QString("buttonKey")); + button.setProperty("value", 1); + button.setProperty("dataStore", qVariantFromValue(static_cast(&dataStore))); + m_subject->buttonClicked(&button); + QCOMPARE(dataStore.value("buttonKey").toInt(), 1); +} + +QTEST_APPLESS_MAIN(Ut_DuiSettingsLanguageSelectionController) diff --git a/tests/ut_duisettingslanguageselectioncontroller/ut_duisettingslanguageselectioncontroller.h b/tests/ut_duisettingslanguageselectioncontroller/ut_duisettingslanguageselectioncontroller.h new file mode 100644 index 000000000..881e0cced --- /dev/null +++ b/tests/ut_duisettingslanguageselectioncontroller/ut_duisettingslanguageselectioncontroller.h @@ -0,0 +1,44 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUISETTINGSLANGUAGESELECTIONCONTROLLER_H +#define UT_DUISETTINGSLANGUAGESELECTIONCONTROLLER_H + +#include +#include + +class DuiSettingsLanguageSelectionController; + +class Ut_DuiSettingsLanguageSelectionController : public QObject +{ + Q_OBJECT + +private slots: + void init(); + void cleanup(); + void initTestCase(); + void cleanupTestCase(); + + void testButtonClicked(); + +private: + DuiSettingsLanguageSelectionController *m_subject; +}; + +#endif diff --git a/tests/ut_duisettingslanguageselectioncontroller/ut_duisettingslanguageselectioncontroller.pro b/tests/ut_duisettingslanguageselectioncontroller/ut_duisettingslanguageselectioncontroller.pro new file mode 100644 index 000000000..b1e5dd596 --- /dev/null +++ b/tests/ut_duisettingslanguageselectioncontroller/ut_duisettingslanguageselectioncontroller.pro @@ -0,0 +1,18 @@ +include(../common_top.pri) + +INCLUDEPATH += $$DUISRCDIR/settingslanguage + +TARGET = ut_duisettingslanguageselectioncontroller + +# unit test and unit +SOURCES += \ + ut_duisettingslanguageselectioncontroller.cpp \ + $$DUISRCDIR/settingslanguage/duisettingslanguageselectioncontroller.cpp + +# unit test and unit +HEADERS += \ + ut_duisettingslanguageselectioncontroller.h \ + $$DUISRCDIR/settingslanguage/duisettingslanguageselectioncontroller.h + +include(../common_bot.pri) + diff --git a/tests/ut_duisettingslanguageselectionfactory/.gitignore b/tests/ut_duisettingslanguageselectionfactory/.gitignore new file mode 100644 index 000000000..d0aa035ba --- /dev/null +++ b/tests/ut_duisettingslanguageselectionfactory/.gitignore @@ -0,0 +1,2 @@ +ut_duisettingslanguageselectionfactory + diff --git a/tests/ut_duisettingslanguageselectionfactory/ut_duisettingslanguageselectionfactory.cpp b/tests/ut_duisettingslanguageselectionfactory/ut_duisettingslanguageselectionfactory.cpp new file mode 100644 index 000000000..99ad39789 --- /dev/null +++ b/tests/ut_duisettingslanguageselectionfactory/ut_duisettingslanguageselectionfactory.cpp @@ -0,0 +1,108 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duisettingslanguageselectionfactory.h" + +#include "duisettingslanguagewidget.h" +#include "duisettingslanguagebinary.h" +#include "duisettingslanguageselectionfactory.h" +#include "duisettingslanguageselection_stub.h" +#include "duisettingslanguageselectioncontroller_stub.h" +#include "duisettingslanguageoption_stub.h" + +#include +#include +#include +#include + +QList Ut_DuiSettingsLanguageSelectionFactory::buttonGroupButtonTitles; +QList Ut_DuiSettingsLanguageSelectionFactory::buttonGroupButtonKeys; +QList Ut_DuiSettingsLanguageSelectionFactory::buttonGroupButtonValues; + +// DuiButtonGroup stubs +void DuiButtonGroup::addButton(DuiButton *button) +{ + Ut_DuiSettingsLanguageSelectionFactory::buttonGroupButtonTitles.append(button->text()); + Ut_DuiSettingsLanguageSelectionFactory::buttonGroupButtonKeys.append(button->property("key").toString()); + Ut_DuiSettingsLanguageSelectionFactory::buttonGroupButtonValues.append(button->property("value").toInt()); +} + +// Tests +void Ut_DuiSettingsLanguageSelectionFactory::initTestCase() +{ + static int argc = 1; + static char *app_name[1] = { (char *)"./ut_duisettingslanguageselectionfactory" }; + app = new DuiApplication(argc, app_name); +} + +void Ut_DuiSettingsLanguageSelectionFactory::cleanupTestCase() +{ + delete app; +} + +void Ut_DuiSettingsLanguageSelectionFactory::init() +{ + // Empty the button lists + buttonGroupButtonTitles.clear(); + buttonGroupButtonKeys.clear(); + buttonGroupButtonValues.clear(); + gDuiSettingsLanguageSelectionStub->stubReset(); + gDuiSettingsLanguageOptionStub->stubReset(); +} + +void Ut_DuiSettingsLanguageSelectionFactory::cleanup() +{ +} + +void Ut_DuiSettingsLanguageSelectionFactory::testBuildWidget() +{ + // Create a settings enum of two values + DuiSettingsLanguageSelection se("TestKey"); + se.addOption("TestValue0", 0); + se.addOption("TestValue1", 1); + DuiSettingsLanguageOption *option0 = new DuiSettingsLanguageOption("StubTitle", 5); + DuiSettingsLanguageOption *option1 = new DuiSettingsLanguageOption("StubTitle", 5); + QList options; + options.append(option0); + options.append(option1); + gDuiSettingsLanguageSelectionStub->stubSetReturnValue("key", QString("TestKey")); + gDuiSettingsLanguageSelectionStub->stubSetReturnValue("options", options); + gDuiSettingsLanguageOptionStub->stubSetReturnValue("title", QString("StubTitle")); + gDuiSettingsLanguageOptionStub->stubSetReturnValue("value", 5); + DuiSettingsLanguageWidget dds; + DuiWidget *widget = DuiSettingsLanguageSelectionFactory::createWidget(se, dds); + QVERIFY(widget != NULL); + + // Two buttons should be created + QCOMPARE(gDuiSettingsLanguageOptionStub->stubCallCount("title"), 2); + QCOMPARE(gDuiSettingsLanguageOptionStub->stubCallCount("value"), 2 * 2); + QCOMPARE(buttonGroupButtonTitles.count(), 2); + QCOMPARE(buttonGroupButtonTitles.at(0), QString("StubTitle")); + QCOMPARE(buttonGroupButtonTitles.at(1), QString("StubTitle")); + QCOMPARE(buttonGroupButtonKeys.count(), 2); + QCOMPARE(buttonGroupButtonKeys.at(0), QString("TestKey")); + QCOMPARE(buttonGroupButtonKeys.at(1), QString("TestKey")); + QCOMPARE(buttonGroupButtonValues.count(), 2); + QCOMPARE(buttonGroupButtonValues.at(0), 5); + QCOMPARE(buttonGroupButtonValues.at(1), 5); + delete option0; + delete option1; +} + +QTEST_APPLESS_MAIN(Ut_DuiSettingsLanguageSelectionFactory) diff --git a/tests/ut_duisettingslanguageselectionfactory/ut_duisettingslanguageselectionfactory.h b/tests/ut_duisettingslanguageselectionfactory/ut_duisettingslanguageselectionfactory.h new file mode 100644 index 000000000..74fa50476 --- /dev/null +++ b/tests/ut_duisettingslanguageselectionfactory/ut_duisettingslanguageselectionfactory.h @@ -0,0 +1,52 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUISETTINGSLANGUAGESELECTIONFACTORY_H +#define UT_DUISETTINGSLANGUAGESELECTIONFACTORY_H + +#include + +class DuiApplication; + +class Ut_DuiSettingsLanguageSelectionFactory : public QObject +{ + Q_OBJECT + +public: + static QList buttonGroupButtonTitles; + static QList buttonGroupButtonKeys; + static QList buttonGroupButtonValues; + +private slots: + // Executed once before every test case + void init(); + // Executed once after every test case + void cleanup(); + // Executed once before first test case + void initTestCase(); + // Executed once after last test case + void cleanupTestCase(); + + void testBuildWidget(); + +private: + DuiApplication *app; +}; + +#endif // UT_DUISETTINGSLANGUAGESELECTIONFACTORY_H diff --git a/tests/ut_duisettingslanguageselectionfactory/ut_duisettingslanguageselectionfactory.pro b/tests/ut_duisettingslanguageselectionfactory/ut_duisettingslanguageselectionfactory.pro new file mode 100644 index 000000000..4a47a5007 --- /dev/null +++ b/tests/ut_duisettingslanguageselectionfactory/ut_duisettingslanguageselectionfactory.pro @@ -0,0 +1,22 @@ +include(../common_top.pri) +TARGET = ut_duisettingslanguageselectionfactory +INCLUDEPATH += $$DUISRCDIR/settingslanguage + +# unit test and unit classes +SOURCES += \ + ut_duisettingslanguageselectionfactory.cpp \ + $$DUISRCDIR/settingslanguage/duisettingslanguageselectionfactory.cpp \ + $$DUISRCDIR/settingslanguage/duisettingslanguagenode.cpp + +# service classes +SOURCES += \ + $$STUBSDIR/stubbase.cpp \ + +# unit test and unit classes +HEADERS += \ + ut_duisettingslanguageselectionfactory.h \ + $$DUISRCDIR/settingslanguage/duisettingslanguageselectionfactory.h \ + $$DUISRCDIR/settingslanguage/duisettingslanguageselectioncontroller.h \ + $$DUISRCDIR/settingslanguage/duisettingslanguagenode.h + +include(../common_bot.pri) diff --git a/tests/ut_duisettingslanguagesettings/.gitignore b/tests/ut_duisettingslanguagesettings/.gitignore new file mode 100644 index 000000000..3123d8e0e --- /dev/null +++ b/tests/ut_duisettingslanguagesettings/.gitignore @@ -0,0 +1 @@ +ut_duisettingslanguagesettings diff --git a/tests/ut_duisettingslanguagesettings/ut_duisettingslanguagesettings.cpp b/tests/ut_duisettingslanguagesettings/ut_duisettingslanguagesettings.cpp new file mode 100644 index 000000000..538793a26 --- /dev/null +++ b/tests/ut_duisettingslanguagesettings/ut_duisettingslanguagesettings.cpp @@ -0,0 +1,61 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include + +#include +#include +#include + +#include "ut_duisettingslanguagesettings.h" + +void Ut_DuiSettingsLanguageSettings::init() +{ + m_subject = new DuiSettingsLanguageSettings; +} + +void Ut_DuiSettingsLanguageSettings::cleanup() +{ + delete m_subject; + m_subject = 0; +} + +void Ut_DuiSettingsLanguageSettings::initTestCase() +{ +} + +void Ut_DuiSettingsLanguageSettings::cleanupTestCase() +{ +} + +void Ut_DuiSettingsLanguageSettings::testAddChildToItem() +{ + DuiSettingsLanguageSelection *aEnum = new DuiSettingsLanguageSelection("foo"); + QCOMPARE(m_subject->numChildren(), uint(0)); + m_subject->addChild(aEnum); + QCOMPARE(m_subject->numChildren(), uint(1)); +} + +void Ut_DuiSettingsLanguageSettings::testNodeType() +{ + QVERIFY((dynamic_cast(m_subject))); +} + +QTEST_MAIN(Ut_DuiSettingsLanguageSettings) diff --git a/tests/ut_duisettingslanguagesettings/ut_duisettingslanguagesettings.h b/tests/ut_duisettingslanguagesettings/ut_duisettingslanguagesettings.h new file mode 100644 index 000000000..edf13abba --- /dev/null +++ b/tests/ut_duisettingslanguagesettings/ut_duisettingslanguagesettings.h @@ -0,0 +1,46 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUISETTINGSLANGUAGESETTINGS_H +#define UT_DUISETTINGSLANGUAGESETTINGS_H + +#include +#include +#include + +Q_DECLARE_METATYPE(DuiSettingsLanguageSettings *); + +class Ut_DuiSettingsLanguageSettings : public QObject +{ + Q_OBJECT + +private slots: + void init(); + void cleanup(); + void initTestCase(); + void cleanupTestCase(); + + void testAddChildToItem(); + void testNodeType(); + +private: + DuiSettingsLanguageSettings *m_subject; +}; + +#endif diff --git a/tests/ut_duisettingslanguagesettings/ut_duisettingslanguagesettings.pro b/tests/ut_duisettingslanguagesettings/ut_duisettingslanguagesettings.pro new file mode 100644 index 000000000..6c205d8ff --- /dev/null +++ b/tests/ut_duisettingslanguagesettings/ut_duisettingslanguagesettings.pro @@ -0,0 +1,21 @@ +include(../common_top.pri) +TARGET = ut_duisettingslanguagesettings +INCLUDEPATH += $$DUISRCDIR/settingslanguage + +# unit test and unit classes +SOURCES += \ + ut_duisettingslanguagesettings.cpp \ + $$DUISRCDIR/settingslanguage/duisettingslanguagesettings.cpp \ + $$DUISRCDIR/settingslanguage/duisettingslanguagenode.cpp + +# service classes +SOURCES += \ + $$STUBSDIR/stubbase.cpp \ + +# unit test and unit classes +HEADERS += \ + ut_duisettingslanguagesettings.h \ + $$DUISRCDIR/settingslanguage/duisettingslanguagesettings.h \ + $$DUISRCDIR/settingslanguage/duisettingslanguagenode.h + +include(../common_bot.pri) diff --git a/tests/ut_duisettingslanguagesettingsfactory/.gitignore b/tests/ut_duisettingslanguagesettingsfactory/.gitignore new file mode 100644 index 000000000..a37d5b36a --- /dev/null +++ b/tests/ut_duisettingslanguagesettingsfactory/.gitignore @@ -0,0 +1,2 @@ +ut_duisettingslanguagesettingsfactory + diff --git a/tests/ut_duisettingslanguagesettingsfactory/ut_duisettingslanguagesettingsfactory.cpp b/tests/ut_duisettingslanguagesettingsfactory/ut_duisettingslanguagesettingsfactory.cpp new file mode 100644 index 000000000..4c24bacaf --- /dev/null +++ b/tests/ut_duisettingslanguagesettingsfactory/ut_duisettingslanguagesettingsfactory.cpp @@ -0,0 +1,176 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duisettingslanguagesettingsfactory.h" +#include "duisettingslanguagesettingsfactory.h" +#include "duisettingslanguagesettings_stub.h" +#include "duisettingslanguageselection_stub.h" +#include "duisettingslanguageselectionfactory_stub.h" +#include "duisettingslanguagetextfactory_stub.h" +#include "duisettingslanguageboolean_stub.h" +#include "duisettingslanguagebooleanfactory_stub.h" +#include "duisettingslanguageinteger_stub.h" +#include "duisettingslanguageintegerfactory_stub.h" +#include "duisettingslanguagenode.h" +#include "duisettingslanguagetext_stub.h" +#include "duisettingslanguagegroup_stub.h" +#include "duisettingslanguagewidget_stub.h" + +#include +#include +#include +#include +#include +#include +#include +#include "../stubs/mockdatastore.h" + +int Ut_DuiSettingsLanguageSettingsFactory::indicatorWidgets; +int Ut_DuiSettingsLanguageSettingsFactory::containerIndicators; +QList Ut_DuiSettingsLanguageSettingsFactory::containers; + +QList Ut_DuiSettingsLanguageSettingsFactory::settingsSelections; +QList Ut_DuiSettingsLanguageSettingsFactory::settingsTexts; +QList Ut_DuiSettingsLanguageSettingsFactory::settingsBooleans; +QList Ut_DuiSettingsLanguageSettingsFactory::settingsIntegers; +QList Ut_DuiSettingsLanguageSettingsFactory::settingsSelectionsDataStores; +QList Ut_DuiSettingsLanguageSettingsFactory::settingsTextsDataStores; +QList Ut_DuiSettingsLanguageSettingsFactory::settingsBooleansDataStores; +QList Ut_DuiSettingsLanguageSettingsFactory::settingsIntegersDataStores; +DuiWidgetController *Ut_DuiSettingsLanguageSettingsFactory::duiSettingsLanguageSelectionFactoryWidget = NULL; +QString Ut_DuiSettingsLanguageSettingsFactory::duiActionProvider_getDefaultActionUri; +DuiAction *Ut_DuiSettingsLanguageSettingsFactory::duiActionProvider_action = NULL; + +// QCoreApplication stubs to avoid crashing in processEvents() +QStringList QCoreApplication::arguments() +{ + return QStringList(); +} + +// DuiImageWidget stubs +void DuiImageWidget::setImage(const QString &, const QSize &) +{ + Ut_DuiSettingsLanguageSettingsFactory::indicatorWidgets++; +} + +// DuiContainer stubs +void DuiContainer::setIconID(const QString &iconId) +{ + Q_UNUSED(iconId); + Ut_DuiSettingsLanguageSettingsFactory::containerIndicators++; +} + +void DuiContainer::setCentralWidget(DuiWidget *centralWidget, bool destroy) +{ + Q_UNUSED(centralWidget); + Q_UNUSED(destroy); + Ut_DuiSettingsLanguageSettingsFactory::containers.append(title()); +} + +// DuiActionProvider stubs +DuiAction *DuiActionProvider::getDefaultAction(const QUrl &uri) +{ + Ut_DuiSettingsLanguageSettingsFactory::duiActionProvider_getDefaultActionUri = uri.toString(); + Ut_DuiSettingsLanguageSettingsFactory::duiActionProvider_action = new DuiAction(NULL); + return Ut_DuiSettingsLanguageSettingsFactory::duiActionProvider_action; +} + +// Tests +void Ut_DuiSettingsLanguageSettingsFactory::initTestCase() +{ + // Create a DuiApplication + static int argc = 1; + static char *app_name[1] = { (char *) "./ut_duisettingslanguagesettingsfactory" }; + app = new DuiApplication(argc, app_name); +} + +void Ut_DuiSettingsLanguageSettingsFactory::cleanupTestCase() +{ + // Destroy DuiApplication + delete app; +} + +void Ut_DuiSettingsLanguageSettingsFactory::init() +{ + indicatorWidgets = 0; + containerIndicators = 0; + containers.clear(); + settingsSelections.clear(); + settingsTexts.clear(); + settingsBooleans.clear(); + settingsIntegers.clear(); + settingsSelectionsDataStores.clear(); + settingsTextsDataStores.clear(); + settingsBooleansDataStores.clear(); + settingsIntegersDataStores.clear(); + duiSettingsLanguageSelectionFactoryWidget = NULL; + duiActionProvider_getDefaultActionUri.clear(); + duiActionProvider_action = NULL; + dataStore = new MockDataStore; + gDuiSettingsLanguageSettingsStub->stubReset(); +} + +void Ut_DuiSettingsLanguageSettingsFactory::cleanup() +{ + delete dataStore; + dataStore = NULL; +} + +void Ut_DuiSettingsLanguageSettingsFactory::testChildrenCreation() +{ + // Create a settings item with a selection of two values, text and group with boolean and integer + DuiSettingsLanguageSelection *aSelection = new DuiSettingsLanguageSelection("EnumTestKey"); + aSelection->addOption("TestValue0", 0); + aSelection->addOption("TestValue1", 1); + DuiSettingsLanguageText *text = new DuiSettingsLanguageText("TextTestKey", "title"); + + // Group that boolean and integer are added. If then there are those items, there must be a group.. + DuiSettingsLanguageGroup *group = new DuiSettingsLanguageGroup(); + DuiSettingsLanguageBoolean *booleanNode = new DuiSettingsLanguageBoolean("BoolTestKey", "titleBool"); + DuiSettingsLanguageInteger *intNode = new DuiSettingsLanguageInteger("IntTestKey", "titleInt"); + + group->addChild(intNode); + group->addChild(booleanNode); + + DuiSettingsLanguageSettings item; + item.addChild(group); + item.addChild(aSelection); + item.addChild(text); + + // Set up the stub to return the same values + QList children; + children.append(group); + children.append(aSelection); + children.append(text); + gDuiSettingsLanguageSettingsStub->stubSetReturnValue("children", children); + + DuiSettingsLanguageWidget dds; + DuiWidget *widget = DuiSettingsLanguageSettingsFactory::createWidget(item, dds, dataStore); + QVERIFY(widget != NULL); + QCOMPARE(gDuiSettingsLanguageSelectionFactoryStub->stubCallCount("createWidget"), 1); + QCOMPARE(gDuiSettingsLanguageSelectionFactoryStub->stubLastCallTo("createWidget").parameter(0), aSelection); + QCOMPARE(gDuiSettingsLanguageTextFactoryStub->stubCallCount("createWidget"), 1); + QCOMPARE(gDuiSettingsLanguageTextFactoryStub->stubLastCallTo("createWidget").parameter(0), text); + QCOMPARE(gDuiSettingsLanguageBooleanFactoryStub->stubCallCount("createWidget"), 1); + QCOMPARE(gDuiSettingsLanguageBooleanFactoryStub->stubLastCallTo("createWidget").parameter(0), booleanNode); + QCOMPARE(gDuiSettingsLanguageIntegerFactoryStub->stubCallCount("createWidget"), 1); + QCOMPARE(gDuiSettingsLanguageIntegerFactoryStub->stubLastCallTo("createWidget").parameter(0), intNode); +} + +QTEST_APPLESS_MAIN(Ut_DuiSettingsLanguageSettingsFactory) diff --git a/tests/ut_duisettingslanguagesettingsfactory/ut_duisettingslanguagesettingsfactory.h b/tests/ut_duisettingslanguagesettingsfactory/ut_duisettingslanguagesettingsfactory.h new file mode 100644 index 000000000..057211616 --- /dev/null +++ b/tests/ut_duisettingslanguagesettingsfactory/ut_duisettingslanguagesettingsfactory.h @@ -0,0 +1,71 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUISETTINGSLANGUAGESETTINGSFACTORY_H +#define UT_DUISETTINGSLANGUAGESETTINGSFACTORY_H + +#include + +class DuiApplication; +class DuiSettingsLanguageSelection; +class DuiSettingsLanguageText; +class DuiSettingsLanguageBoolean; +class DuiSettingsLanguageInteger; +class DuiWidgetController; +class DuiAction; +class DuiDataStore; + +class Ut_DuiSettingsLanguageSettingsFactory : public QObject +{ + Q_OBJECT + +public: + static int indicatorWidgets; + static int containerIndicators; + static QList containers; + static QList settingsSelections; + static QList settingsTexts; + static QList settingsBooleans; + static QList settingsIntegers; + static QList settingsSelectionsDataStores; + static QList settingsTextsDataStores; + static QList settingsBooleansDataStores; + static QList settingsIntegersDataStores; + static DuiWidgetController *duiSettingsLanguageSelectionFactoryWidget; + static QString duiActionProvider_getDefaultActionUri; + static DuiAction *duiActionProvider_action; + +private: + DuiApplication *app; + DuiDataStore *dataStore; + +private slots: + // Executed once before every test case + void init(); + // Executed once after every test case + void cleanup(); + // Executed once before first test case + void initTestCase(); + // Executed once after last test case + void cleanupTestCase(); + + void testChildrenCreation(); +}; + +#endif diff --git a/tests/ut_duisettingslanguagesettingsfactory/ut_duisettingslanguagesettingsfactory.pro b/tests/ut_duisettingslanguagesettingsfactory/ut_duisettingslanguagesettingsfactory.pro new file mode 100644 index 000000000..e3c916832 --- /dev/null +++ b/tests/ut_duisettingslanguagesettingsfactory/ut_duisettingslanguagesettingsfactory.pro @@ -0,0 +1,21 @@ +include(../common_top.pri) +TARGET = ut_duisettingslanguagesettingsfactory +INCLUDEPATH += $$DUISRCDIR/settingslanguage $$DUISRCDIR/style + +# unit test and unit classes +SOURCES += \ + ut_duisettingslanguagesettingsfactory.cpp \ + $$DUISRCDIR/settingslanguage/duisettingslanguagesettingsfactory.cpp \ + $$DUISRCDIR/settingslanguage/duisettingslanguagenode.cpp + +# service classes +SOURCES += \ + $$STUBSDIR/stubbase.cpp \ + +# unit test and unit classes +HEADERS += \ + ut_duisettingslanguagesettingsfactory.h \ + $$DUISRCDIR/settingslanguage/duisettingslanguagesettingsfactory.h \ + $$DUISRCDIR/settingslanguage/duisettingslanguagenode.h + +include(../common_bot.pri) diff --git a/tests/ut_duisettingslanguagetext/.gitignore b/tests/ut_duisettingslanguagetext/.gitignore new file mode 100644 index 000000000..2b96ac30d --- /dev/null +++ b/tests/ut_duisettingslanguagetext/.gitignore @@ -0,0 +1 @@ +ut_duisettingslanguagetext diff --git a/tests/ut_duisettingslanguagetext/ut_duisettingslanguagetext.cpp b/tests/ut_duisettingslanguagetext/ut_duisettingslanguagetext.cpp new file mode 100644 index 000000000..636936e39 --- /dev/null +++ b/tests/ut_duisettingslanguagetext/ut_duisettingslanguagetext.cpp @@ -0,0 +1,74 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include + +#include + +#include "ut_duisettingslanguagetext.h" + +bool gLocalizeStrings = false; +QString qtTrId(const char *id, int) +{ + if (gLocalizeStrings) { + return QString(id) + "Localized"; + } else { + return id; + } +} + +void Ut_DuiSettingsLanguageText::init() +{ + m_subject = new DuiSettingsLanguageText("key", "title"); +} + +void Ut_DuiSettingsLanguageText::cleanup() +{ + delete m_subject; + m_subject = 0; +} + +void Ut_DuiSettingsLanguageText::initTestCase() +{ + gLocalizeStrings = false; +} + +void Ut_DuiSettingsLanguageText::cleanupTestCase() +{ +} + +void Ut_DuiSettingsLanguageText::testTextKeyTitle() +{ + QCOMPARE(m_subject->key(), QString("key")); + QCOMPARE(m_subject->title(), QString("title")); +} + +void Ut_DuiSettingsLanguageText::testNodeType() +{ + QVERIFY((dynamic_cast(m_subject))); +} + +void Ut_DuiSettingsLanguageText::testTextTitleLocalized() +{ + gLocalizeStrings = true; + QCOMPARE(m_subject->title(), QString("titleLocalized")); +} + +QTEST_MAIN(Ut_DuiSettingsLanguageText) diff --git a/tests/ut_duisettingslanguagetext/ut_duisettingslanguagetext.h b/tests/ut_duisettingslanguagetext/ut_duisettingslanguagetext.h new file mode 100644 index 000000000..1ff9c93ab --- /dev/null +++ b/tests/ut_duisettingslanguagetext/ut_duisettingslanguagetext.h @@ -0,0 +1,48 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUISETTINGSLANGUAGETEXT_H +#define UT_DUISETTINGSLANGUAGETEXT_H + +#include +#include + +#include + +Q_DECLARE_METATYPE(DuiSettingsLanguageText *); + +class Ut_DuiSettingsLanguageText : public QObject +{ + Q_OBJECT + +private slots: + void init(); + void cleanup(); + void initTestCase(); + void cleanupTestCase(); + + void testTextKeyTitle(); + void testNodeType(); + void testTextTitleLocalized(); + +private: + DuiSettingsLanguageText *m_subject; +}; + +#endif diff --git a/tests/ut_duisettingslanguagetext/ut_duisettingslanguagetext.pro b/tests/ut_duisettingslanguagetext/ut_duisettingslanguagetext.pro new file mode 100644 index 000000000..3a19bbf0a --- /dev/null +++ b/tests/ut_duisettingslanguagetext/ut_duisettingslanguagetext.pro @@ -0,0 +1,21 @@ +include(../common_top.pri) +TARGET = ut_duisettingslanguagetext +INCLUDEPATH += $$DUISRCDIR/settingslanguage + +# unit test and unit classes +SOURCES += \ + ut_duisettingslanguagetext.cpp \ + $$DUISRCDIR/settingslanguage/duisettingslanguagetext.cpp \ + $$DUISRCDIR/settingslanguage/duisettingslanguagenode.cpp + +# service classes +SOURCES += \ + $$STUBSDIR/stubbase.cpp \ + +# unit test and unit classes +HEADERS += \ + ut_duisettingslanguagetext.h \ + $$DUISRCDIR/settingslanguage/duisettingslanguagetext.h \ + $$DUISRCDIR/settingslanguage/duisettingslanguagenode.h + +include(../common_bot.pri) diff --git a/tests/ut_duisettingslanguagetextcontroller/.gitignore b/tests/ut_duisettingslanguagetextcontroller/.gitignore new file mode 100644 index 000000000..10a641871 --- /dev/null +++ b/tests/ut_duisettingslanguagetextcontroller/.gitignore @@ -0,0 +1 @@ +ut_duisettingslanguagetextcontroller diff --git a/tests/ut_duisettingslanguagetextcontroller/ut_duisettingslanguagetextcontroller.cpp b/tests/ut_duisettingslanguagetextcontroller/ut_duisettingslanguagetextcontroller.cpp new file mode 100644 index 000000000..623376d7a --- /dev/null +++ b/tests/ut_duisettingslanguagetextcontroller/ut_duisettingslanguagetextcontroller.cpp @@ -0,0 +1,73 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duisettingslanguagetextcontroller.h" +#include + +#include +#include +#include +#include +#include +#include "../stubs/mockdatastore.h" + +void TestTextEdit::focusOut() +{ + QFocusEvent event(QEvent::FocusOut); + focusOutEvent(&event); +} + +void Ut_DuiSettingsLanguageTextController::init() +{ + m_subject = new DuiSettingsLanguageTextController(); +} + +void Ut_DuiSettingsLanguageTextController::cleanup() +{ + delete m_subject; +} + +void Ut_DuiSettingsLanguageTextController::initTestCase() +{ + static int argc = 1; + static char *argv[1] = { (char *) "./ut_duisettingslanguagetextcontroller" }; + app = new DuiApplication(argc, argv); + appWin = new DuiApplicationWindow; +} + +void Ut_DuiSettingsLanguageTextController::cleanupTestCase() +{ + delete appWin; + delete app; +} + +void Ut_DuiSettingsLanguageTextController::testTextChanged() +{ + MockDataStore dataStore; + TestTextEdit textEdit; + textEdit.setProperty("key", QString("textKey")); + textEdit.setText("Test"); + textEdit.setProperty("dataStore", qVariantFromValue(static_cast(&dataStore))); + + connect(&textEdit, SIGNAL(lostFocus(Qt::FocusReason)), m_subject, SLOT(textEditLostFocus(Qt::FocusReason))); + textEdit.focusOut(); + QCOMPARE(dataStore.value("textKey").toString(), QString("Test")); +} + +QTEST_APPLESS_MAIN(Ut_DuiSettingsLanguageTextController) diff --git a/tests/ut_duisettingslanguagetextcontroller/ut_duisettingslanguagetextcontroller.h b/tests/ut_duisettingslanguagetextcontroller/ut_duisettingslanguagetextcontroller.h new file mode 100644 index 000000000..90e717e06 --- /dev/null +++ b/tests/ut_duisettingslanguagetextcontroller/ut_duisettingslanguagetextcontroller.h @@ -0,0 +1,55 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUISETTINGSLANGUAGETEXTCONTROLLER_H +#define UT_DUISETTINGSLANGUAGETEXTCONTROLLER_H + +#include +#include +#include + +class DuiApplication; +class DuiApplicationWindow; +class DuiSettingsLanguageTextController; + +class TestTextEdit : public DuiTextEdit +{ +public: + void focusOut(); +}; + +class Ut_DuiSettingsLanguageTextController : public QObject +{ + Q_OBJECT + +private slots: + void init(); + void cleanup(); + void initTestCase(); + void cleanupTestCase(); + + void testTextChanged(); + +private: + DuiApplication *app; + DuiApplicationWindow *appWin; + DuiSettingsLanguageTextController *m_subject; +}; + +#endif diff --git a/tests/ut_duisettingslanguagetextcontroller/ut_duisettingslanguagetextcontroller.pro b/tests/ut_duisettingslanguagetextcontroller/ut_duisettingslanguagetextcontroller.pro new file mode 100644 index 000000000..74f0d5171 --- /dev/null +++ b/tests/ut_duisettingslanguagetextcontroller/ut_duisettingslanguagetextcontroller.pro @@ -0,0 +1,18 @@ +include(../common_top.pri) + +INCLUDEPATH += $$DUISRCDIR/settingslanguage + +TARGET = ut_duisettingslanguagetextcontroller + +# unit test and unit +SOURCES += \ + ut_duisettingslanguagetextcontroller.cpp \ + $$DUISRCDIR/settingslanguage/duisettingslanguagetextcontroller.cpp + +# unit test and unit +HEADERS += \ + ut_duisettingslanguagetextcontroller.h \ + $$DUISRCDIR/settingslanguage/duisettingslanguagetextcontroller.h + +include(../common_bot.pri) + diff --git a/tests/ut_duisettingslanguagetextfactory/.gitignore b/tests/ut_duisettingslanguagetextfactory/.gitignore new file mode 100644 index 000000000..a3fc22bd7 --- /dev/null +++ b/tests/ut_duisettingslanguagetextfactory/.gitignore @@ -0,0 +1 @@ +ut_duisettingslanguagetextfactory diff --git a/tests/ut_duisettingslanguagetextfactory/ut_duisettingslanguagetextfactory.cpp b/tests/ut_duisettingslanguagetextfactory/ut_duisettingslanguagetextfactory.cpp new file mode 100644 index 000000000..6ab7d466b --- /dev/null +++ b/tests/ut_duisettingslanguagetextfactory/ut_duisettingslanguagetextfactory.cpp @@ -0,0 +1,88 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ut_duisettingslanguagetextfactory.h" +#include "mockdatastore.h" + +void Ut_DuiSettingsLanguageTextFactory::initTestCase() +{ + // DuiApplication and DuiApplicationWindow must exist + static int argc = 1; + static char *app_name[1] = { (char *)"./ut_duisettingslanguagetextfactory" }; + app = new DuiApplication(argc, app_name); + appWin = new DuiApplicationWindow; +} + +void Ut_DuiSettingsLanguageTextFactory::cleanupTestCase() +{ + // Destroy the DuiApplicationWindow + delete appWin; + // Destroy the DuiApplication + delete app; +} + +void Ut_DuiSettingsLanguageTextFactory::init() +{ +} + +void Ut_DuiSettingsLanguageTextFactory::cleanup() +{ +} + +void Ut_DuiSettingsLanguageTextFactory::testCreateWidget() +{ + // Create a settings text + DuiSettingsLanguageText settingsText("TestKey", "Title"); + DuiSettingsLanguageWidget dds; + MockDataStore dataStore; + DuiWidget *widget = DuiSettingsLanguageTextFactory::createWidget(settingsText, dds, &dataStore); + QVERIFY(widget != NULL); + + // Expecting the widget to have a QGraphicsLinearLayout + QGraphicsLinearLayout *layout = dynamic_cast(widget->layout()); + QVERIFY(layout != NULL); + + // Expecting the layout to contain a DuiLabel and a DuiTextEdit + QCOMPARE(layout->count(), 2); + + // The label's title should be the SettingsText's title + DuiLabel *label = dynamic_cast(layout->itemAt(0)); + QVERIFY(label != NULL); + QCOMPARE(label->text(), settingsText.title()); + + // The label's title should be the specified key's value + DuiTextEdit *textEdit = dynamic_cast(layout->itemAt(1)); + QVERIFY(textEdit != NULL); + QCOMPARE(textEdit->text(), dataStore.value("TestKey").toString()); +} + +QTEST_APPLESS_MAIN(Ut_DuiSettingsLanguageTextFactory) diff --git a/tests/ut_duisettingslanguagetextfactory/ut_duisettingslanguagetextfactory.h b/tests/ut_duisettingslanguagetextfactory/ut_duisettingslanguagetextfactory.h new file mode 100644 index 000000000..11e13cd6f --- /dev/null +++ b/tests/ut_duisettingslanguagetextfactory/ut_duisettingslanguagetextfactory.h @@ -0,0 +1,46 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUISETTINGSLANGUAGETEXTFACTORY_H +#define UT_DUISETTINGSLANGUAGETEXTFACTORY_H + +#include +#include + +class DuiApplication; +class DuiApplicationWindow; + +class Ut_DuiSettingsLanguageTextFactory : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + + void testCreateWidget(); + +private: + DuiApplication *app; + DuiApplicationWindow *appWin; +}; + +#endif diff --git a/tests/ut_duisettingslanguagetextfactory/ut_duisettingslanguagetextfactory.pro b/tests/ut_duisettingslanguagetextfactory/ut_duisettingslanguagetextfactory.pro new file mode 100644 index 000000000..a9418e456 --- /dev/null +++ b/tests/ut_duisettingslanguagetextfactory/ut_duisettingslanguagetextfactory.pro @@ -0,0 +1,25 @@ +include(../common_top.pri) +TARGET = ut_duisettingslanguagetextfactory +INCLUDEPATH += $$DUISRCDIR/settingslanguage + +TEST_SOURCES = \ + $$DUISRCDIR/settingslanguage/duisettingslanguagetextfactory.cpp \ + +# unit test and unit +SOURCES += \ + ut_duisettingslanguagetextfactory.cpp \ + $$DUISRCDIR/settingslanguage/duisettingslanguagenode.cpp \ + $$TEST_SOURCES \ + +# service classes +SOURCES += \ + $$STUBSDIR/stubbase.cpp \ + +# unit test and unit +HEADERS += \ + ut_duisettingslanguagetextfactory.h \ + $$DUISRCDIR/settingslanguage/duisettingslanguagetextfactory.h \ + $$DUISRCDIR/settingslanguage/duisettingslanguagetextcontroller.h \ + $$DUISRCDIR/settingslanguage/duisettingslanguagenode.h + +include(../common_bot.pri) diff --git a/tests/ut_duisettingslanguagewidget/.gitignore b/tests/ut_duisettingslanguagewidget/.gitignore new file mode 100644 index 000000000..1ba7fdbc7 --- /dev/null +++ b/tests/ut_duisettingslanguagewidget/.gitignore @@ -0,0 +1 @@ +ut_duisettingslanguagewidget diff --git a/tests/ut_duisettingslanguagewidget/ut_duisettingslanguagewidget.cpp b/tests/ut_duisettingslanguagewidget/ut_duisettingslanguagewidget.cpp new file mode 100644 index 000000000..f7719c374 --- /dev/null +++ b/tests/ut_duisettingslanguagewidget/ut_duisettingslanguagewidget.cpp @@ -0,0 +1,52 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duisettingslanguagewidget.h" +#include "duisettingslanguagewidget.h" + +#include +#include + + +void Ut_DuiSettingsLanguageWidget::initTestCase() +{ + // Create a DuiApplication + static int argc = 1; + static char *app_name[1] = { (char *)"./ut_duisettingslanguagewidget" }; + app = new DuiApplication(argc, app_name); +} + +void Ut_DuiSettingsLanguageWidget::cleanupTestCase() +{ + // Destroy DuiApplication + delete app; +} + +void Ut_DuiSettingsLanguageWidget::init() +{ + m_subject = new DuiSettingsLanguageWidget; + QCoreApplication::processEvents(); +} + +void Ut_DuiSettingsLanguageWidget::cleanup() +{ + delete m_subject; +} + +QTEST_APPLESS_MAIN(Ut_DuiSettingsLanguageWidget) diff --git a/tests/ut_duisettingslanguagewidget/ut_duisettingslanguagewidget.h b/tests/ut_duisettingslanguagewidget/ut_duisettingslanguagewidget.h new file mode 100644 index 000000000..c7e281aeb --- /dev/null +++ b/tests/ut_duisettingslanguagewidget/ut_duisettingslanguagewidget.h @@ -0,0 +1,52 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUISETTINGSLANGUAGEWIDGET_H +#define UT_DUISETTINGSLANGUAGEWIDGET_H + +#include + +class DuiApplication; +class DuiSettingsLanguageWidget; + +class Ut_DuiSettingsLanguageWidget : public QObject +{ + Q_OBJECT + +private: + DuiApplication *app; + DuiSettingsLanguageWidget *m_subject; + +signals: + // Signal for clicking the item + void clicked(); + +private slots: + // Executed once before every test case + void init(); + // Executed once after every test case + void cleanup(); + // Executed once before first test case + void initTestCase(); + // Executed once after last test case + void cleanupTestCase(); + +}; + +#endif // UT_DUISETTINGSLANGUAGEWIDGET_H diff --git a/tests/ut_duisettingslanguagewidget/ut_duisettingslanguagewidget.pro b/tests/ut_duisettingslanguagewidget/ut_duisettingslanguagewidget.pro new file mode 100644 index 000000000..4826d124a --- /dev/null +++ b/tests/ut_duisettingslanguagewidget/ut_duisettingslanguagewidget.pro @@ -0,0 +1,18 @@ +include(../common_top.pri) + +QT += xml + +TARGET = ut_duisettingslanguagewidget +INCLUDEPATH += $$DUISRCDIR/settingslanguage + +# unit test and unit classes +SOURCES += \ + ut_duisettingslanguagewidget.cpp \ + $$DUISRCDIR/settingslanguage/duisettingslanguagewidget.cpp + +# unit test and unit classes +HEADERS += \ + ut_duisettingslanguagewidget.h \ + $$DUISRCDIR/settingslanguage/duisettingslanguagewidget.h + +include(../common_bot.pri) diff --git a/tests/ut_duisettingslanguagewidgetfactory/.gitignore b/tests/ut_duisettingslanguagewidgetfactory/.gitignore new file mode 100644 index 000000000..dd11f79b5 --- /dev/null +++ b/tests/ut_duisettingslanguagewidgetfactory/.gitignore @@ -0,0 +1,2 @@ +ut_duisettingslanguagewidgetfactory + diff --git a/tests/ut_duisettingslanguagewidgetfactory/ut_duisettingslanguagewidgetfactory.cpp b/tests/ut_duisettingslanguagewidgetfactory/ut_duisettingslanguagewidgetfactory.cpp new file mode 100644 index 000000000..49c49c090 --- /dev/null +++ b/tests/ut_duisettingslanguagewidgetfactory/ut_duisettingslanguagewidgetfactory.cpp @@ -0,0 +1,77 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include "ut_duisettingslanguagewidgetfactory.h" +#include "duisettingslanguagebinary_stub.h" +#include "duisettingslanguagewidgetfactory.h" +#include "duisettingslanguagesettingsfactory_stub.h" +#include "duisettingslanguagewidget_stub.h" +#include "duisettingslanguagesettings_stub.h" +#include "mockdatastore.h" + +void QGraphicsItem::setParentItem(QGraphicsItem *) +{ +} + +void QGraphicsLinearLayout::insertItem(int, QGraphicsLayoutItem *) +{ +} + +// Tests +void Ut_DuiSettingsLanguageWidgetFactory::initTestCase() +{ +} + +void Ut_DuiSettingsLanguageWidgetFactory::cleanupTestCase() +{ +} + +void Ut_DuiSettingsLanguageWidgetFactory::init() +{ +} + +void Ut_DuiSettingsLanguageWidgetFactory::cleanup() +{ +} + + +void Ut_DuiSettingsLanguageWidgetFactory::testChildrenCreation() +{ + // Create a root with one item + DuiSettingsLanguageSettings *item = new DuiSettingsLanguageSettings(); + DuiSettingsLanguageBinary binary; + binary.addChild(item); + + // Create stub return values + DuiWidgetController widgetController; + QList children; + children.append(item); + gDuiSettingsLanguageBinaryStub->stubSetReturnValue("children", children); + gDuiSettingsLanguageSettingsFactoryStub->stubSetReturnValue("createWidget", &widgetController); + + MockDataStore dataStore; + DuiWidget *widget = DuiSettingsLanguageWidgetFactory::createWidget(binary, &dataStore); + QVERIFY(widget != NULL); + QCOMPARE(gDuiSettingsLanguageSettingsFactoryStub->stubLastCallTo("createWidget").parameter(0), item); + QCOMPARE(gDuiSettingsLanguageSettingsFactoryStub->stubLastCallTo("createWidget").parameter(2), &dataStore); +} + +QTEST_APPLESS_MAIN(Ut_DuiSettingsLanguageWidgetFactory) diff --git a/tests/ut_duisettingslanguagewidgetfactory/ut_duisettingslanguagewidgetfactory.h b/tests/ut_duisettingslanguagewidgetfactory/ut_duisettingslanguagewidgetfactory.h new file mode 100644 index 000000000..0e085755d --- /dev/null +++ b/tests/ut_duisettingslanguagewidgetfactory/ut_duisettingslanguagewidgetfactory.h @@ -0,0 +1,46 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUISETTINGSLANGUAGEFACTORY_H +#define UT_DUISETTINGSLANGUAGEFACTORY_H + +#include + +class DuiSettingsLanguageSettings; +class DuiDataStore; + +class Ut_DuiSettingsLanguageWidgetFactory : public QObject +{ + Q_OBJECT + +private slots: + // Executed once before every test case + void init(); + // Executed once after every test case + void cleanup(); + // Executed once before first test case + void initTestCase(); + // Executed once after last test case + void cleanupTestCase(); + + // Test creation of children + void testChildrenCreation(); +}; + +#endif // UT_DUISETTINGSLANGUAGEFACTORY_H diff --git a/tests/ut_duisettingslanguagewidgetfactory/ut_duisettingslanguagewidgetfactory.pro b/tests/ut_duisettingslanguagewidgetfactory/ut_duisettingslanguagewidgetfactory.pro new file mode 100644 index 000000000..c27014e59 --- /dev/null +++ b/tests/ut_duisettingslanguagewidgetfactory/ut_duisettingslanguagewidgetfactory.pro @@ -0,0 +1,21 @@ +include(../common_top.pri) +TARGET = ut_duisettingslanguagewidgetfactory +INCLUDEPATH += $$DUISRCDIR/settingslanguage + +# unit test and unit classes +SOURCES += \ + ut_duisettingslanguagewidgetfactory.cpp \ + $$DUISRCDIR/settingslanguage/duisettingslanguagewidgetfactory.cpp \ + $$DUISRCDIR/settingslanguage/duisettingslanguagenode.cpp + +# service classes +SOURCES += \ + $$STUBSDIR/stubbase.cpp \ + +# unit test and unit classes +HEADERS += \ + ut_duisettingslanguagewidgetfactory.h \ + $$DUISRCDIR/settingslanguage/duisettingslanguagewidgetfactory.h \ + $$DUISRCDIR/settingslanguage/duisettingslanguagenode.h + +include(../common_bot.pri) diff --git a/tests/ut_duishareddata/.gitignore b/tests/ut_duishareddata/.gitignore new file mode 100644 index 000000000..96fe45a11 --- /dev/null +++ b/tests/ut_duishareddata/.gitignore @@ -0,0 +1,2 @@ +ut_duishareddata + diff --git a/tests/ut_duishareddata/ut_duishareddata.cpp b/tests/ut_duishareddata/ut_duishareddata.cpp new file mode 100644 index 000000000..9ef90d1f5 --- /dev/null +++ b/tests/ut_duishareddata/ut_duishareddata.cpp @@ -0,0 +1,303 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include +#include "core/duishareddata.h" +#include "ut_duishareddata.h" + +void Ut_DuiSharedData::init() +{ +} + +void Ut_DuiSharedData::cleanup() +{ +} + +void Ut_DuiSharedData::testOpenClose() +{ + DuiSharedData *shm = new DuiSharedData("buffer"); + + QVERIFY(shm->open(DuiSharedData::Write) == true); + shm->close(); + + // nothing yet to read + QVERIFY(shm->open(DuiSharedData::ReadOnly) == false); + shm->close(); + + QVERIFY(shm->open(DuiSharedData::Write) == true); + *shm << 1; + shm->close(); + + QVERIFY(shm->open(DuiSharedData::ReadOnly) == true); + shm->close(); + + delete shm; +} + +void Ut_DuiSharedData::testReadWrite_1() +{ + int dataIn1 = 1, dataOut1; + bool dataIn2 = true, dataOut2; + qreal dataIn3 = 0.1, dataOut3; + QFont dataIn4("Times", 10, QFont::Bold), dataOut4; + QVariant dataIn5("qqq"), dataOut5; + QString dataIn6("asdf"), dataOut6; + + qint64 pos1, pos2, pos3, pos4, pos5, pos6; + + DuiSharedData *shm = new DuiSharedData("buffer"); + + QVERIFY(shm->open(DuiSharedData::Write) == true); + + pos1 = shm->pos(); + QVERIFY(pos1 == 0); + *shm << dataIn1; + + pos2 = shm->pos(); + *shm << dataIn2; + + pos3 = shm->pos(); + *shm << dataIn3; + + pos4 = shm->pos(); + *shm << dataIn4; + + pos5 = shm->pos(); + *shm << dataIn5; + + pos6 = shm->pos(); + *shm << dataIn6; + + shm->close(); + + QVERIFY(shm->open(DuiSharedData::ReadOnly) == true); + *shm >> dataOut1 >> dataOut2 >> dataOut3 >> dataOut4 >> dataOut5 >> dataOut6; + + QVERIFY(dataIn1 == dataOut1); + QVERIFY(dataIn2 == dataOut2); + QVERIFY(dataIn3 == dataOut3); + QVERIFY(dataIn4 == dataOut4); + QVERIFY(dataIn5 == dataOut5); + QVERIFY(dataIn6 == dataOut6); + shm->close(); + + QVERIFY(shm->open(DuiSharedData::ReadOnly) == true); + + shm->seek(pos6); + *shm >> dataOut6; + QVERIFY(dataIn6 == dataOut6); + + shm->seek(pos5); + *shm >> dataOut5; + QVERIFY(dataIn5 == dataOut5); + + shm->seek(pos4); + *shm >> dataOut4; + QVERIFY(dataIn4 == dataOut4); + + shm->seek(pos3); + *shm >> dataOut3; + QVERIFY(dataIn3 == dataOut3); + + shm->seek(pos2); + *shm >> dataOut2; + QVERIFY(dataIn2 == dataOut2); + + shm->seek(pos1); + *shm >> dataOut1; + QVERIFY(dataIn1 == dataOut1); + + shm->close(); + delete shm; +} + +// generate random data and save it to shm +void Ut_DuiSharedData::testReadWrite_N(DuiSharedData *shm, QStringList &data, QList &offsets) +{ + int len, i, j; + + srand(time(NULL)); + + for (i = 0; i < 100; i++) { + len = rand() % 100 + 100; + QString newString; + + newString.resize(len); + + for (j = 0; j < len; j++) { + newString[j] = 'a' + rand() % 26; + } + + qint64 offset = shm->pos(); + *shm << newString; + + data << newString; + offsets << offset; + } +} + +// verify that data is shared +void Ut_DuiSharedData::testReadWrite_N_verify(DuiSharedData *shm, QStringList &data, QList &offsets) +{ + int i; + + for (i = 0; i < 100; i++) { + int ind = rand() % 100; + QString str; + + shm->seek(offsets[ind]); + *shm >> str; + QVERIFY(str == data[ind]); + } +} + +// test read/write of shared memory with pageSize=1000 bytes +void Ut_DuiSharedData::testReadWrite_1000() +{ + QStringList data; + QList offsets; + + DuiSharedData *shm1 = new DuiSharedData("buffer1K"); + shm1->setPageSize(1000); + QVERIFY(shm1->open(DuiSharedData::Write) == true); + + testReadWrite_N(shm1, data, offsets); + + shm1->close(); + + DuiSharedData *shm2 = new DuiSharedData("buffer1K"); + shm2->setPageSize(1000); + QVERIFY(shm2->open(DuiSharedData::ReadOnly) == true); + + testReadWrite_N_verify(shm2, data, offsets); + + shm2->close(); + + delete shm1; + delete shm2; +} + +// test read/write of shared memory with pageSize=2000 bytes +void Ut_DuiSharedData::testReadWrite_2000() +{ + QStringList data; + QList offsets; + + DuiSharedData *shm1 = new DuiSharedData("buffer2K"); + shm1->setPageSize(2000); + QVERIFY(shm1->open(DuiSharedData::Write) == true); + + testReadWrite_N(shm1, data, offsets); + + shm1->close(); + + DuiSharedData *shm2 = new DuiSharedData("buffer2K"); + shm2->setPageSize(2000); + QVERIFY(shm2->open(DuiSharedData::ReadOnly) == true); + + testReadWrite_N_verify(shm2, data, offsets); + + shm2->close(); + + delete shm1; + delete shm2; +} + +// test read/write of shared memory with pageSize=5000 bytes +void Ut_DuiSharedData::testReadWrite_5000() +{ + QStringList data; + QList offsets; + + DuiSharedData *shm1 = new DuiSharedData("buffer5K"); + shm1->setPageSize(5000); + QVERIFY(shm1->open(DuiSharedData::Write) == true); + + testReadWrite_N(shm1, data, offsets); + + shm1->close(); + + DuiSharedData *shm2 = new DuiSharedData("buffer5K"); + shm2->setPageSize(5000); + QVERIFY(shm2->open(DuiSharedData::ReadOnly) == true); + + testReadWrite_N_verify(shm2, data, offsets); + + shm2->close(); + + delete shm1; + delete shm2; +} + +// test read/write of shared memory with pageSize=10000 bytes +void Ut_DuiSharedData::testReadWrite_10000() +{ + QStringList data; + QList offsets; + + DuiSharedData *shm1 = new DuiSharedData("buffer10K"); + shm1->setPageSize(10000); + QVERIFY(shm1->open(DuiSharedData::Write) == true); + + testReadWrite_N(shm1, data, offsets); + + shm1->close(); + + DuiSharedData *shm2 = new DuiSharedData("buffer10K"); + shm2->setPageSize(10000); + QVERIFY(shm2->open(DuiSharedData::ReadOnly) == true); + + testReadWrite_N_verify(shm2, data, offsets); + + shm2->close(); + + delete shm1; + delete shm2; +} + +// test read/write of shared memory with pageSize=20000 bytes +void Ut_DuiSharedData::testReadWrite_20000() +{ + QStringList data; + QList offsets; + + DuiSharedData *shm1 = new DuiSharedData("buffer20K"); + shm1->setPageSize(20000); + QVERIFY(shm1->open(DuiSharedData::Write) == true); + + testReadWrite_N(shm1, data, offsets); + + shm1->close(); + + DuiSharedData *shm2 = new DuiSharedData("buffer20K"); + shm2->setPageSize(20000); + QVERIFY(shm2->open(DuiSharedData::ReadOnly) == true); + + testReadWrite_N_verify(shm2, data, offsets); + + shm2->close(); + + delete shm1; + delete shm2; +} + + +QTEST_APPLESS_MAIN(Ut_DuiSharedData) diff --git a/tests/ut_duishareddata/ut_duishareddata.h b/tests/ut_duishareddata/ut_duishareddata.h new file mode 100644 index 000000000..0d4728ee1 --- /dev/null +++ b/tests/ut_duishareddata/ut_duishareddata.h @@ -0,0 +1,53 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUISHAREDDATA_H +#define UT_DUISHAREDDATA_H + +#include +#include + +#include + +Q_DECLARE_METATYPE(DuiSharedData *); + +class Ut_DuiSharedData : public QObject +{ + Q_OBJECT + +private slots: + void init(); + void cleanup(); + + void testOpenClose(); + void testReadWrite_1(); + void testReadWrite_1000(); + void testReadWrite_2000(); + void testReadWrite_5000(); + void testReadWrite_10000(); + void testReadWrite_20000(); + +private: + void testReadWrite_N(DuiSharedData *shm, QStringList &data, QList &offsets); + void testReadWrite_N_verify(DuiSharedData *shm, QStringList &data, QList &offsets); + +}; + +#endif + diff --git a/tests/ut_duishareddata/ut_duishareddata.pro b/tests/ut_duishareddata/ut_duishareddata.pro new file mode 100644 index 000000000..4b6da4f1e --- /dev/null +++ b/tests/ut_duishareddata/ut_duishareddata.pro @@ -0,0 +1,15 @@ +include(../common_top.pri) +INCLUDEPATH += $$DUISRCDIR/theme + +TARGET = ut_duishareddata + +# unit test and unit +SOURCES += \ + ut_duishareddata.cpp \ + +# unit test and unit +HEADERS += \ + ut_duishareddata.h \ + +include(../common_bot.pri) + diff --git a/tests/ut_duislider/.gitignore b/tests/ut_duislider/.gitignore new file mode 100644 index 000000000..4c9eb3eaf --- /dev/null +++ b/tests/ut_duislider/.gitignore @@ -0,0 +1 @@ +ut_duislider diff --git a/tests/ut_duislider/ut_duislider.cpp b/tests/ut_duislider/ut_duislider.cpp new file mode 100644 index 000000000..2de4b3f6b --- /dev/null +++ b/tests/ut_duislider/ut_duislider.cpp @@ -0,0 +1,382 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duislider.h" +#include +#include +#include + +#include + +void Ut_DuiSlider::sliderSetMinIndicatorVisibility() +{ + DuiSlider *s = new DuiSlider; + + bool maxIndicatorVisible = s->isMaxLabelVisible(); + bool handleIndicatorVisible = s->isHandleLabelVisible(); + + s->setMinLabelVisible(true); + QCOMPARE(s->isMinLabelVisible(), true); + + s->setMinLabelVisible(false); + QCOMPARE(s->isMinLabelVisible(), false); + + QCOMPARE(s->isMaxLabelVisible(), maxIndicatorVisible); + QCOMPARE(s->isHandleLabelVisible(), handleIndicatorVisible); + + delete s; +} + +void Ut_DuiSlider::sliderSetMaxIndicatorVisibility() +{ + DuiSlider *s = new DuiSlider; + + bool minIndicatorVisible = s->isMinLabelVisible(); + bool handleIndicatorVisible = s->isHandleLabelVisible(); + + s->setMaxLabelVisible(true); + QCOMPARE(s->isMaxLabelVisible(), true); + + s->setMaxLabelVisible(false); + QCOMPARE(s->isMaxLabelVisible(), false); + + QCOMPARE(s->isMinLabelVisible(), minIndicatorVisible); + QCOMPARE(s->isHandleLabelVisible(), handleIndicatorVisible); + + delete s; +} + +void Ut_DuiSlider::sliderSetHandleIndicatorVisibility() +{ + DuiSlider *s = new DuiSlider; + + bool minIndicatorVisible = s->isMinLabelVisible(); + bool maxIndicatorVisible = s->isMaxLabelVisible(); + + s->setHandleLabelVisible(true); + QCOMPARE(s->isHandleLabelVisible(), true); + + s->setHandleLabelVisible(false); + QCOMPARE(s->isHandleLabelVisible(), false); + + QCOMPARE(s->isMinLabelVisible(), minIndicatorVisible); + QCOMPARE(s->isMaxLabelVisible(), maxIndicatorVisible); + + delete s; +} + +void Ut_DuiSlider::sliderSetMinIndicatorText() +{ + DuiSlider *s = new DuiSlider; + + QString maxLabelText = s->maxLabelText(); + QString handleLabelText = s->handleLabelText(); + + s->setMinLabel("minText"); + + QCOMPARE(s->minLabelText(), QString("minText")); + + QCOMPARE(s->maxLabelText(), maxLabelText); + QCOMPARE(s->handleLabelText(), handleLabelText); + + delete s; +} + +void Ut_DuiSlider::sliderSetMaxIndicatorText() +{ + DuiSlider *s = new DuiSlider; + + QString minLabelText = s->minLabelText(); + QString handleLabelText = s->handleLabelText(); + + s->setMaxLabel("maxText"); + + QCOMPARE(s->maxLabelText(), QString("maxText")); + + QCOMPARE(s->minLabelText(), minLabelText); + QCOMPARE(s->handleLabelText(), handleLabelText); + + delete s; +} + +void Ut_DuiSlider::sliderSetHandleIndicatorText() +{ + DuiSlider *s = new DuiSlider; + + QString minLabelText = s->minLabelText(); + QString maxLabelText = s->maxLabelText(); + + s->setHandleLabel("handleText"); + + QCOMPARE(s->handleLabelText(), QString("handleText")); + + QCOMPARE(s->minLabelText(), minLabelText); + QCOMPARE(s->maxLabelText(), maxLabelText); + + delete s; +} + +void Ut_DuiSlider::sliderSetMinImageID() +{ + DuiSlider *s = new DuiSlider; + + QString maxLabelImageID = s->maxLabelIconID(); + QString handleLabelImageID = s->handleLabelIconID(); + + s->setMinLabelIconID("minIcon"); + + QCOMPARE(s->minLabelIconID(), QString("minIcon")); + + QCOMPARE(s->maxLabelIconID(), maxLabelImageID); + QCOMPARE(s->handleLabelIconID(), handleLabelImageID); + + delete s; +} + +void Ut_DuiSlider::sliderSetMaxImageID() +{ + DuiSlider *s = new DuiSlider; + + QString minLabelImageID = s->minLabelIconID(); + QString handleLabelImageID = s->handleLabelIconID(); + + s->setMaxLabelIconID("maxIcon"); + + QCOMPARE(s->maxLabelIconID(), QString("maxIcon")); + + QCOMPARE(s->minLabelIconID(), minLabelImageID); + QCOMPARE(s->handleLabelIconID(), handleLabelImageID); + + delete s; +} + +void Ut_DuiSlider::sliderSetHandleImageID() +{ + DuiSlider *s = new DuiSlider; + + QString minLabelImageID = s->minLabelIconID(); + QString maxLabelImageID = s->maxLabelIconID(); + + s->setHandleLabelIconID("handleIcon"); + + QCOMPARE(s->handleLabelIconID(), QString("handleIcon")); + + QCOMPARE(s->minLabelIconID(), minLabelImageID); + QCOMPARE(s->maxLabelIconID(), maxLabelImageID); + + delete s; +} + +void Ut_DuiSlider::sliderSetMinimum() +{ + DuiSlider *s = new DuiSlider; + + int max = s->maximum(); + + s->setMinimum(max - 1); + + QCOMPARE(s->minimum(), max - 1); + + QCOMPARE(s->maximum(), max); + QVERIFY(s->value() >= s->minimum()); + QVERIFY(s->value() <= s->maximum()); + + s->setMinimum(s->maximum() + 1); + QVERIFY(s->minimum() <= s->maximum()); + QVERIFY(s->value() >= s->minimum()); + QVERIFY(s->value() <= s->maximum()); + + delete s; +} + +void Ut_DuiSlider::sliderSetMaximum() +{ + DuiSlider *s = new DuiSlider; + + int min = s->minimum(); + + s->setMaximum(min + 1); + + QCOMPARE(s->maximum(), min + 1); + + QCOMPARE(s->minimum(), min); + QVERIFY(s->value() >= s->minimum()); + QVERIFY(s->value() <= s->maximum()); + + s->setMaximum(s->minimum() - 1); + QVERIFY(s->minimum() <= s->maximum()); + QVERIFY(s->value() >= s->minimum()); + QVERIFY(s->value() <= s->maximum()); + + delete s; +} + +void Ut_DuiSlider::sliderSetRange() +{ + DuiSlider *s = new DuiSlider; + + s->setRange(10, 20); + QCOMPARE(s->minimum(), 10); + QCOMPARE(s->maximum(), 20); + QVERIFY(s->value() >= s->minimum()); + QVERIFY(s->value() <= s->maximum()); + + s->setRange(20, 10); + QCOMPARE(s->minimum(), 20); + QCOMPARE(s->maximum(), 20); + QVERIFY(s->value() >= s->minimum()); + QVERIFY(s->value() <= s->maximum()); + + s->setRange(20, 10); + s->setValue(30); + QCOMPARE(s->minimum(), 20); + QCOMPARE(s->maximum(), 20); + QCOMPARE(s->value(), 20); + + s->setRange(10, 5); + s->setValue(3); + QCOMPARE(s->minimum(), 10); + QCOMPARE(s->maximum(), 10); + QCOMPARE(s->value(), 10); + + delete s; +} + +void Ut_DuiSlider::sliderSetValue() +{ + DuiSlider *s = new DuiSlider; + + s->setMinimum(20); + s->setMaximum(30); + + int min = s->minimum(); + int max = s->maximum(); + QCOMPARE(min, 20); + QCOMPARE(max, 30); + + s->setValue((min + max) / 2); + + QCOMPARE(s->value(), (min + max) / 2); + QCOMPARE(s->minimum(), min); + QCOMPARE(s->maximum(), max); + + s->setValue(s->minimum() - 1); + QVERIFY(s->value() >= s->minimum()); + QVERIFY(s->value() <= s->maximum()); + + QCOMPARE(s->minimum(), min); + QCOMPARE(s->maximum(), max); + + s->setValue(s->maximum() + 1); + QVERIFY(s->value() >= s->minimum()); + QVERIFY(s->value() <= s->maximum()); + + s->setMinimum(20); + s->setMaximum(20); + QCOMPARE(s->minimum(), 20); + QCOMPARE(s->maximum(), 20); + QCOMPARE(s->value(), 20); + + s->setMinimum(20); + s->setMaximum(10) ; + s->setValue(30); + QCOMPARE(s->minimum(), 10); + QCOMPARE(s->maximum(), 10); + QCOMPARE(s->value(), 10); + + s->setMinimum(10); + s->setMaximum(5); + s->setValue(3); + QCOMPARE(s->minimum(), 5); + QCOMPARE(s->maximum(), 5); + QCOMPARE(s->value(), 5); + + delete s; +} + +void Ut_DuiSlider::sliderSetSteps() +{ + DuiSlider *s = new DuiSlider; + + s->setMinimum(1); + s->setMaximum(5); + + int min = s->minimum(); + int max = s->maximum(); + QCOMPARE(min, 1); + QCOMPARE(max, 5); + + s->setSteps(2); + + QCOMPARE(s->steps(), 2); + + QCOMPARE(s->minimum(), min); + QCOMPARE(s->maximum(), max); + + s->setValue(2); + QCOMPARE(s->value(), 3); + + s->setRange(1, 7); + + min = s->minimum(); + max = s->maximum(); + QCOMPARE(min, 1); + QCOMPARE(max, 7); + + s->setSteps(-2); + + QCOMPARE(s->steps(), 2); + + QCOMPARE(s->minimum(), min); + QCOMPARE(s->maximum(), max); + + s->setValue(2); + QCOMPARE(s->value(), 1); + + delete s; +} + +void Ut_DuiSlider::sliderOrientation() +{ + DuiSlider *s = new DuiSlider; + + s->setOrientation(Qt::Vertical); + QCOMPARE(s->orientation(), Qt::Vertical); + + s->setOrientation(Qt::Horizontal); + QCOMPARE(s->orientation(), Qt::Horizontal); + + delete s; +} + +void Ut_DuiSlider::sliderState() +{ + DuiSlider *s = new DuiSlider; + + s->setState(DuiSliderModel::Pressed); + QCOMPARE(s->state(), DuiSliderModel::Pressed); + + s->setState(DuiSliderModel::Released); + QCOMPARE(s->state(), DuiSliderModel::Released); + + delete s; +} + +QTEST_APPLESS_MAIN(Ut_DuiSlider) + diff --git a/tests/ut_duislider/ut_duislider.h b/tests/ut_duislider/ut_duislider.h new file mode 100644 index 000000000..ec72577b9 --- /dev/null +++ b/tests/ut_duislider/ut_duislider.h @@ -0,0 +1,50 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUISLIDER_H +#define UT_DUISLIDER_H + +#include +#include +#include + +class Ut_DuiSlider : public QObject +{ + Q_OBJECT + +private slots: + void sliderSetMinIndicatorVisibility(); + void sliderSetMaxIndicatorVisibility(); + void sliderSetHandleIndicatorVisibility(); + void sliderSetMinIndicatorText(); + void sliderSetMaxIndicatorText(); + void sliderSetHandleIndicatorText(); + void sliderSetMinImageID(); + void sliderSetMaxImageID(); + void sliderSetHandleImageID(); + void sliderSetMinimum(); + void sliderSetMaximum(); + void sliderSetRange(); + void sliderSetValue(); + void sliderSetSteps(); + void sliderOrientation(); + void sliderState(); +}; + +#endif diff --git a/tests/ut_duislider/ut_duislider.pro b/tests/ut_duislider/ut_duislider.pro new file mode 100644 index 000000000..75997eaf5 --- /dev/null +++ b/tests/ut_duislider/ut_duislider.pro @@ -0,0 +1,11 @@ +include(../common_top.pri) + +TARGET = ut_duislider + +SOURCES += \ + ut_duislider.cpp \ + +HEADERS += \ + ut_duislider.h \ + +include(../common_bot.pri) diff --git a/tests/ut_duisliderview/.gitignore b/tests/ut_duisliderview/.gitignore new file mode 100644 index 000000000..7958e87d3 --- /dev/null +++ b/tests/ut_duisliderview/.gitignore @@ -0,0 +1 @@ +ut_duisliderview diff --git a/tests/ut_duisliderview/ut_duisliderview.cpp b/tests/ut_duisliderview/ut_duisliderview.cpp new file mode 100644 index 000000000..0a7c76c99 --- /dev/null +++ b/tests/ut_duisliderview/ut_duisliderview.cpp @@ -0,0 +1,87 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include "ut_duisliderview.h" +#include "duiapplication.h" + +DuiApplication *app; + +void Ut_DuiSliderView::initTestCase() +{ + static int argc = 1; + static char *app_name[1] = { (char *) "./ut_duisliderview" }; + app = new DuiApplication(argc, app_name); + + m_seekbar = new DuiSeekBar(); + m_subject = new DuiSliderView(m_seekbar); + m_seekbar->setView(m_subject); +} + +void Ut_DuiSliderView::cleanupTestCase() +{ + delete m_seekbar; + m_seekbar = 0; + + delete app; +} + +void Ut_DuiSliderView::sliderResize() +{ + m_seekbar->setOrientation(Qt::Horizontal); + //just give some size for slider groove + QRectF rect = QRectF(0, 0, 400, 100); + m_seekbar->setGeometry(rect); + QRectF seekbarGeometry = m_seekbar->geometry(); + + QCOMPARE(rect.width(), seekbarGeometry.width()); + + //change size of slider groove + rect = QRectF(0, 0, 600, 100); + m_seekbar->setGeometry(rect); + seekbarGeometry = m_seekbar->geometry(); + + QCOMPARE(rect.width(), seekbarGeometry.width()); + + m_seekbar->setOrientation(Qt::Vertical); + //resize slider groove accordingly to vertical orientation + rect = QRectF(0, 0, 100, 400); + m_seekbar->setGeometry(rect); + seekbarGeometry = m_seekbar->geometry(); + + QCOMPARE(rect.height(), seekbarGeometry.height()); + + //change size of slider groove + rect = QRectF(0, 0, 100, 600); + m_seekbar->setGeometry(rect); + seekbarGeometry = m_seekbar->geometry(); + + QCOMPARE(rect.height(), seekbarGeometry.height()); +} + +QTEST_APPLESS_MAIN(Ut_DuiSliderView) diff --git a/tests/ut_duisliderview/ut_duisliderview.h b/tests/ut_duisliderview/ut_duisliderview.h new file mode 100644 index 000000000..0eaa0840a --- /dev/null +++ b/tests/ut_duisliderview/ut_duisliderview.h @@ -0,0 +1,46 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUISLIDERVIEW_H +#define UT_DUISLIDERVIEW_H + +#include +#include + +class DuiSeekBar; +class DuiSliderView; + +class Ut_DuiSliderView : public QObject +{ + Q_OBJECT +public: + +private slots: + void initTestCase(); + void cleanupTestCase(); + + void sliderResize(); + +private: + DuiSeekBar *m_seekbar; + DuiSliderView *m_subject; +}; + +#endif + diff --git a/tests/ut_duisliderview/ut_duisliderview.pro b/tests/ut_duisliderview/ut_duisliderview.pro new file mode 100644 index 000000000..bcc1636e6 --- /dev/null +++ b/tests/ut_duisliderview/ut_duisliderview.pro @@ -0,0 +1,12 @@ + +include(../common_top.pri) +INCLUDEPATH += $$DUISRCDIR/widgets $$DUISRCDIR/style + +TARGET = ut_duisliderview + +SOURCES += \ + ut_duisliderview.cpp \ + +HEADERS += \ + ut_duisliderview.h +include(../common_bot.pri) diff --git a/tests/ut_duisubdatastore/.gitignore b/tests/ut_duisubdatastore/.gitignore new file mode 100644 index 000000000..650f899a9 --- /dev/null +++ b/tests/ut_duisubdatastore/.gitignore @@ -0,0 +1 @@ +ut_duisubdatastore diff --git a/tests/ut_duisubdatastore/ut_duisubdatastore.cpp b/tests/ut_duisubdatastore/ut_duisubdatastore.cpp new file mode 100644 index 000000000..f147622bf --- /dev/null +++ b/tests/ut_duisubdatastore/ut_duisubdatastore.cpp @@ -0,0 +1,122 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duisubdatastore.h" +#include "duisubdatastore.h" +#include "../stubs/mockdatastore.h" + +static const QString PREFIX("testPrefix"); + + +void Ut_DuiSubDataStore::initTestCase() +{ +} + +void Ut_DuiSubDataStore::cleanupTestCase() +{ +} + +void Ut_DuiSubDataStore::init() +{ + testBaseStore = new MockDataStore; + testableDataStore = new DuiSubDataStore(PREFIX, *testBaseStore); +} + +void Ut_DuiSubDataStore::cleanup() +{ + delete testableDataStore; + delete testBaseStore; +} + +void Ut_DuiSubDataStore::testPrefixSet() +{ + QCOMPARE(testableDataStore->prefix(), PREFIX); +} + +void Ut_DuiSubDataStore::testCreateValue() +{ + QCOMPARE(testBaseStore->contains(PREFIX + QString("foo")), false); + testableDataStore->createValue(QString("foo"), QString("bar1")); + QCOMPARE(testBaseStore->value(PREFIX + QString("foo")).toString(), QString("bar1")); +} + +void Ut_DuiSubDataStore::testSetValue() +{ + QVERIFY(!testableDataStore->setValue(QString("foo"), QString("bar"))); + QCOMPARE(testBaseStore->contains(PREFIX + QString("foo")), false); + + testableDataStore->createValue(QString("foo"), QString("bar1")); + QVERIFY(testableDataStore->setValue(QString("foo"), QString("bar2"))); + QCOMPARE(testBaseStore->value(PREFIX + QString("foo")).toString(), QString("bar2")); +} + +void Ut_DuiSubDataStore::testValue() +{ + QVERIFY(testableDataStore->createValue(QString("foo"), QString("bar"))); + QCOMPARE(testableDataStore->value(QString("foo")).toString(), QString("bar")); +} + +void Ut_DuiSubDataStore::testAllKeys() +{ + testableDataStore->createValue(QString("foo"), QString("bar")); + testableDataStore->createValue(QString("foo2"), QString("bar")); + QStringList keys = testableDataStore->allKeys(); + QCOMPARE(keys.size(), 2); + QVERIFY(keys.contains(QString("foo"))); + QVERIFY(keys.contains(QString("foo2"))); +} + +void Ut_DuiSubDataStore::testRemove() +{ + testableDataStore->createValue(QString("foo"), QString("bar")); + testableDataStore->remove(QString("foo")); + QCOMPARE(testBaseStore->contains(PREFIX + QString("foo")), false); +} + +void Ut_DuiSubDataStore::testClear() +{ + testableDataStore->createValue(QString("foo"), QString("bar")); + testableDataStore->createValue(QString("foo2"), QString("bar")); + testBaseStore->createValue(QString("foo4"), QString("bar")); + testableDataStore->clear(); + QCOMPARE(testBaseStore->contains(PREFIX + QString("foo")), false); + QCOMPARE(testBaseStore->contains(PREFIX + QString("foo2")), false); + QCOMPARE(testBaseStore->contains(QString("foo4")), true); +} + +void Ut_DuiSubDataStore::testContains() +{ + testableDataStore->createValue(QString("foo"), QString("bar")); + testBaseStore->createValue(QString("foo2"), QString("bar")); + QCOMPARE(testableDataStore->contains(QString("foo")), true); + QCOMPARE(testableDataStore->contains(QString("foo2")), false); +} + +void Ut_DuiSubDataStore::testValueChangedSignal() +{ + QSignalSpy spy(testableDataStore, SIGNAL(valueChanged(QString, QVariant))); + + testBaseStore->createValue(QString("foo"), QString("bar")); + QCOMPARE(spy.count(), 0); + + testBaseStore->createValue(PREFIX + QString("foo"), QString("bar")); + QCOMPARE(spy.count(), 1); +} + +QTEST_APPLESS_MAIN(Ut_DuiSubDataStore) diff --git a/tests/ut_duisubdatastore/ut_duisubdatastore.h b/tests/ut_duisubdatastore/ut_duisubdatastore.h new file mode 100644 index 000000000..70da890a9 --- /dev/null +++ b/tests/ut_duisubdatastore/ut_duisubdatastore.h @@ -0,0 +1,53 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUISUBDATASTORE_H +#define UT_DUISUBDATASTORE_H + +#include +#include + +class DuiDataStore; +class DuiSubDataStore; + +class Ut_DuiSubDataStore : public QObject +{ + Q_OBJECT + + DuiDataStore *testBaseStore; + DuiSubDataStore *testableDataStore; + +private slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + + void testPrefixSet(); + void testCreateValue(); + void testSetValue(); + void testValue(); + void testAllKeys(); + void testRemove(); + void testClear(); + void testContains(); + void testValueChangedSignal(); +}; + +#endif // UT_DUISUBDATASTORE_H diff --git a/tests/ut_duisubdatastore/ut_duisubdatastore.pro b/tests/ut_duisubdatastore/ut_duisubdatastore.pro new file mode 100644 index 000000000..3f2c3b453 --- /dev/null +++ b/tests/ut_duisubdatastore/ut_duisubdatastore.pro @@ -0,0 +1,11 @@ +include(../common_top.pri) +TARGET = ut_duisubdatastore +INCLUDEPATH += $$DUISRCDIR/mashup/appletcommunication $$DUISRCDIR/mashup/appletinterface $$DUISRCDIR/mashup/mashup + +SOURCES += \ + ut_duisubdatastore.cpp \ + +HEADERS += \ + ut_duisubdatastore.h \ + +include(../common_bot.pri) diff --git a/tests/ut_duitextedit/.gitignore b/tests/ut_duitextedit/.gitignore new file mode 100644 index 000000000..2eab32383 --- /dev/null +++ b/tests/ut_duitextedit/.gitignore @@ -0,0 +1 @@ +ut_duitextedit diff --git a/tests/ut_duitextedit/ut_duitextedit.cpp b/tests/ut_duitextedit/ut_duitextedit.cpp new file mode 100644 index 000000000..1c0b3c2a2 --- /dev/null +++ b/tests/ut_duitextedit/ut_duitextedit.cpp @@ -0,0 +1,1466 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duitextedit.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +//TODO:using other way instead of using relative paths +#include "../../src/widgets/duitextedit_p.h" + + +Q_DECLARE_METATYPE(Dui::TextContentType); +Q_DECLARE_METATYPE(Qt::InputMethodHints); + +const QString Ut_DuiTextEdit::testString = QString("jallajalla"); + +Q_DECLARE_METATYPE(DuiTextEditModel::LineMode); + +class ReplacerValidator : public QValidator +{ +public: + ReplacerValidator() : QValidator(0) {} + virtual ~ReplacerValidator() {} + + virtual State validate(QString &input, int &pos) const { + Q_UNUSED(pos) + input.replace(QChar('a'), QChar('b')); + return QValidator::Acceptable; + } +}; + + + + +/*! + * Called once before the first testcase is run. + */ +void Ut_DuiTextEdit::initTestCase() +{ + static int dummyArgc = 1; + static char *dummyArgv[1] = { (char *) "./ut_duitextedit" }; + + // prevent loading of duiinputcontext because we don't need it + DuiApplication::setLoadDuiInputContext(false); + + m_app = new DuiApplication(dummyArgc, dummyArgv); + m_appWindow = new DuiApplicationWindow; + QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8")); + // contains valid strings which should be stored by widget as they are + validStrings << "normal" << "normal with spaces" << "specials: !@#$%^&*()_+=-[]{}" + << "A string that is probably too long to fit to one line and needs to be wrapped or scrolled."; + // TODO: Invent more test strings +} + + +/*! + * Called once after the last testcase has finished. + */ +void Ut_DuiTextEdit::cleanupTestCase() +{ + delete m_appWindow; + m_appWindow = 0; + delete m_app; + m_app = 0; +} + + +/*! + * Called before each testcase. + */ +void Ut_DuiTextEdit::init() +{ + m_subject = new DuiTextEdit(DuiTextEditModel::MultiLine, ""); +} + + +/*! + * Called after each testcase. + */ +void Ut_DuiTextEdit::cleanup() +{ + delete m_subject; + m_subject = 0; +} + + +/*! + * Helper function for testSingleLineKeyPressEvent. + * Makes sure that given key press event has no effect on widget. + */ +void Ut_DuiTextEdit::confirmKeyEventIgnored(DuiTextEdit *subject, int key) +{ + subject->setText(testString); + QSignalSpy textChangedSpy(subject, SIGNAL(textChanged())); + int startCursorPos = subject->cursorPosition(); + + // Send event + QKeyEvent *event = new QKeyEvent(QEvent::KeyPress, key, 0, QString()); + subject->keyPressEvent(event); + delete event; + + // Check that text was not changed and cursor has not moved + QCOMPARE(textChangedSpy.count(), 0); + QString text = subject->text(); + QCOMPARE(text, testString); + QCOMPARE(startCursorPos, subject->cursorPosition()); +} + + +/*! + * Helper function for testConstraints. + * Inserts input string by simulating key press for reach character and checks + * that the result matches expectedOutput. + */ +void Ut_DuiTextEdit::constraintTest(DuiTextEdit *subject, const QString &input, + const QString &expectedOutput) +{ + subject->setText(QString()); + for (int i = 0; i < input.size(); i++) { + QString character = QString(input.at(i)); + QKeyEvent *event = new QKeyEvent(QEvent::KeyPress, 0, 0, character); + subject->keyPressEvent(event); + delete event; + } + + qDebug() << "In:" << input << "Out:" << subject->text() << "expected:" << expectedOutput; + QCOMPARE(subject->text(), expectedOutput); +} + + +/*! + * Test text setting. + * Sets various strings and confirms that they are set correctly. + */ +void Ut_DuiTextEdit::testSetText() +{ + QTextDocument *document = m_subject->document(); + QSignalSpy mySpy(document, SIGNAL(contentsChanged())); + QSignalSpy mySpy2(m_subject, SIGNAL(textChanged())); + + for (int i = 0; i < validStrings.size(); i++) { + QString setText = validStrings.at(i); + m_subject->setText(setText); + QString getText = m_subject->text(); + + // Check that the signals were sent and texts match + QCOMPARE(mySpy.count(), (i + 1) * 2); //one to clear old second to set the new + QCOMPARE(mySpy2.count(), (i + 1)); + QCOMPARE(getText, setText); + } +} + + +/*! + * Test inserting text to widget + * inserts strings from test list to widget and to a test string and make sure + * that they match. + */ +void Ut_DuiTextEdit::testInsert() +{ + QTextDocument *document = m_subject->document(); + QSignalSpy mySpy(document, SIGNAL(contentsChanged())); + QSignalSpy mySpy2(m_subject, SIGNAL(textChanged())); + QSignalSpy copyAvailableSpy(m_subject, SIGNAL(copyAvailable(bool))); + + QString appendedString = QString(); + + for (int i = 0; i < validStrings.size(); i++) { + QString appendText = validStrings.at(i); + m_subject->insert(appendText); + appendedString.append(appendText); + QString getText = m_subject->text(); + + // Check that the signals were sent and texts match + QCOMPARE(mySpy.count(), (i + 1)); //one to clear old second to set the new + QCOMPARE(mySpy2.count(), (i + 1)); + QCOMPARE(getText, appendedString); + } + QVERIFY(copyAvailableSpy.count() == 0); + + m_subject->setText("1 2 3 4"); + m_subject->setSelection(1, 2, false); + m_subject->insert(""); + QCOMPARE(m_subject->text(), QString("1 3 4")); + QVERIFY(copyAvailableSpy.first().count() == 1); + QVERIFY(copyAvailableSpy.first().first().toBool() == true); + copyAvailableSpy.clear(); +} + + +/*! + * Test key press events. + * Checks that pressed keys appear on text. Contains separate tests for + * backspace and delete. + */ +void Ut_DuiTextEdit::testKeyPressEvent() +{ + // Test key press for keys 0-125 because only the characters that are visible are + // should be returned from the QTextDocument. + + for (int round = 0; round < 125; round++) { + QChar cRound(round); + switch (cRound.category()) { + // these cases cause problems + case QChar::Other_NotAssigned: + case QChar::Other_Control: + break; + + default: { + QString character = QString(cRound); + m_subject->setText(""); + QKeyEvent *event = new QKeyEvent(QEvent::KeyPress, round, 0, character); + m_subject->keyPressEvent(event); + delete event; + + QCOMPARE(m_subject->text().toUtf8(), character.toUtf8()); + } + break; + } + } + + + // test backspace + m_subject->setText("abcd"); + + QKeyEvent *event = new QKeyEvent(QEvent::KeyPress, Qt::Key_Backspace, 0, QString()); + m_subject->keyPressEvent(event); + delete event; + + QCOMPARE(m_subject->text(), QString("abc")); + + // test delete + m_subject->setCursorPosition(0); + event = new QKeyEvent(QEvent::KeyPress, Qt::Key_Delete, 0, QString()); + m_subject->keyPressEvent(event); + delete event; + + QCOMPARE(m_subject->text(), QString("bc")); + + event = new QKeyEvent(QEvent::KeyPress, Qt::Key_Backspace, 0, QString()); + m_subject->keyPressEvent(event); + delete event; + + //cursor at beginning, backspage key will do nothing + QCOMPARE(m_subject->text(), QString("bc")); +} + + +/*! + * Test that single line edit ignores return key and up/down arrows. + */ +void Ut_DuiTextEdit::testSingleLineKeyPressEvent() +{ + DuiTextEdit singleLine(DuiTextEditModel::SingleLine, ""); + + // Test line mode reading + DuiTextEditModel::LineMode mode = singleLine.lineMode(); + QCOMPARE(mode, DuiTextEditModel::SingleLine); + + confirmKeyEventIgnored(&singleLine, Qt::Key_Return); + confirmKeyEventIgnored(&singleLine, Qt::Key_Up); + confirmKeyEventIgnored(&singleLine, Qt::Key_Down); +} + +#include +/*! + * Test functionality when widget gains focus. + */ +void Ut_DuiTextEdit::testFocusInEvent() +{ + DuiApplicationPage *page = new DuiApplicationPage(); + DuiTextEdit *m_subject = new DuiTextEdit(DuiTextEditModel::MultiLine, ""); + + page->setCentralWidget(m_subject); + page->appearNow(); + + // Set up spies on gainedFocus and lostFocus signals + QSignalSpy spyGainedFocus(m_subject, SIGNAL(gainedFocus(Qt::FocusReason))); + QSignalSpy spyLostFocus(m_subject, SIGNAL(lostFocus(Qt::FocusReason))); + + // Perform test + QFocusEvent *focusEvent = new QFocusEvent(QEvent::FocusIn); + m_subject->focusInEvent(focusEvent); + delete focusEvent; + + // Check that the signals were emitted and their parameters were correct + QCOMPARE(spyGainedFocus.count(), 1); + QCOMPARE(spyLostFocus.count(), 0); +} + + +/*! + * Test functionality when widget loses focus. + */ +void Ut_DuiTextEdit::testFocusOutEvent() +{ + // Set up spies on gainedFocus and lostFocus signals + QSignalSpy spyGainedFocus(m_subject, SIGNAL(gainedFocus(Qt::FocusReason))); + QSignalSpy spyLostFocus(m_subject, SIGNAL(lostFocus(Qt::FocusReason))); + + // Perform test + QFocusEvent *focusEvent = new QFocusEvent(QEvent::FocusOut); + m_subject->focusOutEvent(focusEvent); + delete focusEvent; + + // Check that the signals were emitted and their parameters were correct + QCOMPARE(spyGainedFocus.count(), 0); + QCOMPARE(spyLostFocus.count(), 1); +} + + +/*! + * Test moving to pre-editing mode. + */ +void Ut_DuiTextEdit::testInputMethodEvent() +{ + QString testString2 = testString + '2'; + QSignalSpy spy(m_subject, SIGNAL(textChanged())); + QVERIFY(spy.isValid()); + + QInputMethodEvent *event = new QInputMethodEvent(testString, + QList()); + m_subject->inputMethodEvent(event); + delete event; + QCOMPARE(m_subject->text(), testString); + QCOMPARE(spy.count(), 1); + spy.clear(); + + // Confirm that widget moved to pre-editing mode + QVERIFY(m_subject->mode() == DuiTextEditModel::EditModeActive); + + event = new QInputMethodEvent; + event->setCommitString(testString2); + m_subject->inputMethodEvent(event); + delete event; + QCOMPARE(m_subject->text(), testString2); + QCOMPARE(spy.count(), 1); + spy.clear(); +} + + +/*! + * Test setting cursor position. + */ +void Ut_DuiTextEdit::testSetCursorPosition() +{ + m_subject->setText(testString); + + for (int i = 0; i < testString.count(); i++) { + m_subject->setCursorPosition(i); + QCOMPARE(m_subject->cursorPosition(), i); + } +} + + +// test that setTextCursor updates the state properly +void Ut_DuiTextEdit::testSetTextCursor() +{ + m_subject->setText(testString); + + QTextCursor cursor = m_subject->textCursor(); + cursor.setPosition(0); + cursor.setPosition(5, QTextCursor::KeepAnchor); + m_subject->setTextCursor(cursor); + + QCOMPARE(m_subject->mode(), DuiTextEditModel::EditModeSelect); + + cursor.setPosition(7); + m_subject->setTextCursor(cursor); + QCOMPARE(m_subject->mode(), DuiTextEditModel::EditModeBasic); +} + + +/*! + * Test functionality when Qt::TextEditable-flag is set and removed + */ +void Ut_DuiTextEdit::testTextInteractionFlags() +{ + // Set editable-flag + m_subject->setTextInteractionFlags(Qt::TextEditable); + + // Confirm that flag was set and focus policy set to ClickFocus + QCOMPARE(m_subject->textInteractionFlags(), Qt::TextEditable); + QCOMPARE(m_subject->focusPolicy(), Qt::ClickFocus); + + // Send event to set pre-edited text + QInputMethodEvent *event = new QInputMethodEvent(testString, + QList()); + m_subject->inputMethodEvent(event); + delete event; + + // Confirm that widget is now in pre-edit mode + QCOMPARE(m_subject->mode(), DuiTextEditModel::EditModeActive); + + // Remove editable-flag + m_subject->setTextInteractionFlags(0); + + // Confirm that flags were removed and policy set to NoFocus + QCOMPARE(m_subject->textInteractionFlags(), 0); + QCOMPARE(m_subject->focusPolicy(), Qt::NoFocus); + + // Confirm also that pre-edit mode was exited + QVERIFY(m_subject->mode() != DuiTextEditModel::EditModeActive); +} + + +void Ut_DuiTextEdit::testConstraints() +{ + DuiTextEdit singleLine(DuiTextEditModel::SingleLine, ""); + + // Test line mode reading + DuiTextEditModel::LineMode mode = singleLine.lineMode(); + QCOMPARE(mode, DuiTextEditModel::SingleLine); + + QString testInput("abcdABCD1234*/+-#[]{}()"); + + // Test free text (input should remain unchanged) + singleLine.setContentType(Dui::FreeTextContentType); + QCOMPARE(singleLine.contentType(), Dui::FreeTextContentType); + constraintTest(&singleLine, testInput, testInput); + + // Test numbers + singleLine.setContentType(Dui::NumberContentType); + QCOMPARE(singleLine.contentType(), Dui::NumberContentType); + constraintTest(&singleLine, testInput, "1234"); + + singleLine.setContentType(Dui::NumberContentType); + QCOMPARE(singleLine.contentType(), Dui::NumberContentType); + constraintTest(&singleLine, "+1234", "+1234"); + + singleLine.setContentType(Dui::NumberContentType); + QCOMPARE(singleLine.contentType(), Dui::NumberContentType); + constraintTest(&singleLine, "-1234", "-1234"); + + singleLine.setContentType(Dui::NumberContentType); + QCOMPARE(singleLine.contentType(), Dui::NumberContentType); + constraintTest(&singleLine, "+-1234", "+1234"); + + // Test phone number + singleLine.setContentType(Dui::PhoneNumberContentType); + QCOMPARE(singleLine.contentType(), Dui::PhoneNumberContentType); + constraintTest(&singleLine, testInput, "1234*/+-#()"); + + // Test email address + singleLine.setContentType(Dui::EmailContentType); + QCOMPARE(singleLine.contentType(), Dui::EmailContentType); + constraintTest(&singleLine, testInput, "abcdABCD1234*/+-#{}"); + + // Test URL address + // TODO: URL mode does not currently constrain anything + singleLine.setContentType(Dui::UrlContentType); + QCOMPARE(singleLine.contentType(), Dui::UrlContentType); + constraintTest(&singleLine, testInput, testInput); +} + + +void Ut_DuiTextEdit::testReadOnly() +{ + QString content = "ReadOnly"; + QString changedContent = "Not ReadOnly"; + QString appendedString = "append"; + m_subject->setText(content); + //test readonly + m_subject->setReadOnly(true); + QVERIFY(m_subject->isReadOnly() == true); + + // test backspace when readonly + QKeyEvent *event = new QKeyEvent(QEvent::KeyPress, Qt::Key_Backspace, 0, QString()); + m_subject->keyPressEvent(event); + delete event; + QCOMPARE(m_subject->text(), content); + + // test delete when readonly + m_subject->setCursorPosition(0); + event = new QKeyEvent(QEvent::KeyPress, Qt::Key_Delete, 0, QString()); + m_subject->keyPressEvent(event); + delete event; + QCOMPARE(m_subject->text(), content); + + + m_subject->setReadOnly(false); + QVERIFY(m_subject->isReadOnly() == false); + QVERIFY(m_subject->setText(changedContent) == true); + QCOMPARE(m_subject->text(), changedContent); + QVERIFY(m_subject->insert(appendedString) == true); + QCOMPARE(m_subject->text(), changedContent + appendedString); + + m_subject->setText(content); + // test backspace when not readonly + event = new QKeyEvent(QEvent::KeyPress, Qt::Key_Backspace, 0, QString()); + m_subject->keyPressEvent(event); + delete event; + QCOMPARE(m_subject->text(), QString("ReadOnl")); + + m_subject->setText(content); + // test delete when not readonly + m_subject->setCursorPosition(0); + event = new QKeyEvent(QEvent::KeyPress, Qt::Key_Delete, 0, QString()); + m_subject->keyPressEvent(event); + delete event; + QCOMPARE(m_subject->text(), QString("eadOnly")); +} + +void Ut_DuiTextEdit::testMaxLength_data() +{ + QTest::addColumn("lineMode"); + QTest::addColumn("maxLength"); + QTest::addColumn("text"); + + QString longText( + "This test checks that maxLength property of DuiTextEdit trims\n\n" + "the text as expected.\nasdfasdf\n\nasdfasd"); + DuiTextEditModel::LineMode lineModes[2] = {DuiTextEditModel::SingleLine, DuiTextEditModel::MultiLine}; + for (int i = 0; i < 2; ++i) { + QTest::newRow("too short") << lineModes[i] << -5 << longText; + QTest::newRow("zero") << lineModes[i] << 0 << longText; + QTest::newRow("short") << lineModes[i] << 5 << longText; + QTest::newRow("long") << lineModes[i] << (longText.length() - 5) << longText; + QTest::newRow("too long") << lineModes[i] << (longText.length() + 5) << longText; + } +} + +void Ut_DuiTextEdit::testMaxLength() +{ + QFETCH(DuiTextEditModel::LineMode, lineMode); + QFETCH(int, maxLength); + QFETCH(QString, text); + + const int initialMaxLength = m_subject->maxLength(); + + if (m_subject->lineMode() != lineMode) { + delete m_subject; + m_subject = new DuiTextEdit(lineMode); + } + + for (int i = 0; i < 3; ++i) { + m_subject->clear(); + m_subject->setMaxLength(initialMaxLength); + + QString expectedText = text; + + // Test in three different ways: + if (i == 0) { + // Set limitation afterwards. + m_subject->setText(text); + m_subject->setMaxLength(maxLength); + } else if (i == 1) { + // Set limitation prior setting text. + m_subject->setMaxLength(maxLength); + m_subject->setText(text); + } else { + // Check maxLength with insert(). + m_subject->setMaxLength(maxLength); + m_subject->setText(testString); // Set some initial diibadaaba text. + // Special case where text is inserted at the end. + m_subject->insert(text); + + expectedText.prepend(testString); + } + + // Mimic the filtering DuiTextEdit does for single-line edits. + if (lineMode == DuiTextEditModel::SingleLine) { + expectedText.replace(QChar('\n'), QChar(' ')); + } + + // If maxLength is negative, treat as if zero. + if (maxLength < 0) { + maxLength = 0; + } + + // Check that correct value was stored. + QCOMPARE(m_subject->maxLength(), maxLength); + + // This is what should happen to the text. + expectedText.truncate(maxLength); + + QCOMPARE(m_subject->text(), expectedText); + + // Length must always be equal or less than maxLength. + QVERIFY(m_subject->text().length() <= maxLength); + } +} + +/* +void Ut_DuiTextEdit::testFeedback() +{ + Qt::TextInteractionFlag testGiveFeedback[] = { + Qt::TextSelectableByMouse, + Qt::TextSelectableByKeyboard, + Qt::LinksAccessibleByMouse, + Qt::LinksAccessibleByKeyboard, + Qt::TextEditable, + Qt::TextEditorInteraction, + Qt::TextBrowserInteraction + }; + Qt::TextInteractionFlag testNoFeedback[] = { + Qt::NoTextInteraction + }; + + gDuiFeedbackPlayerStub->stubSetReturnValue( + "feedback", DuiFeedbackPlayerStub::RETURN_OBJECT); + DuiTextEdit edit1("", DuiTextEditModel::SingleLine); + int cursorPosition = 0; + QGraphicsSceneMouseEvent event; + + for (unsigned xx = 0; xx < sizeof(testGiveFeedback) / sizeof(testGiveFeedback[0]); ++xx) + { + edit1.setTextInteractionFlags(testGiveFeedback[xx]); + gDuiFeedbackStub->stubReset(); + edit1.handleMousePress(cursorPosition, &event); + QCOMPARE(gDuiFeedbackStub->stubCallCount("play"), 1); + + edit1.handleMouseRelease(cursorPosition, &event); + QCOMPARE(gDuiFeedbackStub->stubCallCount("play"), 2); + } + + for (unsigned xx = 0; xx < sizeof(testNoFeedback) / sizeof(testNoFeedback[0]); ++xx) + { + edit1.setTextInteractionFlags(testNoFeedback[xx]); + gDuiFeedbackStub->stubReset(); + edit1.handleMousePress(cursorPosition, &event); + QVERIFY(gDuiFeedbackStub->stubCallCount("play") == 0); + + edit1.handleMouseRelease(cursorPosition, &event); + QVERIFY(gDuiFeedbackStub->stubCallCount("play") == 0); + } +} +*/ + + +void Ut_DuiTextEdit::testBadData() +{ + qDebug() << "Check of line mode"; + + //check single line with multi line input + DuiTextEdit *subject = new DuiTextEdit(DuiTextEditModel::SingleLine, ""); + subject->setText("I \n have \n more columns"); + QVERIFY(subject->lineMode() == DuiTextEditModel::SingleLine); + qDebug() << subject->text(); + + // Bug 1: Single line not handling \n properly + // QVERIFY(subject->text() == "I"); + + // check multi line with multi line input + delete subject; + subject = new DuiTextEdit(DuiTextEditModel::MultiLine, ""); + subject->setText("I \n have \n more columns"); + + QVERIFY(subject->lineMode() == DuiTextEditModel::MultiLine); + QVERIFY(subject->text() == "I \n have \n more columns"); + + // check of TextInteractionFlags + qDebug() << "Check of text interaction flags"; + delete subject; + subject = new DuiTextEdit(DuiTextEditModel::SingleLine, ""); + QVERIFY(subject->textInteractionFlags() == Qt::TextEditorInteraction); + subject->setTextInteractionFlags(Qt::NoTextInteraction); + QVERIFY(subject->textInteractionFlags() == Qt::NoTextInteraction); + QList listOfFlags; + listOfFlags << (Qt::TextEditorInteraction | Qt::TextEditable | Qt::TextSelectableByMouse + | Qt::TextSelectableByKeyboard); + listOfFlags << (Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard); + listOfFlags << (Qt::NoTextInteraction | Qt::TextSelectableByKeyboard); + + for (int i = 0; i < listOfFlags.size(); ++i) { + subject->setTextInteractionFlags(listOfFlags.at(i)); + + if (subject->textInteractionFlags() != listOfFlags.at(i)) { + qDebug() << "teststep: " << i << " is wrong!"; + } + + QVERIFY(subject->textInteractionFlags() == listOfFlags.at(i)); + } + + delete subject; + + // check of constraints + qDebug() << "check of constraints"; + subject = new DuiTextEdit(DuiTextEditModel::SingleLine, ""); + + // Number + qDebug() << " number"; + QStringList listNumber, listNumberRes; + subject->setContentType(Dui::NumberContentType); + listNumber << "25" << "99a99" << "88\t88" << "1234567890+-*/" << "noNumberHere" << "110"; + listNumberRes << "25" << "25" << "25" << "25" << "25" << "110"; + + for (int i = 0; i < listNumber.size(); ++i) { + subject->setText(listNumber.at(i)); + + if (subject->text() != listNumberRes.at(i)) { + qDebug() << "teststep (number): " << i << " is wrong!"; + qDebug() << "In:" << listNumber.at(i) << "Out:" << subject->text() + << "expected:" << listNumberRes.at(i); + } + + // Bug #2 Constraints can't handle setting whole strings. If invalid text is set, + // old text is deleted. + // FIXME: DISABLED NOW - not sure if want to have content checking on setText() + //QVERIFY(subject->text() == listNumberRes.at(i)); + //QVERIFY(subject->contentType() == Dui::NumberContentType); + } + + listNumber.clear(); + listNumberRes.clear(); + subject->setText(""); + + // PhoneNumber + qDebug() << " phone number"; + subject->setContentType(Dui::PhoneNumberContentType); + listNumber << "0049618265231" << "++49618275667" << "0180-667676-999-0#12" << "112" + << "45 99 99 99 66 77"; + listNumberRes << "0049618265231" << "0049618265231" << "0180-667676-999-0#12" << "112" + << "459999996677"; + + for (int i = 0; i < listNumber.size(); ++i) { + subject->setText(listNumber.at(i)); + if (subject->text() == listNumber.at(i)) { + qDebug() << "teststep (phone number): " << i << " is wrong!"; + } + // Bug: DuiTextEdit don't check if Phone Number is valid + // QCOMPARE(subject->text(), listNumberRes.at(i)); + // QVERIFY(subject->contentType() == DuiTextEditModel::PhoneNumber); + } + + listNumber.clear(); + listNumberRes.clear(); + subject->setText(""); + + //email + //qDebug() << " e-mail"; + QStringList listString, listStringRes; + + subject->setContentType(Dui::EmailContentType); + listString << "mail@mailme.com" << "coolMail@@nowhere.com" << "mailwithoutAdAndPoint" + << "myMail@mailme.com" << "testmail@abc..com" << "5999@888.com" + << "björnsmail@gmx.net"; + listStringRes << "mail@mailme.com" << "mail@mailme.com" << "" << "myMail@mailme.com" + << "testmail@abc.com" << "5999@888.com" << "björnsmail@gmx.net"; + + for (int i = 0; i < listString.size(); ++i) { + subject->setText(listString.at(i)); + if (subject->text() == listString.at(i)) { + qDebug() << "teststep (e-mail): " << i << " is wrong!"; + } + // Bug: DuiTextEdit don't check if E-Mail is valid + // QCOMPARE(subject->text(), listStringRes.at(i)); + // QVERIFY(subject->contentType() == DuiTextEditModel::Email); + } + + listString.clear(); + listStringRes.clear(); + subject->setText(""); + + // url + qDebug() << " url"; + subject->setContentType(Dui::EmailContentType); + listString << "www.heise.de" << "UrlwithoutAdAndPoint" + << "http://www.google.de/search?hl=de&q=nokia&btnG=Google-Suche&meta=" + << "httx:\\www..stern..de" << "www.888.com"; + listStringRes << "www.heise.de" << "www.heise.de" + << "http://www.google.de/search?hl=de&q=nokia&btnG=Google-Suche&meta=" + << "http://www.google.de/search?hl=de&q=nokia&btnG=Google-Suche&meta=" + << "www.888.com"; + + for (int i = 0 ; i < listString.size(); ++i) { + subject->setText(listString.at(i)); + + if (subject->text() == listString.at(i)) { + qDebug() << "teststep (url): " << i << " is wrong!"; + } + // Bug: DuiTextEdit don't check if URL is valid + // QCOMPARE(subject->text(), listStringRes.at(i)); + // QVERIFY(subject->contentType() == DuiTextEditModel::Email); + } + + listString.clear(); + listStringRes.clear(); + subject->setText(""); + + // check on setCursor + qDebug() << "check setCursor"; + QList numbers, numbersRes; + numbers << 0 << -900 << 0 << 1 << -5 << 99 << 37000 << 36 << 22 << -12; + numbersRes << 0 << 0 << 0 << 1 << 1 << 1 << 1 << 36 << 22 << 22; + subject->setContentType(Dui::FreeTextContentType); + subject->setText("A simple teststring, nothing useful."); + // FIXME: How can I check the set cursor?} + + for (int i = 0; i < numbers.size(); ++i) { + subject->setCursorPosition(numbers.at(i)); + // qDebug() << "In:" << numbers.at(i) << "Out:" << subject->cursorPosition() + // << "expected:" << numbersRes.at(i); + QCOMPARE(subject->cursorPosition(), numbersRes.at(i)); + } +} + + +void Ut_DuiTextEdit::testSelection() +{ + Qt::TextInteractionFlag testSelection[] = { + Qt::TextEditorInteraction, + }; + + Qt::TextInteractionFlag testNoSelection[] = { + Qt::NoTextInteraction, + Qt::LinksAccessibleByMouse, + Qt::LinksAccessibleByKeyboard, + }; + + QSignalSpy copyAvailableSpy(m_subject, SIGNAL(copyAvailable(bool))); + const char *text = "a bcd e"; + m_subject->setText(text); + + m_subject->setSelection(0, 1, true); + QVERIFY(m_subject->text() == text); + QVERIFY(m_subject->mode() == DuiTextEditModel::EditModeSelect); + //verify if setSelection emitted copyAvailable(true) + QVERIFY(copyAvailableSpy.count() == 1); + QVERIFY(copyAvailableSpy.first().count() == 1); + QVERIFY(copyAvailableSpy.first().first().toBool() == true); + copyAvailableSpy.clear(); + + m_subject->deselect(); + QVERIFY(m_subject->text() == text); + QVERIFY(m_subject->mode() == DuiTextEditModel::EditModeBasic); + QVERIFY(copyAvailableSpy.count() == 1); + QVERIFY(copyAvailableSpy.first().count() == 1); + QVERIFY(copyAvailableSpy.first().first().toBool() == false); + copyAvailableSpy.clear(); + + for (unsigned n = 0; n < sizeof(testSelection) / sizeof(testSelection[0]); ++n) { + qDebug() << n << testSelection[n]; + + m_subject->setTextInteractionFlags(testSelection[n]); + m_subject->setText(text); + m_subject->setSelection(1, 1, true); + + QSignalSpy updatedSpy(m_subject, SIGNAL(selectionChanged())); + m_subject->setSelection(2, 1, true); + QCOMPARE(updatedSpy.count(), 1); + QVERIFY(m_subject->mode() == DuiTextEditModel::EditModeSelect); + QVERIFY(copyAvailableSpy.count() == 1); + QVERIFY(copyAvailableSpy.first().count() == 1); + QVERIFY(copyAvailableSpy.first().first().toBool() == true); + copyAvailableSpy.clear(); + + QKeyEvent *event = new QKeyEvent(QEvent::KeyPress, Qt::Key_Backspace, 0, QString()); + m_subject->keyPressEvent(event); + delete event; + + QCOMPARE(m_subject->text(), QString("a e")); + QCOMPARE(updatedSpy.count(), 2); + QVERIFY(m_subject->mode() == DuiTextEditModel::EditModeBasic); + QVERIFY(copyAvailableSpy.count() == 1); + QVERIFY(copyAvailableSpy.first().count() == 1); + QVERIFY(copyAvailableSpy.first().first().toBool() == false); + copyAvailableSpy.clear(); + } + + for (unsigned n = 0; n < sizeof(testNoSelection) / sizeof(testNoSelection[0]); ++n) { + qDebug() << n << testNoSelection[n]; + m_subject->setTextInteractionFlags(testNoSelection[n]); + m_subject->setText(text); + m_subject->setSelection(2, 1, true); + + QKeyEvent *event = new QKeyEvent(QEvent::KeyPress, Qt::Key_Backspace, 0, QString()); + m_subject->keyPressEvent(event); + delete event; + QCOMPARE(m_subject->text(), QString(text)); + QCOMPARE(copyAvailableSpy.count(), 0); + + QVERIFY(m_subject->mode() == DuiTextEditModel::EditModeBasic); + } + + bool success = m_subject->setText(text); + QCOMPARE(success, true); + m_subject->setTextInteractionFlags(Qt::TextEditorInteraction); + m_subject->setSelection(1, 1, true); + + copyAvailableSpy.clear(); // ignore all previuos signals + + m_subject->setCursorPosition(0); + QCOMPARE(m_subject->text(), QString(text)); + QVERIFY(m_subject->mode() == DuiTextEditModel::EditModeBasic); + // setCursorPosition should emit signal copyAvailable(false) + // because text was deselected + QVERIFY(copyAvailableSpy.count() == 1); + QVERIFY(copyAvailableSpy.first().count() == 1); + QVERIFY(copyAvailableSpy.first().first().toBool() == false); + copyAvailableSpy.clear(); + + m_subject->setSelection(1, 1, true); + copyAvailableSpy.clear(); + m_subject->setText(text); + QCOMPARE(m_subject->text(), QString(text)); + QVERIFY(m_subject->mode() == DuiTextEditModel::EditModeBasic); + // setTest should emit signal copyAvailable(false) + // because text was deselected + QVERIFY(copyAvailableSpy.count() == 1); + QVERIFY(copyAvailableSpy.first().count() == 1); + QVERIFY(copyAvailableSpy.first().first().toBool() == false); + copyAvailableSpy.clear(); + + m_subject->setText(text); + QCOMPARE(m_subject->text(), QString(text)); + QVERIFY(m_subject->mode() == DuiTextEditModel::EditModeBasic); + // setText should not emit signal copyAvailable because + // there was no selection + QVERIFY(copyAvailableSpy.count() == 0); +} + + +void Ut_DuiTextEdit::testAutoSelection() +{ + Qt::TextInteractionFlag testSelection[] = { + Qt::TextSelectableByMouse, + Qt::TextSelectableByKeyboard, + Qt::TextEditorInteraction, + Qt::TextBrowserInteraction, + }; + Qt::TextInteractionFlag testNoSelection[] = { + Qt::NoTextInteraction, + Qt::LinksAccessibleByMouse, + Qt::LinksAccessibleByKeyboard, + }; + + for (unsigned n = 0; n < sizeof(testSelection) / sizeof(testSelection[0]); ++n) { + qDebug() << n << testSelection[n]; + m_subject->setTextInteractionFlags(testSelection[n]); + + m_subject->setAutoSelectionEnabled(false); + QVERIFY(m_subject->isAutoSelectionEnabled() == false); + + m_subject->setAutoSelectionEnabled(true); + QVERIFY(m_subject->isAutoSelectionEnabled() == true); + } + + for (unsigned n = 0; n < sizeof(testNoSelection) / sizeof(testNoSelection[0]); ++n) { + qDebug() << n << testNoSelection[n]; + m_subject->setTextInteractionFlags(testNoSelection[n]); + m_subject->setAutoSelectionEnabled(false); + QVERIFY(m_subject->isAutoSelectionEnabled() == false); + m_subject->setAutoSelectionEnabled(true); + QVERIFY(m_subject->isAutoSelectionEnabled() == false); + } +} + + +void Ut_DuiTextEdit::testPrompt() +{ + DuiWidgetModel *model = 0; + + QStringList prompts; + QList expectedSignals; + + QList contentTypes; //all possible content types + + contentTypes << Dui::FreeTextContentType << Dui::NumberContentType + << Dui::PhoneNumberContentType << Dui::EmailContentType + << Dui::UrlContentType << Dui::CustomContentType; + + prompts + << "Some text" + << "Some text" + << QString() + << QString() + << QString(1000, 'A') //very long prompt + << "1234567890" + << QString("Öylätti") + << QString("Äänekoski") + << QString("Åbo") + << "Multi\nline\nprompt" + << "Multi\nline\nprompt"; + + foreach(Dui::TextContentType contentType, contentTypes) { + delete m_subject; + m_subject = new DuiTextEdit(DuiTextEditModel::MultiLine, ""); + m_subject->setContentType(contentType); + + model = m_subject->model(); + QVERIFY(model != 0); + //Verify default prompt + QVERIFY(m_subject->prompt() == QString()); + + //qDebug() << "Multi line text entry; content type:" << contentType; + for (int n = 0; n < prompts.count(); ++n) { + //qDebug() << "Test step #" << n << "prompt:" << prompts.at(n); + + m_subject->setPrompt(prompts.at(n)); + QVERIFY(m_subject->prompt() == prompts.at(n)); + } + } + + //test single line editor + prompts.removeLast(); + prompts.removeLast(); + + foreach(Dui::TextContentType contentType, contentTypes) { + delete m_subject; + m_subject = new DuiTextEdit(DuiTextEditModel::SingleLine, ""); + m_subject->setContentType(contentType); + + model = m_subject->model(); + QVERIFY(model != 0); + //Verify default prompt + QVERIFY(m_subject->prompt() == QString()); + + //qDebug() << "Single line text entry; content type:" << contentType; + for (int n = 0; n < prompts.count(); ++n) { + //qDebug() << "Test step #" << n << "prompt:" << prompts.at(n); + + m_subject->setPrompt(prompts.at(n)); + QVERIFY(m_subject->prompt() == prompts.at(n)); + } + } +} + +void Ut_DuiTextEdit::testValidator() +{ + QSignalSpy copyAvailableSpy(m_subject, SIGNAL(copyAvailable(bool))); + // first test validation with builtin validator + ReplacerValidator replacer; + m_subject->setValidator(&replacer); + + QInputMethodEvent event; + event.setCommitString(QString("aaa")); + + m_subject->inputMethodEvent(&event); + QCOMPARE(m_subject->textCursor().position(), 3); + QCOMPARE(m_subject->text(), QString("bbb")); + + // second test: + qDebug() << "Starting A Line test"; + m_subject->setText(""); + QRegExp aline("a*\n"); + QRegExpValidator aLineValidator(aline, 0); + m_subject->setValidator(&aLineValidator); + event.setCommitString("aaa\n"); + m_subject->inputMethodEvent(&event); + QCOMPARE(m_subject->textCursor().position(), 4); + QCOMPARE(m_subject->text(), QString("aaa\n")); + + // add more text that shouldn't be allowed + event.setCommitString("bcd\n"); + m_subject->inputMethodEvent(&event); + QCOMPARE(m_subject->text(), QString("aaa\n\n")); + + // test that only correct parts are inserted when partly invalid content is passed on selection + m_subject->selectAll(); + QVERIFY(copyAvailableSpy.count() == 1); + QVERIFY(copyAvailableSpy.first().count() == 1); + QVERIFY(copyAvailableSpy.first().first().toBool() == true); + copyAvailableSpy.clear(); + event.setCommitString("aa\nabcd\n\n"); + m_subject->inputMethodEvent(&event); + QCOMPARE(m_subject->text(), QString("aa\n\n\n")); + QVERIFY(copyAvailableSpy.count() == 1); + QVERIFY(copyAvailableSpy.first().count() == 1); + QVERIFY(copyAvailableSpy.first().first().toBool() == false); + copyAvailableSpy.clear(); + + // test that nothing happens on invalid insertion with selection + m_subject->selectAll(); + event.setCommitString("abcd"); + m_subject->inputMethodEvent(&event); + QCOMPARE(m_subject->text(), QString("aa\n\n\n")); + + // test that selection is replaced with insertion on valid insertion + m_subject->selectAll(); + event.setCommitString("aaaaa"); + m_subject->inputMethodEvent(&event); + QCOMPARE(m_subject->text(), QString("aaaaa")); + +} + + +void Ut_DuiTextEdit::testClear() +{ + // test that clear() works. first set content and then test that after clear the state has reset + m_subject->setText("AsdfAsdfasD sdfdf asdf "); + m_subject->setSelection(3, 8, false); + m_subject->clear(); + QCOMPARE(m_subject->cursorPosition(), 0); + QCOMPARE(m_subject->mode(), DuiTextEditModel::EditModeBasic); + QCOMPARE(m_subject->text(), QString("")); +} + + +void Ut_DuiTextEdit::testCursorPositionChanged() +{ + QSignalSpy cursorSpy(m_subject, SIGNAL(cursorPositionChanged())); + QSignalSpy copyAvailableSpy(m_subject, SIGNAL(copyAvailable(bool))); + int expectedCallCount = 0; + + // test that setting text moves cursor to back + m_subject->setText("asdf"); + expectedCallCount++; + QCOMPARE(cursorSpy.count(), expectedCallCount); + + // backspace moves cursor + QKeyEvent event(QEvent::KeyPress, Qt::Key_Backspace, 0, QString()); + m_subject->keyPressEvent(&event); + expectedCallCount++; + QCOMPARE(cursorSpy.count(), expectedCallCount); + + // button press moves + event = QKeyEvent(QEvent::KeyPress, 0, 0, QString("a")); + m_subject->keyPressEvent(&event); + expectedCallCount++; + QCOMPARE(cursorSpy.count(), expectedCallCount); + + // left key moves + event = QKeyEvent(QEvent::KeyPress, Qt::Key_Left, 0, QString()); + m_subject->keyPressEvent(&event); + expectedCallCount++; + QCOMPARE(cursorSpy.count(), expectedCallCount); + + // inputmethodevent moves + QInputMethodEvent imEvent(QString("abcd"), QList()); + m_subject->inputMethodEvent(&imEvent); + expectedCallCount++; + QCOMPARE(cursorSpy.count(), expectedCallCount); + QVERIFY(copyAvailableSpy.count() == 0); +} + + +void Ut_DuiTextEdit::testCopyPaste() +{ + QClipboard *clipboard = QApplication::clipboard(); + QVERIFY(clipboard != 0); + + QString text("some text"); + QString text2("123 456"); + clipboard->setText(text); + m_subject->setText(text2); + //clipboard content should not be changed if nothing was selected + m_subject->copy(); + QCOMPARE(clipboard->text(), text); + + m_subject->setSelection(1, 1, true); + //something should be copied + m_subject->copy(); + QCOMPARE(clipboard->text(), QString("123")); + + m_subject->selectAll(); + clipboard->setText(text); + //whole text should be replaced + m_subject->paste(); + QCOMPARE(m_subject->text(), text); + + //new text should be appended to existing + m_subject->paste(); + QCOMPARE(m_subject->text(), text + text); + + m_subject->setText(text); + m_subject->selectAll(); + clipboard->setText(""); + //nothing should be changed + m_subject->paste(); + QCOMPARE(m_subject->text(), text); + + //verify behavior of read-only text entry + m_subject->setText(text2); + m_subject->setReadOnly(true); + + clipboard->setText(text); + //clipboard content should not be changed if nothing was selected + m_subject->copy(); + QCOMPARE(clipboard->text(), text); + + m_subject->setSelection(1, 1, true); + //something should be copied + m_subject->copy(); + QCOMPARE(clipboard->text(), QString("123")); + + //paste should not modify read-only text entry + m_subject->selectAll(); + clipboard->setText(text); + m_subject->paste(); + QCOMPARE(m_subject->text(), text2); + + m_subject->paste(); + QCOMPARE(m_subject->text(), text2); + + m_subject->setText(text); + m_subject->selectAll(); + clipboard->setText(""); + m_subject->paste(); + QCOMPARE(m_subject->text(), text); + + // text copying should not be possible with masked text entry + m_subject->setEchoMode(DuiTextEditModel::Password); + m_subject->selectAll(); + m_subject->copy(); + QCOMPARE(clipboard->text(), QString()); + + //test copy/paste via keyboard events + QKeyEvent copy(QEvent::KeyPress, Qt::Key_C, Qt::ControlModifier, QChar('\3')); + QKeyEvent paste(QEvent::KeyPress, Qt::Key_V, Qt::ControlModifier, QChar('\22')); + + m_subject->setEchoMode(DuiTextEditModel::Normal); + m_subject->setReadOnly(false); + + m_subject->setText(text); + m_subject->selectAll(); + clipboard->setText(""); + m_subject->keyPressEvent(©); + QCOMPARE(m_subject->text(), text); + QCOMPARE(clipboard->text(), text); + + m_subject->clear(); + m_subject->keyPressEvent(&paste); + QCOMPARE(m_subject->text(), text); + QCOMPARE(clipboard->text(), text); + + //copy/paste via keyboard event is not allwed if text interaction is disabled + m_subject->setText(text); + m_subject->selectAll(); + m_subject->setTextInteractionFlags(Qt::NoTextInteraction); + clipboard->setText(""); + m_subject->keyPressEvent(©); + QCOMPARE(m_subject->text(), text); + QCOMPARE(clipboard->text(), QString()); + + m_subject->clear(); + clipboard->setText(text); + m_subject->keyPressEvent(&paste); + QCOMPARE(m_subject->text(), QString()); + QCOMPARE(clipboard->text(), text); +} + +void Ut_DuiTextEdit::testPasteOnPreedit() +{ + QString text("some text"); + QInputMethodEvent event(text, QList()); + QClipboard *clipboard = QApplication::clipboard(); + QVERIFY(clipboard != 0); + + m_subject->inputMethodEvent(&event); + clipboard->setText(text); + m_subject->paste(); + QCOMPARE(m_subject->text(), text + text); +} + +void Ut_DuiTextEdit::testInputMethodQuery() +{ + QString text = "123"; + Qt::InputMethodQuery query = Qt::ImCurrentSelection; + QVariant queryResult = m_subject->inputMethodQuery(query); + QVERIFY(queryResult.isValid() == true); + QVERIFY(queryResult.toString().isEmpty() == true); + + m_subject->setText(text); + m_subject->selectAll(); + + query = Qt::ImCurrentSelection; + queryResult = m_subject->inputMethodQuery(query); + QVERIFY(queryResult.isValid() == true); + QCOMPARE(queryResult.toString(), text); + + query = static_cast(Dui::VisualizationPriorityQuery); + queryResult = m_subject->inputMethodQuery(query); + QVERIFY(queryResult.isValid() == true); + QVERIFY(queryResult.toString().isEmpty() == false); + + const QString toolbar("testToolbar"); + m_subject->attachToolbar(toolbar); + query = static_cast(Dui::InputMethodToolbarQuery); + queryResult = m_subject->inputMethodQuery(query); + QVERIFY(queryResult.isValid() == true); + QCOMPARE(queryResult.toString(), toolbar); +} + +void Ut_DuiTextEdit::testConstrainedPaste() +{ + //some characters should be filtered out + //if validator was assigned for text editor + + QClipboard *clipboard = QApplication::clipboard(); + QVERIFY(clipboard != 0); + + //test for numbers + clipboard->setText("+123 456q"); + m_subject->setContentType(Dui::NumberContentType); + + m_subject->paste(); + QCOMPARE(m_subject->text(), QString("+123456")); + + m_subject->clear(); + //test for phone numbers + m_subject->setContentType(Dui::PhoneNumberContentType); + clipboard->setText("+*123!45w6pq"); + m_subject->paste(); + QCOMPARE(m_subject->text(), QString("+*12345w6p")); +} + + +void Ut_DuiTextEdit::testSignChange_data() +{ + QTest::addColumn("contentType"); + QTest::addColumn("text"); + QTest::addColumn("expectedText"); + + QTest::newRow("free") << Dui::FreeTextContentType + << QString() << QString(); + + QTest::newRow("insertSign") << Dui::NumberContentType + << QString() << QString("-"); + + QTest::newRow("replacePlusWithMinus") << Dui::NumberContentType + << QString("+") << QString("-"); + + QTest::newRow("replaceMinusWithPlus") << Dui::NumberContentType + << QString("-") << QString("+"); + + QTest::newRow("insertSignNumber") << Dui::NumberContentType + << QString("3.01") << QString("-3.01"); + + QTest::newRow("replacePlusWithMinusNumber") << Dui::NumberContentType + << QString("+9.99") << QString("-9.99"); + + QTest::newRow("replaceMinusWithPlusNumber") << Dui::NumberContentType + << QString("-1") << QString("+1"); +} + +void Ut_DuiTextEdit::testSignChange() +{ + QFETCH(Dui::TextContentType, contentType); + QFETCH(QString, text); + QFETCH(QString, expectedText); + + qDebug() << "contentType=" << contentType << "text=" << text + << "expectedText=" << expectedText; + QKeyEvent metaPlus(QEvent::KeyPress, Qt::Key_plusminus, Qt::MetaModifier, QString()); + + m_subject->setContentType(contentType); + m_subject->insert(text); + QCOMPARE(m_subject->text(), text); + m_subject->keyPressEvent(&metaPlus); + QCOMPARE(m_subject->text(), expectedText); +} + +void Ut_DuiTextEdit::testSetContentType_data() +{ + QTest::addColumn("contentType"); + QTest::addColumn("expectedHints"); + + QTest::newRow("free") << Dui::FreeTextContentType + << Qt::InputMethodHints(Qt::ImhNone); + + QTest::newRow("number") << Dui::NumberContentType + << Qt::InputMethodHints(Qt::ImhFormattedNumbersOnly); + + QTest::newRow("phone") << Dui::PhoneNumberContentType + << Qt::InputMethodHints(Qt::ImhDialableCharactersOnly); + + QTest::newRow("email") << Dui::EmailContentType + << Qt::InputMethodHints(Qt::ImhEmailCharactersOnly); + + QTest::newRow("url") << Dui::UrlContentType + << Qt::InputMethodHints(Qt::ImhUrlCharactersOnly); +} + +void Ut_DuiTextEdit::testSetContentType() +{ + QFETCH(Dui::TextContentType, contentType); + QFETCH(Qt::InputMethodHints, expectedHints); + + qDebug() << "contentType=" << contentType << "expectedHints=" << expectedHints; + + m_subject->setContentType(contentType); + QCOMPARE(int(m_subject->inputMethodHints() & Qt::ImhExclusiveInputMask), int(expectedHints)); +} + +void Ut_DuiTextEdit::testInputMethodHints() +{ + QVERIFY(m_subject->inputMethodHints() == Qt::ImhNone); + + m_subject->setEchoMode(DuiTextEditModel::Password); + QVERIFY(m_subject->inputMethodHints() & Qt::ImhHiddenText); + QVERIFY(m_subject->echoMode() == DuiTextEditModel::Password); + + m_subject->setInputMethodPredictionEnabled(false); + QVERIFY(m_subject->inputMethodHints() & Qt::ImhNoPredictiveText); + QVERIFY(m_subject->inputMethodPredictionEnabled() == false); + + m_subject->setInputMethodAutoCapitalizationEnabled(false); + QVERIFY(m_subject->inputMethodHints() & Qt::ImhNoAutoUppercase); + QVERIFY(m_subject->inputMethodAutoCapitalizationEnabled() == false); +} + +void Ut_DuiTextEdit::testAttachToolbar() +{ + m_subject->attachToolbar(""); + QVERIFY(m_subject->attachedToolbar().isEmpty()); + const QString toolbar("testToolbar"); + m_subject->attachToolbar(toolbar); + QCOMPARE(m_subject->attachedToolbar(), toolbar); +} + +void Ut_DuiTextEdit::testPasswordEchoOnEditClearing() +{ + // tests that the content is cleared when starting editing + m_subject->setText("asdf"); + m_subject->setEchoMode(DuiTextEditModel::PasswordEchoOnEdit); + + QFocusEvent focusEvent(QEvent::FocusIn); + m_subject->focusInEvent(&focusEvent); + + QKeyEvent keyEvent(QEvent::KeyPress, 0, 0, "a"); + m_subject->keyPressEvent(&keyEvent); + + QCOMPARE(m_subject->text().length(), 1); + + // set back to normal mode and check that the content is not cleared when starting editing. + QFocusEvent focusOutEvent(QEvent::FocusOut); + m_subject->focusOutEvent(&focusOutEvent); + + m_subject->setEchoMode(DuiTextEditModel::Normal); + m_subject->keyPressEvent(&keyEvent); + QCOMPARE(m_subject->text().length(), 2); +} + + +QTEST_APPLESS_MAIN(Ut_DuiTextEdit); + diff --git a/tests/ut_duitextedit/ut_duitextedit.h b/tests/ut_duitextedit/ut_duitextedit.h new file mode 100644 index 000000000..745c01544 --- /dev/null +++ b/tests/ut_duitextedit/ut_duitextedit.h @@ -0,0 +1,95 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUITEXTEDIT_H +#define UT_DUITEXTEDIT_H + +#include +#include + +class DuiApplication; +class DuiApplicationWindow; +class DuiTextEdit; + +Q_DECLARE_METATYPE(DuiTextEdit *); + +class Ut_DuiTextEdit : public QObject +{ + Q_OBJECT + +private: + void confirmKeyEventIgnored(DuiTextEdit *subject, int key); + void constraintTest(DuiTextEdit *subject, const QString &input, const QString &expectedOutput); + + DuiTextEdit *m_subject; + DuiApplication *m_app; + DuiApplicationWindow *m_appWindow; + + QStringList validStrings; + static const QString testString; + +private slots: + void initTestCase(); + void cleanupTestCase(); + + void init(); + void cleanup(); + + void testSetText(); + void testInsert(); + void testKeyPressEvent(); + void testSingleLineKeyPressEvent(); + void testFocusInEvent(); + void testFocusOutEvent(); + void testInputMethodEvent(); + void testSetCursorPosition(); + void testSetTextCursor(); + void testTextInteractionFlags(); + void testConstraints(); + void testReadOnly(); + void testMaxLength_data(); + void testMaxLength(); + //void testFeedback(); + void testBadData(); + void testSelection(); + void testAutoSelection(); + void testPrompt(); + void testValidator(); + void testClear(); + void testCursorPositionChanged(); + void testCopyPaste(); + void testPasteOnPreedit(); + void testInputMethodQuery(); + void testConstrainedPaste(); + + void testSignChange_data(); + void testSignChange(); + + void testSetContentType_data(); + void testSetContentType(); + + void testInputMethodHints(); + + void testAttachToolbar(); + + void testPasswordEchoOnEditClearing(); +}; + +#endif + diff --git a/tests/ut_duitextedit/ut_duitextedit.pro b/tests/ut_duitextedit/ut_duitextedit.pro new file mode 100644 index 000000000..70a207868 --- /dev/null +++ b/tests/ut_duitextedit/ut_duitextedit.pro @@ -0,0 +1,19 @@ +include(../common_top.pri) + +TARGET = ut_duitextedit + +SOURCES += \ + ut_duitextedit.cpp \ + $$STUBSDIR/stubbase.cpp \ + +HEADERS += \ + $$STUBSDIR/duipannableviewport_stub.h \ + $$STUBSDIR/duipannablewidget_stub.h \ + $$STUBSDIR/duitexteditview_stub.h \ + $$STUBSDIR/duitheme_stub.h \ + $$STUBSDIR/duiwidgetview_stub.h \ + ut_duitextedit.h \ + +INCLUDEPATH += $$DUISRCDIR/widgets/ + +include(../common_bot.pri) diff --git a/tests/ut_duitexteditview/.gitignore b/tests/ut_duitexteditview/.gitignore new file mode 100644 index 000000000..2a1251647 --- /dev/null +++ b/tests/ut_duitexteditview/.gitignore @@ -0,0 +1 @@ +ut_duitexteditview diff --git a/tests/ut_duitexteditview/ut_duitexteditview.cpp b/tests/ut_duitexteditview/ut_duitexteditview.cpp new file mode 100644 index 000000000..67bbfba63 --- /dev/null +++ b/tests/ut_duitexteditview/ut_duitexteditview.cpp @@ -0,0 +1,236 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duitexteditview.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include "../../src/widgets/duitextedit_p.h" +#include "../../src/widgets/views/duitexteditview_p.h" +#include "../../src/widgets/views/duitexteditviewzoom.h" + +void Ut_DuiTextEditView::initTestCase() +{ + static int dummyArgc = 1; + static char *dummyArgv[1] = { (char *) "./ut_duitexteditview" }; + DuiApplication::setLoadDuiInputContext(false); + m_app = new DuiApplication(dummyArgc, dummyArgv); + m_appWindow = new DuiApplicationWindow; +} + +void Ut_DuiTextEditView::cleanupTestCase() +{ + delete m_appWindow; + m_appWindow = 0; + delete m_app; + m_app = 0; +} + + +void Ut_DuiTextEditView::init() +{ + m_controller = new DuiTextEdit(DuiTextEditModel::MultiLine, ""); + m_subject = new DuiTextEditView(m_controller); + m_controller->setView(m_subject); +} + + +void Ut_DuiTextEditView::cleanup() +{ + m_controller->setView(0); + m_subject = 0; + delete m_controller; + m_controller = 0; +} + + +void Ut_DuiTextEditView::testPaint() +{ + qDebug() << "Nothing to test now for paint"; + /*QPixmap* empty = new QPixmap(200, 200); + empty->fill(QColor(0, 0, 0, 0)); + QPainter *myPainter = new QPainter(empty);*/ + + //QStyleOptionGraphicsItem* option = new QStyleOptionGraphicsItem(); + //m_subject->paint(myPainter, option); + + /*delete myPainter; + delete empty;*/ +} + + +void Ut_DuiTextEditView::testBoundingRect() +{ + // DISABLED TEMPORARILY - setGeometry() doesn't seem to honor minimum size + // on scratchbox. shouldn't be a DuiTextView bug anyway. +#if 0 + QRectF testRect(0, 0, 100, 30); + QRectF adjustedRect = testRect; + QSizeF minSize = m_subject->sizeHint(Qt::MinimumSize); + qDebug() << "minsize:" << minSize; + + if ((testRect.size().height() != minSize.height()) + || (testRect.size().width() != minSize.width())) { + adjustedRect.setSize(minSize); + } + + m_controller->setGeometry(testRect); + + QVERIFY((m_subject->boundingRect() == testRect) + || (m_subject->boundingRect() == adjustedRect)); +#endif +} + + +void Ut_DuiTextEditView::testStyleUpdated() +{ + qDebug() << "Nothing to test now for styleUpdated"; + //Hard to say whether we can test this function, because all the attribute is read from css file + /*m_subject->styleUpdated(); + QString activeTextStyle = m_subject->styleAttribute(DuiTextEditViewPrivate::ActiveTextStyleAttribute); + QCOMPARE(activeTextStyle,"WaveUnderline");*/ +} + + +void Ut_DuiTextEditView::testResizeEvent() +{ + qDebug() << "Nothing to test now for resizeEvent"; +} + + +void Ut_DuiTextEditView::testGrowing() +{ + // tests that the minimum size grows after new text is appended + + QString stringToAppend("\n\nasdf"); + QSizeF oldSize = m_subject->sizeHint(Qt::MinimumSize); + + m_controller->insert(stringToAppend); + QSizeF newSize = m_subject->sizeHint(Qt::MinimumSize); + + QVERIFY(newSize.height() > oldSize.height()); + + // FIXME: first test that removing one line is in between the sizes + + // test that minimum size is the same as in the start after new text is removed + QKeyEvent event(QEvent::KeyPress, Qt::Key_Backspace, Qt::NoModifier); + + for (int i = 0; i < stringToAppend.size(); ++i) { + m_controller->keyPressEvent(&event); + } + + newSize = m_subject->sizeHint(Qt::MinimumSize); + QCOMPARE(newSize.height(), oldSize.height()); +} + +void Ut_DuiTextEditView::testInputMethodQuery() +{ + m_appWindow->scene()->addItem(m_controller); + QVariant result; + QList queries; + QGraphicsSceneMouseEvent event; + + queries << Qt::ImMicroFocus << Qt::ImFont << Qt::ImCursorPosition + << Qt::ImSurroundingText << Qt::ImCurrentSelection; + event.setPos(QPointF(10, 10)); + + result = m_subject->inputMethodQuery(Qt::InputMethodQuery(Dui::VisualizationPriorityQuery)); + QVERIFY(result.isValid()); + QVERIFY(result.toBool() == false); + + foreach(Qt::InputMethodQuery query, queries) { + //at least we should not crash + result = m_subject->inputMethodQuery(query); + } + + m_subject->mousePressEvent(&event); + QTest::qWait(800); //this value must be greater than ZoomTimeInterval in duitexteditview.cpp + + result = m_subject->inputMethodQuery(Qt::InputMethodQuery(Dui::VisualizationPriorityQuery)); + QVERIFY(result.isValid()); + QVERIFY(result.toBool() == true); + + foreach(Qt::InputMethodQuery query, queries) { + //at least we should not crash + result = m_subject->inputMethodQuery(query); + } + m_appWindow->scene()->removeItem(m_controller); +} + +/* + * Bug #145360, Characters in masked text entry are not masked + */ +void Ut_DuiTextEditView::testMaskedCharacters() +{ + QVERIFY(m_controller->echoMode() == DuiTextEditModel::Normal); + m_controller->setEchoMode(DuiTextEditModel::Password); + m_controller->setEchoMode(DuiTextEditModel::Password); //we should not crash here + m_controller->setEchoMode(DuiTextEditModel::Normal); + m_controller->setEchoMode(DuiTextEditModel::Normal); //we should not crash here +} + +/* + * Bug #150452, The position of text cursor is wrong after + * deleting text with backspace key in the DuiTextEdit + */ +void Ut_DuiTextEditView::testUpdateScrollWhenTextChanged() +{ + cleanup(); + m_controller = new DuiTextEdit(DuiTextEditModel::SingleLine, ""); + m_subject = new DuiTextEditView(m_controller); + m_controller->setView(m_subject); + + int count = 256; + qreal hscroll = 0; + QKeyEvent bsEvent(QEvent::KeyPress, Qt::Key_Backspace, Qt::NoModifier, "\b"); + QKeyEvent event(QEvent::KeyPress, Qt::Key_X, Qt::NoModifier, "x"); + + QCOMPARE(m_subject->d_ptr->hscroll, qreal(0)); + for (int n = 0; n < count; ++n) { + m_controller->keyPressEvent(&event); + } + hscroll = m_subject->d_ptr->hscroll; + QVERIFY(hscroll > 0); + + for (int n = 0; n < (count - 2); ++n) { + m_controller->keyPressEvent(&bsEvent); + } + QVERIFY(hscroll > m_subject->d_ptr->hscroll); + QVERIFY(m_subject->d_ptr->hscroll > qreal(1.0)); + + while (!m_controller->text().isEmpty()) { + m_controller->keyPressEvent(&bsEvent); + } + QCOMPARE(m_subject->d_ptr->hscroll, qreal(0)); +} + +QTEST_APPLESS_MAIN(Ut_DuiTextEditView) + diff --git a/tests/ut_duitexteditview/ut_duitexteditview.h b/tests/ut_duitexteditview/ut_duitexteditview.h new file mode 100644 index 000000000..7f4a7e93c --- /dev/null +++ b/tests/ut_duitexteditview/ut_duitexteditview.h @@ -0,0 +1,62 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUITEXTEDITVIEW_H +#define UT_DUITEXTEDITVIEW_H + +#include +#include +#include + + +class DuiApplication; +class DuiApplicationWindow; +class DuiTextEdit; +class DuiTextEditView; + +class Ut_DuiTextEditView : public QObject +{ + Q_OBJECT +public: + static QHash themePixmap; + +private slots: + void init(); + void cleanup(); + void initTestCase(); + void cleanupTestCase(); + + void testPaint(); + void testBoundingRect(); + void testStyleUpdated(); + void testResizeEvent(); + void testGrowing(); + void testInputMethodQuery(); + void testMaskedCharacters(); + void testUpdateScrollWhenTextChanged(); + +private: + DuiTextEdit *m_controller; + DuiTextEditView *m_subject; + DuiApplication *m_app; + DuiApplicationWindow *m_appWindow; +}; + +#endif + diff --git a/tests/ut_duitexteditview/ut_duitexteditview.pro b/tests/ut_duitexteditview/ut_duitexteditview.pro new file mode 100644 index 000000000..9b25d97e1 --- /dev/null +++ b/tests/ut_duitexteditview/ut_duitexteditview.pro @@ -0,0 +1,19 @@ +include(../common_top.pri) +TARGET = ut_duitexteditview + +TEST_SOURCES = \ + +SOURCES += \ + ut_duitexteditview.cpp \ + $$TEST_SOURCES \ + $$STUBSDIR/stubbase.cpp \ + +HEADERS += \ + ut_duitexteditview.h \ +# $$STUBSDIR/duistyledescription_stub.h \ +# $$STUBSDIR/duistyle_stub.h \ +# $$STUBSDIR/duitheme_stub.h \ +# $$STUBSDIR/duiwidgetcontroller_stub.h \ +# $$STUBSDIR/duiwidget_stub.h \ + +include(../common_bot.pri) diff --git a/tests/ut_duitheme/.gitignore b/tests/ut_duitheme/.gitignore new file mode 100644 index 000000000..2f54567e3 --- /dev/null +++ b/tests/ut_duitheme/.gitignore @@ -0,0 +1 @@ +ut_duitheme diff --git a/tests/ut_duitheme/ut_duitheme.cpp b/tests/ut_duitheme/ut_duitheme.cpp new file mode 100644 index 000000000..7fce30f7d --- /dev/null +++ b/tests/ut_duitheme/ut_duitheme.cpp @@ -0,0 +1,184 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "ut_duitheme.h" +#include + +QImage::Format gQImageFormat = QImage::Format_Invalid; +XImage gImage; +QImage gQImage; +unsigned int gDepth; +int gBitsPerUnit; + + +Status XGetGeometry( + Display* /* display */, + Drawable /* drawable */, + Window* /* root_return */, + int* /* x_return */, + int* /* y_return */, + unsigned int* /* width_return */, + unsigned int* /* height_return */, + unsigned int* /* border_width_return */, + unsigned int *depth_return +) +{ + *depth_return = gDepth; + qDebug() << "XGetGeometry() - called. Setting " << *depth_return << " as bit depth."; + return 1; +} + +XImage *XGetImage( + Display* /* display */, + Drawable /* d */, + int /* x */, + int /* y */, + unsigned int /* width */, + unsigned int /* height */, + unsigned long /* plane_mask */, + int /* format */ +) +{ + qDebug() << "XGetImage() - called."; + return &gImage; +} + + +int XBitmapUnit(Display * /*display*/) +{ + return gBitsPerUnit; +} + + +QImage::QImage(const uchar *data, int width, int height, Format format) +{ + Q_UNUSED(data); + Q_UNUSED(width); + Q_UNUSED(height); + Q_UNUSED(format); + + qDebug() << "QImage::QImage() - called."; + gQImageFormat = format; +} + +QImage::~QImage() +{ + +} + +QImage &QImage::operator=(const QImage &) +{ + qDebug() << "QImage::operator = () - called."; + return gQImage; +} + +/* +QPixmap::QPixmap(const QPixmap &) +{ + qDebug() << "QPixmap::QPixmap() - called."; +} +*/ + +void Ut_DuiTheme::init() +{ + m_subject = DuiTheme::instance(); //new DuiTheme(); + gQImageFormat = QImage::Format_Invalid; + gDepth = 0; + gBitsPerUnit = 0; +} + +void Ut_DuiTheme::cleanupTestCase() +{ +} + +void Ut_DuiTheme::initTestCase() +{ +} + +void Ut_DuiTheme::loadCSS() +{ + // set DuiStyleSheetParser::load() to return true + gDuiStyleSheetParserStub->stubSetReturnValue("load", true); + + QString myFilename("myCSSFile"); + m_subject->loadCSS(myFilename); + + QCOMPARE(gDuiStyleSheetParserStub->stubLastParameters(0), myFilename); +} + +#if QT_VERSION < 0x040500 +void Ut_DuiTheme::testPixmapCreationWithAllBitDepths() +{ + QPixmap *pixmap; + + // Test pixmap from handle with 8 bit pixmap + gDepth = 8; + pixmap = m_subject->pixmapFromHandle(8); + QCOMPARE(gQImageFormat, QImage::Format_Indexed8); + + // Test pixmap from handle with 16 bit pixmap + gDepth = 16; + pixmap = m_subject->pixmapFromHandle(16); + QCOMPARE(gQImageFormat, QImage::Format_RGB16); + + // Test pixmap from handle with 24 bit pixmap, no padding + gDepth = 24; + gBitsPerUnit = 24; + pixmap = m_subject->pixmapFromHandle(24); + QCOMPARE(gQImageFormat, QImage::Format_RGB888); + + // Test pixmap from handle with 24 bit pixmap, padding + gDepth = 24; + gBitsPerUnit = 32; + pixmap = m_subject->pixmapFromHandle(24); + QCOMPARE(gQImageFormat, QImage::Format_RGB32); + gBitsPerUnit = 0; // reset + + // Test pixmap from handle with 32 bit pixmap + gDepth = 32; + pixmap = m_subject->pixmapFromHandle(32); + QCOMPARE(gQImageFormat, QImage::Format_ARGB32); +} +#endif // QT_VERSION >= 0x040500 + +void Ut_DuiTheme::cleanup() +{ + // Don't delete, it's a singleton! + //delete m_subject; + //m_subject = 0; +} + +QTEST_MAIN(Ut_DuiTheme) diff --git a/tests/ut_duitheme/ut_duitheme.h b/tests/ut_duitheme/ut_duitheme.h new file mode 100644 index 000000000..752e2e4e1 --- /dev/null +++ b/tests/ut_duitheme/ut_duitheme.h @@ -0,0 +1,48 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUITHEME_H +#define UT_DUITHEME_H + +#include +#include + + +#include "duitheme.h" + +class Ut_DuiTheme : public QObject +{ + Q_OBJECT + +private slots: + void init(); // Executed before each test function + void cleanup(); // Executed after each test function + void initTestCase(); // Executed before all + void cleanupTestCase(); // Executed after all tests have been run + + // Actual test functions + void loadCSS(); +#if QT_VERSION < 0x040500 + void testPixmapCreationWithAllBitDepths(); +#endif // QT_VERSION < 0x040500 + +private: + DuiTheme *m_subject; +}; +#endif diff --git a/tests/ut_duitheme/ut_duitheme.pro b/tests/ut_duitheme/ut_duitheme.pro new file mode 100644 index 000000000..09147df23 --- /dev/null +++ b/tests/ut_duitheme/ut_duitheme.pro @@ -0,0 +1,45 @@ +include(../common_top.pri) + +SOURCES += \ + ut_duitheme.cpp \ +# $$DUISRCDIR/duitheme.cpp \ +# $$DUISRCDIR/duistyledata.cpp \ +# $$DUISRCDIR/duistyledescription.cpp \ + +SOURCES += \ + $$STUBSDIR/stubbase.cpp \ + +HEADERS += \ + ut_duitheme.h \ +# $$DUISRCDIR/duitheme.h \ + +HEADERS += \ + $$STUBSDIR/stubbase.h \ + +HEADERS += \ +# $$DUISRCDIR/duiapplicationmenuview.h \ +# $$DUISRCDIR/duibuttoniconview.h \ +# $$DUISRCDIR/duibuttonview.h \ +# $$DUISRCDIR/duinavigationbarview.h \ +# $$DUISRCDIR/duipixmaploader.h \ +# $$DUISRCDIR/duisliderdotview.h \ +# $$DUISRCDIR/duistyle.h \ +# $$DUISRCDIR/duistylesheet.h \ +# $$DUISRCDIR/duistylesheetparser.h \ +# $$DUISRCDIR/duitoolbarview.h \ +# $$DUISRCDIR/duiviewfactory.h \ +# $$DUISRCDIR/duiwidgetview.h \ + $$STUBSDIR/duiapplicationmenuview_stub.h \ + $$STUBSDIR/duibuttoniconview_stub.h \ + $$STUBSDIR/duibuttonview_stub.h \ + $$STUBSDIR/duinavigationbarview_stub.h \ + $$STUBSDIR/duipixmaploader_stub.h \ + $$STUBSDIR/duisliderdotview_stub.h \ + $$STUBSDIR/duistylesheetparser_stub.h \ + $$STUBSDIR/duistylesheet_stub.h \ + $$STUBSDIR/duistyle_stub.h \ + $$STUBSDIR/duitoolbarview_stub.h \ + $$STUBSDIR/duiviewfactory_stub.h \ + $$STUBSDIR/duiwidgetview_stub.h \ + +include(../common_bot.pri) diff --git a/tests/ut_duitoolbar/.gitignore b/tests/ut_duitoolbar/.gitignore new file mode 100644 index 000000000..61dc5b8dd --- /dev/null +++ b/tests/ut_duitoolbar/.gitignore @@ -0,0 +1 @@ +ut_duitoolbar diff --git a/tests/ut_duitoolbar/ut_duitoolbar.cpp b/tests/ut_duitoolbar/ut_duitoolbar.cpp new file mode 100644 index 000000000..e0a5c8eb6 --- /dev/null +++ b/tests/ut_duitoolbar/ut_duitoolbar.cpp @@ -0,0 +1,258 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_duitoolbar.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +DuiApplication *app; +// TODO: remove this when unneeded in DuiTextEdit's constructor +DuiApplicationWindow *appWin; + +void Ut_DuiToolBar::init() +{ + m_subject = new DuiToolBar(); +} + +void Ut_DuiToolBar::cleanup() +{ + delete m_subject; + m_subject = 0; +} + +void Ut_DuiToolBar::initTestCase() +{ + static int argc = 1; + static char *app_name[1] = { (char *) "./ut_duitoolbar" }; + app = new DuiApplication(argc, app_name); + appWin = new DuiApplicationWindow; +} + +void Ut_DuiToolBar::cleanupTestCase() +{ + delete appWin; + delete app; +} + +void Ut_DuiToolBar::testConstructor() +{ + QVERIFY(m_subject); +} + +void Ut_DuiToolBar::testDestructor() +{ + DuiToolBar *toolbar = new DuiToolBar(); + delete toolbar; +} + +void Ut_DuiToolBar::testAddAction() +{ + // empty action list, check + m_subject->clearActions(); + QVERIFY(m_subject->actions().count() == 0); + + // return value action + DuiAction *action; + + // test addAction(const QString &text) + DuiAction *action0 = new DuiAction("TEXTONLY", m_subject); + m_subject->addAction(action0); + action = qobject_cast(m_subject->actions().at(0)); + // must be one + QVERIFY(m_subject->actions().count() == 1); + QVERIFY(action == action0); + QVERIFY(action->text() == "TEXTONLY"); + + // test addAction(const QString &icon, const QString &text) + DuiAction *action1 = new DuiAction("Icon-list-view-on", "TEXT", m_subject); + m_subject->addAction(action1); + QVERIFY(m_subject->actions().count() == 2); + action = qobject_cast(m_subject->actions().at(1)); + QVERIFY(action == action1); + QVERIFY(action->iconID() == "Icon-list-view-on"); + QVERIFY(action->text() == "TEXT"); + + testValue = false; + senderAction = NULL; + connect(action1, SIGNAL(triggered(bool)), this, SLOT(actionSlot(bool))); + action1->trigger(); + QVERIFY(testValue); + QVERIFY(senderAction == action1); + + // test addAction(DuiAction* action) + DuiAction *action2 = new DuiAction("Icon-time-line-on", "TEXT4", NULL); + m_subject->addAction(action2); + QVERIFY(m_subject->actions().count() == 3); + + action = qobject_cast(m_subject->actions().at(2)); + QVERIFY(action == action2); + delete action2; + +} + +void Ut_DuiToolBar::testAddTextEditAction() +{ + // empty action list, check + m_subject->clearActions(); + QVERIFY(m_subject->actions().count() == 0); + + // test addAction(Text Edit) + DuiTextEdit *textEntry = new DuiTextEdit(); + DuiWidgetAction *actionTextEdit = new DuiWidgetAction(m_subject); + actionTextEdit->setWidget(textEntry); + + m_subject->addAction(actionTextEdit); + DuiWidgetAction *widgetAction = qobject_cast(m_subject->actions().at(0)); + + // must be one + QVERIFY(m_subject->actions().count() == 1); + QVERIFY(widgetAction); + QVERIFY(widgetAction == actionTextEdit); + QVERIFY(widgetAction->widget() == textEntry); +} + +void Ut_DuiToolBar::testInsertAction() +{ + // empty action list, check + m_subject->clearActions(); + QVERIFY(m_subject->actions().count() == 0); + + //adding text edit + DuiTextEdit *textEntry = new DuiTextEdit(); + DuiWidgetAction *actionTextEdit = new DuiWidgetAction(m_subject); + actionTextEdit->setWidget(textEntry); + + m_subject->addAction(actionTextEdit); //first action, indx 0 + + //adding actions + DuiAction *action0 = new DuiAction("action0", m_subject); + m_subject->addAction(action0); //second action, indx 1 + + DuiAction *action1 = new DuiAction("action1", m_subject); + m_subject->insertAction(action0, action1); //third action, indx1 -> action0 goes to indx 2 + + QVERIFY(m_subject->actions().count() == 3); + + DuiWidgetAction *widgetAction = qobject_cast(m_subject->actions().at(0)); // getting indx 0 + DuiAction *action = qobject_cast(m_subject->actions().at(1)); //getting indx 1 + + //veryfing: + QVERIFY(widgetAction); + QVERIFY(widgetAction == actionTextEdit); + QVERIFY(action); + QVERIFY(action == action1); + + action = qobject_cast(m_subject->actions().at(2)); //getting indx 2 + QVERIFY(action); + QVERIFY(action == action0); + +} + +void Ut_DuiToolBar::testActionVisiblity() +{ + // empty action list, check + m_subject->clearActions(); + QVERIFY(m_subject->actions().count() == 0); + + //adding actions: + DuiAction *action0 = new DuiAction("action0", m_subject); + m_subject->addAction(action0); //first action, indx 0 + + DuiAction *action1 = new DuiAction("action1", m_subject); + m_subject->addAction(action1); //second action, indx 1 + + DuiAction *action2 = new DuiAction("action2", m_subject); + m_subject->addAction(action2); //third action, indx 2 + + DuiAction *action3 = new DuiAction("action3", m_subject); + m_subject->addAction(action3); //fourth action, indx 3 + + QVERIFY(m_subject->actions().count() == 4); + + DuiAction *action; //needed for veryfing + + action0->setVisible(false); + action1->setVisible(false); + + QVERIFY(m_subject->actions().count() == 4); + + action = qobject_cast(m_subject->actions().at(0)); + QVERIFY(action); + QVERIFY(action == action0); + QVERIFY(action->isVisible() == false); + + action = qobject_cast(m_subject->actions().at(1)); + QVERIFY(action); + QVERIFY(action == action1); + QVERIFY(action->isVisible() == false); + + action = qobject_cast(m_subject->actions().at(2)); + QVERIFY(action); + QVERIFY(action == action2); + QVERIFY(action->isVisible() == true); + + action = qobject_cast(m_subject->actions().at(3)); + QVERIFY(action); + QVERIFY(action == action3); + QVERIFY(action->isVisible() == true); + + + //text entry: + DuiTextEdit *textEntry = new DuiTextEdit(); + DuiWidgetAction *actionTextEdit = new DuiWidgetAction(m_subject); + actionTextEdit->setWidget(textEntry); + + m_subject->addAction(actionTextEdit); + DuiWidgetAction *widgetAction = qobject_cast(m_subject->actions().at(4)); + QVERIFY(widgetAction); + QVERIFY(widgetAction == actionTextEdit); + QVERIFY(widgetAction->isVisible() == true); + + action0->setVisible(true); + action = qobject_cast(m_subject->actions().at(0)); + QVERIFY(action); + QVERIFY(action == action0); + QVERIFY(action->isVisible() == true); + + action1->setVisible(true); + action = qobject_cast(m_subject->actions().at(1)); + QVERIFY(action); + QVERIFY(action == action1); + QVERIFY(action->isVisible() == true); + + QVERIFY(widgetAction); + QVERIFY(widgetAction->widget()->isVisible() == false); //visiblity should be changed, because there is no room for this anymore +} + +void Ut_DuiToolBar::actionSlot(bool) +{ + senderAction = qobject_cast(sender()); + testValue = true; +} + +QTEST_APPLESS_MAIN(Ut_DuiToolBar) diff --git a/tests/ut_duitoolbar/ut_duitoolbar.h b/tests/ut_duitoolbar/ut_duitoolbar.h new file mode 100644 index 000000000..7766f86b5 --- /dev/null +++ b/tests/ut_duitoolbar/ut_duitoolbar.h @@ -0,0 +1,59 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUITOOLBAR_H +#define UT_DUITOOLBAR_H + +// include unit test headers +#include +#include +#include + +class DuiAction; + +class Ut_DuiToolBar : public QObject +{ + Q_OBJECT + +private Q_SLOTS: + + // test system init and cleanup + void init(); + void cleanup(); + void initTestCase(); + void cleanupTestCase(); + + // class testing + void testConstructor(); + void testDestructor(); + void testAddAction(); + void testAddTextEditAction(); + void testInsertAction(); + void testActionVisiblity(); + + void actionSlot(bool); + +private: + DuiToolBar *m_subject; + + DuiAction *senderAction; + bool testValue; +}; + +#endif diff --git a/tests/ut_duitoolbar/ut_duitoolbar.pro b/tests/ut_duitoolbar/ut_duitoolbar.pro new file mode 100644 index 000000000..3cc0a13a7 --- /dev/null +++ b/tests/ut_duitoolbar/ut_duitoolbar.pro @@ -0,0 +1,13 @@ +include(../common_top.pri) +TARGET = ut_duitoolbar + + +INCLUDEPATH += $$DUISRCDIR/widgets $$DUISRCDIR/style + +SOURCES += \ + ut_duitoolbar.cpp \ + +HEADERS += \ + ut_duitoolbar.h + +include(../common_bot.pri) diff --git a/tests/ut_duitoolbarview/.gitignore b/tests/ut_duitoolbarview/.gitignore new file mode 100644 index 000000000..f76afdde6 --- /dev/null +++ b/tests/ut_duitoolbarview/.gitignore @@ -0,0 +1 @@ +ut_duitoolbarview diff --git a/tests/ut_duitoolbarview/ut_duitoolbarview.cpp b/tests/ut_duitoolbarview/ut_duitoolbarview.cpp new file mode 100644 index 000000000..7de5a43ed --- /dev/null +++ b/tests/ut_duitoolbarview/ut_duitoolbarview.cpp @@ -0,0 +1,90 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ut_duitoolbarview.h" + +DuiApplication *app; +DuiApplicationWindow *appWin; + +void Ut_DuiToolBarView::initTestCase() +{ + static int argc = 1; + static char *app_name[1] = { (char *) "./Ut_DuiToolBarView" }; + app = new DuiApplication(argc, app_name); + appWin = new DuiApplicationWindow; +} + +void Ut_DuiToolBarView::cleanupTestCase() +{ + delete appWin; + delete app; +} + +void Ut_DuiToolBarView::init() +{ + m_toolbar = new DuiToolBar(); + QVERIFY(m_toolbar != 0); + + m_subject = new DuiToolBarView(m_toolbar); + QVERIFY(m_subject != 0); + + m_toolbar->setView(m_subject); + //m_subject->updateStyle(); +} + +void Ut_DuiToolBarView::cleanup() +{ + delete m_toolbar; + m_toolbar = 0; +} + +void Ut_DuiToolBarView::testDeleteAddAction() +{ + m_toolbar->clearActions(); + + DuiWidget *parentWidget = new DuiWidget(); + m_toolbar->addAction(createTextEditAction(parentWidget)); + QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents, 10); + delete parentWidget; + + // toolbar should not crash as action has been deleted + m_toolbar->addAction(new DuiAction("TEXTONLY", m_toolbar)); + QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents, 10); + + QVERIFY(m_toolbar->actions().count() == 1); +} + +DuiWidgetAction *Ut_DuiToolBarView::createTextEditAction(DuiWidget *parentWidget) +{ + DuiTextEdit *textEntry = new DuiTextEdit(); + DuiWidgetAction *actionTextEdit = new DuiWidgetAction(parentWidget); + actionTextEdit->setWidget(textEntry); + return actionTextEdit; +} + +QTEST_APPLESS_MAIN(Ut_DuiToolBarView) diff --git a/tests/ut_duitoolbarview/ut_duitoolbarview.h b/tests/ut_duitoolbarview/ut_duitoolbarview.h new file mode 100644 index 000000000..479de8b93 --- /dev/null +++ b/tests/ut_duitoolbarview/ut_duitoolbarview.h @@ -0,0 +1,52 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUITOOLBARVIEW_H +#define UT_DUITOOLBARVIEW_H + +#include +#include + +class DuiToolBar; +class DuiToolBarView; +class DuiWidget; +class DuiWidgetAction; + +class Ut_DuiToolBarView : public QObject +{ + Q_OBJECT +public: + +private slots: + void initTestCase(); + void cleanupTestCase(); + + void init(); + void cleanup(); + + void testDeleteAddAction(); +private: + DuiToolBar *m_toolbar; + DuiToolBarView *m_subject; + + DuiWidgetAction *createTextEditAction(DuiWidget *parentWidget); +}; + +#endif + diff --git a/tests/ut_duitoolbarview/ut_duitoolbarview.pro b/tests/ut_duitoolbarview/ut_duitoolbarview.pro new file mode 100644 index 000000000..67775a65f --- /dev/null +++ b/tests/ut_duitoolbarview/ut_duitoolbarview.pro @@ -0,0 +1,13 @@ +include(../common_top.pri) +TARGET = ut_duitoolbarview + + +INCLUDEPATH += $$DUISRCDIR/widgets $$DUISRCDIR/style + +SOURCES += \ + ut_duitoolbarview.cpp \ + +HEADERS += \ + ut_duitoolbarview.h + +include(../common_bot.pri) diff --git a/tests/ut_duiwidget/.gitignore b/tests/ut_duiwidget/.gitignore new file mode 100644 index 000000000..3a32441b3 --- /dev/null +++ b/tests/ut_duiwidget/.gitignore @@ -0,0 +1 @@ +ut_duiwidget diff --git a/tests/ut_duiwidget/ut_duiwidget.cpp b/tests/ut_duiwidget/ut_duiwidget.cpp new file mode 100644 index 000000000..f6c300638 --- /dev/null +++ b/tests/ut_duiwidget/ut_duiwidget.cpp @@ -0,0 +1,148 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include "duipannableviewport.h" +#include "duipannablewidget.h" +#include "duiwidgetcontroller.h" +#include "duiondisplaychangeevent.h" + +/* ## Removing Stubs ## +#include "duipannableviewport_stub.h" +#include "duipannablewidget_stub.h" +#include "duiwidgetcontroller_stub.h" +*/ +#include "duiwidget.h" +#include "ut_duiwidget.h" + +void Ut_DuiWidget::init() +{ + widget = new DuiWidget; +} + +void Ut_DuiWidget::cleanup() +{ + delete widget; +} + +void Ut_DuiWidget::testShape_data() +{ + QTest::addColumn("size"); + QTest::newRow("0") << QSizeF(50, 50); + QTest::newRow("1") << QSizeF(5, 5); +} + +void Ut_DuiWidget::testShape() +{ + QFETCH(QSizeF, size); + widget->resize(size); + widget->setWindowFrameMargins(0, 0, 0, 0); + QVERIFY(widget->shape().boundingRect() == QRectF(QPointF(), size)); +} + +void Ut_DuiWidget::testClearActions() +{ + for (int i = 0; i < 5; ++i) + widget->addAction(new DuiAction("duiaction", widget)); + + QVERIFY(widget->actions().count() == 5); + + // empty action list, check + widget->clearActions(); + QVERIFY(widget->actions().count() == 0); +} + +void Ut_DuiWidget::testOnDisplay() +{ + QRectF viewRect(0, 0, 864, 480); + { + DuiOnDisplayChangeEvent ev(DuiOnDisplayChangeEvent::FullyOnDisplay, + viewRect); + widget->event(&ev); + } + QVERIFY(widget->isOnDisplay() == true); + + { + DuiOnDisplayChangeEvent ev(DuiOnDisplayChangeEvent::FullyOffDisplay, + viewRect); + widget->event(&ev); + } + QVERIFY(widget->isOnDisplay() == false); +} + +void Ut_DuiWidget::testEnteredDisplay() +{ + m_dummySlotCalled = false; + + QRectF viewRect(0, 0, 864, 480); + { + DuiOnDisplayChangeEvent ev(DuiOnDisplayChangeEvent::FullyOffDisplay, + viewRect); + widget->event(&ev); + } + + connect(widget, SIGNAL(displayEntered()), this, SLOT(dummySlot())); + + QVERIFY(m_dummySlotCalled == false); + + { + DuiOnDisplayChangeEvent ev(DuiOnDisplayChangeEvent::FullyOnDisplay, + viewRect); + widget->event(&ev); + } + + QVERIFY(m_dummySlotCalled == true); + + disconnect(widget, SIGNAL(displayEntered()), this, SLOT(dummySlot())); +} + +void Ut_DuiWidget::testExitedDisplay() +{ + m_dummySlotCalled = false; + + QRectF viewRect(0, 0, 864, 480); + { + DuiOnDisplayChangeEvent ev(DuiOnDisplayChangeEvent::FullyOnDisplay, + viewRect); + widget->event(&ev); + } + + QVERIFY(m_dummySlotCalled == false); + + connect(widget, SIGNAL(displayExited()), this, SLOT(dummySlot())); + + { + DuiOnDisplayChangeEvent ev(DuiOnDisplayChangeEvent::FullyOffDisplay, + viewRect); + widget->event(&ev); + } + + QVERIFY(m_dummySlotCalled == true); + + disconnect(widget, SIGNAL(displayExited()), this, SLOT(dummySlot())); +} + +void Ut_DuiWidget::dummySlot() +{ + m_dummySlotCalled = true; +} + +QTEST_APPLESS_MAIN(Ut_DuiWidget); + diff --git a/tests/ut_duiwidget/ut_duiwidget.h b/tests/ut_duiwidget/ut_duiwidget.h new file mode 100644 index 000000000..789201393 --- /dev/null +++ b/tests/ut_duiwidget/ut_duiwidget.h @@ -0,0 +1,55 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIWIDGET_H +#define UT_DUIWIDGET_H + +#include +#include +#include "duiwidget.h" + +Q_DECLARE_METATYPE(QPointF); + +#define MAX_PARAMS 10 +class Ut_DuiWidget : public QObject +{ + Q_OBJECT + +private: + DuiWidget *widget; + bool m_dummySlotCalled; + +private slots: + void init(); + void cleanup(); + + void testShape_data(); + void testShape(); + void testClearActions(); + + void testOnDisplay(); + void testEnteredDisplay(); + void testExitedDisplay(); + +protected slots: + void dummySlot(); +}; + +#endif // UT_DUIWIDGET_H + diff --git a/tests/ut_duiwidget/ut_duiwidget.pro b/tests/ut_duiwidget/ut_duiwidget.pro new file mode 100644 index 000000000..4f1addda8 --- /dev/null +++ b/tests/ut_duiwidget/ut_duiwidget.pro @@ -0,0 +1,24 @@ +include(../common_top.pri) + +INCLUDEPATH += $$DUISRCDIR/widgets + +TEST_SOURCES += \ +# $$DUISRCDIR/duiwidget.cpp \ + +SOURCES += \ + ut_duiwidget.cpp \ +# $$TEST_SOURCES \ +# $$STUBSDIR/stubbase.cpp \ + +HEADERS += \ +# $$DUISRCDIR/duipannableviewport.h \ +# $$DUISRCDIR/duipannablewidget.h \ +# $$DUISRCDIR/duiwidgetcontroller.h \ +# $$DUISRCDIR/duiwidget.h \ +# $$STUBSDIR/duipannableviewport_stub.h \ +# $$STUBSDIR/duipannablewidget_stub.h \ +# $$STUBSDIR/duiwidgetcontroller_stub.h \ +# $$STUBSDIR/stubbase.h \ + ut_duiwidget.h \ + +include(../common_bot.pri) diff --git a/tests/ut_duiwidgetcontroller/.gitignore b/tests/ut_duiwidgetcontroller/.gitignore new file mode 100644 index 000000000..280808e53 --- /dev/null +++ b/tests/ut_duiwidgetcontroller/.gitignore @@ -0,0 +1 @@ +ut_duiwidgetcontroller diff --git a/tests/ut_duiwidgetcontroller/ut_duiwidgetcontroller.cpp b/tests/ut_duiwidgetcontroller/ut_duiwidgetcontroller.cpp new file mode 100644 index 000000000..98ca1387b --- /dev/null +++ b/tests/ut_duiwidgetcontroller/ut_duiwidgetcontroller.cpp @@ -0,0 +1,301 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include "ut_duiwidgetcontroller.h" +#include +#include +#include +#include +#include +#include + +int qQGraphicsWidgetSizeHintCallCount; +int modelSetupCount; +QList Ut_DuiWidgetController::createdViews; +QList Ut_DuiWidgetController::viewCreatingControllers; +bool Ut_DuiWidgetController::viewCreatesChildWidgets = false; +bool Ut_DuiWidgetController::viewSetsItselfActive = false; + +class MockWidgetView : public DuiWidgetView +{ +public: + MockWidgetView(DuiWidgetController *controller, QSizeF sizeHint = QSizeF(-1, -1), bool createChildWidgets = false, bool setWidgetActive = false); + void setActive(bool active); + bool active; +protected: + QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const; +private: + QSizeF sh; +}; + +MockWidgetView::MockWidgetView(DuiWidgetController *controller, QSizeF sizeH, bool createChildWidgets, bool setWidgetActive) : DuiWidgetView(controller), + active(false) +{ + sh = sizeH; + if (createChildWidgets) { + // Create child widget + DuiWidget *child1 = new DuiWidget(); + + // Create another child widget + DuiWidget *child2 = new DuiWidget(); + + // Create layout and assign children to the layout + QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(Qt::Horizontal); + layout->addItem(child1); + layout->addItem(child2); + + controller->setLayout(layout); + } + if (setWidgetActive) { + controller->setActive(true); + } +} + +void MockWidgetView::setActive(bool a) +{ + active = a; +} + +QSizeF MockWidgetView::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const +{ + Q_UNUSED(which); + Q_UNUSED(constraint); + return sh; +} + +class TestWidgetController : public DuiWidgetController +{ +public: + void setView(DuiWidgetView *view); + void useModel(); +protected: + virtual void setupModel(); +}; + +void TestWidgetController::setView(DuiWidgetView *view) +{ + DuiWidgetController::setView(view); +} + +// dummy method to make sure the model has been set up. +void TestWidgetController::useModel() +{ + QString name = model()->objectName(); + if (name.isEmpty()) + return; +} + +void TestWidgetController::setupModel() +{ + modelSetupCount++; +} + +// DuiTheme stubs (used by DuiWidgetController) +DuiWidgetView *DuiTheme::view(const DuiWidgetController *const_controller) +{ + DuiWidgetController *controller = const_cast(const_controller); + if (Ut_DuiWidgetController::viewCreatingControllers.contains(controller)) { + DuiWidgetView *view = new MockWidgetView(controller, QSizeF(-1, -1), Ut_DuiWidgetController::viewCreatesChildWidgets, Ut_DuiWidgetController::viewSetsItselfActive); + Ut_DuiWidgetController::createdViews.append(view); + return view; + } + return NULL; +} + +// QGraphicsWidget stubs (used by DuiWidgetController) +QSizeF QGraphicsWidget::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const +{ + Q_UNUSED(which); + Q_UNUSED(constraint); + qQGraphicsWidgetSizeHintCallCount++; + return QSizeF(); +} + +void Ut_DuiWidgetController::initTestCase() +{ + static int argc = 1; + static char *app_name[1] = { (char *) "./ut_duiwidgetcontroller" }; + app = new DuiApplication(argc, app_name); +} + +void Ut_DuiWidgetController::cleanupTestCase() +{ + delete app; +} + +void Ut_DuiWidgetController::init() +{ + modelSetupCount = 0; + qQGraphicsWidgetSizeHintCallCount = 0; + controller = new TestWidgetController; + viewCreatesChildWidgets = false; + viewSetsItselfActive = false; + viewCreatingControllers.clear(); + createdViews.clear(); +} + +void Ut_DuiWidgetController::cleanup() +{ + delete controller; +} + +void Ut_DuiWidgetController::testBoundingRect() +{ + QVERIFY((controller->boundingRect() == QRectF())); +} + +void Ut_DuiWidgetController::testSetGeometry_data() +{ + QTest::addColumn("rect"); + QTest::newRow("0") << QRectF(100, 100, 50, 50); + QTest::newRow("1") << QRectF(10, 10, 5, 5); +} + +void Ut_DuiWidgetController::testSetGeometry() +{ + QFETCH(QRectF, rect); + controller->setGeometry(rect); + QVERIFY(controller->geometry() == rect); +} + +void Ut_DuiWidgetController::testSizeHint() +{ + QCOMPARE(modelSetupCount, 0); + + // Test size hint without view + controller->sizeHint(Qt::MinimumSize); + controller->sizeHint(Qt::PreferredSize); + controller->sizeHint(Qt::MaximumSize); + QCOMPARE(qQGraphicsWidgetSizeHintCallCount, 3); + + QCOMPARE(modelSetupCount, 0); + + // Test size hint with invalid view + DuiWidgetView *view = new MockWidgetView(controller); + //view->updateStyle(); + controller->setView(view); + + QCOMPARE(modelSetupCount, 0); + + qQGraphicsWidgetSizeHintCallCount = 0; + controller->sizeHint(Qt::MinimumSize); + controller->sizeHint(Qt::PreferredSize); + controller->sizeHint(Qt::MaximumSize); + QCOMPARE(qQGraphicsWidgetSizeHintCallCount, 3); + + QCOMPARE(modelSetupCount, 0); + + // Test size hint with valid view + DuiWidgetView *view2 = new MockWidgetView(controller, QSizeF(12, 34)); + //view2->updateStyle(); + controller->setView(view2); + QSizeF size(12 + view2->marginLeft() + view2->marginRight(), 34 + view2->marginTop() + view2->marginBottom()); + QCOMPARE(controller->sizeHint(Qt::MinimumSize), size); + QCOMPARE(controller->sizeHint(Qt::PreferredSize), size); + QCOMPARE(controller->sizeHint(Qt::MaximumSize), size); + + QCOMPARE(modelSetupCount, 0); + controller->useModel(); + QCOMPARE(modelSetupCount, 1); + controller->useModel(); + QCOMPARE(modelSetupCount, 1); +} + +void Ut_DuiWidgetController::testActiveStateWhenViewIsSet() +{ + MockWidgetView *view = new MockWidgetView(controller); + controller->setView(view); + + // Verify that controller is not in active state. + QCOMPARE(controller->isActive(), false); + QCOMPARE(view->active, false); + + // Verify that when controller is set to active state also the view is set to active state. + controller->setActive(true); + QCOMPARE(controller->isActive(), true); + QCOMPARE(view->active, true); + + // Verify that when controller is set to inactive state also the view is set to inactive state. + controller->setActive(false); + QCOMPARE(controller->isActive(), false); + QCOMPARE(view->active, false); +} + +void Ut_DuiWidgetController::testActiveStateWhenViewIsUnset() +{ + // Verify that we can set controller active without a view + controller->setActive(true); + QCOMPARE(controller->isActive(), true); + + // Verify that when we set a view to an already active controller the view becomes active + MockWidgetView *view = new MockWidgetView(controller); + controller->setView(view); + QCOMPARE(view->active, true); +} + +void Ut_DuiWidgetController::testAddingToSceneWhenViewCreatesChildWidgets() +{ + DuiWidgetController *testController = new TestWidgetController; + + // Setup testing environment: + // - A MockWidgetView should be created by DuiTheme for this controller. + // - The MockWidgetView should create child widgets for this widget. + viewCreatingControllers.append(testController); + viewCreatesChildWidgets = true; + + // Add the widget to scene + QGraphicsScene *scene = new QGraphicsScene; + QGraphicsView *view = new QGraphicsView(scene); + view->setFixedSize(380, 92); + scene->addItem(testController); + + // Verify that only one view is created + QCOMPARE(createdViews.count(), 1); + + delete view; + delete scene; +} + +void Ut_DuiWidgetController::testSettingActiveWhenViewCreatesChildWidgets() +{ + DuiWidgetController *testController = new TestWidgetController; + + // Setup testing environment: + // - A MockWidgetView should be created by DuiTheme for this controller. + // - The MockWidgetView should set widget active when its constructed. + viewCreatingControllers.append(testController); + viewSetsItselfActive = true; + + // Set geometry call will create view + testController->setGeometry(QRect(0, 0, 100, 100)); + + // Verify that only one view is created + QCOMPARE(createdViews.count(), 1); + + // Verify that controller's view is active + const MockWidgetView *view = dynamic_cast(testController->view()); + QVERIFY(view != NULL); + QCOMPARE(view->active, true); + + delete testController; +} + +QTEST_APPLESS_MAIN(Ut_DuiWidgetController); + diff --git a/tests/ut_duiwidgetcontroller/ut_duiwidgetcontroller.h b/tests/ut_duiwidgetcontroller/ut_duiwidgetcontroller.h new file mode 100644 index 000000000..60172703d --- /dev/null +++ b/tests/ut_duiwidgetcontroller/ut_duiwidgetcontroller.h @@ -0,0 +1,62 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIWIDGETCONTROLLER_H +#define UT_DUIWIDGETCONTROLLER_H + +#include +#include + +class TestWidgetController; +class DuiWidgetController; +class DuiApplication; +class DuiWidgetView; + +class Ut_DuiWidgetController : public QObject +{ + Q_OBJECT + +public: + static QList createdViews; + static QList viewCreatingControllers; + static bool viewCreatesChildWidgets; + static bool viewSetsItselfActive; + +private: + DuiApplication *app; + TestWidgetController *controller; + +private slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + + void testBoundingRect(); + void testSetGeometry_data(); + void testSetGeometry(); + void testSizeHint(); + void testActiveStateWhenViewIsSet(); + void testActiveStateWhenViewIsUnset(); + void testAddingToSceneWhenViewCreatesChildWidgets(); + void testSettingActiveWhenViewCreatesChildWidgets(); +}; + +#endif // UT_DUIWIDGETCONTROLLER_H + diff --git a/tests/ut_duiwidgetcontroller/ut_duiwidgetcontroller.pro b/tests/ut_duiwidgetcontroller/ut_duiwidgetcontroller.pro new file mode 100644 index 000000000..cb72fa488 --- /dev/null +++ b/tests/ut_duiwidgetcontroller/ut_duiwidgetcontroller.pro @@ -0,0 +1,8 @@ +include(../common_top.pri) + +TARGET = ut_duiwidgetcontroller + +SOURCES += ut_duiwidgetcontroller.cpp +HEADERS += ut_duiwidgetcontroller.h + +include(../common_bot.pri) diff --git a/tests/ut_duiwidgetview/.gitignore b/tests/ut_duiwidgetview/.gitignore new file mode 100644 index 000000000..2d24a0bb9 --- /dev/null +++ b/tests/ut_duiwidgetview/.gitignore @@ -0,0 +1 @@ +ut_duiwidgetview diff --git a/tests/ut_duiwidgetview/ut_duiwidgetview.cpp b/tests/ut_duiwidgetview/ut_duiwidgetview.cpp new file mode 100644 index 000000000..13f7f34f0 --- /dev/null +++ b/tests/ut_duiwidgetview/ut_duiwidgetview.cpp @@ -0,0 +1,174 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include + +#include + +#include "ut_duiwidgetview.h" + +class MyDuiWidgetView : public DuiWidgetView +{ +public: + MyDuiWidgetView(DuiWidgetController *controller); + virtual ~MyDuiWidgetView() {} + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0); + virtual void setGeometry(const QRectF &rect); + virtual QRectF boundingRect() const; + virtual QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const; +}; + +MyDuiWidgetView::MyDuiWidgetView(DuiWidgetController *controller) + : DuiWidgetView(controller) +{ +} + + +void MyDuiWidgetView::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + Q_UNUSED(painter); + Q_UNUSED(option); + Q_UNUSED(widget); +} + +void MyDuiWidgetView::setGeometry(const QRectF &rect) +{ + Q_UNUSED(rect); +} + +QRectF MyDuiWidgetView::boundingRect() const +{ + return QRectF(); +} + +QSizeF MyDuiWidgetView::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const +{ + Q_UNUSED(which); + Q_UNUSED(constraint); + return QSizeF(); +} + +void Ut_DuiWidgetView::init() +{ +} + +void Ut_DuiWidgetView::cleanup() +{ +} + +void Ut_DuiWidgetView::initTestCase() +{ + static int argc = 1; + static char *app_name[1] = { (char *) "./ut_duibuttonview" }; + app = new DuiApplication(argc, app_name); + + // DuiWidgetView is pure abstract + // to test, we need something derived from it + + m_controller = new DuiWidgetController(); + m_subject = new MyDuiWidgetView(m_controller); + m_controller->setView(m_subject); +} + +void Ut_DuiWidgetView::cleanupTestCase() +{ + //delete m_subject; + //m_subject = 0; + delete m_controller; + m_controller = 0; + + delete app; + app = 0; +} + +void Ut_DuiWidgetView::setObjectName() +{ + m_subject->setObjectName("myTestString"); +} + +void Ut_DuiWidgetView::shape() +{ + m_subject->shape(); +} + +void Ut_DuiWidgetView::resizeEvent() +{ + QGraphicsSceneResizeEvent myQGSE; + + m_subject->resizeEvent(&myQGSE); +} + +void Ut_DuiWidgetView::mousePressEvent() +{ + QGraphicsSceneMouseEvent *mouseEvent = new QGraphicsSceneMouseEvent(QEvent::GraphicsSceneMousePress); + m_subject->mousePressEvent(mouseEvent); +} + +void Ut_DuiWidgetView::mouseReleaseEvent() +{ + QGraphicsSceneMouseEvent *mouseEvent = new QGraphicsSceneMouseEvent(QEvent::GraphicsSceneMouseRelease); + m_subject->mouseReleaseEvent(mouseEvent); +} + +void Ut_DuiWidgetView::mouseMoveEvent() +{ + QGraphicsSceneMouseEvent *mouseEvent = new QGraphicsSceneMouseEvent(QEvent::GraphicsSceneMouseMove); + m_subject->mouseMoveEvent(mouseEvent); +} + +void Ut_DuiWidgetView::setBottomMarginParameter(DuiWidgetStyleContainer &container, int param) +{ + const DuiWidgetStyle *const_s = container.operator ->(); + DuiWidgetStyle *s = const_cast(const_s); + s->setMarginBottom(param); +} + +void Ut_DuiWidgetView::testThatActiveStyleIsUsedInActiveState() +{ + // Define style parameter in default-mode style + DuiWidgetStyleContainer &container = m_subject->style(); + setBottomMarginParameter(container, 3); + QCOMPARE(container->marginBottom(), 3); + + // Define style parameter in active-mode style + container.setModeActive(); + setBottomMarginParameter(container, 1); + QCOMPARE(container->marginBottom(), 1); + + // Reset the style container to default mode + container.setModeDefault(); + + // Verify that default style is used + QCOMPARE(m_subject->style()->marginBottom(), 3); + + // Set view to active state + m_subject->setActive(true); + + // Verify that active style is used + QCOMPARE(m_subject->style()->marginBottom(), 1); + + // Set view back to default state + m_subject->setActive(false); + + // Verify that default style is used + QCOMPARE(m_subject->style()->marginBottom(), 3); +} + +QTEST_APPLESS_MAIN(Ut_DuiWidgetView) diff --git a/tests/ut_duiwidgetview/ut_duiwidgetview.h b/tests/ut_duiwidgetview/ut_duiwidgetview.h new file mode 100644 index 000000000..1a7a8b13b --- /dev/null +++ b/tests/ut_duiwidgetview/ut_duiwidgetview.h @@ -0,0 +1,58 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIWIDGETVIEW_H +#define UT_DUIWIDGETVIEW_H + +#include +#include + +// the real unit/DuiWidgetView class declaration +#include +#include +#include + +Q_DECLARE_METATYPE(DuiWidgetView *); + +class Ut_DuiWidgetView : public QObject +{ + Q_OBJECT + +private slots: + void init(); + void cleanup(); + void initTestCase(); + void cleanupTestCase(); + void setObjectName(); + void shape(); + void resizeEvent(); + void mousePressEvent(); + void mouseReleaseEvent(); + void mouseMoveEvent(); + void testThatActiveStyleIsUsedInActiveState(); + +private: + void setBottomMarginParameter(DuiWidgetStyleContainer &container, int param); + + DuiWidgetView *m_subject; + DuiWidgetController *m_controller; + DuiApplication *app; +}; + +#endif diff --git a/tests/ut_duiwidgetview/ut_duiwidgetview.pro b/tests/ut_duiwidgetview/ut_duiwidgetview.pro new file mode 100644 index 000000000..796419752 --- /dev/null +++ b/tests/ut_duiwidgetview/ut_duiwidgetview.pro @@ -0,0 +1,15 @@ +include(../common_top.pri) + +INCLUDEPATH += $$DUISRCDIR/widgets $$DUISRCDIR/style + +TARGET = ut_duiwidgetview + +# unit test and unit +SOURCES += \ + ut_duiwidgetview.cpp \ + +# unit test and unit +HEADERS += \ + ut_duiwidgetview.h \ + +include(../common_bot.pri) diff --git a/tests/ut_duiwindow/.gitignore b/tests/ut_duiwindow/.gitignore new file mode 100644 index 000000000..1b3ce577d --- /dev/null +++ b/tests/ut_duiwindow/.gitignore @@ -0,0 +1 @@ +ut_duiwindow diff --git a/tests/ut_duiwindow/ut_duiwindow.cpp b/tests/ut_duiwindow/ut_duiwindow.cpp new file mode 100644 index 000000000..787cc9fe2 --- /dev/null +++ b/tests/ut_duiwindow/ut_duiwindow.cpp @@ -0,0 +1,356 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include +#include +#include "duiondisplaychangeevent.h" + +#include "ut_duiwindow.h" + +DuiWindow *win; + +// Variables for onDisplay -tests +bool Ut_DuiWindow::m_onDisplayHandlerCalled = false; +bool Ut_DuiWindow::m_onDisplaySignalSent = false; + +// DuiDeviceProfile stubs +class DuiDeviceProfile +{ +public: + static DuiDeviceProfile *instance(); + QSize resolution() const; +}; + +DuiDeviceProfile *DuiDeviceProfile::instance() +{ + static DuiDeviceProfile p; + return &p; +} + +QSize DuiDeviceProfile::resolution() const +{ + return QSize(1000, 500); +} + +// DuiComponentData stubs +bool DuiComponentData::softwareRendering() +{ + return true; +} + +bool DuiComponentData::fullScreen() +{ + return false; +} + +void DuiComponentData::registerWindow(DuiWindow *window) +{ + Q_UNUSED(window); +} + +void DuiComponentData::unregisterWindow(DuiWindow *window) +{ + Q_UNUSED(window); +} + +void DuiComponentData::setActiveWindow(DuiWindow *window) +{ + Q_UNUSED(window); +} + +QList DuiComponentData::windows() +{ + QList windowlist; + return windowlist; +} + +// DuiApplication stubs +DuiWindow *DuiApplication::activeWindow() +{ + return 0; +} + +static Dui::PrestartMode fakeMode = Dui::LazyShutdown; + +bool DuiApplication::isPrestarted() +{ + if ((fakeMode == Dui::LazyShutdown) || (fakeMode == Dui::TerminateOnClose)) + return true; + + return false; +} + +void DuiApplication::setPrestartMode(Dui::PrestartMode mode) +{ + fakeMode = mode; + return; +} + +Dui::PrestartMode DuiApplication::prestartMode() +{ + return fakeMode; +} + +// DuiSceneManager stubs +void DuiSceneManager::setOrientationAngle(Dui::OrientationAngle angle, Dui::OrientationChangeMode mode) +{ + Q_UNUSED(mode); + Dui::Orientation newOrientation = (angle == Dui::Angle90 || Dui::Angle270) + ? Dui::Portrait + : Dui::Landscape; + + emit orientationChanged(newOrientation); +} + +// DuiWindows' visibility handler re-imps +void DuiWindow::enterDisplayEvent() +{ + Ut_DuiWindow::m_onDisplayHandlerCalled = true; +} + +void DuiWindow::exitDisplayEvent() +{ + Ut_DuiWindow::m_onDisplayHandlerCalled = true; +} + +// Test class implementation +void Ut_DuiWindow::init() +{ + win = new DuiWindow; +} + +void Ut_DuiWindow::cleanup() +{ + delete win; + win = 0; +} + +void Ut_DuiWindow::testNoSceneManager() +{ + const DuiWindow *const_win = const_cast(win); + QCOMPARE((quintptr) const_win->sceneManager(), (quintptr) 0); +} + +void Ut_DuiWindow::testNoScene() +{ + QCOMPARE((quintptr) win->scene(), (quintptr) 0); +} + +void Ut_DuiWindow::testSceneManagerAutocreation() +{ + QVERIFY(win->sceneManager() != 0); +} + +void Ut_DuiWindow::testIfSceneExistsWhenSceneManagerAutocreated() +{ + win->sceneManager(); + QCOMPARE((quintptr) win->scene(), (quintptr) win->sceneManager()->scene()); +} + +void Ut_DuiWindow::testConstructorWithSceneManager() +{ + DuiSceneManager *manager = new DuiSceneManager; + const DuiWindow *const_win = new DuiWindow(manager); + QCOMPARE((quintptr) const_win->sceneManager(), (quintptr) manager); + delete const_win; +} + +void Ut_DuiWindow::testSetSceneManager() +{ + DuiSceneManager *manager = new DuiSceneManager; + win->setSceneManager(manager); + + QCOMPARE((quintptr) win->sceneManager(), (quintptr) manager); +} + +void Ut_DuiWindow::testOrientation_data() +{ + QTest::addColumn("newAngle"); + QTest::addColumn("newOrientation"); + QTest::newRow("Angle0") << Dui::Angle0 << Dui::Landscape; + QTest::newRow("Angle90") << Dui::Angle90 << Dui::Portrait; + QTest::newRow("Angle180") << Dui::Angle180 << Dui::Landscape; + QTest::newRow("Angle270") << Dui::Angle270 << Dui::Portrait; + QTest::newRow("Angle360") << Dui::Angle0 << Dui::Landscape; +} + +void Ut_DuiWindow::testOrientation() +{ + QFETCH(Dui::OrientationAngle, newAngle); + QFETCH(Dui::Orientation, newOrientation); + + win->setOrientationAngle(newAngle); + QCOMPARE(win->orientation(), newOrientation); +} + +void Ut_DuiWindow::testSetOrientationAngle_data() +{ + QTest::addColumn("newAngle"); + QTest::newRow("Angle0") << Dui::Angle0; + QTest::newRow("Angle90") << Dui::Angle90; + QTest::newRow("Angle180") << Dui::Angle180; + QTest::newRow("Angle270") << Dui::Angle270; + QTest::newRow("Angle360") << Dui::Angle0; +} + +void Ut_DuiWindow::testSetOrientationAngle() +{ + QFETCH(Dui::OrientationAngle, newAngle); + + win->setOrientationAngle(newAngle); + QCOMPARE(win->orientationAngle(), newAngle); +} + +void Ut_DuiWindow::testVisibleSceneSize_data() +{ + QTest::addColumn("newAngle"); + QTest::addColumn("newOrientation"); + QTest::newRow("Angle0") << Dui::Angle0 << Dui::Landscape; + QTest::newRow("Angle90") << Dui::Angle90 << Dui::Portrait; + QTest::newRow("Angle180") << Dui::Angle180 << Dui::Landscape; + QTest::newRow("Angle270") << Dui::Angle270 << Dui::Portrait; + QTest::newRow("Angle360") << Dui::Angle0 << Dui::Landscape; +} + +void Ut_DuiWindow::testVisibleSceneSize() +{ + QFETCH(Dui::OrientationAngle, newAngle); + QFETCH(Dui::Orientation, newOrientation); + + win->setOrientationAngle(newAngle); + + QSize vss = win->visibleSceneSize(); + + if (newOrientation == Dui::Portrait) + vss.transpose(); + + QCOMPARE(vss, DuiDeviceProfile::instance()->resolution()); +} + +void Ut_DuiWindow::testOrientationChangedSignalPropagationFromSceneManager() +{ + QSignalSpy orientationSpy(win, SIGNAL(orientationChanged(Dui::Orientation))); + QSignalSpy angleSpy(win, SIGNAL(orientationAngleChanged(Dui::OrientationAngle))); + + Dui::OrientationAngle newAngle = (Dui::OrientationAngle)(win->orientationAngle() + 90); + + win->sceneManager()->setOrientationAngle(newAngle); + + QCOMPARE(orientationSpy.count(), 1); + QCOMPARE(angleSpy.count(), 1); +} + +void Ut_DuiWindow::testIsOnDisplay() +{ + DuiOnDisplayChangeEvent ev1(false, QRectF(QPointF(0, 0), win->visibleSceneSize())); + win->event(&ev1); + + QVERIFY(win->isOnDisplay() == false); + + DuiOnDisplayChangeEvent ev2(true, QRectF(QPointF(0, 0), win->visibleSceneSize())); + win->event(&ev2); + + QVERIFY(win->isOnDisplay() == true); +} + +void Ut_DuiWindow::testEnterDisplayEventHandler() +{ + Ut_DuiWindow::m_onDisplayHandlerCalled = false; + + DuiOnDisplayChangeEvent ev1(false, QRectF(QPointF(0, 0), win->visibleSceneSize())); + win->event(&ev1); + + DuiOnDisplayChangeEvent ev2(true, QRectF(QPointF(0, 0), win->visibleSceneSize())); + win->event(&ev2); + + QVERIFY(Ut_DuiWindow::m_onDisplayHandlerCalled == true); +} + +void Ut_DuiWindow::testExitDisplayEventHandler() +{ + Ut_DuiWindow::m_onDisplayHandlerCalled = false; + + DuiOnDisplayChangeEvent ev1(true, QRectF(QPointF(0, 0), win->visibleSceneSize())); + win->event(&ev1); + + DuiOnDisplayChangeEvent ev2(false, QRectF(QPointF(0, 0), win->visibleSceneSize())); + win->event(&ev2); + + QVERIFY(Ut_DuiWindow::m_onDisplayHandlerCalled == true); +} + +void Ut_DuiWindow::testEnteredDisplaySignal() +{ + connect(win, SIGNAL(enteredDisplay()), this, SLOT(onDisplayTestSlot())); + + Ut_DuiWindow::m_onDisplaySignalSent = false; + + DuiOnDisplayChangeEvent ev1(false, QRectF(QPointF(0, 0), win->visibleSceneSize())); + win->event(&ev1); + + DuiOnDisplayChangeEvent ev2(true, QRectF(QPointF(0, 0), win->visibleSceneSize())); + win->event(&ev2); + + QVERIFY(Ut_DuiWindow::m_onDisplaySignalSent == true); + + disconnect(win, SIGNAL(enteredDisplay()), this, SLOT(onDisplayTestSlot())); +} + +void Ut_DuiWindow::testExitedDisplaySignal() +{ + connect(win, SIGNAL(exitedDisplay()), this, SLOT(onDisplayTestSlot())); + + Ut_DuiWindow::m_onDisplaySignalSent = false; + + DuiOnDisplayChangeEvent ev1(true, QRectF(QPointF(0, 0), win->visibleSceneSize())); + win->event(&ev1); + + DuiOnDisplayChangeEvent ev2(false, QRectF(QPointF(0, 0), win->visibleSceneSize())); + win->event(&ev2); + + QVERIFY(Ut_DuiWindow::m_onDisplaySignalSent == true); + + disconnect(win, SIGNAL(exitedDisplay()), this, SLOT(onDisplayTestSlot())); +} + +void Ut_DuiWindow::onDisplayTestSlot() +{ + Ut_DuiWindow::m_onDisplaySignalSent = true; +} + +void Ut_DuiWindow::testDisplayExitedOnClose() +{ + win->show(); + QSignalSpy spy(win, SIGNAL(exitedDisplay())); + win->close(); + QCOMPARE(spy.count(), 1); +} + +void Ut_DuiWindow::testDisplayExitedOnCloseLazyShutdownApp() +{ + DuiApplication::setPrestartMode(Dui::LazyShutdown); + win->show(); + QSignalSpy spy(win, SIGNAL(exitedDisplay())); + win->close(); + QCOMPARE(spy.count(), 1); +} + +QTEST_MAIN(Ut_DuiWindow); diff --git a/tests/ut_duiwindow/ut_duiwindow.h b/tests/ut_duiwindow/ut_duiwindow.h new file mode 100644 index 000000000..f84708332 --- /dev/null +++ b/tests/ut_duiwindow/ut_duiwindow.h @@ -0,0 +1,71 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_DUIWINDOW_H +#define UT_DUIWINDOW_H + +#include +#include +#include + +class DuiWindow; +class DuiApplication; + +#define MAX_PARAMS 10 +class Ut_DuiWindow: public QObject +{ + Q_OBJECT + +private slots: + void init(); + void cleanup(); + + void testNoSceneManager(); + void testNoScene(); + void testSceneManagerAutocreation(); + void testIfSceneExistsWhenSceneManagerAutocreated(); + void testConstructorWithSceneManager(); + void testSetSceneManager(); + void testOrientation_data(); + void testOrientation(); + void testSetOrientationAngle_data(); + void testSetOrientationAngle(); + void testVisibleSceneSize_data(); + void testVisibleSceneSize(); + void testOrientationChangedSignalPropagationFromSceneManager(); + void testIsOnDisplay(); + void testEnterDisplayEventHandler(); + void testExitDisplayEventHandler(); + void testEnteredDisplaySignal(); + void testExitedDisplaySignal(); + void testDisplayExitedOnClose(); + void testDisplayExitedOnCloseLazyShutdownApp(); + +public slots: + void onDisplayTestSlot(); + +public: + static bool m_onDisplayHandlerCalled; + static bool m_onDisplaySignalSent; +}; + +Q_DECLARE_METATYPE(Dui::Orientation); +Q_DECLARE_METATYPE(Dui::OrientationAngle); + +#endif diff --git a/tests/ut_duiwindow/ut_duiwindow.pro b/tests/ut_duiwindow/ut_duiwindow.pro new file mode 100644 index 000000000..9fab40edf --- /dev/null +++ b/tests/ut_duiwindow/ut_duiwindow.pro @@ -0,0 +1,16 @@ +include(../common_top.pri) + +TARGET = ut_duiwindow + +INCLUDEPATH += $$DUISRCDIR/events + +# Input +HEADERS += \ + ut_duiwindow.h \ + +SOURCES += \ + ut_duiwindow.cpp \ + +HEADERS += \ + +include(../common_bot.pri) diff --git a/tests/ut_translations/.gitignore b/tests/ut_translations/.gitignore new file mode 100644 index 000000000..5ffec3f09 --- /dev/null +++ b/tests/ut_translations/.gitignore @@ -0,0 +1 @@ +ut_translations diff --git a/tests/ut_translations/translations-qttrid/.gitignore b/tests/ut_translations/translations-qttrid/.gitignore new file mode 100644 index 000000000..6e922cde2 --- /dev/null +++ b/tests/ut_translations/translations-qttrid/.gitignore @@ -0,0 +1 @@ +ut_translations-qttrid.ts diff --git a/tests/ut_translations/translations-qttrid/translations-qttrid.pro b/tests/ut_translations/translations-qttrid/translations-qttrid.pro new file mode 100644 index 000000000..c8d3fd565 --- /dev/null +++ b/tests/ut_translations/translations-qttrid/translations-qttrid.pro @@ -0,0 +1,18 @@ +QMAKE_EXTRA_TARGETS += check +check.depends = . +check.commands = echo "nothing to do here for “make check”" + +QMAKE_EXTRA_TARGETS += check-xml +check-xml.depends = . +check-xml.commands = echo "nothing to do here for “make check-xml”" + +LANGUAGES = ar_EG en_GB de_DE +CATALOGNAME = ut_translations-qttrid +SOURCEDIR = $$PWD/.. +TRANSLATIONDIR = $$PWD +TRANSLATION_INSTALLDIR = $$[QT_INSTALL_LIBS]/libdui-tests/translations-qttrid +DUIROOT = ../../.. +# these include files are installed to $$[QT_INSTALL_DATA]/mkspecs/features +# and included in the "libdui-dev" package: +include($$DUIROOT/src/dui_defines.prf) +include($$DUIROOT/src/translations.prf) diff --git a/tests/ut_translations/translations-qttrid/ut_translations-qttrid_ar_EG.ts b/tests/ut_translations/translations-qttrid/ut_translations-qttrid_ar_EG.ts new file mode 100644 index 000000000..2607fa42d --- /dev/null +++ b/tests/ut_translations/translations-qttrid/ut_translations-qttrid_ar_EG.ts @@ -0,0 +1,73 @@ + + + + + + + + + Untranslated message (engineering English) + + + + + + Translated message (engineering English) + + + + + + Big localized number: %L1 (engineering English) + Big localized number: %L1 + + + + + Big non-localized number: %L1 (engineering English) + Big non-localized number: %1 + + + + %Ln messages received. + + 1st translation: %Ln + 2nd translation: %Ln + 3rd translation: %Ln + 4th translation: %Ln + 5th translation: %Ln + 6th translation: %Ln + + + + + %Ln non-local messages received. + + 1st non-local translation: %n + 2nd non-local translation: %n + 3rd non-local translation: %n + 4th non-local translation: %n + 5th non-local translation: %n + 6th non-local translation: %n + + + + + Name: %1 City: %2 + + + + + %Ln messages received from %1. + %Ln messages received from %1 + + + + + + + + + + + diff --git a/tests/ut_translations/translations-qttrid/ut_translations-qttrid_de_DE.ts b/tests/ut_translations/translations-qttrid/ut_translations-qttrid_de_DE.ts new file mode 100644 index 000000000..6c28f9c4f --- /dev/null +++ b/tests/ut_translations/translations-qttrid/ut_translations-qttrid_de_DE.ts @@ -0,0 +1,60 @@ + + + + + + + + + Untranslated message (engineering English) + + + + + + Translated message (engineering English) + Übersetzte Meldung + + + + + Big localized number: %L1 (engineering English) + + + + + + Big non-localized number: %L1 (engineering English) + + + + + %Ln messages received. + + %Ln Meldung erhalten. + %Ln Meldungen erhalten. + + + + + %Ln non-local messages received. + + %n nicht-lokalisierte Meldung erhalten. + %n nicht-lokalisierte Meldungen erhalten. + + + + + Name: %1 City: %2 + Name: %1 Stadt: %2 + + + + %Ln messages received from %1. + + %Ln Nachricht erhalten von %1. + %Ln Nachrichten erhalten von %1. + + + + diff --git a/tests/ut_translations/translations-qttrid/ut_translations-qttrid_en_GB.ts b/tests/ut_translations/translations-qttrid/ut_translations-qttrid_en_GB.ts new file mode 100644 index 000000000..663739468 --- /dev/null +++ b/tests/ut_translations/translations-qttrid/ut_translations-qttrid_en_GB.ts @@ -0,0 +1,61 @@ + + + + + + + + + Untranslated message (engineering English) + + + + + + Translated message (engineering English) + Translated message + + + + + Big localized number: %L1 (engineering English) + Big localized number: %L1 + + + + + Big non-localized number: %L1 (engineering English) + Big non-localized number: %1 + + + + %Ln messages received. + + %Ln message received. + %Ln messages received. + + + + + %Ln non-local messages received. + + %n non-local message received. + %n non-local messages received. + + + + + Name: %1 City: %2 + + + + + %Ln messages received from %1. + %Ln messages received from %1 + + + + + + + diff --git a/tests/ut_translations/translations-tr/translations-tr.pro b/tests/ut_translations/translations-tr/translations-tr.pro new file mode 100644 index 000000000..c1c3f6a17 --- /dev/null +++ b/tests/ut_translations/translations-tr/translations-tr.pro @@ -0,0 +1,21 @@ +QMAKE_EXTRA_TARGETS += check +check.depends = . +check.commands = echo "nothing to do here for “make check”" + +QMAKE_EXTRA_TARGETS += check-xml +check-xml.depends = . +check-xml.commands = echo "nothing to do here for “make check-xml”" + +LANGUAGES = en_GB fi_FI +DISABLE_QTTRID_ENGINEERING_ENGLISH = yes +CATALOGNAME = ut_translations-tr +SOURCEDIR = $$PWD/.. +TRANSLATIONDIR = $$PWD +TRANSLATION_INSTALLDIR = $$[QT_INSTALL_LIBS]/libdui-tests/translations-tr +# add “-verbose” to force without “-idbased” which is the default in translations.pri +LRELEASE_OPTIONS = "-verbose" +DUIROOT = ../../.. +# these include files are installed to $$[QT_INSTALL_DATA]/mkspecs/features +# and included in the "libdui-dev" package: +include($$DUIROOT/src/dui_defines.prf) +include($$DUIROOT/src/translations.prf) diff --git a/tests/ut_translations/translations-tr/ut_translations-tr_en_GB.ts b/tests/ut_translations/translations-tr/ut_translations-tr_en_GB.ts new file mode 100644 index 000000000..592e1ab6f --- /dev/null +++ b/tests/ut_translations/translations-tr/ut_translations-tr_en_GB.ts @@ -0,0 +1,11 @@ + + + + + Ut_Translations + + hello_str + Hello world + + + diff --git a/tests/ut_translations/translations-tr/ut_translations-tr_fi_FI.ts b/tests/ut_translations/translations-tr/ut_translations-tr_fi_FI.ts new file mode 100644 index 000000000..f9cbd79da --- /dev/null +++ b/tests/ut_translations/translations-tr/ut_translations-tr_fi_FI.ts @@ -0,0 +1,11 @@ + + + + + Ut_Translations + + hello_str + Moi maailma + + + diff --git a/tests/ut_translations/ut_translations.cpp b/tests/ut_translations/ut_translations.cpp new file mode 100644 index 000000000..d92b09cb5 --- /dev/null +++ b/tests/ut_translations/ut_translations.cpp @@ -0,0 +1,878 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "ut_translations.h" +#include + +bool confIsDown() +{ + DuiGConfItem languageItem("/Dui/i18n/Language"); + QString originalValue = languageItem.value().toString(); + int skipConf = 0; + + if (originalValue.isEmpty()) { + languageItem.set("xx"); + //GConf is not running here, so skip it + if (languageItem.value().toString() != "xx") { + skipConf = 1; + } else { + languageItem.set(originalValue); + } + } + + return skipConf == 1; +} + +void Ut_Translations::initTestCase() +{ + static int argc = 0; + static char *argv[1] = { (char *) "" }; + qap = new QCoreApplication(argc, argv); + // could also use: QCoreApplication::applicationDirPath() + // but it seems to have some problems under scratchbox + DuiLocale::addTranslationPath(qApp->applicationDirPath() + "/translations-tr"); + DuiLocale::addTranslationPath(qApp->applicationDirPath() + "/translations-qttrid"); + QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8")); +} + +void Ut_Translations::cleanupTestCase() +{ + delete qap; +} + +void Ut_Translations::init() +{ +} + +void Ut_Translations::cleanup() +{ +} + +void Ut_Translations::testinstallTrCatalogThenUseQtTr_data() +{ + QTest::addColumn("localeName"); + QTest::addColumn("catalog"); + QTest::addColumn("string_id"); + QTest::addColumn("translation"); + + QTest::newRow("fi_FI") << QString("fi_FI") + << QString("ut_translations-tr") + << QString("hello_str") + << QString("Moi maailma"); + QTest::newRow("en_GB") << QString("en_GB") + << QString("ut_translations-tr") + << QString("hello_str") + << QString("Hello world"); +} + +void Ut_Translations::testinstallTrCatalogThenUseQtTr() +{ + QFETCH(QString, localeName); + QFETCH(QString, catalog); + QFETCH(QString, string_id); + QFETCH(QString, translation); + + DuiLocale locale(localeName); + QString context("Ut_Translations"); + DuiLocale localeWithoutTranslations("ru_RU"); + // The following line removes the message catalog which + // may have been installed by previous unit tests in this + // file or by a previous execution of this test: + DuiLocale::setDefault(localeWithoutTranslations); + // Everything should be untranslated now: + QCOMPARE(locale.translate(qPrintable(context), qPrintable(string_id)), + string_id); + QCOMPARE(tr(qPrintable(string_id)), string_id); + locale.installTrCatalog(catalog); + // The .ts file we are using here uses + // + // Ut_Translations + // ... + // therefore we have to give "Ut_Translations" as context + // to locale.translate(): + QCOMPARE(locale.translate(qPrintable(context), qPrintable(string_id)), + translation); + // Make the locale the default to enable the message catalog also for + // tr(): + DuiLocale::setDefault(locale); + // Note that the context for tr() is automatically + // "Ut_Translations" + QCOMPARE(tr(qPrintable(string_id)), translation); +} + +void Ut_Translations::testOriginalQtTr_data() +{ + QTest::addColumn("catalog"); + QTest::addColumn("string_id"); + QTest::addColumn("translation"); + + QTest::newRow("fi_FI") << QString(qApp->applicationDirPath() + "/translations-tr/ut_translations-tr_fi_FI.qm") + << QString("hello_str") + << QString("Moi maailma"); + QTest::newRow("en_GB") << QString(qApp->applicationDirPath() + "/translations-tr/ut_translations-tr_en_GB.qm") + << QString("hello_str") + << QString("Hello world"); +} + +void Ut_Translations::testOriginalQtTr() +{ + QFETCH(QString, catalog); + QFETCH(QString, string_id); + QFETCH(QString, translation); + + // Note that the context for tr() is "Ut_Translations", i.e. + // the section + // + // Ut_Translations + // ... + // + // from the .ts file is used here. + + DuiLocale localeWithoutTranslations("en_GB"); + // do not install any catalogs for this locale and make it the default: + DuiLocale::setDefault(localeWithoutTranslations); + // Everything should be untranslated now: + QCOMPARE(tr(qPrintable(string_id)), string_id); + + QTranslator translator; + translator.load(catalog); + qap->installTranslator(&translator); + QCOMPARE(tr(qPrintable(string_id)), translation); +} + +void Ut_Translations::testQtTrId_data() +{ + QTest::addColumn("localeName"); + QTest::addColumn("messageId"); + QTest::addColumn("engEnglish"); + QTest::addColumn("translation"); + + QTest::newRow("en_GB untranslated") + << QString("en_GB") + //% "Untranslated message (engineering English)" + << QString(QT_TRID_NOOP("xx_untranslated_message")) + << QString("!! Untranslated message (engineering English)") + << QString("!! Untranslated message (engineering English)"); + + QTest::newRow("en_GB translated") + << QString("en_GB") + //% "Translated message (engineering English)" + << QString(QT_TRID_NOOP("xx_translated_message")) + << QString("!! Translated message (engineering English)") + << QString("Translated message"); + + QTest::newRow("de_DE untranslated") + << QString("de_DE") + //% "Untranslated message (engineering English)" + << QString(QT_TRID_NOOP("xx_untranslated_message")) + << QString("!! Untranslated message (engineering English)") + << QString("!! Untranslated message (engineering English)"); + + QTest::newRow("de_DE translated") + << QString("de_DE") + //% "Translated message (engineering English)" + << QString(QT_TRID_NOOP("xx_translated_message")) + << QString("!! Translated message (engineering English)") + << QString("Übersetzte Meldung"); +} + +void Ut_Translations::testQtTrId() +{ + QFETCH(QString, localeName); + QFETCH(QString, messageId); + QFETCH(QString, engEnglish); + QFETCH(QString, translation); + + DuiLocale localeWithoutTranslations("en_GB"); + // do not install any catalogs for this locale and make it the default: + DuiLocale::setDefault(localeWithoutTranslations); + // Everything should be untranslated now: + QCOMPARE(qtTrId(qPrintable(messageId)), messageId); + + // after loading catalog + DuiLocale locale(localeName); + + // installs the catalog for the “Engineering English”: + locale.installTrCatalog("ut_translations-qttrid.qm"); + QCOMPARE(locale.translate("", qPrintable(messageId)), engEnglish); + + DuiLocale::setDefault(locale); + // now qtTrId should return the engineering English: + QCOMPARE(qtTrId(qPrintable(messageId)), engEnglish); + + // installs the catalog for the real translation: + locale.installTrCatalog("ut_translations-qttrid"); + QCOMPARE(locale.translate("", qPrintable(messageId)), translation); + + DuiLocale::setDefault(locale); + // now qtTrId should return the real translation, unless + // the message is not translated at all: + QCOMPARE(qtTrId(qPrintable(messageId)), translation); +} + +void Ut_Translations::testQtTrIdLocalizedNumbers_data() +{ + QTest::addColumn("localeName"); + QTest::addColumn("messageId"); + QTest::addColumn("number"); + QTest::addColumn("engEnglish"); + QTest::addColumn("translation"); + + QTest::newRow("en_GB 4711") + << QString("en_GB") + //% "Big localized number: %L1 (engineering English)" + << QString(QT_TRID_NOOP("id_%L1_big_number")) + << 4711.0 + << QString("!! Big localized number: %L1 (engineering English)") + << QString("Big localized number: 4,711"); + + QTest::newRow("en_GB 4711 nonlocal") + << QString("en_GB") + //% "Big non-localized number: %L1 (engineering English)" + << QString(QT_TRID_NOOP("id_%L1_big_nonlocal_number")) + << 4711.0 + << QString("!! Big non-localized number: %L1 (engineering English)") + << QString("Big non-localized number: 4711"); + + QTest::newRow("ar_EG 4711") + << QString("ar_EG") + //% "Big localized number: %L1 (engineering English)" + << QString(QT_TRID_NOOP("id_%L1_big_number")) + << 4711.0 + << QString("!! Big localized number: %L1 (engineering English)") + << QString("Big localized number: ٤٬٧١١"); + + QTest::newRow("ar_EG 4711 nonlocal") + << QString("ar_EG") + //% "Big non-localized number: %L1 (engineering English)" + << QString(QT_TRID_NOOP("id_%L1_big_nonlocal_number")) + << 4711.0 + << QString("!! Big non-localized number: %L1 (engineering English)") + << QString("Big non-localized number: 4711"); +} + +void Ut_Translations::testQtTrIdLocalizedNumbers() +{ + QFETCH(QString, localeName); + QFETCH(QString, messageId); + QFETCH(double, number); + QFETCH(QString, engEnglish); + QFETCH(QString, translation); + + DuiLocale localeWithoutTranslations("en_GB"); + // do not install any catalogs for this locale and make it the default: + DuiLocale::setDefault(localeWithoutTranslations); + // Everything should be untranslated now: + QCOMPARE(qtTrId(qPrintable(messageId)).arg(number), messageId.arg(number)); + + DuiLocale locale(localeName); + + // installs the catalog for the “Engineering English”: + locale.installTrCatalog("ut_translations-qttrid.qm"); + QCOMPARE(locale.translate("", qPrintable(messageId)).arg(number), + engEnglish.arg(number)); + + DuiLocale::setDefault(locale); + // now qtTrId should return the engineering English: + QCOMPARE(qtTrId(qPrintable(messageId)).arg(number), engEnglish.arg(number)); + + // installs the catalog for the real translation: + locale.installTrCatalog("ut_translations-qttrid"); + QCOMPARE(locale.translate("", qPrintable(messageId)).arg(number), translation); + + DuiLocale::setDefault(locale); + // now qtTrId should return the real translation, unless + // the message is not translated at all: + QCOMPARE(qtTrId(qPrintable(messageId)).arg(number), translation); +} + +void Ut_Translations::testQtTrIdLocalizedNumbersPlural_data() +{ + QTest::addColumn("localeName"); + QTest::addColumn("messageId"); + QTest::addColumn("number"); + QTest::addColumn("engEnglish"); + QTest::addColumn("engEnglishLocalizedNumber"); + QTest::addColumn("translation"); + + // The following 2 qtTrId() lines are dummies to make lupdate work + // (QT_TRID_NOOP has no support for plural apparently): + + //% "%Ln messages received." + qtTrId("id_%Ln_messages_received.", 0); + //% "%Ln non-local messages received." + qtTrId("id_%Ln_nonlocal_messages_received.", 0); + + QTest::newRow("en_GB 0") + << QString("en_GB") + << QString("id_%Ln_messages_received.") + << 0 + << QString("!! 0 messages received.") + << QString("!! 0 messages received.") + << QString("0 messages received."); + QTest::newRow("en_GB 1") + << QString("en_GB") + << QString("id_%Ln_messages_received.") + << 1 + << QString("!! 1 messages received.") + << QString("!! 1 messages received.") + << QString("1 message received."); + QTest::newRow("en_GB 2") + << QString("en_GB") + << QString("id_%Ln_messages_received.") + << 2 + << QString("!! 2 messages received.") + << QString("!! 2 messages received.") + << QString("2 messages received."); + + QTest::newRow("en_GB 0 nonlocal") + << QString("en_GB") + << QString("id_%Ln_nonlocal_messages_received.") + << 0 + << QString("!! 0 non-local messages received.") + << QString("!! 0 non-local messages received.") + << QString("0 non-local messages received."); + QTest::newRow("en_GB 1 nonlocal") + << QString("en_GB") + << QString("id_%Ln_nonlocal_messages_received.") + << 1 + << QString("!! 1 non-local messages received.") + << QString("!! 1 non-local messages received.") + << QString("1 non-local message received."); + QTest::newRow("en_GB 2 nonlocal") + << QString("en_GB") + << QString("id_%Ln_nonlocal_messages_received.") + << 2 + << QString("!! 2 non-local messages received.") + << QString("!! 2 non-local messages received.") + << QString("2 non-local messages received."); + + QTest::newRow("ar_EG 0") + << QString("ar_EG") + << QString("id_%Ln_messages_received.") + << 0 + << QString("!! 0 messages received.") + << QString("!! ٠ messages received.") + << QString("1st translation: ٠"); + QTest::newRow("ar_EG 1") + << QString("ar_EG") + << QString("id_%Ln_messages_received.") + << 1 + << QString("!! 1 messages received.") + << QString("!! ١ messages received.") + << QString("2nd translation: ١"); + QTest::newRow("ar_EG 2") + << QString("ar_EG") + << QString("id_%Ln_messages_received.") + << 2 + << QString("!! 2 messages received.") + << QString("!! ٢ messages received.") + << QString("3rd translation: ٢"); + QTest::newRow("ar_EG 3") + << QString("ar_EG") + << QString("id_%Ln_messages_received.") + << 3 + << QString("!! 3 messages received.") + << QString("!! ٣ messages received.") + << QString("4th translation: ٣"); + QTest::newRow("ar_EG 4") + << QString("ar_EG") + << QString("id_%Ln_messages_received.") + << 4 + << QString("!! 4 messages received.") + << QString("!! ٤ messages received.") + << QString("4th translation: ٤"); + QTest::newRow("ar_EG 5") + << QString("ar_EG") + << QString("id_%Ln_messages_received.") + << 5 + << QString("!! 5 messages received.") + << QString("!! ٥ messages received.") + << QString("4th translation: ٥"); + QTest::newRow("ar_EG 6") + << QString("ar_EG") + << QString("id_%Ln_messages_received.") + << 6 + << QString("!! 6 messages received.") + << QString("!! ٦ messages received.") + << QString("4th translation: ٦"); + QTest::newRow("ar_EG 7") + << QString("ar_EG") + << QString("id_%Ln_messages_received.") + << 7 + << QString("!! 7 messages received.") + << QString("!! ٧ messages received.") + << QString("4th translation: ٧"); + QTest::newRow("ar_EG 8") + << QString("ar_EG") + << QString("id_%Ln_messages_received.") + << 8 + << QString("!! 8 messages received.") + << QString("!! ٨ messages received.") + << QString("4th translation: ٨"); + QTest::newRow("ar_EG 9") + << QString("ar_EG") + << QString("id_%Ln_messages_received.") + << 9 + << QString("!! 9 messages received.") + << QString("!! ٩ messages received.") + << QString("4th translation: ٩"); + QTest::newRow("ar_EG 10") + << QString("ar_EG") + << QString("id_%Ln_messages_received.") + << 10 + << QString("!! 10 messages received.") + << QString("!! ١٠ messages received.") + << QString("4th translation: ١٠"); + + QTest::newRow("ar_EG 0 nonlocal") + << QString("ar_EG") + << QString("id_%Ln_nonlocal_messages_received.") + << 0 + << QString("!! 0 non-local messages received.") + << QString("!! ٠ non-local messages received.") + << QString("1st non-local translation: 0"); + QTest::newRow("ar_EG 1 nonlocal") + << QString("ar_EG") + << QString("id_%Ln_nonlocal_messages_received.") + << 1 + << QString("!! 1 non-local messages received.") + << QString("!! ١ non-local messages received.") + << QString("2nd non-local translation: 1"); + QTest::newRow("ar_EG 2 nonlocal") + << QString("ar_EG") + << QString("id_%Ln_nonlocal_messages_received.") + << 2 + << QString("!! 2 non-local messages received.") + << QString("!! ٢ non-local messages received.") + << QString("3rd non-local translation: 2"); + QTest::newRow("ar_EG 3 nonlocal") + << QString("ar_EG") + << QString("id_%Ln_nonlocal_messages_received.") + << 3 + << QString("!! 3 non-local messages received.") + << QString("!! ٣ non-local messages received.") + << QString("4th non-local translation: 3"); + QTest::newRow("ar_EG 4 nonlocal") + << QString("ar_EG") + << QString("id_%Ln_nonlocal_messages_received.") + << 4 + << QString("!! 4 non-local messages received.") + << QString("!! ٤ non-local messages received.") + << QString("4th non-local translation: 4"); + QTest::newRow("ar_EG 5 nonlocal") + << QString("ar_EG") + << QString("id_%Ln_nonlocal_messages_received.") + << 5 + << QString("!! 5 non-local messages received.") + << QString("!! ٥ non-local messages received.") + << QString("4th non-local translation: 5"); + QTest::newRow("ar_EG 6 nonlocal") + << QString("ar_EG") + << QString("id_%Ln_nonlocal_messages_received.") + << 6 + << QString("!! 6 non-local messages received.") + << QString("!! ٦ non-local messages received.") + << QString("4th non-local translation: 6"); + QTest::newRow("ar_EG 7 nonlocal") + << QString("ar_EG") + << QString("id_%Ln_nonlocal_messages_received.") + << 7 + << QString("!! 7 non-local messages received.") + << QString("!! ٧ non-local messages received.") + << QString("4th non-local translation: 7"); + QTest::newRow("ar_EG 8 nonlocal") + << QString("ar_EG") + << QString("id_%Ln_nonlocal_messages_received.") + << 8 + << QString("!! 8 non-local messages received.") + << QString("!! ٨ non-local messages received.") + << QString("4th non-local translation: 8"); + QTest::newRow("ar_EG 9 nonlocal") + << QString("ar_EG") + << QString("id_%Ln_nonlocal_messages_received.") + << 9 + << QString("!! 9 non-local messages received.") + << QString("!! ٩ non-local messages received.") + << QString("4th non-local translation: 9"); + QTest::newRow("ar_EG 10 nonlocal") + << QString("ar_EG") + << QString("id_%Ln_nonlocal_messages_received.") + << 10 + << QString("!! 10 non-local messages received.") + << QString("!! ١٠ non-local messages received.") + << QString("4th non-local translation: 10"); +} + +void Ut_Translations::testQtTrIdLocalizedNumbersPlural() +{ + QFETCH(QString, localeName); + QFETCH(QString, messageId); + QFETCH(int, number); + QFETCH(QString, engEnglish); + QFETCH(QString, engEnglishLocalizedNumber); + QFETCH(QString, translation); + + QString messageIdNumberReplaced = messageId; + messageIdNumberReplaced.replace("%Ln", QString::number(number)); + + DuiLocale localeWithoutTranslations("en_GB"); + // do not install any catalogs for this locale and make it the default: + DuiLocale::setDefault(localeWithoutTranslations); + // Everything should be untranslated now: + QCOMPARE(qtTrId(qPrintable(messageId), number), messageIdNumberReplaced); + + DuiLocale locale(localeName); + + // installs the catalog for the “Engineering English”: + locale.installTrCatalog("ut_translations-qttrid.qm"); + QCOMPARE(locale.translate("", qPrintable(messageId), "", number), engEnglish); + DuiLocale::setDefault(locale); + + // now qtTrId should return the engineering English: + QCOMPARE(qtTrId(qPrintable(messageId), number), engEnglishLocalizedNumber); + + // installs the catalog for the real translation: + locale.installTrCatalog("ut_translations-qttrid"); + QCOMPARE(locale.translate("", qPrintable(messageId), "", number), translation); + + DuiLocale::setDefault(locale); + // now qtTrId should return the real translation, unless + // the message is not translated at all: + QCOMPARE(qtTrId(qPrintable(messageId), number), translation); +} + +void Ut_Translations::testQtTrIdMultipleVariable_data() +{ + QTest::addColumn("localeName"); + QTest::addColumn("messageId"); + QTest::addColumn("variable1"); + QTest::addColumn("variable2"); + QTest::addColumn("engEnglish"); + QTest::addColumn("translation"); + + QTest::newRow("de_DE") + << QString("de_DE") + //% "Name: %1 City: %2" + << QString(QT_TRID_NOOP("id_name_%1_and_%2_city")) + << QString("Müller") + << QString("Köln") + << QString("!! Name: %1 City: %2") + << QString("Name: Müller Stadt: Köln"); +} + +void Ut_Translations::testQtTrIdMultipleVariable() +{ + QFETCH(QString, localeName); + QFETCH(QString, messageId); + QFETCH(QString, variable1); + QFETCH(QString, variable2); + QFETCH(QString, engEnglish); + QFETCH(QString, translation); + + DuiLocale localeWithoutTranslations("en_GB"); + // do not install any catalogs for this locale and make it the default: + DuiLocale::setDefault(localeWithoutTranslations); + // Everything should be untranslated now: + QCOMPARE(qtTrId(qPrintable(messageId)).arg(variable1).arg(variable2), + messageId.arg(variable1).arg(variable2)); + + DuiLocale locale(localeName); + + // installs the catalog for the “Engineering English”: + locale.installTrCatalog("ut_translations-qttrid.qm"); + QCOMPARE(locale.translate("", qPrintable(messageId)) + .arg(variable1).arg(variable2), + engEnglish.arg(variable1).arg(variable2)); + + DuiLocale::setDefault(locale); + // now qtTrId should return the engineering English: + QCOMPARE(qtTrId(qPrintable(messageId)).arg(variable1).arg(variable2), + engEnglish.arg(variable1).arg(variable2)); + + // installs the catalog for the real translation: + locale.installTrCatalog("ut_translations-qttrid"); + QCOMPARE(locale.translate( + "", qPrintable(messageId)).arg(variable1).arg(variable2), + translation); + + DuiLocale::setDefault(locale); + // now qtTrId should return the real translation, unless + // the message is not translated at all: + QCOMPARE(qtTrId(qPrintable(messageId)).arg(variable1).arg(variable2), + translation); +} + +void Ut_Translations::testQtTrIdMultipleVariableWithPlural_data() +{ + QTest::addColumn("localeName"); + QTest::addColumn("messageId"); + QTest::addColumn("number"); + QTest::addColumn("variable"); + QTest::addColumn("engEnglish"); + QTest::addColumn("translation"); + + // The following qtTrId() line is a dummy to make lupdate work + // (QT_TRID_NOOP has no support for plural apparently): + + //% "%Ln messages received from %1." + qtTrId("id_%Ln_messages_received_from_%1.", 0); + + QTest::newRow("de_DE") + << QString("de_DE") + << QString("id_%Ln_messages_received_from_%1.") + << 0 + << QString("Björn Müller") + << QString("!! 0 messages received from Björn Müller.") + << QString("0 Nachrichten erhalten von Björn Müller."); + QTest::newRow("de_DE") + << QString("de_DE") + << QString("id_%Ln_messages_received_from_%1.") + << 1 + << QString("Björn Müller") + << QString("!! 1 messages received from Björn Müller.") + << QString("1 Nachricht erhalten von Björn Müller."); + QTest::newRow("de_DE") + << QString("de_DE") + << QString("id_%Ln_messages_received_from_%1.") + << 2 + << QString("Björn Müller") + << QString("!! 2 messages received from Björn Müller.") + << QString("2 Nachrichten erhalten von Björn Müller."); +} + +void Ut_Translations::testQtTrIdMultipleVariableWithPlural() +{ + QFETCH(QString, localeName); + QFETCH(QString, messageId); + QFETCH(int, number); + QFETCH(QString, variable); + QFETCH(QString, engEnglish); + QFETCH(QString, translation); + + QString messageIdNumberReplaced = messageId; + messageIdNumberReplaced.replace("%Ln", QString::number(number)); + + DuiLocale localeWithoutTranslations("en_GB"); + // do not install any catalogs for this locale and make it the default: + DuiLocale::setDefault(localeWithoutTranslations); + // Everything should be untranslated now: + QCOMPARE(qtTrId(qPrintable(messageId), number).arg(variable), + messageIdNumberReplaced.arg(variable)); + + DuiLocale locale(localeName); + + // installs the catalog for the “Engineering English”: + locale.installTrCatalog("ut_translations-qttrid.qm"); + QCOMPARE(locale.translate("", qPrintable(messageId), "", number).arg(variable), + engEnglish); + + DuiLocale::setDefault(locale); + // now qtTrId should return the engineering English: + QCOMPARE(qtTrId(qPrintable(messageId), number).arg(variable), engEnglish); + + // installs the catalog for the real translation: + locale.installTrCatalog("ut_translations-qttrid"); + QCOMPARE(locale.translate("", qPrintable(messageId), "", number).arg(variable), + translation); + + DuiLocale::setDefault(locale); + // now qtTrId should return the real translation, unless + // the message is not translated at all: + QCOMPARE(qtTrId(qPrintable(messageId), number).arg(variable), + translation); +} + +void Ut_Translations::testGettingTheDefaultLocaleFromTheEnvironment_data() +{ + QTest::addColumn("localeName"); + + QTest::newRow("en_GB") << "en_GB"; + QTest::newRow("fi_FI") << "fi_FI"; + QTest::newRow("ru_RU") << "ru_RU"; +} + +void Ut_Translations::testGettingTheDefaultLocaleFromTheEnvironment() +{ + QFETCH(QString, localeName); + + DuiLocale::s_systemDefault = NULL; + qputenv("LANG", qPrintable(localeName)); + QCOMPARE(QString(qgetenv("LANG")), QString(localeName)); + + QString languageItemOriginalValue(""); + DuiLocale *locale; + if (confIsDown()) { + // gconf is not available. Therefore, + // DuiLocale::createSystemDuiLocale() will get the language + // from the LANG variable. + locale = new DuiLocale(); + } else { + // gconf is available. Therefore, + // DuiLocale::createSystemDuiLocale() would get the language + // from gconf. But if the language string it gets from gconf + // is empty, it falls back to getting the language from the + // LANG variable, as in the case when gconf is not available + // at all. Therefore, we set the language in gconf to the + // empty string temporarily to test whether getting the locale + // from the LANG variable works: + DuiGConfItem languageItem("/Dui/i18n/Language"); + QString languageItemOriginalValue = languageItem.value().toString(); + languageItem.set(""); + QCOMPARE(languageItem.value().toString(), QString("")); + locale = new DuiLocale(); + languageItem.set(languageItemOriginalValue); + } + + QCOMPARE(locale->name(), localeName); +} + +void Ut_Translations::testCreatingAndDestroyingLocales() +{ + DuiLocale locale1; + DuiLocale locale2("fi_FI"); + QCOMPARE(locale2.name(), QString("fi_FI")); + DuiLocale::setDefault(locale2); + locale1.formatNumber(13); + DuiLocale locale3; + DuiLocale locale4("en_GB"); + QCOMPARE(locale4.name(), QString("en_GB")); + { + DuiLocale locale1; + } + { + DuiLocale locale1; + { + DuiLocale locale2("fi"); + } + { + DuiLocale locale3; + } + DuiLocale::setDefault(locale1); + } +} + +void Ut_Translations::benchmarkDuiLocaleConstructorAndDelete() +{ + QBENCHMARK { + DuiLocale *locale = new DuiLocale("de_DE"); + delete locale; + } +} + +void Ut_Translations::benchmarkDuiLocaleConstructorAndDeleteStack() +{ + QBENCHMARK { + DuiLocale locale("de_DE"); + } +} + +void Ut_Translations::benchmarkQLocaleConstructorAndDelete() +{ + QBENCHMARK { + QLocale *locale = new QLocale("de_DE"); + delete locale; + } +} + +void Ut_Translations::benchmarkQLocaleConstructorAndDeleteStack() +{ + QBENCHMARK { + QLocale locale("de_DE"); + } +} + +void Ut_Translations::benchmarkDuiLocaleAssignmentOperator() +{ + DuiLocale *locale1 = new DuiLocale("de_DE"); + DuiLocale *locale2 = new DuiLocale(); + QBENCHMARK { + *locale2 = *locale1; + } + delete locale1; + delete locale2; +} + +void Ut_Translations::benchmarkDuiLocaleAssignmentOperatorStack() +{ + DuiLocale locale1("de_DE"); + DuiLocale locale2; + QBENCHMARK { + locale2 = locale1; + } +} + +void Ut_Translations::benchmarkQLocaleAssignmentOperator() +{ + QLocale *locale1 = new QLocale("de_DE"); + QLocale *locale2 = new QLocale(); + QBENCHMARK { + *locale2 = *locale1; + } + delete locale1; + delete locale2; +} + +void Ut_Translations::benchmarkQLocaleAssignmentOperatorStack() +{ + QLocale locale1("de_DE"); + QLocale locale2; + QBENCHMARK { + locale2 = locale1; + } +} + +void Ut_Translations::benchmarkDuiLocaleCopyConstructorAndDelete() +{ + DuiLocale *locale1 = new DuiLocale("de_DE"); + QBENCHMARK { + DuiLocale *locale2 = new DuiLocale(*locale1); + delete locale2; + } + delete locale1; +} + +void Ut_Translations::benchmarkDuiLocaleCopyConstructorAndDeleteStack() +{ + DuiLocale locale1("de_DE"); + QBENCHMARK { + DuiLocale locale2(locale1); + } +} + +void Ut_Translations::benchmarkQLocaleCopyConstructorAndDelete() +{ + QLocale *locale1 = new QLocale("de_DE"); + QBENCHMARK { + QLocale *locale2 = new QLocale(*locale1); + delete locale2; + } + delete locale1; +} + +void Ut_Translations::benchmarkQLocaleCopyConstructorAndDeleteStack() +{ + QLocale locale1("de_DE"); + QBENCHMARK { + QLocale locale2(locale1); + } +} + +QTEST_APPLESS_MAIN(Ut_Translations); + diff --git a/tests/ut_translations/ut_translations.h b/tests/ut_translations/ut_translations.h new file mode 100644 index 000000000..480b9a1ea --- /dev/null +++ b/tests/ut_translations/ut_translations.h @@ -0,0 +1,78 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef UT_TRANSLATIONS_H +#define UT_TRANSLATIONS_H + + +#include +#include +#define private public +#include +#undef private + +Q_DECLARE_METATYPE(DuiLocale::Category); +Q_DECLARE_METATYPE(DuiLocale); + +class Ut_Translations : public QObject +{ + Q_OBJECT + +private: + QCoreApplication *qap; + +private slots: + void initTestCase(); + void init(); + void cleanupTestCase(); + void cleanup(); + + void testinstallTrCatalogThenUseQtTr_data(); + void testinstallTrCatalogThenUseQtTr(); + void testOriginalQtTr_data(); + void testOriginalQtTr(); + void testQtTrId_data(); + void testQtTrId(); + void testQtTrIdLocalizedNumbers_data(); + void testQtTrIdLocalizedNumbers(); + void testQtTrIdLocalizedNumbersPlural_data(); + void testQtTrIdLocalizedNumbersPlural(); + void testQtTrIdMultipleVariable_data(); + void testQtTrIdMultipleVariable(); + void testQtTrIdMultipleVariableWithPlural_data(); + void testQtTrIdMultipleVariableWithPlural(); + void testGettingTheDefaultLocaleFromTheEnvironment_data(); + void testGettingTheDefaultLocaleFromTheEnvironment(); + void testCreatingAndDestroyingLocales(); + void benchmarkDuiLocaleConstructorAndDelete(); + void benchmarkDuiLocaleConstructorAndDeleteStack(); + void benchmarkQLocaleConstructorAndDelete(); + void benchmarkQLocaleConstructorAndDeleteStack(); + void benchmarkDuiLocaleAssignmentOperator(); + void benchmarkDuiLocaleAssignmentOperatorStack(); + void benchmarkQLocaleAssignmentOperator(); + void benchmarkQLocaleAssignmentOperatorStack(); + void benchmarkDuiLocaleCopyConstructorAndDelete(); + void benchmarkDuiLocaleCopyConstructorAndDeleteStack(); + void benchmarkQLocaleCopyConstructorAndDelete(); + void benchmarkQLocaleCopyConstructorAndDeleteStack(); +}; + + +#endif diff --git a/tests/ut_translations/ut_translations.pro b/tests/ut_translations/ut_translations.pro new file mode 100644 index 000000000..50eabb52a --- /dev/null +++ b/tests/ut_translations/ut_translations.pro @@ -0,0 +1,10 @@ +include(../common_top.pri) + +TARGET = ut_translations + +# Input +HEADERS += ut_translations.h +SOURCES += ut_translations.cpp + +include(../common_bot.pri) + diff --git a/tools/.gitignore b/tools/.gitignore new file mode 100644 index 000000000..8d762b2b4 --- /dev/null +++ b/tools/.gitignore @@ -0,0 +1,2 @@ +.dummy +dui-servicefwgen diff --git a/tools/build-widgetsgallery.xml b/tools/build-widgetsgallery.xml new file mode 100644 index 000000000..d06251850 --- /dev/null +++ b/tools/build-widgetsgallery.xml @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tools/dui-servicefwgen.d/dui-servicefwgen.cpp b/tools/dui-servicefwgen.d/dui-servicefwgen.cpp new file mode 100644 index 000000000..2cd6ceeb5 --- /dev/null +++ b/tools/dui-servicefwgen.d/dui-servicefwgen.cpp @@ -0,0 +1,896 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace +{ + const QString command("qdbusxml2cpp"); + QString upperCamelServiceName; + QString lowerServiceName; + QString xmlFilename; + QString newXmlFilename; + QString chainTag; + QString asyncTag; + QString upperCamelProxyName; + QString proxyCppFilename; + QString proxyHeaderFilename; + QString newProxyHeaderFilename; + QString wrapperHeaderFilename; + QString wrapperCppFilename; + QString wrapperHeaderGuard; + QString upperCamelAdaptorName; + QString adaptorCppFilename; + QString newAdaptorCppFilename; + QString newAdaptorHeaderFilename; + QString adaptorHeaderFilename; + QString allSignals; + QString allConnectSignals; + QHash doc; + QString docTag; + QString cwd("."); + QString pid; + bool needsDuiApplication; + QString hideThisWindowCode("\n\ + // hide this window\n\ + {\n\ + // Tell the window to not to be shown in the switcher\n\ + Atom skipTaskbarAtom = XInternAtom(QX11Info::display(), \"_NET_WM_STATE_SKIP_TASKBAR\", False);\n\ +\n\ + Atom netWmStateAtom = XInternAtom(QX11Info::display(), \"_NET_WM_STATE\", False);\n\ + QVector atoms;\n\ + atoms.append(skipTaskbarAtom);\n\ + XChangeProperty(QX11Info::display(), windowId, netWmStateAtom, XA_ATOM, 32, PropModeReplace, (unsigned char *)atoms.data(), atoms.count());\n\ + XSync(QX11Info::display(), False);\n\ + }\n"); +}; + +void removeNewXmlFile() +{ + QFile newXmlFile(newXmlFilename); + newXmlFile.remove(); +} + +void chomp(QString in) +{ + in.remove(QRegExp("\n$")); +} + +QString botBitH() +{ + return QString("\ +\n\ +public:\n\ + /*!\n\ + * @brief Constructs a base interface\n\ + * @param preferredService, define the preferred service provider. Leave\n\ + empty if no preferred provider. In most cases, this should be left\n\ + empty.\n\ + * @param parent Parent object\n\ + */\n\ +\n\ + " + upperCamelServiceName + "( const QString& preferredService = \"\", QObject* parent = 0 );\n\ +\n\ + /*!\n\ + * @brief Set the service name\n\ + * @param service Name of the desired service\n\ + */\n\ +\n\ + void setService(const QString & service);\n\ +Q_SIGNALS:\n\ +" + allSignals + "\n\ +\n\ +};\n\ +#endif"); + } + + QString botBitC() + { + return QString("\ + " + upperCamelServiceName + "::" + upperCamelServiceName + "( const QString& preferredService, QObject* parent )\n\ + : DuiServiceFwBaseIf( " + upperCamelProxyName + "::staticInterfaceName(), parent )\n\ + {\n\ + // Resolve the provider service name\n\ + service = resolveServiceName( interface, preferredService );\n\ + \n\ + bool serviceNameInvalid = service.contains( \" \" ); // \"not provided\" - when the service wouldn't run\n\ + if ( serviceNameInvalid ) {\n\ + service.clear();\n\ + }\n\ +\n\ + if (!service.isEmpty()) {\n\ + // Construct the D-Bus proxy\n\ + interfaceProxy = new " + upperCamelProxyName + "( service, \"/\", QDBusConnection::sessionBus(), this );\n\ + // allConnectSignals go here (empty block if none)\n\ +" + allConnectSignals + "\n\ + }\n\ +}\n\ +\n\ +void " + upperCamelServiceName + "::setService(const QString & service)\n\ +{\n\ + if (service.isEmpty()) return;\n\ +\n\ + this->service = service;\n\ +\n\ + if ( interfaceProxy ) {\n\ + delete interfaceProxy;\n\ + interfaceProxy = 0;\n\ + }\n\ + interfaceProxy = new " + upperCamelProxyName + "( service, \"/\", QDBusConnection::sessionBus(), this );\n\ + {\n\ +" + allConnectSignals + "\n\ + }\n\ +}"); + } + + QString middleBitH() + { + return QString("\ +class " + upperCamelServiceName + " : public DuiServiceFwBaseIf\n\ +{\n\ +Q_OBJECT\n\ +\n\ +public:"); + } + + QString topBitH() + { + QString commandLine(QCoreApplication::arguments().join(" ")); + + return QString("\ +#ifndef " + wrapperHeaderGuard + "\n\ + #define " + wrapperHeaderGuard + "\n\ +\n\ +/*\n\ + * automatically generated with the command line :\n\ + * " + commandLine + "\n\ + */\n\ +\n\ +#include \n\ +\n\ +#include \n\ +#include <" + proxyHeaderFilename + ">\n"); + } + + QString topBitC() + { + QString commandLine(QCoreApplication::arguments().join(" ")); + + return QString("\ + /*\n\ + * automatically generated with the command line :\n\ + * " + commandLine + "\n\ + */\n\ + \n\ +#include \"" + wrapperHeaderFilename + "\"\n"); + } + + QStringList getParamNames(QString parameters) + { + QStringList retVal; + + QStringList typesAndNames = parameters.split(","); + + for (int typeAndNameIndex = 0; typeAndNameIndex < typesAndNames.size(); ++typeAndNameIndex) { + QString typeAndName(typesAndNames[ typeAndNameIndex ]); + QStringList bits = typeAndName.split(QRegExp("\\W+")); + QString name = bits.last(); + + retVal.append(name); + } + + return retVal; + } + + void processAdaptorCppFile() + { + QStringList ifSignals; + + QFile adaptorCppFile(adaptorCppFilename); + if (!adaptorCppFile.open(QIODevice::ReadOnly | QIODevice::Text)) { + qCritical("Could not open %s", qPrintable(adaptorCppFilename)); + exit(-1); + } + QTextStream adaptorCppFileStream(&adaptorCppFile); + + QFile newAdaptorCppFile(newAdaptorCppFilename); + if (!newAdaptorCppFile.open(QIODevice::WriteOnly | QIODevice::Text)) { + qCritical("Could not open %s", qPrintable(adaptorCppFilename)); + exit(-1); + } + QTextStream newAdaptorCppStream(&newAdaptorCppFile); + + bool inChainTask = false; + bool needGoBack = false; + + while (!adaptorCppFileStream.atEnd()) { + QString line = adaptorCppFileStream.readLine(); + chomp(line); + + // remove doctag - can be more than one per line + line.remove(QRegExp(docTag + "\\d+")); + + // add chaining code to NEWADAPTOR + { + // always remove asyncTag, since we don't care about it in the cpp file + line.remove(asyncTag); + + if (needsDuiApplication && line.contains(QRegExp("#include "))) { + newAdaptorCppStream << endl; + newAdaptorCppStream << "#include " << endl; + newAdaptorCppStream << "#include " << endl; + newAdaptorCppStream << "#include " << endl; + newAdaptorCppStream << "#include " << endl; + newAdaptorCppStream << "#include " << endl; + newAdaptorCppStream << "#include " << endl; + newAdaptorCppStream << "#include " << endl; + newAdaptorCppStream << "#include " << endl; + newAdaptorCppStream << "#include " << endl; + newAdaptorCppStream << "#include " << endl; + newAdaptorCppStream << endl; + newAdaptorCppStream << line << endl; + } else if (needsDuiApplication && line.contains("QDBusAbstractAdaptor(parent)")) { + newAdaptorCppStream << line + "," << endl; + newAdaptorCppStream << " backServiceName()," << endl; + newAdaptorCppStream << " windowId(-1)" << endl; + } else if (line.contains(newXmlFilename)) { + line.replace(newXmlFilename, xmlFilename); + newAdaptorCppStream << line << endl; + } else if (inChainTask) { + line.remove(chainTag); + if (line == "{") { + newAdaptorCppStream << line << endl; + newAdaptorCppStream << " this->windowId = windowId;" << endl; + newAdaptorCppStream << " this->backServiceName = backServiceName;" << endl; + newAdaptorCppStream << endl; + } else if (line.contains("return") || line == "}") { // match end of function - need to add the connect *before* the return, if there is one + newAdaptorCppStream << endl; + newAdaptorCppStream << " DuiApplication::instance()->activeWindow()->setWindowTitle( windowTitle );" << endl; + newAdaptorCppStream << " DuiApplicationWindow *appWindow = DuiApplication::activeApplicationWindow();" << endl; + newAdaptorCppStream << " if (appWindow != 0) {" << endl; + newAdaptorCppStream << " appWindow->currentPage()->setEscapeButtonMode( DuiEscapeButtonPanelModel::BackMode );" << endl; + newAdaptorCppStream << " // connect to the back button - assumes the above 'showImage' opens a" << endl; + newAdaptorCppStream << " // new window and so the window referred to below is already the top one" << endl; + newAdaptorCppStream << " connect(appWindow->currentPage(), SIGNAL(backButtonClicked())," << endl; + newAdaptorCppStream << " this, SLOT(goBack()));" << endl; + newAdaptorCppStream << " }" << endl; + newAdaptorCppStream << endl; + newAdaptorCppStream << " // update the X server" << endl; + newAdaptorCppStream << " {" << endl; + newAdaptorCppStream << " XPropertyEvent p;" << endl; + newAdaptorCppStream << " p.send_event = True;" << endl; + newAdaptorCppStream << " p.display = QX11Info::display();" << endl; + newAdaptorCppStream << " p.type = PropertyNotify;" << endl; + newAdaptorCppStream << " p.window = RootWindow(p.display, 0);" << endl; + newAdaptorCppStream << " p.atom = XInternAtom(p.display, \"_NET_CLIENT_LIST\", False);" << endl; + newAdaptorCppStream << " p.state = PropertyNewValue;" << endl; + newAdaptorCppStream << " p.time = CurrentTime;" << endl; + newAdaptorCppStream << " XSendEvent(p.display, p.window, False, PropertyChangeMask," << endl; + newAdaptorCppStream << " (XEvent*)&p);" << endl; + newAdaptorCppStream << endl; + newAdaptorCppStream << " XSync(QX11Info::display(), False);" << endl; + newAdaptorCppStream << " }" << endl; + newAdaptorCppStream << endl; + newAdaptorCppStream << line << endl; + inChainTask = false; + } else { + newAdaptorCppStream << line << endl; + } + } else if (line.contains(chainTag)) { + line.remove(chainTag); + // remove CHAINTASK + line.replace("(", "(const QString &backServiceName, const QString &windowTitle, const uint windowId, "); + newAdaptorCppStream << line << endl; + inChainTask = true; + needGoBack = true; + } else { + newAdaptorCppStream << line << endl; + } + } + } + + if (needGoBack) { + newAdaptorCppStream << "\ +void " + upperCamelAdaptorName + "::goBack()\n\ +{\n\ + qDebug() << __PRETTY_FUNCTION__;\n\ +\n\ + bool backServiceRegistered = ( windowId != -1 );\n\ + if ( backServiceRegistered ) {\n\ + DuiApplicationIfProxy duiApplicationIfProxy(backServiceName, this);\n\ +\n\ + if (duiApplicationIfProxy.connection().isConnected()) {\n\ + qDebug() << \"Launching \" << backServiceName;\n\ + duiApplicationIfProxy.launch();\n\ + } else {\n\ + qWarning() << \"Could not launch\" << backServiceName;\n\ + qWarning() << \"DBus not connected?\";\n\ + }\n\ +\n\ + // unhide the chain parent's window\n\ + {\n\ + // Tell the window to not to be shown in the switcher\n\ + XDeleteProperty(QX11Info::display(), windowId, XInternAtom(QX11Info::display(), \"_NET_WM_STATE\", False));\n\ + XSync(QX11Info::display(), False);\n\ + }\n\ +\n\ + qWarning() << \"quitting - bye bye\";\n\ + QTimer::singleShot( 0, QApplication::instance(), SLOT( quit() ) );\n\ + } else {\n\ + qWarning() << \"backService is not registered: not going back\";\n\ + }\n\ +}" << endl; + } + + newAdaptorCppFile.close(); + adaptorCppFile.close(); + + // mv new adaptor header file (with chain parameters added) + // to replace one produced by qdbusxml2cpp + adaptorCppFile.remove(); + newAdaptorCppFile.rename(adaptorCppFilename); + + removeNewXmlFile(); + } + + void processAdaptorHeaderFile() + { + QStringList ifSignals; + + QFile adaptorHeaderFile(adaptorHeaderFilename); + if (!adaptorHeaderFile.open(QIODevice::ReadOnly | QIODevice::Text)) { + qCritical("Could not open %s", qPrintable(adaptorHeaderFilename)); + exit(-1); + } + QTextStream adaptorHeaderFileStream(&adaptorHeaderFile); + + QFile newAdaptorHeaderFile(newAdaptorHeaderFilename); + if (!newAdaptorHeaderFile.open(QIODevice::WriteOnly | QIODevice::Text)) { + qCritical("Could not open %s", qPrintable(adaptorHeaderFilename)); + exit(-1); + } + QTextStream newAdaptorHeaderStream(&newAdaptorHeaderFile); + + bool hasChains = false; + + while (!adaptorHeaderFileStream.atEnd()) { + QString line = adaptorHeaderFileStream.readLine(); + chomp(line); + + // remove doctag - can be more than one per line + line.remove(QRegExp(docTag + "\\d+")); + + // add chaining code to NEWADAPTOR + { + if (line.contains("Q_SIGNALS:")) { + if (hasChains) { + newAdaptorHeaderStream << " void goBack();" << endl; + newAdaptorHeaderStream << "" << endl; + newAdaptorHeaderStream << "private:" << endl; + newAdaptorHeaderStream << " QString backServiceName;" << endl; + newAdaptorHeaderStream << " int windowId;" << endl; + newAdaptorHeaderStream << "" << endl; + } + newAdaptorHeaderStream << line << endl; + } else if (line.contains(QRegExp("chainTask=\\\\\"\\w+\\\\\"")) || line.contains(QRegExp("asyncTask=\\\\\"\\w+\\\\\""))) { // process comment - remember the backslashes are in the source too, hence so many of them + // remove asyncTask attribute + { + QRegExp matchThis("asyncTask=\\\\\"\\w+\\\\\"\\s*"); + if (line.contains(matchThis)) { + line.remove(matchThis); + line.remove(asyncTag); + } + } + + // remove asyncTask attribute + bool isChainTask = false; + { + QRegExp matchThis("chainTask=\\\\\"(\\w+)\\\\\"\\s*"); + if (line.contains(matchThis)) { + line.remove(matchThis); + isChainTask = matchThis.cap(1).contains("true"); + line.remove(chainTag); + } + } + + // remove extraneous spaces (inserted randomly by qdbusxml2cpp?) + line.replace(QRegExp("\\s+(/*>)"), "\\1"); + + newAdaptorHeaderStream << line << endl; + + // this has to be printed after the method tag, above + if (isChainTask) { + newAdaptorHeaderStream << "\" \\n\"" << endl; + newAdaptorHeaderStream << "\" \\n\"" << endl; + newAdaptorHeaderStream << "\" \\n\"" << endl; + } + } else if (line.contains(chainTag + "(") || line.contains(asyncTag + "(")) { // add parameters to the chain methods + if (line.contains(asyncTag)) { + line.remove(asyncTag); + QRegExp matchThis("(\\w+)(\\s+)(\\w+)\\("); + line.replace(matchThis, "Q_NOREPLY \\1\\2\\3("); // put Q_NOREPLY before the first word on the line (which should be 'void', but perhaps not) + + // make warning if type is not void + line.contains(matchThis); + QString type = matchThis.cap(1); + QString method = matchThis.cap(3); + if (type != "void") { + QString prototype(line); + + // clean up prototype and method name for warning message + prototype.remove(chainTag); + prototype.remove(QRegExp("^\\s+")); + method.remove(chainTag); + qDebug() << "WARNING: " + prototype; + qDebug() << " : asyncTask=\"true\" specified for " + method + "(), but type is " + type; + qDebug() << " : return type should be void for async methods - did you really mean this?"; + qDebug() << " : consider editing the xml to make the return type \'void\'"; + } + } + + if (line.contains(chainTag)) { + hasChains = true; + line.remove(chainTag); + line.replace("(", "(const QString &backServiceName, const QString &windowTitle, const uint windowId, "); + } + + newAdaptorHeaderStream << line << endl; + } else { + // remove extraneous spaces (inserted randomly by qdbusxml2cpp?) + line.replace(QRegExp("\\s+(/*>)"), "\\1"); + + newAdaptorHeaderStream << line << endl; + } + } + } + + newAdaptorHeaderFile.close(); + adaptorHeaderFile.close(); + + // mv new adaptor header file (with chain parameters added) + // to replace one produced by qdbusxml2cpp + adaptorHeaderFile.remove(); + newAdaptorHeaderFile.rename(adaptorHeaderFilename); + + // remove temporary file + removeNewXmlFile(); + } + + void processProxyHeaderFile() + { + QStringList ifSignals; + + QFile proxyHeaderFile(proxyHeaderFilename); + if (!proxyHeaderFile.open(QIODevice::ReadOnly | QIODevice::Text)) { + qCritical("Could not open %s", qPrintable(proxyHeaderFilename)); + exit(-1); + } + QTextStream proxyHeaderStream(&proxyHeaderFile); + + QFile newProxyHeaderFile(newProxyHeaderFilename); + if (!newProxyHeaderFile.open(QIODevice::WriteOnly | QIODevice::Text)) { + qCritical("Could not open %s", qPrintable(newProxyHeaderFilename)); + exit(-1); + } + QTextStream newProxyHeaderStream(&newProxyHeaderFile); + + QFile wrapperHeaderFile(wrapperHeaderFilename); + if (!wrapperHeaderFile.open(QIODevice::WriteOnly | QIODevice::Text)) { + qCritical("Could not open %s", qPrintable(wrapperHeaderFilename)); + exit(-1); + } + QTextStream wrapperHeaderStream(&wrapperHeaderFile); + + QFile wrapperCppFile(wrapperCppFilename); + if (!wrapperCppFile.open(QIODevice::WriteOnly | QIODevice::Text)) { + qCritical("Could not open %s", qPrintable(wrapperCppFilename)); + exit(-1); + } + QTextStream wrapperCppStream(&wrapperCppFile); + + wrapperCppStream << topBitC() << endl; + wrapperHeaderStream << topBitH() << endl; + + bool inSignalSection = false; + bool inChainTask = false; + + while (!proxyHeaderStream.atEnd()) { + QString line = proxyHeaderStream.readLine(); + chomp(line); + + // add documentation and remove doc tags here + // note that middle bit is added here too, so it's not just about doc + if (line.contains(QRegExp("^class"))) { + if (!doc[ 0 ].isEmpty()) { + QStringList thisDoc(doc[ 0 ]); + + // adjust indentation + QRegExp matchThis("^(\\s+)"); + if (thisDoc.join("\n").contains(matchThis)) { + thisDoc.replaceInStrings(QRegExp("^" + matchThis.cap(1)), ""); + } + wrapperHeaderStream << thisDoc.join("\n") << endl; + } + wrapperHeaderStream << middleBitH() << endl; + } else { + for (int docTagNo = 1; docTagNo < doc.size(); ++docTagNo) { + QString fullDocTag = docTag + QString::number(docTagNo); + if (line.contains(fullDocTag)) { + line.remove(fullDocTag); + if (!line.contains("return")) { + QStringList thisDoc = doc[ docTagNo ]; + + if (!thisDoc.isEmpty()) { + // adjust indentation + QRegExp matchThis("^(\\s+)"); + if (thisDoc.join("\n").contains(matchThis)) { + QString correctIndentation(4, ' '); + thisDoc.replaceInStrings(QRegExp("^" + matchThis.cap(1)), correctIndentation); + } + wrapperHeaderStream << endl; + wrapperHeaderStream << thisDoc.join("\n") << endl; + } + } + } + } + } + line.remove(QRegExp(docTag + "\\d+")); + + // add chaining code to NEWPROXY + { + // always remove asyncTag, since we don't care about it in the cpp file + line.remove(asyncTag); + + if (needsDuiApplication && line.contains(QRegExp("#include "))) { + newProxyHeaderStream << "#include " << endl; + newProxyHeaderStream << "#include " << endl; + newProxyHeaderStream << "#include " << endl; + newProxyHeaderStream << "#include " << endl; + newProxyHeaderStream << "#include " << endl; + newProxyHeaderStream << "#include " << endl; + newProxyHeaderStream << "#include " << endl; + newProxyHeaderStream << "#include " << endl; + newProxyHeaderStream << "#include " << endl; + newProxyHeaderStream << endl; + newProxyHeaderStream << line << endl; + } else if (needsDuiApplication && line.contains(newXmlFilename)) { + line.replace(newXmlFilename, xmlFilename); + newProxyHeaderStream << line << endl; + } else if (inChainTask) { + if (line.contains("QList")) { + newProxyHeaderStream << " Qt::HANDLE windowId = DuiApplication::instance()->activeWindow()->winId();" << endl; + newProxyHeaderStream << " QString windowTitle = DuiApplication::instance()->activeWindow()->windowTitle();" << endl; + newProxyHeaderStream << " QString goBackServiceName = DuiComponentData::instance()->serviceName();" << endl; + newProxyHeaderStream << "" << endl; + newProxyHeaderStream << line << endl; + newProxyHeaderStream << " argumentList << qVariantFromValue(goBackServiceName);" << endl; + newProxyHeaderStream << " argumentList << qVariantFromValue(windowTitle);" << endl; + newProxyHeaderStream << " argumentList << qVariantFromValue((uint)windowId);" << endl; + } else if (line.contains("return")) { + + newProxyHeaderStream << hideThisWindowCode << endl; + + line.remove(chainTag); + newProxyHeaderStream << line << endl; + inChainTask = false; + } else { + newProxyHeaderStream << line << endl; + } + } else if (line.contains(chainTag)) { + line.remove(chainTag); + newProxyHeaderStream << line << endl; + inChainTask = true; + } else { + newProxyHeaderStream << line << endl; + } + } + + if (inSignalSection) { + bool atEndOfSignalSection = (line == "};"); + if (atEndOfSignalSection) { + inSignalSection = false; + } else { + ifSignals.append(line); + } + } else { + if (line.contains("Q_SIGNALS:")) { + inSignalSection = true; + } else { + QRegExp matchThis("inline\\s+QDBusPendingReply<([^>]*)>\\s*(\\w+)\\(([^)]*)\\)"); + if (line.contains(matchThis)) { + QString returnType = matchThis.cap(1); + QString methodName = matchThis.cap(2); + QString parameters = matchThis.cap(3); + + if (returnType.isEmpty()) { + returnType = "void"; + } + + QStringList paramNames = getParamNames(parameters); + + wrapperHeaderStream << " " + returnType + " " + methodName + "( " + parameters + " );" << endl; + + wrapperCppStream << returnType + " " + upperCamelServiceName + "::" + methodName + "( " + parameters + " )" << endl; + wrapperCppStream << "{" << endl; + if (returnType == "void") { + wrapperCppStream << " static_cast<" + upperCamelServiceName + "Proxy*>(interfaceProxy)->" + methodName + "( " + paramNames.join(", ") + " );" << endl; + } else { + wrapperCppStream << " return qobject_cast<" + upperCamelServiceName + "Proxy*>(interfaceProxy)->" + methodName + "( " + paramNames.join(", ") + " ).value();" << endl; + } + wrapperCppStream << "}\n" << endl; + } + } + } + } + + allSignals = ifSignals.join("\n"); + + // process signals, removing void and param names + QStringList connectSignals; + for (int thisSignalIndex = 0; thisSignalIndex < ifSignals.size(); ++thisSignalIndex) { + QString thisSignal = ifSignals.at(thisSignalIndex); + + QString signalName; + QString signature; + QRegExp matchThis("^\\s+void\\s+(\\w+)\\(([^)]*)\\);$"); + if (thisSignal.contains(matchThis)) { + signalName = matchThis.cap(1); + signature = matchThis.cap(2); + } + + QStringList typesOnly; + QStringList paramsAndTypes = signature.split(','); + for (int thisParamAndTypeIndex = 0; thisParamAndTypeIndex < paramsAndTypes.size(); ++thisParamAndTypeIndex) { + QString thisParamsAndType = paramsAndTypes.at(thisParamAndTypeIndex); + // remove last word + QRegExp matchThis("(.*)\\b\\w+$"); + if (thisParamsAndType.contains(matchThis)) { + typesOnly.append(matchThis.cap(1)); + } + } + QString joinedTypes(typesOnly.join(",")); + + connectSignals.append("\ + connect( interfaceProxy, SIGNAL( " + signalName + "( " + joinedTypes + " ) ),\ + this, SIGNAL( " + signalName + "( " + joinedTypes + " ) ) );\ + "); + } + + allConnectSignals = connectSignals.join("\n"); + + wrapperCppStream << botBitC() << endl; + wrapperHeaderStream << botBitH() << endl; + + // mv new proxy header file (with chain parameters added) + // to replace one produced by qdbusxml2cpp + proxyHeaderFile.remove(); + newProxyHeaderFile.rename(proxyHeaderFilename); + + // remove temporary file + removeNewXmlFile(); + } + +// add a tag to the name of chain and async methods in the xml file +// so that we can easily tell which methods are to be chained/asynched after they are processed by qdbusxml2cpp + void preprocessXML() + { + QString inDoc("outOfDoc"); + int docTagNo = -1; + QFile xmlFile(xmlFilename); + if (!xmlFile.open(QIODevice::ReadOnly | QIODevice::Text)) { + qCritical("Could not open %s", qPrintable(xmlFilename)); + exit(-1); + } + QTextStream xmlStream(&xmlFile); + + QFile newXmlFile(newXmlFilename); + if (!newXmlFile.open(QFile::WriteOnly | QFile::Truncate)) { + qCritical("Could not open %s", qPrintable(newXmlFilename)); + exit(-1); + } + QTextStream newXmlStream(&newXmlFile); + + while (!xmlStream.atEnd()) { + QString line = xmlStream.readLine(); + + // tag tasks + if (line.contains("chainTask=\"true\"")) { + // add chaintag + QRegExp matchThis("name=\"([^\"]+)\""); + line.replace(matchThis, "name=\"\\1" + chainTag + "\""); + needsDuiApplication = true; + } + if (line.contains("asyncTask=\"true\"")) { + // add asynctag + QRegExp matchThis("name=\"([^\"]+)\""); + line.replace(matchThis, "name=\"\\1" + asyncTag + "\""); + needsDuiApplication = true; + } + + // tag the interfaces and methods + if (line.contains("")) { + // record entry of doc blocks + inDoc = "openDoc"; + } else if (line.contains("")) { + // record exit of doc blocks + inDoc = "closeDoc"; + } + + if (inDoc == "insideDoc") { + // record doc lines + doc[ docTagNo ] << line; + } else if (inDoc == "openDoc") { + inDoc = "insideDoc"; + } else if (inDoc == "closeDoc") { + inDoc = "outsideDoc"; + } else { + newXmlStream << line << endl; + } + } + + newXmlStream.flush(); + xmlStream.flush(); + } + + void runQDBusXml2Cpp(const QStringList ¶ms) + { + QProcess qdbusxml2cpp; + qdbusxml2cpp.setWorkingDirectory(cwd); + + qdbusxml2cpp.start(command, params); + if (!qdbusxml2cpp.waitForStarted()) + qCritical() << qdbusxml2cpp.error(); + if (!qdbusxml2cpp.waitForFinished()) + qCritical() << "did not finish"; + } + + void usage() + { + qDebug() << "usage: $0 [-a|-p] interfaceName"; + qDebug() << " -a generate adaptor files"; + qDebug() << " -p generate proxy files"; + qDebug() << " -h this help"; + exit(1); + } + + int main(int argc, char *argv[]) + { + QCoreApplication *app = new QCoreApplication(argc, argv); + Q_UNUSED(app); + + QString interfaceName(""); + pid = QString::number(QCoreApplication::applicationPid()); + + if (argc == 1) { + usage(); + } + + QHash opts; + opts[ "a" ] = false; + opts[ "p" ] = false; + + //foreach (QString arg, QStringList( argv ) ) { + for (int argIndex = 1; argIndex < argc; ++argIndex) { + QString arg(argv[ argIndex ]); + + if (arg == "-h") { + usage(); + } else if (arg == "-a") { + opts[ "a" ] = true; + if (opts[ "p" ]) { + qDebug() << "both -p and -a supplied"; + qDebug() << "disabling proxy generation"; + opts[ "p" ] = 0; + } + } else if (arg == "-p") { + opts[ "p" ] = true; + if (opts[ "a" ]) { + qDebug() << "both -p and -a supplied"; + qDebug() << "disabling adaptor generation"; + opts[ "a" ] = false; + } + } else { + QStringList bits = arg.split("/"); + + interfaceName = bits.takeLast(); + QString interfacePath = bits.join("/"); + if (!interfacePath.isEmpty()) { + cwd = interfacePath; + } + } + } + + if (! opts[ "a" ] && ! opts[ "p" ]) { + qDebug() << "neither -p or -a specified"; + qDebug() << "assuming -p"; + opts[ "p" ] = true; + } + + if (interfaceName.isEmpty()) { + usage(); + } + + // make different upper/lower case versions from the Upper Camel version + upperCamelServiceName = interfaceName.split(".").last(); + lowerServiceName = upperCamelServiceName.toLower(); + + xmlFilename = interfaceName + ".xml"; + newXmlFilename = interfaceName + "-" + pid + ".xml"; + + // tag to add to chained methods in the xml file + chainTag = "CHAINTASK"; + asyncTag = "ASYNCTASK"; + docTag = "DOCTAG"; + + upperCamelProxyName = ""; + proxyCppFilename = ""; + proxyHeaderFilename = ""; + newProxyHeaderFilename = ""; + wrapperHeaderFilename = ""; + wrapperCppFilename = ""; + wrapperHeaderGuard = ""; + upperCamelAdaptorName = ""; + adaptorCppFilename = ""; + newAdaptorCppFilename = ""; + newAdaptorHeaderFilename = ""; + needsDuiApplication = false; + + preprocessXML(); + + if (opts[ "p" ]) { + upperCamelProxyName = upperCamelServiceName + "Proxy"; + QString proxyBase = lowerServiceName + "proxy"; + proxyCppFilename = proxyBase + ".cpp"; + proxyHeaderFilename = proxyBase + ".h"; + newProxyHeaderFilename = proxyBase + "-" + pid + ".h"; + wrapperHeaderFilename = lowerServiceName + ".h"; + wrapperCppFilename = lowerServiceName + ".cpp"; + wrapperHeaderGuard = wrapperHeaderFilename.toUpper().replace(".", "_"); + + runQDBusXml2Cpp(QStringList() << "-c" << upperCamelProxyName << "-p" << proxyBase << newXmlFilename); + processProxyHeaderFile(); + } else { + upperCamelAdaptorName = upperCamelServiceName + "Adaptor"; + QString adaptorBase = lowerServiceName + "adaptor"; + adaptorCppFilename = adaptorBase + ".cpp"; + adaptorHeaderFilename = adaptorBase + ".h"; + newAdaptorCppFilename = adaptorBase + "-" + pid + ".cpp"; + newAdaptorHeaderFilename = adaptorBase + "-" + pid + ".h"; + + runQDBusXml2Cpp(QStringList() << "-c" << upperCamelAdaptorName << "-a" << adaptorBase << newXmlFilename); + processAdaptorCppFile(); + processAdaptorHeaderFile(); + } + } diff --git a/tools/dui-servicefwgen.d/dui-servicefwgen.d.pro b/tools/dui-servicefwgen.d/dui-servicefwgen.d.pro new file mode 100644 index 000000000..2db2266b2 --- /dev/null +++ b/tools/dui-servicefwgen.d/dui-servicefwgen.d.pro @@ -0,0 +1,12 @@ +include(../../mkspecs/common.pri) + +TEMPLATE = app +TARGET = ../dui-servicefwgen +DEPENDPATH += . +INCLUDEPATH += . + +# Input +SOURCES += dui-servicefwgen.cpp + +target.path = $$DUI_INSTALL_BIN +INSTALLS += target diff --git a/tools/dui-servicefwgen.d/dui-servicefwgen.pl b/tools/dui-servicefwgen.d/dui-servicefwgen.pl new file mode 100644 index 000000000..188bc9068 --- /dev/null +++ b/tools/dui-servicefwgen.d/dui-servicefwgen.pl @@ -0,0 +1,747 @@ +#! /usr/bin/perl -w +# This script is used to automatically generate the proxy source files, +# and the wrapper header file for an interface +use strict; + +use vars qw( + $upperCamelServiceName + $lowerServiceName + $xmlFile + $newXmlFile + $chainTag + $asyncTag + $upperCamelProxyName + $proxyCppFile + $proxyHeaderFile + $newProxyHeaderFile + $wrapperHeaderFile + $wrapperCppFile + $wrapperHeaderGuard + $upperCamelAdaptorName + $adaptorCppFile + $newAdaptorCppFile + $newAdaptorHeaderFile + $adaptorHeaderFile + $allSignals + $allConnectSignals + $needsDuiApplication + @doc + $docTag +); + +sub processAdaptorHeaderFile +{ + my @signals = (); + + open( ADAPTOR, "<$adaptorHeaderFile" ) || die( "Could not open $adaptorHeaderFile:$!" ); + open( NEWADAPTOR, ">$newAdaptorHeaderFile" ) || die( "Could not open $newAdaptorHeaderFile:$!" ); + + while () { + chomp(); + + # remove doctag - can be more than one per line + s/$docTag\d+//g; + + # add chaining code to NEWADAPTOR + { + if ( /Q_SIGNALS:/ ) { + print NEWADAPTOR " void goBack();\n"; + print NEWADAPTOR "\n"; + print NEWADAPTOR "private:\n"; + print NEWADAPTOR " QString backServiceName;\n"; + print NEWADAPTOR " int windowId;\n"; + print NEWADAPTOR "\n"; + print NEWADAPTOR "$_\n"; + } elsif ( /chainTask=\\"\w+\\"/ || /asyncTask=\\"\w+\\"/ ) { # process comment + # remove asyncTask attribute + if ( s/asyncTask=\\"\w+\\"\s*// ) { + $_ =~ s/\Q$asyncTag\E//g; + } + + # remove asyncTask attribute + my $isChainTask = 0; + if ( s/chainTask=\\"(\w+)\\"\s*// ) { + $isChainTask = ($1 =~ /true/); + $_ =~ s/\Q$chainTag\E//g; + } + + # remove extraneous spaces (inserted randomly by qdbusxml2cpp?) + $_ =~ s/\s+(\/*>)/$1/; + + print NEWADAPTOR "$_\n"; + + # this has to be printed after the method tag, above + if ( $isChainTask ) { + print NEWADAPTOR "\" \\n\"\n"; + print NEWADAPTOR "\" \\n\"\n"; + print NEWADAPTOR "\" \\n\"\n"; + } + } elsif ( /$chainTag\(/ || /$asyncTag\(/ ) { # add parameters to the chain methods + if ( s/\Q$asyncTag\E//g ) { + $_ =~ s/(\w+)(\s+)(\w+)/Q_NOREPLY $1$2$3/; # put Q_NOREPLY before the first word on the line (which should be 'void', but perhaps not) + + # make warning if type is not void + my $type = $1; + my $method = $3; + if ( $type ne "void" ) { + my $prototype = $_; + + # clean up prototype and method name for warning message + $prototype =~ s/\Q$chainTag\E//g; + $prototype =~ s/^\s+//; + $method =~ s/\Q$chainTag\E//g; + print STDERR "WARNING: $prototype\n"; + print STDERR " : asyncTask=\"true\" specified for $method(), but type is $type\n"; + print STDERR " : return type should be void for async methods - did you really mean this?\n"; + print STDERR " : consider editing the xml to make the return type \'void\'\n"; + } + } + + if ( s/\Q$chainTag\E//g ) { + $_ =~ s/\(/\(const QString \&backServiceName, const QString \&windowTitle, const uint windowId, /; + } + + print NEWADAPTOR "$_\n"; + } else { + # remove extraneous spaces (inserted randomly by qdbusxml2cpp?) + $_ =~ s/\s+(\/*>)/$1/; + + print NEWADAPTOR "$_\n"; + } + } + } + + close( NEWADAPTOR ); + close( ADAPTOR ); + + # mv new adaptor header file (with chain parameters added) + # to replace one produced by qdbusxml2cpp + unlink( $adaptorHeaderFile ); + rename( $newAdaptorHeaderFile, $adaptorHeaderFile ); + + # remove temporary file + unlink( $newXmlFile ); +} + +sub processAdaptorCppFile +{ + my @signals = (); + + open( ADAPTOR, "<$adaptorCppFile" ) || die( "Could not open $adaptorCppFile:$!" ); + open( NEWADAPTOR, ">$newAdaptorCppFile" ) || die( "Could not open $newAdaptorCppFile:$!" ); + + my $inChainTask = 0; + + while () { + chomp(); + + # remove doctag - can be more than one per line + s/$docTag\d+//g; + + # add chaining code to NEWADAPTOR + { + # always remove asyncTag, since we don't care about it in the cpp file + $_ =~ s/\Q$asyncTag\E//g; + + if ( $needsDuiApplication && /#include / ) { + print NEWADAPTOR "\n"; + print NEWADAPTOR "#include \n"; + print NEWADAPTOR "#include \n"; + print NEWADAPTOR "#include \n"; + print NEWADAPTOR "#include \n"; + print NEWADAPTOR "#include \n"; + print NEWADAPTOR "#include \n"; + print NEWADAPTOR "#include \n"; + print NEWADAPTOR "#include \n"; + print NEWADAPTOR "#include \n"; + print NEWADAPTOR "#include \n"; + print NEWADAPTOR "\n"; + print NEWADAPTOR "$_\n"; + } elsif ( $needsDuiApplication && /QDBusAbstractAdaptor\(parent\)/ ) { + print NEWADAPTOR "$_,\n"; + print NEWADAPTOR " backServiceName(),\n"; + print NEWADAPTOR " windowId(-1)\n"; + } elsif ( s/\Q$newXmlFile\E/$xmlFile/g ) { + print NEWADAPTOR "$_\n"; + } elsif ( $inChainTask ) { + $_ =~ s/\Q$chainTag\E//; + if ( /^{$/ ) { #} + print NEWADAPTOR "$_\n"; + print NEWADAPTOR " this->windowId = windowId;\n"; + print NEWADAPTOR " this->backServiceName = backServiceName;\n"; + print NEWADAPTOR "\n"; + } elsif ( /return/ || /^}$/ ) { # match end of function - need to add the connect *before* the return, if there is one + print NEWADAPTOR "\n"; + print NEWADAPTOR " DuiApplication::instance()->activeWindow()->setWindowTitle( windowTitle );\n"; + print NEWADAPTOR " DuiApplicationWindow *appWindow = DuiApplication::activeApplicationWindow();\n"; + print NEWADAPTOR " if (appWindow != 0) {\n"; + print NEWADAPTOR " appWindow->currentPage()->setEscapeButtonMode( DuiEscapeButtonPanelModel::BackMode );\n"; + print NEWADAPTOR " // connect to the back button - assumes the above 'showImage' opens a\n"; + print NEWADAPTOR " // new window and so the window referred to below is already the top one\n"; + print NEWADAPTOR " connect(appWindow->currentPage(), SIGNAL(backButtonClicked()),\n"; + print NEWADAPTOR " this, SLOT(goBack()));\n"; + print NEWADAPTOR " }\n"; + print NEWADAPTOR "\n"; + print NEWADAPTOR " // update the X server\n"; + print NEWADAPTOR " {\n"; + print NEWADAPTOR " XPropertyEvent p;\n"; + print NEWADAPTOR " p.send_event = True;\n"; + print NEWADAPTOR " p.display = QX11Info::display();\n"; + print NEWADAPTOR " p.type = PropertyNotify;\n"; + print NEWADAPTOR " p.window = RootWindow(p.display, 0);\n"; + print NEWADAPTOR " p.atom = XInternAtom(p.display, \"_NET_CLIENT_LIST\", False);\n"; + print NEWADAPTOR " p.state = PropertyNewValue;\n"; + print NEWADAPTOR " p.time = CurrentTime;\n"; + print NEWADAPTOR " XSendEvent(p.display, p.window, False, PropertyChangeMask,\n"; + print NEWADAPTOR " (XEvent*)&p);\n"; + print NEWADAPTOR "\n"; + print NEWADAPTOR " XSync(QX11Info::display(), False);\n"; + print NEWADAPTOR " }\n"; + print NEWADAPTOR "\n"; + print NEWADAPTOR "$_\n"; + $inChainTask = 0; + } else { + print NEWADAPTOR "$_\n"; + } + } elsif ( s/\Q$chainTag\E// ) { + # remove CHAINTASK + $_ =~ s/\(/\(const QString \&backServiceName, const QString \&windowTitle, const uint windowId, /; + print NEWADAPTOR "$_\n"; + $inChainTask = 1; + } else { + print NEWADAPTOR "$_\n"; + } + } + } + + print NEWADAPTOR <$newProxyHeaderFile" ) || die( "Could not open $newProxyHeaderFile:$!" ); + open( IFH, ">$wrapperHeaderFile" ) || die( "Could not open $wrapperHeaderFile:$!" ); + open( IFC, ">$wrapperCppFile" ) || die( "Could not open $wrapperCppFile:$!" ); + + print IFC topBitC(); + print IFH topBitH(); + + my $inSignalSection = 0; + my $inChainTask = 0; + + while () { + chomp(); + + # add documentation and remove doc tags here + # note that middle bit is added here too, so it's not just about doc + if ( /^class/ ) { + if ( defined( $doc[ 0 ] ) ) { + my $thisDoc = $doc[ 0 ]; + # adjust indentation + if ( $thisDoc =~ /^(\s+)/ ) { + my $noSpaces = length( $1 ); + $thisDoc =~ s/^\s{$noSpaces}//mg; + } + print IFH $thisDoc; + } + print IFH middleBitH(); + } else { + for ( my $docTagNo=1; $docTagNo<@doc; ++$docTagNo ) { + if ( s/$docTag$docTagNo// && !/return/ ) { + my $thisDoc = $doc[ $docTagNo ]; + # adjust indentation + if ( $thisDoc =~ /^(\s+)/ ) { + my $noSpaces = length( $1 ); + my $correctIndentation=' 'x4; + $thisDoc =~ s/^\s{$noSpaces}/$correctIndentation/mg; + } + print IFH "\n"; + print IFH $thisDoc; + } + } + } + s/$docTag\d+//g; + + # add chaining code to NEWPROXY + { + # always remove asyncTag, since we don't care about it in the cpp file + $_ =~ s/\Q$asyncTag\E//g; + + if ( $needsDuiApplication && /#include / ) { + print NEWPROXY "#include \n"; + print NEWPROXY "#include \n"; + print NEWPROXY "#include \n"; + print NEWPROXY "#include \n"; + print NEWPROXY "#include \n"; + print NEWPROXY "#include \n"; + print NEWPROXY "#include \n"; + print NEWPROXY "#include \n"; + print NEWPROXY "#include \n"; + print NEWPROXY "\n"; + print NEWPROXY "$_\n"; + } elsif ( $needsDuiApplication && s/\Q$newXmlFile\E/$xmlFile/g ) { + print NEWPROXY "$_\n"; + } elsif ( $inChainTask ) { + if ( /QList/ ) { + print NEWPROXY " Qt::HANDLE windowId = DuiApplication::instance()->activeWindow()->winId();\n"; + print NEWPROXY " QString windowTitle = DuiApplication::instance()->activeWindow()->windowTitle();\n"; + print NEWPROXY " QString goBackServiceName = DuiComponentData::instance()->serviceName();\n"; + print NEWPROXY "\n"; + print NEWPROXY "$_\n"; + print NEWPROXY " argumentList << qVariantFromValue(goBackServiceName);\n"; + print NEWPROXY " argumentList << qVariantFromValue(windowTitle);\n"; + print NEWPROXY " argumentList << qVariantFromValue((uint)windowId);\n"; + } elsif ( /return/ ) { + + print NEWPROXY < atoms; + atoms.append(skipTaskbarAtom); + XChangeProperty(QX11Info::display(), windowId, netWmStateAtom, XA_ATOM, 32, PropModeReplace, (unsigned char *)atoms.data(), atoms.count()); + XSync(QX11Info::display(), False); + } + +EOF + $_ =~ s/\Q$chainTag\E//; + print NEWPROXY "$_\n"; + $inChainTask = 0; + } else { + print NEWPROXY "$_\n"; + } + } elsif ( s/\Q$chainTag\E// ) { + print NEWPROXY "$_\n"; + $inChainTask = 1; + } else { + print NEWPROXY "$_\n"; + } + } + + if ( $inSignalSection ) { #{ + my $atEndOfSignalSection = /^};$/; + if ( $atEndOfSignalSection ) { + $inSignalSection = 0; + } else { + push @signals, $_; + } + } else { + if ( /Q_SIGNALS:/ ) { + $inSignalSection = 1; + } elsif ( /inline\s+QDBusPendingReply<([^>]*)>\s*(\w+)\(([^)]*)\)/ ) { + my $returnType = $1; + my $methodName = $2; + my $parameters = $3; + + $returnType = "void" if ( $returnType eq "" ); + + my @paramNames = getParamNames( $parameters ); + + print IFH " $returnType $methodName( $parameters );\n"; + + print IFC "$returnType ${upperCamelServiceName}::$methodName( $parameters )\n"; + print IFC "{\n"; + if ( $returnType eq "void" ) { + print IFC " static_cast<${upperCamelServiceName}Proxy*>(interfaceProxy)->${methodName}( ".join( ", ", @paramNames )." );\n"; + } else { + print IFC " return qobject_cast<${upperCamelServiceName}Proxy*>(interfaceProxy)->${methodName}( ".join( ", ", @paramNames )." ).value();\n"; + } + print IFC "}\n\n"; + } + } + } + + $allSignals = join( "\n", @signals ); + + # process signals, removing void and param names + my @connectSignals = (); + foreach ( @signals ) { + my ($signalName, $signature) = ($_ =~ m/^\s+void\s+(\w+)\(([^)]*)\);$/); + + my @typesOnly = (); + my @paramsAndTypes = split( ',', $signature ); + foreach ( @paramsAndTypes ) { + # remove last word + /(.*)\b\w+$/; + push @typesOnly, $1; + } + my $joinedTypes = join( ',', @typesOnly ); + + push @connectSignals, <$newXmlFile" ) || die( "Could not open $newXmlFile:$!" ); + while () { + + # tag tasks + if ( /chainTask=\"true\"/ ) { + s/name=\"([^\"]+)\"/name=\"\Q$1$chainTag\E\"/; + $needsDuiApplication = 1; + } + if ( /asyncTask=\"true\"/ ) { + s/name=\"([^\"]+)\"/name=\"\Q$1$asyncTag\E\"/; + $needsDuiApplication = 1; + } + + # tag the interfaces and methods + if ( // ) { + # record entry of doc blocks + $inDoc = "openDoc"; + } elsif ( /<\/doc>/ ) { + # record exit of doc blocks + $inDoc = "closeDoc"; + } + + if ( $inDoc eq "insideDoc" ) { + # record doc lines + $doc[ $docTagNo ] .= $_; + } elsif ( $inDoc eq "openDoc" ) { + $inDoc = "insideDoc"; + } elsif ( $inDoc eq "closeDoc" ) { + $inDoc = "outsideDoc"; + } else { + print NEWXML $_; + } + } + close( NEWXML ); + close( XML ); +} + +sub getParamNames() +{ + my ( $parameters ) = @_; + my @retVal = (); + + my @typesAndNames = split( /,/, $parameters ); + + foreach my $typeAndName ( @typesAndNames ) { + my @bits = split( /\W+/, $typeAndName ); + my $name = $bits[-1]; + + push @retVal, $name; + } + + return @retVal; +} + +sub topBitH +{ + my $commandLine = join( " ", $0, @ARGV ); + + return < + +#include +#include <$proxyHeaderFile> + +EOF +} + +sub middleBitH +{ + return <service = service; + + if ( interfaceProxy ) { + delete interfaceProxy; + interfaceProxy = 0; + } + interfaceProxy = new $upperCamelProxyName( service, "/", QDBusConnection::sessionBus(), this ); + { +$allConnectSignals + } +} +EOF +} + +sub usage() +{ + print STDERR "usage: $0 [-a|-p] interfaceName\n"; + print STDERR " -a generate adaptor files\n"; + print STDERR " -p generate proxy files\n"; + print STDERR " -h this help\n"; + exit(1); +} + +sub main() +{ + my $interfaceName=""; + + if ( @ARGV == 0 ) { + usage(); + } + + my %opts = ( + "a" => 0, + "p" => 0, + ); + + for my $arg (@ARGV) { + if ( $arg eq "-h" ) { + usage(); + } elsif ( $arg eq "-a" ) { + $opts{ "a" } = 1; + if ( $opts{ "p" } ) { + print STDERR "both -p and -a supplied\n"; + print STDERR "disabling proxy generation\n"; + $opts{ "p" } = 0; + } + } elsif ( $arg eq "-p" ) { + $opts{ "p" } = 1; + if ( $opts{ "a" } ) { + print STDERR "both -p and -a supplied\n"; + print STDERR "disabling adaptor generation\n"; + $opts{ "a" } = 0; + } + } else { + my @bits = split( "/", $arg ); + + $interfaceName = pop @bits; + my $interfacePath = join( "/", @bits ); + chdir( $interfacePath ) + if ( defined( $interfacePath ) && ($interfacePath ne "") ); + } + } + + if ( ! $opts{ "a" } && ! $opts{ "p" } ) { + print STDERR "neither -p or -a specified\n"; + print STDERR "assuming -p\n"; + $opts{ "p" } = 1; + } + + if ( $interfaceName eq "" ) { + usage(); + } + + # make different upper/lower case versions from the Upper Camel version + $upperCamelServiceName=(split(/\./, $interfaceName))[-1]; + $lowerServiceName =lc( $upperCamelServiceName ); + + $xmlFile = "$interfaceName.xml"; + $newXmlFile = "$interfaceName-$$.xml"; + + # tag to add to chained methods in the xml file + my $randomNumber = int( rand( 1000000000 ) ); + $chainTag = "CHAINTASK$randomNumber"; + $asyncTag = "ASYNCTASK$randomNumber"; + $docTag = "DOCTAG$randomNumber"; + + $upperCamelProxyName = ""; + $proxyCppFile = ""; + $proxyHeaderFile = ""; + $newProxyHeaderFile = ""; + $wrapperHeaderFile = ""; + $wrapperCppFile = ""; + $wrapperHeaderGuard = ""; + $upperCamelAdaptorName = ""; + $adaptorCppFile = ""; + $newAdaptorCppFile = ""; + $newAdaptorHeaderFile = ""; + $needsDuiApplication = 0; + + preprocessXML(); + + if ( $opts{ "p" } ) { + $upperCamelProxyName = "${upperCamelServiceName}Proxy"; + my $proxyBase = "${lowerServiceName}proxy"; + $proxyCppFile = "${proxyBase}.cpp"; + $proxyHeaderFile = "${proxyBase}.h"; + $newProxyHeaderFile = "${proxyBase}-$$.h"; + $wrapperHeaderFile = "${lowerServiceName}.h"; + $wrapperCppFile = "${lowerServiceName}.cpp"; + ( $wrapperHeaderGuard = uc($wrapperHeaderFile) ) =~ s/\./_/; + + system( "qdbusxml2cpp -c $upperCamelProxyName -p $proxyBase $newXmlFile" ); + processProxyHeaderFile(); + } else { + $upperCamelAdaptorName = "${upperCamelServiceName}Adaptor"; + my $adaptorBase = "${lowerServiceName}adaptor"; + $adaptorCppFile = "${adaptorBase}.cpp"; + $adaptorHeaderFile = "${adaptorBase}.h"; + $newAdaptorCppFile = "${adaptorBase}-$$.cpp"; + $newAdaptorHeaderFile = "${adaptorBase}-$$.h"; + + system( "qdbusxml2cpp -c $upperCamelAdaptorName -a $proxyBase $newXmlFile" ); + processAdaptorCppFile(); + processAdaptorHeaderFile(); + } +} + +main(); + +exit(0); diff --git a/tools/duiapplettester/.gitignore b/tools/duiapplettester/.gitignore new file mode 100644 index 000000000..a5c3dd033 --- /dev/null +++ b/tools/duiapplettester/.gitignore @@ -0,0 +1,2 @@ +duiapplettester + diff --git a/tools/duiapplettester/duiapplettester.cpp b/tools/duiapplettester/duiapplettester.cpp new file mode 100644 index 000000000..ed9cda309 --- /dev/null +++ b/tools/duiapplettester/duiapplettester.cpp @@ -0,0 +1,200 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiapplettester.h" + +#include +#include +#include +#include +#include +#include "duiapplettesterwindow.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Horizontal margin around the applet +static const int hMargin = 10; +// Vertical margin around the applet +static const int vMargin = 10; + +DuiAppletTester::DuiAppletTester() : + m_app(NULL), + m_metadata(NULL), + m_appletInstanceDataStore(NULL), + m_widget(NULL), + m_window(NULL), + appletSettings(NULL), + settingsDialog(NULL) +{ +} + +DuiAppletTester::~DuiAppletTester() +{ + // Set m_widget to NULL (since it's already destroyed at this point) to prevent double deletion + m_widget = NULL; + teardown(); +} + +bool DuiAppletTester::init(const DuiAppletMetaData &metaData, DuiAppletId appletId) +{ + // Try to construct a valid instance data store and bail out if not successful + m_appletInstanceDataStore = generateInstanceDataStorePath(metaData.appletBinary()); + if (m_appletInstanceDataStore == NULL) { + teardown(); + return false; + } + + // Construct applet settings and a dialog for them + appletSettings = new DuiAppletSettings(metaData.fileName(), appletId); + settingsDialog = new DuiAppletSettingsDialog(*appletSettings); + + // Load the applet + m_widget = DuiAppletLoader::loadApplet(metaData, *m_appletInstanceDataStore, *appletSettings->dataAccess()); + + if (m_widget == NULL) { + qWarning() << "Failed to construct actual applet widget."; + teardown(); + return false; + } + m_metadata = &metaData; + + // Attach a duiaction if the applet contains settings + if (appletSettings->hasSettings()) { + //% "Applet Settings" + DuiAction *action = new DuiAction(qtTrId("duiapplethandle_applet_settings"), m_widget); + connect(action, SIGNAL(triggered(bool)), this, SLOT(openAppletSettings()), Qt::QueuedConnection); + m_widget->addAction(action); + } + return true; +} + +void DuiAppletTester::openAppletSettings() +{ + settingsDialog->exec(); +} + +int DuiAppletTester::exec() +{ + if (m_widget == NULL) { + return -1; + } + + if (m_window == NULL) { + m_window = new DuiAppletTesterWindow; + connect(m_window, SIGNAL(resized(QSize)), this, SLOT(windowResized(QSize))); + +#ifndef __arm__ + // Bring back the window frame in case somebody has messed with it and removed it... + if (m_window->windowFlags() & Qt::FramelessWindowHint) { + m_window->setWindowFlags(m_window->windowFlags() ^ Qt::FramelessWindowHint); + } +#endif + } + + m_window->setWindowTitle(QString("Dui applet tester: ") + m_metadata->appletBinary()); + m_widget->setPos(0.0, 0.0); + + QGraphicsLinearLayout widgetLayout; + widgetLayout.setContentsMargins(0, 0, 0, 0); + + QGraphicsWidget *parentWidget = new QGraphicsWidget(); + parentWidget->setLayout(&widgetLayout); + widgetLayout.addItem(m_widget); + m_window->scene()->addItem(parentWidget); + parentWidget->setZValue(-1); + + QRect rect = QRect(QPoint(), m_widget->preferredSize().toSize()); + rect.adjust(0, 0, hMargin * 2, vMargin * 2); + m_window->setFrameStyle(0); + m_window->setGeometry(rect); + m_window->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + m_window->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + m_window->centerOn(0.0, 0.0); + + m_window->show(); + + return qApp->exec(); +} + +void DuiAppletTester::windowResized(const QSize &newSize) +{ + if (m_widget != NULL) { + QSizeF newWidgetSize(newSize.width() - (hMargin * 2), newSize.height() - (vMargin * 2)); + newWidgetSize.boundedTo(m_widget->maximumSize()); + newWidgetSize.expandedTo(m_widget->minimumSize()); + m_widget->setGeometry(0.0, 0.0, newWidgetSize.width(), newWidgetSize.height()); + + // Twingle with the widget position if the new window size is bigger than the scene rect. + // This makes the applet top-left corner stay in the window top-left corner. + QPointF widgetPos = m_widget->pos(); + if (m_window->sceneRect().width() < newSize.width()) { + widgetPos.setX((m_window->sceneRect().width() - newSize.width()) / 2); + } + if (m_window->sceneRect().height() < newSize.height()) { + widgetPos.setY((m_window->sceneRect().height() - newSize.height()) / 2); + } + m_widget->setPos(widgetPos); + } +} + +DuiDataStore *DuiAppletTester::generateInstanceDataStorePath(const QString &appletBinary) +{ + QString appletInstanceFileDataPath(appletBinary); + appletInstanceFileDataPath = QDir::tempPath() + '/' + appletInstanceFileDataPath.replace('/', '_'); + appletInstanceFileDataPath.append(".datastore"); + appletInstanceFileDataPath = QDir::cleanPath(appletInstanceFileDataPath); + qDebug() << "Instance file:" << appletInstanceFileDataPath; + + DuiFileDataStore *dataStore = new DuiFileDataStore(appletInstanceFileDataPath); + if (!dataStore->isReadable() || !dataStore->isWritable()) { + qWarning() << "Couldn't create applet instance data store"; + delete dataStore; + dataStore = NULL; + } + + return dataStore; +} + +void DuiAppletTester::teardown() +{ + delete m_widget; + m_widget = NULL; + delete m_appletInstanceDataStore; + m_appletInstanceDataStore = NULL; + + m_metadata = NULL; + + delete settingsDialog; + settingsDialog = NULL; + + delete appletSettings; + appletSettings = NULL; +} diff --git a/tools/duiapplettester/duiapplettester.h b/tools/duiapplettester/duiapplettester.h new file mode 100644 index 000000000..ed1c45371 --- /dev/null +++ b/tools/duiapplettester/duiapplettester.h @@ -0,0 +1,129 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETTESTER_H +#define DUIAPPLETTESTER_H + +#include +#include + +class DuiAppletMetaData; +class DuiDataStore; +class QString; +class QSize; +class DuiWidget; +class DuiAppletTesterWindow; +class DuiApplication; +class DuiSettingsLanguageBinary; +class DuiAppletSettings; +class DuiAppletSettingsDialog; +class DuiGConfDataStore; + +/*! + * A simple applet loader. Constructs an instance data store to an applet + * instance and constructs the applet widget. + */ +class DuiAppletTester : public QObject +{ + Q_OBJECT + +public: + /*! + * Constructor. + */ + DuiAppletTester(); + + /*! + * Destructor. + */ + ~DuiAppletTester(); + + /*! + * Initialize the applet. + * \param metaData Metadata of the applet. + * \param appletId AppletId of the applet. + * \return \c true if the applet was initialized correctly, \c false if something went wrong. + */ + bool init(const DuiAppletMetaData &metaData, DuiAppletId appletId); + + /*! + * Starts the applet tester. Constructs a window and starts the application + * event loop. The parameters are passed to DuiApplication. + * \return the return value of DuiApplication::exec(). + */ + int exec(); + +public slots: + /*! + * Notify this object that the window size has changed. The new size + * is passed as a parameter. + * \param newSize the new window size. + */ + void windowResized(const QSize &newSize); + +protected slots: + /*! + * \brief A slot for opening applet settings + */ + void openAppletSettings(); + +private: + /*! + * Generates an instance data store object for an applet instance. The applet binary + * name is used as an identifier. The returned data store is readable and writable. + * If no such data store can be created, this method returns \c NULL. + * \param appletBinary the applet binary name. + * \return a new data store object or \c NULL if one couldn't be constructed + */ + static DuiDataStore *generateInstanceDataStorePath(const QString &appletBinary); + + /*! + * Cleans up any resources that this class has currently reserverd. + */ + void teardown(); + + //! The application object + DuiApplication *m_app; + + //! The applet metadata + const DuiAppletMetaData *m_metadata; + + //! The applet instance data store + DuiDataStore *m_appletInstanceDataStore; + + //! The applet widget + DuiWidget *m_widget; + + //! The application's window + DuiAppletTesterWindow *m_window; + + //! A list of applet instance settings binaries read during initialization + QList instanceSettingsBinaries; + + //! A list of applet global settings binaries read during initialization + QList globalSettingsBinaries; + + //! Applet settings + DuiAppletSettings *appletSettings; + + //! Applet settings dialog + DuiAppletSettingsDialog *settingsDialog; +}; + +#endif // DUIAPPLETTESTER_H diff --git a/tools/duiapplettester/duiapplettester.pro b/tools/duiapplettester/duiapplettester.pro new file mode 100644 index 000000000..99790dbc8 --- /dev/null +++ b/tools/duiapplettester/duiapplettester.pro @@ -0,0 +1,32 @@ +include(../../mkspecs/common.pri) + +INCLUDEPATH += . \ + ../../src/include \ + ../../src/mashup/mashup +DEPENDPATH += $$INCLUDEPATH +TEMPLATE = app +TARGET = duiapplettester + +QT += xml + +win32|macx { + macx { + QMAKE_LFLAGS += -F../../lib + LIBS += -framework dui + } + win32:LIBS += -L../../lib -ldui0 +} else { + LIBS += ../../lib/libdui.so +} + +# Input +HEADERS += duiapplettester.h \ + duiapplettesterwindow.h \ + ../../src/mashup/mashup/duiappletid.h +SOURCES += main.cpp \ + duiapplettester.cpp \ + duiapplettesterwindow.cpp \ + ../../src/mashup/mashup/duiappletid.cpp +target.path = $$DUI_INSTALL_BIN +INSTALLS += target +CONFIG -= app_bundle diff --git a/tools/duiapplettester/duiapplettesterwindow.cpp b/tools/duiapplettester/duiapplettesterwindow.cpp new file mode 100644 index 000000000..4ac944f50 --- /dev/null +++ b/tools/duiapplettester/duiapplettesterwindow.cpp @@ -0,0 +1,44 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "duiapplettesterwindow.h" + +#include +#include +#include + +DuiAppletTesterWindow::DuiAppletTesterWindow() +{ + setScene(new DuiScene); + setSceneRect(QRectF(QPointF(), visibleSceneSize(Dui::Landscape))); + centerOn(sceneRect().center()); + DuiSceneManager *manager = new DuiSceneManager(scene()); + setSceneManager(manager); +} + +DuiAppletTesterWindow::~DuiAppletTesterWindow() +{ +} + +void DuiAppletTesterWindow::resizeEvent(QResizeEvent *event) +{ + setSceneRect(QRectF(QPointF(), event->size())); + DuiWindow::resizeEvent(event); + emit resized(event->size()); +} diff --git a/tools/duiapplettester/duiapplettesterwindow.h b/tools/duiapplettester/duiapplettesterwindow.h new file mode 100644 index 000000000..a1986b9e9 --- /dev/null +++ b/tools/duiapplettester/duiapplettesterwindow.h @@ -0,0 +1,55 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLETTESTERWINDOW_H +#define DUIAPPLETTESTERWINDOW_H + +#include + +/*! + * A window class for the dui applet tester application. + */ +class DuiAppletTesterWindow : public DuiWindow +{ + Q_OBJECT + +public: + DuiAppletTesterWindow(); + + /*! + * Destructor. + */ + virtual ~DuiAppletTesterWindow(); + +signals: + /*! + * A signal that gets emitted when the window size has changed. + */ + void resized(const QSize &); + +protected: + /*! + * Handler for window resizing events. + * \param event the resize event. + */ + virtual void resizeEvent(QResizeEvent *event); + +}; + +#endif // DUIAPPLETTESTERWINDOW_H diff --git a/tools/duiapplettester/main.cpp b/tools/duiapplettester/main.cpp new file mode 100644 index 000000000..96c853c0c --- /dev/null +++ b/tools/duiapplettester/main.cpp @@ -0,0 +1,85 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +/* + * A helper applet runner tool. + */ + +#include "duiapplettester.h" + +#include +#include +#include +#include +#include +#include + +void usage(const char *progName) +{ + qWarning("Usage: %s -i [OPTION] METADATAFILENAME", progName); + qWarning(" -i, --instanceId=ID Defines the instance id of the applet"); + qWarning(" metadatafilename Defines the metadata file of the applet"); +} + +int main(int argc, char **argv) +{ + DuiAppletId::AppletInstanceID instanceId = 0; + while (1) { + int option_index = 0; + static struct option long_options[] = { + { "instanceid", 1, NULL, 'i' }, /* --instanceid or -i */ + { "help", 0, NULL, 'h' }, /* --help or -h */ + { 0, 0, 0, 0 } + }; + int c = getopt_long_only(argc, argv, "i:h", long_options, &option_index); + if (c == -1) + break; + switch (c) { + case 'i': + instanceId = atoi(optarg); + break; + case 'h': + usage(argv[0]); + return -1; + default: + break; + } + } + + // Load applet metadata + if (optind >= argc || QString(argv[optind]).isEmpty()) { + usage(argv[0]); + } else { + QString metaDataFileName = argv[optind]; + DuiAppletMetaData metadata(metaDataFileName); + DuiApplication m_app(argc, argv, metadata.resourceIdentifier()); + DuiAppletId appletId("duiapplettester", "default", instanceId); + if (!metadata.isValid()) { + qWarning() << "Applet metadata file" << metaDataFileName << "is not valid"; + return -1; + } + DuiAppletTester tester; + if (!tester.init(metadata, appletId)) { + qWarning() << "Applet initialization failed"; + return -1; + } + + return tester.exec(); + } +} diff --git a/tools/duiapplicationextensiontester/.gitignore b/tools/duiapplicationextensiontester/.gitignore new file mode 100644 index 000000000..8d4745e82 --- /dev/null +++ b/tools/duiapplicationextensiontester/.gitignore @@ -0,0 +1 @@ +duiapplicationextensiontester diff --git a/tools/duiapplicationextensiontester/duiapplicationextensiontester.cpp b/tools/duiapplicationextensiontester/duiapplicationextensiontester.cpp new file mode 100644 index 000000000..9505ba937 --- /dev/null +++ b/tools/duiapplicationextensiontester/duiapplicationextensiontester.cpp @@ -0,0 +1,103 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +/* + * Application extension testing tool. + */ + +#include "duiapplicationextensiontester.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +ApplicationExtensionPage::ApplicationExtensionPage(const char *metaDataFileName) : + metaDataFileName(metaDataFileName) +{ + QString appName = QFileInfo(QCoreApplication::applicationFilePath()).fileName(); + QString path = QDir::homePath() + "/.config/" + appName; + if (!QDir::root().exists(path)) { + QDir::root().mkpath(path); + } + + QFile f(path + "/extensionarea.data"); + f.open(QFile::WriteOnly | QFile::Truncate); + QTextStream ts(&f); + ts << "[1]\ndesktopFile=" << metaDataFileName << "\nprivate\\layoutIndex=0\n"; +} + +void ApplicationExtensionPage::createContent() +{ + DuiWidget *panel = centralWidget(); + QGraphicsLinearLayout *vbox = new QGraphicsLinearLayout(Qt::Vertical); + panel->setLayout(vbox); + + DuiApplicationExtensionArea *extArea = new DuiApplicationExtensionArea("extensionarea"); + vbox->addItem(extArea); +} + +void usage(const char *progName) +{ + qWarning("Usage: %s METADATAFILENAME", progName); + qWarning(" metadatafilename Defines the metadata file of the extension"); +} + +int main(int argc, char **argv) +{ + while (1) { + int option_index = 0; + static struct option long_options[] = { + { "help", 0, NULL, 'h' }, /* --help or -h */ + { 0, 0, 0, 0 } + }; + int c = getopt_long_only(argc, argv, ":h", long_options, &option_index); + if (c == -1) + break; + switch (c) { + case 'h': + usage(argv[0]); + return -1; + default: + break; + } + } + + if (optind >= argc || QString(argv[optind]).isEmpty()) { + usage(argv[0]); + return -1; + } + + DuiApplication m_app(argc, argv); + DuiApplicationWindow window; + ApplicationExtensionPage page(argv[optind]); + window.show(); + page.appear(); + + return m_app.exec(); +} diff --git a/tools/duiapplicationextensiontester/duiapplicationextensiontester.h b/tools/duiapplicationextensiontester/duiapplicationextensiontester.h new file mode 100644 index 000000000..2b9ec8abc --- /dev/null +++ b/tools/duiapplicationextensiontester/duiapplicationextensiontester.h @@ -0,0 +1,38 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef DUIAPPLICATIONEXTENSIONTESTER_H +#define DUIAPPLICATIONEXTENSIONTESTER_H + +#include + +class ApplicationExtensionPage : public DuiApplicationPage +{ + Q_OBJECT + +public: + ApplicationExtensionPage(const char *metaDataFileName); + + virtual void createContent(); + +private: + const char *metaDataFileName; +}; + +#endif diff --git a/tools/duiapplicationextensiontester/duiapplicationextensiontester.pro b/tools/duiapplicationextensiontester/duiapplicationextensiontester.pro new file mode 100644 index 000000000..ac9feebda --- /dev/null +++ b/tools/duiapplicationextensiontester/duiapplicationextensiontester.pro @@ -0,0 +1,26 @@ +include(../../mkspecs/common.pri) + +INCLUDEPATH += . \ + ../../src/include +DEPENDPATH += $$INCLUDEPATH +TEMPLATE = app +TARGET = duiapplicationextensiontester + +win32|macx { + macx { + QMAKE_LFLAGS += -F../../lib + LIBS += -framework dui + } + win32:LIBS += -L../../lib -ldui0 +} else { + LIBS += ../../lib/libdui.so +} + +# Input +HEADERS += duiapplicationextensiontester.h + +SOURCES += duiapplicationextensiontester.cpp + +target.path = $$DUI_INSTALL_BIN +INSTALLS += target +CONFIG -= app_bundle diff --git a/tools/duinotificationstresstest b/tools/duinotificationstresstest new file mode 100755 index 000000000..1f99a63cf --- /dev/null +++ b/tools/duinotificationstresstest @@ -0,0 +1,37 @@ +#!/usr/bin/perl -w + +$INTERVAL = ($#ARGV == 0) ? $ARGV[0] : 10; + +my @EVENTTYPES = ( "press", "release", "cancel", "error" ); +my @groupIDs; + +while(1) { + my $r = int(rand(2)); + my $group; + + if($#groupIDs < 0 || $r == 0) { + $group="" + } else { + $group="-i ".$groupIDs[int(rand($#groupIDs + 1))]; + } + + $r = int(rand(3)); + $e = int(rand($#EVENTTYPES + 1)); + + if($r == 0) { + system("duinotificationtool -a add $group $EVENTTYPES[$e] '' 'Application Event' Icon-camera"); + $n = $? >> 8; + print "notification $n created $group\n" + } elsif($r == 1) { + system("duinotificationtool -a add $group $EVENTTYPES[$e] '' 'System Event' Icon-camera"); + $n = $? >> 8; + print "notification $n created $group\n" + } elsif($r == 2) { + system("duinotificationtool -a add -g $EVENTTYPES[$e] '' 'Group' Icon-camera"); + $groupID=$? >> 8; + push @groupIDs, $groupID; + print "group $groupID created\n"; + } + + sleep($INTERVAL); +} diff --git a/tools/duinotificationtool/.gitignore b/tools/duinotificationtool/.gitignore new file mode 100644 index 000000000..9656168ee --- /dev/null +++ b/tools/duinotificationtool/.gitignore @@ -0,0 +1 @@ +duinotificationtool diff --git a/tools/duinotificationtool/duinotificationtool.cpp b/tools/duinotificationtool/duinotificationtool.cpp new file mode 100644 index 000000000..1d6c751ab --- /dev/null +++ b/tools/duinotificationtool/duinotificationtool.cpp @@ -0,0 +1,250 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libdui. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +//============================================================================ +// Description : Tool to handle notifications and notification groups +//============================================================================ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// The actions for this tool +enum ToolAction { + Undefined, + Add, + Update, + Remove +}; + +// The action to perform +ToolAction toolAction = Undefined; + +// Whether to operate on notification groups instead of notifications +bool groupMode = false; + +// Persistent mode in use +bool persistentMode = false; + +// Notifications list mode in use +bool listMode = false; + +// Application name provided with list mode +QString applicationName("duinotificationtool"); + +// The notification/notification group ID to use +unsigned int id = 0; + +// The notification/notification group ID to use +unsigned int count = 1; + +// Prints usage information +int usage(const char *program) +{ + std::cerr << std::setw(7) << "Usage: " << program << " [OPTION]... EVENTTYPE [SUMMARY BODY IMAGEURI SERVICENAME OBJECTPATH INTERFACE METHODNAME ARG...]" << std::endl; + std::cerr << std::setw(7) << "Manage notifications." << std::endl; + std::cerr << std::setw(7) << std::endl; + std::cerr << std::setw(7) << "Mandatory arguments to long options are mandatory for short options too." << std::endl; + std::cerr << std::setw(7) << " -a, --action=ACTION The action (add/update/remove) to perform." << std::endl; + std::cerr << std::setw(7) << " add - Adds a new notification or notification group." << std::endl; + std::cerr << std::setw(7) << " update - Updates an existing notification or notification group." << std::endl; + std::cerr << std::setw(7) << " remove - Removes an existing notification or notification group." << std::endl; + std::cerr << std::setw(7) << " -g, --group Whether to operate on notification groups instead of notifications." << std::endl; + std::cerr << std::setw(7) << " -i, --id=ID The notification/notification group ID to use." << std::endl; + std::cerr << std::setw(7) << " -c, --count=NUMBER The number of notifications. This parameter has no effect when the action is 'remove'" << std::endl; + std::cerr << std::setw(7) << " -p, --persistent Set notification/group to persistent. This parameter has no effect when the action is 'remove'" << std::endl; + std::cerr << std::setw(7) << " -l, --list=APPLICATION List all notifications that belong to an application name. Returns a count of notifications as an exit value." << std::endl; + std::cerr << std::setw(7) << " --help display this help and exit" << std::endl; + return -1; +} + +// Parses command line arguments (the flags) +int parseArguments(int argc, char *argv[]) +{ + while (1) { + int option_index = 0; + static struct option long_options[] = { + { "action", 1, NULL, 'a' }, + { "group", 0, NULL, 'g' }, + { "id", 1, NULL, 'i' }, + { "count", 1, NULL, 'c' }, + { "help", 0, NULL, 'h' }, + { "list", 1, NULL, 'l'}, + { "persistent", 0, NULL, 'p'}, + { 0, 0, 0, 0 } + }; + + int c = getopt_long(argc, argv, "a:gi:c:pl:", long_options, &option_index); + if (c == -1) + break; + + switch (c) { + case 'a': + if (strcmp(optarg, "add") == 0) { + toolAction = Add; + } else if (strcmp(optarg, "update") == 0) { + toolAction = Update; + } else if (strcmp(optarg, "remove") == 0) { + toolAction = Remove; + } + break; + case 'i': + id = atoi(optarg); + break; + case 'c': + count = atoi(optarg); + break; + case 'g': + groupMode = true; + break; + case 'p': + persistentMode = true; + break; + case 'l': + listMode = true; + applicationName = QString(optarg); + break; + case 'h': + return usage(argv[0]); + default: + break; + } + } + + if (!listMode) { + if (toolAction == Undefined || + (toolAction == Add && argc < optind + 1) || + (toolAction == Update && argc < optind + 4) || + ((toolAction == Update || toolAction == Remove) && id == 0)) { + return usage(argv[0]); + } + } + return 0; +} + +int main(int argc, char *argv[]) +{ + // Parse arguments + int result = parseArguments(argc, argv); + if (result != 0) { + return result; + } + + // DuiApplication creates DuiNotificationManager for specified application + QScopedPointer duiApplication(new DuiApplication(argc, argv, applicationName, 0)); + if (duiApplication.isNull()) { + std::cerr << "Couldn't initialize DuiApplication" << std::endl; + return -1; + } + + // Calls notificationIdList from NotificationManager. Returns size of the list from main. + if (listMode) { + QList list = DuiNotification::notifications(); + std::cout << "\n" << applicationName.toUtf8().data() << " has " << list.size() << " notifications." << std::endl; + std::cout << "Notification id(s):" << std::endl; + foreach(DuiNotification * notification, list) { + std::cout << notification->id() << std::endl; + } + return list.size(); + } + + // Execute the desired action + switch (toolAction) { + case Add: + case Update: { + // Get the parameters for adding and updating notifications/notification groups + QString eventType = QString(argv[optind]); + QString summary, body, imageURI; + if (argc >= optind + 1) { + summary = QString(argv[optind + 1]); + } + if (argc >= optind + 2) { + body = QString(argv[optind + 2]); + } + if (argc >= optind + 3) { + imageURI = QString(argv[optind + 3]); + } + + // Create an action if one is defined + DuiRemoteAction *remoteAction; + if (argc >= optind + 4 + 4) { + QString serviceName(argv[optind + 4]); + QString objectPath(argv[optind + 5]); + QString interface(argv[optind + 6]); + QString methodName(argv[optind + 7]); + QList arguments; + + for (int i = optind + 8; i < argc; ++i) { + arguments.append(QVariant(argv[i])); + } + remoteAction = new DuiRemoteAction(serviceName, objectPath, interface, methodName, arguments); + } else { + remoteAction = new DuiRemoteAction; + } + + if (toolAction == Add) { + // Add a notification/notification group + if (groupMode) { + result = DuiNotificationGroup(eventType, summary, body, imageURI, *remoteAction, count, persistentMode).id(); + } else { + if (id != 0) { + result = DuiNotification(DuiNotificationGroup(id), eventType, summary, body, imageURI, *remoteAction).id(); + } else { + result = DuiNotification(eventType, summary, body, imageURI, *remoteAction, count, persistentMode).id(); + } + } + } else { + // Update a notification/notification group + if (groupMode) { + DuiNotificationGroup group(id); + group.update(eventType, summary, body, imageURI, count, *remoteAction); + } else { + DuiNotification notification(id); + notification.update(eventType, summary, body, imageURI, count, *remoteAction); + } + } + + delete remoteAction; + break; + } + case Remove: + if (groupMode) { + DuiNotificationGroup group(id); + group.remove(); + } else { + DuiNotification notification(id); + notification.remove(); + } + break; + default: + break; + } + + return result; +} diff --git a/tools/duinotificationtool/duinotificationtool.pro b/tools/duinotificationtool/duinotificationtool.pro new file mode 100644 index 000000000..ba20f3f37 --- /dev/null +++ b/tools/duinotificationtool/duinotificationtool.pro @@ -0,0 +1,21 @@ +include(../../mkspecs/common.pri) + +TEMPLATE = app +TARGET = duinotificationtool +INCLUDEPATH += . \ + ../../src/include \ + ../../src/notification +DEPENDPATH += $$INCLUDEPATH +win32|macx { + macx { + QMAKE_LFLAGS += -F../../lib + LIBS += -framework dui + } + win32:LIBS += -L../../lib -ldui0 +} else { + LIBS += ../../lib/libdui.so +} +SOURCES += duinotificationtool.cpp +target.path = $$DUI_INSTALL_BIN +INSTALLS += target +CONFIG -= app_bundle diff --git a/tools/duitheme.pmdoc/01base-contents.xml b/tools/duitheme.pmdoc/01base-contents.xml new file mode 100644 index 000000000..bc1e5a791 --- /dev/null +++ b/tools/duitheme.pmdoc/01base-contents.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/tools/duitheme.pmdoc/01base.xml b/tools/duitheme.pmdoc/01base.xml new file mode 100644 index 000000000..dfded4dbe --- /dev/null +++ b/tools/duitheme.pmdoc/01base.xml @@ -0,0 +1 @@ +com.nokia.libdui.theme.duitheme.base.pkg1../../duitheme/base/usr/share/themes/baseparentinstallFrom.isRelativeTypeinstallTo.pathinstallTo \ No newline at end of file diff --git a/tools/duitheme.pmdoc/02devel-contents.xml b/tools/duitheme.pmdoc/02devel-contents.xml new file mode 100644 index 000000000..bc1e5a791 --- /dev/null +++ b/tools/duitheme.pmdoc/02devel-contents.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/tools/duitheme.pmdoc/02devel.xml b/tools/duitheme.pmdoc/02devel.xml new file mode 100644 index 000000000..68869d0bc --- /dev/null +++ b/tools/duitheme.pmdoc/02devel.xml @@ -0,0 +1 @@ +com.nokia.libdui.theme.duitheme.devel.pkg1../../duitheme/devel/usr/share/themes/develparentinstallFrom.isRelativeTypeinstallTo.pathinstallTo \ No newline at end of file diff --git a/tools/duitheme.pmdoc/03rd-contents.xml b/tools/duitheme.pmdoc/03rd-contents.xml new file mode 100644 index 000000000..8c568f556 --- /dev/null +++ b/tools/duitheme.pmdoc/03rd-contents.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/tools/duitheme.pmdoc/03rd.xml b/tools/duitheme.pmdoc/03rd.xml new file mode 100644 index 000000000..bccde49b6 --- /dev/null +++ b/tools/duitheme.pmdoc/03rd.xml @@ -0,0 +1 @@ +com.nokia.libdui.theme.duitheme.rd.pkg1../../duitheme/rd/usr/share/themes/rdparentinstallFrom.isRelativeTypeinstallTo.pathinstallFrom.pathinstallTo03rd-contents.xml/CVS$/\.svn$/\.cvsignore$/\.cvspass$/\.DS_Store$ \ No newline at end of file diff --git a/tools/duitheme.pmdoc/04translations-contents.xml b/tools/duitheme.pmdoc/04translations-contents.xml new file mode 100644 index 000000000..bc1e5a791 --- /dev/null +++ b/tools/duitheme.pmdoc/04translations-contents.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/tools/duitheme.pmdoc/04translations.xml b/tools/duitheme.pmdoc/04translations.xml new file mode 100644 index 000000000..8ea8b9f66 --- /dev/null +++ b/tools/duitheme.pmdoc/04translations.xml @@ -0,0 +1 @@ +com.nokia.libdui.theme.duitheme.translations.pkg1../demos/widgetsgallery/translations/usr/share/l10n/dui/parentinstallFrom.isRelativeTypeinstallTo.pathinstallFrom.pathinstallToincludeRoot/CVS$/\.svn$/\.cvsignore$/\.cvspass$/\.DS_Store$/ts$/Makefile$/translations.app$/translations.pro$/.*\.ts$ \ No newline at end of file diff --git a/tools/duitheme.pmdoc/05style-contents.xml b/tools/duitheme.pmdoc/05style-contents.xml new file mode 100644 index 000000000..bc1e5a791 --- /dev/null +++ b/tools/duitheme.pmdoc/05style-contents.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/tools/duitheme.pmdoc/05style.xml b/tools/duitheme.pmdoc/05style.xml new file mode 100644 index 000000000..f6c640257 --- /dev/null +++ b/tools/duitheme.pmdoc/05style.xml @@ -0,0 +1 @@ +com.nokia.libdui.theme.duitheme.style.pkg1../demos/widgetsgallery/theme/base/style/usr/share/themes/base/dui/widgetsgallery/styleparentinstallFrom.isRelativeTypeinstallTo.pathinstallTo \ No newline at end of file diff --git a/tools/duitheme.pmdoc/06images-contents.xml b/tools/duitheme.pmdoc/06images-contents.xml new file mode 100644 index 000000000..bc1e5a791 --- /dev/null +++ b/tools/duitheme.pmdoc/06images-contents.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/tools/duitheme.pmdoc/06images.xml b/tools/duitheme.pmdoc/06images.xml new file mode 100644 index 000000000..b643c395f --- /dev/null +++ b/tools/duitheme.pmdoc/06images.xml @@ -0,0 +1 @@ +com.nokia.libdui.theme.duitheme.images.pkg1../demos/widgetsgallery/theme/devel/images/usr/share/themes/devel/dui/widgetsgallery/imagesparentinstallFrom.isRelativeTypeinstallTo.pathinstallTo \ No newline at end of file diff --git a/tools/duitheme.pmdoc/07style-contents.xml b/tools/duitheme.pmdoc/07style-contents.xml new file mode 100644 index 000000000..bc1e5a791 --- /dev/null +++ b/tools/duitheme.pmdoc/07style-contents.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/tools/duitheme.pmdoc/07style.xml b/tools/duitheme.pmdoc/07style.xml new file mode 100644 index 000000000..ab28ca9c9 --- /dev/null +++ b/tools/duitheme.pmdoc/07style.xml @@ -0,0 +1 @@ +com.nokia.libdui.theme.duitheme.style-1.pkg1../demos/widgetsgallery/theme/devel/style/usr/share/themes/devel/dui/widgetsgallery/styleparentinstallFrom.isRelativeTypeinstallTo.pathinstallTo \ No newline at end of file diff --git a/tools/duitheme.pmdoc/08svg-contents.xml b/tools/duitheme.pmdoc/08svg-contents.xml new file mode 100644 index 000000000..bc1e5a791 --- /dev/null +++ b/tools/duitheme.pmdoc/08svg-contents.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/tools/duitheme.pmdoc/08svg.xml b/tools/duitheme.pmdoc/08svg.xml new file mode 100644 index 000000000..fafd88a5c --- /dev/null +++ b/tools/duitheme.pmdoc/08svg.xml @@ -0,0 +1 @@ +com.nokia.libdui.theme.duitheme.svg.pkg1../demos/widgetsgallery/theme/devel/svg/usr/share/themes/devel/dui/widgetsgallery/svgparentinstallFrom.isRelativeTypeinstallTo.pathinstallTo \ No newline at end of file diff --git a/tools/duitheme.pmdoc/09style-contents.xml b/tools/duitheme.pmdoc/09style-contents.xml new file mode 100644 index 000000000..bc1e5a791 --- /dev/null +++ b/tools/duitheme.pmdoc/09style-contents.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/tools/duitheme.pmdoc/09style.xml b/tools/duitheme.pmdoc/09style.xml new file mode 100644 index 000000000..cb7fb0c31 --- /dev/null +++ b/tools/duitheme.pmdoc/09style.xml @@ -0,0 +1 @@ +com.nokia.libdui.theme.duitheme.style-2.pkg1../demos/widgetsgallery/theme/demo/style/usr/share/themes/demo/dui/widgetsgallery/styleparentinstallFrom.isRelativeTypeinstallTo.pathinstallTo \ No newline at end of file diff --git a/tools/duitheme.pmdoc/index.xml b/tools/duitheme.pmdoc/index.xml new file mode 100644 index 000000000..8bc9f51d6 --- /dev/null +++ b/tools/duitheme.pmdoc/index.xml @@ -0,0 +1 @@ +duitheme/Volumes/DirectUI/libdui/tools/duitheme.mpkgcom.nokia.libdui.theme01base.xml02devel.xml03rd.xml04translations.xml05style.xml06images.xml07style.xml08svg.xml09style.xmlproperties.customizeOptionproperties.titleproperties.anywhereDomainproperties.systemDomain \ No newline at end of file diff --git a/tools/settingslanguage/settings.rng b/tools/settingslanguage/settings.rng new file mode 100644 index 000000000..7dbf81bec --- /dev/null +++ b/tools/settingslanguage/settings.rng @@ -0,0 +1,103 @@ + + + + A set of settings. + + + + + A settings node representing a group of setting items. + A group can contain one or more setting items. + + + + + + + + + + + + + + + + + + + A settings node representing a selection. A + selection can have a predefined set of possible options. + + The key (name) of the selection. + + + + + A possible value for a selection. + + The type must be an integer. + + + The title of the option. + + + + + + + + + + A settings node representing text. A text item can contain any string data. + + The key (name) of the text item. + + + + The title of the text item. + + + + + + + + A settings node representing boolean. + + The key (name) of the boolean item. + + + + The title of the boolean item. + + + + + + + + A settings node representing an integer from a range. + + The key (name) of the integer. + + + + The title of the integer. + + + + Minimum value that the integer can have. + + + + Maximum value that the integer can have. + + + + + + diff --git a/tools/tools.pro b/tools/tools.pro new file mode 100644 index 000000000..bf97df7e9 --- /dev/null +++ b/tools/tools.pro @@ -0,0 +1,28 @@ +include(../mkspecs/common.pri) + +TEMPLATE = subdirs +SUBDIRS = \ + duiapplettester \ + duiapplicationextensiontester \ + duinotificationtool \ + dui-servicefwgen.d \ + +macx:SUBDIRS -= duinotificationtool +macx:SUBDIRS -= duiapplettester +macx:SUBDIRS -= duiapplicationextensiontester + +QMAKE_EXTRA_TARGETS += check +check.depends = +check.commands = $$system(true) + +QMAKE_EXTRA_TARGETS += check-xml +check-xml.depends = +check-xml.commands = $$system(true) + +tools.target = .dummy +tools.commands = touch $$tools.target +tools.path = $$DUI_INSTALL_BIN +tools.files = duinotificationstresstest + +INSTALLS += \ + tools diff --git a/tools/widgetsgallery.nsi b/tools/widgetsgallery.nsi new file mode 100644 index 000000000..5ae8f93a4 --- /dev/null +++ b/tools/widgetsgallery.nsi @@ -0,0 +1,112 @@ +; HM NIS Edit Wizard helper defines +!define PRODUCT_NAME "Widgets Gallery" +!define PRODUCT_VERSION "0.15" +!define PRODUCT_PUBLISHER "Nokia" +!define PRODUCT_WEB_SITE "http://www.nokia.com" +!define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\widgetsgallery.exe" +!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" +!define PRODUCT_UNINST_ROOT_KEY "HKLM" + +; MUI 1.67 compatible ------ +!include "MUI.nsh" + +; MUI Settings +!define MUI_ABORTWARNING +!define MUI_ICON "${NSISDIR}\Contrib\Graphics\Icons\modern-install.ico" +!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico" + +; Welcome page +!insertmacro MUI_PAGE_WELCOME +; License page +;!insertmacro MUI_PAGE_LICENSE "c:\path\to\licence\YourSoftwareLicence.txt" +; Directory page +!insertmacro MUI_PAGE_DIRECTORY +; Instfiles page +!insertmacro MUI_PAGE_INSTFILES +; Finish page +!define MUI_FINISHPAGE_RUN "$INSTDIR\bin\widgetsgallery.exe" +!insertmacro MUI_PAGE_FINISH + +; Uninstaller pages +!insertmacro MUI_UNPAGE_INSTFILES + +; Language files +!insertmacro MUI_LANGUAGE "English" + +; MUI end ------ + +Name "${PRODUCT_NAME} ${PRODUCT_VERSION}" + +; this path seems to be relative from the widgetsgallery.nsi location +OutFile "..\..\WidgetsGallerySetup.exe" + +InstallDir "$PROGRAMFILES\WidgetsGallery" +InstallDirRegKey HKLM "${PRODUCT_DIR_REGKEY}" "" +ShowInstDetails show +ShowUnInstDetails show + + +Section "MainSection" SEC01 + SetOutPath "$INSTDIR" + SetOverwrite ifnewer + + ; dui files + File /r "..\..\inst\*.*" + + ; qt files + SetOutPath "$INSTDIR\bin" + File "..\..\qtlibs\libgcc_s_dw2-1.dll" + File "..\..\qtlibs\QtCored4.dll" + File "..\..\qtlibs\QtGuid4.dll" + File "..\..\qtlibs\QtNetworkd4.dll" + File "..\..\qtlibs\QtOpenGLd4.dll" + File "..\..\qtlibs\QtSvgd4.dll" + File "..\..\qtlibs\QtXmld4.dll" + File "..\..\qtlibs\mingwm10.dll" + + CreateDirectory "$SMPROGRAMS\Widgets Gallery" + CreateShortCut "$SMPROGRAMS\Widgets Gallery\Widgets Gallery.lnk" "$INSTDIR\bin\widgetsgallery.exe" + CreateShortCut "$DESKTOP\Widgets Gallery.lnk" "$INSTDIR\bin\widgetsgallery.exe" +SectionEnd + + +;Section -Post +; WriteUninstaller "$INSTDIR\uninst.exe" +; WriteRegStr HKLM "${PRODUCT_DIR_REGKEY}" "" "$INSTDIR\bin\widgetsgallery.exe" +; WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)" +; WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\uninst.exe" +; WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$INSTDIR\bin\widgetsgallery.exe" +; WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}" +; WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "URLInfoAbout" "${PRODUCT_WEB_SITE}" +; WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "Publisher" "${PRODUCT_PUBLISHER}" +;SectionEnd + + +Function un.onUninstSuccess + HideWindow + MessageBox MB_ICONINFORMATION|MB_OK "$(^Name) was successfully removed from your computer." +FunctionEnd + +Function un.onInit + MessageBox MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2 "Are you sure you want to completely remove $(^Name) and all of its components?" IDYES +2 + Abort +FunctionEnd + +;Section Uninstall +; Delete "$INSTDIR\${PRODUCT_NAME}.url" +; Delete "$INSTDIR\uninst.exe" +; Delete "$INSTDIR\Example.file" +; Delete "$INSTDIR\AppMainExe.exe" + +; Delete "$SMPROGRAMS\Widgets Gallery\Uninstall.lnk" +; Delete "$SMPROGRAMS\Widgets Gallery\Website.lnk" +; Delete "$DESKTOP\Widgets Gallery.lnk" +; Delete "$SMPROGRAMS\Widgets Gallery\Widgets Gallery.lnk" + +; RMDir "$SMPROGRAMS\Widgets Gallery" +; RMDir "$INSTDIR" + +; DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" +; DeleteRegKey HKLM "${PRODUCT_DIR_REGKEY}" +; SetAutoClose true +;SectionEnd diff --git a/tools/windows/touch.bat b/tools/windows/touch.bat new file mode 100644 index 000000000..c49824e0b --- /dev/null +++ b/tools/windows/touch.bat @@ -0,0 +1,3 @@ +rem a dummy touch implementation for windows... +echo "dummy touch called" + diff --git a/tools/windows/true.bat b/tools/windows/true.bat new file mode 100644 index 000000000..204ffcb5f --- /dev/null +++ b/tools/windows/true.bat @@ -0,0 +1,2 @@ +rem dummy true implementation for windows +echo "dummy true called"