on xenial help sign in
merge trunk
commit3114d70e2e858539bc939fd881f05bce14603e5d authorMichael Zanetti <michael.zanetti@canonical.com> dateThu 4 Jul 2013, 13:45 (13 years ago) parentf470392c7eed8a
124 files changed+3393−1125
CMakeLists.txt+1 COPYING.LGPL+514 Greeter/GreeterContent.qml+1 LGPL_EXCEPTION.txt+22 Notifications/Notification.qml+109−12 Notifications/Notifications.qml+10−13 Panel/Indicators.qml+111−27 Panel/MenuContent.qml+1−1 Panel/Panel.qml+3−74 debian/changelog+7 debian/control+46−48 debian/copyright+13−3 debian/rules+22−2 debian/scopes-recommends-generator+27 debian/unity8-autopilot.install+1−1 debian/unity8-fake-env.install+1−1 debian/unity8-private.install+6 debian/unity8.install+15−21 main.cpp+8−9 paths.h.in+8−7 plugins/HudClient/CMakeLists.txt+2−2 plugins/LightDM/CMakeLists.txt+6−3 plugins/LightDM/Greeter.cpp+6−6 plugins/LightDM/Greeter.h+4−4 plugins/LightDM/plugin.cpp+5−4 plugins/ListViewWithPageHeader/CMakeLists.txt+2−2 plugins/ListViewWithPageHeader/listviewwithpageheader.cpp+3 plugins/Ubuntu/Gestures/CMakeLists.txt+2−2 plugins/Ubuntu/Gestures/DirectionalDragArea.cpp+3−3 plugins/Ubuntu/Gestures/DirectionalDragArea.h+3−3 plugins/Unity/CMakeLists.txt+10−2 plugins/Unity/applicationpreview.cpp+96 plugins/Unity/applicationpreview.h+66 tests/qmltests/plugins/Dee/DeeVariantText.qml → plugins/Unity/genericpreview.cpp+8−4 Notifications/timings.js → plugins/Unity/genericpreview.h+23−6 plugins/Unity/moviepreview.cpp+67 plugins/Unity/moviepreview.h+60 plugins/Unity/musicpreview.cpp+54 plugins/Unity/musicpreview.h+62 plugins/Unity/plugin.cpp+6 plugins/Unity/preview.cpp+173 plugins/Unity/preview.h+80 plugins/Unity/previewaction.cpp+75 plugins/Unity/previewaction.h+71 plugins/Unity/previewinfohint.cpp+67 plugins/Unity/previewinfohint.h+58 plugins/Unity/scope.cpp+79−11 plugins/Unity/scope.h+20−3 plugins/Unity/variantutils.cpp+158 plugins/Unity/variantutils.h+34 plugins/Utils/CMakeLists.txt+2−2 plugins/Utils/qlimitproxymodelqml.cpp+4−4 run+3−3 run_on_device+2−3 tests/autopilot/setup.py+21 tests/autopilot/unity8/tests/__init__.py+6−4 tests/mocks/CMakeLists.txt+2 tests/qmltests/plugins/HudClient/CMakeLists.txt → tests/mocks/HudClient/CMakeLists.txt tests/qmltests/plugins/HudClient/fake_hud_plugin.cpp → tests/mocks/HudClient/fake_hud_plugin.cpp tests/qmltests/plugins/HudClient/fake_hud_plugin.h → tests/mocks/HudClient/fake_hud_plugin.h tests/qmltests/plugins/HudClient/fake_libhud_client.cpp → tests/mocks/HudClient/fake_libhud_client.cpp tests/qmltests/plugins/HudClient/libhud_client_stub.cpp → tests/mocks/HudClient/libhud_client_stub.cpp tests/qmltests/plugins/HudClient/libhud_client_stub.h → tests/mocks/HudClient/libhud_client_stub.h tests/qmltests/plugins/HudClient/qmldir → tests/mocks/HudClient/qmldir tests/mocks/LightDM/CMakeLists.txt+5−2 tests/mocks/LightDM/InfographicModel.cpp−416 tests/mocks/LightDM/InfographicModelPrivate.h−99 tests/mocks/LightDM/demo/CMakeLists.txt+11−2 tests/mocks/LightDM/demo/UsersModelPrivate.cpp+1−1 tests/mocks/LightDM/full/CMakeLists.txt+1−3 tests/mocks/LightDM/single-passphrase/CMakeLists.txt+1−3 tests/mocks/LightDM/single-passphrase/UsersModelPrivate.cpp+1−1 tests/mocks/LightDM/single-pin/CMakeLists.txt+1−3 tests/mocks/LightDM/single-pin/UsersModelPrivate.cpp+1−1 tests/mocks/LightDM/single/CMakeLists.txt+1−3 tests/mocks/LightDM/single/UsersModelPrivate.cpp+1−1 tests/mocks/Ubuntu/Application/CMakeLists.txt+2−2 tests/mocks/Ubuntu/CMakeLists.txt+1 tests/qmltests/plugins/Ubuntu/ChewieUI/CMakeLists.txt → tests/mocks/Ubuntu/ChewieUI/CMakeLists.txt tests/qmltests/plugins/Ubuntu/ChewieUI/fake_chewie_plugin.cpp → tests/mocks/Ubuntu/ChewieUI/fake_chewie_plugin.cpp tests/qmltests/plugins/Ubuntu/ChewieUI/fake_chewie_plugin.h → tests/mocks/Ubuntu/ChewieUI/fake_chewie_plugin.h tests/qmltests/plugins/Ubuntu/ChewieUI/fake_pluginmodel.cpp → tests/mocks/Ubuntu/ChewieUI/fake_pluginmodel.cpp tests/qmltests/plugins/Ubuntu/ChewieUI/fake_pluginmodel.h → tests/mocks/Ubuntu/ChewieUI/fake_pluginmodel.h tests/qmltests/plugins/Ubuntu/ChewieUI/qmldir → tests/mocks/Ubuntu/ChewieUI/qmldir tests/mocks/Unity.moved/CMakeLists.txt+1 tests/mocks/Unity/Launcher/CMakeLists.txt → tests/mocks/Unity.moved/Launcher/CMakeLists.txt tests/mocks/Unity/Launcher/MockLauncherItem.cpp → tests/mocks/Unity.moved/Launcher/MockLauncherItem.cpp tests/mocks/Unity/Launcher/MockLauncherItem.h → tests/mocks/Unity.moved/Launcher/MockLauncherItem.h tests/mocks/Unity/Launcher/MockLauncherModel.cpp → tests/mocks/Unity.moved/Launcher/MockLauncherModel.cpp tests/mocks/Unity/Launcher/MockLauncherModel.h → tests/mocks/Unity.moved/Launcher/MockLauncherModel.h tests/mocks/Unity/Launcher/plugin.cpp → tests/mocks/Unity.moved/Launcher/plugin.cpp tests/mocks/Unity/Launcher/plugin.h → tests/mocks/Unity.moved/Launcher/plugin.h tests/mocks/Unity/Launcher/qmldir → tests/mocks/Unity.moved/Launcher/qmldir tests/mocks/Unity/CMakeLists.txt+44 tests/qmltests/plugins/Unity/Notifications/notification.js → tests/mocks/Unity/Notifications/notification.js tests/qmltests/plugins/Unity/Notifications/qmldir → tests/mocks/Unity/Notifications/qmldir tests/qmltests/plugins/Unity/fake_scope.cpp → tests/mocks/Unity/fake_scope.cpp tests/qmltests/plugins/Unity/fake_scope.h → tests/mocks/Unity/fake_scope.h tests/qmltests/plugins/Unity/fake_scopes.cpp → tests/mocks/Unity/fake_scopes.cpp tests/qmltests/plugins/Unity/fake_scopes.h → tests/mocks/Unity/fake_scopes.h tests/qmltests/plugins/Unity/fake_unity_plugin.cpp → tests/mocks/Unity/fake_unity_plugin.cpp tests/qmltests/plugins/Unity/fake_unity_plugin.h → tests/mocks/Unity/fake_unity_plugin.h tests/qmltests/plugins/Unity/qmldir → tests/mocks/Unity/qmldir tests/mocks/libusermetrics/CMakeLists.txt+17 tests/mocks/libusermetrics/ColorTheme.cpp+128 tests/mocks/libusermetrics/ColorTheme.h+68 tests/mocks/libusermetrics/UserMetrics.cpp+465 tests/mocks/LightDM/InfographicModel.h → tests/mocks/libusermetrics/UserMetrics.h+22−60 tests/mocks/libusermetrics/libusermetricsoutput/ColorTheme.h+1 tests/mocks/libusermetrics/libusermetricsoutput/UserMetrics.h+1 tests/plugins/CMakeLists.txt+1 tests/plugins/ListViewWithPageHeader/listviewwithpageheadertest.cpp+6 tests/plugins/Unity/CMakeLists.txt+38 tests/plugins/Unity/previewbindingstest.cpp+114 plugins/LightDM/InfographicModel.h → tests/plugins/Unity/previewbindingstest.h+15−8 tests/plugins/Utils/qlimitproxymodeltest.cpp+15 tests/qmltests/CMakeLists.txt+14−15 tests/qmltests/Notifications/tst_Notifications.qml+48−7 tests/qmltests/Panel/tst_Indicators.qml+34−45 tests/qmltests/Panel/tst_Panel.qml+65−113 tests/qmltests/plugins/CMakeLists.txt−3 tests/qmltests/plugins/Dee/qmldir−3 tests/qmltests/plugins/Ubuntu/CMakeLists.txt−1 tests/qmltests/plugins/Unity/CMakeLists.txt−43
CMakeLists.txt+1
@@ -57,6 +57,7 @@ find_package(Qt5DBus)
5757include(GNUInstallDirs)
5858
5959set(SHELL_APP_DIR ${CMAKE_INSTALL_DATADIR}/unity8)
60+set(SHELL_PRIVATE_LIBDIR ${CMAKE_INSTALL_LIBDIR}/unity8)
6061
6162configure_file(paths.h.in ${CMAKE_CURRENT_BINARY_DIR}/paths.h @ONLY)
6263
COPYING.LGPLnew file+514
@@ -0,0 +1,514 @@
1+ GNU LESSER GENERAL PUBLIC LICENSE
2+
3+ The Qt Toolkit is Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
4+ Contact: http://www.qt-project.org/legal
5+
6+ You may use, distribute and copy the Qt GUI Toolkit under the terms of
7+ GNU Lesser General Public License version 2.1, which is displayed below.
8+
9+-------------------------------------------------------------------------
10+
11+ GNU LESSER GENERAL PUBLIC LICENSE
12+ Version 2.1, February 1999
13+
14+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
15+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16+ Everyone is permitted to copy and distribute verbatim copies
17+ of this license document, but changing it is not allowed.
18+
19+[This is the first released version of the Lesser GPL. It also counts
20+ as the successor of the GNU Library Public License, version 2, hence
21+ the version number 2.1.]
22+
23+ Preamble
24+
25+ The licenses for most software are designed to take away your
26+freedom to share and change it. By contrast, the GNU General Public
27+Licenses are intended to guarantee your freedom to share and change
28+free software--to make sure the software is free for all its users.
29+
30+ This license, the Lesser General Public License, applies to some
31+specially designated software packages--typically libraries--of the
32+Free Software Foundation and other authors who decide to use it. You
33+can use it too, but we suggest you first think carefully about whether
34+this license or the ordinary General Public License is the better
35+strategy to use in any particular case, based on the explanations below.
36+
37+ When we speak of free software, we are referring to freedom of use,
38+not price. Our General Public Licenses are designed to make sure that
39+you have the freedom to distribute copies of free software (and charge
40+for this service if you wish); that you receive source code or can get
41+it if you want it; that you can change the software and use pieces of
42+it in new free programs; and that you are informed that you can do
43+these things.
44+
45+ To protect your rights, we need to make restrictions that forbid
46+distributors to deny you these rights or to ask you to surrender these
47+rights. These restrictions translate to certain responsibilities for
48+you if you distribute copies of the library or if you modify it.
49+
50+ For example, if you distribute copies of the library, whether gratis
51+or for a fee, you must give the recipients all the rights that we gave
52+you. You must make sure that they, too, receive or can get the source
53+code. If you link other code with the library, you must provide
54+complete object files to the recipients, so that they can relink them
55+with the library after making changes to the library and recompiling
56+it. And you must show them these terms so they know their rights.
57+
58+ We protect your rights with a two-step method: (1) we copyright the
59+library, and (2) we offer you this license, which gives you legal
60+permission to copy, distribute and/or modify the library.
61+
62+ To protect each distributor, we want to make it very clear that
63+there is no warranty for the free library. Also, if the library is
64+modified by someone else and passed on, the recipients should know
65+that what they have is not the original version, so that the original
66+author's reputation will not be affected by problems that might be
67+introduced by others.
68+
69+ Finally, software patents pose a constant threat to the existence of
70+any free program. We wish to make sure that a company cannot
71+effectively restrict the users of a free program by obtaining a
72+restrictive license from a patent holder. Therefore, we insist that
73+any patent license obtained for a version of the library must be
74+consistent with the full freedom of use specified in this license.
75+
76+ Most GNU software, including some libraries, is covered by the
77+ordinary GNU General Public License. This license, the GNU Lesser
78+General Public License, applies to certain designated libraries, and
79+is quite different from the ordinary General Public License. We use
80+this license for certain libraries in order to permit linking those
81+libraries into non-free programs.
82+
83+ When a program is linked with a library, whether statically or using
84+a shared library, the combination of the two is legally speaking a
85+combined work, a derivative of the original library. The ordinary
86+General Public License therefore permits such linking only if the
87+entire combination fits its criteria of freedom. The Lesser General
88+Public License permits more lax criteria for linking other code with
89+the library.
90+
91+ We call this license the "Lesser" General Public License because it
92+does Less to protect the user's freedom than the ordinary General
93+Public License. It also provides other free software developers Less
94+of an advantage over competing non-free programs. These disadvantages
95+are the reason we use the ordinary General Public License for many
96+libraries. However, the Lesser license provides advantages in certain
97+special circumstances.
98+
99+ For example, on rare occasions, there may be a special need to
100+encourage the widest possible use of a certain library, so that it becomes
101+a de-facto standard. To achieve this, non-free programs must be
102+allowed to use the library. A more frequent case is that a free
103+library does the same job as widely used non-free libraries. In this
104+case, there is little to gain by limiting the free library to free
105+software only, so we use the Lesser General Public License.
106+
107+ In other cases, permission to use a particular library in non-free
108+programs enables a greater number of people to use a large body of
109+free software. For example, permission to use the GNU C Library in
110+non-free programs enables many more people to use the whole GNU
111+operating system, as well as its variant, the GNU/Linux operating
112+system.
113+
114+ Although the Lesser General Public License is Less protective of the
115+users' freedom, it does ensure that the user of a program that is
116+linked with the Library has the freedom and the wherewithal to run
117+that program using a modified version of the Library.
118+
119+ The precise terms and conditions for copying, distribution and
120+modification follow. Pay close attention to the difference between a
121+"work based on the library" and a "work that uses the library". The
122+former contains code derived from the library, whereas the latter must
123+be combined with the library in order to run.
124+
125+ GNU LESSER GENERAL PUBLIC LICENSE
126+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
127+
128+ 0. This License Agreement applies to any software library or other
129+program which contains a notice placed by the copyright holder or
130+other authorized party saying it may be distributed under the terms of
131+this Lesser General Public License (also called "this License").
132+Each licensee is addressed as "you".
133+
134+ A "library" means a collection of software functions and/or data
135+prepared so as to be conveniently linked with application programs
136+(which use some of those functions and data) to form executables.
137+
138+ The "Library", below, refers to any such software library or work
139+which has been distributed under these terms. A "work based on the
140+Library" means either the Library or any derivative work under
141+copyright law: that is to say, a work containing the Library or a
142+portion of it, either verbatim or with modifications and/or translated
143+straightforwardly into another language. (Hereinafter, translation is
144+included without limitation in the term "modification".)
145+
146+ "Source code" for a work means the preferred form of the work for
147+making modifications to it. For a library, complete source code means
148+all the source code for all modules it contains, plus any associated
149+interface definition files, plus the scripts used to control compilation
150+and installation of the library.
151+
152+ Activities other than copying, distribution and modification are not
153+covered by this License; they are outside its scope. The act of
154+running a program using the Library is not restricted, and output from
155+such a program is covered only if its contents constitute a work based
156+on the Library (independent of the use of the Library in a tool for
157+writing it). Whether that is true depends on what the Library does
158+and what the program that uses the Library does.
159+
160+ 1. You may copy and distribute verbatim copies of the Library's
161+complete source code as you receive it, in any medium, provided that
162+you conspicuously and appropriately publish on each copy an
163+appropriate copyright notice and disclaimer of warranty; keep intact
164+all the notices that refer to this License and to the absence of any
165+warranty; and distribute a copy of this License along with the
166+Library.
167+
168+ You may charge a fee for the physical act of transferring a copy,
169+and you may at your option offer warranty protection in exchange for a
170+fee.
171+
172+ 2. You may modify your copy or copies of the Library or any portion
173+of it, thus forming a work based on the Library, and copy and
174+distribute such modifications or work under the terms of Section 1
175+above, provided that you also meet all of these conditions:
176+
177+ a) The modified work must itself be a software library.
178+
179+ b) You must cause the files modified to carry prominent notices
180+ stating that you changed the files and the date of any change.
181+
182+ c) You must cause the whole of the work to be licensed at no
183+ charge to all third parties under the terms of this License.
184+
185+ d) If a facility in the modified Library refers to a function or a
186+ table of data to be supplied by an application program that uses
187+ the facility, other than as an argument passed when the facility
188+ is invoked, then you must make a good faith effort to ensure that,
189+ in the event an application does not supply such function or
190+ table, the facility still operates, and performs whatever part of
191+ its purpose remains meaningful.
192+
193+ (For example, a function in a library to compute square roots has
194+ a purpose that is entirely well-defined independent of the
195+ application. Therefore, Subsection 2d requires that any
196+ application-supplied function or table used by this function must
197+ be optional: if the application does not supply it, the square
198+ root function must still compute square roots.)
199+
200+These requirements apply to the modified work as a whole. If
201+identifiable sections of that work are not derived from the Library,
202+and can be reasonably considered independent and separate works in
203+themselves, then this License, and its terms, do not apply to those
204+sections when you distribute them as separate works. But when you
205+distribute the same sections as part of a whole which is a work based
206+on the Library, the distribution of the whole must be on the terms of
207+this License, whose permissions for other licensees extend to the
208+entire whole, and thus to each and every part regardless of who wrote
209+it.
210+
211+Thus, it is not the intent of this section to claim rights or contest
212+your rights to work written entirely by you; rather, the intent is to
213+exercise the right to control the distribution of derivative or
214+collective works based on the Library.
215+
216+In addition, mere aggregation of another work not based on the Library
217+with the Library (or with a work based on the Library) on a volume of
218+a storage or distribution medium does not bring the other work under
219+the scope of this License.
220+
221+ 3. You may opt to apply the terms of the ordinary GNU General Public
222+License instead of this License to a given copy of the Library. To do
223+this, you must alter all the notices that refer to this License, so
224+that they refer to the ordinary GNU General Public License, version 2,
225+instead of to this License. (If a newer version than version 2 of the
226+ordinary GNU General Public License has appeared, then you can specify
227+that version instead if you wish.) Do not make any other change in
228+these notices.
229+
230+ Once this change is made in a given copy, it is irreversible for
231+that copy, so the ordinary GNU General Public License applies to all
232+subsequent copies and derivative works made from that copy.
233+
234+ This option is useful when you wish to copy part of the code of
235+the Library into a program that is not a library.
236+
237+ 4. You may copy and distribute the Library (or a portion or
238+derivative of it, under Section 2) in object code or executable form
239+under the terms of Sections 1 and 2 above provided that you accompany
240+it with the complete corresponding machine-readable source code, which
241+must be distributed under the terms of Sections 1 and 2 above on a
242+medium customarily used for software interchange.
243+
244+ If distribution of object code is made by offering access to copy
245+from a designated place, then offering equivalent access to copy the
246+source code from the same place satisfies the requirement to
247+distribute the source code, even though third parties are not
248+compelled to copy the source along with the object code.
249+
250+ 5. A program that contains no derivative of any portion of the
251+Library, but is designed to work with the Library by being compiled or
252+linked with it, is called a "work that uses the Library". Such a
253+work, in isolation, is not a derivative work of the Library, and
254+therefore falls outside the scope of this License.
255+
256+ However, linking a "work that uses the Library" with the Library
257+creates an executable that is a derivative of the Library (because it
258+contains portions of the Library), rather than a "work that uses the
259+library". The executable is therefore covered by this License.
260+Section 6 states terms for distribution of such executables.
261+
262+ When a "work that uses the Library" uses material from a header file
263+that is part of the Library, the object code for the work may be a
264+derivative work of the Library even though the source code is not.
265+Whether this is true is especially significant if the work can be
266+linked without the Library, or if the work is itself a library. The
267+threshold for this to be true is not precisely defined by law.
268+
269+ If such an object file uses only numerical parameters, data
270+structure layouts and accessors, and small macros and small inline
271+functions (ten lines or less in length), then the use of the object
272+file is unrestricted, regardless of whether it is legally a derivative
273+work. (Executables containing this object code plus portions of the
274+Library will still fall under Section 6.)
275+
276+ Otherwise, if the work is a derivative of the Library, you may
277+distribute the object code for the work under the terms of Section 6.
278+Any executables containing that work also fall under Section 6,
279+whether or not they are linked directly with the Library itself.
280+
281+ 6. As an exception to the Sections above, you may also combine or
282+link a "work that uses the Library" with the Library to produce a
283+work containing portions of the Library, and distribute that work
284+under terms of your choice, provided that the terms permit
285+modification of the work for the customer's own use and reverse
286+engineering for debugging such modifications.
287+
288+ You must give prominent notice with each copy of the work that the
289+Library is used in it and that the Library and its use are covered by
290+this License. You must supply a copy of this License. If the work
291+during execution displays copyright notices, you must include the
292+copyright notice for the Library among them, as well as a reference
293+directing the user to the copy of this License. Also, you must do one
294+of these things:
295+
296+ a) Accompany the work with the complete corresponding
297+ machine-readable source code for the Library including whatever
298+ changes were used in the work (which must be distributed under
299+ Sections 1 and 2 above); and, if the work is an executable linked
300+ with the Library, with the complete machine-readable "work that
301+ uses the Library", as object code and/or source code, so that the
302+ user can modify the Library and then relink to produce a modified
303+ executable containing the modified Library. (It is understood
304+ that the user who changes the contents of definitions files in the
305+ Library will not necessarily be able to recompile the application
306+ to use the modified definitions.)
307+
308+ b) Use a suitable shared library mechanism for linking with the
309+ Library. A suitable mechanism is one that (1) uses at run time a
310+ copy of the library already present on the user's computer system,
311+ rather than copying library functions into the executable, and (2)
312+ will operate properly with a modified version of the library, if
313+ the user installs one, as long as the modified version is
314+ interface-compatible with the version that the work was made with.
315+
316+ c) Accompany the work with a written offer, valid for at
317+ least three years, to give the same user the materials
318+ specified in Subsection 6a, above, for a charge no more
319+ than the cost of performing this distribution.
320+
321+ d) If distribution of the work is made by offering access to copy
322+ from a designated place, offer equivalent access to copy the above
323+ specified materials from the same place.
324+
325+ e) Verify that the user has already received a copy of these
326+ materials or that you have already sent this user a copy.
327+
328+ For an executable, the required form of the "work that uses the
329+Library" must include any data and utility programs needed for
330+reproducing the executable from it. However, as a special exception,
331+the materials to be distributed need not include anything that is
332+normally distributed (in either source or binary form) with the major
333+components (compiler, kernel, and so on) of the operating system on
334+which the executable runs, unless that component itself accompanies
335+the executable.
336+
337+ It may happen that this requirement contradicts the license
338+restrictions of other proprietary libraries that do not normally
339+accompany the operating system. Such a contradiction means you cannot
340+use both them and the Library together in an executable that you
341+distribute.
342+
343+ 7. You may place library facilities that are a work based on the
344+Library side-by-side in a single library together with other library
345+facilities not covered by this License, and distribute such a combined
346+library, provided that the separate distribution of the work based on
347+the Library and of the other library facilities is otherwise
348+permitted, and provided that you do these two things:
349+
350+ a) Accompany the combined library with a copy of the same work
351+ based on the Library, uncombined with any other library
352+ facilities. This must be distributed under the terms of the
353+ Sections above.
354+
355+ b) Give prominent notice with the combined library of the fact
356+ that part of it is a work based on the Library, and explaining
357+ where to find the accompanying uncombined form of the same work.
358+
359+ 8. You may not copy, modify, sublicense, link with, or distribute
360+the Library except as expressly provided under this License. Any
361+attempt otherwise to copy, modify, sublicense, link with, or
362+distribute the Library is void, and will automatically terminate your
363+rights under this License. However, parties who have received copies,
364+or rights, from you under this License will not have their licenses
365+terminated so long as such parties remain in full compliance.
366+
367+ 9. You are not required to accept this License, since you have not
368+signed it. However, nothing else grants you permission to modify or
369+distribute the Library or its derivative works. These actions are
370+prohibited by law if you do not accept this License. Therefore, by
371+modifying or distributing the Library (or any work based on the
372+Library), you indicate your acceptance of this License to do so, and
373+all its terms and conditions for copying, distributing or modifying
374+the Library or works based on it.
375+
376+ 10. Each time you redistribute the Library (or any work based on the
377+Library), the recipient automatically receives a license from the
378+original licensor to copy, distribute, link with or modify the Library
379+subject to these terms and conditions. You may not impose any further
380+restrictions on the recipients' exercise of the rights granted herein.
381+You are not responsible for enforcing compliance by third parties with
382+this License.
383+
384+ 11. If, as a consequence of a court judgment or allegation of patent
385+infringement or for any other reason (not limited to patent issues),
386+conditions are imposed on you (whether by court order, agreement or
387+otherwise) that contradict the conditions of this License, they do not
388+excuse you from the conditions of this License. If you cannot
389+distribute so as to satisfy simultaneously your obligations under this
390+License and any other pertinent obligations, then as a consequence you
391+may not distribute the Library at all. For example, if a patent
392+license would not permit royalty-free redistribution of the Library by
393+all those who receive copies directly or indirectly through you, then
394+the only way you could satisfy both it and this License would be to
395+refrain entirely from distribution of the Library.
396+
397+If any portion of this section is held invalid or unenforceable under any
398+particular circumstance, the balance of the section is intended to apply,
399+and the section as a whole is intended to apply in other circumstances.
400+
401+It is not the purpose of this section to induce you to infringe any
402+patents or other property right claims or to contest validity of any
403+such claims; this section has the sole purpose of protecting the
404+integrity of the free software distribution system which is
405+implemented by public license practices. Many people have made
406+generous contributions to the wide range of software distributed
407+through that system in reliance on consistent application of that
408+system; it is up to the author/donor to decide if he or she is willing
409+to distribute software through any other system and a licensee cannot
410+impose that choice.
411+
412+This section is intended to make thoroughly clear what is believed to
413+be a consequence of the rest of this License.
414+
415+ 12. If the distribution and/or use of the Library is restricted in
416+certain countries either by patents or by copyrighted interfaces, the
417+original copyright holder who places the Library under this License may add
418+an explicit geographical distribution limitation excluding those countries,
419+so that distribution is permitted only in or among countries not thus
420+excluded. In such case, this License incorporates the limitation as if
421+written in the body of this License.
422+
423+ 13. The Free Software Foundation may publish revised and/or new
424+versions of the Lesser General Public License from time to time.
425+Such new versions will be similar in spirit to the present version,
426+but may differ in detail to address new problems or concerns.
427+
428+Each version is given a distinguishing version number. If the Library
429+specifies a version number of this License which applies to it and
430+"any later version", you have the option of following the terms and
431+conditions either of that version or of any later version published by
432+the Free Software Foundation. If the Library does not specify a
433+license version number, you may choose any version ever published by
434+the Free Software Foundation.
435+
436+ 14. If you wish to incorporate parts of the Library into other free
437+programs whose distribution conditions are incompatible with these,
438+write to the author to ask for permission. For software which is
439+copyrighted by the Free Software Foundation, write to the Free
440+Software Foundation; we sometimes make exceptions for this. Our
441+decision will be guided by the two goals of preserving the free status
442+of all derivatives of our free software and of promoting the sharing
443+and reuse of software generally.
444+
445+ NO WARRANTY
446+
447+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
448+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
449+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
450+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
451+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
452+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
453+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
454+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
455+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
456+
457+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
458+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
459+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
460+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
461+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
462+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
463+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
464+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
465+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
466+DAMAGES.
467+
468+ END OF TERMS AND CONDITIONS
469+
470+ How to Apply These Terms to Your New Libraries
471+
472+ If you develop a new library, and you want it to be of the greatest
473+possible use to the public, we recommend making it free software that
474+everyone can redistribute and change. You can do so by permitting
475+redistribution under these terms (or, alternatively, under the terms of the
476+ordinary General Public License).
477+
478+ To apply these terms, attach the following notices to the library. It is
479+safest to attach them to the start of each source file to most effectively
480+convey the exclusion of warranty; and each file should have at least the
481+"copyright" line and a pointer to where the full notice is found.
482+
483+ <one line to give the library's name and a brief idea of what it does.>
484+ Copyright (C) <year> <name of author>
485+
486+ This library is free software; you can redistribute it and/or
487+ modify it under the terms of the GNU Lesser General Public
488+ License as published by the Free Software Foundation; either
489+ version 2.1 of the License, or (at your option) any later version.
490+
491+ This library is distributed in the hope that it will be useful,
492+ but WITHOUT ANY WARRANTY; without even the implied warranty of
493+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
494+ Lesser General Public License for more details.
495+
496+ You should have received a copy of the GNU Lesser General Public
497+ License along with this library; if not, write to the Free Software
498+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
499+
500+Also add information on how to contact you by electronic and paper mail.
501+
502+You should also get your employer (if you work as a programmer) or your
503+school, if any, to sign a "copyright disclaimer" for the library, if
504+necessary. Here is a sample; alter the names:
505+
506+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
507+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
508+
509+ <signature of Ty Coon>, 1 April 1990
510+ Ty Coon, President of Vice
511+
512+That's all there is to it!
513+
514+
Greeter/GreeterContent.qml+1
@@ -124,6 +124,7 @@ MouseArea {
124124
125125 function updateUsername(uid) {
126126 greeterContentLoader.infographicModel.username = greeterContentLoader.model.data(uid, LightDM.UserRoles.NameRole)
127+ greeterContentLoader.infographicModel.readyForDataChangeSlot();
127128 }
128129
129130 anchors {
LGPL_EXCEPTION.txtnew file+22
@@ -0,0 +1,22 @@
1+Digia Qt LGPL Exception version 1.1
2+
3+As an additional permission to the GNU Lesser General Public License version
4+2.1, the object code form of a "work that uses the Library" may incorporate
5+material from a header file that is part of the Library. You may distribute
6+such object code under terms of your choice, provided that:
7+ (i) the header files of the Library have not been modified; and
8+ (ii) the incorporated material is limited to numerical parameters, data
9+ structure layouts, accessors, macros, inline functions and
10+ templates; and
11+ (iii) you comply with the terms of Section 6 of the GNU Lesser General
12+ Public License version 2.1.
13+
14+Moreover, you may apply this exception to a modified version of the Library,
15+provided that such modification does not involve copying material from the
16+Library into the modified Library's header files unless such material is
17+limited to (i) numerical parameters; (ii) data structure layouts;
18+(iii) accessors; and (iv) small macros, templates and inline functions of
19+five lines or less in length.
20+
21+Furthermore, you are not required to apply this additional permission to a
22+modified version of the Library.
Notifications/Notification.qml+109−12
@@ -30,10 +30,25 @@ UbuntuShape {
3030 property var type
3131 property var notification
3232
33− implicitHeight: childrenRect.height
33+ objectName: "background"
34+ implicitHeight: contentColumn.height + contentColumn.spacing * 2
3435 color: Qt.rgba(0, 0, 0, 0.85)
3536 opacity: 0
3637
38+ clip: true
39+
40+ Behavior on implicitHeight {
41+ id: heightBehavior
42+
43+ enabled: false
44+ UbuntuNumberAnimation {
45+ duration: UbuntuAnimation.SnapDuration
46+ }
47+ }
48+
49+ // delay enabling height behavior until the add transition is complete
50+ onOpacityChanged: if (opacity == 1) heightBehavior.enabled = true
51+
3752 MouseArea {
3853 id: interactiveArea
3954
@@ -52,7 +67,7 @@ UbuntuShape {
5267 top: parent.top
5368 margins: spacing
5469 }
55− height: childrenRect.height + spacing
70+
5671 spacing: units.gu(1)
5772
5873 Row {
@@ -125,30 +140,112 @@ UbuntuShape {
125140 }
126141 }
127142
128− Row {
143+ Item {
129144 id: buttonRow
130145
131146 objectName: "buttonRow"
132− spacing: contentColumn.spacing
133− layoutDirection: Qt.RightToLeft
147+ anchors {
148+ left: parent.left
149+ right: parent.right
150+ }
134151 visible: notification.type == Notification.SnapDecision
152+ height: units.gu(4)
153+
154+ property real buttonWidth: (width - contentColumn.spacing) / 2
155+ property bool expanded
156+
157+ Button {
158+ id: leftButton
159+
160+ objectName: "button1"
161+ width: parent.expanded ? parent.width : parent.buttonWidth
162+ anchors {
163+ top: parent.top
164+ bottom: parent.bottom
165+ }
166+ text: notification.type == Notification.SnapDecision && actionRepeater.count >= 2 ? actionRepeater.itemAt(1).actionLabel : ""
167+ color: "#cdcdcb"
168+ onClicked: {
169+ if (actionRepeater.count > 2) {
170+ buttonRow.expanded = !buttonRow.expanded
171+ } else {
172+ notification.notification.invokeAction(actionRepeater.itemAt(1).actionId)
173+ }
174+ }
175+
176+ Behavior on width {
177+ UbuntuNumberAnimation {
178+ duration: UbuntuAnimation.SnapDuration
179+ }
180+ }
181+ }
182+
183+ Button {
184+ id: rightButton
185+
186+ objectName: "button0"
187+ anchors {
188+ left: leftButton.right
189+ leftMargin: contentColumn.spacing
190+ right: parent.right
191+ }
192+ text: notification.type == Notification.SnapDecision && actionRepeater.count >= 1 ? actionRepeater.itemAt(0).actionLabel : ""
193+ anchors {
194+ top: parent.top
195+ bottom: parent.bottom
196+ }
197+ color: "#d85317"
198+ visible: width > 0
199+ onClicked: notification.notification.invokeAction(actionRepeater.itemAt(0).actionId)
200+ }
201+ }
202+
203+ Column {
204+ objectName: "buttonColumn"
205+ spacing: contentColumn.spacing
135206 anchors {
136207 left: parent.left
137208 right: parent.right
138209 }
139210
211+ // calculate initial position before Column takes over
212+ y: buttonRow.y + buttonRow.height + contentColumn.spacing
213+
214+ visible: notification.type == Notification.SnapDecision
215+ height: buttonRow.expanded ? implicitHeight : 0
216+
140217 Repeater {
141218 id: actionRepeater
219+
142220 model: notification.actions
221+ delegate: Loader {
222+ id: loader
143223
144− Button {
145− objectName: "button" + index
146− color: Positioner.isFirstItem ? "#d85317" : "#cdcdcb"
147− width: (buttonRow.width - buttonRow.spacing) / 2
148− height: units.gu(4)
149− text: label
150224 property string actionId: id
151− onClicked: notification.notification.invokeAction(id)
225+ property string actionLabel: label
226+
227+ anchors {
228+ left: parent.left
229+ right: parent.right
230+ }
231+
232+ Component {
233+ id: actionButton
234+
235+ Button {
236+ objectName: "button" + index
237+ anchors {
238+ left: parent.left
239+ right: parent.right
240+ }
241+
242+ text: loader.actionLabel
243+ height: units.gu(4)
244+ color: "#cdcdcb"
245+ onClicked: notification.notification.invokeAction(loader.actionId)
246+ }
247+ }
248+ sourceComponent: (index == 0 || index == 1) ? undefined : actionButton
152249 }
153250 }
154251 }
Notifications/Notifications.qml+10−13
@@ -17,7 +17,6 @@
1717import QtQuick 2.0
1818import Ubuntu.Components 0.1
1919import "../Components"
20−import "timings.js" as Timings
2120
2221ListView {
2322 id: notificationList
@@ -40,40 +39,38 @@ ListView {
4039 actions: model.actions
4140 notificationId: model.id
4241 notification: notificationList.model.getRaw(notificationId)
42+
43+ // make sure there's no opacity-difference between the several
44+ // elements in a notification
45+ layer.enabled: add.running || remove.running || populate.running
4346 }
4447
4548 populate: Transition {
46− NumberAnimation {
49+ UbuntuNumberAnimation {
4750 property: "opacity"
4851 to: 1
49− duration: Timings.snapBeat
50− easing.type: Timings.easing
52+ duration: UbuntuAnimation.SnapDuration
5153 }
5254 }
5355
5456 add: Transition {
55− NumberAnimation {
57+ UbuntuNumberAnimation {
5658 property: "opacity"
5759 to: 1
58− duration: Timings.snapBeat
59− easing.type: Timings.easing
60+ duration: UbuntuAnimation.SnapDuration
6061 }
6162 }
6263
6364 remove: Transition {
64− NumberAnimation {
65+ UbuntuNumberAnimation {
6566 property: "opacity"
6667 to: 0
67− duration: Timings.fastBeat
68− easing.type: Timings.easing
6968 }
7069 }
7170
7271 displaced: Transition {
73− NumberAnimation {
72+ UbuntuNumberAnimation {
7473 properties: "x,y"
75− duration: Timings.fastBeat
76− easing.type: Timings.easing
7774 }
7875 }
7976}
Panel/Indicators.qml+111−27
@@ -16,32 +16,49 @@
1616
1717import QtQuick 2.0
1818import Ubuntu.Components 0.1
19+import Ubuntu.Gestures 0.1
1920import Ubuntu.ChewieUI 0.1 as ChewieUI
2021
2122import "../Components"
23+import "../Components/ListItems"
2224import "../Components/Math.js" as MathLocal
2325
2426Showable {
2527 id: indicators
2628
27− property int progress: panelHeight
28− property int openedHeight: units.gu(71)
29+ property int referenceOpenedHeight: units.gu(71)
30+ property real openedHeight: pinnedMode ? referenceOpenedHeight - panelHeight
31+ : referenceOpenedHeight
2932 property int panelHeight: units.gu(3)
3033 property bool pinnedMode: true //should be set true if indicators menu can cover whole screen
3134
3235 property int hintValue
33− readonly property int lockThreshold: shell.height/2
34− property bool fullyOpened: revealer ? progress == revealer.openedValue : false
35− property bool partiallyOpened: revealer ? progress > revealer.closedValue && progress < revealer.openedValue : false
36+ readonly property int lockThreshold: referenceOpenedHeight / 2
37+ property bool fullyOpened: height == openedHeight
38+ property bool partiallyOpened: height > panelHeight && !fullyOpened
39+
40+ // TODO: Perhaps we need a animation standard for showing/hiding? Each showable seems to
41+ // use its own values. Need to ask design about this.
42+ showAnimation: StandardAnimation {
43+ property: "height"
44+ duration: 350
45+ to: openedHeight
46+ easing.type: Easing.OutCubic
47+ }
3648
37− property Revealer revealer: null
49+ hideAnimation: StandardAnimation {
50+ property: "height"
51+ duration: 350
52+ to: panelHeight
53+ easing.type: Easing.OutCubic
54+ }
3855
39− height: menuContent.height + handle.height + menuContent.y
56+ height: panelHeight
4057
41− onProgressChanged: {
42− // need to use handle.get_height(). As the handle height depends on progress changes (but this is called first!)
43− var contentProgress = progress - handle.get_height()
44− if (!showAnimation.running && !hideAnimation.running && !revealer.hintingAnimation.running) {
58+ onHeightChanged: {
59+ // need to use handle.get_height(). As the handle height depends on indicators.height changes (but this is called first!)
60+ var contentProgress = indicators.height - handle.get_height()
61+ if (!showAnimation.running && !hideAnimation.running) {
4562 if (contentProgress <= hintValue && indicators.state == "reveal") {
4663 indicators.state = "hint"
4764 menuContent.hideAll()
@@ -66,12 +83,6 @@ Showable {
6683 }
6784 }
6885
69− function handlePress() {
70− menuContent.hideAll()
71− menuContent.activateContent()
72− indicators.state = "hint"
73− }
74−
7586 function openOverview() {
7687 indicatorRow.currentItem = null
7788 menuContent.showOverview()
@@ -91,7 +102,9 @@ Showable {
91102 If bar is dragged down a distance greater than or equal to lockThreshold, this is 1.
92103 Otherwise it contains the bar's location as a fraction of the distance between hintValue (is 0) and lockThreshold (is 1).
93104 */
94− var verticalProgress = MathLocal.clamp((indicators.progress - handle.height - hintValue) / (lockThreshold - hintValue), 0, 1)
105+ var verticalProgress =
106+ MathLocal.clamp((indicators.height - handle.height - hintValue) /
107+ (lockThreshold - hintValue), 0, 1)
95108
96109 /*
97110 Percentage of an indicator icon's width the user's press can stray horizontally from the
@@ -139,6 +152,17 @@ Showable {
139152 }
140153 }
141154
155+ VerticalThinDivider {
156+ anchors {
157+ top: indicators.top
158+ topMargin: panelHeight
159+ bottom: handle.bottom
160+ right: indicators.left
161+ }
162+ width: units.dp(2)
163+ source: "graphics/VerticalDivider.png"
164+ }
165+
142166 MenuContent {
143167 id: menuContent
144168 objectName: "menuContent"
@@ -147,8 +171,8 @@ Showable {
147171 left: parent.left
148172 right: parent.right
149173 top: indicatorRow.bottom
174+ bottom: parent.bottom
150175 }
151− height: progress - y
152176 indicatorsModel: indicatorsModel
153177 animate: false
154178 clip: indicators.partiallyOpened
@@ -187,7 +211,7 @@ Showable {
187211 clip: height < handleImage.height
188212
189213 function get_height() {
190− return Math.max(Math.min(handleImage.height, progress - handleImage.height), 0)
214+ return Math.max(Math.min(handleImage.height, indicators.height - handleImage.height), 0)
191215 }
192216
193217 BorderImage {
@@ -205,6 +229,29 @@ Showable {
205229 }
206230 }
207231
232+ PanelSeparatorLine {
233+ id: indicatorsSeparatorLine
234+ visible: true
235+ anchors {
236+ top: handle.bottom
237+ left: indicators.left
238+ right: indicators.right
239+ }
240+ }
241+
242+ BorderImage {
243+ id: dropShadow
244+ anchors {
245+ top: indicators.top
246+ bottom: indicatorsSeparatorLine.bottom
247+ left: indicators.left
248+ right: indicators.right
249+ margins: -units.gu(1)
250+ }
251+ visible: indicators.height > panelHeight
252+ source: "graphics/rectangular_dropshadow.sci"
253+ }
254+
208255 PanelBackground {
209256 anchors.fill: indicatorRow
210257 }
@@ -249,7 +296,7 @@ Showable {
249296 openOverview()
250297 }
251298 else {
252− indicators.calculateCurrentItem(revealer.lateralPosition, false)
299+ indicators.calculateCurrentItem(dragHandle.touchX, false)
253300 menuContent.showMenu()
254301 }
255302 indicators.state = "commit"
@@ -258,10 +305,10 @@ Showable {
258305 }
259306
260307 Connections {
261− target: revealer
262− onLateralPositionChanged: {
263− var buffer = revealer.dragging ? true : false
264− indicators.calculateCurrentItem(revealer.lateralPosition, buffer)
308+ target: dragHandle
309+ onTouchXChanged: {
310+ var buffer = dragHandle.dragging ? true : false
311+ indicators.calculateCurrentItem(dragHandle.touchX, buffer)
265312 }
266313 }
267314
@@ -277,6 +324,43 @@ Showable {
277324 state = last_state;
278325 }
279326
327+ property var dragHandle: showDragHandle.dragging ? showDragHandle : hideDragHandle
328+ DragHandle {
329+ id: showDragHandle
330+ anchors.bottom: parent.bottom
331+ // go beyond parent so that it stays reachable, at the top of the screen.
332+ anchors.bottomMargin: pinnedMode ? 0 : -panelHeight
333+ anchors.left: parent.left
334+ anchors.right: parent.right
335+ height: panelHeight
336+ direction: Direction.Downwards
337+ enabled: !indicators.shown
338+ hintDisplacement: pinnedMode ? indicators.hintValue : 0
339+ autoCompleteDragThreshold: maxTotalDragDistance / 2
340+ stretch: true
341+ maxTotalDragDistance: openedHeight - handle.height
342+ distanceThreshold: pinnedMode ? 0 : units.gu(3)
343+
344+ onStatusChanged: {
345+ if (status === DirectionalDragArea.Recognized) {
346+ menuContent.hideAll()
347+ menuContent.activateContent()
348+ }
349+ }
350+ }
351+ DragHandle {
352+ id: hideDragHandle
353+ anchors.fill: handle
354+ height: panelHeight
355+ direction: Direction.Upwards
356+ enabled: indicators.shown
357+ hintDisplacement: units.gu(2)
358+ autoCompleteDragThreshold: maxTotalDragDistance / 6
359+ stretch: true
360+ maxTotalDragDistance: referenceOpenedHeight - 2*panelHeight
361+ distanceThreshold: 0
362+ }
363+
280364 property list<State> offScreenModeStates: [
281365 State {
282366 name: "initial"
@@ -289,7 +373,7 @@ Showable {
289373 name: "reveal"
290374 extend: "hint"
291375 PropertyChanges { target: menuContent; animate: true }
292− StateChangeScript { script: calculateCurrentItem(revealer.lateralPosition, false); }
376+ StateChangeScript { script: calculateCurrentItem(dragHandle.touchX, false); }
293377 },
294378 State {
295379 name: "locked"
@@ -311,7 +395,7 @@ Showable {
311395 State {
312396 name: "reveal"
313397 PropertyChanges { target: menuContent; animate: true }
314− StateChangeScript { script: calculateCurrentItem(revealer.lateralPosition, false); }
398+ StateChangeScript { script: calculateCurrentItem(dragHandle.touchX, false); }
315399 },
316400 State {
317401 name: "locked"
Panel/MenuContent.qml+1−1
@@ -98,7 +98,7 @@ Rectangle {
9898 visible: content.__shown
9999 onVisibleChanged: {
100100 // Reset the indicator states
101− if (!visible && item) {
101+ if (!visible && item && item["reset"]) {
102102 item.reset()
103103 }
104104 }
Panel/Panel.qml+3−74
@@ -17,7 +17,6 @@
1717import QtQuick 2.0
1818import Ubuntu.Components 0.1
1919import "../Components"
20−import "../Components/ListItems"
2120
2221Item {
2322 id: root
@@ -75,29 +74,6 @@ Item {
7574 }
7675 }
7776
78− BorderImage {
79− id: dropShadow
80− anchors {
81− top: indicatorsMenu.top
82− bottom: indicatorsSeparatorLine.bottom
83− left: indicatorsMenu.left
84− right: indicatorsMenu.right
85− margins: -units.gu(1)
86− }
87− visible: indicatorsMenu.progress != indicatorRevealer.closedValue
88− source: "graphics/rectangular_dropshadow.sci"
89− }
90−
91− VerticalThinDivider {
92− anchors {
93− top: leftSeparatorLine.top
94− bottom: indicatorsSeparatorLine.top
95− right: indicatorsMenu.left
96− }
97− width: units.dp(2)
98− source: "graphics/VerticalDivider.png"
99− }
100−
10177 Indicators {
10278 id: indicatorsMenu
10379
@@ -105,58 +81,13 @@ Item {
10581 y: 0
10682 width: root.indicatorsMenuWidth
10783 shown: false
108− revealer: indicatorRevealer
109− hintValue: indicatorRevealer.hintDisplacement
84+ hintValue: __panelMinusSeparatorLineHeight * 3
11085 panelHeight: __panelMinusSeparatorLineHeight
111− showAnimation: StandardAnimation { property: "progress"; duration: 350; to: indicatorRevealer.openedValue; easing.type: Easing.OutCubic }
112− hideAnimation: StandardAnimation { property: "progress"; duration: 350; to: indicatorRevealer.closedValue; easing.type: Easing.OutCubic }
113− openedHeight: parent.height
86+ referenceOpenedHeight: parent.height
11487
11588 pinnedMode: !fullscreenMode
11689
117− property real unitProgress: (indicatorRevealer.closedValue - progress) / (indicatorRevealer.closedValue - indicatorRevealer.openedValue)
118− }
119−
120− PanelSeparatorLine {
121− id: indicatorsSeparatorLine
122− anchors {
123− top: indicatorsMenu.bottom
124− left: indicatorsMenu.left
125− right: parent.right
126− }
127− }
128−
129− Revealer {
130− id: indicatorRevealer
131− objectName: "indicatorRevealer"
132−
133− width: root.indicatorsMenuWidth
134− anchors {
135− top: parent.top
136− bottom: parent.bottom
137− right: parent.right
138− }
139− target: indicatorsMenu
140− handleSize: __panelMinusSeparatorLineHeight
141− closedValue: __panelMinusSeparatorLineHeight
142− dragVelocityThreshold: units.dp(1)
143− boundProperty: "progress"
144− hintDisplacement: __panelMinusSeparatorLineHeight * 3
145− openOnPress: !fullscreenMode
146− orientation: Qt.Vertical
147−
148− onOpenClicked: {
149− indicatorsMenu.openOverview();
150− indicatorsMenu.show();
151− }
152− onCloseClicked: indicatorsMenu.hide();
153−
154− onOpenPressed: indicatorsMenu.handlePress()
155−
156− function dragToValue(dragPosition) {
157− var offset = target.shown ? 0 : -hintDisplacement + handleSize;
158− return dragPosition + offset;
159− }
90+ property real unitProgress: (height - panelHeight) / (openedHeight - panelHeight)
16091 }
16192
16293 SearchIndicator {
@@ -192,13 +123,11 @@ Item {
192123 name: "in" //fully opaque and visible at top edge of screen
193124 when: !fullscreenMode
194125 PropertyChanges { target: panelBackground; y: 0 }
195− PropertyChanges { target: indicatorRevealer; openedValue: indicatorsMenu.openedHeight - panelHeight }
196126 },
197127 State {
198128 name: "out" //pushed off screen
199129 when: fullscreenMode
200130 PropertyChanges { target: panelBackground; y: -panelHeight }
201− PropertyChanges { target: indicatorRevealer; openedValue: indicatorsMenu.openedHeight }
202131 }
203132 ]
204133}
debian/changelog+7
@@ -1,3 +1,10 @@
1+unity8 (7.81.3-0ubuntu1) UNRELEASED; urgency=low
2+
3+ * Clean packaging for entering saucy and following daily release guidelines
4+ * Automatic snapshot from revision 49 (bootstrap)
5+
6+ -- Didier Roche <didrocks@ubuntu.com> Wed, 26 Jun 2013 11:01:09 +0200
7+
18unity8 (7.81.3) UNRELEASED; urgency=low
29
310 * Choose more appropriate values for edge-drag gestures (LP: #1194150)
debian/control+46−48
@@ -1,10 +1,10 @@
11Source: unity8
22Section: x11
3−Priority: extra
3+Priority: optional
44Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
55Build-Depends: cmake,
66 debhelper (>= 9),
7− libc6-dev,
7+ libjson-perl,
88 libdee-qt5-dev (>= 3.0),
99 libgl1-mesa-dev[!armhf] | libgl-dev[!armhf],
1010 libgl1-mesa-dri,
@@ -14,9 +14,13 @@ Build-Depends: cmake,
1414 libqt5v8-5-private-dev,
1515 libunity-core-6.0-dev (<< 7.80),
1616 libunity-api-dev,
17+ libunity-dev (>= 7.0.3),
18+ libusermetricsoutput1-dev,
1719 libxcb1-dev,
1820 pkg-config,
1921 python3,
22+ python (>= 2.7),
23+ python-setuptools,
2024 qt5-default,
2125 qtbase5-dev,
2226 qtbase5-private-dev,
@@ -28,75 +32,69 @@ Build-Depends: cmake,
2832 qtdeclarative5-ubuntu-ui-toolkit-plugin,
2933 qtdeclarative5-xmllistmodel-plugin,
3034 ttf-ubuntu-font-family,
31−Standards-Version: 3.9.3
35+ libunity-scopes-json-def-phone,
36+Standards-Version: 3.9.4
3237Homepage: http://launchpad.net/unity
3338# If you aren't a member of ~unity-team but need to upload
3439# packaging changes, just go ahead. ~unity-team will notice
3540# and sync up the code again.
36−Vcs-Bzr: https://code.launchpad.net/~unity-team/unity/phablet
37−Vcs-Browser: https://bazaar.launchpad.net/~unity-team/unity/phablet/files
41+Vcs-Bzr: https://code.launchpad.net/unity8
42+Vcs-Browser: https://bazaar.launchpad.net/~unity-team/unity8/trunk
3843
3944Package: unity8
40−Replaces: qml-phone-shell (<< 7.80~)
41−Breaks: qml-phone-shell (<< 7.80~)
42−Architecture: amd64 armhf i386
43−Depends: indicators-client (>= 0.6.1),
45+Architecture: any
46+Depends: ${misc:Depends},
47+ ${shlibs:Depends},
48+ unity8-private (= ${binary:Version}),
49+ indicators-client (>= 0.6.1),
4450 qtdeclarative5-dee-plugin,
4551 qtdeclarative5-ubuntu-ui-toolkit-plugin,
4652 qtdeclarative5-unity-notifications-plugin | unity-notifications-impl,
4753 unity-notifications-impl-1,
4854 qtdeclarative5-xmllistmodel-plugin,
49− qtubuntu,
50− ${misc:Depends},
51− ${shlibs:Depends},
52−Recommends: indicators-client-plugin-datetime (>= 0.6.1),
55+ unity8-fake-env | qtubuntu-shell,
56+Recommends: ${unity-default-masterscopes},
57+ indicators-client-plugin-datetime (>= 0.6.1),
5358 indicators-client-plugin-messaging (>= 0.6.1),
5459 indicators-client-plugin-network (>= 0.6.1),
5560 indicators-client-plugin-power (>= 0.6.1),
5661 indicators-client-plugin-sound (>= 0.6.1),
57− unity-scope-home,
58− unity-lens-applications,
59−Description: Ubuntu QML shell
60− The Ubuntu QML shell is the primary user interface for Ubuntu devices.
62+Description: Unity 8 shell
63+ The Unity 8 shell is the primary user interface for Ubuntu devices.
6164
62−Package: qml-phone-shell
63−Depends: unity8, ${misc:Depends}
64−Architecture: all
65−Description: transitional dummy package
66− This is a transitional dummy package. It can safely be removed.
65+Package: unity8-private
66+Architecture: any
67+Multi-Arch: same
68+Pre-Depends: ${misc:Pre-Depends}
69+Depends: ${misc:Depends},
70+ ${shlibs:Depends},
71+Description: Unity 8 private libs
72+ The Unity 8 shell is the primary user interface for Ubuntu devices.
73+ .
74+ This package contains the private libraries for QML and other components
75+ only used by the shell.
6776
6877Package: unity8-fake-env
69−Replaces: qml-phone-shell-fake-env (<< 7.80~)
70−Breaks: qml-phone-shell-fake-env (<< 7.80~)
71−Architecture: amd64 armhf i386
72−Depends: ${misc:Depends}, ${shlibs:Depends}
73−Description: Fake environment for running Ubuntu QML shell
74− Provides fake implementations of some QML modules used by Ubuntu QML shell
78+Architecture: any
79+Multi-Arch: same
80+Pre-Depends: ${misc:Pre-Depends}
81+Depends: ${misc:Depends},
82+ ${shlibs:Depends},
83+Provides: qtubuntu-shell,
84+Description: Fake environment for running Unity 8 shell
85+ Provides fake implementations of some QML modules used by Unity 8 shell
7586 (e.g Ubuntu.Application) so that you can run it in a sandboxed environment.
7687
77−Package: qml-phone-shell-fake-env
78−Depends: unity8-fake-env, ${misc:Depends}
79−Architecture: all
80−Description: transitional dummy package
81− This is a transitional dummy package. It can safely be removed.
82−
8388Package: unity8-autopilot
84−Replaces: qml-phone-shell-autopilot (<< 7.80~)
85−Breaks: qml-phone-shell-autopilot (<< 7.80~)
8689Architecture: all
87−Depends: libautopilot-qt,
90+Depends: ${misc:Depends},
91+ ${shlibs:Depends},
92+ ${python:Depends},
93+ libautopilot-qt,
8894 libqt5test5,
8995 libqt5widgets5,
9096 python-evdev,
91− unity8 (= ${source:Version}),
92− unity8-fake-env (= ${source:Version}),
93− ${misc:Depends},
94− ${shlibs:Depends},
95−Description: Test package for the shell
97+ unity8 (>= ${source:Version}),
98+ unity8-fake-env (>= ${source:Version}),
99+Description: Test package for Unity 8 shell
96100 Autopilot tests for the unity8 package
97−
98−Package: qml-phone-shell-autopilot
99−Depends: unity8-autopilot, ${misc:Depends}
100−Architecture: all
101−Description: transitional dummy package
102− This is a transitional dummy package. It can safely be removed.
debian/copyright+13−3
@@ -1,7 +1,9 @@
11Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
2+Upstream-Name: unity8
3+Source: http://launchpad.net/unity
24
35Files: *
4−Copyright: 2013 Canonical Ltd.
6+Copyright: 2011-2013 Canonical Ltd.
57License: GPL-3
68
79License: GPL-3
@@ -20,9 +22,17 @@ License: GPL-3
2022 On Debian systems, the full text of the GNU General Public License
2123 version 3 can be found in the file /usr/share/common-licenses/GPL-3.
2224
23−Files: tests/unittests/plugins/Utils/modeltest.*
25+Files: tests/mocks/LightDM/UsersModel.h tests/mocks/LightDM/Greeter.h
26+Copyright: 2013 Canonical Ltd.
27+ 2010-2011 David Edmundson
28+ 2010-2011 Robert Ancell
29+License: GPL-3
30+
31+Files: plugins/Utils/qvariantlistmodel.*
32+ tests/unittests/plugins/Utils/modeltest.*
33+ tests/plugins/Utils/modeltest.*
2434Copyright: 2013 Digia Plc and/or its subsidiary(-ies).
25−License:
35+License: LGPL-2.1 with Digia Qt LGPL Exception 1.1 or GPL-3
2636 Commercial License Usage
2737 Licensees holding valid commercial Qt licenses may use this file in
2838 accordance with the commercial license agreement provided with the
debian/rules+22−2
@@ -6,11 +6,31 @@
66export DPKG_GENSYMBOLS_CHECK_LEVEL=4
77export NO_PNG_PKG_MANGLE=1
88
9+SCOPES_RECOMMENDS := $(shell perl debian/scopes-recommends-generator /usr/share/unity/client-scopes.json)
10+
911%:
10− dh $@ --parallel
12+ dh $@ --parallel --fail-missing --with python2
13+
14+override_dh_auto_clean:
15+ dh_auto_clean
16+ rm -rf builddir
1117
1218override_dh_install:
13− dh_install --fail-missing
19+ # install autopilot tests
20+ cd tests/autopilot; \
21+ set -ex; for python in $(shell pyversions -r); do \
22+ $$python setup.py install --root=$(CURDIR)/debian/tmp --install-layout=deb; \
23+ done; \
24+ cd $(CURDIR)
25+ dh_install -X'*.pyc' --fail-missing
1426
27+# use private lib directories
28+override_dh_makeshlibs:
29+ dh_makeshlibs -Nunity8-private -Nunity8-fake-env
30+
31+# libMockLightDM-qml.so links against liblightdm-qt5-2.so which doesn't exist
1532override_dh_shlibdeps:
1633 dh_shlibdeps -XlibMockLightDM-qml.so
34+
35+override_dh_gencontrol:
36+ dh_gencontrol -- -Vunity-default-masterscopes="$(SCOPES_RECOMMENDS)"
debian/scopes-recommends-generatornew file+27
@@ -0,0 +1,27 @@
1+#!/usr/bin/perl -w
2+
3+use strict;
4+binmode STDOUT, ":utf8";
5+use utf8;
6+
7+use JSON;
8+
9+my $json;
10+{
11+ local $/; #Enable 'slurp' mode
12+ open my $fh, "<", $ARGV[0];
13+ $json = <$fh>;
14+ close $fh;
15+}
16+# get it to a scalar
17+my $j = "[" . $json . "]";
18+
19+my $decoded_json = decode_json( $j );
20+
21+my $recommends_list = "";
22+for my $record ( @$decoded_json ) {
23+ foreach my $key ( keys(%$record) ) {
24+ $recommends_list = $recommends_list . $key . ", ";
25+ }
26+}
27+print $recommends_list;
debian/unity8-autopilot.install+1−1
@@ -1 +1 @@
1−tests/autopilot/unity8/* usr/lib/python2.7/dist-packages/unity8/
1+usr/lib/python*/*/unity*
debian/unity8-fake-env.install+1−1
@@ -1 +1 @@
1−/usr/share/unity8/plugins/mocks/*
1+usr/lib/*/unity8/qml/mocks
debian/unity8-private.installnew file+6
@@ -0,0 +1,6 @@
1+usr/lib/*/unity8/qml/HudClient
2+usr/lib/*/unity8/qml/LightDM
3+usr/lib/*/unity8/qml/ListViewWithPageHeader
4+usr/lib/*/unity8/qml/Ubuntu
5+usr/lib/*/unity8/qml/Unity
6+usr/lib/*/unity8/qml/Utils
debian/unity8.install+15−21
@@ -1,21 +1,15 @@
1−/usr/bin/unity8
2−/usr/share/applications/unity8.desktop
3−/usr/share/locale/*
4−/usr/share/unity8/Applications/*
5−/usr/share/unity8/Bottombar/*
6−/usr/share/unity8/Components/*
7−/usr/share/unity8/Dash/*
8−/usr/share/unity8/Greeter/*
9−/usr/share/unity8/Hud/*
10−/usr/share/unity8/Launcher/*
11−/usr/share/unity8/Notifications/*
12−/usr/share/unity8/Panel/*
13−/usr/share/unity8/Shell.qml
14−/usr/share/unity8/SideStage/*
15−/usr/share/unity8/graphics/*
16−/usr/share/unity8/plugins/HudClient/*
17−/usr/share/unity8/plugins/LightDM/*
18−/usr/share/unity8/plugins/ListViewWithPageHeader/*
19−/usr/share/unity8/plugins/Ubuntu/*
20−/usr/share/unity8/plugins/Unity/*
21−/usr/share/unity8/plugins/Utils/*
1+usr/bin/unity8
2+usr/share/applications/unity8.desktop
3+usr/share/locale
4+usr/share/unity8/Applications
5+usr/share/unity8/Bottombar
6+usr/share/unity8/Components
7+usr/share/unity8/Dash
8+usr/share/unity8/Greeter
9+usr/share/unity8/Hud
10+usr/share/unity8/Launcher
11+usr/share/unity8/Notifications
12+usr/share/unity8/Panel
13+usr/share/unity8/Shell.qml
14+usr/share/unity8/SideStage
15+usr/share/unity8/graphics
main.cpp+8−9
@@ -39,10 +39,10 @@ void prependImportPaths(QQmlEngine *engine, const QStringList &paths)
3939 // don't duplicate
4040 const QString& path = paths[i];
4141 QStringList::iterator iter = qFind(importPathList.begin(), importPathList.end(), path);
42− if (iter == importPathList.end())
43− importPathList.prepend(path);
42+ if (iter == importPathList.end()) {
43+ engine->addImportPath(path);
44+ }
4445 }
45− engine->setImportPathList(importPathList);
4646}
4747
4848/* When you append and import path to the list of import paths it will be the *last*
@@ -54,10 +54,10 @@ void appendImportPaths(QQmlEngine *engine, const QStringList &paths)
5454 Q_FOREACH(const QString& path, paths) {
5555 // don't duplicate
5656 QStringList::iterator iter = qFind(importPathList.begin(), importPathList.end(), path);
57− if (iter == importPathList.end())
57+ if (iter == importPathList.end()) {
5858 importPathList.append(path);
59+ }
5960 }
60− importPathList.append(paths);
6161 engine->setImportPathList(importPathList);
6262}
6363
@@ -79,7 +79,7 @@ int main(int argc, char** argv)
7979 setenv("QML_FORCE_THREADED_RENDERER", "1", 1);
8080 setenv("QML_FIXED_ANIMATION_STEP", "1", 1);
8181
82− QGuiApplication::setApplicationName("Qml Phone Shell");
82+ QGuiApplication::setApplicationName("Unity 8");
8383 QGuiApplication application(argc, argv);
8484
8585 resolveIconTheme();
@@ -134,9 +134,8 @@ int main(int argc, char** argv)
134134 QObject::connect(view->engine(), SIGNAL(quit()), qApp, SLOT(quit()));
135135
136136 QUrl source("Shell.qml");
137− prependImportPaths(view->engine(), QStringList() << ::shellAppDirectory());
138− prependImportPaths(view->engine(), ::shellImportPaths());
139− appendImportPaths(view->engine(), QStringList() << ::fakePluginsImportPath());
137+ prependImportPaths(view->engine(), ::overrideImportPaths());
138+ appendImportPaths(view->engine(), ::fallbackImportPaths());
140139 view->setSource(source);
141140 view->setColor("transparent");
142141
paths.h.in+8−7
@@ -46,22 +46,23 @@ inline QString shellAppDirectory() {
4646 }
4747}
4848
49−inline QStringList shellImportPaths() {
49+inline QStringList overrideImportPaths() {
5050 QStringList paths;
51− if (isRunningInstalled()) {
52− paths << QString("@CMAKE_INSTALL_PREFIX@/@SHELL_APP_DIR@/plugins");
53− } else {
51+ if (!isRunningInstalled()) {
5452 paths << QString("@CMAKE_BINARY_DIR@/plugins");
5553 }
5654 return paths;
5755}
5856
59−inline QString fakePluginsImportPath() {
57+inline QStringList fallbackImportPaths() {
58+ QStringList paths;
6059 if (isRunningInstalled()) {
61− return QString("@CMAKE_INSTALL_PREFIX@/@SHELL_APP_DIR@/plugins/mocks");
60+ paths << QString("@CMAKE_INSTALL_PREFIX@/@SHELL_PRIVATE_LIBDIR@/qml");
61+ paths << QString("@CMAKE_INSTALL_PREFIX@/@SHELL_PRIVATE_LIBDIR@/qml/mocks");
6262 } else {
63− return QString("@CMAKE_BINARY_DIR@/tests/mocks");
63+ paths << QString("@CMAKE_BINARY_DIR@/tests/mocks");
6464 }
65+ return paths;
6566}
6667
6768inline QString sourceDirectory() {
plugins/HudClient/CMakeLists.txt+2−2
@@ -41,9 +41,9 @@ file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/qmldir"
4141 )
4242
4343install(TARGETS HudClientQml
44− DESTINATION ${SHELL_APP_DIR}/plugins/HudClient
44+ DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/HudClient
4545 )
4646
4747install(FILES qmldir
48− DESTINATION ${SHELL_APP_DIR}/plugins/HudClient
48+ DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/HudClient
4949 )
plugins/LightDM/CMakeLists.txt+6−3
@@ -1,6 +1,7 @@
11# Dependencies
2+include(FindPkgConfig)
3+pkg_check_modules(LIBUSERMETRICSOUTPUT REQUIRED libusermetricsoutput-1)
24# TODO: Once we split out a separate greeter process, uncomment these lines
3−#include(FindPkgConfig)
45#pkg_check_modules(LIBLIGHTDM REQUIRED liblightdm-qt5-2)
56
67include_directories(
@@ -8,6 +9,7 @@ include_directories(
89 ${CMAKE_CURRENT_BINARY_DIR}
910 ${CMAKE_SOURCE_DIR}/tests/mocks/LightDM
1011 #${LIBLIGHTDM_INCLUDE_DIRS}
12+ ${LIBUSERMETRICSOUTPUT_INCLUDE_DIRS}
1113)
1214
1315set(QMLPLUGIN_SRC
@@ -25,6 +27,7 @@ target_link_libraries(LightDM-qml
2527 MockLightDM-demo
2628# TODO: Once we split out a separate greeter process, uncomment these lines
2729# ${LIBLIGHTDM_LDFLAGS}
30+ ${LIBUSERMETRICSOUTPUT_LDFLAGS}
2831 )
2932
3033qt5_use_modules(LightDM-qml Gui Qml)
@@ -35,9 +38,9 @@ file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/qmldir"
3538 )
3639
3740install(TARGETS LightDM-qml
38− DESTINATION ${SHELL_APP_DIR}/plugins/LightDM
41+ DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/LightDM
3942 )
4043
4144install(FILES qmldir
42− DESTINATION ${SHELL_APP_DIR}/plugins/LightDM
45+ DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/LightDM
4346 )
plugins/LightDM/Greeter.cpp+6−6
@@ -102,21 +102,21 @@ bool Greeter::startSessionSync(const QString &session)
102102 return d->m_greeter->startSessionSync(session);
103103}
104104
105−void Greeter::showPromptFilter(QString text, QLightDM::Greeter::PromptType type)
105+void Greeter::showPromptFilter(const QString &text, QLightDM::Greeter::PromptType type)
106106{
107107 Q_D(Greeter);
108108 d->wasPrompted = true;
109109
110110 // Strip prompt of any colons at the end
111− text = text.trimmed();
112− if (text.endsWith(":") || text.endsWith(":")) {
113− text.chop(1);
111+ QString trimmedText = text.trimmed();
112+ if (trimmedText.endsWith(":") || trimmedText.endsWith(":")) {
113+ trimmedText.chop(1);
114114 }
115115
116− Q_EMIT showPrompt(text, type == QLightDM::Greeter::PromptTypeSecret);
116+ Q_EMIT showPrompt(trimmedText, type == QLightDM::Greeter::PromptTypeSecret);
117117}
118118
119−void Greeter::showMessageFilter(QString text, QLightDM::Greeter::MessageType type)
119+void Greeter::showMessageFilter(const QString &text, QLightDM::Greeter::MessageType type)
120120{
121121 Q_EMIT showMessage(text, type == QLightDM::Greeter::MessageTypeError);
122122}
plugins/LightDM/Greeter.h+4−4
@@ -51,8 +51,8 @@ public Q_SLOTS:
5151 bool startSessionSync(const QString &session=QString());
5252
5353Q_SIGNALS:
54− void showMessage(QString text, bool isError);
55− void showPrompt(QString text, bool isSecret);
54+ void showMessage(const QString &text, bool isError);
55+ void showPrompt(const QString &text, bool isSecret);
5656 void authenticationComplete();
5757 void promptlessChanged();
5858
@@ -62,8 +62,8 @@ private:
6262 Q_DECLARE_PRIVATE(Greeter)
6363
6464private Q_SLOTS:
65− void showMessageFilter(QString text, QLightDM::Greeter::MessageType type);
66− void showPromptFilter(QString text, QLightDM::Greeter::PromptType type);
65+ void showMessageFilter(const QString &text, QLightDM::Greeter::MessageType type);
66+ void showPromptFilter(const QString &text, QLightDM::Greeter::PromptType type);
6767 void authenticationCompleteFilter();
6868};
6969
plugins/LightDM/plugin.cpp+5−4
@@ -20,8 +20,9 @@
2020#include "plugin.h"
2121#include "Greeter.h"
2222#include "UsersModel.h"
23+#include <libusermetricsoutput/ColorTheme.h>
24+#include <libusermetricsoutput/UserMetrics.h>
2325#include <QLightDM/UsersModel>
24−#include "InfographicModel.h"
2526
2627#include <QtCore/QAbstractItemModel>
2728#include <QtQml>
@@ -44,17 +45,17 @@ static QObject *infographic_provider(QQmlEngine *engine, QJSEngine *scriptEngine
4445{
4546 Q_UNUSED(engine)
4647 Q_UNUSED(scriptEngine)
47− return InfographicModel::getInstance();
48+ return UserMetricsOutput::UserMetrics::getInstance();
4849}
4950
5051void LightDMPlugin::registerTypes(const char *uri)
5152{
5253 qmlRegisterType<QAbstractItemModel>();
53− qmlRegisterType<InfographicColorTheme>();
54+ qmlRegisterType<UserMetricsOutput::ColorTheme>();
5455
5556 Q_ASSERT(uri == QLatin1String("LightDM"));
5657 qmlRegisterSingletonType<Greeter>(uri, 0, 1, "Greeter", greeter_provider);
5758 qmlRegisterSingletonType<UsersModel>(uri, 0, 1, "Users", users_provider);
5859 qmlRegisterUncreatableType<QLightDM::UsersModel>(uri, 0, 1, "UserRoles", "Type is not instantiable");
59− qmlRegisterSingletonType<InfographicModel>(uri, 0, 1, "Infographic", infographic_provider);
60+ qmlRegisterSingletonType<UserMetricsOutput::UserMetrics>(uri, 0, 1, "Infographic", infographic_provider);
6061}
plugins/ListViewWithPageHeader/CMakeLists.txt+2−2
@@ -36,9 +36,9 @@ file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/qmldir"
3636 )
3737
3838install(TARGETS ListViewWithPageHeader-qml
39− DESTINATION ${SHELL_APP_DIR}/plugins/ListViewWithPageHeader
39+ DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/ListViewWithPageHeader
4040 )
4141
4242install(FILES qmldir
43− DESTINATION ${SHELL_APP_DIR}/plugins/ListViewWithPageHeader
43+ DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/ListViewWithPageHeader
4444 )
plugins/ListViewWithPageHeader/listviewwithpageheader.cpp+3
@@ -342,6 +342,9 @@ void ListViewWithPageHeader::positionAtBeginning()
342342
343343void ListViewWithPageHeader::showHeader()
344344{
345+ if (!m_headerItem)
346+ return;
347+
345348 auto to = qMax(-minYExtent(), contentY() - m_headerItem->height() + m_headerItemShownHeight);
346349 if (to != contentY()) {
347350 m_headerShowAnimation->setTo(to);
plugins/Ubuntu/Gestures/CMakeLists.txt+2−2
@@ -27,9 +27,9 @@ add_custom_target(UbuntuGestureQmlDirFile ALL
2727)
2828
2929install(TARGETS UbuntuGestureQml
30− DESTINATION ${SHELL_APP_DIR}/plugins/Ubuntu/Gestures
30+ DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/Ubuntu/Gestures
3131 )
3232
3333install(FILES qmldir
34− DESTINATION ${SHELL_APP_DIR}/plugins/Ubuntu/Gestures
34+ DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/Ubuntu/Gestures
3535 )
plugins/Ubuntu/Gestures/DirectionalDragArea.cpp+3−3
@@ -404,7 +404,7 @@ void DirectionalDragArea::setStatus(DirectionalDragArea::Status newStatus)
404404 }
405405}
406406
407−void DirectionalDragArea::setPreviousPos(QPointF point)
407+void DirectionalDragArea::setPreviousPos(const QPointF &point)
408408{
409409 Q_ASSERT(m_status != Rejected);
410410
@@ -426,7 +426,7 @@ void DirectionalDragArea::setPreviousPos(QPointF point)
426426 }
427427}
428428
429−void DirectionalDragArea::setPreviousScenePos(QPointF point)
429+void DirectionalDragArea::setPreviousScenePos(const QPointF &point)
430430{
431431 Q_ASSERT(m_status != Rejected);
432432
@@ -448,7 +448,7 @@ void DirectionalDragArea::setPreviousScenePos(QPointF point)
448448 }
449449}
450450
451−void DirectionalDragArea::updateVelocityCalculator(QPointF point)
451+void DirectionalDragArea::updateVelocityCalculator(const QPointF &point)
452452{
453453 if (Direction::isHorizontal(m_direction)) {
454454 m_velocityCalculator->setTrackedPosition(point.x());
plugins/Ubuntu/Gestures/DirectionalDragArea.h+3−3
@@ -219,9 +219,9 @@ private:
219219 bool movedFarEnough(const QPointF &point) const;
220220 const QTouchEvent::TouchPoint *fetchTargetTouchPoint(QTouchEvent *event);
221221 void setStatus(Status newStatus);
222− void setPreviousPos(QPointF point);
223− void setPreviousScenePos(QPointF point);
224− void updateVelocityCalculator(QPointF point);
222+ void setPreviousPos(const QPointF &point);
223+ void setPreviousScenePos(const QPointF &point);
224+ void updateVelocityCalculator(const QPointF &point);
225225
226226 Status m_status;
227227
plugins/Unity/CMakeLists.txt+10−2
@@ -19,6 +19,14 @@ set(QMLPLUGIN_SRC
1919 categoryfilter.cpp
2020 plugin.cpp
2121 bottombarvisibilitycommunicatorshell.cpp
22+ applicationpreview.cpp
23+ genericpreview.cpp
24+ moviepreview.cpp
25+ musicpreview.cpp
26+ preview.cpp
27+ previewaction.cpp
28+ previewinfohint.cpp
29+ variantutils.cpp
2230 )
2331
2432add_library(Unity-qml MODULE
@@ -40,11 +48,11 @@ file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/qmldir"
4048 )
4149
4250install(TARGETS Unity-qml
43− DESTINATION ${SHELL_APP_DIR}/plugins/Unity
51+ DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/Unity
4452 )
4553
4654install(FILES qmldir
47− DESTINATION ${SHELL_APP_DIR}/plugins/Unity
55+ DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/Unity
4856 )
4957
5058
plugins/Unity/applicationpreview.cppnew file+96
@@ -0,0 +1,96 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Pawel Stolowski <pawel.stolowski@canonical.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify
8+ * it under the terms of the GNU General Public License as published by
9+ * the Free Software Foundation; version 3.
10+ *
11+ * This program is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ * GNU General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU General Public License
17+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+// local
21+#include "applicationpreview.h"
22+
23+#include <QDebug>
24+
25+ApplicationPreview::ApplicationPreview(QObject *parent):
26+ Preview(parent),
27+ m_unityAppPreview(nullptr)
28+{
29+}
30+
31+QString ApplicationPreview::lastUpdate() const
32+{
33+ if (m_unityAppPreview) {
34+ return QString::fromStdString(m_unityAppPreview->last_update());
35+ } else {
36+ qWarning() << "Preview not set";
37+ }
38+ return QString();
39+}
40+
41+QString ApplicationPreview::copyright() const
42+{
43+ if (m_unityAppPreview) {
44+ return QString::fromStdString(m_unityAppPreview->copyright());
45+ } else {
46+ qWarning() << "Preview not set";
47+ }
48+ return QString();
49+}
50+
51+QString ApplicationPreview::license() const
52+{
53+ if (m_unityAppPreview) {
54+ return QString::fromStdString(m_unityAppPreview->license());
55+ } else {
56+ qWarning() << "Preview not set";
57+ }
58+ return QString();
59+}
60+
61+QString ApplicationPreview::appIcon() const
62+{
63+ if (m_unityAppPreview) {
64+ return QString::fromUtf8(g_icon_to_string(m_unityAppPreview->app_icon()));
65+ } else {
66+ qWarning() << "Preview not set";
67+ }
68+ return QString();
69+}
70+
71+float ApplicationPreview::rating() const
72+{
73+ if (m_unityAppPreview) {
74+ return m_unityAppPreview->rating();
75+ } else {
76+ qWarning() << "Preview not set";
77+ }
78+ return 0.0f;
79+}
80+
81+unsigned int ApplicationPreview::numRatings() const
82+{
83+ if (m_unityAppPreview) {
84+ return m_unityAppPreview->num_ratings();
85+ } else {
86+ qWarning() << "Preview not set";
87+ }
88+ return 0;
89+}
90+
91+void ApplicationPreview::setUnityPreview(unity::dash::Preview::Ptr unityPreview)
92+{
93+ m_unityAppPreview = std::dynamic_pointer_cast<unity::dash::ApplicationPreview>(unityPreview);
94+
95+ Q_EMIT previewChanged();
96+}
plugins/Unity/applicationpreview.hnew file+66
@@ -0,0 +1,66 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Pawel Stolowski <pawel.stolowski@canonical.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify
8+ * it under the terms of the GNU General Public License as published by
9+ * the Free Software Foundation; version 3.
10+ *
11+ * This program is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ * GNU General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU General Public License
17+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+#ifndef APPLICATIONPREVIEW_H
21+#define APPLICATIONPREVIEW_H
22+
23+// local
24+#include "preview.h"
25+
26+// Qt
27+#include <QObject>
28+#include <QMetaType>
29+
30+// libunity-core
31+#include <UnityCore/ApplicationPreview.h>
32+
33+class Q_DECL_EXPORT ApplicationPreview: public Preview
34+{
35+ Q_OBJECT
36+
37+ Q_PROPERTY(QString lastUpdate READ lastUpdate NOTIFY previewChanged)
38+ Q_PROPERTY(QString copyright READ copyright NOTIFY previewChanged)
39+ Q_PROPERTY(QString license READ license NOTIFY previewChanged)
40+ Q_PROPERTY(QString appIcon READ appIcon NOTIFY previewChanged)
41+ Q_PROPERTY(float rating READ rating NOTIFY previewChanged)
42+ Q_PROPERTY(unsigned int numRatings READ numRatings NOTIFY previewChanged)
43+
44+public:
45+ explicit ApplicationPreview(QObject *parent = 0);
46+
47+ QString lastUpdate() const;
48+ QString copyright() const;
49+ QString license() const;
50+ QString appIcon() const;
51+ float rating() const;
52+ unsigned int numRatings() const;
53+
54+Q_SIGNALS:
55+ void previewChanged();
56+
57+protected:
58+ void setUnityPreview(unity::dash::Preview::Ptr unityPreview) override;
59+
60+private:
61+ unity::dash::ApplicationPreview::Ptr m_unityAppPreview;
62+};
63+
64+Q_DECLARE_METATYPE(ApplicationPreview *)
65+
66+#endif
tests/qmltests/plugins/Dee/DeeVariantText.qml → plugins/Unity/genericpreview.cpprenamed+8−4
@@ -1,6 +1,9 @@
11/*
22 * Copyright (C) 2013 Canonical, Ltd.
33 *
4+ * Authors:
5+ * Pawel Stolowski <pawel.stolowski@canonical.com>
6+ *
47 * This program is free software; you can redistribute it and/or modify
58 * it under the terms of the GNU General Public License as published by
69 * the Free Software Foundation; version 3.
@@ -14,9 +17,10 @@
1417 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1518 */
1619
17−import QtQuick 2.0
20+// local
21+#include "genericpreview.h"
1822
19−Item {
20− property variant value
21− property string text
23+GenericPreview::GenericPreview(QObject *parent):
24+ Preview(parent)
25+{
2226}
Notifications/timings.js → plugins/Unity/genericpreview.hrenamed+23−6
@@ -1,6 +1,9 @@
11/*
22 * Copyright (C) 2013 Canonical, Ltd.
33 *
4+ * Authors:
5+ * Pawel Stolowski <pawel.stolowski@canonical.com>
6+ *
47 * This program is free software; you can redistribute it and/or modify
58 * it under the terms of the GNU General Public License as published by
69 * the Free Software Foundation; version 3.
@@ -14,10 +17,24 @@
1417 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1518 */
1619
17−var rhythm = 700;
18−var fastBeat = 0.5 * rhythm;
19−var snapBeat = 0.5 * fastBeat;
20−var slowBeat = rhythm;
21−var sleepyBeat = slowBeat * 2;
20+#ifndef GENERICPREVIEW_H
21+#define GENERICPREVIEW_H
22+
23+// local
24+#include "preview.h"
25+
26+// Qt
27+#include <QObject>
28+#include <QMetaType>
29+
30+class GenericPreview : public Preview
31+{
32+ Q_OBJECT
33+
34+public:
35+ explicit GenericPreview(QObject *parent = 0);
36+};
37+
38+Q_DECLARE_METATYPE(GenericPreview *)
2239
23−var easing = Easing.OutQuint;
40+#endif
plugins/Unity/moviepreview.cppnew file+67
@@ -0,0 +1,67 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Pawel Stolowski <pawel.stolowski@canonical.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify
8+ * it under the terms of the GNU General Public License as published by
9+ * the Free Software Foundation; version 3.
10+ *
11+ * This program is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ * GNU General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU General Public License
17+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+// local
21+#include "moviepreview.h"
22+
23+// Qt
24+#include <QDebug>
25+
26+MoviePreview::MoviePreview(QObject *parent):
27+ Preview(parent),
28+ m_unityMoviePreview(nullptr)
29+{
30+}
31+
32+QString MoviePreview::year() const
33+{
34+ if (m_unityMoviePreview) {
35+ return QString::fromStdString(m_unityMoviePreview->year());
36+ } else {
37+ qWarning() << "Preview not set";
38+ }
39+ return QString();
40+}
41+
42+float MoviePreview::rating() const
43+{
44+ if (m_unityMoviePreview) {
45+ return m_unityMoviePreview->rating();
46+ } else {
47+ qWarning() << "Preview not set";
48+ }
49+ return 0.0f;
50+}
51+
52+unsigned int MoviePreview::numRatings() const
53+{
54+ if (m_unityMoviePreview) {
55+ return m_unityMoviePreview->num_ratings();
56+ } else {
57+ qWarning() << "Preview not set";
58+ }
59+ return 0;
60+}
61+
62+void MoviePreview::setUnityPreview(unity::dash::Preview::Ptr unityPreview)
63+{
64+ m_unityMoviePreview = std::dynamic_pointer_cast<unity::dash::MoviePreview>(unityPreview);
65+
66+ Q_EMIT previewChanged();
67+}
plugins/Unity/moviepreview.hnew file+60
@@ -0,0 +1,60 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Pawel Stolowski <pawel.stolowski@canonical.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify
8+ * it under the terms of the GNU General Public License as published by
9+ * the Free Software Foundation; version 3.
10+ *
11+ * This program is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ * GNU General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU General Public License
17+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+#ifndef MOVIEPREVIEW_H
21+#define MOVIEPREVIEW_H
22+
23+// local
24+#include "preview.h"
25+
26+// Qt
27+#include <QObject>
28+#include <QMetaType>
29+
30+// libunity-core
31+#include <UnityCore/MoviePreview.h>
32+
33+class Q_DECL_EXPORT MoviePreview: public Preview
34+{
35+ Q_OBJECT
36+
37+ Q_PROPERTY(QString year READ year NOTIFY previewChanged)
38+ Q_PROPERTY(float rating READ rating NOTIFY previewChanged)
39+ Q_PROPERTY(unsigned int numRatings READ numRatings NOTIFY previewChanged)
40+
41+public:
42+ explicit MoviePreview(QObject *parent = 0);
43+
44+ QString year() const;
45+ float rating() const;
46+ unsigned int numRatings() const;
47+
48+Q_SIGNALS:
49+ void previewChanged();
50+
51+protected:
52+ void setUnityPreview(unity::dash::Preview::Ptr unityPreview) override;
53+
54+private:
55+ unity::dash::MoviePreview::Ptr m_unityMoviePreview;
56+};
57+
58+Q_DECLARE_METATYPE(MoviePreview *)
59+
60+#endif
plugins/Unity/musicpreview.cppnew file+54
@@ -0,0 +1,54 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Pawel Stolowski <pawel.stolowski@canonical.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify
8+ * it under the terms of the GNU General Public License as published by
9+ * the Free Software Foundation; version 3.
10+ *
11+ * This program is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ * GNU General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU General Public License
17+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+#include "musicpreview.h"
21+#include <QDebug>
22+
23+// dee-qt
24+#include "deelistmodel.h"
25+
26+MusicPreview::MusicPreview(QObject *parent):
27+ Preview(parent),
28+ m_unityMusicPreview(nullptr)
29+{
30+ m_tracks = new DeeListModel(this);
31+}
32+
33+void MusicPreview::setUnityPreview(unity::dash::Preview::Ptr unityPreview)
34+{
35+ m_unityMusicPreview = std::dynamic_pointer_cast<unity::dash::MusicPreview>(unityPreview);
36+ m_tracks->setModel(m_unityMusicPreview->GetTracksModel()->model());
37+ m_unityMusicPreview->GetTracksModel()->model.changed.connect(sigc::mem_fun(this, &MusicPreview::onTracksModelChanged));
38+
39+ Q_EMIT previewChanged();
40+ Q_EMIT tracksChanged();
41+}
42+
43+DeeListModel* MusicPreview::tracks() const
44+{
45+ if (m_unityMusicPreview == nullptr) {
46+ qWarning() << "Preview not set";
47+ }
48+ return m_tracks;
49+}
50+
51+void MusicPreview::onTracksModelChanged(unity::glib::Object<DeeModel> /* model */)
52+{
53+ m_tracks->setModel(m_unityMusicPreview->GetTracksModel()->model());
54+}
plugins/Unity/musicpreview.hnew file+62
@@ -0,0 +1,62 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Pawel Stolowski <pawel.stolowski@canonical.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify
8+ * it under the terms of the GNU General Public License as published by
9+ * the Free Software Foundation; version 3.
10+ *
11+ * This program is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ * GNU General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU General Public License
17+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+#ifndef MUSICPREVIEW_H
21+#define MUSICPREVIEW_H
22+
23+// local
24+#include "preview.h"
25+
26+// Qt
27+#include <QObject>
28+#include <QMetaType>
29+
30+// libunity-core
31+#include <UnityCore/MusicPreview.h>
32+
33+class DeeListModel;
34+
35+class Q_DECL_EXPORT MusicPreview: public Preview
36+{
37+ Q_OBJECT
38+
39+ Q_PROPERTY(DeeListModel* tracks READ tracks NOTIFY tracksChanged)
40+
41+public:
42+ explicit MusicPreview(QObject *parent = 0);
43+
44+ DeeListModel* tracks() const;
45+
46+Q_SIGNALS:
47+ void tracksChanged();
48+
49+protected:
50+ void setUnityPreview(unity::dash::Preview::Ptr unityPreview) override;
51+
52+private Q_SLOTS:
53+ void onTracksModelChanged(unity::glib::Object<DeeModel> model);
54+
55+private:
56+ unity::dash::MusicPreview::Ptr m_unityMusicPreview;
57+ DeeListModel *m_tracks;
58+};
59+
60+Q_DECLARE_METATYPE(MusicPreview *)
61+
62+#endif
plugins/Unity/plugin.cpp+6
@@ -24,6 +24,9 @@
2424#include "plugin.h"
2525
2626// local
27+#include "preview.h"
28+#include "previewaction.h"
29+#include "previewinfohint.h"
2730#include "scope.h"
2831#include "scopes.h"
2932#include "categories.h"
@@ -39,6 +42,9 @@ static const char* DBUS_SERVICE = "com.canonical.Shell.BottomBarVisibilityCommun
3942void UnityPlugin::registerTypes(const char *uri)
4043{
4144 Q_ASSERT(uri == QLatin1String("Unity"));
45+ qmlRegisterUncreatableType<Preview>(uri, 0, 1, "Preview", "Can't create Preview object in QML.");
46+ qmlRegisterUncreatableType<PreviewAction>(uri, 0, 1, "PreviewAction", "Can't create PreviewAction object in QML.");
47+ qmlRegisterUncreatableType<PreviewInfoHint>(uri, 0, 1, "PreviewInfoHint", "Can't create PreviewInfoHint object in QML.");
4248 qmlRegisterType<Scope>(uri, 0, 1, "Scope");
4349 qmlRegisterType<Scopes>(uri, 0, 1, "Scopes");
4450 qmlRegisterType<Categories>(uri, 0, 1, "Categories");
plugins/Unity/preview.cppnew file+173
@@ -0,0 +1,173 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Pawel Stolowski <pawel.stolowski@canonical.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify
8+ * it under the terms of the GNU General Public License as published by
9+ * the Free Software Foundation; version 3.
10+ *
11+ * This program is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ * GNU General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU General Public License
17+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+// local
21+#include "preview.h"
22+#include "previewaction.h"
23+#include "previewinfohint.h"
24+#include "genericpreview.h"
25+#include "applicationpreview.h"
26+#include "moviepreview.h"
27+#include "musicpreview.h"
28+#include "variantutils.h"
29+
30+// Qt
31+#include <QDebug>
32+#include <QtAlgorithms>
33+
34+#include <UnityCore/GenericPreview.h>
35+#include <UnityCore/ApplicationPreview.h>
36+#include <UnityCore/MoviePreview.h>
37+#include <UnityCore/MusicPreview.h>
38+
39+Preview::Preview(QObject *parent):
40+ QObject(parent),
41+ m_unityPreview(nullptr)
42+{
43+}
44+
45+QString Preview::rendererName() const
46+{
47+ if (m_unityPreview) {
48+ return QString::fromStdString(m_unityPreview->renderer_name());
49+ } else {
50+ qWarning() << "Preview not set";
51+ }
52+ return QString();
53+}
54+
55+QString Preview::title() const
56+{
57+ if (m_unityPreview) {
58+ return QString::fromStdString(m_unityPreview->title());
59+ } else {
60+ qWarning() << "Preview not set";
61+ }
62+ return QString();
63+}
64+
65+QString Preview::subtitle () const
66+{
67+ if (m_unityPreview) {
68+ return QString::fromStdString(m_unityPreview->subtitle());
69+ } else {
70+ qWarning() << "Preview not set";
71+ }
72+ return QString();
73+}
74+
75+QString Preview::description() const
76+{
77+ if (m_unityPreview) {
78+ return QString::fromStdString(m_unityPreview->description());
79+ } else {
80+ qWarning() << "Preview not set";
81+ }
82+ return QString();
83+}
84+
85+QVariant Preview::actions()
86+{
87+ return QVariant::fromValue(m_actions);
88+}
89+
90+QVariant Preview::infoHints()
91+{
92+ return QVariant::fromValue(m_infoHints);
93+}
94+
95+QString Preview::image() const
96+{
97+ if (m_unityPreview) {
98+ return QString::fromUtf8(g_icon_to_string(m_unityPreview->image()));
99+ } else {
100+ qWarning() << "Preview not set";
101+ }
102+ return QString::null;
103+}
104+
105+QString Preview::imageSourceUri() const
106+{
107+ if (m_unityPreview) {
108+ return QString::fromStdString(m_unityPreview->image_source_uri());
109+ } else {
110+ qWarning() << "Preview not set";
111+ }
112+ return QString::null;
113+}
114+
115+Preview* Preview::newFromUnityPreview(unity::dash::Preview::Ptr unityPreview)
116+{
117+ Preview* preview = nullptr;
118+
119+ if (dynamic_cast<unity::dash::GenericPreview *>(unityPreview.get()) != nullptr) {
120+ preview = new GenericPreview();
121+ } else if (dynamic_cast<unity::dash::MusicPreview *>(unityPreview.get()) != nullptr) {
122+ preview = new MusicPreview();
123+ } else if (dynamic_cast<unity::dash::MoviePreview *>(unityPreview.get()) != nullptr) {
124+ preview = new MoviePreview();
125+ } else if (dynamic_cast<unity::dash::ApplicationPreview *>(unityPreview.get()) != nullptr) {
126+ preview = new ApplicationPreview();
127+ } else {
128+ qWarning() << "Unknown preview type: " << typeid(*unityPreview).name();
129+ preview = new GenericPreview();
130+ }
131+
132+ preview->setUnityPreviewBase(unityPreview);
133+ preview->setUnityPreview(unityPreview);
134+
135+ return preview;
136+}
137+
138+void Preview::setUnityPreviewBase(unity::dash::Preview::Ptr unityPreview)
139+{
140+ m_unityPreview = unityPreview;
141+
142+ qDeleteAll(m_infoHints);
143+ m_infoHints.clear();
144+ qDeleteAll(m_actions);
145+ m_actions.clear();
146+
147+ for (auto unityInfoHint: m_unityPreview->GetInfoHints()) {
148+ auto hint = new PreviewInfoHint(this);
149+ hint->setUnityInfoHint(unityInfoHint);
150+ m_infoHints.append(hint);
151+ }
152+
153+ for (auto unityAction: m_unityPreview->GetActions()) {
154+ auto action = new PreviewAction(this);
155+ action->setUnityAction(unityAction);
156+ m_actions.append(action);
157+ }
158+}
159+
160+void Preview::setUnityPreview(unity::dash::Preview::Ptr /* unityPreview */)
161+{
162+ // default implementation does nothing
163+}
164+
165+void Preview::execute(const QString& actionId, const QHash<QString, QVariant>& hints)
166+{
167+ if (m_unityPreview) {
168+ auto unityHints = convertToHintsMap(hints);
169+ m_unityPreview->PerformAction(actionId.toStdString(), unityHints);
170+ } else {
171+ qWarning() << "Preview not set";
172+ }
173+}
plugins/Unity/preview.hnew file+80
@@ -0,0 +1,80 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Pawel Stolowski <pawel.stolowski@canonical.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify
8+ * it under the terms of the GNU General Public License as published by
9+ * the Free Software Foundation; version 3.
10+ *
11+ * This program is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ * GNU General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU General Public License
17+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+#ifndef PREVIEW_H
21+#define PREVIEW_H
22+
23+// Qt
24+#include <QObject>
25+#include <QString>
26+#include <QMetaType>
27+#include <QList>
28+
29+// libunity-core
30+#include <UnityCore/Preview.h>
31+
32+// local
33+#include "previewaction.h"
34+
35+class Q_DECL_EXPORT Preview : public QObject
36+{
37+ Q_OBJECT
38+
39+ Q_PROPERTY(QString rendererName READ rendererName NOTIFY previewChanged)
40+ Q_PROPERTY(QString title READ title NOTIFY previewChanged)
41+ Q_PROPERTY(QString subtitle READ subtitle NOTIFY previewChanged)
42+ Q_PROPERTY(QString description READ description NOTIFY previewChanged)
43+ Q_PROPERTY(QVariant actions READ actions NOTIFY previewChanged)
44+ Q_PROPERTY(QVariant infoHints READ infoHints NOTIFY previewChanged)
45+ Q_PROPERTY(QString image READ image NOTIFY previewChanged)
46+ Q_PROPERTY(QString imageSourceUri READ imageSourceUri NOTIFY previewChanged)
47+
48+public:
49+ explicit Preview(QObject *parent = 0);
50+ static Preview* newFromUnityPreview(unity::dash::Preview::Ptr unityPreview);
51+
52+ QString rendererName() const;
53+ QString title() const;
54+ QString subtitle() const;
55+ QString description() const;
56+ QVariant actions();
57+ QVariant infoHints();
58+ QString image() const;
59+ QString imageSourceUri() const;
60+
61+ Q_INVOKABLE void execute(const QString& actionId, const QHash<QString, QVariant>& hints);
62+
63+Q_SIGNALS:
64+ void previewChanged();
65+
66+protected:
67+ virtual void setUnityPreview(unity::dash::Preview::Ptr unityPreview);
68+
69+ unity::dash::Preview::Ptr m_unityPreview;
70+
71+private:
72+ void setUnityPreviewBase(unity::dash::Preview::Ptr unityPreview);
73+
74+ QList<QObject *> m_actions;
75+ QList<QObject *> m_infoHints;
76+};
77+
78+Q_DECLARE_METATYPE(Preview *)
79+
80+#endif
plugins/Unity/previewaction.cppnew file+75
@@ -0,0 +1,75 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Pawel Stolowski <pawel.stolowski@canonical.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify
8+ * it under the terms of the GNU General Public License as published by
9+ * the Free Software Foundation; version 3.
10+ *
11+ * This program is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ * GNU General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU General Public License
17+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+#include "previewaction.h"
21+
22+PreviewAction::PreviewAction(QObject *parent)
23+ : QObject(parent),
24+ m_unityAction(nullptr)
25+{
26+}
27+
28+void PreviewAction::setUnityAction(unity::dash::Preview::ActionPtr unityAction)
29+{
30+ m_unityAction = unityAction;
31+
32+ Q_EMIT previewActionChanged();
33+}
34+
35+QString PreviewAction::id() const
36+{
37+ if (m_unityAction)
38+ return QString::fromStdString(m_unityAction->id);
39+ return QString();
40+}
41+
42+QString PreviewAction::displayName() const
43+{
44+ if (m_unityAction)
45+ return QString::fromStdString(m_unityAction->display_name);
46+ return QString();
47+}
48+
49+QString PreviewAction::iconHint() const
50+{
51+ if (m_unityAction)
52+ return QString::fromStdString(m_unityAction->icon_hint);
53+ return QString();
54+}
55+
56+QString PreviewAction::extraText() const
57+{
58+ if (m_unityAction)
59+ return QString::fromStdString(m_unityAction->extra_text);
60+ return QString();
61+}
62+
63+QString PreviewAction::activationUri() const
64+{
65+ if (m_unityAction)
66+ return QString::fromStdString(m_unityAction->activation_uri);
67+ return QString();
68+}
69+
70+LayoutHint PreviewAction::layoutHint() const
71+{
72+ if (m_unityAction)
73+ return static_cast<LayoutHint>(m_unityAction->layout_hint);
74+ return LayoutHint::None;
75+}
plugins/Unity/previewaction.hnew file+71
@@ -0,0 +1,71 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Pawel Stolowski <pawel.stolowski@canonical.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify
8+ * it under the terms of the GNU General Public License as published by
9+ * the Free Software Foundation; version 3.
10+ *
11+ * This program is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ * GNU General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU General Public License
17+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+#ifndef PREVIEWACTION_H
21+#define PREVIEWACTION_H
22+
23+// Qt
24+#include <QObject>
25+#include <QList>
26+
27+// libuinity-core
28+#include <UnityCore/Preview.h>
29+
30+enum LayoutHint // keep in sync with unty::dash::LayoutHint
31+{
32+ None,
33+ Left,
34+ Right,
35+ Top,
36+ Bottom
37+};
38+
39+class PreviewAction : public QObject
40+{
41+ Q_OBJECT
42+
43+ Q_PROPERTY(QString id READ id NOTIFY previewActionChanged)
44+ Q_PROPERTY(QString displayName READ displayName NOTIFY previewActionChanged)
45+ Q_PROPERTY(QString iconHint READ iconHint NOTIFY previewActionChanged)
46+ Q_PROPERTY(QString extraText READ extraText NOTIFY previewActionChanged)
47+ Q_PROPERTY(QString activationUri READ activationUri NOTIFY previewActionChanged)
48+ Q_PROPERTY(LayoutHint layoutHint READ layoutHint NOTIFY previewActionChanged)
49+
50+public:
51+ explicit PreviewAction(QObject *parent = 0);
52+ void setUnityAction(unity::dash::Preview::ActionPtr unityAction);
53+
54+ QString id() const;
55+ QString displayName() const;
56+ QString iconHint() const;
57+ QString extraText() const;
58+ QString activationUri() const;
59+ LayoutHint layoutHint() const;
60+
61+Q_SIGNALS:
62+ void previewActionChanged();
63+
64+private:
65+ unity::dash::Preview::ActionPtr m_unityAction;
66+};
67+
68+Q_DECLARE_METATYPE(PreviewAction *)
69+Q_DECLARE_METATYPE(LayoutHint)
70+
71+#endif
plugins/Unity/previewinfohint.cppnew file+67
@@ -0,0 +1,67 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Pawel Stolowski <pawel.stolowski@canonical.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify
8+ * it under the terms of the GNU General Public License as published by
9+ * the Free Software Foundation; version 3.
10+ *
11+ * This program is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ * GNU General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU General Public License
17+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+// local
21+#include "previewinfohint.h"
22+#include "variantutils.h"
23+
24+PreviewInfoHint::PreviewInfoHint(QObject *parent):
25+ QObject(parent),
26+ m_unityInfoHint(nullptr)
27+{
28+}
29+
30+void PreviewInfoHint::setUnityInfoHint(unity::dash::Preview::InfoHintPtr unityInfoHint)
31+{
32+ m_unityInfoHint = unityInfoHint;
33+
34+ Q_EMIT previewInfoHintChanged();
35+}
36+
37+QString PreviewInfoHint::id() const
38+{
39+ if (m_unityInfoHint) {
40+ return QString::fromStdString(m_unityInfoHint->id);
41+ }
42+ return QString();
43+}
44+
45+QString PreviewInfoHint::displayName() const
46+{
47+ if (m_unityInfoHint) {
48+ return QString::fromStdString(m_unityInfoHint->display_name);
49+ }
50+ return QString();
51+}
52+
53+QString PreviewInfoHint::iconHint() const
54+{
55+ if (m_unityInfoHint) {
56+ return QString::fromStdString(m_unityInfoHint->icon_hint);
57+ }
58+ return QString();
59+}
60+
61+QVariant PreviewInfoHint::value() const
62+{
63+ if (m_unityInfoHint) {
64+ return QVariantFromGVariant(m_unityInfoHint->value);
65+ }
66+ return QVariant();
67+}
plugins/Unity/previewinfohint.hnew file+58
@@ -0,0 +1,58 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Pawel Stolowski <pawel.stolowski@canonical.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify
8+ * it under the terms of the GNU General Public License as published by
9+ * the Free Software Foundation; version 3.
10+ *
11+ * This program is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ * GNU General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU General Public License
17+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+#ifndef PREVIEWINFOHINT_H
21+#define PREVIEWINFOHINT_H
22+
23+// Qt
24+#include <QObject>
25+#include <QString>
26+#include <QVariant>
27+
28+// libunity-core
29+#include <UnityCore/Preview.h>
30+
31+class PreviewInfoHint : public QObject
32+{
33+ Q_OBJECT
34+
35+ Q_PROPERTY(QString id READ id NOTIFY previewInfoHintChanged)
36+ Q_PROPERTY(QString displayName READ displayName NOTIFY previewInfoHintChanged)
37+ Q_PROPERTY(QString iconHint READ iconHint NOTIFY previewInfoHintChanged)
38+ Q_PROPERTY(QVariant value READ value NOTIFY previewInfoHintChanged)
39+
40+public:
41+ explicit PreviewInfoHint(QObject *parent = 0);
42+ void setUnityInfoHint(unity::dash::Preview::InfoHintPtr unityInfoHint);
43+
44+ QString id() const;
45+ QString displayName() const;
46+ QString iconHint() const;
47+ QVariant value() const;
48+
49+Q_SIGNALS:
50+ void previewInfoHintChanged();
51+
52+private:
53+ unity::dash::Preview::InfoHintPtr m_unityInfoHint;
54+};
55+
56+Q_DECLARE_METATYPE(PreviewInfoHint *)
57+
58+#endif
plugins/Unity/scope.cpp+79−11
@@ -19,12 +19,19 @@
1919
2020// Self
2121#include "scope.h"
22+
23+// local
2224#include "categories.h"
25+#include "preview.h"
26+#include "variantutils.h"
2327
2428// Qt
2529#include <QUrl>
2630#include <QDebug>
2731#include <QtGui/QDesktopServices>
32+#include <QQmlEngine>
33+
34+#include <UnityCore/Variant.h>
2835
2936#include <libintl.h>
3037
@@ -118,21 +125,80 @@ void Scope::setNoResultsHint(const QString& hint) {
118125 }
119126}
120127
121−void Scope::activate(const QString& /*uri*/)
128+
129+unity::dash::LocalResult Scope::createLocalResult(const QVariant &uri, const QVariant &icon_hint,
130+ const QVariant &category, const QVariant &result_type,
131+ const QVariant &mimetype, const QVariant &title,
132+ const QVariant &comment, const QVariant &dnd_uri,
133+ const QVariant &metadata)
134+{
135+ unity::dash::LocalResult res;
136+ res.uri = uri.toString().toStdString();
137+ res.icon_hint = icon_hint.toString().toStdString();
138+ res.category_index = category.toUInt();
139+ res.result_type = result_type.toUInt();
140+ res.mimetype = mimetype.toString().toStdString();
141+ res.name = title.toString().toStdString();
142+ res.comment = comment.toString().toStdString();
143+ res.dnd_uri = dnd_uri.toString().toStdString();
144+ res.hints = convertToHintsMap(metadata);
145+
146+ return res;
147+}
148+
149+// FIXME: Change to use row index.
150+void Scope::activate(const QVariant &uri, const QVariant &icon_hint, const QVariant &category,
151+ const QVariant &result_type, const QVariant &mimetype, const QVariant &title,
152+ const QVariant &comment, const QVariant &dnd_uri, const QVariant &metadata)
153+{
154+ auto res = createLocalResult(uri, icon_hint, category, result_type, mimetype, title, comment, dnd_uri, metadata);
155+ m_unityScope->Activate(res);
156+}
157+
158+// FIXME: Change to use row index.
159+void Scope::preview(const QVariant &uri, const QVariant &icon_hint, const QVariant &category,
160+ const QVariant &result_type, const QVariant &mimetype, const QVariant &title,
161+ const QVariant &comment, const QVariant &dnd_uri, const QVariant &metadata)
122162{
123− // TODO:
124− // we need to create unity::dash::LocalResult (see UnityCore/Result.h) and pass it to Activate;
125− // this requires entire row from the model, so we need row index rather than uri.
126− // m_unityScope->Activate(QByteArray::fromPercentEncoding(uri.toUtf8()).constData());
163+ auto res = createLocalResult(uri, icon_hint, category, result_type, mimetype, title, comment, dnd_uri, metadata);
164+ m_unityScope->Preview(res);
127165}
128166
129−void Scope::onActivated(unity::dash::LocalResult const& result, unity::dash::ScopeHandledType type, unity::glib::HintsMap const&)
167+void Scope::onActivated(unity::dash::LocalResult const& result, unity::dash::ScopeHandledType type, unity::glib::HintsMap const& hints)
130168{
131− if (type == unity::dash::NOT_HANDLED) {
132− fallbackActivate(QString::fromStdString(result.uri));
169+ // note: we will not get called on SHOW_PREVIEW, instead UnityCore will signal preview_ready.
170+ switch (type)
171+ {
172+ case unity::dash::NOT_HANDLED:
173+ fallbackActivate(QString::fromStdString(result.uri));
174+ break;
175+ case unity::dash::SHOW_DASH:
176+ Q_EMIT showDash();
177+ break;
178+ case unity::dash::HIDE_DASH:
179+ Q_EMIT hideDash();
180+ break;
181+ case unity::dash::GOTO_DASH_URI:
182+ if (hints.find("goto-uri") != hints.end()) {
183+ Q_EMIT gotoUri(QString::fromStdString(g_variant_get_string(hints.at("goto-uri"), nullptr)));
184+ } else {
185+ qWarning() << "Missing goto-uri hint for GOTO_DASH_URI activation reply";
186+ }
187+ break;
188+ default:
189+ qWarning() << "Unhandled activation response:" << type;
133190 }
134191}
135192
193+void Scope::onPreviewReady(unity::dash::LocalResult const& /* result */, unity::dash::Preview::Ptr const& preview)
194+{
195+ auto prv = Preview::newFromUnityPreview(preview);
196+ // is this the best solution? QML may need to keep more than one preview instance around, so we can't own it.
197+ // passing it by value is not possible.
198+ QQmlEngine::setObjectOwnership(prv, QQmlEngine::JavaScriptOwnership);
199+ Q_EMIT previewReady(prv);
200+}
201+
136202void Scope::fallbackActivate(const QString& uri)
137203{
138204 /* FIXME: stripping all content before the first column because for some
@@ -161,10 +227,10 @@ void Scope::fallbackActivate(const QString& uri)
161227 return;
162228 }
163229
164− qWarning() << "FIXME: Possibly no handler for scheme: " << url.scheme();
165− qWarning() << "Trying to open" << tweakedUri;
230+ qDebug() << "Trying to open" << uri;
231+
166232 /* Try our luck */
167− QDesktopServices::openUrl(url);
233+ QDesktopServices::openUrl(uri); //url?
168234}
169235
170236void Scope::setUnityScope(const unity::dash::Scope::Ptr& scope)
@@ -204,6 +270,8 @@ void Scope::setUnityScope(const unity::dash::Scope::Ptr& scope)
204270 /* FIXME: signal should be forwarded instead of calling the handler directly */
205271 m_unityScope->activated.connect(sigc::mem_fun(this, &Scope::onActivated));
206272
273+ m_unityScope->preview_ready.connect(sigc::mem_fun(this, &Scope::onPreviewReady));
274+
207275 /* Synchronize local states with m_unityScope right now and whenever
208276 m_unityScope becomes connected */
209277 /* FIXME: should emit change notification signals for all properties */
plugins/Unity/scope.h+20−3
@@ -33,6 +33,7 @@
3333#include "deelistmodel.h"
3434
3535class Categories;
36+class Preview;
3637
3738class Scope : public QObject
3839{
@@ -73,7 +74,12 @@ public:
7374 void setSearchQuery(const QString& search_query);
7475 void setNoResultsHint(const QString& hint);
7576
76− Q_INVOKABLE void activate(const QString& uri);
77+ Q_INVOKABLE void activate(const QVariant &uri, const QVariant &icon_hint, const QVariant &category,
78+ const QVariant &result_type, const QVariant &mimetype, const QVariant &title,
79+ const QVariant &comment, const QVariant &dnd_uri, const QVariant &metadata);
80+ Q_INVOKABLE void preview(const QVariant &uri, const QVariant &icon_hint, const QVariant &category,
81+ const QVariant &result_type, const QVariant &mimetype, const QVariant &title,
82+ const QVariant &comment, const QVariant &dnd_uri, const QVariant &metadata);
7783 void setUnityScope(const unity::dash::Scope::Ptr& scope);
7884 unity::dash::Scope::Ptr unityScope() const;
7985
@@ -94,6 +100,12 @@ Q_SIGNALS:
94100 void searchQueryChanged();
95101 void noResultsHintChanged();
96102
103+ // signals triggered by activate(..) or preview(..) requests.
104+ void previewReady(Preview *preview);
105+ void showDash();
106+ void hideDash();
107+ void gotoUri(const QString &uri);
108+
97109private Q_SLOTS:
98110 void synchronizeStates();
99111 void onSearchFinished(const std::string &, unity::glib::HintsMap const &);
@@ -105,8 +117,13 @@ private:
105117 void onCategoriesSwarmNameChanged(const std::string&);
106118 void onCategoriesModelChanged(unity::glib::Object<DeeModel>);
107119 void onCategoriesChanged(const unity::dash::Categories::Ptr&);
108−
109− void onActivated(unity::dash::LocalResult const& result, unity::dash::ScopeHandledType type, unity::glib::HintsMap const&);
120+ unity::dash::LocalResult createLocalResult(const QVariant &uri, const QVariant &icon_hint,
121+ const QVariant &category, const QVariant &result_type,
122+ const QVariant &mimetype, const QVariant &title,
123+ const QVariant &comment, const QVariant &dnd_uri,
124+ const QVariant &metadata);
125+ void onActivated(unity::dash::LocalResult const& result, unity::dash::ScopeHandledType type, unity::glib::HintsMap const& hints);
126+ void onPreviewReady(unity::dash::LocalResult const& result, unity::dash::Preview::Ptr const& preview);
110127 void fallbackActivate(const QString& uri);
111128
112129 unity::dash::Scope::Ptr m_unityScope;
plugins/Unity/variantutils.cppnew file+158
@@ -0,0 +1,158 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Pawel Stolowski <pawel.stolowski@canonical.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify
8+ * it under the terms of the GNU General Public License as published by
9+ * the Free Software Foundation; version 3.
10+ *
11+ * This program is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ * GNU General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU General Public License
17+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+#include "variantutils.h"
21+
22+/* Returns floating ref */
23+GVariant* GVariantFromQVariant(const QVariant &var)
24+{
25+ GVariant *gv = nullptr;
26+
27+ switch (var.type()) {
28+ case QVariant::String:
29+ gv = g_variant_new_string(var.toString().toUtf8());
30+ break;
31+ case QVariant::UInt:
32+ gv = g_variant_new_uint32(var.toUInt());
33+ break;
34+ case QVariant::Int:
35+ gv = g_variant_new_int32(var.toInt());
36+ break;
37+ case QVariant::LongLong:
38+ gv = g_variant_new_int64(var.toLongLong());
39+ break;
40+ case QVariant::ULongLong:
41+ gv = g_variant_new_uint64(var.toULongLong());
42+ break;
43+ case QVariant::Double:
44+ gv = g_variant_new_double(var.toDouble());
45+ break;
46+ case QVariant::Bool:
47+ gv = g_variant_new_boolean(var.toBool());
48+ break;
49+ case QVariant::Hash: {
50+ const auto hash = var.toHash();
51+ GVariant **children = new GVariant*[hash.size()];
52+ int cnt = 0;
53+ QHash<QString, QVariant>::const_iterator it = hash.constBegin();
54+ while (it != hash.constEnd()) {
55+ GVariant *key = g_variant_new_string(it.key().toUtf8());
56+ children[cnt++] = g_variant_new_dict_entry(key, g_variant_new_variant(GVariantFromQVariant(it.value())));
57+ ++it;
58+ }
59+ gv = g_variant_new_array(G_VARIANT_TYPE("{sv}"), children, hash.size());
60+ delete [] children;
61+ break;
62+ }
63+ default:
64+ break;
65+ }
66+ return gv;
67+}
68+
69+// implementation of this conversion taken from libdee-qt private utility function.
70+QVariant QVariantFromGVariant(GVariant *value)
71+{
72+ /* We need to special-case a{sv} here as G_VARIANT_CLASS_ARRAY handles simple arrays;
73+ we need to create QVariantHash, not a list */
74+ if (g_variant_is_of_type(value, G_VARIANT_TYPE_VARDICT)) {
75+ const gsize nChildren = g_variant_n_children(value);
76+ QVariantHash hash;
77+ for (gsize i = 0; i < nChildren; ++i)
78+ {
79+ GVariant* dict_entry = g_variant_get_child_value(value, i);
80+
81+ gchar* dict_key;
82+ GVariant *dict_var;
83+ g_variant_get(dict_entry, "{&sv}", &dict_key, &dict_var);
84+ hash.insert(QString::fromUtf8(dict_key), QVariantFromGVariant(dict_var));
85+ g_variant_unref(dict_var);
86+ g_variant_unref(dict_entry);
87+ }
88+ return hash;
89+ }
90+
91+ switch (g_variant_classify(value)) {
92+ case G_VARIANT_CLASS_BOOLEAN:
93+ return QVariant((bool) g_variant_get_boolean(value));
94+ case G_VARIANT_CLASS_BYTE:
95+ return QVariant((uchar) g_variant_get_byte(value));
96+ case G_VARIANT_CLASS_INT16:
97+ return QVariant((qint16) g_variant_get_int16(value));
98+ case G_VARIANT_CLASS_UINT16:
99+ return QVariant((quint16) g_variant_get_uint16(value));
100+ case G_VARIANT_CLASS_INT32:
101+ return QVariant((qint32) g_variant_get_int32(value));
102+ case G_VARIANT_CLASS_UINT32:
103+ return QVariant((quint32) g_variant_get_uint32(value));
104+ case G_VARIANT_CLASS_INT64:
105+ return QVariant((qint64) g_variant_get_int64(value));
106+ case G_VARIANT_CLASS_UINT64:
107+ return QVariant((quint64) g_variant_get_uint64(value));
108+ case G_VARIANT_CLASS_DOUBLE:
109+ return QVariant(g_variant_get_double(value));
110+ case G_VARIANT_CLASS_STRING:
111+ return QVariant(QString::fromUtf8(g_variant_get_string(value, NULL)));
112+ case G_VARIANT_CLASS_ARRAY:
113+ case G_VARIANT_CLASS_TUPLE:
114+ {
115+ const gsize nChildren = g_variant_n_children(value);
116+ QList<QVariant> array;
117+ for (gsize i = 0; i < nChildren; ++i)
118+ {
119+ GVariant* gvariant = g_variant_get_child_value(value, i);
120+ array << QVariantFromGVariant(gvariant);
121+ g_variant_unref(gvariant);
122+ }
123+ return array;
124+ }
125+ default:
126+ /* Fallback on an empty QVariant.
127+ FIXME: Missing conversion of following GVariant types:
128+ - G_VARIANT_CLASS_HANDLE
129+ - G_VARIANT_CLASS_OBJECT_PATH
130+ - G_VARIANT_CLASS_SIGNATURE
131+ - G_VARIANT_CLASS_VARIANT
132+ - G_VARIANT_CLASS_MAYBE
133+ - G_VARIANT_CLASS_DICT_ENTRY
134+ */
135+ return QVariant();
136+ }
137+}
138+
139+unity::glib::HintsMap convertToHintsMap(const QHash<QString, QVariant> &val)
140+{
141+ unity::glib::HintsMap hintsMap;
142+ QHash<QString, QVariant>::const_iterator it = val.constBegin();
143+ while (it != val.constEnd()) {
144+ hintsMap[it.key().toStdString()] = GVariantFromQVariant(it.value());
145+ ++it;
146+ }
147+ return hintsMap;
148+}
149+
150+unity::glib::HintsMap convertToHintsMap(const QVariant &var)
151+{
152+ if (var.type() == QVariant::Hash) {
153+ unity::glib::HintsMap hintsMap;
154+ const auto hash = var.toHash();
155+ return convertToHintsMap(hash);
156+ }
157+ return unity::glib::HintsMap();
158+}
plugins/Unity/variantutils.hnew file+34
@@ -0,0 +1,34 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Pawel Stolowski <pawel.stolowski@canonical.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify
8+ * it under the terms of the GNU General Public License as published by
9+ * the Free Software Foundation; version 3.
10+ *
11+ * This program is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ * GNU General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU General Public License
17+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+#ifndef VARIANTUTILS_H
21+#define VARIANTUTILS_H
22+
23+#include <glib.h>
24+#include <QVariant>
25+
26+// libunity-core
27+#include <UnityCore/Variant.h>
28+
29+GVariant* GVariantFromQVariant(const QVariant &value);
30+QVariant QVariantFromGVariant(GVariant *value);
31+unity::glib::HintsMap convertToHintsMap(const QHash<QString, QVariant> &val);
32+unity::glib::HintsMap convertToHintsMap(const QVariant &var);
33+
34+#endif
plugins/Utils/CMakeLists.txt+2−2
@@ -28,9 +28,9 @@ file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/qmldir"
2828 )
2929
3030install(TARGETS Utils-qml
31− DESTINATION ${SHELL_APP_DIR}/plugins/Utils
31+ DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/Utils
3232 )
3333
3434install(FILES qmldir
35− DESTINATION ${SHELL_APP_DIR}/plugins/Utils
35+ DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/Utils
3636 )
plugins/Utils/qlimitproxymodelqml.cpp+4−4
@@ -39,11 +39,11 @@ QHash<int, QByteArray> QLimitProxyModelQML::roleNames() const
3939void
4040QLimitProxyModelQML::setModel(QAbstractItemModel *itemModel)
4141{
42− if (sourceModel() != NULL) {
43− sourceModel()->disconnect(this);
44− }
45−
4642 if (itemModel != sourceModel()) {
43+ if (sourceModel() != NULL) {
44+ sourceModel()->disconnect(this);
45+ }
46+
4747 setSourceModel(itemModel);
4848
4949 if (sourceModel() != NULL) {
run+3−3
@@ -41,17 +41,17 @@ done
4141
4242if $FAKE; then
4343 export QML2_IMPORT_PATH=$PWD/builddir/tests/mocks:$PWD/builddir/plugins
44− export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD/builddir/tests/mocks/LightDM/single
44+ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD/builddir/tests/mocks/libusermetrics:$PWD/builddir/tests/mocks/LightDM/single
4545fi
4646
4747if $PINLOCK; then
4848 export QML2_IMPORT_PATH=$PWD/builddir/tests/mocks:$PWD/builddir/plugins
49− export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD/builddir/tests/mocks/LightDM/single-pin
49+ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD/builddir/tests/mocks/libusermetrics:$PWD/builddir/tests/mocks/LightDM/single-pin
5050fi
5151
5252if $KEYLOCK; then
5353 export QML2_IMPORT_PATH=$PWD/builddir/tests/mocks:$PWD/builddir/plugins
54− export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD/builddir/tests/mocks/LightDM/single-passphrase
54+ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD/builddir/tests/mocks/libusermetrics:$PWD/builddir/tests/mocks/LightDM/single-passphrase
5555fi
5656
5757# Force icon theme if running on the desktop, otherwise gnome theme (if running
run_on_device+2−3
@@ -86,16 +86,15 @@ build() {
8686
8787run() {
8888 SERVICEFILE="${CHROOT_PREFIX}/etc/device-services"
89− adb shell "egrep '$BINARY|qml-phone-shell' $SERVICEFILE"
89+ adb shell "egrep '$BINARY' $SERVICEFILE"
9090 CONTAINS_SHELL=$?
9191 if [ $CONTAINS_SHELL -eq 0 ]; then
9292 echo "Modifying $SERVICEFILE on device. Old contents will be saved in $SERVICEFILE.backup"
9393 adb shell cp $SERVICEFILE $SERVICEFILE.backup
94− adb shell sed -i "/$BINARY\\\\\|qml-phone-shell/d" $SERVICEFILE
94+ adb shell sed -i "/$BINARY/d" $SERVICEFILE
9595 if $FLIPPED; then exec_with_adb /usr/bin/service ubuntu-touch-session restart
9696 else exec_with_adb /usr/bin/service ubuntu-session restart; fi
9797 fi
98− adb shell pkill qml-phone-shell
9998 adb shell pkill $BINARY
10099 ARGS="--nomousetouch"
101100 if $GDB; then
tests/autopilot/setup.pynew file+21
@@ -0,0 +1,21 @@
1+#!/usr/bin/python
2+
3+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
4+# Copyright 2013 Canonical
5+#
6+# This program is free software: you can redistribute it and/or modify it
7+# under the terms of the GNU General Public License version 3, as published
8+# by the Free Software Foundation.
9+
10+
11+from distutils.core import setup
12+from setuptools import find_packages
13+
14+setup(
15+ name='unity',
16+ version='8.0',
17+ description='Unity 8 autopilot tests.',
18+ url='https://launchpad.net/unity',
19+ license='GPLv3',
20+ packages=find_packages(),
21+)
tests/autopilot/unity8/tests/__init__.py+6−4
@@ -8,6 +8,7 @@
88"""unity8 autopilot tests."""
99
1010import os.path
11+import sysconfig
1112
1213from autopilot.testcase import AutopilotTestCase
1314from autopilot.matchers import Eventually
@@ -23,6 +24,7 @@ class ShellTestCase(AutopilotTestCase):
2324
2425 """A common test case class that provides several useful methods for shell tests."""
2526
27+ libdir = "/usr/lib/{0}/unity8".format(sysconfig.get_config_var('MULTIARCH'))
2628 lightdm_mock = "full"
2729
2830 def setUp(self, geometry, grid_size):
@@ -39,8 +41,8 @@ class ShellTestCase(AutopilotTestCase):
3941 self.launch_test_local(geometry)
4042
4143 def launch_test_local(self, geometry):
42− os.environ['LD_LIBRARY_PATH'] = "../../../unity_build/build/lib:../../builddir/tests/mocks/LightDM/" + self.lightdm_mock
43− os.environ['QML2_IMPORT_PATH'] = "../../builddir/tests/mocks:../../builddir/plugins"
44+ os.environ['LD_LIBRARY_PATH'] = "../../builddir/tests/mocks/libusermetrics:../../builddir/tests/mocks/LightDM" + self.lightdm_mock
45+ os.environ['QML2_IMPORT_PATH'] = "../../builddir/tests/mocks"
4446 if geometry != "0x0":
4547 self.app = self.launch_test_application(
4648 "../../builddir/unity8", "-geometry", geometry, "-frameless", app_type='qt')
@@ -49,8 +51,8 @@ class ShellTestCase(AutopilotTestCase):
4951 "../../builddir/unity8", "-fullscreen", app_type='qt')
5052
5153 def launch_test_installed(self, geometry):
52− os.environ['LD_LIBRARY_PATH'] = "/usr/share/unity8/plugins/mocks/LightDM/" + self.lightdm_mock
53− os.environ['QML2_IMPORT_PATH'] = "/usr/share/unity8/plugins/mocks:/usr/share/unity8/plugins"
54+ os.environ['LD_LIBRARY_PATH'] = "{0}/qml/mocks/libusermetrics:{0}/qml/mocks/LightDM/{1}".format(self.libdir, self.lightdm_mock)
55+ os.environ['QML2_IMPORT_PATH'] = "{0}/qml/mocks".format(self.libdir)
5456 if model() == 'Desktop' and geometry != "0x0":
5557 self.app = self.launch_test_application(
5658 "unity8", "-geometry", geometry, "-frameless", app_type='qt')
tests/mocks/CMakeLists.txt+2
@@ -1,3 +1,5 @@
1+add_subdirectory(libusermetrics)
12add_subdirectory(LightDM)
23add_subdirectory(Ubuntu)
34add_subdirectory(Unity)
5+add_subdirectory(HudClient)
tests/qmltests/plugins/HudClient/CMakeLists.txt → tests/mocks/HudClient/CMakeLists.txtrenamed

The content is the same.

tests/qmltests/plugins/HudClient/fake_hud_plugin.cpp → tests/mocks/HudClient/fake_hud_plugin.cpprenamed

The content is the same.

tests/qmltests/plugins/HudClient/fake_hud_plugin.h → tests/mocks/HudClient/fake_hud_plugin.hrenamed

The content is the same.

tests/qmltests/plugins/HudClient/fake_libhud_client.cpp → tests/mocks/HudClient/fake_libhud_client.cpprenamed

The content is the same.

tests/qmltests/plugins/HudClient/libhud_client_stub.cpp → tests/mocks/HudClient/libhud_client_stub.cpprenamed

The content is the same.

tests/qmltests/plugins/HudClient/libhud_client_stub.h → tests/mocks/HudClient/libhud_client_stub.hrenamed

The content is the same.

tests/qmltests/plugins/HudClient/qmldir → tests/mocks/HudClient/qmldirrenamed

The content is the same.

tests/mocks/LightDM/CMakeLists.txt+5−2
@@ -13,6 +13,7 @@ add_subdirectory(single-passphrase)
1313include_directories(
1414 ${CMAKE_CURRENT_SOURCE_DIR}
1515 ${CMAKE_CURRENT_BINARY_DIR}
16+ ${CMAKE_SOURCE_DIR}/tests/mocks/libusermetrics
1617)
1718
1819set(QMLPLUGIN_SRC
@@ -34,6 +35,8 @@ add_dependencies(MockLightDM-qml MockLightDM-full)
3435target_link_libraries(MockLightDM-qml
3536 -L${CMAKE_CURRENT_BINARY_DIR}/full
3637 -llightdm-qt5-2
38+ -L${CMAKE_BINARY_DIR}/tests/mocks/libusermetrics
39+ -lusermetricsoutput
3740 )
3841
3942qt5_use_modules(MockLightDM-qml Gui Qml)
@@ -44,9 +47,9 @@ file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/qmldir"
4447 )
4548
4649install(TARGETS MockLightDM-qml
47− DESTINATION ${SHELL_APP_DIR}/plugins/mocks/LightDM
50+ DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/mocks/LightDM
4851 )
4952
5053install(FILES qmldir
51− DESTINATION ${SHELL_APP_DIR}/plugins/mocks/LightDM
54+ DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/mocks/LightDM
5255 )
tests/mocks/LightDM/InfographicModel.cppdeleted−416
@@ -1,416 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− *
16− * Author: Pete Woods <pete.woods@canonical.com>
17− */
18−
19−#include "InfographicModelPrivate.h"
20−#include "InfographicModel.h"
21−
22−#include <QtCore/QDir>
23−#include <QtCore/QString>
24−#include <QtGui/QIcon>
25−#include <QMultiMap>
26−
27−using namespace QLightDM;
28−
29−namespace QLightDM
30−{
31−
32−class InfographicColorThemePrivate: QObject
33−{
34−public:
35− explicit InfographicColorThemePrivate(InfographicColorTheme *parent = 0);
36−
37− InfographicColorThemePrivate(const QColor &start, const QColor &main,
38− const QColor &end, InfographicColorTheme *parent = 0);
39−
40− ~InfographicColorThemePrivate();
41−
42− InfographicColorTheme * const q_ptr;
43−
44− QColor m_start;
45−
46− QColor m_main;
47−
48− QColor m_end;
49−
50−protected:
51− int calculateLength();
52−
53−private:
54− Q_DECLARE_PUBLIC(InfographicColorTheme)
55−};
56−
57−class InfographicDataPrivate: QObject
58−{
59−public:
60− explicit InfographicDataPrivate(InfographicData *parent);
61−
62− InfographicDataPrivate(const QString &label,
63− const InfographicColorTheme &firstColor,
64− const QVariantList &firstMonth,
65− const InfographicColorTheme &secondColor,
66− const QVariantList &secondMonth, InfographicData *parent);
67−
68− ~InfographicDataPrivate();
69−
70− InfographicData * const q_ptr;
71− QString m_label;
72− InfographicColorTheme m_firstColor;
73− QVariantList m_firstMonth;
74− InfographicColorTheme m_secondColor;
75− QVariantList m_secondMonth;
76− int m_length;
77−
78−protected:
79− int calculateLength();
80−
81−private:
82− Q_DECLARE_PUBLIC(InfographicData)
83−};
84−
85−}
86−
87−InfographicColorThemePrivate::InfographicColorThemePrivate(
88− InfographicColorTheme *parent) :
89− q_ptr(parent)
90−{
91−}
92−
93−InfographicColorThemePrivate::InfographicColorThemePrivate(const QColor &start,
94− const QColor &main, const QColor &end, InfographicColorTheme *parent) :
95− q_ptr(parent), m_start(start), m_main(main), m_end(end)
96−{
97−}
98−
99−InfographicColorThemePrivate::~InfographicColorThemePrivate()
100−{
101−}
102−
103−InfographicColorTheme::InfographicColorTheme(QObject *parent) :
104− QObject(parent), d_ptr(new InfographicColorThemePrivate(this))
105−{
106−}
107−
108−InfographicColorTheme::InfographicColorTheme(QColor &first, QColor &main,
109− QColor &end, QObject *parent) :
110− QObject(parent), d_ptr(
111− new InfographicColorThemePrivate(first, main, end, this))
112−{
113−
114−}
115−
116−InfographicColorTheme & InfographicColorTheme::operator=(
117− const InfographicColorTheme & other)
118−{
119− if (d_ptr->m_start != other.d_ptr->m_start)
120− {
121− d_ptr->m_start = other.d_ptr->m_start;
122− startChanged(d_ptr->m_start);
123− }
124− if (d_ptr->m_main != other.d_ptr->m_main)
125− {
126− d_ptr->m_main = other.d_ptr->m_main;
127− mainChanged(d_ptr->m_main);
128− }
129−
130− if (d_ptr->m_end != other.d_ptr->m_end)
131− {
132− d_ptr->m_end = other.d_ptr->m_end;
133− endChanged(d_ptr->m_end);
134− }
135−
136− return *this;
137−}
138−
139−InfographicColorTheme::~InfographicColorTheme()
140−{
141− delete d_ptr;
142−}
143−
144−QColor InfographicColorTheme::start() const
145−{
146− return d_ptr->m_start;
147−}
148−
149−QColor InfographicColorTheme::main() const
150−{
151− return d_ptr->m_main;
152−}
153−
154−QColor InfographicColorTheme::end() const
155−{
156− return d_ptr->m_end;
157−}
158−
159−InfographicDataPrivate::InfographicDataPrivate(InfographicData *parent) :
160− q_ptr(parent), m_firstColor(this), m_secondColor(this)
161−{
162− m_length = calculateLength();
163−}
164−
165−InfographicDataPrivate::InfographicDataPrivate(const QString &label,
166− const InfographicColorTheme &firstColor, const QVariantList &firstMonth,
167− const InfographicColorTheme &secondColor,
168− const QVariantList &secondMonth, InfographicData *parent) :
169− q_ptr(parent), m_label(label), m_firstColor(this), m_firstMonth(
170− firstMonth), m_secondColor(this), m_secondMonth(secondMonth)
171−{
172− m_length = calculateLength();
173− m_firstColor = firstColor;
174− m_secondColor = secondColor;
175−}
176−
177−InfographicDataPrivate::~InfographicDataPrivate()
178−{
179−}
180−
181−int InfographicDataPrivate::calculateLength()
182−{
183− int day(m_firstMonth.size());
184− auto it = m_firstMonth.end(), end = m_firstMonth.begin();
185− while (it != end)
186− {
187− --it;
188− --day;
189− if (!it->isNull())
190− {
191− return day;
192− }
193− }
194−
195− return -1;
196−}
197−
198−InfographicData::InfographicData(QObject *parent) :
199− QObject(parent), d_ptr(new InfographicDataPrivate(this))
200−{
201−}
202−
203−InfographicData::InfographicData(const QString &label,
204− const InfographicColorTheme &firstColor, const QVariantList &firstMonth,
205− const InfographicColorTheme &secondColor,
206− const QVariantList &secondMonth, QObject* parent) :
207− QObject(parent), d_ptr(
208− new InfographicDataPrivate(label, firstColor, firstMonth,
209− secondColor, secondMonth, this))
210−{
211−}
212−
213−InfographicData::~InfographicData()
214−{
215− delete d_ptr;
216−}
217−
218−const QString & InfographicData::label() const
219−{
220− return d_ptr->m_label;
221−}
222−
223−const InfographicColorTheme & InfographicData::firstColor() const
224−{
225− return d_ptr->m_firstColor;
226−}
227−
228−const QVariantList & InfographicData::firstMonth() const
229−{
230− return d_ptr->m_firstMonth;
231−}
232−
233−const InfographicColorTheme & InfographicData::secondColor() const
234−{
235− return d_ptr->m_secondColor;
236−}
237−
238−const QVariantList & InfographicData::secondMonth() const
239−{
240− return d_ptr->m_secondMonth;
241−}
242−
243−int InfographicData::length() const
244−{
245− return d_ptr->m_length;
246−}
247−
248−InfographicModelPrivate::InfographicModelPrivate(InfographicModel *parent) :
249− q_ptr(parent), m_currentDay(0)
250−{
251− m_fakeData.insert("", InfographicDataPtr(new InfographicData(this)));
252−}
253−
254−InfographicModelPrivate::~InfographicModelPrivate()
255−{
256−}
257−
258−void InfographicModelPrivate::setUsername(const QString &username)
259−{
260− if(m_username == username) {
261− return;
262− }
263−
264− m_username = username;
265−
266− m_dataIndex = m_fakeData.constFind(m_username);
267− if (m_dataIndex == m_fakeData.end())
268− {
269− m_dataIndex = m_fakeData.constFind("");
270− }
271−
272− loadFakeData();
273−
274− q_ptr->usernameChanged(m_username);
275−}
276−
277−void InfographicModelPrivate::loadFakeData()
278−{
279− m_newData = *m_dataIndex;
280−
281− bool oldLabelEmpty = m_label.isEmpty();
282− bool newLabelEmpty = m_newData->label().isEmpty();
283−
284− if (oldLabelEmpty && !newLabelEmpty)
285− {
286− q_ptr->dataAboutToAppear();
287− finishSetFakeData();
288− } else if (!oldLabelEmpty && newLabelEmpty)
289− {
290− q_ptr->dataAboutToDisappear();
291− } else if (!oldLabelEmpty && !newLabelEmpty)
292− {
293− q_ptr->dataAboutToChange();
294− }
295− // we emit no signal if the data has stayed empty
296−}
297−
298−void InfographicModelPrivate::finishSetFakeData()
299−{
300− bool oldLabelEmpty = m_label.isEmpty();
301− bool newLabelEmpty = m_newData->label().isEmpty();
302−
303− m_label = m_newData->label();
304− m_firstColor = m_newData->firstColor();
305− m_firstMonth.setVariantList(m_newData->firstMonth());
306− m_secondColor = m_newData->secondColor();
307− m_secondMonth.setVariantList(m_newData->secondMonth());
308−
309− bool currentDayChanged = m_currentDay != m_newData->length();
310− m_currentDay = m_newData->length();
311−
312− q_ptr->labelChanged(m_label);
313− if (currentDayChanged)
314− {
315− q_ptr->currentDayChanged(m_currentDay);
316− }
317−
318− if (oldLabelEmpty && !newLabelEmpty)
319− {
320− q_ptr->dataAppeared();
321− } else if (!oldLabelEmpty && newLabelEmpty)
322− {
323− q_ptr->dataDisappeared();
324− } else if (!oldLabelEmpty && !newLabelEmpty)
325− {
326− q_ptr->dataChanged();
327− }
328− // we emit no signal if the data has stayed empty
329−}
330−
331−void InfographicModelPrivate::nextFakeData()
332−{
333− ++m_dataIndex;
334− if (m_dataIndex == m_fakeData.end() || m_dataIndex.key() != m_username)
335− {
336− m_dataIndex = m_fakeData.constFind(m_username);
337− }
338−
339− loadFakeData();
340−}
341−
342−InfographicModel::InfographicModel(QObject *parent) :
343− QObject(parent), d_ptr(new InfographicModelPrivate(this))
344−{
345− d_ptr->generateFakeData();
346− setUsername("");
347−
348− connect(this, SIGNAL(nextDataSource()), this, SLOT(nextDataSourceSlot()),
349− Qt::QueuedConnection);
350− connect(this, SIGNAL(readyForDataChange()), this,
351− SLOT(readyForDataChangeSlot()), Qt::QueuedConnection);
352−}
353−
354−InfographicModel::~InfographicModel()
355−{
356− delete d_ptr;
357−}
358−
359−QString InfographicModel::label() const
360−{
361− return d_ptr->m_label;
362−}
363−
364−QString InfographicModel::username() const
365−{
366− return d_ptr->m_username;
367−}
368−
369−void InfographicModel::setUsername(const QString &username)
370−{
371− d_ptr->setUsername(username);
372−}
373−
374−InfographicColorTheme * InfographicModel::firstColor() const
375−{
376− return &d_ptr->m_firstColor;
377−}
378−
379−InfographicColorTheme * InfographicModel::secondColor() const
380−{
381− return &d_ptr->m_secondColor;
382−}
383−
384−QAbstractItemModel * InfographicModel::firstMonth() const
385−{
386− return &d_ptr->m_firstMonth;
387−}
388−
389−QAbstractItemModel * InfographicModel::secondMonth() const
390−{
391− return &d_ptr->m_secondMonth;
392−}
393−
394−int InfographicModel::currentDay() const
395−{
396− return d_ptr->m_currentDay;
397−}
398−
399−void InfographicModel::nextDataSourceSlot()
400−{
401− d_ptr->nextFakeData();
402−}
403−
404−void InfographicModel::readyForDataChangeSlot()
405−{
406− d_ptr->finishSetFakeData();
407−}
408−
409−/**
410− * Factory methods
411− */
412−
413−InfographicModel * InfographicModel::getInstance()
414−{
415− return new InfographicModel();
416−}
tests/mocks/LightDM/InfographicModelPrivate.hdeleted−99
@@ -1,99 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− *
16− * Author: Pete Woods <pete.woods@canonical.com>
17− */
18−
19−#ifndef INFOGRAPHICMODEL_PRIVATE_H
20−#define INFOGRAPHICMODEL_PRIVATE_H
21−
22−#include <QtCore/QSharedPointer>
23−
24−#include "InfographicModel.h"
25−#include "plugins/Utils/qvariantlistmodel.h"
26−
27−namespace QLightDM
28−{
29−class InfographicDataPrivate;
30−
31−class Q_DECL_EXPORT InfographicData: public QObject
32−{
33−public:
34− explicit InfographicData(QObject *parent);
35−
36− InfographicData(const QString &label,
37− const InfographicColorTheme &firstColor,
38− const QVariantList &firstMonth,
39− const InfographicColorTheme &secondColor,
40− const QVariantList &secondMonth, QObject* parent);
41−
42− ~InfographicData();
43−
44−protected:
45− InfographicDataPrivate * const d_ptr;
46−
47−public:
48− const QString & label() const;
49− const InfographicColorTheme & firstColor() const;
50− const QVariantList & firstMonth() const;
51− const InfographicColorTheme & secondColor() const;
52− const QVariantList & secondMonth() const;
53− int length() const;
54−
55−private:
56− Q_DECLARE_PRIVATE(InfographicData)
57−};
58−
59−class InfographicModelPrivate: QObject
60−{
61−
62−public:
63− explicit InfographicModelPrivate(InfographicModel *parent);
64−
65− ~InfographicModelPrivate();
66−
67−public:
68− typedef QSharedPointer<InfographicData> InfographicDataPtr;
69− typedef QMultiMap<QString, InfographicDataPtr> FakeDataMap;
70−
71− InfographicModel * const q_ptr;
72− QString m_label;
73− InfographicColorTheme m_firstColor;
74− QVariantListModel m_firstMonth;
75− InfographicColorTheme m_secondColor;
76− QVariantListModel m_secondMonth;
77− int m_currentDay;
78− QString m_username;
79− FakeDataMap::const_iterator m_dataIndex;
80− InfographicDataPtr m_newData;
81− FakeDataMap m_fakeData;
82−
83− void setUsername(const QString &username);
84−
85−protected:
86− void nextFakeData();
87−
88− void generateFakeData();
89−
90− void loadFakeData();
91−
92− void finishSetFakeData();
93−
94−private:
95− Q_DECLARE_PUBLIC(InfographicModel)
96−};
97−}
98−
99−#endif // INFOGRAPHICMODEL_PRIVATE_H
tests/mocks/LightDM/demo/CMakeLists.txt+11−2
@@ -1,13 +1,22 @@
1+include(FindPkgConfig)
2+pkg_check_modules(LIBUSERMETRICSOUTPUT REQUIRED libusermetricsoutput-1)
3+
14set(LibLightDM_SOURCES
25 ../Greeter.cpp
36 ../UsersModel.cpp
4− ../InfographicModel.cpp
57 GreeterPrivate.cpp
68 UsersModelPrivate.cpp
7− InfographicModelPrivate.cpp
89 ${CMAKE_SOURCE_DIR}/plugins/Utils/qvariantlistmodel.cpp
910 )
1011
1112add_library(MockLightDM-demo STATIC ${LibLightDM_SOURCES})
1213
14+include_directories(
15+ ${LIBUSERMETRICSOUTPUT_INCLUDE_DIRS}
16+)
17+
18+target_link_libraries(MockLightDM-demo
19+ ${LIBUSERMETRICSOUTPUT_LDFLAGS}
20+ )
21+
1322qt5_use_modules(MockLightDM-demo Gui)
tests/mocks/LightDM/demo/UsersModelPrivate.cpp+1−1
@@ -26,7 +26,7 @@ UsersModelPrivate::UsersModelPrivate(UsersModel* parent)
2626{
2727 entries =
2828 {
29− { "guest", "Guest", 0, 0, false, false, 0, 0 },
29+ { "single", "Guest", 0, 0, false, false, 0, 0 },
3030 };
3131}
3232
tests/mocks/LightDM/full/CMakeLists.txt+1−3
@@ -1,10 +1,8 @@
11set(LibLightDM_SOURCES
22 ../Greeter.cpp
33 ../UsersModel.cpp
4− ../InfographicModel.cpp
54 GreeterPrivate.cpp
65 UsersModelPrivate.cpp
7− InfographicModelPrivate.cpp
86 ${CMAKE_SOURCE_DIR}/plugins/Utils/qvariantlistmodel.cpp
97 )
108
@@ -16,5 +14,5 @@ set_target_properties(MockLightDM-full PROPERTIES
1614 OUTPUT_NAME lightdm-qt5-2)
1715
1816install(TARGETS MockLightDM-full
19− DESTINATION ${SHELL_APP_DIR}/plugins/mocks/LightDM/full
17+ DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/mocks/LightDM/full
2018 )
tests/mocks/LightDM/single-passphrase/CMakeLists.txt+1−3
@@ -1,10 +1,8 @@
11set(LibLightDM_SOURCES
22 ../Greeter.cpp
33 ../UsersModel.cpp
4− ../InfographicModel.cpp
54 GreeterPrivate.cpp
65 UsersModelPrivate.cpp
7− InfographicModelPrivate.cpp
86 ${CMAKE_SOURCE_DIR}/plugins/Utils/qvariantlistmodel.cpp
97 )
108
@@ -17,5 +15,5 @@ set_target_properties(MockLightDM-single-passphrase PROPERTIES
1715 OUTPUT_NAME lightdm-qt5-2)
1816
1917install(TARGETS MockLightDM-single-passphrase
20− DESTINATION ${SHELL_APP_DIR}/plugins/mocks/LightDM/single-passphrase
18+ DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/mocks/LightDM/single-passphrase
2119 )
tests/mocks/LightDM/single-passphrase/UsersModelPrivate.cpp+1−1
@@ -26,7 +26,7 @@ UsersModelPrivate::UsersModelPrivate(UsersModel* parent)
2626{
2727 entries =
2828 {
29− { "has-pin", "Has PIN", 0, 0, false, false, 0, 0 },
29+ { "single", "Has Passphrase", 0, 0, false, false, 0, 0 },
3030 };
3131}
3232
tests/mocks/LightDM/single-pin/CMakeLists.txt+1−3
@@ -1,10 +1,8 @@
11set(LibLightDM_SOURCES
22 ../Greeter.cpp
33 ../UsersModel.cpp
4− ../InfographicModel.cpp
54 GreeterPrivate.cpp
65 UsersModelPrivate.cpp
7− InfographicModelPrivate.cpp
86 ${CMAKE_SOURCE_DIR}/plugins/Utils/qvariantlistmodel.cpp
97 )
108
@@ -17,5 +15,5 @@ set_target_properties(MockLightDM-single-pin PROPERTIES
1715 OUTPUT_NAME lightdm-qt5-2)
1816
1917install(TARGETS MockLightDM-single-pin
20− DESTINATION ${SHELL_APP_DIR}/plugins/mocks/LightDM/single-pin
18+ DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/mocks/LightDM/single-pin
2119 )
tests/mocks/LightDM/single-pin/UsersModelPrivate.cpp+1−1
@@ -26,7 +26,7 @@ UsersModelPrivate::UsersModelPrivate(UsersModel* parent)
2626{
2727 entries =
2828 {
29− { "has-pin", "Has PIN", 0, 0, false, false, 0, 0 },
29+ { "single", "Has PIN", 0, 0, false, false, 0, 0 },
3030 };
3131}
3232
tests/mocks/LightDM/single/CMakeLists.txt+1−3
@@ -1,9 +1,7 @@
11set(LibLightDM_SOURCES
22 ../Greeter.cpp
3− ../InfographicModel.cpp
43 ../UsersModel.cpp
54 GreeterPrivate.cpp
6− InfographicModelPrivate.cpp
75 UsersModelPrivate.cpp
86 ${CMAKE_SOURCE_DIR}/plugins/Utils/qvariantlistmodel.cpp
97 )
@@ -16,5 +14,5 @@ set_target_properties(MockLightDM-single PROPERTIES
1614 OUTPUT_NAME lightdm-qt5-2)
1715
1816install(TARGETS MockLightDM-single
19− DESTINATION ${SHELL_APP_DIR}/plugins/mocks/LightDM/single
17+ DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/mocks/LightDM/single
2018 )
tests/mocks/LightDM/single/UsersModelPrivate.cpp+1−1
@@ -26,7 +26,7 @@ UsersModelPrivate::UsersModelPrivate(UsersModel* parent)
2626{
2727 entries =
2828 {
29− { "one", "Only User", 0, 0, false, false, 0, 0 },
29+ { "single", "Single User", 0, 0, false, false, 0, 0 },
3030 };
3131}
3232
tests/mocks/Ubuntu/Application/CMakeLists.txt+2−2
@@ -27,9 +27,9 @@ add_custom_target(InputFilterAreaQmlFile ALL
2727)
2828
2929install(TARGETS FakeUbuntuApplicationQml
30− DESTINATION ${SHELL_APP_DIR}/plugins/mocks/Ubuntu/Application
30+ DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/mocks/Ubuntu/Application
3131 )
3232
3333install(FILES qmldir InputFilterArea.qml
34− DESTINATION ${SHELL_APP_DIR}/plugins/mocks/Ubuntu/Application
34+ DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/mocks/Ubuntu/Application
3535 )
tests/mocks/Ubuntu/CMakeLists.txt+1
@@ -1 +1,2 @@
11add_subdirectory(Application)
2+add_subdirectory(ChewieUI)
tests/qmltests/plugins/Ubuntu/ChewieUI/CMakeLists.txt → tests/mocks/Ubuntu/ChewieUI/CMakeLists.txtrenamed

The content is the same.

tests/qmltests/plugins/Ubuntu/ChewieUI/fake_chewie_plugin.cpp → tests/mocks/Ubuntu/ChewieUI/fake_chewie_plugin.cpprenamed

The content is the same.

tests/qmltests/plugins/Ubuntu/ChewieUI/fake_chewie_plugin.h → tests/mocks/Ubuntu/ChewieUI/fake_chewie_plugin.hrenamed

The content is the same.

tests/qmltests/plugins/Ubuntu/ChewieUI/fake_pluginmodel.cpp → tests/mocks/Ubuntu/ChewieUI/fake_pluginmodel.cpprenamed

The content is the same.

tests/qmltests/plugins/Ubuntu/ChewieUI/fake_pluginmodel.h → tests/mocks/Ubuntu/ChewieUI/fake_pluginmodel.hrenamed

The content is the same.

tests/qmltests/plugins/Ubuntu/ChewieUI/qmldir → tests/mocks/Ubuntu/ChewieUI/qmldirrenamed

The content is the same.

tests/mocks/Unity.moved/CMakeLists.txtnew file+1
@@ -0,0 +1 @@
1+add_subdirectory(Launcher)
tests/mocks/Unity/Launcher/CMakeLists.txt → tests/mocks/Unity.moved/Launcher/CMakeLists.txtrenamed

The content is the same.

tests/mocks/Unity/Launcher/MockLauncherItem.cpp → tests/mocks/Unity.moved/Launcher/MockLauncherItem.cpprenamed

The content is the same.

tests/mocks/Unity/Launcher/MockLauncherItem.h → tests/mocks/Unity.moved/Launcher/MockLauncherItem.hrenamed

The content is the same.

tests/mocks/Unity/Launcher/MockLauncherModel.cpp → tests/mocks/Unity.moved/Launcher/MockLauncherModel.cpprenamed

The content is the same.

tests/mocks/Unity/Launcher/MockLauncherModel.h → tests/mocks/Unity.moved/Launcher/MockLauncherModel.hrenamed

The content is the same.

tests/mocks/Unity/Launcher/plugin.cpp → tests/mocks/Unity.moved/Launcher/plugin.cpprenamed

The content is the same.

tests/mocks/Unity/Launcher/plugin.h → tests/mocks/Unity.moved/Launcher/plugin.hrenamed

The content is the same.

tests/mocks/Unity/Launcher/qmldir → tests/mocks/Unity.moved/Launcher/qmldirrenamed

The content is the same.

tests/mocks/Unity/CMakeLists.txt+44
@@ -1 +1,45 @@
1+set(CMAKE_AUTOMOC ON)
2+
3+include(FindPkgConfig)
4+find_package(Qt5Core REQUIRED)
5+find_package(Qt5Quick REQUIRED)
6+pkg_search_module(DEE dee-1.0 REQUIRED)
7+pkg_search_module(GOBJECT gobject-2.0 REQUIRED)
8+pkg_search_module(DEEQT libdee-qt5 REQUIRED)
9+
10+include_directories(
11+ ${CMAKE_SOURCE_DIR}/plugins/Unity
12+ ${CMAKE_CURRENT_BINARY_DIR}
13+ ${Qt5Core_INCLUDE_DIRS}
14+ ${Qt5Quick_INCLUDE_DIRS}
15+ ${DEE_INCLUDE_DIRS}
16+ ${DEEQT_INCLUDE_DIRS}
17+)
18+
19+add_definitions(-DQT_NO_KEYWORDS)
20+
21+set(UnityQML_SOURCES
22+ ${CMAKE_SOURCE_DIR}/plugins/Unity/categories.cpp
23+ ${CMAKE_SOURCE_DIR}/plugins/Unity/categoryfilter.cpp
24+ ${CMAKE_SOURCE_DIR}/plugins/Utils/qsortfilterproxymodelqml.cpp
25+ fake_scope.cpp
26+ fake_scopes.cpp
27+ fake_unity_plugin.cpp
28+)
29+
30+add_library(FakeUnityQml MODULE ${UnityQML_SOURCES})
31+target_link_libraries(FakeUnityQml
32+ ${Qt5Core_LIBRARIES}
33+ ${Qt5Quick_LIBRARIES}
34+ ${DEEQT_LDFLAGS}
35+ ${GOBJECT_LDFLAGS}
36+)
37+
38+qt5_use_modules(FakeUnityQml Qml)
39+
40+# copy qmldir file into build directory for shadow builds
41+file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/qmldir"
42+ DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
43+ )
44+
145add_subdirectory(Launcher)
tests/qmltests/plugins/Unity/Notifications/notification.js → tests/mocks/Unity/Notifications/notification.jsrenamed

The content is the same.

tests/qmltests/plugins/Unity/Notifications/qmldir → tests/mocks/Unity/Notifications/qmldirrenamed

The content is the same.

tests/qmltests/plugins/Unity/fake_scope.cpp → tests/mocks/Unity/fake_scope.cpprenamed

The content is the same.

tests/qmltests/plugins/Unity/fake_scope.h → tests/mocks/Unity/fake_scope.hrenamed

The content is the same.

tests/qmltests/plugins/Unity/fake_scopes.cpp → tests/mocks/Unity/fake_scopes.cpprenamed

The content is the same.

tests/qmltests/plugins/Unity/fake_scopes.h → tests/mocks/Unity/fake_scopes.hrenamed

The content is the same.

tests/qmltests/plugins/Unity/fake_unity_plugin.cpp → tests/mocks/Unity/fake_unity_plugin.cpprenamed

The content is the same.

tests/qmltests/plugins/Unity/fake_unity_plugin.h → tests/mocks/Unity/fake_unity_plugin.hrenamed

The content is the same.

tests/qmltests/plugins/Unity/qmldir → tests/mocks/Unity/qmldirrenamed

The content is the same.

tests/mocks/libusermetrics/CMakeLists.txtnew file+17
@@ -0,0 +1,17 @@
1+set(mock_SOURCES
2+ ColorTheme.cpp
3+ UserMetrics.cpp
4+ ${CMAKE_SOURCE_DIR}/plugins/Utils/qvariantlistmodel.cpp
5+ )
6+
7+add_library(MockUserMetrics SHARED ${mock_SOURCES})
8+
9+qt5_use_modules(MockUserMetrics Gui)
10+
11+set_target_properties(MockUserMetrics PROPERTIES
12+ OUTPUT_NAME usermetricsoutput
13+ VERSION 1)
14+
15+install(TARGETS MockUserMetrics
16+ DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/mocks/libusermetrics
17+ )
tests/mocks/libusermetrics/ColorTheme.cppnew file+128
@@ -0,0 +1,128 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Author: Pete Woods <pete.woods@canonical.com>
17+ */
18+
19+#include "ColorTheme.h"
20+
21+#include <QtCore/QDir>
22+#include <QtCore/QString>
23+#include <QtGui/QIcon>
24+#include <QMultiMap>
25+
26+using namespace UserMetricsOutput;
27+
28+namespace UserMetricsOutput
29+{
30+
31+class ColorThemePrivate: QObject
32+{
33+public:
34+ explicit ColorThemePrivate(ColorTheme *parent = 0);
35+
36+ ColorThemePrivate(const QColor &start, const QColor &main,
37+ const QColor &end, ColorTheme *parent = 0);
38+
39+ ~ColorThemePrivate();
40+
41+ ColorTheme * const q_ptr;
42+
43+ QColor m_start;
44+
45+ QColor m_main;
46+
47+ QColor m_end;
48+
49+protected:
50+ int calculateLength();
51+
52+private:
53+ Q_DECLARE_PUBLIC(ColorTheme)
54+};
55+
56+}
57+
58+ColorThemePrivate::ColorThemePrivate(
59+ ColorTheme *parent) :
60+ q_ptr(parent)
61+{
62+}
63+
64+ColorThemePrivate::ColorThemePrivate(const QColor &start,
65+ const QColor &main, const QColor &end, ColorTheme *parent) :
66+ q_ptr(parent), m_start(start), m_main(main), m_end(end)
67+{
68+}
69+
70+ColorThemePrivate::~ColorThemePrivate()
71+{
72+}
73+
74+ColorTheme::ColorTheme(QObject *parent) :
75+ QObject(parent), d_ptr(new ColorThemePrivate(this))
76+{
77+}
78+
79+ColorTheme::ColorTheme(QColor &first, QColor &main,
80+ QColor &end, QObject *parent) :
81+ QObject(parent), d_ptr(
82+ new ColorThemePrivate(first, main, end, this))
83+{
84+
85+}
86+
87+ColorTheme & ColorTheme::operator=(
88+ const ColorTheme & other)
89+{
90+ if (d_ptr->m_start != other.d_ptr->m_start)
91+ {
92+ d_ptr->m_start = other.d_ptr->m_start;
93+ startChanged(d_ptr->m_start);
94+ }
95+ if (d_ptr->m_main != other.d_ptr->m_main)
96+ {
97+ d_ptr->m_main = other.d_ptr->m_main;
98+ mainChanged(d_ptr->m_main);
99+ }
100+
101+ if (d_ptr->m_end != other.d_ptr->m_end)
102+ {
103+ d_ptr->m_end = other.d_ptr->m_end;
104+ endChanged(d_ptr->m_end);
105+ }
106+
107+ return *this;
108+}
109+
110+ColorTheme::~ColorTheme()
111+{
112+ delete d_ptr;
113+}
114+
115+QColor ColorTheme::start() const
116+{
117+ return d_ptr->m_start;
118+}
119+
120+QColor ColorTheme::main() const
121+{
122+ return d_ptr->m_main;
123+}
124+
125+QColor ColorTheme::end() const
126+{
127+ return d_ptr->m_end;
128+}
tests/mocks/libusermetrics/ColorTheme.hnew file+68
@@ -0,0 +1,68 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Author: Pete Woods <pete.woods@canonical.com>
17+ */
18+
19+#ifndef UNITY_MOCK_COLORTHEME_H
20+#define UNITY_MOCK_COLORTHEME_H
21+
22+#include <QtGui/QColor>
23+
24+namespace UserMetricsOutput
25+{
26+class ColorThemePrivate;
27+
28+class Q_DECL_EXPORT ColorTheme: public QObject
29+{
30+Q_OBJECT
31+
32+Q_PROPERTY(QColor start READ start NOTIFY startChanged FINAL)
33+Q_PROPERTY(QColor main READ main NOTIFY mainChanged FINAL)
34+Q_PROPERTY(QColor end READ end NOTIFY endChanged FINAL)
35+
36+public:
37+ explicit ColorTheme(QObject *parent = 0);
38+
39+ explicit ColorTheme(QColor &first, QColor &main, QColor &end,
40+ QObject *parent = 0);
41+
42+ ColorTheme & operator=(const ColorTheme & other);
43+
44+ ~ColorTheme();
45+
46+ QColor start() const;
47+
48+ QColor main() const;
49+
50+ QColor end() const;
51+
52+Q_SIGNALS:
53+ void startChanged(const QColor &color);
54+
55+ void mainChanged(const QColor &color);
56+
57+ void endChanged(const QColor &color);
58+
59+protected:
60+ ColorThemePrivate * const d_ptr;
61+
62+ Q_DECLARE_PRIVATE(ColorTheme)
63+
64+};
65+
66+}
67+
68+#endif // UNITY_MOCK_COLORTHEME_H
tests/mocks/libusermetrics/UserMetrics.cppnew file+465
@@ -0,0 +1,465 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Author: Pete Woods <pete.woods@canonical.com>
17+ */
18+
19+#include "UserMetrics.h"
20+#include "plugins/Utils/qvariantlistmodel.h"
21+
22+#include <QtCore/QDir>
23+#include <QtCore/QString>
24+#include <QtGui/QIcon>
25+#include <QMultiMap>
26+
27+using namespace UserMetricsOutput;
28+
29+namespace UserMetricsOutput
30+{
31+class UserMetricsDataPrivate;
32+class UserMetricsPrivate;
33+
34+class Q_DECL_EXPORT UserMetricsData: public QObject
35+{
36+public:
37+ explicit UserMetricsData(QObject *parent);
38+
39+ UserMetricsData(const QString &label,
40+ const ColorTheme &firstColor,
41+ const QVariantList &firstMonth,
42+ const ColorTheme &secondColor,
43+ const QVariantList &secondMonth, QObject* parent);
44+
45+ ~UserMetricsData();
46+
47+protected:
48+ UserMetricsDataPrivate * const d_ptr;
49+
50+public:
51+ const QString & label() const;
52+ const ColorTheme & firstColor() const;
53+ const QVariantList & firstMonth() const;
54+ const ColorTheme & secondColor() const;
55+ const QVariantList & secondMonth() const;
56+ int length() const;
57+
58+private:
59+ Q_DECLARE_PRIVATE(UserMetricsData)
60+};
61+
62+class UserMetricsPrivate: QObject
63+{
64+public:
65+ explicit UserMetricsPrivate(UserMetrics *parent);
66+
67+ ~UserMetricsPrivate();
68+
69+public:
70+ typedef QSharedPointer<UserMetricsData> UserMetricsDataPtr;
71+ typedef QMultiMap<QString, UserMetricsDataPtr> FakeDataMap;
72+
73+ UserMetrics * const q_ptr;
74+ QString m_label;
75+ ColorTheme m_firstColor;
76+ QVariantListModel m_firstMonth;
77+ ColorTheme m_secondColor;
78+ QVariantListModel m_secondMonth;
79+ int m_currentDay;
80+ QString m_username;
81+ FakeDataMap::const_iterator m_dataIndex;
82+ UserMetricsDataPtr m_newData;
83+ FakeDataMap m_fakeData;
84+
85+ void setUsername(const QString &username);
86+
87+protected:
88+ void nextFakeData();
89+
90+ void generateFakeData();
91+
92+ void loadFakeData();
93+
94+ void finishSetFakeData();
95+
96+private:
97+ Q_DECLARE_PUBLIC(UserMetrics)
98+};
99+
100+class UserMetricsDataPrivate: QObject
101+{
102+public:
103+ explicit UserMetricsDataPrivate(UserMetricsData *parent);
104+
105+ UserMetricsDataPrivate(const QString &label,
106+ const ColorTheme &firstColor,
107+ const QVariantList &firstMonth,
108+ const ColorTheme &secondColor,
109+ const QVariantList &secondMonth, UserMetricsData *parent);
110+
111+ ~UserMetricsDataPrivate();
112+
113+ UserMetricsData * const q_ptr;
114+ QString m_label;
115+ ColorTheme m_firstColor;
116+ QVariantList m_firstMonth;
117+ ColorTheme m_secondColor;
118+ QVariantList m_secondMonth;
119+ int m_length;
120+
121+protected:
122+ int calculateLength();
123+
124+private:
125+ Q_DECLARE_PUBLIC(UserMetricsData)
126+};
127+
128+}
129+
130+UserMetricsDataPrivate::UserMetricsDataPrivate(UserMetricsData *parent) :
131+ q_ptr(parent), m_firstColor(this), m_secondColor(this)
132+{
133+ m_length = calculateLength();
134+}
135+
136+UserMetricsDataPrivate::UserMetricsDataPrivate(const QString &label,
137+ const ColorTheme &firstColor, const QVariantList &firstMonth,
138+ const ColorTheme &secondColor,
139+ const QVariantList &secondMonth, UserMetricsData *parent) :
140+ q_ptr(parent), m_label(label), m_firstColor(this), m_firstMonth(
141+ firstMonth), m_secondColor(this), m_secondMonth(secondMonth)
142+{
143+ m_length = calculateLength();
144+ m_firstColor = firstColor;
145+ m_secondColor = secondColor;
146+}
147+
148+UserMetricsDataPrivate::~UserMetricsDataPrivate()
149+{
150+}
151+
152+int UserMetricsDataPrivate::calculateLength()
153+{
154+ int day(m_firstMonth.size());
155+ auto it = m_firstMonth.end(), end = m_firstMonth.begin();
156+ while (it != end)
157+ {
158+ --it;
159+ --day;
160+ if (!it->isNull())
161+ {
162+ return day;
163+ }
164+ }
165+
166+ return -1;
167+}
168+
169+UserMetricsData::UserMetricsData(QObject *parent) :
170+ QObject(parent), d_ptr(new UserMetricsDataPrivate(this))
171+{
172+}
173+
174+UserMetricsData::UserMetricsData(const QString &label,
175+ const ColorTheme &firstColor, const QVariantList &firstMonth,
176+ const ColorTheme &secondColor,
177+ const QVariantList &secondMonth, QObject* parent) :
178+ QObject(parent), d_ptr(
179+ new UserMetricsDataPrivate(label, firstColor, firstMonth,
180+ secondColor, secondMonth, this))
181+{
182+}
183+
184+UserMetricsData::~UserMetricsData()
185+{
186+ delete d_ptr;
187+}
188+
189+const QString & UserMetricsData::label() const
190+{
191+ return d_ptr->m_label;
192+}
193+
194+const ColorTheme & UserMetricsData::firstColor() const
195+{
196+ return d_ptr->m_firstColor;
197+}
198+
199+const QVariantList & UserMetricsData::firstMonth() const
200+{
201+ return d_ptr->m_firstMonth;
202+}
203+
204+const ColorTheme & UserMetricsData::secondColor() const
205+{
206+ return d_ptr->m_secondColor;
207+}
208+
209+const QVariantList & UserMetricsData::secondMonth() const
210+{
211+ return d_ptr->m_secondMonth;
212+}
213+
214+int UserMetricsData::length() const
215+{
216+ return d_ptr->m_length;
217+}
218+
219+UserMetricsPrivate::UserMetricsPrivate(UserMetrics *parent) :
220+ q_ptr(parent), m_firstColor(this), m_secondColor(this)
221+{
222+ m_fakeData.insert("", UserMetricsDataPtr(new UserMetricsData(this)));
223+}
224+
225+UserMetricsPrivate::~UserMetricsPrivate()
226+{
227+}
228+
229+void UserMetricsPrivate::setUsername(const QString &username)
230+{
231+ if (m_username == username) {
232+ return;
233+ }
234+
235+ m_username = username;
236+
237+ m_dataIndex = m_fakeData.constFind(m_username);
238+ if (m_dataIndex == m_fakeData.end())
239+ {
240+ m_dataIndex = m_fakeData.constFind("");
241+ }
242+
243+ loadFakeData();
244+
245+ q_ptr->usernameChanged(m_username);
246+}
247+
248+void UserMetricsPrivate::generateFakeData()
249+{
250+ std::default_random_engine generator;
251+ std::normal_distribution<qreal> distribution(0.5, 0.2);
252+ auto rand = std::bind(distribution, generator);
253+
254+ QVector<QColor> colours;
255+ colours.push_back(QColor::fromRgbF(0.3, 0.27, 0.32));
256+ colours.push_back(QColor::fromRgbF(0.83, 0.49, 0.58));
257+ colours.push_back(QColor::fromRgbF(0.63, 0.51, 0.59));
258+
259+ colours.push_back(QColor::fromRgbF(0.28, 0.26, 0.4));
260+ colours.push_back(QColor::fromRgbF(0.47, 0.38, 0.56));
261+ colours.push_back(QColor::fromRgbF(0.69, 0.65, 0.78));
262+
263+ colours.push_back(QColor::fromRgbF(0.32, 0.21, 0.16));
264+ colours.push_back(QColor::fromRgbF(0.55, 0.45, 0.32));
265+ colours.push_back(QColor::fromRgbF(0.85, 0.74, 0.53));
266+
267+ colours.push_back(QColor::fromRgbF(0.25, 0.31, 0.19));
268+ colours.push_back(QColor::fromRgbF(0.63, 0.53, 0.3));
269+ colours.push_back(QColor::fromRgbF(0.89, 0.56, 0.31));
270+
271+ ColorTheme first(colours[0], colours[1], colours[2]);
272+ ColorTheme second(colours[3], colours[4], colours[5]);
273+ ColorTheme eighth(colours[6], colours[7], colours[8]);
274+ ColorTheme ninth(colours[9], colours[10], colours[11]);
275+
276+ {
277+ QVariantList firstMonth;
278+ while (firstMonth.size() < 17)
279+ firstMonth.push_back(QVariant(rand()));
280+ while (firstMonth.size() < 31)
281+ firstMonth.push_back(QVariant());
282+ QVariantList secondMonth;
283+ while (secondMonth.size() < 31)
284+ secondMonth.push_back(QVariant(rand()));
285+ QSharedPointer<UserMetricsData> data(
286+ new UserMetricsData("<b>52km</b> travelled", first, firstMonth,
287+ ninth, secondMonth, this));
288+ m_fakeData.insert("single", data);
289+ }
290+
291+ {
292+ QVariantList firstMonth;
293+ while (firstMonth.size() < 17)
294+ firstMonth.push_back(QVariant(rand()));
295+ while (firstMonth.size() < 31)
296+ firstMonth.push_back(QVariant());
297+ QVariantList secondMonth;
298+ while (secondMonth.size() < 31)
299+ secondMonth.push_back(QVariant(rand()));
300+ QSharedPointer<UserMetricsData> data(
301+ new UserMetricsData("<b>33</b> messages today", second,
302+ firstMonth, eighth, secondMonth, this));
303+ m_fakeData.insert("single", data);
304+ }
305+
306+ {
307+ QVariantList firstMonth;
308+ while (firstMonth.size() < 17)
309+ firstMonth.push_back(QVariant(rand()));
310+ while (firstMonth.size() < 31)
311+ firstMonth.push_back(QVariant());
312+ QVariantList secondMonth;
313+ while (secondMonth.size() < 31)
314+ secondMonth.push_back(QVariant(rand()));
315+ QSharedPointer<UserMetricsData> data(
316+ new UserMetricsData("<b>19</b> minutes talk time", eighth,
317+ firstMonth, second, secondMonth, this));
318+ m_fakeData.insert("single", data);
319+ // Also use same data for some tablet users
320+ m_fakeData.insert("has-password", data);
321+ m_fakeData.insert("no-password", data);
322+ m_fakeData.insert("empty-name", data);
323+ }
324+}
325+
326+void UserMetricsPrivate::loadFakeData()
327+{
328+ m_newData = *m_dataIndex;
329+
330+ bool oldLabelEmpty = m_label.isEmpty();
331+ bool newLabelEmpty = m_newData->label().isEmpty();
332+
333+ if (oldLabelEmpty && !newLabelEmpty)
334+ {
335+ q_ptr->dataAboutToAppear();
336+ finishSetFakeData();
337+ } else if (!oldLabelEmpty && newLabelEmpty)
338+ {
339+ q_ptr->dataAboutToDisappear();
340+ } else if (!oldLabelEmpty && !newLabelEmpty)
341+ {
342+ q_ptr->dataAboutToChange();
343+ }
344+ // we emit no signal if the data has stayed empty
345+}
346+
347+void UserMetricsPrivate::finishSetFakeData()
348+{
349+ bool oldLabelEmpty = m_label.isEmpty();
350+ bool newLabelEmpty = m_newData->label().isEmpty();
351+
352+ m_label = m_newData->label();
353+ m_firstColor = m_newData->firstColor();
354+ m_firstMonth.setVariantList(m_newData->firstMonth());
355+ m_secondColor = m_newData->secondColor();
356+ m_secondMonth.setVariantList(m_newData->secondMonth());
357+
358+ bool currentDayChanged = m_currentDay != m_newData->length();
359+ m_currentDay = m_newData->length();
360+
361+ q_ptr->labelChanged(m_label);
362+ if (currentDayChanged)
363+ {
364+ q_ptr->currentDayChanged(m_currentDay);
365+ }
366+
367+ if (oldLabelEmpty && !newLabelEmpty)
368+ {
369+ q_ptr->dataAppeared();
370+ } else if (!oldLabelEmpty && newLabelEmpty)
371+ {
372+ q_ptr->dataDisappeared();
373+ } else if (!oldLabelEmpty && !newLabelEmpty)
374+ {
375+ q_ptr->dataChanged();
376+ }
377+ // we emit no signal if the data has stayed empty
378+}
379+
380+void UserMetricsPrivate::nextFakeData()
381+{
382+ ++m_dataIndex;
383+ if (m_dataIndex == m_fakeData.end() || m_dataIndex.key() != m_username)
384+ {
385+ m_dataIndex = m_fakeData.constFind(m_username);
386+ }
387+
388+ loadFakeData();
389+}
390+
391+UserMetrics::UserMetrics(QObject *parent) :
392+ QObject(parent), d_ptr(new UserMetricsPrivate(this))
393+{
394+ d_ptr->generateFakeData();
395+ setUsername("");
396+
397+ connect(this, SIGNAL(nextDataSource()), this, SLOT(nextDataSourceSlot()),
398+ Qt::QueuedConnection);
399+ connect(this, SIGNAL(readyForDataChange()), this,
400+ SLOT(readyForDataChangeSlot()), Qt::QueuedConnection);
401+}
402+
403+UserMetrics::~UserMetrics()
404+{
405+ delete d_ptr;
406+}
407+
408+QString UserMetrics::label() const
409+{
410+ return d_ptr->m_label;
411+}
412+
413+QString UserMetrics::username() const
414+{
415+ return d_ptr->m_username;
416+}
417+
418+void UserMetrics::setUsername(const QString &username)
419+{
420+ d_ptr->setUsername(username);
421+}
422+
423+ColorTheme *UserMetrics::firstColor() const
424+{
425+ return &d_ptr->m_firstColor;
426+}
427+
428+ColorTheme *UserMetrics::secondColor() const
429+{
430+ return &d_ptr->m_secondColor;
431+}
432+
433+QAbstractItemModel *UserMetrics::firstMonth() const
434+{
435+ return &d_ptr->m_firstMonth;
436+}
437+
438+QAbstractItemModel *UserMetrics::secondMonth() const
439+{
440+ return &d_ptr->m_secondMonth;
441+}
442+
443+int UserMetrics::currentDay() const
444+{
445+ return d_ptr->m_currentDay;
446+}
447+
448+void UserMetrics::nextDataSourceSlot()
449+{
450+ d_ptr->nextFakeData();
451+}
452+
453+void UserMetrics::readyForDataChangeSlot()
454+{
455+ d_ptr->finishSetFakeData();
456+}
457+
458+/**
459+ * Factory methods
460+ */
461+
462+UserMetrics * UserMetrics::getInstance()
463+{
464+ return new UserMetrics();
465+}
tests/mocks/LightDM/InfographicModel.h → tests/mocks/libusermetrics/UserMetrics.hrenamed+22−60
@@ -16,74 +16,34 @@
1616 * Author: Pete Woods <pete.woods@canonical.com>
1717 */
1818
19−#ifndef LIGHTDM_INFOGRAPHICMODEL_H
20−#define LIGHTDM_INFOGRAPHICMODEL_H
19+#ifndef UNITY_MOCK_USERMETRICS_H
20+#define UNITY_MOCK_USERMETRICS_H
2121
22+#include "ColorTheme.h"
23+#include <QtCore/QAbstractListModel>
2224#include <QtCore/QString>
23−#include <QtGui/qcolor.h>
24−#include <QAbstractListModel>
25+#include <QtGui/QColor>
2526
26−namespace QLightDM
27+namespace UserMetricsOutput
2728{
28−class InfographicColorThemePrivate;
29+class UserMetricsPrivate;
2930
30−class Q_DECL_EXPORT InfographicColorTheme: public QObject
31−{
32−Q_OBJECT
33−
34−Q_PROPERTY(QColor start READ start NOTIFY startChanged FINAL)
35−Q_PROPERTY(QColor main READ main NOTIFY mainChanged FINAL)
36−Q_PROPERTY(QColor end READ end NOTIFY endChanged FINAL)
37−
38−public:
39− explicit InfographicColorTheme(QObject *parent = 0);
40−
41− explicit InfographicColorTheme(QColor &first, QColor &main, QColor &end,
42− QObject *parent = 0);
43−
44− InfographicColorTheme & operator=(const InfographicColorTheme & other);
45−
46− ~InfographicColorTheme();
47−
48− QColor start() const;
49−
50− QColor main() const;
51−
52− QColor end() const;
53−
54−Q_SIGNALS:
55− void startChanged(const QColor &color);
56−
57− void mainChanged(const QColor &color);
58−
59− void endChanged(const QColor &color);
60−
61−protected:
62− InfographicColorThemePrivate * const d_ptr;
63−
64− Q_DECLARE_PRIVATE(InfographicColorTheme)
65−
66−};
67−
68−class InfographicModelPrivate;
69−
70−class Q_DECL_EXPORT InfographicModel: public QObject
31+class Q_DECL_EXPORT UserMetrics: public QObject
7132{
7233Q_OBJECT
7334
7435Q_PROPERTY(QString label READ label NOTIFY labelChanged FINAL)
7536Q_PROPERTY(QString username READ username WRITE setUsername NOTIFY usernameChanged FINAL)
76−Q_PROPERTY(QLightDM::InfographicColorTheme* firstColor READ firstColor NOTIFY firstColorChanged FINAL)
77−Q_PROPERTY(QLightDM::InfographicColorTheme* secondColor READ secondColor NOTIFY secondColorChanged FINAL)
37+Q_PROPERTY(UserMetricsOutput::ColorTheme* firstColor READ firstColor NOTIFY firstColorChanged FINAL)
38+Q_PROPERTY(UserMetricsOutput::ColorTheme* secondColor READ secondColor NOTIFY secondColorChanged FINAL)
7839Q_PROPERTY(QAbstractItemModel *firstMonth READ firstMonth NOTIFY firstMonthChanged FINAL)
7940Q_PROPERTY(QAbstractItemModel *secondMonth READ secondMonth NOTIFY secondMonthChanged FINAL)
8041Q_PROPERTY(int currentDay READ currentDay NOTIFY currentDayChanged FINAL)
8142
8243public:
83− static InfographicModel *getInstance();
44+ static UserMetrics *getInstance();
8445
85− explicit InfographicModel(QObject *parent = 0);
86− ~InfographicModel();
46+ ~UserMetrics();
8747
8848 QString label() const;
8949
@@ -91,13 +51,13 @@ public:
9151
9252 void setUsername(const QString &username);
9353
94− InfographicColorTheme * firstColor() const;
54+ ColorTheme * firstColor() const;
9555
9656 QAbstractItemModel *firstMonth() const;
9757
9858 int currentDay() const;
9959
100− InfographicColorTheme * secondColor() const;
60+ ColorTheme * secondColor() const;
10161
10262 QAbstractItemModel *secondMonth() const;
10363
@@ -106,13 +66,13 @@ Q_SIGNALS:
10666
10767 void usernameChanged(const QString &username);
10868
109− void firstColorChanged(InfographicColorTheme *color);
69+ void firstColorChanged(ColorTheme *color);
11070
11171 void firstMonthChanged(QAbstractItemModel *firstMonth);
11272
11373 void currentDayChanged(int length);
11474
115− void secondColorChanged(InfographicColorTheme *color);
75+ void secondColorChanged(ColorTheme *color);
11676
11777 void secondMonthChanged(QAbstractItemModel *secondMonth);
11878
@@ -138,13 +98,15 @@ protected Q_SLOTS:
13898 void readyForDataChangeSlot();
13999
140100protected:
141− InfographicModelPrivate * const d_ptr;
101+ UserMetricsPrivate * const d_ptr;
102+
103+ explicit UserMetrics(QObject *parent = 0);
142104
143− Q_DISABLE_COPY(InfographicModel)
144− Q_DECLARE_PRIVATE(InfographicModel)
105+ Q_DISABLE_COPY(UserMetrics)
106+ Q_DECLARE_PRIVATE(UserMetrics)
145107
146108};
147109
148110}
149111
150−#endif // LIGHTDM_INFOGRAPHICMODEL_H
112+#endif // UNITY_MOCK_USERMETRICS_H
tests/mocks/libusermetrics/libusermetricsoutput/ColorTheme.hnew file+1
@@ -0,0 +1 @@
1+../ColorTheme.h
tests/mocks/libusermetrics/libusermetricsoutput/UserMetrics.hnew file+1
@@ -0,0 +1 @@
1+../UserMetrics.h
tests/plugins/CMakeLists.txt+1
@@ -1,3 +1,4 @@
11add_subdirectory(Utils)
22add_subdirectory(Ubuntu)
3+add_subdirectory(Unity)
34add_subdirectory(ListViewWithPageHeader)
tests/plugins/ListViewWithPageHeader/listviewwithpageheadertest.cpp+6
@@ -1299,6 +1299,12 @@ private Q_SLOTS:
12991299 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
13001300 }
13011301
1302+ void testCrashShowHeaderWithNoHeader()
1303+ {
1304+ lvwph->setHeader(nullptr);
1305+ lvwph->showHeader();
1306+ }
1307+
13021308private:
13031309 QQuickView *view;
13041310 ListViewWithPageHeader *lvwph;
tests/plugins/Unity/CMakeLists.txtnew file+38
@@ -0,0 +1,38 @@
1+pkg_check_modules(UNITYCORE REQUIRED unity-core-6.0)
2+pkg_check_modules(LIBUNITYPROTO REQUIRED unity-protocol-private)
3+
4+include_directories(
5+ ${Unity-qml_SOURCE_DIR}
6+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../plugins/Unity
7+ ${CMAKE_CURRENT_BINARY_DIR}
8+ ${LIBUNITYPROTO_INCLUDE_DIRS}
9+ ${UNITYCORE_INCLUDE_DIRS}
10+ )
11+
12+macro(run_tests)
13+ set(_test_list "")
14+ foreach(_test ${ARGN})
15+ set(testCommand
16+ ${CMAKE_CURRENT_BINARY_DIR}/${_test}Exec
17+ -o ${CMAKE_BINARY_DIR}/${_test}.xml,xunitxml
18+ -o -,txt)
19+ add_test(NAME test${CLASSNAME}${_test} COMMAND ${testCommand})
20+ add_custom_target(${_test} ${testCommand})
21+ add_executable(${_test}Exec ${_test}.cpp previewbindingstest.cpp)
22+ qt5_use_modules(${_test}Exec Test Core Qml)
23+ set_tests_properties(test${CLASSNAME}${_test}
24+ PROPERTIES ENVIRONMENT LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/plugins/Unity:${LIBUNITYPROTO_LIBRARY_DIRS})
25+
26+ target_link_libraries(${_test}Exec
27+ Unity-qml
28+ ${UNITYCORE_LDFLAGS}
29+ ${LIBUNITYPROTO_LDFLAGS}
30+ )
31+
32+ set(_test_list "${_test_list};${_test}")
33+ endforeach()
34+endmacro(run_tests)
35+
36+run_tests(
37+ previewbindingstest
38+ )
tests/plugins/Unity/previewbindingstest.cppnew file+114
@@ -0,0 +1,114 @@
1+/*
2+ * Copyright (C) 2011, 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#include "previewbindingstest.h"
18+#include <QTest>
19+
20+#include <UnityCore/Preview.h>
21+#include <UnityCore/GLibWrapper.h>
22+#include <unity-protocol.h>
23+
24+#include "genericpreview.h"
25+#include "applicationpreview.h"
26+#include "moviepreview.h"
27+#include "musicpreview.h"
28+
29+void PreviewBindingsTest::initTestCase()
30+{
31+}
32+
33+void PreviewBindingsTest::testGenericPreview()
34+{
35+ auto raw_preview = (GObject *)unity_protocol_generic_preview_new();
36+ unity_protocol_preview_set_title(UNITY_PROTOCOL_PREVIEW(raw_preview), "Metallica");
37+ unity_protocol_preview_set_subtitle(UNITY_PROTOCOL_PREVIEW(raw_preview), "Ride The Lightning");
38+ unity_protocol_preview_set_description(UNITY_PROTOCOL_PREVIEW(raw_preview), "Lorem ipsum dolor sit amet");
39+ unity::glib::Object<GObject> gen_prv(raw_preview);
40+
41+ auto core_prv = unity::dash::Preview::PreviewForProtocolObject(gen_prv);
42+ auto prv = Preview::newFromUnityPreview(core_prv);
43+
44+ QCOMPARE(prv != nullptr, true);
45+ QCOMPARE(prv->title(), QString("Metallica"));
46+ QCOMPARE(prv->subtitle(), QString("Ride The Lightning"));
47+ QCOMPARE(prv->description(), QString("Lorem ipsum dolor sit amet"));
48+}
49+
50+void PreviewBindingsTest::testApplicationPreview()
51+{
52+ auto raw_preview = (GObject *)unity_protocol_application_preview_new();
53+ unity_protocol_preview_set_title(UNITY_PROTOCOL_PREVIEW(raw_preview), "Firefox");
54+ unity_protocol_preview_set_subtitle(UNITY_PROTOCOL_PREVIEW(raw_preview), "Web Browser");
55+ unity_protocol_preview_set_description(UNITY_PROTOCOL_PREVIEW(raw_preview), "Lorem ipsum dolor sit amet");
56+ unity_protocol_application_preview_set_license(UNITY_PROTOCOL_APPLICATION_PREVIEW(raw_preview), "GPL");
57+ unity_protocol_application_preview_set_rating(UNITY_PROTOCOL_APPLICATION_PREVIEW(raw_preview), 0.5f);
58+ unity_protocol_application_preview_set_num_ratings(UNITY_PROTOCOL_APPLICATION_PREVIEW(raw_preview), 4);
59+ unity::glib::Object<GObject> gen_prv(raw_preview);
60+
61+ auto core_prv = unity::dash::Preview::PreviewForProtocolObject(gen_prv);
62+ auto prv = Preview::newFromUnityPreview(core_prv);
63+ auto app_prv = dynamic_cast<ApplicationPreview*>(prv);
64+
65+ QCOMPARE(app_prv != nullptr, true);
66+ QCOMPARE(app_prv->title(), QString("Firefox"));
67+ QCOMPARE(app_prv->subtitle(), QString("Web Browser"));
68+ QCOMPARE(app_prv->description(), QString("Lorem ipsum dolor sit amet"));
69+ QCOMPARE(app_prv->license(), QString("GPL"));
70+ QCOMPARE(app_prv->rating(), 0.5f);
71+ QCOMPARE(app_prv->numRatings(), unsigned (4));
72+}
73+
74+void PreviewBindingsTest::testMoviePreview()
75+{
76+ auto raw_preview = (GObject *)unity_protocol_movie_preview_new();
77+ unity_protocol_preview_set_title(UNITY_PROTOCOL_PREVIEW(raw_preview), "Blade Runner");
78+ unity_protocol_preview_set_subtitle(UNITY_PROTOCOL_PREVIEW(raw_preview), "Ridley Scott");
79+ unity_protocol_preview_set_description(UNITY_PROTOCOL_PREVIEW(raw_preview), "Lorem ipsum dolor sit amet");
80+ unity_protocol_movie_preview_set_year(UNITY_PROTOCOL_MOVIE_PREVIEW(raw_preview), "1982");
81+ unity::glib::Object<GObject> gen_prv(raw_preview);
82+
83+ auto core_prv = unity::dash::Preview::PreviewForProtocolObject(gen_prv);
84+ auto prv = Preview::newFromUnityPreview(core_prv);
85+ auto movie_prv = dynamic_cast<MoviePreview*>(prv);
86+
87+ QCOMPARE(movie_prv != nullptr, true);
88+ QCOMPARE(movie_prv->title(), QString("Blade Runner"));
89+ QCOMPARE(movie_prv->subtitle(), QString("Ridley Scott"));
90+ QCOMPARE(movie_prv->description(), QString("Lorem ipsum dolor sit amet"));
91+ QCOMPARE(movie_prv->year(), QString("1982"));
92+}
93+
94+void PreviewBindingsTest::testMusicPreview()
95+{
96+ auto raw_preview = (GObject *)unity_protocol_music_preview_new();
97+ unity_protocol_preview_set_title(UNITY_PROTOCOL_PREVIEW(raw_preview), "Metallica");
98+ unity_protocol_preview_set_subtitle(UNITY_PROTOCOL_PREVIEW(raw_preview), "Death Magnetic");
99+ unity_protocol_preview_set_description(UNITY_PROTOCOL_PREVIEW(raw_preview), "Lorem ipsum dolor sit amet");
100+ unity::glib::Object<GObject> gen_prv(raw_preview);
101+
102+ auto core_prv = unity::dash::Preview::PreviewForProtocolObject(gen_prv);
103+ auto prv = Preview::newFromUnityPreview(core_prv);
104+ auto music_prv = dynamic_cast<MusicPreview*>(prv);
105+
106+ QCOMPARE(music_prv != nullptr, true);
107+ QCOMPARE(music_prv->title(), QString("Metallica"));
108+ QCOMPARE(music_prv->subtitle(), QString("Death Magnetic"));
109+ QCOMPARE(music_prv->description(), QString("Lorem ipsum dolor sit amet"));
110+}
111+
112+QTEST_MAIN(PreviewBindingsTest)
113+
114+#include "previewbindingstest.moc"
plugins/LightDM/InfographicModel.h → tests/plugins/Unity/previewbindingstest.hrenamed+15−8
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2012,2013 Canonical, Ltd.
2+ * Copyright (C) 2011, 2013 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -12,16 +12,23 @@
1212 *
1313 * You should have received a copy of the GNU General Public License
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− *
16− * Authors: Pete Woods <pete.woods@canonical.com>
1715 */
1816
19−#ifndef INFOGRAPHICMODEL_H
20−#define INFOGRAPHICMODEL_H
17+#ifndef PREVIEWBINDINGSTEST_H
18+#define PREVIEWBINDINGSTEST_H
19+
20+#include <QObject>
2121
22−#include <QLightDM/InfographicModel>
22+class PreviewBindingsTest : public QObject
23+{
24+ Q_OBJECT
2325
24−typedef QLightDM::InfographicModel InfographicModel;
25−typedef QLightDM::InfographicColorTheme InfographicColorTheme;
26+ private Q_SLOTS:
27+ void initTestCase();
28+ void testGenericPreview();
29+ void testApplicationPreview();
30+ void testMoviePreview();
31+ void testMusicPreview();
32+};
2633
2734#endif
tests/plugins/Utils/qlimitproxymodeltest.cpp+15
@@ -446,6 +446,7 @@ private Q_SLOTS:
446446
447447 ModelTest t1(&proxy);
448448 }
449+
449450 void testModelChanged() {
450451 QLimitProxyModelQML proxy;
451452 MockListModel model, model2;
@@ -464,6 +465,20 @@ private Q_SLOTS:
464465 proxy.setModel(&model);
465466 QCOMPARE(spyOnModelChanged.count(), 3);
466467 }
468+
469+ void setSameModelTwice() {
470+ QLimitProxyModelQML proxy;
471+ MockListModel model;
472+
473+ proxy.setModel(&model);
474+ proxy.setModel(&model);
475+
476+ QSignalSpy spyOnCountChanged(&proxy, SIGNAL(countChanged()));
477+
478+ model.insertRows(0, 5);
479+ QCOMPARE(proxy.rowCount(), 5);
480+ QCOMPARE(spyOnCountChanged.count(), 1);
481+ }
467482};
468483
469484QTEST_MAIN(QLimitProxyModelTest)
tests/qmltests/CMakeLists.txt+14−15
@@ -1,12 +1,11 @@
11# add_qml_test macro
22include(QmlTest)
33
4−add_subdirectory(plugins)
54add_subdirectory(Components)
65
76set(qmltest_DEFAULT_IMPORT_PATHS
8− ${CMAKE_CURRENT_BINARY_DIR}/plugins
97 ${CMAKE_BINARY_DIR}/tests/utils/modules
8+ ${CMAKE_BINARY_DIR}/tests/mocks
109)
1110
1211set(qmltest_DEFAULT_TARGETS qmlunittests)
@@ -43,27 +42,27 @@ add_qml_test(Dash DashBar IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${CMAKE_CURRE
4342add_qml_test(Dash DashContent IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS})
4443add_qml_test(Dash DashPreview)
4544add_qml_test(Dash GenericScopeView IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
46−add_qml_test(Dash ScopeView IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${CMAKE_CURRENT_BINARY_DIR}/plugins)
45+add_qml_test(Dash ScopeView IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
4746add_qml_test(Dash FilterGrids IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/plugins ${CMAKE_CURRENT_SOURCE_DIR}/plugins
4847 ${CMAKE_BINARY_DIR}/tests/mocks)
4948add_qml_test(Dash/Apps RunningApplicationsGrid IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/tests/mocks)
50−add_qml_test(Greeter Lockscreen IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/plugins ${CMAKE_BINARY_DIR}/tests/mocks
51− PROPERTIES ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/LightDM/full")
52−add_qml_test(Greeter Tablet IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/plugins ${CMAKE_BINARY_DIR}/tests/mocks
53− ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/LightDM/full")
54−add_qml_test(Greeter Phone IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/plugins ${CMAKE_BINARY_DIR}/tests/mocks
55− ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/LightDM/single")
56−add_qml_test(Greeter Infographics IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/plugins ${CMAKE_BINARY_DIR}/tests/mocks
57− ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/LightDM/full")
49+add_qml_test(Greeter Lockscreen IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS}
50+ PROPERTIES ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/libusermetrics:${CMAKE_BINARY_DIR}/tests/mocks/LightDM/full")
51+add_qml_test(Greeter Tablet IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS}
52+ ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/libusermetrics:${CMAKE_BINARY_DIR}/tests/mocks/LightDM/full")
53+add_qml_test(Greeter Phone IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS}
54+ ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/libusermetrics:${CMAKE_BINARY_DIR}/tests/mocks/LightDM/single")
55+add_qml_test(Greeter Infographics IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS}
56+ ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/libusermetrics:${CMAKE_BINARY_DIR}/tests/mocks/LightDM/full")
5857add_qml_test(Hud Hud)
5958add_qml_test(Hud Result)
60−add_qml_test(Launcher Launcher IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins/ ${CMAKE_BINARY_DIR}/tests/mocks/ ${qmltest_DEFAULT_IMPORT_PATHS})
61−add_qml_test(Notifications Notifications IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_CURRENT_SOURCE_DIR}/plugins)
59+add_qml_test(Launcher Launcher IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
60+add_qml_test(Notifications Notifications IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_SOURCE_DIR}/tests/mocks)
6261add_qml_test(Panel IndicatorRow)
63−add_qml_test(Panel Indicators)
62+add_qml_test(Panel Indicators IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
6463add_qml_test(Panel MenuContent)
6564add_qml_test(Panel Overview)
66−add_qml_test(Panel Panel)
65+add_qml_test(Panel Panel IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
6766add_qml_test(Panel SearchIndicator)
6867add_qml_test(Panel/Menus IndicatorMenuWindow IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS})
6968add_qml_test(SideStage SideStage IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS}
tests/qmltests/Notifications/tst_Notifications.qml+48−7
@@ -53,7 +53,10 @@ Row {
5353 icon: "../graphics/avatars/funky.png",
5454 secondaryIcon: "../graphics/applicationIcons/facebook.png",
5555 actions: [{ id: "ok_id", label: "Ok"},
56− { id: "cancel_id", label: "Cancel"}]
56+ { id: "cancel_id", label: "Cancel"},
57+ { id: "notreally_id", label: "Not really"},
58+ { id: "noway_id", label: "No way"},
59+ { id: "nada_id", label: "Nada"}]
5760 }
5861
5962 mockModel.append(n)
@@ -132,7 +135,7 @@ Row {
132135 id: interactiveControls
133136
134137 width: units.gu(30)
135− height: units.gu(71)
138+ height: units.gu(81)
136139 color: "grey"
137140
138141 Column {
@@ -193,7 +196,10 @@ Row {
193196 icon: "../graphics/avatars/funky.png",
194197 secondaryIcon: "../graphics/applicationIcons/facebook.png",
195198 actions: [{ id: "ok_id", label: "Ok"},
196− { id: "cancel_id", label: "Cancel"}],
199+ { id: "cancel_id", label: "Cancel"},
200+ { id: "notreally_id", label: "Not really"},
201+ { id: "noway_id", label: "No way"},
202+ { id: "nada_id", label: "Nada"}],
197203 summaryVisible: true,
198204 bodyVisible: true,
199205 interactiveAreaEnabled: false,
@@ -341,15 +347,50 @@ Row {
341347 var buttonAccept = findChild(buttonRow, "button0")
342348
343349 waitForRendering(notification)
344− mouseClick(buttonCancel, buttonCancel.width / 2, buttonCancel.height / 2)
345− actionSpy.wait()
346− compare(actionSpy.signalArguments[0][0], data.actions[1]["id"], "got wrong id for negative action")
347− actionSpy.clear()
348350
351+ // only test the left/cancel-button if two actions have been passed in
352+ if (data.actions.length == 2) {
353+ mouseClick(buttonCancel, buttonCancel.width / 2, buttonCancel.height / 2)
354+ actionSpy.wait()
355+ compare(actionSpy.signalArguments[0][0], data.actions[1]["id"], "got wrong id for negative action")
356+ actionSpy.clear()
357+ }
358+
359+ // click the positive/right button
349360 mouseClick(buttonAccept, buttonAccept.width / 2, buttonAccept.height / 2)
350361 actionSpy.wait()
351362 compare(actionSpy.signalArguments[0][0], data.actions[0]["id"], "got wrong id positive action")
352363 actionSpy.clear()
364+
365+ // check if there's more than one negative choice
366+ if (data.actions.length > 2) {
367+ var initialHeight = notification.height
368+
369+ // click to expand
370+ mouseClick(buttonCancel, buttonCancel.width / 2, buttonCancel.height / 2)
371+ waitForRendering(notification)
372+ actionSpy.clear()
373+ 
374+ // test the additional buttons
375+ for (var i = 2; i < data.actions.length; i++) {
376+ waitForRendering(notification)
377+ var buttonColumn = findChild(notification, "buttonColumn")
378+ var button = findChild(buttonColumn, "button" + i)
379+ mouseClick(button, button.width / 2, button.height / 2)
380+ actionSpy.wait()
381+ compare(actionSpy.signalArguments[0][0], data.actions[i]["id"], "got wrong id for additional negative action")
382+ actionSpy.clear()
383+ }
384+
385+ // click to collapse
386+ mouseClick(buttonCancel, buttonCancel.width / 2, buttonCancel.height / 2)
387+ waitForRendering(notification)
388+ tryCompare(notification, "height", initialHeight)
389+ } else {
390+ mouseClick(buttonCancel, buttonCancel.width / 2, buttonCancel.height / 2)
391+ actionSpy.wait()
392+ compare(actionSpy.signalArguments[0][0], data.actions[1]["id"], "got wrong id for negative action")
393+ }
353394 }
354395 }
355396 }
tests/qmltests/Panel/tst_Indicators.qml+34−45
@@ -42,23 +42,9 @@ Item {
4242 }
4343 width: (shell.width > units.gu(60)) ? units.gu(40) : shell.width
4444 y: 0
45− hintValue: indicatorRevealer.hintDisplacement
4645 shown: false
47− revealer: indicatorRevealer
4846
4947 openedHeight: parent.height - click_me.height
50−
51− showAnimation: NumberAnimation { property: "progress"; duration: 350; to: indicatorRevealer.openedValue; easing.type: Easing.OutCubic }
52− hideAnimation: NumberAnimation { property: "progress"; duration: 350; to: indicatorRevealer.closedValue; easing.type: Easing.OutCubic }
53− }
54−
55− Revealer {
56− anchors.fill: indicators
57− id: indicatorRevealer
58− hintDisplacement: indicators.panelHeight * 3
59−
60− openedValue: indicators.openedHeight - indicators.panelHeight
61− closedValue: indicators.panelHeight
6248 }
6349
6450 // Just a rect for clicking to open the indicators.
@@ -153,60 +139,63 @@ Item {
153139 {
154140 // tests changing the lateral position of the revealer activates the correct indicator items.
155141
156− // This "should" put the indicators in "hint" state
157− indicators.progress = indicators.hintValue;
158−
159142 var indicator_row = findChild(indicators, "indicatorRow")
160143 var row_repeater = findChild(indicators, "rowRepeater")
161144
162145 for (var i = 0; i < row_repeater.count; i++) {
163146 var indicator_item = row_repeater.itemAt(i);
164147
165− var indicator_position = indicator_row.row.x + indicator_item.x + indicator_item.width/2;
148+ var indicator_position = indicators.mapFromItem(indicator_item,
149+ indicator_item.width/2, indicator_item.height/2)
166150
167− indicatorRevealer.lateralPosition = indicator_position;
151+ touchFlick(indicators,
152+ indicator_position.x, indicator_position.y,
153+ indicator_position.x, indicators.openedHeight * 0.4,
154+ true /* beginTouch */, false /* endTouch */)
168155
169− compare(indicator_row.currentItem, indicator_item, "Incorrect item activated at position " + i);
156+ compare(indicator_row.currentItem, indicator_item,
157+ "Incorrect item activated at position " + i);
158+
159+ touchFlick(indicators,
160+ indicator_position.x, indicators.openedHeight * 0.4,
161+ indicator_position.x, indicator_position.y,
162+ false /* beginTouch */, true /* endTouch */)
163+
164+ // wait until fully closed
165+ tryCompare(indicators, "height", indicators.panelHeight)
170166 }
171167 }
172168
173− // PROGRESS TESTS
174−
175− // values for specific state changes are subject to internal decisions, so we can't determine the true progress value
176− // which would cause the state to change without making too many assuptyions
177− // However, we can assume that a partially opened panel will not be initial, and fully opened panel will be locked.
169+ // values for specific state changes are subject to internal decisions, so we can't
170+ // determine the true height value which would cause the state to change without making
171+ // too many assuptyions
172+ // However, we can assume that a partially opened panel will not be initial, and fully
173+ // opened panel will be locked.
178174
179175 function test_progress_changes_state_to_not_initial() {
180− indicators.progress = indicatorRevealer.closedValue + (indicatorRevealer.openedValue - indicatorRevealer.closedValue)/2;
181− compare(indicators.state!="initial", true, "Indicators should not be in initial state when partially opened.");
176+ indicators.height = indicators.openedHeight / 2
177+ compare(indicators.state!="initial", true,
178+ "Indicators should not be in initial state when partially opened.")
182179 }
183180
184181 function test_progress_changes_state_to_locked() {
185− indicators.progress = indicators.openedHeight;
186− compare(indicators.state, "locked", "Indicators should be locked when fully opened.");
182+ indicators.height = indicators.openedHeight - indicators.panelHeight
183+ compare(indicators.state, "locked", "Indicators should be locked when fully opened.")
187184 }
188185
189186 function test_partially_open() {
190− indicators.progress = indicatorRevealer.closedValue + (indicatorRevealer.openedValue - indicatorRevealer.closedValue)/2;
191− compare(indicators.partiallyOpened, true, "Indicator should show as partially opened when in between revealer closedValue & openedValue height");
192− compare(indicators.fullyOpened, false, "Indicator should not show as fully opened when in between revealer closedValue & openedValue height");
187+ indicators.height = indicators.openedHeight / 2
188+ compare(indicators.partiallyOpened, true,
189+ "Indicator should show as partially opened when height is half of openedHeight")
190+ compare(indicators.fullyOpened, false,
191+ "Indicator should not show as fully opened when height is half of openedHeight")
193192 }
194193
195194 function test_fully_open() {
196− indicators.progress = indicatorRevealer.openedValue
197− compare(indicators.partiallyOpened, false, "Indicator should show as fully opened when in between revealer closedValue & openedValue height");
198− compare(indicators.fullyOpened, true, "Indicator should not show as fully opened when at revealer openedValue height");
195+ indicators.height = indicators.openedHeight
196+ compare(indicators.partiallyOpened, false);
197+ compare(indicators.fullyOpened, true);
199198 }
200199
201− // The indicator menu content should be shown if the indicators are show through an animation before they
202− // enter a furthur state through a progress change (eg press indicator row, drag down a less then hint
203− // threshold and release to show
204− function test_menu_open_on_hint_drag() {
205− indicators.handlePress();
206− indicators.show()
207−
208− var menuContent = findChild(indicators, "menuContent")
209− compare(menuContent.__shown, true, "Indicator menu content should be shown after a indicator show.");
210− }
211200 }
212201}
tests/qmltests/Panel/tst_Panel.qml+65−113
@@ -78,92 +78,56 @@ Item {
7878 return panel.mapFromItem(indicator_item, indicator_item.width/2, indicator_item.height/2);
7979 }
8080
81− function test_hint_data() { return get_window_data() }
82−
8381 // Pressing on the indicator panel should activate the indicator hints
8482 // and expose a portion of the conent.
85− function test_hint(data) {
86− panel.fullscreenMode = data.fullscreenFlag;
87−
88− var indicator_item_coord = get_indicator_item_position(0);
89− var indicator_revealer = findChild(panel, "indicatorRevealer");
90− verify(indicator_revealer != undefined)
91−
92− mousePress(panel,
93− indicator_item_coord.x, panel.panelHeight/2,
94− Qt.LeftButton, Qt.NoModifier , 0);
95−
96− if (!panel.fullscreenMode)
97− {
98− compare(indicator_revealer.hintingAnimation.running, true, "Indicator revealer hint animation should be running after mouse press on indicator panel in pinned mode");
99− tryCompare(indicator_revealer.hintingAnimation, "running", false);
100− tryCompare(panel.indicators, "partiallyOpened", true);
101− }
102− else
103− {
104− // nothing should happen
105− compare(indicator_revealer.hintingAnimation.running, false, "Indicator revealer hint animation should not be running after mouse press on indicator panel in fullscreen mode");
106− compare(panel.indicators.partiallyOpened, false, "Indicator should not be partially opened when panel is pressed in fullscreenmode");
107− compare(panel.indicators.fullyOpened, false, "Indicator should not be partially opened when panel is pressed in fullscreenmode");
108− }
109−
110− mouseRelease(panel,
111− indicator_item_coord.x, panel.panelHeight/2,
112− Qt.LeftButton, Qt.NoModifier , 0);
113− }
114−
115− function test_show_click_data() { return get_window_data() }
116−
117− // Clicking the indicator panel should fully open the inidicators
118− function test_show_click(data) {
119− panel.fullscreenMode = data.fullscreenFlag;
83+ function test_hint() {
84+ panel.fullscreenMode = false;
85+ // Wait for the indicators to get into position.
86+ // (switches between normal and fullscreen modes are animated)
87+ tryCompare(panel.indicators, "y", 0)
12088
12189 var indicator_item_coord = get_indicator_item_position(0);
12290
123− mouseClick(panel,
124− indicator_item_coord.x, panel.panelHeight/2,
125− Qt.LeftButton, Qt.NoModifier , 0);
91+ touchPress(panel, indicator_item_coord.x, panel.panelHeight / 2)
12692
127− if (!panel.fullscreenMode)
128− {
129− compare(panel.indicators.showAnimation.running, true, "Show animation should run after panel is clicked in pinned mode.");
130− tryCompare(panel.indicators, "fullyOpened", true);
93+ // hint animation should be run, meaning that indicators will move downwards
94+ // by hintValue pixels without any drag taking place
95+ tryCompare(panel.indicators, "height",
96+ panel.indicators.panelHeight + panel.indicators.hintValue);
97+ tryCompare(panel.indicators, "partiallyOpened", true);
98+ tryCompare(panel.indicators, "fullyOpened", false);
13199
132− // click will activate device overview.
133− compare(findChild(panel.indicators, "indicatorRow").overviewActive, true, "Overview indicator should be avtive when indicators clicked.")
134− }
135− else
136− {
137− compare(panel.indicators.showAnimation.running, false, "Indicators should not open when panel is clicked in pinned mode.");
138− }
100+ touchRelease(panel, indicator_item_coord.x, panel.panelHeight/2)
139101 }
140102
141− function test_show_press_release_data() { return get_window_data() }
142−
143− // Pressing and releasing on the indicator panel will fully open the indicators
144− function test_show_press_release(data) {
145− panel.fullscreenMode = data.fullscreenFlag;
103+ // Pressing on the top edge of the screen should have no effect if the panel
104+ // is hidden (!pinned), which is the case when a fullscreen app is being shown
105+ function test_noHintOnFullscreenMode() {
106+ panel.fullscreenMode = true;
107+ // Wait for the indicators to get into position.
108+ // (switches between normal and fullscreen modes are animated)
109+ tryCompare(panel.indicators, "y", -panel.panelHeight)
146110
147111 var indicator_item_coord = get_indicator_item_position(0);
148112
149− mousePress(panel,
150− indicator_item_coord.x, panel.panelHeight/2,
151− Qt.LeftButton, Qt.NoModifier , 0);
113+ touchPress(panel, indicator_item_coord.x, panel.panelHeight / 2)
152114
153− mouseRelease(panel,
154− indicator_item_coord.x, panel.panelHeight/2,
155− Qt.LeftButton, Qt.NoModifier , 0);
115+ // Give some time for a hint animation to change things, if any
116+ wait(500)
156117
157− if (!panel.fullscreenMode)
158− {
159− compare(panel.indicators.showAnimation.running, true, "Show animation should run after panel is clicked in pinned mode.");
160− tryCompare(panel.indicators, "fullyOpened", true);
161− }
162− else
163− {
164− // nothing should happen.
165− compare(panel.indicators.showAnimation.running, false, "Indicators should not open when panel is clicked in pinned mode.");
166− }
118+ // no hint animation when fullscreen
119+ compare(panel.indicators.y, -panel.panelHeight)
120+ var indicatorRow = findChild(panel.indicators, "indicatorRow");
121+ verify(indicatorRow != undefined)
122+ compare(indicatorRow.y, 0)
123+ compare(panel.indicators.height, panel.indicators.panelHeight)
124+ compare(panel.indicators.partiallyOpened, false,
125+ "Indicator should not be partially opened when panel is pressed in" +
126+ " fullscreenmode")
127+ compare(panel.indicators.fullyOpened, false, "Indicator should not be partially" +
128+ " opened when panel is pressed in fullscreenmode")
129+
130+ touchRelease(panel, indicator_item_coord.x, panel.panelHeight/2)
167131 }
168132
169133 function test_drag_show_data() { return get_window_data() }
@@ -174,9 +138,6 @@ Item {
174138 function test_drag_show(data) {
175139 panel.fullscreenMode = data.fullscreenFlag;
176140
177− var indicator_revealer = findChild(panel, "indicatorRevealer");
178− verify(indicator_revealer != undefined)
179−
180141 var indicator_row = findChild(panel.indicators, "indicatorRow");
181142 verify(indicator_row != undefined)
182143
@@ -186,6 +147,14 @@ Item {
186147 var menu_content = findChild(panel.indicators, "menuContent");
187148 verify(indicator_row != undefined)
188149
150+ // Wait for the indicators to get into position.
151+ // (switches between normal and fullscreen modes are animated)
152+ if (data.fullscreenFlag) {
153+ tryCompare(panel.indicators, "y", -panel.panelHeight)
154+ } else {
155+ tryCompare(panel.indicators, "y", 0)
156+ }
157+
189158 // do this for each indicator item
190159 for (var i = 0; i < row_repeater.count; i++) {
191160
@@ -194,40 +163,25 @@ Item {
194163
195164 var indicator_item_coord = get_indicator_item_position(i);
196165
197− // 1) Press on the panel
198− mousePress(panel,
199− indicator_item_coord.x, panel.panelHeight/2,
200− Qt.LeftButton, Qt.NoModifier , 0);
201−
202− if (!panel.fullscreenMode)
203− {
204− // hint animation should be run, and panel will end in partiallyOpened state.
205− compare(indicator_revealer.hintingAnimation.running, true, "Indicator revealer hint animation should be running after mouse press on indicator panel");
206− tryCompare(indicator_revealer.hintingAnimation, "running", false);
207− tryCompare(panel.indicators, "partiallyOpened", true);
208− }
209−
210− // 2) Drag the mouse down
211− var old_progress = panel.indicators.progress
212− mouseMove(panel,
213− indicator_item_coord.x, old_progress + (panel.height - old_progress)/2,
214− 0, Qt.LeftButton);
215−
216− // progress should increase.
217− var progress_increases = panel.indicators.progress > old_progress;
218− compare(progress_increases, true, "Progress has not increased on dragging indicator.");
166+ touchPress(panel,
167+ indicator_item_coord.x, panel.panelHeight / 2)
219168
220− mouseMove(panel,
221− indicator_item_coord.x, shell.y + shell.height,
222− 0, Qt.LeftButton);
169+ // 1) Drag the mouse down
170+ touchFlick(panel,
171+ indicator_item_coord.x, panel.panelHeight / 2,
172+ indicator_item_coord.x, panel.height * 0.8,
173+ false /* beginTouch */, false /* endTouch */)
223174
224− tryCompare(panel.indicators, "fullyOpened", true);
175+ // Indicators height should follow the drag, and therefore increase accordingly.
176+ // They should be at least half-way through the screen
177+ tryCompareFunction(
178+ function() {return panel.indicators.height >= panel.height * 0.5},
179+ true)
225180
226− mouseRelease(panel,
227− indicator_item_coord.x, indicator_item_coord.y + panel.height/2,
228− Qt.LeftButton, Qt.NoModifier , 0);
181+ touchRelease(panel, indicator_item_coord.x, panel.height * 0.8)
229182
230− compare(indicator_row.currentItem, indicator_item, "Incorrect item activated at position " + i);
183+ compare(indicator_row.currentItem, indicator_item,
184+ "Incorrect item activated at position " + i)
231185 compare(menu_content.__shown, true, "Menu conetent should be enabled for item at position " + i);
232186
233187 // init for next indicator_item
@@ -242,11 +196,10 @@ Item {
242196 var search_indicator = findChild(panel, "search");
243197 verify(search_indicator != undefined);
244198
245− mouseClick(search_indicator,
246− 1, 1,
247− Qt.LeftButton, Qt.NoModifier , 0);
199+ tap(search_indicator, 1, 1)
248200
249− compare(search_clicked, true, "Clicking search indicator while it was enabled did not emit searchClicked signal")
201+ compare(search_clicked, true,
202+ "Tapping search indicator while it was enabled did not emit searchClicked signal")
250203 }
251204
252205 function test_search_click_when_not_visible() {
@@ -256,11 +209,10 @@ Item {
256209 var search_indicator = findChild(panel, "search");
257210 verify(search_indicator != undefined);
258211
259− mouseClick(search_indicator,
260− 1, 1,
261− Qt.LeftButton, Qt.NoModifier , 0);
212+ tap(search_indicator, 1, 1)
262213
263− compare(search_clicked, false, "Clicking search indicator while it was not visible emitted searchClicked signal")
214+ compare(search_clicked, false,
215+ "Tapping search indicator while it was not visible emitted searchClicked signal")
264216 }
265217 }
266218}
tests/qmltests/plugins/CMakeLists.txtdeleted−3
@@ -1,3 +0,0 @@
1−add_subdirectory(HudClient)
2−add_subdirectory(Ubuntu)
3−add_subdirectory(Unity)
tests/qmltests/plugins/Dee/qmldirdeleted−3
@@ -1,3 +0,0 @@
1−module Dee
2−
3−DeeVariantText 3.0 DeeVariantText.qml
tests/qmltests/plugins/Ubuntu/CMakeLists.txtdeleted−1
@@ -1 +0,0 @@
1−add_subdirectory(ChewieUI)
tests/qmltests/plugins/Unity/CMakeLists.txtdeleted−43
@@ -1,43 +0,0 @@
1−set(CMAKE_AUTOMOC ON)
2−
3−include(FindPkgConfig)
4−find_package(Qt5Core REQUIRED)
5−find_package(Qt5Quick REQUIRED)
6−pkg_search_module(DEE dee-1.0 REQUIRED)
7−pkg_search_module(GOBJECT gobject-2.0 REQUIRED)
8−pkg_search_module(DEEQT libdee-qt5 REQUIRED)
9−
10−include_directories(
11− ${CMAKE_SOURCE_DIR}/plugins/Unity
12− ${CMAKE_CURRENT_BINARY_DIR}
13− ${Qt5Core_INCLUDE_DIRS}
14− ${Qt5Quick_INCLUDE_DIRS}
15− ${DEE_INCLUDE_DIRS}
16− ${DEEQT_INCLUDE_DIRS}
17−)
18−
19−add_definitions(-DQT_NO_KEYWORDS)
20−
21−set(UnityQML_SOURCES
22− ${CMAKE_SOURCE_DIR}/plugins/Unity/categories.cpp
23− ${CMAKE_SOURCE_DIR}/plugins/Unity/categoryfilter.cpp
24− ${CMAKE_SOURCE_DIR}/plugins/Utils/qsortfilterproxymodelqml.cpp
25− fake_scope.cpp
26− fake_scopes.cpp
27− fake_unity_plugin.cpp
28−)
29−
30−add_library(FakeUnityQml MODULE ${UnityQML_SOURCES})
31−target_link_libraries(FakeUnityQml
32− ${Qt5Core_LIBRARIES}
33− ${Qt5Quick_LIBRARIES}
34− ${DEEQT_LDFLAGS}
35− ${GOBJECT_LDFLAGS}
36−)
37−
38−qt5_use_modules(FakeUnityQml Qml)
39−
40−# copy qmldir file into build directory for shadow builds
41−file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/qmldir"
42− DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
43− )