on xenial help sign in
Merge trunk.
commit855960ade1a36d8c4e1e6260e6b12ee6c35c1826 authorMichał Sawicz <michal.sawicz@canonical.com> dateFri 23 May 2014, 00:38 (12 years ago) parent0a9e4a7fed3e2a
293 files changed+4794−4381
CMakeLists.txt+5−5 CODING+11−15 build → build.sh+1−2 cmake/modules/Plugins.cmake−68 cmake/modules/QmlPlugins.cmake+143 cmake/modules/QmlTest.cmake+2−4 data/CMakeLists.txt+1−2 data/unity-scope-tool.desktop.in−8 data/unity8.conf+9−1 debian/changelog+181 debian/control+41−30 debian/rules+1−2 debian/unity-scope-tool.install−1 debian/unity8-common.install+5 debian/unity8-fake-env.install+1−1 debian/unity8-private.install+1−1 debian/unity8.install+1−7 plugins/AccountsService/CMakeLists.txt+1−4 plugins/AccountsService/qmldir+1−1 plugins/CMakeLists.txt+14−1 plugins/DashViews/CMakeLists.txt → plugins/Dash/CMakeLists.txt+4−9 plugins/Dash/CardCreator.js+520 plugins/Dash/CardCreatorCache.qml+40 plugins/DashViews/abstractdashview.cpp → plugins/Dash/abstractdashview.cpp+18−82 plugins/DashViews/abstractdashview.h → plugins/Dash/abstractdashview.h+14−37 plugins/DashViews/horizontaljournal.cpp → plugins/Dash/horizontaljournal.cpp−12 plugins/DashViews/horizontaljournal.h → plugins/Dash/horizontaljournal.h−4 plugins/DashViews/listviewwithpageheader.cpp → plugins/Dash/listviewwithpageheader.cpp−50 plugins/DashViews/listviewwithpageheader.h → plugins/Dash/listviewwithpageheader.h−20 plugins/DashViews/organicgrid.cpp → plugins/Dash/organicgrid.cpp−8 plugins/DashViews/organicgrid.h → plugins/Dash/organicgrid.h−4 plugins/DashViews/plugin.cpp → plugins/Dash/plugin.cpp+2−2 plugins/DashViews/plugin.h → plugins/Dash/plugin.h+3−3 plugins/Dash/qmldir+4 plugins/DashViews/verticaljournal.cpp → plugins/Dash/verticaljournal.cpp−8 plugins/DashViews/verticaljournal.h → plugins/Dash/verticaljournal.h−4 plugins/DashViews/qmldir−3 plugins/HudClient/CMakeLists.txt+1−6 plugins/HudClient/qmldir+1−1 plugins/LightDM/CMakeLists.txt+1−6 plugins/LightDM/qmldir+1−1 plugins/Powerd/CMakeLists.txt+1−3 plugins/Powerd/qmldir+1−1 plugins/SessionBroadcast/CMakeLists.txt+1−4 plugins/SessionBroadcast/qmldir+1−1 plugins/Ubuntu/DownloadDaemonListener/CMakeLists.txt+1−6 plugins/Ubuntu/DownloadDaemonListener/qmldir+1−1 plugins/Ubuntu/Gestures/CMakeLists.txt+1−6 plugins/Ubuntu/Gestures/qmldir+1−1 plugins/Unity/Indicators/CMakeLists.txt+4−7 plugins/Unity/Indicators/menucontentactivator.cpp−1 plugins/Unity/Indicators/qml/CMakeLists.txt−5 plugins/Unity/Indicators/qml/MenuItemFactory.qml+1−1 plugins/Unity/Indicators/qml/qmldir+1−1 plugins/Unity/Indicators/rootactionstate.cpp+7−8 plugins/Unity/Launcher/CMakeLists.txt+1−3 plugins/Unity/Launcher/backend/launcherbackend.cpp+293−29 plugins/Unity/Launcher/backend/launcherbackend.h+52−4 plugins/Unity/Launcher/qmldir+1−1 plugins/Utils/CMakeLists.txt+1−4 plugins/Utils/bottombarvisibilitycommunicatorshell.cpp−49 plugins/Utils/bottombarvisibilitycommunicatorshell.h−59 plugins/Utils/plugin.cpp−10 plugins/Utils/qmldir+1−1 po/am.po+9−13 po/ar.po+9−27 po/ast.po+9−5 po/az.po+9−22 po/bg.po+9−5 po/br.po+9−5 po/bs.po+9−7 po/ca.po+16−29 po/ckb.po+9−22 po/cs.po+9−23 po/da.po+9−6 po/de.po+20−33 po/el.po+9−22 po/en_AU.po+9−22 po/en_GB.po+9−22 po/eo.po+9−6 po/es.po+10−6 po/eu.po+9−5 po/fa.po+9−6 po/fi.po+10−6 po/fo.po+9−6 po/fr.po+30−34 po/gd.po+22−36 po/gl.po+10−6 po/he.po+19−30 po/hi.po+9−9 po/hr.po+9−7 po/hu.po+9−22 po/hy.po+9−6 po/id.po+9−6 po/is.po+9−22 po/it.po+9−22 po/ja.po+9−13 po/km.po+12−24 po/kn.po+9−6 po/ko.po+9−6 po/ky.po+9−6 po/lo.po+9−13 po/lt.po+15−30 po/lv.po+27−24 po/ml.po+10−23 po/mr.po+9−6 po/ms.po+9−22 po/my.po+9−13 po/nb.po+41−36 po/nl.po+9−22 po/pl.po+9−24 po/pt.po+9−6 po/pt_BR.po+20−31 po/ro.po+9−7 po/ru.po+10−6 po/shn.po+9−6 po/si.po+9−6 po/sl.po+9−25 po/sq.po+9−16 po/sr.po+9−7 po/sv.po+9−6 po/sw.po+9−9 po/ta.po+10−23 po/te.po+9−6 po/tr.po+13−26 po/ug.po+12−8 po/uk.po+20−33 po/unity8.pot+7−3 po/vi.po+9−6 po/xh.po+9−6 po/zh_CN.po+37−34 po/zh_HK.po+9−21 po/zh_TW.po+9−21 qml/Bottombar/Bottombar.qml−227 qml/Bottombar/HudButton.qml−64 qml/Bottombar/graphics/hud@20.png qml/Bottombar/graphics/hud_invoke_button_active@20.png qml/CMakeLists.txt−1 qml/Components/FilterGrid.qml+39−26 qml/Components/LazyImage.qml+1 qml/Components/PageHeader.qml+1−1 qml/Components/ResponsiveGridView.qml+3−3 qml/Components/Revealer.qml−241 qml/Components/ZoomableImage.qml+153 qml/Dash/Card.qml−236 qml/Dash/CardCarousel.qml+25−13 qml/Dash/CardFilterGrid.qml+24−26 qml/Dash/CardHeader.qml−126 qml/Dash/CardTool.qml+30−22 qml/Dash/DashContent.qml+19−11 qml/Dash/DashRenderer.qml+8−9 qml/Dash/GenericScopeView.qml+24−25 qml/Dash/PreviewListView.qml+2−2 qml/Dash/Previews/PreviewHeader.qml+86−9 qml/Dash/Previews/PreviewProgress.qml+3−2 qml/Dash/Previews/PreviewRatingInput.qml+2−2 qml/Dash/Previews/PreviewTextSummary.qml+4−2 qml/Dash/Previews/PreviewZoomableImage.qml+4−7 qml/Dash/ScopeListView.qml+1−1 qml/Dash/graphics/carousel_dropshadow@27.png qml/Dash/graphics/carousel_dropshadow@27.sci+5 qml/Greeter/Clock.qml+3−6 qml/Greeter/Greeter.qml+115−42 qml/Greeter/GreeterContent.qml+1−10 qml/Greeter/Infographics.qml+3 qml/Hud/Hud.qml+1−1 qml/Notifications/Notifications.qml+11 qml/ScopeTool.qml+1−1 qml/Shell.qml+79−92 qml/graphics/dropshadow_left@20.png qml/Hud/graphics/dropshadow_right@20.png → qml/graphics/dropshadow_right@20.png run → run.sh+1−1 run_on_device → run_on_device.sh+2−2 src/ApplicationArguments.h+4−8 src/main.cpp+43−6 tests/autopilot/unity8/process_helpers.py+11−4 tests/autopilot/unity8/shell/__init__.py+50−1 tests/autopilot/unity8/shell/emulators/dash.py+3−4 tests/autopilot/unity8/shell/tests/test_emulators.py+1−1 tests/autopilot/unity8/shell/tests/test_notifications.py+97−57 tests/autopilot/unity8/shell/tests/test_upstart.py+2−2 tests/mocks/AccountsService/CMakeLists.txt+1−12 tests/mocks/AccountsService/qmldir+1 tests/mocks/CMakeLists.txt+30 tests/mocks/GSettings.1.0/CMakeLists.txt+1−4 tests/mocks/GSettings.1.0/qmldir+1 tests/mocks/HudClient/CMakeLists.txt+1−4 tests/mocks/HudClient/qmldir+2 tests/mocks/LightDM/CMakeLists.txt+5−12 tests/mocks/LightDM/qmldir+1 tests/mocks/Powerd/CMakeLists.txt+1−12 tests/mocks/Powerd/qmldir+1 tests/mocks/QMenuModel/CMakeLists.txt+2−12 tests/mocks/QMenuModel/qmldir+1 tests/mocks/QtMultimedia/CMakeLists.txt+1−12 tests/mocks/QtMultimedia/qmldir+1 tests/mocks/Ubuntu/DownloadDaemonListener/CMakeLists.txt+1−9 tests/mocks/Ubuntu/DownloadDaemonListener/qmldir+1 tests/mocks/Ubuntu/Thumbnailer/CMakeLists.txt+1−7 tests/mocks/Ubuntu/Thumbnailer/qmldir+2 tests/mocks/Unity/Application/CMakeLists.txt+9−35 tests/mocks/Unity/Application/qmldir+2 tests/mocks/Unity/CMakeLists.txt+9−12 tests/mocks/Unity/Indicators/CMakeLists.txt+1−14 tests/mocks/Unity/Indicators/qml/FakeMenuPage.qml → tests/mocks/Unity/Indicators/FakeMenuPage.qml tests/mocks/Unity/Indicators/qmldir+1 tests/mocks/Unity/Launcher/CMakeLists.txt+1−5 tests/mocks/Unity/Launcher/qmldir+1 tests/mocks/Unity/Notifications/CMakeLists.txt+1−11 tests/mocks/Unity/Notifications/qmldir+1 tests/mocks/Unity/fake_categories.cpp+21−24 tests/mocks/Unity/fake_categories.h+5−18 tests/mocks/Unity/fake_previewmodel.cpp+2−15 tests/mocks/Unity/fake_previewmodel.h+7−25 tests/mocks/Unity/fake_previewstack.cpp+3−11 tests/mocks/Unity/fake_previewstack.h+6−17 tests/mocks/Unity/fake_previewwidgetmodel.cpp+2−10 tests/mocks/Unity/fake_previewwidgetmodel.h+3−12 tests/mocks/Unity/fake_resultsmodel.cpp+2−44 tests/mocks/Unity/fake_resultsmodel.h+5−37 tests/mocks/Unity/fake_scope.cpp+3−14 tests/mocks/Unity/fake_scope.h+26−72 tests/mocks/Unity/fake_scopes.cpp+11−22 tests/mocks/Unity/fake_scopes.h+7−24 tests/mocks/Unity/fake_unity_plugin.cpp+3−2 tests/mocks/Unity/qmldir+1 tests/plugins/CMakeLists.txt+1−1 tests/plugins/Dash/CMakeLists.txt+79 tests/plugins/Dash/cardcreator/1.res+79 tests/plugins/Dash/cardcreator/1.tst+3 tests/plugins/Dash/cardcreator/2.res+116 tests/plugins/Dash/cardcreator/2.tst+3 tests/plugins/Dash/cardcreator/3.res+96 tests/plugins/Dash/cardcreator/3.tst+3 tests/plugins/Dash/cardcreator/4.res+96 tests/plugins/Dash/cardcreator/4.tst+3 tests/plugins/Dash/cardcreator/5.res+139 tests/plugins/Dash/cardcreator/5.tst+3 tests/plugins/Dash/cardcreatortest.cpp+91 tests/plugins/Dash/cardcreatortest.qml+29 tests/plugins/DashViews/horizontaljournaltest.cpp → tests/plugins/Dash/horizontaljournaltest.cpp+6−6 tests/plugins/DashViews/horizontaljournaltest.qml → tests/plugins/Dash/horizontaljournaltest.qml+1−1 tests/plugins/DashViews/horizontaljournaltry.cpp → tests/plugins/Dash/horizontaljournaltry.cpp tests/plugins/DashViews/horizontaljournaltry.qml → tests/plugins/Dash/horizontaljournaltry.qml+1−1 tests/plugins/DashViews/listviewwithpageheadertestsectionexternalmodel.cpp → tests/plugins/Dash/listviewwithpageheadersectionexternalmodeltest.cpp+1−5 tests/plugins/DashViews/listviewwithpageheadertestsection.cpp → tests/plugins/Dash/listviewwithpageheadersectiontest.cpp+1−13 tests/plugins/DashViews/listviewwithpageheadertest.cpp → tests/plugins/Dash/listviewwithpageheadertest.cpp−15 tests/plugins/DashViews/listviewwithpageheadertest.qml → tests/plugins/Dash/listviewwithpageheadertest.qml+1−1 tests/plugins/DashViews/listviewwithpageheadertestsection.qml → tests/plugins/Dash/listviewwithpageheadertestsection.qml+1−1 tests/plugins/DashViews/listviewwithpageheadertestsectionexternalmodel.qml → tests/plugins/Dash/listviewwithpageheadertestsectionexternalmodel.qml+1−1 tests/plugins/DashViews/organicgridtest.cpp → tests/plugins/Dash/organicgridtest.cpp+2−5 tests/plugins/DashViews/organicgridtest.qml → tests/plugins/Dash/organicgridtest.qml+1−1 tests/plugins/DashViews/organicgridtry.cpp → tests/plugins/Dash/organicgridtry.cpp tests/plugins/DashViews/organicgridtry.qml → tests/plugins/Dash/organicgridtry.qml+1−1 tests/plugins/DashViews/tst_listviewwithpageheaderqml.qml → tests/plugins/Dash/tst_ListViewWithPageHeaderQML.qml+1−1 tests/plugins/DashViews/verticaljournaltest.cpp → tests/plugins/Dash/verticaljournaltest.cpp+6−6 tests/plugins/DashViews/verticaljournaltest.qml → tests/plugins/Dash/verticaljournaltest.qml+1−1 tests/plugins/DashViews/verticaljournaltry.cpp → tests/plugins/Dash/verticaljournaltry.cpp tests/plugins/DashViews/verticaljournaltry.qml → tests/plugins/Dash/verticaljournaltry.qml+1−1 tests/plugins/DashViews/CMakeLists.txt−84 tests/plugins/Ubuntu/Gestures/CMakeLists.txt+1 tests/plugins/Unity/Indicators/rootactionstatetest.cpp+37 tests/plugins/Unity/Launcher/CMakeLists.txt+3−3 tests/plugins/Unity/Launcher/launcherbackendtest.cpp+167 tests/plugins/Utils/CMakeLists.txt+2−1 tests/qmltests/CMakeLists.txt+5−5 tests/qmltests/Components/CMakeLists.txt+1 tests/qmltests/Components/RevealingRectangle.qml−78 tests/qmltests/Components/tst_FilterGrid.qml+1−1 tests/qmltests/Components/tst_PageHeaderLabel.qml+4−4 tests/qmltests/Components/tst_Revealer.qml−262 tests/qmltests/Components/tst_ZoomableImage.qml+192 tests/qmltests/Dash/Previews/tst_Preview.qml+1−1 tests/qmltests/Dash/Previews/tst_PreviewHeader.qml+66−4 tests/qmltests/Dash/Previews/tst_PreviewRatingInput.qml+21−2 tests/qmltests/Dash/Previews/tst_PreviewTextSummary.qml+5−5 tests/qmltests/Dash/Previews/tst_PreviewZoomableImage.qml+6−3 tests/qmltests/Dash/tst_Card.qml+78−92 tests/qmltests/Dash/tst_CardBenchmark.qml+10−7 tests/qmltests/Dash/tst_CardHeader.qml−116 tests/qmltests/Dash/tst_CardTool.qml+11−31 tests/qmltests/Dash/tst_Dash.qml+1−1 tests/qmltests/Dash/tst_DashContent.qml+5−5 tests/qmltests/Dash/tst_GenericScopeView.qml+14−14 tests/qmltests/Greeter/tst_Clock.qml+3−3 tests/qmltests/Greeter/tst_Phone.qml+10−50 tests/qmltests/Greeter/tst_Tablet.qml+36−8 tests/qmltests/Panel/Indicators/tst_MenuItemFactory.qml+29−4 tests/utils/modules/Unity/Test/CMakeLists.txt+4−7 tests/utils/modules/Unity/Test/UnityTestCase.qml+26 tests/utils/modules/Unity/Test/qmldir+2 tools/registry-tracker.cpp+33−26 tools/unlock-device+2−4
CMakeLists.txt+5−5
@@ -48,11 +48,11 @@ add_custom_target(cppcheck COMMAND cppcheck --enable=all -q --error-exitcode=2
4848 ${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/tests)
4949
5050include(FindPkgConfig)
51−find_package(Qt5Core)
52−find_package(Qt5Qml)
53−find_package(Qt5Quick)
54−find_package(Qt5Gui)
55−find_package(Qt5DBus)
51+find_package(Qt5Core 5.2 REQUIRED)
52+find_package(Qt5Qml 5.2 REQUIRED)
53+find_package(Qt5Quick 5.2 REQUIRED)
54+find_package(Qt5Gui 5.2 REQUIRED)
55+find_package(Qt5DBus 5.2 REQUIRED)
5656
5757# Standard install paths
5858include(GNUInstallDirs)
CODING+11−15
@@ -20,7 +20,7 @@ install dependencies
2020If its your first time, install build dependencies
2121
2222$ cd ~/unity8/trunk
23−$ ./build --setup
23+$ ./build.sh --setup
2424
2525 this will:
2626 - install the required dependencies to build, as well as run on the desktop
@@ -31,7 +31,7 @@ build Unity 8
3131-------------
3232
3333$ cd ~/unity8/trunk
34−$ ./build
34+$ ./build.sh
3535
3636You may also rebuild with the -c for clean, which just deletes the build
3737directory.
@@ -43,10 +43,10 @@ Running Unity 8 on your desktop
4343run the Unity 8 shell
4444---------------------
4545$ cd ~/unity8/trunk
46−$ ./run
46+$ ./run.sh
4747
4848Options can be passed to test the lock screen
49−$ ./run -p OR -k
49+$ ./run.sh -p OR -k
5050
5151-p is for pin lock, for which the default prompt answer is "1234"
5252-k is for keylock passphrase, for which the default prompt answer is "password"
@@ -78,19 +78,19 @@ Running Unity 8 on devices
7878 on the device yourself)
7979
8080$ cd ~/unity/trunk
81−$ ./run_on_device --setup
81+$ ./run_on_device.sh --setup
8282 this will:
8383 - install your public SSH key on the device
8484 - install the needed dependencies
8585
86−$ ./run_on_device
86+$ ./run_on_device.sh
8787 this will:
8888 - rsync the code to the device
8989 - build on the device
9090 - replace the running shell
9191
9292Options can be passed to test the lock screen
93−$ ./run_on_device -p OR -k
93+$ ./run_on_device.sh -p OR -k
9494
9595-p is for pin lock, for which the default prompt answer is "1234"
9696-k is for keylock passphrase, for which the default prompt answer is "password"
@@ -107,9 +107,9 @@ Notes
107107- exporting ANDROID_SERIAL=$your_device_serial or
108108 ANDROID_SERIAL=$your_device_ip:5555 will make adb not complain about
109109 multiple devices
110−- you can export TARGET_IP=$your_device_ip TARGET_SSH_PORT=22 for run_on_device
110+- you can export TARGET_IP=$your_device_ip TARGET_SSH_PORT=22 for run_on_device.sh
111111 to not use adb forwarding - useful if you use multiple devices
112−- using Ninja (package ninja-build - run_on_device -s installs this now)
112+- using Ninja (package ninja-build - run_on_device.sh -s installs this now)
113113 will improve build times (especially in the nothing-to-build case)
114114
115115
@@ -131,7 +131,7 @@ Running tests
131131=============
132132
133133Tests are run from the build directory (which will be ./builddir if you used
134−the ./build script).
134+the ./build.sh script).
135135
136136To run the tests that do not require any graphical capability and therefore
137137are pretty fast run:
@@ -167,15 +167,11 @@ NB: Manual test or interation doesn't make sense for all components or classes,
167167particularly the non-graphical ones. In such cases no "tryFoo" make target is
168168provided.
169169
170−NB: The tests expect the locale to be the C locale, they may fail if run
171−under a different locale, if you get failures others can not reproduce
172−prepend 'LC_ALL=C' to the 'make test' command
173−
174170Running autopilot tests
175171=======================
176172
177173Autopilot tests are run from the build directory (which will be ./builddir if you used
178−the ./build script).
174+the ./build.sh script).
179175
180176$ make autopilot
181177
build → build.shrenamed+1−2
@@ -43,13 +43,12 @@ install_dependencies() {
4343 gsettings-desktop-schemas \
4444 gsettings-ubuntu-schemas \
4545 qmenumodel-qml \
46− qtdeclarative5-dee-plugin \
46+ qml-module-qtquick-xmllistmodel \
4747 qtdeclarative5-gsettings1.0 \
4848 qtdeclarative5-ubuntu-ui-toolkit-plugin \
4949 qtdeclarative5-ubuntu-settings-components \
5050 qtdeclarative5-ubuntu-thumbnailer0.1 \
5151 unity-notifications-impl \
52− qtdeclarative5-xmllistmodel-plugin \
5352 unity-scope-home \
5453 unity-lens-applications \
5554 unity-plugin-scopes \
cmake/modules/Plugins.cmakedeleted−68
@@ -1,68 +0,0 @@
1−find_program(qmlplugindump_exe qmlplugindump)
2−
3−if(NOT qmlplugindump_exe)
4− msg(FATAL_ERROR "Could not locate qmlplugindump.")
5−endif()
6−
7−# Creates target for copying and installing qmlfiles
8−#
9−# export_qmlfiles(plugin sub_path)
10−#
11−#
12−# Target to be created:
13−# - plugin-qmlfiles - Copies the qml files (*.qml, *.js, qmldir) into the shadow build folder.
14−
15−macro(export_qmlfiles PLUGIN PLUGIN_SUBPATH)
16−
17− file(GLOB QMLFILES
18− *.qml
19− *.js
20− qmldir
21− )
22−
23− # copy the qmldir file
24− add_custom_target(${PLUGIN}-qmlfiles ALL
25− COMMAND cp ${QMLFILES} ${CMAKE_BINARY_DIR}/plugins/${PLUGIN_SUBPATH}
26− DEPENDS ${QMLFILES}
27− SOURCES ${QMLFILES}
28− )
29−
30− # install the qmlfiles file.
31− install(FILES ${QMLFILES}
32− DESTINATION ${SHELL_INSTALL_QML}/${PLUGIN_SUBPATH}
33− )
34−endmacro(export_qmlfiles)
35−
36−
37−# Creates target for generating the qmltypes file for a plugin and installs plugin files
38−#
39−# export_qmlplugin(plugin version sub_path [TARGETS target1 [target2 ...]])
40−#
41−# TARGETS additional install targets (eg the plugin shared object)
42−#
43−# Target to be created:
44−# - plugin-qmltypes - Generates the qmltypes file in the shadow build folder.
45−
46−macro(export_qmlplugin PLUGIN VERSION PLUGIN_SUBPATH)
47− set(multi_value_keywords TARGETS)
48− cmake_parse_arguments(qmlplugin "" "" "${multi_value_keywords}" ${ARGN})
49−
50− # Only try to generate .qmltypes if not cross compiling
51− if(NOT CMAKE_CROSSCOMPILING)
52− # create the plugin.qmltypes file
53− add_custom_target(${PLUGIN}-qmltypes ALL
54− COMMAND ${qmlplugindump_exe} -notrelocatable ${PLUGIN} ${VERSION} ${CMAKE_BINARY_DIR}/plugins > ${CMAKE_BINARY_DIR}/plugins/${PLUGIN_SUBPATH}/plugin.qmltypes
55− )
56− add_dependencies(${PLUGIN}-qmltypes ${PLUGIN}-qmlfiles ${qmlplugin_TARGETS})
57−
58− # install the qmltypes file.
59− install(FILES ${CMAKE_BINARY_DIR}/plugins/${PLUGIN_SUBPATH}/plugin.qmltypes
60− DESTINATION ${SHELL_INSTALL_QML}/${PLUGIN_SUBPATH}
61− )
62− endif()
63−
64− # install the additional targets
65− install(TARGETS ${qmlplugin_TARGETS}
66− DESTINATION ${SHELL_INSTALL_QML}/${PLUGIN_SUBPATH}
67− )
68−endmacro(export_qmlplugin)
cmake/modules/QmlPlugins.cmakenew file+143
@@ -0,0 +1,143 @@
1+# If you need to override the qmlplugindump binary, create the qmlplugin executable
2+# target before loading this plugin.
3+
4+if(NOT TARGET qmlplugindump)
5+ find_program(qmlplugindump_exe qmlplugindump)
6+
7+ if(NOT qmlplugindump_exe)
8+ msg(FATAL_ERROR "Could not locate qmlplugindump.")
9+ endif()
10+
11+ add_executable(qmlplugindump IMPORTED)
12+ set_target_properties(qmlplugindump PROPERTIES IMPORTED_LOCATION ${qmlplugindump_exe})
13+endif()
14+
15+
16+# Creates a target for copying resource files into build dir and optionally installing them.
17+#
18+# Files will be copied into ${BINARY_DIR}/${path} or ${CMAKE_CURRENT_BINARY_DIR} and installed
19+# into ${DESTINATION}/${path}.
20+#
21+# Resource file names are matched against {*.{qml,js,jpg,png,sci,svg},qmldir}.
22+#
23+# export_qmlfiles(plugin path
24+# [SEARCH_PATH path] # Path to search for resources in (defaults to ${CMAKE_CURRENT_SOURCE_DIR})
25+# [BINARY_DIR path]
26+# [DESTINATION path]
27+# [TARGET_PREFIX string] # Will be prefixed to the target name
28+# )
29+#
30+# Created target:
31+# - ${TARGET_PREFIX}${plugin}-qmlfiles - Copies resources into the binary dir.
32+
33+macro(export_qmlfiles PLUGIN PATH)
34+ set(single SEARCH_PATH BINARY_DIR DESTINATION TARGET_PREFIX)
35+ cmake_parse_arguments(QMLFILES "" "${single}" "" ${ARGN})
36+
37+ if(NOT QMLFILES_SEARCH_PATH)
38+ set(QMLFILES_SEARCH_PATH ${CMAKE_CURRENT_SOURCE_DIR})
39+ endif()
40+
41+ if(QMLFILES_BINARY_DIR)
42+ set(qmlfiles_dir ${QMLFILES_BINARY_DIR}/${PATH})
43+ else()
44+ set(qmlfiles_dir ${CMAKE_CURRENT_BINARY_DIR})
45+ endif()
46+
47+ file(GLOB QMLFILES
48+ ${QMLFILES_SEARCH_PATH}/*.qml
49+ ${QMLFILES_SEARCH_PATH}/*.js
50+ ${QMLFILES_SEARCH_PATH}/*.jpg
51+ ${QMLFILES_SEARCH_PATH}/*.png
52+ ${QMLFILES_SEARCH_PATH}/*.sci
53+ ${QMLFILES_SEARCH_PATH}/*.svg
54+ ${QMLFILES_SEARCH_PATH}/qmldir
55+ )
56+
57+ execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${qmlfiles_dir})
58+
59+ # copy the files
60+ add_custom_target(${QMLFILES_TARGET_PREFIX}${PLUGIN}-qmlfiles ALL
61+ COMMAND cp ${QMLFILES} ${qmlfiles_dir}
62+ DEPENDS ${QMLFILES}
63+ SOURCES ${QMLFILES}
64+ )
65+
66+ if(QMLFILES_DESTINATION)
67+ # install the qmlfiles file.
68+ install(FILES ${QMLFILES}
69+ DESTINATION ${QMLFILES_DESTINATION}/${PATH}
70+ )
71+ endif()
72+endmacro(export_qmlfiles)
73+
74+
75+# Creates a target for generating the typeinfo file for a QML plugin and optionally installs it
76+# and additional targets.
77+#
78+# Files will be copied into ${BINARY_DIR}/${path} or ${CMAKE_CURRENT_BINARY_DIR} and installed
79+# into ${DESTINATION}/${path}. If you don't pass BINARY_DIR, it's assumed that current source
80+# path ends with ${path}.
81+#
82+# The generated file will be named after the last segment of the plugin name, e.g. Foo.qmltypes.
83+#
84+# export_qmlplugin(plugin version path
85+# [BINARY_DIR path]
86+# [DESTINATION path]
87+# [TARGET_PREFIX string] # Will be prefixed to the target name
88+# [ENVIRONMENT string] # Will be added to qmlplugindump's env
89+# [TARGETS target1 [target2 ...]] # Targets to depend on and install (e.g. the plugin shared object)
90+# )
91+#
92+# Created target:
93+# - ${TARGET_PREFIX}${plugin}-qmltypes - Generates the qmltypes file in the binary dir.
94+
95+macro(export_qmlplugin PLUGIN VERSION PATH)
96+ set(single BINARY_DIR DESTINATION TARGET_PREFIX ENVIRONMENT)
97+ set(multi TARGETS)
98+ cmake_parse_arguments(QMLPLUGIN "" "${single}" "${multi}" ${ARGN})
99+
100+ get_target_property(qmlplugindump_executable qmlplugindump LOCATION)
101+
102+ if(QMLPLUGIN_BINARY_DIR)
103+ set(qmlplugin_dir ${QMLPLUGIN_BINARY_DIR}/${PATH})
104+ else()
105+ # Find import path to point qmlplugindump at
106+ string(REGEX REPLACE "${PATH}$" "" QMLPLUGIN_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}")
107+ set(qmlplugin_dir ${CMAKE_CURRENT_BINARY_DIR})
108+ endif()
109+
110+ # Find the last segment of the plugin name to use as qmltypes basename
111+ string(REGEX MATCH "[^.]+$" plugin_suffix ${PLUGIN})
112+ set(target_prefix ${QMLPLUGIN_TARGET_PREFIX}${PLUGIN})
113+ set(qmltypes_path ${qmlplugin_dir}/${plugin_suffix}.qmltypes)
114+
115+ # Only generate typeinfo if not cross compiling
116+ if(NOT CMAKE_CROSSCOMPILING)
117+ add_custom_target(${target_prefix}-qmltypes ALL
118+ COMMAND env ${QMLPLUGIN_ENVIRONMENT} ${qmlplugindump_executable} -notrelocatable
119+ ${PLUGIN} ${VERSION} ${QMLPLUGIN_BINARY_DIR} > ${qmltypes_path}
120+ )
121+ add_dependencies(${target_prefix}-qmltypes ${target_prefix}-qmlfiles ${QMLPLUGIN_TARGETS})
122+
123+ if (QMLPLUGIN_DESTINATION)
124+ # Install the typeinfo file
125+ install(FILES ${qmltypes_path}
126+ DESTINATION ${QMLPLUGIN_DESTINATION}/${PATH}
127+ )
128+ endif()
129+ endif()
130+
131+ set_target_properties(${QMLPLUGIN_TARGETS} PROPERTIES
132+ ARCHIVE_OUTPUT_DIRECTORY ${qmlplugin_dir}
133+ LIBRARY_OUTPUT_DIRECTORY ${qmlplugin_dir}
134+ RUNTIME_OUTPUT_DIRECTORY ${qmlplugin_dir}
135+ )
136+
137+ if (QMLPLUGIN_DESTINATION)
138+ # Install additional targets
139+ install(TARGETS ${QMLPLUGIN_TARGETS}
140+ DESTINATION ${QMLPLUGIN_DESTINATION}/${PATH}
141+ )
142+ endif()
143+endmacro()
cmake/modules/QmlTest.cmake+2−4
@@ -59,11 +59,11 @@ macro(add_manual_qml_test SUBPATH COMPONENT_NAME)
5959endmacro(add_manual_qml_test)
6060
6161macro(add_qml_benchmark SUBPATH COMPONENT_NAME ITERATIONS)
62− add_qml_test_internal(${SUBPATH} ${COMPONENT_NAME} ${ITERATIONS})
62+ add_qml_test_internal(${SUBPATH} ${COMPONENT_NAME} ${ITERATIONS} ${ARGN})
6363endmacro(add_qml_benchmark)
6464
6565macro(add_qml_test SUBPATH COMPONENT_NAME)
66− add_qml_test_internal(${SUBPATH} ${COMPONENT_NAME} 0)
66+ add_qml_test_internal(${SUBPATH} ${COMPONENT_NAME} 0 ${ARGN})
6767endmacro(add_qml_test)
6868
6969macro(add_qml_test_internal SUBPATH COMPONENT_NAME ITERATIONS)
@@ -156,8 +156,6 @@ macro(add_binary_qml_test CLASS_NAME LD_PATH DEPS)
156156
157157 add_qmltest_target(xvfbtest${CLASS_NAME} "${xvfbtestCommand}" FALSE TRUE)
158158 add_dependencies(qmluitests xvfbtest${CLASS_NAME})
159−
160− add_manual_qml_test(. ${CLASS_NAME} IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins)
161159endmacro(add_binary_qml_test)
162160
163161macro(add_qmltest_target qmltest_TARGET qmltest_command qmltest_NO_TARGETS qmltest_NO_ADD_TEST)
data/CMakeLists.txt+1−2
@@ -1,8 +1,7 @@
11# generate desktop file
22configure_file(${SHELL_APP}.desktop.in ${CMAKE_CURRENT_BINARY_DIR}/${SHELL_APP}.desktop @ONLY)
3−configure_file(${SCOPE_TOOL}.desktop.in ${CMAKE_CURRENT_BINARY_DIR}/${SCOPE_TOOL}.desktop @ONLY)
43
54# install desktop files
6−install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${SHELL_APP}.desktop ${CMAKE_CURRENT_BINARY_DIR}/${SCOPE_TOOL}.desktop
5+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${SHELL_APP}.desktop
76 DESTINATION ${CMAKE_INSTALL_DATADIR}/applications
87 )
data/unity-scope-tool.desktop.indeleted−8
@@ -1,8 +0,0 @@
1−[Desktop Entry]
2−Type=Application
3−Name=Unity Scope Tool
4−Comment=Developer tool for Unity scopes.
5−Exec=@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_BINDIR@/unity-scope-tool
6−Terminal=false
7−Icon=unity-scope-tool
8−X-Ubuntu-Touch=true
data/unity8.conf+9−1
@@ -12,6 +12,9 @@ respawn
1212expect stop
1313
1414pre-start script
15+ # Tell unity-mir to raise SIGSTOP after we start
16+ initctl set-env UNITY_MIR_EMITS_SIGSTOP=1
17+
1518 if [ -n "$MIR_SOCKET" ]; then
1619 if [ -z "$UNITY_MIR_SOCKET" ]; then
1720 # Save original value of MIR_SOCKET in case we are restarted,
@@ -42,7 +45,12 @@ pre-start script
4245 fi
4346
4447 initctl emit scope-ui-starting
45− initctl emit indicator-services-start
48+ initctl emit --no-wait indicator-services-start
4649end script
4750
4851exec ${BINARY:-unity8} $ARGS
52+
53+post-stop script
54+ initctl set-env --global MIR_SOCKET=$UNITY_MIR_SOCKET
55+ initctl unset-env --global UNITY_MIR_SOCKET
56+end script
debian/changelog+181
@@ -1,3 +1,184 @@
1+unity8 (7.86+14.10.20140522-0ubuntu1) utopic; urgency=low
2+
3+ [ Albert Astals ]
4+ * Use Interface classes from unity-api
5+
6+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Thu, 22 May 2014 17:59:23 +0000
7+
8+unity8 (7.86+14.10.20140519-0ubuntu1) utopic; urgency=low
9+
10+ [ Ubuntu daily release ]
11+ * New rebuild forced
12+
13+ [ Albert Astals ]
14+ * Use the new displayMargin feature Also port our DashViews to use
15+ same naming and behaviour + update tests
16+
17+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Mon, 19 May 2014 07:35:51 +0000
18+
19+unity8 (7.86+14.10.20140516.5-0ubuntu1) utopic; urgency=low
20+
21+ [ Michal Hruby ]
22+ * Updated scope tool to create proper config files after recent
23+ libunity-scopes-api changes.
24+
25+ [ Michał Sawicz ]
26+ * Refactor export_qmlfiles and export_qmlplugins to be more generic
27+ and clean up installed mocks.
28+
29+ [ Albert Astals ]
30+ * Remove empty dirs
31+ * Set the tabbarmodel index as we do on real code It works better :D
32+ (LP: #1317255)
33+
34+ [ Thomi Richards ]
35+ * Use new import location for ProcessSearchError in process_helpers
36+ script.
37+
38+ [ Andrea Cimitan ]
39+ * Adds shadow for the carousel
40+
41+ [ Daniel d'Andrada ]
42+ * Remove Revealer component It's not used anywhere anymore. It's been
43+ replaced by DragHandle.
44+
45+ [ Andy Doan ]
46+ * unlock_device: support more complex reboot/wait cycles Currently
47+ this script only allows you to override how to "wait" on the device.
48+ This changes the logic to also support how you go about rebooting
49+ the device. This is handy for the ubuntu-emulator because adb-reboot
50+ is not currently supported. However, we also have a more
51+ sophisticated, fool-proof way we reboot/wait in the CI lab that
52+ would be nice to take advantage of:
53+ http://bazaar.launchpad.net/~ubuntu-test-case-dev/ubuntu-test-
54+ cases/touch/view/head:/scripts/reboot-and-wait
55+
56+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Fri, 16 May 2014 18:46:32 +0000
57+
58+unity8 (7.86+14.10.20140516.2-0ubuntu1) utopic; urgency=low
59+
60+ [ CI bot ]
61+ * Resync trunk
62+
63+ [ Michael Zanetti ]
64+ * support appid:// entries in gsettings schema and make
65+ findDesktopFile work with short-appid (LP: #1239750)
66+
67+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Fri, 16 May 2014 12:32:40 +0000
68+
69+unity8 (7.86+14.10.20140514.1-0ubuntu1) utopic; urgency=low
70+
71+ [ Antti Kaijanmäki ]
72+ * Indicators/RootActionState: use g_variant_iter_loop to extract
73+ icons.
74+
75+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Wed, 14 May 2014 11:43:55 +0000
76+
77+unity8 (7.86+14.10.20140513-0ubuntu1) utopic; urgency=low
78+
79+ [ Andrea Cimitan ]
80+ * Improve padding in Text preview widget. (LP: #1316683)
81+
82+ [ CI bot ]
83+ * Resync trunk
84+
85+ [ Nick Dedekind ]
86+ * Removed binding loop from Unity.Indicators.MenuContentActivator
87+ Change handler for QMLListProperty used by MenuContent.qml:
88+ menuActivator.content[index].active If we're already asking for the
89+ index, we know it exists already. No need to send a
90+ changeNotification on an implied creation.
91+
92+ [ Josh Arenson ]
93+ * Implements usage-style documentation for unity8 executable. Fixes
94+ lp:1269282 (LP: #1269282)
95+
96+ [ Albert Astals ]
97+ * Create specialized Card code in Javascript instead of having various
98+ copied&pasted files (LP: #1297197)
99+
100+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Tue, 13 May 2014 08:34:02 +0000
101+
102+unity8 (7.86+14.10.20140507.3-0ubuntu1) utopic; urgency=low
103+
104+ [ Michał Sawicz ]
105+ * Remove HUD from the bottom edge. Again.
106+
107+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Wed, 07 May 2014 11:14:30 +0000
108+
109+unity8 (7.86+14.10.20140505-0ubuntu1) utopic; urgency=low
110+
111+ [ Ted Gould ]
112+ * Provide a dbus interface for setting the count and countVisible
113+ properties. (LP: #1301400)
114+
115+ [ Michał Sawicz ]
116+ * Pass env variables to initctl start.
117+ * Suffix .sh to our scripts and clean up debian/rules.
118+ * Adapt to Debian Qt package renames and drop unneeded Dee plugin
119+ dependency.
120+
121+ [ Ying-Chun Liu ]
122+ * Add Zoomable Image for Preview widgets.
123+
124+ [ Albert Astals ]
125+ * Remove support for Qt <= 5.2.1
126+
127+ [ Mirco Müller ]
128+ * Implemented feature-request from Design for modal snap-decision
129+ notifications on the phone. See LP #1285712 (LP: #1285712)
130+
131+ [ Andrea Cimitan ]
132+ * Make progressbas in preview widget big as the button
133+
134+ [ CI bot ]
135+ * Resync trunk
136+
137+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Mon, 05 May 2014 12:09:43 +0000
138+
139+unity8 (7.86+14.10.20140502.6-0ubuntu1) utopic; urgency=low
140+
141+ [ tpeeters ]
142+ * Adapt to new TabBar
143+
144+ [ Tim Peeters ]
145+ * Adapt to new TabBar
146+
147+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Fri, 02 May 2014 16:44:52 +0000
148+
149+unity8 (7.86+14.10.20140429.2-0ubuntu1) utopic; urgency=medium
150+
151+ [ Andrea Cimitan ]
152+ * Update upstart job to reflect latest unity-mir changes
153+ * Fix locale in qml tests and fixtimeformattertest (LP: #1301038)
154+ * Fix 1309135 (LP: #1309135)
155+
156+ [ Michał Sawicz ]
157+ * Split out unity8-common package
158+ * Don't wait for indicator services to start, and drop Scope Tool's
159+ .desktop file. (LP: #1310172)
160+
161+ [ Michael Terry ]
162+ * Stop clock from hiding when the 'show dash' button is pressed in
163+ greeter. (LP: #1308139)
164+ * Make swipe teases in the greeter more helpful and obvious (LP:
165+ #1267623)
166+
167+ [ Nick Dedekind ]
168+ * Fixed datetime indicator appointment colour (LP: #1307048)
169+
170+ [ Albert Astals ]
171+ * Improve Card creation time by adding loaders that make sure only
172+ what's needed is loaded (LP: #1297197)
173+ * CategoryDelegateRange: Fix condition for detecting overshooting
174+ * Make xvfbtests work in the DashView plugins
175+ * Fix binding loop in FilterGrid height
176+
177+ [ Victor R. Ruiz ]
178+ * Move autopilot notification code to a helper method.
179+
180+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Tue, 29 Apr 2014 15:21:33 +0000
181+
1182unity8 (7.85+14.04.20140416-0ubuntu1) trusty; urgency=low
2183
3184 [ Albert Astals ]
debian/control+41−30
@@ -11,34 +11,34 @@ Build-Depends: cmake,
1111 libgl1-mesa-dev[!armhf] | libgl-dev[!armhf],
1212 libgl1-mesa-dri,
1313 libgles2-mesa-dev[armhf],
14+ libglib2.0-dev,
1415 libgsettings-qt-dev,
1516 libhud-client2-dev,
1617 libpulse-dev,
1718 libqmenumodel-dev (>= 0.2.7),
19+ libqt5xmlpatterns5-dev,
1820 libunity-api-dev (>= 7.80.6),
1921 libunity-mir-dev,
2022 libusermetricsoutput1-dev,
2123 libxcb1-dev,
22− libglib2.0-dev,
2324 pkg-config,
24− python:any (>= 2.7),
2525 python-setuptools,
2626 python3-all:any,
2727 python3-setuptools,
28+ python:any (>= 2.7),
29+ qml-module-qtquick-xmllistmodel,
30+ qml-module-qtquick2,
31+ qml-module-qttest,
2832 qt5-default,
29− qtbase5-dev,
33+ qtbase5-dev (>= 5.2.1),
3034 qtbase5-dev-tools,
31− qtbase5-private-dev,
32− qtdeclarative5-dev,
35+ qtbase5-private-dev (>= 5.2.1),
36+ qtdeclarative5-dev (>= 5.2.1),
3337 qtdeclarative5-dev-tools,
38+ qtdeclarative5-private-dev (>= 5.2.1),
3439 qtdeclarative5-qtmultimedia-plugin,
35− qtdeclarative5-private-dev,
36− qtdeclarative5-qtquick2-plugin,
37− qtdeclarative5-test-plugin,
3840 qtdeclarative5-ubuntu-settings-components,
3941 qtdeclarative5-ubuntu-ui-toolkit-plugin (>= 0.1.47),
40− qtdeclarative5-xmllistmodel-plugin,
41− libqt5xmlpatterns5-dev,
4242 ttf-ubuntu-font-family,
4343Standards-Version: 3.9.4
4444Homepage: http://launchpad.net/unity
@@ -60,7 +60,8 @@ Description: Indicators client test application
6060
6161Package: unity-scope-tool
6262Architecture: any
63−Depends: unity8 (= ${binary:Version}),
63+Depends: unity8-common (= ${source:Version}),
64+ unity8-private (= ${binary:Version}),
6465 ${misc:Depends},
6566 ${shlibs:Depends},
6667Description: Development tool for Unity scopes
@@ -71,27 +72,17 @@ Package: unity8
7172Architecture: any
7273Provides: indicator-renderer,
7374Depends: gsettings-desktop-schemas,
75+ libcap2-bin,
7476 libglib2.0-bin,
75− libunity-mir1,
77+ libunity-mir1 (>= 0.4),
7678 qmenumodel-qml (>= 0.2.7),
77− qtdeclarative5-dee-plugin,
79+ qml-module-qtquick-xmllistmodel,
7880 qtdeclarative5-gsettings1.0,
7981 qtdeclarative5-ubuntu-settings-components,
80− qtdeclarative5-ubuntu-thumbnailer0.1 | ubuntu-thumbnailer-impl,
81− ubuntu-thumbnailer-impl-0,
82− qtdeclarative5-ubuntu-ui-toolkit-plugin (>= 0.1.47),
83− qtdeclarative5-unity-notifications-plugin | unity-notifications-impl,
84− qtdeclarative5-xmllistmodel-plugin,
85− unity-application-impl-2,
8682 unity-launcher-impl-3,
87− unity-notifications-impl-2,
88− unity8-fake-env | unity-application-impl,
83+ unity8-common (= ${source:Version}),
8984 unity8-private (= ${binary:Version}),
9085 unity8-private | unity-launcher-impl,
91− unity-plugin-scopes | unity-scopes-impl,
92− unity-scopes-impl-0,
93−# for setcap:
94− libcap2-bin,
9586 ${misc:Depends},
9687 ${shlibs:Depends},
9788Recommends: unity-scope-click,
@@ -99,10 +90,30 @@ Recommends: unity-scope-click,
9990 unity-scope-scopes,
10091Breaks: indicator-network (<< 0.5.1),
10192 ubuntu-touch-session (<< 0.107),
102−Replaces: ubuntu-touch-session (<< 0.82~)
93+Replaces: ubuntu-touch-session (<< 0.82~),
10394Description: Unity 8 shell
10495 The Unity 8 shell is the primary user interface for Ubuntu devices.
10596
97+Package: unity8-common
98+Architecture: all
99+Depends: qtdeclarative5-ubuntu-thumbnailer0.1 | ubuntu-thumbnailer-impl,
100+ qtdeclarative5-ubuntu-ui-toolkit-plugin (>= 0.1.47),
101+ qtdeclarative5-unity-notifications-plugin | unity-notifications-impl,
102+ ubuntu-thumbnailer-impl-0,
103+ unity-application-impl-2,
104+ unity-notifications-impl-3,
105+ unity-plugin-scopes | unity-scopes-impl,
106+ unity-scopes-impl-0,
107+ unity8-fake-env | unity-application-impl,
108+ ${misc:Depends},
109+Breaks: unity8 (<< 7.86),
110+Replaces: unity8 (<< 7.86),
111+Description: Unity 8 shell (common files)
112+ The Unity 8 shell is the primary user interface for Ubuntu devices.
113+ .
114+ This package contains the QML, graphics and locale files shared between
115+ unity8 and unity-scope-tool.
116+
106117Package: unity8-autopilot
107118Architecture: all
108119Depends: gir1.2-glib-2.0,
@@ -119,12 +130,12 @@ Depends: gir1.2-glib-2.0,
119130 python3-fixtures,
120131 python3-gi,
121132 ubuntu-ui-toolkit-autopilot,
122− unity8 (>= ${source:Version}),
123− unity8-fake-env (>= ${source:Version}),
133+ unity8 (= ${source:Version}),
134+ unity8-fake-env (= ${source:Version}),
124135 url-dispatcher-tools,
125136 ${misc:Depends},
126− ${python:Depends},
127137 ${python3:Depends},
138+ ${python:Depends},
128139 ${shlibs:Depends},
129140Description: Test package for Unity 8 shell
130141 Autopilot tests for the unity8 package
@@ -146,9 +157,9 @@ Architecture: any
146157Multi-Arch: same
147158Pre-Depends: ${misc:Pre-Depends},
148159Depends: gsettings-ubuntu-schemas,
160+ libunity-core-6.0-9,
149161 ${misc:Depends},
150162 ${shlibs:Depends},
151− libunity-core-6.0-9,
152163Provides: unity-launcher-impl,
153164 unity-launcher-impl-3,
154165Description: Unity 8 private libs
debian/rules+1−2
@@ -6,8 +6,7 @@
66export DPKG_GENSYMBOLS_CHECK_LEVEL=4
77export NO_PNG_PKG_MANGLE=1
88
9−.PHONY: build
10−build %:
9+%:
1110 dh $@ --parallel --fail-missing --with python2,python3
1211
1312override_dh_auto_clean:
debian/unity-scope-tool.install−1
@@ -1,3 +1,2 @@
11usr/bin/unity-scope-tool
2−usr/share/applications/unity-scope-tool.desktop
32usr/share/unity8/ScopeTool.qml
debian/unity8-common.installnew file+5
@@ -0,0 +1,5 @@
1+usr/share/locale
2+usr/share/unity8/Components
3+usr/share/unity8/Dash
4+usr/share/unity8/Notifications
5+usr/share/unity8/graphics
debian/unity8-fake-env.install+1−1
@@ -1,4 +1,4 @@
1−usr/lib/*/unity8/qml/nonmirplugins
21usr/lib/*/unity8/qml/mocks
2+usr/lib/*/unity8/qml/nonmirplugins
33usr/lib/*/unity8/qml/scopefakes
44usr/share/unity8/mocks
debian/unity8-private.install+1−1
@@ -1,7 +1,7 @@
11usr/lib/*/unity8/qml/AccountsService
2+usr/lib/*/unity8/qml/Dash
23usr/lib/*/unity8/qml/HudClient
34usr/lib/*/unity8/qml/LightDM
4−usr/lib/*/unity8/qml/DashViews
55usr/lib/*/unity8/qml/Powerd
66usr/lib/*/unity8/qml/SessionBroadcast
77usr/lib/*/unity8/qml/Ubuntu
debian/unity8.install+1−7
@@ -1,15 +1,9 @@
1+data/unity8.conf usr/share/upstart/sessions/
12usr/bin/unity8
23usr/share/applications/unity8.desktop
3−usr/share/locale
4−usr/share/unity8/Bottombar
5−usr/share/unity8/Components
6−usr/share/unity8/Dash
74usr/share/unity8/Greeter
85usr/share/unity8/Hud
96usr/share/unity8/Launcher
10−usr/share/unity8/Notifications
117usr/share/unity8/Panel
128usr/share/unity8/Shell.qml
139usr/share/unity8/Stages
14−usr/share/unity8/graphics
15−data/unity8.conf usr/share/upstart/sessions/
plugins/AccountsService/CMakeLists.txt+1−4
@@ -1,5 +1,3 @@
1−include(Plugins)
2−
31add_definitions(-DSM_BUSNAME=systemBus)
42
53add_library(AccountsService-qml MODULE
@@ -10,8 +8,7 @@ add_library(AccountsService-qml MODULE
108
119qt5_use_modules(AccountsService-qml DBus Qml)
1210
13−export_qmlfiles(AccountsService AccountsService)
14−export_qmlplugin(AccountsService 0.1 AccountsService TARGETS AccountsService-qml)
11+add_unity8_plugin(AccountsService 0.1 AccountsService TARGETS AccountsService-qml)
1512
1613set(POLKIT_LIB_DIR "${CMAKE_INSTALL_LOCALSTATEDIR}/lib/polkit-1")
1714set(POLKIT_DATA_DIR "${CMAKE_INSTALL_PREFIX}/share/polkit-1")
plugins/AccountsService/qmldir+1−1
@@ -1,3 +1,3 @@
11module AccountsService
22plugin AccountsService-qml
3−typeinfo plugin.qmltypes
3+typeinfo AccountsService.qmltypes
plugins/CMakeLists.txt+14−1
@@ -1,7 +1,20 @@
1+include(QmlPlugins)
2+
3+# Set up and install a plugin for unity8.
4+#
5+# add_unity8_plugin(plugin version path
6+# [...] # See export_qmlfiles and export_qmlplugin documentation for more options
7+# )
8+
9+macro(add_unity8_plugin PLUGIN VERSION PATH)
10+ export_qmlfiles(${PLUGIN} ${PATH} DESTINATION ${SHELL_INSTALL_QML} ${ARGN})
11+ export_qmlplugin(${PLUGIN} ${VERSION} ${PATH} DESTINATION ${SHELL_INSTALL_QML} ${ARGN})
12+endmacro()
13+
114add_subdirectory(AccountsService)
215add_subdirectory(HudClient)
316add_subdirectory(LightDM)
4−add_subdirectory(DashViews)
17+add_subdirectory(Dash)
518add_subdirectory(Powerd)
619add_subdirectory(SessionBroadcast)
720add_subdirectory(Ubuntu)
plugins/DashViews/CMakeLists.txt → plugins/Dash/CMakeLists.txtrenamed+4−9
@@ -1,6 +1,3 @@
1−# export_qmlplugin macro
2−include(Plugins)
3−
41# There's no cmake var for v8 include path :-/
52# so create one
63LIST(GET Qt5Core_INCLUDE_DIRS 0 QtCoreDir0)
@@ -30,17 +27,15 @@ set(QMLPLUGIN_SRC
3027 organicgrid.cpp
3128 )
3229
33−add_library(DashViews-qml MODULE
30+add_library(Dash-qml MODULE
3431 ${QMLPLUGIN_SRC}
3532 )
3633
37−target_link_libraries(DashViews-qml
34+target_link_libraries(Dash-qml
3835 ${Qt5Gui_LIBRARIES}
3936 ${Qt5Quick_LIBRARIES}
4037 )
4138
42−qt5_use_modules(DashViews-qml Qml Quick)
39+qt5_use_modules(Dash-qml Qml Quick)
4340
44−# export the qmldir qmltypes and plugin files
45−export_qmlfiles(DashViews DashViews)
46−export_qmlplugin(DashViews 0.1 DashViews TARGETS DashViews-qml)
41+add_unity8_plugin(Dash 0.1 Dash TARGETS Dash-qml)
plugins/Dash/CardCreator.jsnew file+520
@@ -0,0 +1,520 @@
1+/*
2+ * Copyright (C) 2014 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+.pragma library
18+
19+var kBackgroundLoaderCode = 'Loader {\n\
20+ id: backgroundLoader; \n\
21+ objectName: "backgroundLoader"; \n\
22+ anchors.fill: parent; \n\
23+ asynchronous: root.asynchronous; \n\
24+ visible: status == Loader.Ready; \n\
25+ sourceComponent: UbuntuShape { \n\
26+ objectName: "background"; \n\
27+ radius: "medium"; \n\
28+ color: getColor(0) || "white"; \n\
29+ gradientColor: getColor(1) || color; \n\
30+ anchors.fill: parent; \n\
31+ image: backgroundImage.source ? backgroundImage : null; \n\
32+ property real luminance: 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b; \n\
33+ property Image backgroundImage: Image { \n\
34+ objectName: "backgroundImage"; \n\
35+ source: { \n\
36+ if (cardData && typeof cardData["background"] === "string") return cardData["background"]; \n\
37+ else if (template && typeof template["card-background"] === "string") return template["card-background"]; \n\
38+ else return ""; \n\
39+ } \n\
40+ } \n\
41+ function getColor(index) { \n\
42+ if (cardData && typeof cardData["background"] === "object" \n\
43+ && (cardData["background"]["type"] === "color" || cardData["background"]["type"] === "gradient")) { \n\
44+ return cardData["background"]["elements"][index]; \n\
45+ } else if (template && typeof template["card-background"] === "object" \n\
46+ && (template["card-background"]["type"] === "color" || template["card-background"]["type"] === "gradient")) { \n\
47+ return template["card-background"]["elements"][index]; \n\
48+ } else return undefined; \n\
49+ } \n\
50+ } \n\
51+ }\n';
52+
53+// %1 is used as anchors of artShapeHolder
54+// %2 is used as image width
55+// %3 is used as image height
56+var kArtShapeHolderCode = 'Item { \n\
57+ id: artShapeHolder; \n\
58+ height: root.fixedArtShapeSize.height != -1 ? root.fixedArtShapeSize.height : artShapeLoader.height; \n\
59+ width: root.fixedArtShapeSize.width != -1 ? root.fixedArtShapeSize.width : artShapeLoader.width; \n\
60+ anchors { %1 } \n\
61+ Loader { \n\
62+ id: artShapeLoader; \n\
63+ objectName: "artShapeLoader"; \n\
64+ active: cardData && cardData["art"] || false; \n\
65+ asynchronous: root.asynchronous; \n\
66+ visible: status == Loader.Ready; \n\
67+ sourceComponent: UbuntuShape { \n\
68+ id: artShape; \n\
69+ objectName: "artShape"; \n\
70+ radius: "medium"; \n\
71+ readonly property real aspect: components !== undefined ? components["art"]["aspect-ratio"] : 1; \n\
72+ readonly property bool aspectSmallerThanImageAspect: aspect < image.aspect; \n\
73+ Component.onCompleted: updateWidthHeightBindings(); \n\
74+ onAspectSmallerThanImageAspectChanged: updateWidthHeightBindings(); \n\
75+ visible: image.status == Image.Ready; \n\
76+ borderSource: artShapeBorderSource; \n\
77+ function updateWidthHeightBindings() { \n\
78+ if (aspectSmallerThanImageAspect) { \n\
79+ width = Qt.binding(function() { return !visible ? 0 : image.width }); \n\
80+ height = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.height : width / image.aspect }); \n\
81+ } else { \n\
82+ width = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.width : height * image.aspect }); \n\
83+ height = Qt.binding(function() { return !visible ? 0 : image.height }); \n\
84+ } \n\
85+ } \n\
86+ image: Image { \n\
87+ objectName: "artImage"; \n\
88+ source: cardData && cardData["art"] || ""; \n\
89+ cache: true; \n\
90+ asynchronous: root.asynchronous; \n\
91+ fillMode: components && components["art"]["fill-mode"] === "fit" ? Image.PreserveAspectFit: Image.PreserveAspectCrop; \n\
92+ readonly property real aspect: implicitWidth / implicitHeight; \n\
93+ width: %2; \n\
94+ height: %3; \n\
95+ } \n\
96+ } \n\
97+ } \n\
98+ }\n';
99+
100+var kOverlayLoaderCode = 'Loader { \n\
101+ id: overlayLoader; \n\
102+ anchors { \n\
103+ left: artShapeHolder.left; \n\
104+ right: artShapeHolder.right; \n\
105+ bottom: artShapeHolder.bottom; \n\
106+ } \n\
107+ active: artShapeLoader.active && artShapeLoader.item && artShapeLoader.item.image.status === Image.Ready || false; \n\
108+ asynchronous: root.asynchronous; \n\
109+ visible: showHeader && status == Loader.Ready; \n\
110+ sourceComponent: ShaderEffect { \n\
111+ id: overlay; \n\
112+ height: fixedHeaderHeight != -1 ? fixedHeaderHeight : headerHeight; \n\
113+ opacity: 0.6; \n\
114+ property var source: ShaderEffectSource { \n\
115+ id: shaderSource; \n\
116+ sourceItem: artShapeLoader.item; \n\
117+ onVisibleChanged: if (visible) scheduleUpdate(); \n\
118+ live: false; \n\
119+ sourceRect: Qt.rect(0, artShapeLoader.height - overlay.height, artShapeLoader.width, overlay.height); \n\
120+ } \n\
121+ vertexShader: " \n\
122+ uniform highp mat4 qt_Matrix; \n\
123+ attribute highp vec4 qt_Vertex; \n\
124+ attribute highp vec2 qt_MultiTexCoord0; \n\
125+ varying highp vec2 coord; \n\
126+ void main() { \n\
127+ coord = qt_MultiTexCoord0; \n\
128+ gl_Position = qt_Matrix * qt_Vertex; \n\
129+ }"; \n\
130+ fragmentShader: " \n\
131+ varying highp vec2 coord; \n\
132+ uniform sampler2D source; \n\
133+ uniform lowp float qt_Opacity; \n\
134+ void main() { \n\
135+ lowp vec4 tex = texture2D(source, coord); \n\
136+ gl_FragColor = vec4(0, 0, 0, tex.a) * qt_Opacity; \n\
137+ }"; \n\
138+ } \n\
139+ }\n';
140+
141+// %1 is used as anchors of row
142+// %2 is used as first child of the row
143+// %3 is used as second child of the row
144+var kHeaderRow2Code = 'Row { \n\
145+ id: row; \n\
146+ objectName: "outerRow"; \n\
147+ property real margins: units.gu(1); \n\
148+ spacing: margins; \n\
149+ anchors { %1 } \n\
150+ anchors.right: parent.right; \n\
151+ anchors.margins: margins;\n\
152+ data: [ %2\n\
153+ ,\n\
154+ %3 \n\
155+ ] \n\
156+ }\n';
157+
158+// %1 is used as anchors of row
159+// %2 is used as first child of the row
160+// %3 is used as second child of the row
161+// %4 is used as third child of the row
162+var kHeaderRow3Code = 'Row { \n\
163+ id: row; \n\
164+ objectName: "outerRow"; \n\
165+ property real margins: units.gu(1); \n\
166+ spacing: margins; \n\
167+ anchors { %1 } \n\
168+ anchors.right: parent.right; \n\
169+ anchors.margins: margins;\n\
170+ data: [ %2\n\
171+ ,\n\
172+ %3 \n\
173+ ,\n\
174+ %4 \n\
175+ ] \n\
176+ }\n';
177+
178+// %1 is used as first child of the column
179+// %2 is used as second child of the column
180+var kHeaderColumnCode = 'Column { \n\
181+ anchors.verticalCenter: parent.verticalCenter; \n\
182+ spacing: units.dp(2); \n\
183+ width: parent.width - x;\n\
184+ data: [ %1\n\
185+ ,\n\
186+ %2 \n\
187+ ] \n\
188+ }\n';
189+
190+// %1 is used as anchors of mascotShapeLoader
191+var kMascotShapeLoaderCode = 'Loader { \n\
192+ id: mascotShapeLoader; \n\
193+ objectName: "mascotShapeLoader"; \n\
194+ asynchronous: root.asynchronous; \n\
195+ active: mascotImage.status === Image.Ready; \n\
196+ visible: showHeader && active && status == Loader.Ready; \n\
197+ width: units.gu(6); \n\
198+ height: units.gu(5.625); \n\
199+ sourceComponent: UbuntuShape { image: mascotImage } \n\
200+ anchors { %1 } \n\
201+ }\n';
202+
203+// %1 is used as anchors of mascotImage
204+// %2 is used as visible of mascotImage
205+var kMascotImageCode = 'Image { \n\
206+ id: mascotImage; \n\
207+ objectName: "mascotImage"; \n\
208+ anchors { %1 } \n\
209+ readonly property int maxSize: Math.max(width, height) * 4; \n\
210+ source: cardData && cardData["mascot"]; \n\
211+ width: units.gu(6); \n\
212+ height: units.gu(5.625); \n\
213+ sourceSize { width: maxSize; height: maxSize } \n\
214+ fillMode: Image.PreserveAspectCrop; \n\
215+ horizontalAlignment: Image.AlignHCenter; \n\
216+ verticalAlignment: Image.AlignVCenter; \n\
217+ visible: %2; \n\
218+ }\n';
219+
220+// %1 is used as anchors of titleLabel
221+// %1 is used as color of titleLabel
222+// %3 is used as extra condition for visible of titleLabel
223+var kTitleLabelCode = 'Label { \n\
224+ id: titleLabel; \n\
225+ objectName: "titleLabel"; \n\
226+ anchors { %1 } \n\
227+ elide: Text.ElideRight; \n\
228+ fontSize: "small"; \n\
229+ wrapMode: Text.Wrap; \n\
230+ maximumLineCount: 2; \n\
231+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale); \n\
232+ color: %2; \n\
233+ visible: showHeader %3; \n\
234+ text: root.title; \n\
235+ font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal; \n\
236+ horizontalAlignment: root.headerAlignment; \n\
237+ }\n';
238+
239+// %1 is used as anchors of subtitleLabel
240+// %2 is used as color of subtitleLabel
241+var kSubtitleLabelCode = 'Label { \n\
242+ id: subtitleLabel; \n\
243+ objectName: "subtitleLabel"; \n\
244+ anchors { %1 } \n\
245+ elide: Text.ElideRight; \n\
246+ fontSize: "small"; \n\
247+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale); \n\
248+ color: %2; \n\
249+ visible: titleLabel.visible && titleLabel.text; \n\
250+ text: cardData && cardData["subtitle"] || ""; \n\
251+ font.weight: Font.Light; \n\
252+ horizontalAlignment: root.headerAlignment; \n\
253+ }\n';
254+
255+// %1 is used as top anchor of summary
256+// %2 is used as topMargin anchor of summary
257+// %3 is used as color of summary
258+var kSummaryLabelCode = 'Label { \n\
259+ id: summary; \n\
260+ objectName: "summaryLabel"; \n\
261+ anchors { \n\
262+ top: %1; \n\
263+ left: parent.left; \n\
264+ right: parent.right; \n\
265+ margins: units.gu(1); \n\
266+ topMargin: %2; \n\
267+ } \n\
268+ wrapMode: Text.Wrap; \n\
269+ maximumLineCount: 5; \n\
270+ elide: Text.ElideRight; \n\
271+ text: cardData && cardData["summary"] || ""; \n\
272+ height: text ? implicitHeight : 0; \n\
273+ fontSize: "small"; \n\
274+ color: %3; \n\
275+ }\n';
276+
277+function cardString(template, components) {
278+ var code;
279+ code = 'AbstractButton { \n\
280+ id: root; \n\
281+ property var template; \n\
282+ property var components; \n\
283+ property var cardData; \n\
284+ property var artShapeBorderSource; \n\
285+ property real fontScale: 1.0; \n\
286+ property int headerAlignment: Text.AlignLeft; \n\
287+ property int fixedHeaderHeight: -1; \n\
288+ property size fixedArtShapeSize: Qt.size(-1, -1); \n\
289+ readonly property string title: cardData && cardData["title"] || ""; \n\
290+ property bool asynchronous: true; \n\
291+ property bool showHeader: true; \n\
292+ implicitWidth: childrenRect.width; \n';
293+
294+ var hasArt = components["art"] && components["art"]["field"] || false;
295+ var hasSummary = components["summary"] || false;
296+ var artAndSummary = hasArt && hasSummary;
297+ var isHorizontal = template["card-layout"] === "horizontal";
298+ var hasBackground = !isHorizontal && (template["card-background"] || components["background"] || artAndSummary);
299+ var hasTitle = components["title"] || false;
300+ var hasMascot = components["mascot"] || false;
301+ var headerAsOverlay = hasArt && template && template["overlay"] === true && (hasTitle || hasMascot);
302+ var hasSubtitle = components["subtitle"] || false;
303+ var hasHeaderRow = hasMascot && hasTitle;
304+
305+ if (hasBackground) {
306+ code += kBackgroundLoaderCode;
307+ }
308+
309+ if (hasArt) {
310+ code += 'readonly property size artShapeSize: artShapeLoader.item ? Qt.size(artShapeLoader.item.width, artShapeLoader.item.height) : Qt.size(-1, -1);\n';
311+
312+ var widthCode, heightCode;
313+ var anchors;
314+ if (isHorizontal) {
315+ anchors = 'left: parent.left';
316+ if (hasMascot || hasTitle) {
317+ widthCode = 'height * artShape.aspect'
318+ heightCode = 'headerHeight';
319+ } else {
320+ // This side of the else is a bit silly, who wants an horizontal layout without mascot and title?
321+ // So we define a "random" height of the image height + 2 gu for the margins
322+ widthCode = 'height * artShape.aspect'
323+ heightCode = 'units.gu(7.625)';
324+ }
325+ } else {
326+ anchors = 'horizontalCenter: parent.horizontalCenter;';
327+ widthCode = 'root.width'
328+ heightCode = 'width / artShape.aspect';
329+ }
330+
331+ code += kArtShapeHolderCode.arg(anchors).arg(widthCode).arg(heightCode);
332+ } else {
333+ code += 'readonly property size artShapeSize: Qt.size(-1, -1);\n'
334+ }
335+
336+ if (headerAsOverlay) {
337+ code += kOverlayLoaderCode;
338+ }
339+
340+ var headerVerticalAnchors;
341+ if (headerAsOverlay) {
342+ headerVerticalAnchors = 'bottom: artShapeHolder.bottom; \n\
343+ bottomMargin: units.gu(1);\n';
344+ } else {
345+ if (hasArt) {
346+ if (isHorizontal) {
347+ headerVerticalAnchors = 'top: artShapeHolder.top; \n\
348+ topMargin: units.gu(1);\n';
349+ } else {
350+ headerVerticalAnchors = 'top: artShapeHolder.bottom; \n\
351+ topMargin: units.gu(1);\n';
352+ }
353+ } else {
354+ headerVerticalAnchors = 'top: parent.top; \n\
355+ topMargin: units.gu(1);\n';
356+ }
357+ }
358+ var headerLeftAnchor;
359+ var headerLeftAnchorHasMagin = false;
360+ if (isHorizontal && hasArt) {
361+ headerLeftAnchor = 'left: artShapeHolder.right; \n\
362+ leftMargin: units.gu(1);\n';
363+ headerLeftAnchorHasMagin = true;
364+ } else {
365+ headerLeftAnchor = 'left: parent.left;\n';
366+ }
367+
368+ if (hasHeaderRow) {
369+ code += 'readonly property int headerHeight: row.height + row.margins * 2;\n'
370+ } else if (hasMascot) {
371+ code += 'readonly property int headerHeight: mascotImage.height + units.gu(1) * 2;\n'
372+ } else if (hasSubtitle) {
373+ code += 'readonly property int headerHeight: titleLabel.height + titleLabel.anchors.topMargin * 2 + subtitleLabel.height + subtitleLabel.anchors.topMargin;\n'
374+ } else if (hasTitle) {
375+ code += 'readonly property int headerHeight: titleLabel.height + titleLabel.anchors.topMargin * 2;\n'
376+ } else {
377+ code += 'readonly property int headerHeight: 0;\n'
378+ }
379+
380+ var mascotShapeCode = "";
381+ var mascotCode = "";
382+ if (hasMascot) {
383+ var useMascotShape = !hasBackground && !headerAsOverlay;
384+ var anchors = "";
385+ if (!hasHeaderRow) {
386+ anchors += headerLeftAnchor;
387+ anchors += headerVerticalAnchors;
388+ if (!headerLeftAnchorHasMagin) {
389+ anchors += 'leftMargin: units.gu(1);\n'
390+ }
391+ } else {
392+ anchors = "verticalCenter: parent.verticalCenter;"
393+ }
394+
395+ if (useMascotShape) {
396+ mascotShapeCode = kMascotShapeLoaderCode.arg(anchors);
397+ }
398+
399+ var mascotImageVisible = useMascotShape ? 'false' : 'showHeader';
400+ mascotCode = kMascotImageCode.arg(anchors).arg(mascotImageVisible);
401+ }
402+
403+ var summaryColorWithBackground = 'backgroundLoader.active && backgroundLoader.item && backgroundLoader.item.luminance < 0.7 ? "white" : "grey"';
404+
405+ var titleSubtitleCode = "";
406+ if (hasTitle) {
407+ var color;
408+ if (headerAsOverlay) {
409+ color = '"white"';
410+ } else if (hasSummary) {
411+ color = 'summary.color';
412+ } else if (hasBackground) {
413+ color = summaryColorWithBackground;
414+ } else {
415+ color = '"grey"';
416+ }
417+
418+ var titleAnchors;
419+ var subtitleAnchors;
420+ if (hasMascot && hasSubtitle) {
421+ // Using row + column
422+ titleAnchors = 'left: parent.left; right: parent.right';
423+ subtitleAnchors = titleAnchors;
424+ } else if (hasMascot) {
425+ // Using row + label
426+ titleAnchors = 'verticalCenter: parent.verticalCenter;\n'
427+ } else {
428+ if (headerAsOverlay) {
429+ // Using anchors to the overlay
430+ titleAnchors = 'left: parent.left; \n\
431+ leftMargin: units.gu(1); \n\
432+ right: parent.right; \n\
433+ top: overlayLoader.top; \n\
434+ topMargin: units.gu(1);\n';
435+ } else {
436+ // Using anchors to the mascot/parent
437+ titleAnchors = "right: parent.right;";
438+ titleAnchors += headerLeftAnchor;
439+ titleAnchors += headerVerticalAnchors;
440+ }
441+ subtitleAnchors = 'left: titleLabel.left; \n\
442+ leftMargin: titleLabel.leftMargin; \n\
443+ right: titleLabel.right; \n\
444+ top: titleLabel.bottom; \n\
445+ topMargin: units.dp(2);\n';
446+ }
447+
448+ var titleLabelVisibleExtra = (headerAsOverlay ? '&& overlayLoader.active': '');
449+ var titleCode = kTitleLabelCode.arg(titleAnchors).arg(color).arg(titleLabelVisibleExtra);
450+ var subtitleCode = "";
451+ if (hasSubtitle) {
452+ subtitleCode += kSubtitleLabelCode.arg(subtitleAnchors).arg(color);
453+ }
454+
455+ if (hasMascot && hasSubtitle) {
456+ // If using row + column wrap the code in the column
457+ titleSubtitleCode = kHeaderColumnCode.arg(titleCode).arg(subtitleCode);
458+ } else {
459+ titleSubtitleCode = titleCode + subtitleCode;
460+ }
461+ }
462+
463+ if (hasHeaderRow) {
464+ if (mascotShapeCode != "") {
465+ code += kHeaderRow3Code.arg(headerVerticalAnchors + headerLeftAnchor).arg(mascotShapeCode).arg(mascotCode).arg(titleSubtitleCode);
466+ } else {
467+ code += kHeaderRow2Code.arg(headerVerticalAnchors + headerLeftAnchor).arg(mascotCode).arg(titleSubtitleCode);
468+ }
469+ } else {
470+ code += mascotShapeCode + mascotCode + titleSubtitleCode;
471+ }
472+
473+ if (hasSummary) {
474+ var summaryTopAnchor;
475+ if (isHorizontal && hasArt) summaryTopAnchor = "artShapeHolder.bottom";
476+ else if (headerAsOverlay && hasArt) summaryTopAnchor = "artShapeHolder.bottom";
477+ else if (hasHeaderRow) summaryTopAnchor = "row.bottom";
478+ else if (hasMascot) summaryTopAnchor = "mascotImage.bottom";
479+ else if (hasSubtitle) summaryTopAnchor = "subtitleLabel.bottom";
480+ else if (hasTitle) summaryTopAnchor = "titleLabel.bottom";
481+ else if (hasArt) summaryTopAnchor = "artShapeHolder.bottom";
482+ else summaryTopAnchor = "parent.top";
483+
484+ var color;
485+ if (hasBackground) {
486+ color = summaryColorWithBackground;
487+ } else {
488+ color = '"grey"';
489+ }
490+
491+ var summaryTopMargin = (hasMascot || hasSubtitle ? 'anchors.margins' : '0');
492+
493+ code += kSummaryLabelCode.arg(summaryTopAnchor).arg(summaryTopMargin).arg(color);
494+ }
495+
496+ if (hasSummary) {
497+ code += 'implicitHeight: summary.y + summary.height + (summary.text ? units.gu(1) : 0);\n';
498+ } else if (hasHeaderRow) {
499+ code += 'implicitHeight: row.y + row.height + units.gu(1);\n';
500+ } else if (hasMascot) {
501+ code += 'implicitHeight: mascotImage.y + mascotImage.height;\n';
502+ } else if (hasSubtitle) {
503+ code += 'implicitHeight: subtitleLabel.y + subtitleLabel.height + units.gu(1);\n';
504+ } else if (hasTitle) {
505+ code += 'implicitHeight: titleLabel.y + titleLabel.height + units.gu(1);\n';
506+ }
507+ // Close the AbstractButton
508+ code += '}\n';
509+
510+ return code;
511+}
512+
513+function createCardComponent(parent, template, components) {
514+ var imports = 'import QtQuick 2.2; \n\
515+ import Ubuntu.Components 0.1; \n\
516+ import Ubuntu.Thumbnailer 0.1;\n';
517+ var card = cardString(template, components);
518+ var code = imports + 'Component {\n' + card + '}\n';
519+ return Qt.createQmlObject(code, parent, "createCardComponent");
520+}
plugins/Dash/CardCreatorCache.qmlnew file+40
@@ -0,0 +1,40 @@
1+/*
2+ * Copyright (C) 2014 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+pragma Singleton
18+import QtQuick 2.2
19+import "CardCreator.js" as CardCreator
20+
21+QtObject {
22+ id: root
23+
24+ property var cache: new Object();
25+
26+ function getCardComponent(template, components) {
27+ if (template === undefined || components === undefined)
28+ return undefined;
29+
30+ var tString = JSON.stringify(template);
31+ var cString = JSON.stringify(components);
32+ var allString = tString + cString;
33+ var component = cache[allString];
34+ if (component === undefined) {
35+ component = CardCreator.createCardComponent(root, template, components);
36+ cache[allString] = component;
37+ }
38+ return component;
39+ }
40+}
plugins/DashViews/abstractdashview.cpp → plugins/Dash/abstractdashview.cpprenamed+18−82
@@ -23,10 +23,8 @@ AbstractDashView::AbstractDashView()
2323 , m_asyncRequestedIndex(-1)
2424 , m_columnSpacing(0)
2525 , m_rowSpacing(0)
26− , m_delegateCreationBegin(0)
27− , m_delegateCreationEnd(0)
28− , m_delegateCreationBeginValid(false)
29− , m_delegateCreationEndValid(false)
26+ , m_displayMarginBeginning(0)
27+ , m_displayMarginEnd(0)
3028 , m_needsRelayout(false)
3129 , m_delegateValidated(false)
3230 , m_implicitHeightDirty(false)
@@ -46,17 +44,10 @@ void AbstractDashView::setModel(QAbstractItemModel *model)
4644 if (!m_delegateModel) {
4745 createDelegateModel();
4846 } else {
49−#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
50− disconnect(m_delegateModel, SIGNAL(modelUpdated(QQuickChangeSet,bool)), this, SLOT(onModelUpdated(QQuickChangeSet,bool)));
51− }
52− m_delegateModel->setModel(QVariant::fromValue<QAbstractItemModel *>(model));
53− connect(m_delegateModel, SIGNAL(modelUpdated(QQuickChangeSet,bool)), this, SLOT(onModelUpdated(QQuickChangeSet,bool)));
54−#else
5547 disconnect(m_delegateModel, SIGNAL(modelUpdated(QQmlChangeSet,bool)), this, SLOT(onModelUpdated(QQmlChangeSet,bool)));
5648 }
5749 m_delegateModel->setModel(QVariant::fromValue<QAbstractItemModel *>(model));
5850 connect(m_delegateModel, SIGNAL(modelUpdated(QQmlChangeSet,bool)), this, SLOT(onModelUpdated(QQmlChangeSet,bool)));
59−#endif
6051
6152 cleanupExistingItems();
6253
@@ -121,73 +112,42 @@ void AbstractDashView::setRowSpacing(qreal rowSpacing)
121112 }
122113}
123114
124−qreal AbstractDashView::delegateCreationBegin() const
125−{
126− return m_delegateCreationBegin;
127−}
128−
129−void AbstractDashView::setDelegateCreationBegin(qreal begin)
115+qreal AbstractDashView::displayMarginBeginning() const
130116{
131− m_delegateCreationBeginValid = true;
132− if (m_delegateCreationBegin == begin)
133− return;
134− m_delegateCreationBegin = begin;
135− if (isComponentComplete()) {
136− polish();
137− }
138− emit delegateCreationBeginChanged();
117+ return m_displayMarginBeginning;
139118}
140119
141−void AbstractDashView::resetDelegateCreationBegin()
120+void AbstractDashView::setDisplayMarginBeginning(qreal begin)
142121{
143− m_delegateCreationBeginValid = false;
144− if (m_delegateCreationBegin == 0)
122+ if (m_displayMarginBeginning == begin)
145123 return;
146− m_delegateCreationBegin = 0;
124+ m_displayMarginBeginning = begin;
147125 if (isComponentComplete()) {
148126 polish();
149127 }
150− emit delegateCreationBeginChanged();
128+ emit displayMarginBeginningChanged();
151129}
152130
153−qreal AbstractDashView::delegateCreationEnd() const
131+qreal AbstractDashView::displayMarginEnd() const
154132{
155− return m_delegateCreationEnd;
133+ return m_displayMarginEnd;
156134}
157135
158−void AbstractDashView::setDelegateCreationEnd(qreal end)
136+void AbstractDashView::setDisplayMarginEnd(qreal end)
159137{
160− m_delegateCreationEndValid = true;
161− if (m_delegateCreationEnd == end)
138+ if (m_displayMarginEnd == end)
162139 return;
163− m_delegateCreationEnd = end;
140+ m_displayMarginEnd = end;
164141 if (isComponentComplete()) {
165142 polish();
166143 }
167− emit delegateCreationEndChanged();
168−}
169−
170−void AbstractDashView::resetDelegateCreationEnd()
171−{
172− m_delegateCreationEndValid = false;
173− if (m_delegateCreationEnd == 0)
174− return;
175− m_delegateCreationEnd = 0;
176− if (isComponentComplete()) {
177− polish();
178− }
179− emit delegateCreationEndChanged();
144+ emit displayMarginEndChanged();
180145}
181146
182147void AbstractDashView::createDelegateModel()
183148{
184−#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
185− m_delegateModel = new QQuickVisualDataModel(qmlContext(this), this);
186− connect(m_delegateModel, SIGNAL(createdItem(int,QQuickItem*)), this, SLOT(itemCreated(int,QQuickItem*)));
187−#else
188149 m_delegateModel = new QQmlDelegateModel(qmlContext(this), this);
189150 connect(m_delegateModel, SIGNAL(createdItem(int,QObject*)), this, SLOT(itemCreated(int,QObject*)));
190−#endif
191151 if (isComponentComplete())
192152 m_delegateModel->componentComplete();
193153}
@@ -198,9 +158,8 @@ void AbstractDashView::refill()
198158 return;
199159 }
200160
201− const bool delegateRangesValid = m_delegateCreationBeginValid && m_delegateCreationEndValid;
202− const qreal from = delegateRangesValid ? m_delegateCreationBegin : 0;
203− const qreal to = delegateRangesValid ? m_delegateCreationEnd : from + height();
161+ const qreal from = -m_displayMarginBeginning;
162+ const qreal to = height() + m_displayMarginEnd;
204163 const qreal buffer = (to - from) * bufferRatio;
205164 const qreal bufferFrom = from - buffer;
206165 const qreal bufferTo = to + buffer;
@@ -253,16 +212,9 @@ QQuickItem *AbstractDashView::createItem(int modelIndex, bool asynchronous)
253212 return nullptr;
254213
255214 m_asyncRequestedIndex = -1;
256−#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
257− QQuickItem *item = m_delegateModel->item(modelIndex, asynchronous);
258−#else
259215 QObject* object = m_delegateModel->object(modelIndex, asynchronous);
260216 QQuickItem *item = qmlobject_cast<QQuickItem*>(object);
261−#endif
262217 if (!item) {
263−#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
264− m_asyncRequestedIndex = modelIndex;
265−#else
266218 if (object) {
267219 m_delegateModel->release(object);
268220 if (!m_delegateValidated) {
@@ -273,7 +225,6 @@ QQuickItem *AbstractDashView::createItem(int modelIndex, bool asynchronous)
273225 } else {
274226 m_asyncRequestedIndex = modelIndex;
275227 }
276−#endif
277228 return nullptr;
278229 } else {
279230 addItemToView(modelIndex, item);
@@ -283,13 +234,8 @@ QQuickItem *AbstractDashView::createItem(int modelIndex, bool asynchronous)
283234
284235void AbstractDashView::releaseItem(QQuickItem *item)
285236{
286−#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
287− QQuickVisualModel::ReleaseFlags flags = m_delegateModel->release(item);
288− if (flags & QQuickVisualModel::Destroyed) {
289−#else
290237 QQmlDelegateModel::ReleaseFlags flags = m_delegateModel->release(item);
291238 if (flags & QQmlDelegateModel::Destroyed) {
292−#endif
293239 item->setParentItem(nullptr);
294240 }
295241}
@@ -299,10 +245,6 @@ void AbstractDashView::setImplicitHeightDirty()
299245 m_implicitHeightDirty = true;
300246}
301247
302−#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
303−void AbstractDashView::itemCreated(int modelIndex, QQuickItem *item)
304−{
305−#else
306248void AbstractDashView::itemCreated(int modelIndex, QObject *object)
307249{
308250 QQuickItem *item = qmlobject_cast<QQuickItem*>(object);
@@ -310,7 +252,6 @@ void AbstractDashView::itemCreated(int modelIndex, QObject *object)
310252 qWarning() << "AbstractDashView::itemCreated got a non item for index" << modelIndex;
311253 return;
312254 }
313−#endif
314255 item->setParentItem(this);
315256
316257 // We only need to call createItem if we are here because of an asynchronous generation
@@ -325,11 +266,7 @@ void AbstractDashView::itemCreated(int modelIndex, QObject *object)
325266 }
326267}
327268
328−#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
329−void AbstractDashView::onModelUpdated(const QQuickChangeSet &changeSet, bool reset)
330−#else
331269void AbstractDashView::onModelUpdated(const QQmlChangeSet &changeSet, bool reset)
332−#endif
333270{
334271 if (reset) {
335272 cleanupExistingItems();
@@ -364,9 +301,8 @@ void AbstractDashView::updatePolish()
364301
365302 refill();
366303
367− const bool delegateRangesValid = m_delegateCreationBeginValid && m_delegateCreationEndValid;
368− const qreal from = delegateRangesValid ? m_delegateCreationBegin : 0;
369− const qreal to = delegateRangesValid ? m_delegateCreationEnd : from + height();
304+ const qreal from = -m_displayMarginBeginning;
305+ const qreal to = height() + m_displayMarginEnd;
370306 updateItemCulling(from, to);
371307
372308 if (m_implicitHeightDirty) {
plugins/DashViews/abstractdashview.h → plugins/Dash/abstractdashview.hrenamed+14−37
@@ -23,12 +23,8 @@ class QAbstractItemModel;
2323class QQmlComponent;
2424#pragma GCC diagnostic push
2525#pragma GCC diagnostic ignored "-pedantic"
26−#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
27−#include <private/qquickvisualdatamodel_p.h>
28−#else
2926#include <private/qqmldelegatemodel_p.h>
3027#include <qqmlinfo.h>
31−#endif
3228#pragma GCC diagnostic pop
3329
3430class AbstractDashView : public QQuickItem
@@ -39,14 +35,12 @@ class AbstractDashView : public QQuickItem
3935 Q_PROPERTY(QQmlComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged)
4036 Q_PROPERTY(qreal columnSpacing READ columnSpacing WRITE setColumnSpacing NOTIFY columnSpacingChanged)
4137 Q_PROPERTY(qreal rowSpacing READ rowSpacing WRITE setRowSpacing NOTIFY rowSpacingChanged)
42− Q_PROPERTY(qreal delegateCreationBegin READ delegateCreationBegin
43− WRITE setDelegateCreationBegin
44− NOTIFY delegateCreationBeginChanged
45− RESET resetDelegateCreationBegin)
46− Q_PROPERTY(qreal delegateCreationEnd READ delegateCreationEnd
47− WRITE setDelegateCreationEnd
48− NOTIFY delegateCreationEndChanged
49− RESET resetDelegateCreationEnd)
38+ Q_PROPERTY(qreal displayMarginBeginning READ displayMarginBeginning
39+ WRITE setDisplayMarginBeginning
40+ NOTIFY displayMarginBeginningChanged)
41+ Q_PROPERTY(qreal displayMarginEnd READ displayMarginEnd
42+ WRITE setDisplayMarginEnd
43+ NOTIFY displayMarginEndChanged)
5044
5145friend class VerticalJournalTest;
5246friend class HorizontalJournalTest;
@@ -67,21 +61,19 @@ public:
6761 qreal rowSpacing() const;
6862 void setRowSpacing(qreal rowSpacing);
6963
70− qreal delegateCreationBegin() const;
71− void setDelegateCreationBegin(qreal);
72− void resetDelegateCreationBegin();
64+ qreal displayMarginBeginning() const;
65+ void setDisplayMarginBeginning(qreal);
7366
74− qreal delegateCreationEnd() const;
75− void setDelegateCreationEnd(qreal);
76− void resetDelegateCreationEnd();
67+ qreal displayMarginEnd() const;
68+ void setDisplayMarginEnd(qreal);
7769
7870Q_SIGNALS:
7971 void modelChanged();
8072 void delegateChanged();
8173 void columnSpacingChanged();
8274 void rowSpacingChanged();
83− void delegateCreationBeginChanged();
84− void delegateCreationEndChanged();
75+ void displayMarginBeginningChanged();
76+ void displayMarginEndChanged();
8577
8678protected Q_SLOTS:
8779 void relayout();
@@ -94,13 +86,8 @@ protected:
9486 void setImplicitHeightDirty();
9587
9688private Q_SLOTS:
97−#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
98− void itemCreated(int modelIndex, QQuickItem *item);
99− void onModelUpdated(const QQuickChangeSet &changeSet, bool reset);
100−#else
10189 void itemCreated(int modelIndex, QObject *object);
10290 void onModelUpdated(const QQmlChangeSet &changeSet, bool reset);
103−#endif
10491 void onHeightChanged();
10592
10693private:
@@ -117,27 +104,17 @@ private:
117104 virtual void doRelayout() = 0;
118105 virtual void updateItemCulling(qreal visibleFromY, qreal visibleToY) = 0;
119106 virtual void calculateImplicitHeight() = 0;
120−#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
121− virtual void processModelRemoves(const QVector<QQuickChangeSet::Remove> &removes) = 0;
122−#else
123107 virtual void processModelRemoves(const QVector<QQmlChangeSet::Remove> &removes) = 0;
124−#endif
125108
126−#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
127− QQuickVisualDataModel *m_delegateModel;
128−#else
129109 QQmlDelegateModel *m_delegateModel;
130−#endif
131110
132111 // Index we are waiting because we requested it asynchronously
133112 int m_asyncRequestedIndex;
134113
135114 int m_columnSpacing;
136115 int m_rowSpacing;
137− qreal m_delegateCreationBegin;
138− qreal m_delegateCreationEnd;
139− bool m_delegateCreationBeginValid;
140− bool m_delegateCreationEndValid;
116+ qreal m_displayMarginBeginning;
117+ qreal m_displayMarginEnd;
141118 bool m_needsRelayout;
142119 bool m_delegateValidated;
143120 bool m_implicitHeightDirty;
plugins/DashViews/horizontaljournal.cpp → plugins/Dash/horizontaljournal.cpprenamed−12
@@ -28,12 +28,8 @@
2828#include <qqmlengine.h>
2929#pragma GCC diagnostic push
3030#pragma GCC diagnostic ignored "-pedantic"
31−#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
32−#include <private/qquickvisualdatamodel_p.h>
33−#else
3431#include <private/qqmldelegatemodel_p.h>
3532#include <qqmlinfo.h>
36−#endif
3733#include <private/qquickitem_p.h>
3834#pragma GCC diagnostic pop
3935
@@ -188,17 +184,9 @@ void HorizontalJournal::calculateImplicitHeight()
188184 }
189185}
190186
191−#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
192−void HorizontalJournal::processModelRemoves(const QVector<QQuickChangeSet::Remove> &removes)
193−#else
194187void HorizontalJournal::processModelRemoves(const QVector<QQmlChangeSet::Remove> &removes)
195−#endif
196188{
197−#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
198− Q_FOREACH(const QQuickChangeSet::Remove &remove, removes) {
199−#else
200189 Q_FOREACH(const QQmlChangeSet::Remove &remove, removes) {
201−#endif
202190 for (int i = remove.count - 1; i >= 0; --i) {
203191 const int indexToRemove = remove.index + i;
204192 // We only support removing from the end so
plugins/DashViews/horizontaljournal.h → plugins/Dash/horizontaljournal.hrenamed−4
@@ -52,11 +52,7 @@ private:
5252 void calculateImplicitHeight() override;
5353 void doRelayout() override;
5454 void updateItemCulling(qreal visibleFromY, qreal visibleToY) override;
55−#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
56− void processModelRemoves(const QVector<QQuickChangeSet::Remove> &removes) override;
57−#else
5855 void processModelRemoves(const QVector<QQmlChangeSet::Remove> &removes) override;
59−#endif
6056
6157 int m_firstVisibleIndex;
6258 QList<QQuickItem*> m_visibleItems;
plugins/DashViews/listviewwithpageheader.cpp → plugins/Dash/listviewwithpageheader.cpprenamed−50
@@ -97,11 +97,7 @@
9797#include <qqmlengine.h>
9898#pragma GCC diagnostic push
9999#pragma GCC diagnostic ignored "-pedantic"
100−#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
101−#include <private/qquickvisualdatamodel_p.h>
102−#else
103100#include <private/qqmldelegatemodel_p.h>
104−#endif
105101#include <private/qqmlglobal_p.h>
106102#include <private/qquickitem_p.h>
107103#include <private/qquickanimation_p.h>
@@ -191,17 +187,10 @@ void ListViewWithPageHeader::setModel(QAbstractItemModel *model)
191187 if (!m_delegateModel) {
192188 createDelegateModel();
193189 } else {
194−#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
195− disconnect(m_delegateModel, SIGNAL(modelUpdated(QQuickChangeSet,bool)), this, SLOT(onModelUpdated(QQuickChangeSet,bool)));
196− }
197− m_delegateModel->setModel(QVariant::fromValue<QAbstractItemModel *>(model));
198− connect(m_delegateModel, SIGNAL(modelUpdated(QQuickChangeSet,bool)), this, SLOT(onModelUpdated(QQuickChangeSet,bool)));
199−#else
200190 disconnect(m_delegateModel, SIGNAL(modelUpdated(QQmlChangeSet,bool)), this, SLOT(onModelUpdated(QQmlChangeSet,bool)));
201191 }
202192 m_delegateModel->setModel(QVariant::fromValue<QAbstractItemModel *>(model));
203193 connect(m_delegateModel, SIGNAL(modelUpdated(QQmlChangeSet,bool)), this, SLOT(onModelUpdated(QQmlChangeSet,bool)));
204−#endif
205194 Q_EMIT modelChanged();
206195 polish();
207196 // TODO?
@@ -570,13 +559,8 @@ void ListViewWithPageHeader::viewportMoved(Qt::Orientations orient)
570559
571560void ListViewWithPageHeader::createDelegateModel()
572561{
573−#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
574− m_delegateModel = new QQuickVisualDataModel(qmlContext(this), this);
575− connect(m_delegateModel, SIGNAL(createdItem(int,QQuickItem*)), this, SLOT(itemCreated(int,QQuickItem*)));
576−#else
577562 m_delegateModel = new QQmlDelegateModel(qmlContext(this), this);
578563 connect(m_delegateModel, SIGNAL(createdItem(int,QObject*)), this, SLOT(itemCreated(int,QObject*)));
579−#endif
580564 if (isComponentComplete())
581565 m_delegateModel->componentComplete();
582566 updateWatchedRoles();
@@ -657,13 +641,8 @@ bool ListViewWithPageHeader::addVisibleItems(qreal fillFrom, qreal fillTo, bool
657641void ListViewWithPageHeader::reallyReleaseItem(ListItem *listItem)
658642{
659643 QQuickItem *item = listItem->m_item;
660−#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
661− QQuickVisualModel::ReleaseFlags flags = m_delegateModel->release(item);
662− if (flags & QQuickVisualModel::Destroyed) {
663−#else
664644 QQmlDelegateModel::ReleaseFlags flags = m_delegateModel->release(item);
665645 if (flags & QQmlDelegateModel::Destroyed) {
666−#endif
667646 item->setParentItem(nullptr);
668647 }
669648 delete listItem->m_sectionItem;
@@ -796,16 +775,9 @@ ListViewWithPageHeader::ListItem *ListViewWithPageHeader::createItem(int modelIn
796775 return nullptr;
797776
798777 m_asyncRequestedIndex = -1;
799−#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
800− QQuickItem *item = m_delegateModel->item(modelIndex, asynchronous);
801−#else
802778 QObject* object = m_delegateModel->object(modelIndex, asynchronous);
803779 QQuickItem *item = qmlobject_cast<QQuickItem*>(object);
804−#endif
805780 if (!item) {
806−#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
807− m_asyncRequestedIndex = modelIndex;
808−#else
809781 if (object) {
810782 m_delegateModel->release(object);
811783 if (!m_delegateValidated) {
@@ -816,7 +788,6 @@ ListViewWithPageHeader::ListItem *ListViewWithPageHeader::createItem(int modelIn
816788 } else {
817789 m_asyncRequestedIndex = modelIndex;
818790 }
819−#endif
820791 return 0;
821792 } else {
822793// qDebug() << "ListViewWithPageHeader::createItem::We have the item" << modelIndex << item;
@@ -872,10 +843,6 @@ ListViewWithPageHeader::ListItem *ListViewWithPageHeader::createItem(int modelIn
872843 }
873844}
874845
875−#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
876−void ListViewWithPageHeader::itemCreated(int modelIndex, QQuickItem *item)
877−{
878−#else
879846void ListViewWithPageHeader::itemCreated(int modelIndex, QObject *object)
880847{
881848 QQuickItem *item = qmlobject_cast<QQuickItem*>(object);
@@ -883,7 +850,6 @@ void ListViewWithPageHeader::itemCreated(int modelIndex, QObject *object)
883850 qWarning() << "ListViewWithPageHeader::itemCreated got a non item for index" << modelIndex;
884851 return;
885852 }
886−#endif
887853// qDebug() << "ListViewWithPageHeader::itemCreated" << modelIndex << item;
888854 // Check we are not being taken down and don't paint anything
889855 // TODO Check if we still need this in 5.2
@@ -924,21 +890,13 @@ void ListViewWithPageHeader::onHeightChanged()
924890}
925891
926892
927−#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
928−void ListViewWithPageHeader::onModelUpdated(const QQuickChangeSet &changeSet, bool /*reset*/)
929−#else
930893void ListViewWithPageHeader::onModelUpdated(const QQmlChangeSet &changeSet, bool /*reset*/)
931−#endif
932894{
933895 // TODO Do something with reset
934896// qDebug() << "ListViewWithPageHeader::onModelUpdated" << changeSet << reset;
935897 const auto oldFirstVisibleIndex = m_firstVisibleIndex;
936898
937−#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
938− Q_FOREACH(const QQuickChangeSet::Remove &remove, changeSet.removes()) {
939−#else
940899 Q_FOREACH(const QQmlChangeSet::Remove &remove, changeSet.removes()) {
941−#endif
942900// qDebug() << "ListViewWithPageHeader::onModelUpdated Remove" << remove.index << remove.count;
943901 if (remove.index + remove.count > m_firstVisibleIndex && remove.index < m_firstVisibleIndex + m_visibleItems.count()) {
944902 const qreal oldFirstValidIndexPos = m_visibleItems.first()->y();
@@ -992,11 +950,7 @@ void ListViewWithPageHeader::onModelUpdated(const QQmlChangeSet &changeSet, bool
992950 }
993951 }
994952
995−#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
996− Q_FOREACH(const QQuickChangeSet::Insert &insert, changeSet.inserts()) {
997−#else
998953 Q_FOREACH(const QQmlChangeSet::Insert &insert, changeSet.inserts()) {
999−#endif
1000954// qDebug() << "ListViewWithPageHeader::onModelUpdated Insert" << insert.index << insert.count;
1001955 const bool insertingInValidIndexes = insert.index > m_firstVisibleIndex && insert.index < m_firstVisibleIndex + m_visibleItems.count();
1002956 const bool firstItemWithViewOnTop = insert.index == 0 && m_firstVisibleIndex == 0 && m_visibleItems.first()->y() + m_clipItem->y() > contentY();
@@ -1054,11 +1008,7 @@ void ListViewWithPageHeader::onModelUpdated(const QQmlChangeSet &changeSet, bool
10541008 }
10551009 }
10561010
1057−#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
1058− Q_FOREACH(const QQuickChangeSet::Change &change, changeSet.changes()) {
1059−#else
10601011 Q_FOREACH(const QQmlChangeSet::Change &change, changeSet.changes()) {
1061−#endif
10621012// qDebug() << "ListViewWithPageHeader::onModelUpdated Change" << change.index << change.count;
10631013 for (int i = change.index; i < change.count; ++i) {
10641014 ListItem *item = itemAtIndex(i);
plugins/DashViews/listviewwithpageheader.h → plugins/Dash/listviewwithpageheader.hrenamed−20
@@ -17,21 +17,13 @@
1717#ifndef LISTVIEWWITHPAGEHEADER_H
1818#define LISTVIEWWITHPAGEHEADER_H
1919
20−#pragma GCC diagnostic push
21−#pragma GCC diagnostic ignored "-pedantic"
2220#include <private/qquickitemchangelistener_p.h>
2321#include <private/qquickflickable_p.h>
24−#pragma GCC diagnostic pop
2522
2623class QAbstractItemModel;
2724class QQuickNumberAnimation;
28−#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
29−class QQuickChangeSet;
30−class QQuickVisualDataModel;
31−#else
3225class QQmlChangeSet;
3326class QQmlDelegateModel;
34−#endif
3527
3628
3729/**
@@ -117,19 +109,11 @@ protected:
117109 void updatePolish();
118110
119111private Q_SLOTS:
120−#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
121− void itemCreated(int modelIndex, QQuickItem *item);
122−#else
123112 void itemCreated(int modelIndex, QObject *object);
124−#endif
125113 void onContentHeightChanged();
126114 void onContentWidthChanged();
127115 void onHeightChanged();
128−#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
129− void onModelUpdated(const QQuickChangeSet &changeSet, bool reset);
130−#else
131116 void onModelUpdated(const QQmlChangeSet &changeSet, bool reset);
132−#endif
133117 void onShowHeaderAnimationFinished();
134118
135119private:
@@ -168,11 +152,7 @@ private:
168152 QQuickItem *getSectionItem(int modelIndex, bool alreadyInserted);
169153 QQuickItem *getSectionItem(const QString &sectionText);
170154
171−#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
172− QQuickVisualDataModel *m_delegateModel;
173−#else
174155 QQmlDelegateModel *m_delegateModel;
175−#endif
176156
177157 // Index we are waiting because we requested it asynchronously
178158 int m_asyncRequestedIndex;
plugins/DashViews/organicgrid.cpp → plugins/Dash/organicgrid.cpprenamed−8
@@ -237,17 +237,9 @@ void OrganicGrid::calculateImplicitHeight()
237237 }
238238}
239239
240−#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
241−void OrganicGrid::processModelRemoves(const QVector<QQuickChangeSet::Remove> &removes)
242−#else
243240void OrganicGrid::processModelRemoves(const QVector<QQmlChangeSet::Remove> &removes)
244−#endif
245241{
246−#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
247− Q_FOREACH(const QQuickChangeSet::Remove &remove, removes) {
248−#else
249242 Q_FOREACH(const QQmlChangeSet::Remove &remove, removes) {
250−#endif
251243 for (int i = remove.count - 1; i >= 0; --i) {
252244 const int indexToRemove = remove.index + i;
253245 // We only support removing from the end
plugins/DashViews/organicgrid.h → plugins/Dash/organicgrid.hrenamed−4
@@ -79,11 +79,7 @@ private:
7979 void doRelayout() override;
8080 void updateItemCulling(qreal visibleFromY, qreal visibleToY) override;
8181 void calculateImplicitHeight() override;
82−#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
83− void processModelRemoves(const QVector<QQuickChangeSet::Remove> &removes) override;
84−#else
8582 void processModelRemoves(const QVector<QQmlChangeSet::Remove> &removes) override;
86−#endif
8783
8884 QSizeF m_smallDelegateSize;
8985 QSizeF m_bigDelegateSize;
plugins/DashViews/plugin.cpp → plugins/Dash/plugin.cpprenamed+2−2
@@ -24,9 +24,9 @@
2424
2525#include <QAbstractItemModel>
2626
27−void DashViewsPlugin::registerTypes(const char *uri)
27+void DashPlugin::registerTypes(const char *uri)
2828{
29− Q_ASSERT(uri == QLatin1String("DashViews"));
29+ Q_ASSERT(uri == QLatin1String("Dash"));
3030 qmlRegisterType<QAbstractItemModel>();
3131 qmlRegisterType<HorizontalJournal>(uri, 0, 1, "HorizontalJournal");
3232 qmlRegisterType<ListViewWithPageHeader>(uri, 0, 1, "ListViewWithPageHeader");
plugins/DashViews/plugin.h → plugins/Dash/plugin.hrenamed+3−3
@@ -15,13 +15,13 @@
1515 *
1616 */
1717
18−#ifndef DASHVIEWS_PLUGIN_H
19−#define DASHVIEWS_PLUGIN_H
18+#ifndef DASH_PLUGIN_H
19+#define DASH_PLUGIN_H
2020
2121#include <QtQml/QQmlEngine>
2222#include <QtQml/QQmlExtensionPlugin>
2323
24−class DashViewsPlugin : public QQmlExtensionPlugin
24+class DashPlugin : public QQmlExtensionPlugin
2525{
2626 Q_OBJECT
2727 Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
plugins/Dash/qmldirnew file+4
@@ -0,0 +1,4 @@
1+module Dash
2+plugin Dash-qml
3+typeinfo Dash.qmltypes
4+singleton CardCreatorCache 0.1 CardCreatorCache.qml
plugins/DashViews/verticaljournal.cpp → plugins/Dash/verticaljournal.cpprenamed−8
@@ -239,17 +239,9 @@ void VerticalJournal::updateItemCulling(qreal visibleFromY, qreal visibleToY)
239239 }
240240}
241241
242−#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
243−void VerticalJournal::processModelRemoves(const QVector<QQuickChangeSet::Remove> &removes)
244−#else
245242void VerticalJournal::processModelRemoves(const QVector<QQmlChangeSet::Remove> &removes)
246−#endif
247243{
248−#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
249− Q_FOREACH(const QQuickChangeSet::Remove &remove, removes) {
250−#else
251244 Q_FOREACH(const QQmlChangeSet::Remove &remove, removes) {
252−#endif
253245 for (int i = remove.count - 1; i >= 0; --i) {
254246 const int indexToRemove = remove.index + i;
255247 // Since we only support removing from the end, indexToRemove
plugins/DashViews/verticaljournal.h → plugins/Dash/verticaljournal.hrenamed−4
@@ -90,11 +90,7 @@ private:
9090 void calculateImplicitHeight() override;
9191 void doRelayout() override;
9292 void updateItemCulling(qreal visibleFromY, qreal visibleToY) override;
93−#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
94− void processModelRemoves(const QVector<QQuickChangeSet::Remove> &removes) override;
95−#else
9693 void processModelRemoves(const QVector<QQmlChangeSet::Remove> &removes) override;
97−#endif
9894
9995 QVector<QList<ViewItem>> m_columnVisibleItems;
10096 QHash<int, int> m_indexColumnMap;
plugins/DashViews/qmldirdeleted−3
@@ -1,3 +0,0 @@
1−module DashViews
2−plugin DashViews-qml
3−typeinfo plugin.qmltypes
plugins/HudClient/CMakeLists.txt+1−6
@@ -1,6 +1,3 @@
1−# export_qmlplugin macro
2−include(Plugins)
3−
41find_package(Qt5Core REQUIRED)
52find_package(Qt5Quick REQUIRED)
63pkg_search_module(DEE dee-1.0 REQUIRED)
@@ -38,6 +35,4 @@ target_link_libraries(HudClientQml
3835
3936qt5_use_modules(HudClientQml Qml)
4037
41−# export the qmldir qmltypes and plugin files
42−export_qmlfiles(HudClient HudClient)
43−export_qmlplugin(HudClient 0.1 HudClient TARGETS HudClientQml)
38+add_unity8_plugin(HudClient 0.1 HudClient TARGETS HudClientQml)
plugins/HudClient/qmldir+1−1
@@ -1,3 +1,3 @@
11module HudClient
22plugin HudClientQml
3−typeinfo plugin.qmltypes
3+typeinfo HudClient.qmltypes
plugins/LightDM/CMakeLists.txt+1−6
@@ -1,6 +1,3 @@
1−# export_qmlplugin macro
2−include(Plugins)
3−
41# Dependencies
52include(FindPkgConfig)
63pkg_check_modules(LIBUSERMETRICSOUTPUT REQUIRED libusermetricsoutput-1)
@@ -37,6 +34,4 @@ target_link_libraries(LightDM-qml
3734
3835qt5_use_modules(LightDM-qml DBus Gui Qml)
3936
40−# export the qmldir qmltypes and plugin files
41−export_qmlfiles(LightDM LightDM)
42−export_qmlplugin(LightDM 0.1 LightDM TARGETS LightDM-qml)
37+add_unity8_plugin(LightDM 0.1 LightDM TARGETS LightDM-qml)
plugins/LightDM/qmldir+1−1
@@ -1,3 +1,3 @@
11module LightDM
22plugin LightDM-qml
3−typeinfo plugin.qmltypes
3+typeinfo LightDM.qmltypes
plugins/Powerd/CMakeLists.txt+1−3
@@ -1,4 +1,3 @@
1−include(Plugins)
21include(FindPkgConfig)
32
43pkg_search_module(GIO REQUIRED gio-2.0)
@@ -17,5 +16,4 @@ add_library(Powerd-qml MODULE
1716qt5_use_modules(Powerd-qml DBus Qml)
1817target_link_libraries(Powerd-qml ${GIO_LDFLAGS})
1918
20−export_qmlfiles(Powerd Powerd)
21−export_qmlplugin(Powerd 0.1 Powerd TARGETS Powerd-qml)
19+add_unity8_plugin(Powerd 0.1 Powerd TARGETS Powerd-qml)
plugins/Powerd/qmldir+1−1
@@ -1,3 +1,3 @@
11module Powerd
22plugin Powerd-qml
3−typeinfo plugin.qmltypes
3+typeinfo Powerd.qmltypes
plugins/SessionBroadcast/CMakeLists.txt+1−4
@@ -1,5 +1,3 @@
1−include(Plugins)
2−
31add_definitions(-DSM_BUSNAME=systemBus)
42
53add_library(SessionBroadcast-qml MODULE
@@ -9,5 +7,4 @@ add_library(SessionBroadcast-qml MODULE
97
108qt5_use_modules(SessionBroadcast-qml DBus Qml)
119
12−export_qmlfiles(SessionBroadcast SessionBroadcast)
13−export_qmlplugin(SessionBroadcast 0.1 SessionBroadcast TARGETS SessionBroadcast-qml)
10+add_unity8_plugin(SessionBroadcast 0.1 SessionBroadcast TARGETS SessionBroadcast-qml)
plugins/SessionBroadcast/qmldir+1−1
@@ -1,3 +1,3 @@
11module SessionBroadcast
22plugin SessionBroadcast-qml
3−typeinfo plugin.qmltypes
3+typeinfo SessionBroadcast.qmltypes
plugins/Ubuntu/DownloadDaemonListener/CMakeLists.txt+1−6
@@ -1,6 +1,3 @@
1−# export_qmlplugin macro
2−include(Plugins)
3−
41include_directories(
52 ${CMAKE_CURRENT_SOURCE_DIR}
63 ${CMAKE_CURRENT_BINARY_DIR}
@@ -17,6 +14,4 @@ add_library(DownloadDaemonListener MODULE ${DOWNLOADDAEMONLISTENER_SOURCES})
1714
1815qt5_use_modules(DownloadDaemonListener Qml Quick DBus Core)
1916
20−# export the qmldir qmltypes and plugin files
21−export_qmlfiles(Ubuntu.DownloadDaemonListener Ubuntu/DownloadDaemonListener)
22−export_qmlplugin(Ubuntu.DownloadDaemonListener 0.1 Ubuntu/DownloadDaemonListener TARGETS DownloadDaemonListener)
17+add_unity8_plugin(Ubuntu.DownloadDaemonListener 0.1 Ubuntu/DownloadDaemonListener TARGETS DownloadDaemonListener)
plugins/Ubuntu/DownloadDaemonListener/qmldir+1−1
@@ -1,3 +1,3 @@
11module Ubuntu.DownloadDaemonListener
22plugin DownloadDaemonListener
3−typeinfo plugins.qmltypes
3+typeinfo DownloadDaemonListener.qmltypes
plugins/Ubuntu/Gestures/CMakeLists.txt+1−6
@@ -1,6 +1,3 @@
1−# export_qmlplugin macro
2−include(Plugins)
3−
41set(UbuntuGestureQml_SOURCES
52 plugin.cpp
63 AxisVelocityCalculator.cpp
@@ -19,6 +16,4 @@ qt5_use_modules(UbuntuGestureQml Core Quick)
1916# So that Foo.cpp can #include "Foo.moc"
2017include_directories(${CMAKE_CURRENT_BINARY_DIR})
2118
22−# export the qmldir qmltypes and plugin files
23−export_qmlfiles(Ubuntu.Gestures Ubuntu/Gestures)
24−export_qmlplugin(Ubuntu.Gestures 0.1 Ubuntu/Gestures TARGETS UbuntuGestureQml)
19+add_unity8_plugin(Ubuntu.Gestures 0.1 Ubuntu/Gestures TARGETS UbuntuGestureQml)
plugins/Ubuntu/Gestures/qmldir+1−1
@@ -1,3 +1,3 @@
11module Ubuntu.Gestures
22plugin UbuntuGestureQml
3−typeinfo plugin.qmltypes
3+typeinfo Gestures.qmltypes
plugins/Unity/Indicators/CMakeLists.txt+4−7
@@ -1,6 +1,3 @@
1−# export_qmlplugin macro
2−include(Plugins)
3−
41project(IndicatorsQml)
52
63pkg_check_modules(GLIB REQUIRED glib-2.0>=2.32)
@@ -10,8 +7,6 @@ pkg_check_modules(QMENUMODEL REQUIRED qmenumodel)
107find_package(Qt5Core REQUIRED)
118find_package(Qt5Quick REQUIRED)
129
13−add_subdirectory(qml)
14−
1510include_directories(
1611 ${CMAKE_CURRENT_SOURCE_DIR}
1712 ${CMAKE_CURRENT_BINARY_DIR}
@@ -56,5 +51,7 @@ target_link_libraries(IndicatorsQml
5651
5752qt5_use_modules(IndicatorsQml Core Qml Quick)
5853
59−# export the qmltypes and plugin files
60−export_qmlplugin(Unity.Indicators 0.1 Unity/Indicators TARGETS IndicatorsQml)
54+add_unity8_plugin(Unity.Indicators 0.1 Unity/Indicators
55+ SEARCH_PATH qml
56+ TARGETS IndicatorsQml
57+)
plugins/Unity/Indicators/menucontentactivator.cpp−1
@@ -316,7 +316,6 @@ MenuContentState* MenuContentActivatorPrivate::content_at(QQmlListProperty<MenuC
316316 if (!d->m_content.contains(index)) {
317317 MenuContentState* content = new MenuContentState(false);
318318 d->m_content[index] = content;
319− Q_EMIT p->contentChanged();
320319 return content;
321320 }
322321
plugins/Unity/Indicators/qml/CMakeLists.txtdeleted−5
@@ -1,5 +0,0 @@
1−# export_qmlplugin macro
2−include(Plugins)
3−
4−# export the qmldir, *.qml files.
5−export_qmlfiles(Unity.Indicators Unity/Indicators)
plugins/Unity/Indicators/qml/MenuItemFactory.qml+1−1
@@ -273,7 +273,7 @@ Item {
273273 text: menuData && menuData.label || ""
274274 iconSource: menuData && menuData.icon || "image://theme/calendar"
275275 time: timeFormatter.timeString
276− eventColor: menu && menu.ext.hasOwnProperty("xCanonicalColor") ? menu.ext.xCanonicalColor : Qt.rgba(0.0, 0.0, 0.0, 0.0)
276+ eventColor: getExtendedProperty(extendedData, "xCanonicalColor", Qt.rgba(0.0, 0.0, 0.0, 0.0))
277277 enabled: menuData && menuData.sensitive || false
278278
279279 onMenuModelChanged: {
plugins/Unity/Indicators/qml/qmldir+1−1
@@ -1,6 +1,6 @@
11module Unity.Indicators
22plugin IndicatorsQml
3−typeinfo plugin.qmltypes
3+typeinfo Indicators.qmltypes
44
55CachedUnityMenuModel 0.1 CachedUnityMenuModel.qml
66IndicatorBase 0.1 IndicatorBase.qml
plugins/Unity/Indicators/rootactionstate.cpp+7−8
@@ -240,19 +240,18 @@ QVariant RootActionState::toQVariant(GVariant* state) const
240240
241241 QStringList icons;
242242
243− if (g_variant_type_is_array(g_variant_get_type(vvalue))) {
244−
245−
246− for (int i = 0, iMax = g_variant_n_children(vvalue); i < iMax; i++) {
247− GVariant *child = g_variant_get_child_value(vvalue, i);
248−
243+ if (g_variant_is_of_type(vvalue, G_VARIANT_TYPE("av"))) {
244+ GVariantIter iter;
245+ GVariant *val = 0;
246+ g_variant_iter_init (&iter, vvalue);
247+ while (g_variant_iter_loop (&iter, "v", &val))
248+ {
249249 // FIXME - should be sending a url.
250− GIcon *gicon = g_icon_deserialize (child);
250+ GIcon *gicon = g_icon_deserialize (val);
251251 if (gicon) {
252252 icons << iconUri(gicon);
253253 g_object_unref (gicon);
254254 }
255− g_variant_unref(child);
256255 }
257256 }
258257 // will overwrite icon.
plugins/Unity/Launcher/CMakeLists.txt+1−3
@@ -32,6 +32,4 @@ target_link_libraries(UnityLauncher-qml ${GSETTINGS_QT_LDFLAGS})
3232
3333qt5_use_modules(UnityLauncher-qml DBus Qml)
3434
35−# export the qmldir and qmltypes files
36−export_qmlfiles(Unity.Launcher Unity/Launcher)
37−export_qmlplugin(Unity.Launcher 0.1 Unity/Launcher TARGETS UnityLauncher-qml)
35+add_unity8_plugin(Unity.Launcher 0.1 Unity/Launcher TARGETS UnityLauncher-qml)
plugins/Unity/Launcher/backend/launcherbackend.cpp+293−29
@@ -31,13 +31,14 @@
3131class LauncherBackendItem
3232{
3333public:
34− QString desktopFile;
3534 QString displayName;
3635 QString icon;
36+ int count;
37+ bool countVisible;
3738};
3839
3940LauncherBackend::LauncherBackend(QObject *parent):
40− QObject(parent),
41+ QDBusVirtualObject(parent),
4142 m_accounts(nullptr)
4243{
4344#ifndef LAUNCHER_TESTING
@@ -45,10 +46,25 @@ LauncherBackend::LauncherBackend(QObject *parent):
4546#endif
4647 m_user = qgetenv("USER");
4748 syncFromAccounts();
49+
50+ /* Set up ourselves on DBus */
51+ QDBusConnection con = QDBusConnection::sessionBus();
52+ if (!con.registerService("com.canonical.Unity.Launcher")) {
53+ qDebug() << "Unable to register launcher name";
54+ }
55+ if (!con.registerVirtualObject("/com/canonical/Unity/Launcher", this, QDBusConnection::VirtualObjectRegisterOption::SubPath)) {
56+ qDebug() << "Unable to register launcher object";
57+ }
4858}
4959
5060LauncherBackend::~LauncherBackend()
5161{
62+ /* Remove oursevles from DBus */
63+ QDBusConnection con = QDBusConnection::sessionBus();
64+ con.unregisterService("com.canonical.Unity.Launcher");
65+ con.unregisterObject("/com/canonical/Unity/Launcher");
66+
67+ /* Clear data */
5268 m_storedApps.clear();
5369
5470 Q_FOREACH(LauncherBackendItem *item, m_itemCache) {
@@ -90,17 +106,12 @@ void LauncherBackend::setStoredApplications(const QStringList &appIds)
90106
91107QString LauncherBackend::desktopFile(const QString &appId) const
92108{
93− LauncherBackendItem *item = m_itemCache.value(appId);
94− if (item) {
95− return item->desktopFile;
96− }
97−
98109 return findDesktopFile(appId);
99110}
100111
101112QString LauncherBackend::displayName(const QString &appId) const
102113{
103− LauncherBackendItem *item = m_itemCache.value(appId);
114+ LauncherBackendItem *item = m_itemCache.value(appId, nullptr);
104115 if (item) {
105116 return item->displayName;
106117 }
@@ -118,16 +129,9 @@ QString LauncherBackend::displayName(const QString &appId) const
118129QString LauncherBackend::icon(const QString &appId) const
119130{
120131 QString iconName;
121− LauncherBackendItem *item = m_itemCache.value(appId);
132+ LauncherBackendItem *item = getItem(appId);
122133 if (item) {
123134 iconName = item->icon;
124− } else {
125− QString df = findDesktopFile(appId);
126− if (!df.isEmpty()) {
127− LauncherBackendItem *item = parseDesktopFile(df);
128− m_itemCache.insert(appId, item);
129− iconName = item->icon;
130− }
131135 }
132136
133137 return iconName;
@@ -153,10 +157,70 @@ int LauncherBackend::progress(const QString &appId) const
153157
154158int LauncherBackend::count(const QString &appId) const
155159{
156− // TODO: Return value for count emblem.
157− // TODO: emit countChanged() when this value changes.
158− Q_UNUSED(appId)
159− return 0;
160+ int count = -1;
161+ LauncherBackendItem *item = getItem(appId);
162+
163+ if (item) {
164+ if (item->countVisible) {
165+ count = item->count;
166+ }
167+ }
168+
169+ return count;
170+}
171+
172+void LauncherBackend::setCount(const QString &appId, int count) const
173+{
174+ LauncherBackendItem *item = getItem(appId);
175+
176+ bool emitchange = false;
177+ if (item) {
178+ emitchange = (item->count != count);
179+ item->count = count;
180+ }
181+
182+ if (emitchange) {
183+ /* TODO: This needs to use the accessor to handle the visibility
184+ correctly, but when we have the two properties we can just use
185+ the local value */
186+ Q_EMIT countChanged(appId, this->count(appId));
187+ QVariant vcount(item->count);
188+ emitPropChangedDbus(appId, "count", vcount);
189+ }
190+}
191+
192+bool LauncherBackend::countVisible(const QString &appId) const
193+{
194+ bool visible = false;
195+ LauncherBackendItem *item = getItem(appId);
196+
197+ if (item) {
198+ visible = item->countVisible;
199+ }
200+
201+ return visible;
202+}
203+
204+void LauncherBackend::setCountVisible(const QString &appId, bool visible) const
205+{
206+ LauncherBackendItem *item = getItem(appId);
207+
208+ bool emitchange = false;
209+ if (item) {
210+ emitchange = (item->countVisible != visible);
211+ item->countVisible = visible;
212+ } else {
213+ qDebug() << "Unable to find:" << appId;
214+ }
215+
216+ if (emitchange) {
217+ /* TODO: Because we're using visible in determining the
218+ count we need to emit a count changed as well */
219+ Q_EMIT countChanged(appId, this->count(appId));
220+ Q_EMIT countVisibleChanged(appId, item->countVisible);
221+ QVariant vCountVisible(item->countVisible);
222+ emitPropChangedDbus(appId, "countVisible", vCountVisible);
223+ }
160224}
161225
162226void LauncherBackend::setUser(const QString &username)
@@ -194,13 +258,33 @@ void LauncherBackend::syncFromAccounts()
194258 Q_FOREACH(const QString &entry, gSettings.get("favorites").toStringList()) {
195259 if (entry.startsWith("application://")) {
196260 QString appId = entry;
197− // Transform "application://foobar.desktop" to "foobar"
261+ // Transform "application://foobar.desktop" to "application://foobar"
198262 appId.remove("application://");
199263 if (appId.endsWith(".desktop")) {
200264 appId.chop(8);
201265 }
202266 QString df = findDesktopFile(appId);
203267
268+ if (!df.isEmpty()) {
269+ m_storedApps << appId;
270+
271+ if (!m_itemCache.contains(appId)) {
272+ m_itemCache.insert(appId, parseDesktopFile(df));
273+ }
274+ }
275+ }
276+ if (entry.startsWith("appid://")) {
277+ QString appId = entry;
278+ appId.remove("appid://");
279+ // Strip hook name and current-user-version in case its there
280+
281+ if (appId.split('/').count() != 3) {
282+ qWarning() << "ignoring entry " + appId + ". Not a valid appId.";
283+ continue;
284+ }
285+ appId = appId.split('/').first() + "_" + appId.split('/').at(1);
286+ QString df = findDesktopFile(appId);
287+
204288 if (!df.isEmpty()) {
205289 m_storedApps << appId;
206290
@@ -245,10 +329,13 @@ QString LauncherBackend::findDesktopFile(const QString &appId) const
245329 helper = helper.replace(dashPos, 1, '/');
246330 }
247331
248− Q_FOREACH(const QString &searchDir, searchDirs) {
249− QFileInfo fileInfo(QDir(searchDir), helper + ".desktop");
250− if (fileInfo.exists()) {
251− return fileInfo.absoluteFilePath();
332+ Q_FOREACH(const QString &searchDirName, searchDirs) {
333+ QDir searchDir(searchDirName);
334+ Q_FOREACH(const QString &desktopFile, searchDir.entryList(QStringList() << "*.desktop")) {
335+ if (desktopFile.startsWith(helper)) {
336+ QFileInfo fileInfo(searchDir, desktopFile);
337+ return fileInfo.absoluteFilePath();
338+ }
252339 }
253340 }
254341
@@ -263,7 +350,6 @@ LauncherBackendItem* LauncherBackend::parseDesktopFile(const QString &desktopFil
263350 QSettings settings(desktopFile, QSettings::IniFormat);
264351
265352 LauncherBackendItem* item = new LauncherBackendItem();
266− item->desktopFile = desktopFile;
267353 item->displayName = settings.value("Desktop Entry/Name").toString();
268354
269355 QString iconString = settings.value("Desktop Entry/Icon").toString();
@@ -275,6 +361,35 @@ LauncherBackendItem* LauncherBackend::parseDesktopFile(const QString &desktopFil
275361 } else {
276362 item->icon = "image://theme/" + iconString;
277363 }
364+
365+ /* TODO: These should be looked up in a cache somewhere */
366+ item->count = 0;
367+ item->countVisible = false;
368+
369+ return item;
370+}
371+
372+/* Gets an item, and tries to create a new one if we need it to */
373+LauncherBackendItem* LauncherBackend::getItem(const QString &appId) const
374+{
375+ LauncherBackendItem *item = m_itemCache.value(appId, nullptr);
376+ if (!item) {
377+ QString df = findDesktopFile(appId);
378+ if (!df.isEmpty()) {
379+ item = parseDesktopFile(df);
380+ if (item) {
381+ m_itemCache[appId] = item;
382+ } else {
383+ qWarning() << "Unable to parse desktop file for" << appId << "path" << df;
384+ }
385+ } else {
386+ qWarning() << "Unable to find desktop file for:" << appId;
387+ }
388+ }
389+
390+ if (!item)
391+ qWarning() << "Unable to find item for: " << appId;
392+
278393 return item;
279394}
280395
@@ -285,16 +400,17 @@ void LauncherBackend::loadFromVariant(const QVariantMap &details)
285400 }
286401 QString appId = details.value("id").toString();
287402
288− LauncherBackendItem *item = m_itemCache.value(appId);
403+ LauncherBackendItem *item = m_itemCache.value(appId, nullptr);
289404 if (item) {
290405 delete item;
291406 }
292407
293408 item = new LauncherBackendItem();
294409
295− item->desktopFile = details.value("desktopFile").toString();
296410 item->displayName = details.value("name").toString();
297411 item->icon = details.value("icon").toString();
412+ item->count = details.value("count").toInt();
413+ item->countVisible = details.value("countVisible").toBool();
298414
299415 m_itemCache.insert(appId, item);
300416 m_storedApps.append(appId);
@@ -307,7 +423,8 @@ QVariantMap LauncherBackend::itemToVariant(const QString &appId) const
307423 details.insert("id", appId);
308424 details.insert("name", item->displayName);
309425 details.insert("icon", item->icon);
310− details.insert("desktopFile", item->desktopFile);
426+ details.insert("count", item->count);
427+ details.insert("countVisible", item->countVisible);
311428 return details;
312429}
313430
@@ -318,3 +435,150 @@ bool LauncherBackend::isDefaultsItem(const QList<QVariantMap> &apps) const
318435 // list of one item with the 'defaults' field set to true.
319436 return (apps.size() == 1 && apps[0].value("defaults").toBool());
320437}
438+
439+bool LauncherBackend::handleMessage(const QDBusMessage& message, const QDBusConnection& connection)
440+{
441+ /* Check to make sure we're getting properties on our interface */
442+ if (message.type() != QDBusMessage::MessageType::MethodCallMessage) {
443+ return false;
444+ }
445+ if (message.interface() != "org.freedesktop.DBus.Properties") {
446+ return false;
447+ }
448+ if (message.arguments()[0].toString() != "com.canonical.Unity.Launcher.Item") {
449+ return false;
450+ }
451+
452+ /* Break down the path to just the app id */
453+ QString pathtemp = message.path();
454+ if (!pathtemp.startsWith("/com/canonical/Unity/Launcher/")) {
455+ return false;
456+ }
457+ pathtemp.remove("/com/canonical/Unity/Launcher/");
458+ if (pathtemp.indexOf('/') >= 0) {
459+ return false;
460+ }
461+
462+ /* Find ourselves an appid */
463+ QString appid = decodeAppId(pathtemp);
464+ QVariantList retval;
465+
466+ if (message.member() == "Get") {
467+ if (message.arguments()[1].toString() == "count") {
468+ retval.append(QVariant::fromValue(QDBusVariant(this->count(appid))));
469+ } else if (message.arguments()[1].toString() == "countVisible") {
470+ retval.append(QVariant::fromValue(QDBusVariant(this->countVisible(appid))));
471+ }
472+ } else if (message.member() == "Set") {
473+ if (message.arguments()[1].toString() == "count") {
474+ this->setCount(appid, message.arguments()[2].value<QDBusVariant>().variant().toInt());
475+ } else if (message.arguments()[1].toString() == "countVisible") {
476+ this->setCountVisible(appid, message.arguments()[2].value<QDBusVariant>().variant().toBool());
477+ }
478+ } else if (message.member() == "GetAll") {
479+ retval.append(this->itemToVariant(appid));
480+ } else {
481+ return false;
482+ }
483+
484+ QDBusMessage reply = message.createReply(retval);
485+ return connection.send(reply);
486+}
487+
488+QString LauncherBackend::introspect(const QString &path) const
489+{
490+ /* This case we should just list the nodes */
491+ if (path == "/com/canonical/Unity/Launcher/" || path == "/com/canonical/Unity/Launcher") {
492+ QString nodes;
493+
494+ Q_FOREACH(const QString &appId, m_itemCache.keys()) {
495+ nodes.append("<node name=\"");
496+ nodes.append(encodeAppId(appId));
497+ nodes.append("\"/>\n");
498+ }
499+
500+ return nodes;
501+ }
502+
503+ /* Should not happen, but let's handle it */
504+ if (!path.startsWith("/com/canonical/Unity/Launcher")) {
505+ return "";
506+ }
507+
508+ /* Now we should be looking at a node */
509+ QString nodeiface =
510+ "<interface name=\"com.canonical.Unity.Launcher.Item\">"
511+ "<property name=\"count\" type=\"i\" access=\"readwrite\" />"
512+ "<property name=\"countVisible\" type=\"b\" access=\"readwrite\" />"
513+ "</interface>";
514+ return nodeiface;
515+}
516+
517+QString LauncherBackend::decodeAppId(const QString& path)
518+{
519+ QByteArray bytes = path.toUtf8();
520+ QByteArray decoded;
521+
522+ for (int i = 0; i < bytes.size(); ++i) {
523+ char chr = bytes.at(i);
524+
525+ if (chr == '_') {
526+ QString number;
527+ number.append(bytes.at(i+1));
528+ number.append(bytes.at(i+2));
529+
530+ bool okay;
531+ char newchar = number.toUInt(&okay, 16);
532+ if (okay)
533+ decoded.append(newchar);
534+
535+ i += 2;
536+ } else {
537+ decoded.append(chr);
538+ }
539+ }
540+
541+ return QString::fromUtf8(decoded);
542+}
543+
544+QString LauncherBackend::encodeAppId(const QString& appId)
545+{
546+ QByteArray bytes = appId.toUtf8();
547+ QString encoded;
548+
549+ for (int i = 0; i < bytes.size(); ++i) {
550+ uchar chr = bytes.at(i);
551+
552+ if ((chr >= 'a' && chr <= 'z') ||
553+ (chr >= 'A' && chr <= 'Z') ||
554+ (chr >= '0' && chr <= '9'&& i != 0)) {
555+ encoded.append(chr);
556+ } else {
557+ QString hexval = QString("_%1").arg(chr, 2, 16, QChar('0'));
558+ encoded.append(hexval.toUpper());
559+ }
560+ }
561+
562+ return encoded;
563+}
564+
565+void LauncherBackend::emitPropChangedDbus(const QString& appId, const QString& property, QVariant &value) const
566+{
567+ QString path("/com/canonical/Unity/Launcher/");
568+ path.append(encodeAppId(appId));
569+
570+ QDBusMessage message = QDBusMessage::createSignal(path, "org.freedesktop.DBus.Properties", "PropertiesChanged");
571+
572+ QList<QVariant> arguments;
573+ QVariantHash changedprops;
574+ changedprops[property] = QVariant::fromValue(QDBusVariant(value));
575+ QVariantList deletedprops;
576+
577+ arguments.append(changedprops);
578+ arguments.append(deletedprops);
579+
580+ message.setArguments(arguments);
581+
582+ QDBusConnection con = QDBusConnection::sessionBus();
583+ con.send(message);
584+}
plugins/Unity/Launcher/backend/launcherbackend.h+52−4
@@ -24,6 +24,7 @@
2424#include <QObject>
2525#include <QSettings>
2626#include <QStringList>
27+#include <QDBusVirtualObject>
2728
2829class AccountsServiceDBusAdaptor;
2930
@@ -32,11 +33,13 @@ class AccountsServiceDBusAdaptor;
3233 */
3334
3435class LauncherBackendItem;
36+class LauncherBackendTest;
3537
36−class LauncherBackend : public QObject
38+class LauncherBackend : public QDBusVirtualObject
3739{
3840 Q_OBJECT
3941
42+ friend LauncherBackendTest;
4043
4144public:
4245 LauncherBackend(QObject *parent = 0);
@@ -116,16 +119,53 @@ public:
116119 */
117120 int count(const QString &appId) const;
118121
122+ /**
123+ * @brief Set the count on an item
124+ * @param appId The ID of the application
125+ * @param count Count to show on the application
126+ */
127+ void setCount(const QString &appId, int count) const;
128+
129+ /**
130+ * @brief Get whether the count should be visible
131+ * @param appId The ID of the application.
132+ * @returns Whether to show a count on the launcher
133+ */
134+ bool countVisible(const QString &appId) const;
135+
136+ /**
137+ * @brief Set the visibility of the count item
138+ * @param appId The ID of the application
139+ * @param visible Whether the count should be visible
140+ */
141+ void setCountVisible(const QString &appId, bool visible) const;
142+
119143 /**
120144 * @brief Sets the username for which to look up launcher items.
121145 * @param username The username to use.
122146 */
123147 void setUser(const QString &username);
124148
149+ /**
150+ * @brief Handle a message to an application node
151+ * @param message DBus message to handle
152+ * @param connection DBus connection that we're using
153+ * @returns whether the message was handled
154+ */
155+ virtual bool handleMessage(const QDBusMessage& message, const QDBusConnection& connection);
156+
157+ /**
158+ * @brief Get introspection information on the objects we're exporting
159+ * @param path the dbus path containing the appid
160+ * @returns Introspection information for that node in the tree
161+ */
162+ virtual QString introspect (const QString &path) const;
163+
125164Q_SIGNALS:
126− void quickListChanged(const QString &appId, const QList<QuickListEntry> &quickList);
127− void progressChanged(const QString &appId, int progress);
128− void countChanged(const QString &appId, int count);
165+ void quickListChanged(const QString &appId, const QList<QuickListEntry> &quickList) const;
166+ void progressChanged(const QString &appId, int progress) const;
167+ void countChanged(const QString &appId, int count) const;
168+ void countVisibleChanged(const QString &appId, bool visible) const;
129169
130170private:
131171 QString findDesktopFile(const QString &appId) const;
@@ -143,6 +183,14 @@ private:
143183
144184 AccountsServiceDBusAdaptor *m_accounts;
145185 QString m_user;
186+
187+ void emitPropChangedDbus(const QString& appId, const QString& property, QVariant &value) const;
188+
189+protected: /* Protected to allow testing */
190+ LauncherBackendItem* getItem(const QString& appId) const;
191+
192+ static QString decodeAppId(const QString& path);
193+ static QString encodeAppId(const QString& appId);
146194};
147195
148196#endif // LAUNCHERBACKEND_H
plugins/Unity/Launcher/qmldir+1−1
@@ -1,3 +1,3 @@
11module Unity.Launcher
22plugin UnityLauncher-qml
3−typeinfo plugin.qmltypes
3+typeinfo Launcher.qmltypes
plugins/Utils/CMakeLists.txt+1−4
@@ -11,7 +11,6 @@ include_directories(
1111)
1212
1313set(QMLPLUGIN_SRC
14− bottombarvisibilitycommunicatorshell.cpp
1514 qlimitproxymodelqml.cpp
1615 qsortfilterproxymodelqml.cpp
1716 timeformatter.cpp
@@ -34,6 +33,4 @@ set_target_properties(Utils-qml PROPERTIES COMPILE_FLAGS -fvisibility=default)
3433
3534qt5_use_modules(Utils-qml Qml Quick DBus Network XmlPatterns Gui Concurrent)
3635
37−# export the qmldir qmltypes and plugin files
38−export_qmlfiles(Utils Utils)
39−export_qmlplugin(Utils 0.1 Utils TARGETS Utils-qml)
36+add_unity8_plugin(Utils 0.1 Utils TARGETS Utils-qml)
plugins/Utils/bottombarvisibilitycommunicatorshell.cppdeleted−49
@@ -1,49 +0,0 @@
1−/*
2− * Copyright (C) 2012 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 "bottombarvisibilitycommunicatorshell.h"
18−
19−BottomBarVisibilityCommunicatorShell::BottomBarVisibilityCommunicatorShell()
20− : m_forceHidden(false),
21− m_position(0)
22−{
23−}
24−
25−bool BottomBarVisibilityCommunicatorShell::forceHidden() const
26−{
27− return m_forceHidden;
28−}
29−
30−double BottomBarVisibilityCommunicatorShell::position() const
31−{
32− return m_position;
33−}
34−
35−void BottomBarVisibilityCommunicatorShell::setForceHidden(bool forceHidden)
36−{
37− if (forceHidden != m_forceHidden) {
38− m_forceHidden = forceHidden;
39− Q_EMIT forceHiddenChanged(forceHidden);
40− }
41−}
42−
43−void BottomBarVisibilityCommunicatorShell::setPosition(double position)
44−{
45− if (position != m_position) {
46− m_position = position;
47− Q_EMIT positionChanged(position);
48− }
49−}
plugins/Utils/bottombarvisibilitycommunicatorshell.hdeleted−59
@@ -1,59 +0,0 @@
1−/*
2− * Copyright (C) 2012 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−#ifndef BOTTOMBARVISIBILITYCOMMUNICATORSHELL_H
18−#define BOTTOMBARVISIBILITYCOMMUNICATORSHELL_H
19−
20−#include <QObject>
21−
22−class QDBusInterface;
23−
24−/** This is an internal class used to talk with the bottom bar used by either
25− * applications or the SDK.
26− * There is a method to force the bottom bar to be hidden or otherwise behave as usual
27− */
28−
29−class BottomBarVisibilityCommunicatorShell : public QObject
30−{
31− Q_OBJECT
32− Q_PROPERTY(bool forceHidden READ forceHidden WRITE setForceHidden NOTIFY forceHiddenChanged)
33− Q_PROPERTY(double position READ position WRITE setPosition NOTIFY positionChanged)
34−
35− Q_CLASSINFO("D-Bus Interface", "com.canonical.Shell.BottomBarVisibilityCommunicator")
36−public:
37− static BottomBarVisibilityCommunicatorShell& instance() {
38− static BottomBarVisibilityCommunicatorShell instance;
39− return instance;
40− }
41−
42− bool forceHidden() const;
43− void setForceHidden(bool forceHidden);
44−
45− double position() const;
46− void setPosition(double position);
47−
48−Q_SIGNALS:
49− void forceHiddenChanged(bool forceHidden);
50− void positionChanged(double position);
51−
52−private:
53− BottomBarVisibilityCommunicatorShell();
54−
55− bool m_forceHidden;
56− double m_position;
57−};
58−
59−#endif
plugins/Utils/plugin.cpp−10
@@ -26,16 +26,12 @@
2626#include "plugin.h"
2727
2828// local
29−#include "bottombarvisibilitycommunicatorshell.h"
3029#include "qlimitproxymodelqml.h"
3130#include "qsortfilterproxymodelqml.h"
3231#include "timeformatter.h"
3332#include "unitymenumodelpaths.h"
3433#include "easingcurve.h"
3534
36−static const char* BOTTOM_BAR_VISIBILITY_COMMUNICATOR_DBUS_PATH = "/BottomBarVisibilityCommunicator";
37−static const char* DBUS_SERVICE = "com.canonical.Shell.BottomBarVisibilityCommunicator";
38−
3935void UtilsPlugin::registerTypes(const char *uri)
4036{
4137 Q_ASSERT(uri == QLatin1String("Utils"));
@@ -45,16 +41,10 @@ void UtilsPlugin::registerTypes(const char *uri)
4541 qmlRegisterType<UnityMenuModelPaths>(uri, 0, 1, "UnityMenuModelPaths");
4642 qmlRegisterType<TimeFormatter>(uri, 0, 1, "TimeFormatter");
4743 qmlRegisterType<GDateTimeFormatter>(uri, 0, 1, "GDateTimeFormatter");
48− qmlRegisterUncreatableType<BottomBarVisibilityCommunicatorShell>(uri, 0, 1, "BottomBarVisibilityCommunicatorShell", "Can't create BottomBarVisibilityCommunicatorShell");
4944 qmlRegisterType<EasingCurve>(uri, 0, 1, "EasingCurve");
5045}
5146
5247void UtilsPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
5348{
5449 QQmlExtensionPlugin::initializeEngine(engine, uri);
55−
56− QDBusConnection::sessionBus().registerService(DBUS_SERVICE);
57− BottomBarVisibilityCommunicatorShell *bottomBarVisibilityCommunicator = &BottomBarVisibilityCommunicatorShell::instance();
58− QDBusConnection::sessionBus().registerObject(BOTTOM_BAR_VISIBILITY_COMMUNICATOR_DBUS_PATH, bottomBarVisibilityCommunicator, QDBusConnection::ExportAllContents);
59− engine->rootContext()->setContextProperty("bottomBarVisibilityCommunicatorShell", bottomBarVisibilityCommunicator);
6050}
plugins/Utils/qmldir+1−1
@@ -1,3 +1,3 @@
11module Utils
22plugin Utils-qml
3−typeinfo plugin.qmltypes
3+typeinfo Utils.qmltypes
po/am.po+9−13
@@ -7,16 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
1111"PO-Revision-Date: 2014-01-18 19:28+0000\n"
1212"Last-Translator: samson <Unknown>\n"
1313"Language-Team: Amharic <am@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=2; plural=n > 1;\n"
18−"X-Launchpad-Export-Date: 2014-03-28 06:48+0000\n"
19−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-01 06:43+0000\n"
18+"X-Generator: Launchpad (build 16985)\n"
2019
2120#: plugins/Unity/Launcher/launcheritem.cpp:43
2221#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -85,7 +84,7 @@ msgstr ""
8584msgid "See less"
8685msgstr ""
8786
88−#: qml/Dash/DashApps.qml:38
87+#: qml/Dash/DashApps.qml:37
8988msgid "Recent"
9089msgstr ""
9190
@@ -114,6 +113,10 @@ msgstr ""
114113msgid "Send"
115114msgstr "መላኪያ"
116115
116+#: qml/Greeter/Greeter.qml:151
117+msgid "Swipe to unlock"
118+msgstr ""
119+
117120#: qml/Greeter/Lockscreen.qml:149
118121msgid "Emergency Call"
119122msgstr ""
@@ -159,14 +162,7 @@ msgstr ""
159162msgid "Search"
160163msgstr "መፈለጊያ"
161164
162−#: qml/Shell.qml:417
165+#: qml/Shell.qml:348
163166#, qt-format
164167msgid "Please enter %1"
165168msgstr "እባክዎን ያስገቡ %1"
166−
167−#~ msgid "Comments:"
168−#~ msgstr "አስተያየቶች:"
169−
170−#, qt-format
171−#~ msgid "(%1)"
172−#~ msgstr "(%1)"
po/ar.po+9−27
@@ -7,17 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
1111"PO-Revision-Date: 2014-02-21 11:19+0000\n"
1212"Last-Translator: Ibrahim Saed <ibraheem5000@gmail.com>\n"
1313"Language-Team: Arabic <ar@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n % 100 >= "
18−"3 && n % 100 <= 10 ? 3 : n % 100 >= 11 && n % 100 <= 99 ? 4 : 5;\n"
19−"X-Launchpad-Export-Date: 2014-03-28 06:48+0000\n"
20−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-01 06:43+0000\n"
18+"X-Generator: Launchpad (build 16985)\n"
2119
2220#: plugins/Unity/Launcher/launcheritem.cpp:43
2321#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -89,7 +87,7 @@ msgstr "شاهد المزيد"
8987msgid "See less"
9088msgstr "شاهد أقل"
9189
92−#: qml/Dash/DashApps.qml:38
90+#: qml/Dash/DashApps.qml:37
9391msgid "Recent"
9492msgstr ""
9593
@@ -118,6 +116,10 @@ msgstr "أضف تعليق"
118116msgid "Send"
119117msgstr "أرسل"
120118
119+#: qml/Greeter/Greeter.qml:151
120+msgid "Swipe to unlock"
121+msgstr ""
122+
121123#: qml/Greeter/Lockscreen.qml:149
122124msgid "Emergency Call"
123125msgstr "مكالمة طوارئ"
@@ -163,27 +165,7 @@ msgstr "من فضلك أدخِل رقم التعريف الشخصي لبطاقة
163165msgid "Search"
164166msgstr "ابحث"
165167
166−#: qml/Shell.qml:417
168+#: qml/Shell.qml:348
167169#, qt-format
168170msgid "Please enter %1"
169171msgstr "من فضلك أدخِل %1"
170−
171−#~ msgid "Review"
172−#~ msgstr "التعليق"
173−
174−#, qt-format
175−#~ msgid "(%1)"
176−#~ msgstr "(%1)"
177−
178−#~ msgid "Comments:"
179−#~ msgstr "التعليقات:"
180−
181−#, qt-format
182−#~ msgid "%1 review"
183−#~ msgid_plural "%1 reviews"
184−#~ msgstr[0] "لا تعليقات (%1)"
185−#~ msgstr[1] "تعليق واحد (%1)"
186−#~ msgstr[2] "تعليقان (%1)"
187−#~ msgstr[3] "%1 تعليقات"
188−#~ msgstr[4] "%1 تعليقا"
189−#~ msgstr[5] "%1 تعليق"
po/ast.po+9−5
@@ -7,15 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
1111"PO-Revision-Date: 2014-04-04 02:16+0000\n"
1212"Last-Translator: Xuacu Saturio <xuacusk8@gmail.com>\n"
1313"Language-Team: Asturian <ast@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2014-04-08 07:13+0000\n"
18−"X-Generator: Launchpad (build 16976)\n"
17+"X-Launchpad-Export-Date: 2014-05-01 06:43+0000\n"
18+"X-Generator: Launchpad (build 16985)\n"
1919
2020#: plugins/Unity/Launcher/launcheritem.cpp:43
2121#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -88,7 +88,7 @@ msgstr "Ver más"
8888msgid "See less"
8989msgstr "Ver menos"
9090
91−#: qml/Dash/DashApps.qml:38
91+#: qml/Dash/DashApps.qml:37
9292msgid "Recent"
9393msgstr "Reciente"
9494
@@ -117,6 +117,10 @@ msgstr "Amestar una reseña"
117117msgid "Send"
118118msgstr "Unviar"
119119
120+#: qml/Greeter/Greeter.qml:151
121+msgid "Swipe to unlock"
122+msgstr ""
123+
120124#: qml/Greeter/Lockscreen.qml:149
121125msgid "Emergency Call"
122126msgstr "Llamada d'emerxencia"
@@ -162,7 +166,7 @@ msgstr "Escriba'l PIN de la SIM"
162166msgid "Search"
163167msgstr "Guetar"
164168
165−#: qml/Shell.qml:417
169+#: qml/Shell.qml:348
166170#, qt-format
167171msgid "Please enter %1"
168172msgstr "Introduz %1"
po/az.po+9−22
@@ -7,16 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
1111"PO-Revision-Date: 2014-01-15 09:50+0000\n"
1212"Last-Translator: Turan Mahmudov <turan.mahmudov@gmail.com>\n"
1313"Language-Team: Azerbaijani <az@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2014-03-28 06:48+0000\n"
19−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-01 06:43+0000\n"
18+"X-Generator: Launchpad (build 16985)\n"
2019
2120#: plugins/Unity/Launcher/launcheritem.cpp:43
2221#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -86,7 +85,7 @@ msgstr ""
8685msgid "See less"
8786msgstr ""
8887
89−#: qml/Dash/DashApps.qml:38
88+#: qml/Dash/DashApps.qml:37
9089msgid "Recent"
9190msgstr ""
9291
@@ -115,6 +114,10 @@ msgstr "Rəy yaz"
115114msgid "Send"
116115msgstr "Göndər"
117116
117+#: qml/Greeter/Greeter.qml:151
118+msgid "Swipe to unlock"
119+msgstr ""
120+
118121#: qml/Greeter/Lockscreen.qml:149
119122msgid "Emergency Call"
120123msgstr "Zərurət zəngi"
@@ -160,23 +163,7 @@ msgstr ""
160163msgid "Search"
161164msgstr "Axtar"
162165
163−#: qml/Shell.qml:417
166+#: qml/Shell.qml:348
164167#, qt-format
165168msgid "Please enter %1"
166169msgstr "Xahiş edirik daxil edin: %1"
167−
168−#~ msgid "Comments:"
169−#~ msgstr "Şərhlər:"
170−
171−#~ msgid "Review"
172−#~ msgstr "Rəy"
173−
174−#, qt-format
175−#~ msgid "%1 review"
176−#~ msgid_plural "%1 reviews"
177−#~ msgstr[0] "%1 rəy"
178−#~ msgstr[1] "%1 rəy"
179−
180−#, qt-format
181−#~ msgid "(%1)"
182−#~ msgstr "(%1)"
po/bg.po+9−5
@@ -7,15 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
1111"PO-Revision-Date: 2014-04-01 14:08+0000\n"
1212"Last-Translator: Atanas Kovachki <Unknown>\n"
1313"Language-Team: Bulgarian <bg@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2014-04-03 06:06+0000\n"
18−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-01 06:43+0000\n"
18+"X-Generator: Launchpad (build 16985)\n"
1919
2020#: plugins/Unity/Launcher/launcheritem.cpp:43
2121#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -91,7 +91,7 @@ msgstr ""
9191msgid "See less"
9292msgstr ""
9393
94−#: qml/Dash/DashApps.qml:38
94+#: qml/Dash/DashApps.qml:37
9595msgid "Recent"
9696msgstr "Последни"
9797
@@ -120,6 +120,10 @@ msgstr "Добави отзив"
120120msgid "Send"
121121msgstr "Изпрати"
122122
123+#: qml/Greeter/Greeter.qml:151
124+msgid "Swipe to unlock"
125+msgstr ""
126+
123127#: qml/Greeter/Lockscreen.qml:149
124128msgid "Emergency Call"
125129msgstr "Спешно повикване"
@@ -165,7 +169,7 @@ msgstr ""
165169msgid "Search"
166170msgstr "Търсене"
167171
168−#: qml/Shell.qml:417
172+#: qml/Shell.qml:348
169173#, qt-format
170174msgid "Please enter %1"
171175msgstr "Моля, въведете %1"
po/br.po+9−5
@@ -7,15 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
1111"PO-Revision-Date: 2014-04-15 18:15+0000\n"
1212"Last-Translator: Rouxel <vincent.rouxel@mailoo.org>\n"
1313"Language-Team: Breton <br@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2014-04-16 07:12+0000\n"
18−"X-Generator: Launchpad (build 16976)\n"
17+"X-Launchpad-Export-Date: 2014-05-01 06:43+0000\n"
18+"X-Generator: Launchpad (build 16985)\n"
1919
2020#: plugins/Unity/Launcher/launcheritem.cpp:43
2121#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -84,7 +84,7 @@ msgstr ""
8484msgid "See less"
8585msgstr ""
8686
87−#: qml/Dash/DashApps.qml:38
87+#: qml/Dash/DashApps.qml:37
8888msgid "Recent"
8989msgstr ""
9090
@@ -113,6 +113,10 @@ msgstr ""
113113msgid "Send"
114114msgstr ""
115115
116+#: qml/Greeter/Greeter.qml:151
117+msgid "Swipe to unlock"
118+msgstr ""
119+
116120#: qml/Greeter/Lockscreen.qml:149
117121msgid "Emergency Call"
118122msgstr ""
@@ -158,7 +162,7 @@ msgstr ""
158162msgid "Search"
159163msgstr ""
160164
161−#: qml/Shell.qml:417
165+#: qml/Shell.qml:348
162166#, qt-format
163167msgid "Please enter %1"
164168msgstr ""
po/bs.po+9−7
@@ -7,17 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
1111"PO-Revision-Date: 2014-01-16 22:33+0000\n"
1212"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1313"Language-Team: Bosnian <bs@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
18−"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
19−"X-Launchpad-Export-Date: 2014-03-28 06:48+0000\n"
20−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-01 06:43+0000\n"
18+"X-Generator: Launchpad (build 16985)\n"
2119
2220#: plugins/Unity/Launcher/launcheritem.cpp:43
2321#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -86,7 +84,7 @@ msgstr ""
8684msgid "See less"
8785msgstr ""
8886
89−#: qml/Dash/DashApps.qml:38
87+#: qml/Dash/DashApps.qml:37
9088msgid "Recent"
9189msgstr ""
9290
@@ -115,6 +113,10 @@ msgstr ""
115113msgid "Send"
116114msgstr ""
117115
116+#: qml/Greeter/Greeter.qml:151
117+msgid "Swipe to unlock"
118+msgstr ""
119+
118120#: qml/Greeter/Lockscreen.qml:149
119121msgid "Emergency Call"
120122msgstr ""
@@ -160,7 +162,7 @@ msgstr ""
160162msgid "Search"
161163msgstr ""
162164
163−#: qml/Shell.qml:417
165+#: qml/Shell.qml:348
164166#, qt-format
165167msgid "Please enter %1"
166168msgstr ""
po/ca.po+16−29
@@ -7,16 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
11−"PO-Revision-Date: 2014-01-10 07:45+0000\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
11+"PO-Revision-Date: 2014-05-14 08:15+0000\n"
1212"Last-Translator: Adolfo Jayme <fitoschido@gmail.com>\n"
1313"Language-Team: Catalan <ca@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2014-03-28 06:48+0000\n"
19−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-16 06:52+0000\n"
18+"X-Generator: Launchpad (build 17007)\n"
2019
2120#: plugins/Unity/Launcher/launcheritem.cpp:43
2221#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -85,28 +84,28 @@ msgstr "Cerques recents"
8584
8685#: qml/Components/SeeMore.qml:35
8786msgid "See more"
88−msgstr ""
87+msgstr "Mostra'n més"
8988
9089#: qml/Components/SeeMore.qml:58
9190msgid "See less"
92−msgstr ""
91+msgstr "Mostra'n menys"
9392
94−#: qml/Dash/DashApps.qml:38
93+#: qml/Dash/DashApps.qml:37
9594msgid "Recent"
9695msgstr ""
9796
9897#: qml/Dash/PreviewListView.qml:52
9998#, qt-format
10099msgid "%1 Preview"
101−msgstr ""
100+msgstr "Previsualització de %1"
102101
103102#: qml/Dash/Previews/PreviewActionCombo.qml:34
104103msgid "More..."
105−msgstr ""
104+msgstr "Més..."
106105
107106#: qml/Dash/Previews/PreviewActionCombo.qml:34
108107msgid "Less..."
109−msgstr ""
108+msgstr "Menys..."
110109
111110#: qml/Dash/Previews/PreviewRatingInput.qml:81
112111msgid "Rate this"
@@ -120,6 +119,10 @@ msgstr "Afegiu una ressenya"
120119msgid "Send"
121120msgstr "Envia"
122121
122+#: qml/Greeter/Greeter.qml:151
123+msgid "Swipe to unlock"
124+msgstr ""
125+
123126#: qml/Greeter/Lockscreen.qml:149
124127msgid "Emergency Call"
125128msgstr "Trucada d'emergència"
@@ -159,29 +162,13 @@ msgstr "Mostra la contrasenya"
159162
160163#: qml/Notifications/NotificationMenuItemFactory.qml:103
161164msgid "Please enter SIM PIN"
162−msgstr ""
165+msgstr "Introduïu el PIN de la targeta SIM"
163166
164167#: qml/Panel/SearchIndicator.qml:27
165168msgid "Search"
166169msgstr "Cerca"
167170
168−#: qml/Shell.qml:417
171+#: qml/Shell.qml:348
169172#, qt-format
170173msgid "Please enter %1"
171174msgstr "Introduïu %1"
172−
173−#, qt-format
174−#~ msgid "(%1)"
175−#~ msgstr "(%1)"
176−
177−#~ msgid "Comments:"
178−#~ msgstr "Comentaris:"
179−
180−#~ msgid "Review"
181−#~ msgstr "Ressenya"
182−
183−#, qt-format
184−#~ msgid "%1 review"
185−#~ msgid_plural "%1 reviews"
186−#~ msgstr[0] "%1 ressenya"
187−#~ msgstr[1] "%1 ressenyes"
po/ckb.po+9−22
@@ -7,16 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
1111"PO-Revision-Date: 2014-01-21 11:05+0000\n"
1212"Last-Translator: Aras <aras.noori@gmail.com>\n"
1313"Language-Team: Kurdish (Sorani) <ckb@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2014-03-28 06:49+0000\n"
19−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-01 06:44+0000\n"
18+"X-Generator: Launchpad (build 16985)\n"
2019
2120#: plugins/Unity/Launcher/launcheritem.cpp:43
2221#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -85,7 +84,7 @@ msgstr ""
8584msgid "See less"
8685msgstr ""
8786
88−#: qml/Dash/DashApps.qml:38
87+#: qml/Dash/DashApps.qml:37
8988msgid "Recent"
9089msgstr ""
9190
@@ -114,6 +113,10 @@ msgstr "پێداچوونەوە زۆر بکە"
114113msgid "Send"
115114msgstr "ناردن"
116115
116+#: qml/Greeter/Greeter.qml:151
117+msgid "Swipe to unlock"
118+msgstr ""
119+
117120#: qml/Greeter/Lockscreen.qml:149
118121msgid "Emergency Call"
119122msgstr "هێڵی فریاگوزاری"
@@ -159,23 +162,7 @@ msgstr ""
159162msgid "Search"
160163msgstr "گەڕان"
161164
162−#: qml/Shell.qml:417
165+#: qml/Shell.qml:348
163166#, qt-format
164167msgid "Please enter %1"
165168msgstr "تکایە %1 بنووسە"
166−
167−#, qt-format
168−#~ msgid "(%1)"
169−#~ msgstr "(%1)"
170−
171−#~ msgid "Comments:"
172−#~ msgstr "لێدوانەکان:"
173−
174−#, qt-format
175−#~ msgid "%1 review"
176−#~ msgid_plural "%1 reviews"
177−#~ msgstr[0] "%1 پێداچوونەوە"
178−#~ msgstr[1] "%1 پێداچوونەوەکان"
179−
180−#~ msgid "Review"
181−#~ msgstr "پێداچوونەوە"
po/cs.po+9−23
@@ -7,16 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
1111"PO-Revision-Date: 2014-01-08 10:11+0000\n"
1212"Last-Translator: Tadeáš Pařík <tadeas.parik@gmail.com>\n"
1313"Language-Team: Czech <cs@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
18−"X-Launchpad-Export-Date: 2014-03-28 06:48+0000\n"
19−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-01 06:43+0000\n"
18+"X-Generator: Launchpad (build 16985)\n"
2019
2120#: plugins/Unity/Launcher/launcheritem.cpp:43
2221#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -85,7 +84,7 @@ msgstr ""
8584msgid "See less"
8685msgstr ""
8786
88−#: qml/Dash/DashApps.qml:38
87+#: qml/Dash/DashApps.qml:37
8988msgid "Recent"
9089msgstr ""
9190
@@ -114,6 +113,10 @@ msgstr "Přidat recenzi"
114113msgid "Send"
115114msgstr "Odeslat"
116115
116+#: qml/Greeter/Greeter.qml:151
117+msgid "Swipe to unlock"
118+msgstr ""
119+
117120#: qml/Greeter/Lockscreen.qml:149
118121msgid "Emergency Call"
119122msgstr "Tísňové volání"
@@ -159,24 +162,7 @@ msgstr ""
159162msgid "Search"
160163msgstr "Hledat"
161164
162−#: qml/Shell.qml:417
165+#: qml/Shell.qml:348
163166#, qt-format
164167msgid "Please enter %1"
165168msgstr "Zadejte prosím %1"
166−
167−#~ msgid "Comments:"
168−#~ msgstr "Komentáře:"
169−
170−#, qt-format
171−#~ msgid "(%1)"
172−#~ msgstr "(%1)"
173−
174−#~ msgid "Review"
175−#~ msgstr "Recenze"
176−
177−#, qt-format
178−#~ msgid "%1 review"
179−#~ msgid_plural "%1 reviews"
180−#~ msgstr[0] "%1 recenze"
181−#~ msgstr[1] "%1 recenze"
182−#~ msgstr[2] "%1 recenzí"
po/da.po+9−6
@@ -7,16 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
1111"PO-Revision-Date: 2014-01-14 20:16+0000\n"
1212"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1313"Language-Team: Danish <da@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2014-03-28 06:48+0000\n"
19−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-01 06:43+0000\n"
18+"X-Generator: Launchpad (build 16985)\n"
2019
2120#: plugins/Unity/Launcher/launcheritem.cpp:43
2221#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -85,7 +84,7 @@ msgstr ""
8584msgid "See less"
8685msgstr ""
8786
88−#: qml/Dash/DashApps.qml:38
87+#: qml/Dash/DashApps.qml:37
8988msgid "Recent"
9089msgstr ""
9190
@@ -114,6 +113,10 @@ msgstr ""
114113msgid "Send"
115114msgstr ""
116115
116+#: qml/Greeter/Greeter.qml:151
117+msgid "Swipe to unlock"
118+msgstr ""
119+
117120#: qml/Greeter/Lockscreen.qml:149
118121msgid "Emergency Call"
119122msgstr ""
@@ -159,7 +162,7 @@ msgstr ""
159162msgid "Search"
160163msgstr ""
161164
162−#: qml/Shell.qml:417
165+#: qml/Shell.qml:348
163166#, qt-format
164167msgid "Please enter %1"
165168msgstr ""
po/de.po+20−33
@@ -7,25 +7,24 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
11−"PO-Revision-Date: 2014-01-15 11:01+0000\n"
12−"Last-Translator: Dennis Baudys <Unknown>\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
11+"PO-Revision-Date: 2014-05-20 13:45+0000\n"
12+"Last-Translator: Tobias Bannert <Unknown>\n"
1313"Language-Team: German <de@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2014-03-28 06:48+0000\n"
19−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-22 06:49+0000\n"
18+"X-Generator: Launchpad (build 17017)\n"
2019
2120#: plugins/Unity/Launcher/launcheritem.cpp:43
2221#: plugins/Unity/Launcher/launcheritem.cpp:73
2322msgid "Lock to Launcher"
24−msgstr ""
23+msgstr "Im Starter sperren"
2524
2625#: plugins/Unity/Launcher/launcheritem.cpp:73
2726msgid "Unlock from Launcher"
28−msgstr ""
27+msgstr "Aus dem Starter entsperren"
2928
3029#: qml/Components/EdgeDemoOverlay.qml:151
3130msgid "Skip intro"
@@ -81,28 +80,28 @@ msgstr "Letzte Suchbegriffe"
8180
8281#: qml/Components/SeeMore.qml:35
8382msgid "See more"
84−msgstr ""
83+msgstr "Mehr ansehen"
8584
8685#: qml/Components/SeeMore.qml:58
8786msgid "See less"
88−msgstr ""
87+msgstr "Weniger ansehen"
8988
90−#: qml/Dash/DashApps.qml:38
89+#: qml/Dash/DashApps.qml:37
9190msgid "Recent"
92−msgstr ""
91+msgstr "Kürzlich"
9392
9493#: qml/Dash/PreviewListView.qml:52
9594#, qt-format
9695msgid "%1 Preview"
97−msgstr ""
96+msgstr "%1 Vorschau"
9897
9998#: qml/Dash/Previews/PreviewActionCombo.qml:34
10099msgid "More..."
101−msgstr ""
100+msgstr "Mehr …"
102101
103102#: qml/Dash/Previews/PreviewActionCombo.qml:34
104103msgid "Less..."
105−msgstr ""
104+msgstr "Weniger …"
106105
107106#: qml/Dash/Previews/PreviewRatingInput.qml:81
108107msgid "Rate this"
@@ -116,6 +115,10 @@ msgstr "Bewertung hinzufügen"
116115msgid "Send"
117116msgstr "Senden"
118117
118+#: qml/Greeter/Greeter.qml:151
119+msgid "Swipe to unlock"
120+msgstr "Wischen zum Entsperren"
121+
119122#: qml/Greeter/Lockscreen.qml:149
120123msgid "Emergency Call"
121124msgstr "Notruf"
@@ -155,29 +158,13 @@ msgstr "Passwort anzeigen"
155158
156159#: qml/Notifications/NotificationMenuItemFactory.qml:103
157160msgid "Please enter SIM PIN"
158−msgstr ""
161+msgstr "Bitte die PIN der SIM eingeben"
159162
160163#: qml/Panel/SearchIndicator.qml:27
161164msgid "Search"
162165msgstr "Suchen"
163166
164−#: qml/Shell.qml:417
167+#: qml/Shell.qml:348
165168#, qt-format
166169msgid "Please enter %1"
167170msgstr "Bitte geben Sie %1 ein"
168−
169−#~ msgid "Comments:"
170−#~ msgstr "Kommentare:"
171−
172−#, qt-format
173−#~ msgid "(%1)"
174−#~ msgstr "(%1)"
175−
176−#~ msgid "Review"
177−#~ msgstr "Bewertung"
178−
179−#, qt-format
180−#~ msgid "%1 review"
181−#~ msgid_plural "%1 reviews"
182−#~ msgstr[0] "%1 Bewertung"
183−#~ msgstr[1] "%1 Bewertungen"
po/el.po+9−22
@@ -7,16 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
1111"PO-Revision-Date: 2014-02-26 09:58+0000\n"
1212"Last-Translator: j3lc <x_nikos@yahoo.gr>\n"
1313"Language-Team: Greek <el@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2014-03-28 06:48+0000\n"
19−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-01 06:43+0000\n"
18+"X-Generator: Launchpad (build 16985)\n"
2019
2120#: plugins/Unity/Launcher/launcheritem.cpp:43
2221#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -89,7 +88,7 @@ msgstr "Περρισότερα"
8988msgid "See less"
9089msgstr "Λιγότερα"
9190
92−#: qml/Dash/DashApps.qml:38
91+#: qml/Dash/DashApps.qml:37
9392msgid "Recent"
9493msgstr ""
9594
@@ -118,6 +117,10 @@ msgstr "Προσθέστε την αξιολόγησή σας"
118117msgid "Send"
119118msgstr "Αποστολή"
120119
120+#: qml/Greeter/Greeter.qml:151
121+msgid "Swipe to unlock"
122+msgstr ""
123+
121124#: qml/Greeter/Lockscreen.qml:149
122125msgid "Emergency Call"
123126msgstr "Κλήση έκτακτης ανάγκης"
@@ -163,23 +166,7 @@ msgstr "Παρακαλώ εισάγετε το PIN της κάρτας SIM"
163166msgid "Search"
164167msgstr "Αναζήτηση"
165168
166−#: qml/Shell.qml:417
169+#: qml/Shell.qml:348
167170#, qt-format
168171msgid "Please enter %1"
169172msgstr "Πληκτρολογήστε %1"
170−
171−#, qt-format
172−#~ msgid "%1 review"
173−#~ msgid_plural "%1 reviews"
174−#~ msgstr[0] "%1 αξιολόγηση"
175−#~ msgstr[1] "%1 αξιολογήσεις"
176−
177−#, qt-format
178−#~ msgid "(%1)"
179−#~ msgstr "(%1)"
180−
181−#~ msgid "Comments:"
182−#~ msgstr "Σχόλια:"
183−
184−#~ msgid "Review"
185−#~ msgstr "Αξιολόγηση"
po/en_AU.po+9−22
@@ -7,16 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
1111"PO-Revision-Date: 2013-09-28 07:46+0000\n"
1212"Last-Translator: Jared Norris <jarednorris@ubuntu.com>\n"
1313"Language-Team: English (Australia) <en_AU@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2014-03-28 06:49+0000\n"
19−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-01 06:44+0000\n"
18+"X-Generator: Launchpad (build 16985)\n"
2019
2120#: plugins/Unity/Launcher/launcheritem.cpp:43
2221#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -85,7 +84,7 @@ msgstr ""
8584msgid "See less"
8685msgstr ""
8786
88−#: qml/Dash/DashApps.qml:38
87+#: qml/Dash/DashApps.qml:37
8988msgid "Recent"
9089msgstr ""
9190
@@ -114,6 +113,10 @@ msgstr "Add a review"
114113msgid "Send"
115114msgstr "Send"
116115
116+#: qml/Greeter/Greeter.qml:151
117+msgid "Swipe to unlock"
118+msgstr ""
119+
117120#: qml/Greeter/Lockscreen.qml:149
118121msgid "Emergency Call"
119122msgstr "Emergency Call"
@@ -159,23 +162,7 @@ msgstr ""
159162msgid "Search"
160163msgstr "Search"
161164
162−#: qml/Shell.qml:417
165+#: qml/Shell.qml:348
163166#, qt-format
164167msgid "Please enter %1"
165168msgstr "Please enter %1"
166−
167−#~ msgid "Comments:"
168−#~ msgstr "Comments:"
169−
170−#~ msgid "Review"
171−#~ msgstr "Review"
172−
173−#, qt-format
174−#~ msgid "%1 review"
175−#~ msgid_plural "%1 reviews"
176−#~ msgstr[0] "%1 review"
177−#~ msgstr[1] "%1 reviews"
178−
179−#, qt-format
180−#~ msgid "(%1)"
181−#~ msgstr "(%1)"
po/en_GB.po+9−22
@@ -7,16 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
1111"PO-Revision-Date: 2014-03-07 13:27+0000\n"
1212"Last-Translator: Andi Chandler <Unknown>\n"
1313"Language-Team: English (United Kingdom) <en_GB@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2014-03-28 06:49+0000\n"
19−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-01 06:44+0000\n"
18+"X-Generator: Launchpad (build 16985)\n"
2019
2120#: plugins/Unity/Launcher/launcheritem.cpp:43
2221#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -87,7 +86,7 @@ msgstr "See more"
8786msgid "See less"
8887msgstr "See less"
8988
90−#: qml/Dash/DashApps.qml:38
89+#: qml/Dash/DashApps.qml:37
9190msgid "Recent"
9291msgstr ""
9392
@@ -116,6 +115,10 @@ msgstr "Add a review"
116115msgid "Send"
117116msgstr "Send"
118117
118+#: qml/Greeter/Greeter.qml:151
119+msgid "Swipe to unlock"
120+msgstr ""
121+
119122#: qml/Greeter/Lockscreen.qml:149
120123msgid "Emergency Call"
121124msgstr "Emergency Call"
@@ -161,23 +164,7 @@ msgstr "Please enter SIM PIN"
161164msgid "Search"
162165msgstr "Search"
163166
164−#: qml/Shell.qml:417
167+#: qml/Shell.qml:348
165168#, qt-format
166169msgid "Please enter %1"
167170msgstr "Please enter %1"
168−
169−#~ msgid "Comments:"
170−#~ msgstr "Comments:"
171−
172−#~ msgid "Review"
173−#~ msgstr "Review"
174−
175−#, qt-format
176−#~ msgid "%1 review"
177−#~ msgid_plural "%1 reviews"
178−#~ msgstr[0] "%1 review"
179−#~ msgstr[1] "%1 reviews"
180−
181−#, qt-format
182−#~ msgid "(%1)"
183−#~ msgstr "(%1)"
po/eo.po+9−6
@@ -7,16 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
1111"PO-Revision-Date: 2013-06-26 22:35+0000\n"
1212"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1313"Language-Team: Esperanto <eo@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2014-03-28 06:48+0000\n"
19−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-01 06:43+0000\n"
18+"X-Generator: Launchpad (build 16985)\n"
2019
2120#: plugins/Unity/Launcher/launcheritem.cpp:43
2221#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -85,7 +84,7 @@ msgstr ""
8584msgid "See less"
8685msgstr ""
8786
88−#: qml/Dash/DashApps.qml:38
87+#: qml/Dash/DashApps.qml:37
8988msgid "Recent"
9089msgstr ""
9190
@@ -114,6 +113,10 @@ msgstr ""
114113msgid "Send"
115114msgstr ""
116115
116+#: qml/Greeter/Greeter.qml:151
117+msgid "Swipe to unlock"
118+msgstr ""
119+
117120#: qml/Greeter/Lockscreen.qml:149
118121msgid "Emergency Call"
119122msgstr ""
@@ -159,7 +162,7 @@ msgstr ""
159162msgid "Search"
160163msgstr ""
161164
162−#: qml/Shell.qml:417
165+#: qml/Shell.qml:348
163166#, qt-format
164167msgid "Please enter %1"
165168msgstr ""
po/es.po+10−6
@@ -7,15 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
11−"PO-Revision-Date: 2014-03-28 22:37+0000\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
11+"PO-Revision-Date: 2014-05-15 15:38+0000\n"
1212"Last-Translator: Adolfo Jayme <fitoschido@gmail.com>\n"
1313"Language-Team: Spanish <es@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2014-03-29 07:34+0000\n"
18−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-16 06:52+0000\n"
18+"X-Generator: Launchpad (build 17007)\n"
1919
2020#: plugins/Unity/Launcher/launcheritem.cpp:43
2121#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -89,7 +89,7 @@ msgstr "Ver más"
8989msgid "See less"
9090msgstr "Ver menos"
9191
92−#: qml/Dash/DashApps.qml:38
92+#: qml/Dash/DashApps.qml:37
9393msgid "Recent"
9494msgstr "Recientes"
9595
@@ -118,6 +118,10 @@ msgstr "Añadir una reseña"
118118msgid "Send"
119119msgstr "Enviar"
120120
121+#: qml/Greeter/Greeter.qml:151
122+msgid "Swipe to unlock"
123+msgstr "Deslice para desbloquear"
124+
121125#: qml/Greeter/Lockscreen.qml:149
122126msgid "Emergency Call"
123127msgstr "Llamada de emergencia"
@@ -163,7 +167,7 @@ msgstr "Escriba el PIN de la SIM"
163167msgid "Search"
164168msgstr "Buscar"
165169
166−#: qml/Shell.qml:417
170+#: qml/Shell.qml:348
167171#, qt-format
168172msgid "Please enter %1"
169173msgstr "Introduzca %1"
po/eu.po+9−5
@@ -7,15 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
1111"PO-Revision-Date: 2014-03-30 12:44+0000\n"
1212"Last-Translator: Ibai Oihanguren Sala <Unknown>\n"
1313"Language-Team: Basque <eu@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2014-03-31 06:44+0000\n"
18−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-01 06:43+0000\n"
18+"X-Generator: Launchpad (build 16985)\n"
1919
2020#: plugins/Unity/Launcher/launcheritem.cpp:43
2121#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -88,7 +88,7 @@ msgstr "Ikusi gehiago"
8888msgid "See less"
8989msgstr "Ikusi gutxiago"
9090
91−#: qml/Dash/DashApps.qml:38
91+#: qml/Dash/DashApps.qml:37
9292msgid "Recent"
9393msgstr "Azkenak"
9494
@@ -117,6 +117,10 @@ msgstr "Gehitu kritika"
117117msgid "Send"
118118msgstr "Bidali"
119119
120+#: qml/Greeter/Greeter.qml:151
121+msgid "Swipe to unlock"
122+msgstr ""
123+
120124#: qml/Greeter/Lockscreen.qml:149
121125msgid "Emergency Call"
122126msgstr "Larrialdi-deia"
@@ -162,7 +166,7 @@ msgstr "Sartu SIMaren PINa"
162166msgid "Search"
163167msgstr "Bilatu"
164168
165−#: qml/Shell.qml:417
169+#: qml/Shell.qml:348
166170#, qt-format
167171msgid "Please enter %1"
168172msgstr "Sartu %1"
po/fa.po+9−6
@@ -7,16 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
1111"PO-Revision-Date: 2013-10-31 19:02+0000\n"
1212"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1313"Language-Team: Persian <fa@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2014-03-28 06:49+0000\n"
19−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-01 06:43+0000\n"
18+"X-Generator: Launchpad (build 16985)\n"
2019
2120#: plugins/Unity/Launcher/launcheritem.cpp:43
2221#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -85,7 +84,7 @@ msgstr ""
8584msgid "See less"
8685msgstr ""
8786
88−#: qml/Dash/DashApps.qml:38
87+#: qml/Dash/DashApps.qml:37
8988msgid "Recent"
9089msgstr ""
9190
@@ -114,6 +113,10 @@ msgstr ""
114113msgid "Send"
115114msgstr ""
116115
116+#: qml/Greeter/Greeter.qml:151
117+msgid "Swipe to unlock"
118+msgstr ""
119+
117120#: qml/Greeter/Lockscreen.qml:149
118121msgid "Emergency Call"
119122msgstr ""
@@ -159,7 +162,7 @@ msgstr ""
159162msgid "Search"
160163msgstr ""
161164
162−#: qml/Shell.qml:417
165+#: qml/Shell.qml:348
163166#, qt-format
164167msgid "Please enter %1"
165168msgstr ""
po/fi.po+10−6
@@ -7,15 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
11−"PO-Revision-Date: 2014-04-05 09:57+0000\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
11+"PO-Revision-Date: 2014-05-15 13:06+0000\n"
1212"Last-Translator: Jiri Grönroos <Unknown>\n"
1313"Language-Team: Finnish <fi@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2014-04-08 07:13+0000\n"
18−"X-Generator: Launchpad (build 16976)\n"
17+"X-Launchpad-Export-Date: 2014-05-16 06:52+0000\n"
18+"X-Generator: Launchpad (build 17007)\n"
1919
2020#: plugins/Unity/Launcher/launcheritem.cpp:43
2121#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -86,7 +86,7 @@ msgstr "Näytä lisää"
8686msgid "See less"
8787msgstr "Näytä vähemmän"
8888
89−#: qml/Dash/DashApps.qml:38
89+#: qml/Dash/DashApps.qml:37
9090msgid "Recent"
9191msgstr "Viimeisimmät"
9292
@@ -115,6 +115,10 @@ msgstr "Lisää arvostelu"
115115msgid "Send"
116116msgstr "Lähetä"
117117
118+#: qml/Greeter/Greeter.qml:151
119+msgid "Swipe to unlock"
120+msgstr "Avaa pyyhkäisemällä"
121+
118122#: qml/Greeter/Lockscreen.qml:149
119123msgid "Emergency Call"
120124msgstr "Hätäpuhelu"
@@ -160,7 +164,7 @@ msgstr "Anna SIM-kortin PIN-koodi"
160164msgid "Search"
161165msgstr "Hae"
162166
163−#: qml/Shell.qml:417
167+#: qml/Shell.qml:348
164168#, qt-format
165169msgid "Please enter %1"
166170msgstr "Kirjoita %1"
po/fo.po+9−6
@@ -7,16 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
1111"PO-Revision-Date: 2014-01-14 20:08+0000\n"
1212"Last-Translator: Jógvan Olsen <jeggy@jebster.net>\n"
1313"Language-Team: Faroese <fo@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2014-03-28 06:48+0000\n"
19−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-01 06:43+0000\n"
18+"X-Generator: Launchpad (build 16985)\n"
2019
2120#: plugins/Unity/Launcher/launcheritem.cpp:43
2221#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -85,7 +84,7 @@ msgstr ""
8584msgid "See less"
8685msgstr ""
8786
88−#: qml/Dash/DashApps.qml:38
87+#: qml/Dash/DashApps.qml:37
8988msgid "Recent"
9089msgstr ""
9190
@@ -114,6 +113,10 @@ msgstr ""
114113msgid "Send"
115114msgstr ""
116115
116+#: qml/Greeter/Greeter.qml:151
117+msgid "Swipe to unlock"
118+msgstr ""
119+
117120#: qml/Greeter/Lockscreen.qml:149
118121msgid "Emergency Call"
119122msgstr ""
@@ -159,7 +162,7 @@ msgstr ""
159162msgid "Search"
160163msgstr "Leita"
161164
162−#: qml/Shell.qml:417
165+#: qml/Shell.qml:348
163166#, qt-format
164167msgid "Please enter %1"
165168msgstr ""
po/fr.po+30−34
@@ -7,16 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
11−"PO-Revision-Date: 2014-01-28 00:34+0000\n"
12−"Last-Translator: Pierre <Unknown>\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
11+"PO-Revision-Date: 2014-05-08 17:29+0000\n"
12+"Last-Translator: Sébastien Maes <nautilussebastien@gmail.com>\n"
1313"Language-Team: French <fr@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=2; plural=n > 1;\n"
18−"X-Launchpad-Export-Date: 2014-03-28 06:48+0000\n"
19−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-10 08:01+0000\n"
18+"X-Generator: Launchpad (build 16996)\n"
2019
2120#: plugins/Unity/Launcher/launcheritem.cpp:43
2221#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -25,7 +24,7 @@ msgstr "Conserver dans le lanceur"
2524
2625#: plugins/Unity/Launcher/launcheritem.cpp:73
2726msgid "Unlock from Launcher"
28−msgstr ""
27+msgstr "Retirer du lanceur"
2928
3029#: qml/Components/EdgeDemoOverlay.qml:151
3130msgid "Skip intro"
@@ -38,6 +37,7 @@ msgstr "Bord droit"
3837#: qml/Components/EdgeDemo.qml:114
3938msgid "Try swiping from the right edge to unlock the phone"
4039msgstr ""
40+"Faites glisser votre doigt à partir du bord droit pour déverrouiller."
4141
4242#: qml/Components/EdgeDemo.qml:145
4343msgid "Top edge"
@@ -46,6 +46,8 @@ msgstr "Bord supérieur"
4646#: qml/Components/EdgeDemo.qml:146
4747msgid "Try swiping from the top edge to access the indicators"
4848msgstr ""
49+"Faites glisser votre doigt à partir du bord supérieur pour accéder aux "
50+"indicateurs."
4951
5052#: qml/Components/EdgeDemo.qml:171
5153msgid "Close"
@@ -54,6 +56,8 @@ msgstr "Fermer"
5456#: qml/Components/EdgeDemo.qml:172
5557msgid "Swipe up again to close the settings screen"
5658msgstr ""
59+"Faites glisser à nouveau votre doigt vers le bord supérieur pour fermer "
60+"l'écran des paramètres"
5761
5862#: qml/Components/EdgeDemo.qml:199
5963msgid "Left edge"
@@ -62,16 +66,20 @@ msgstr "Bord gauche"
6266#: qml/Components/EdgeDemo.qml:200
6367msgid "Swipe from the left to reveal the launcher for quick access to apps"
6468msgstr ""
69+"Faites glisser votre doigt à partir du bord gauche pour afficher le lanceur "
70+"d'applications."
6571
6672#: qml/Components/EdgeDemo.qml:227
6773msgid "Well done"
68−msgstr ""
74+msgstr "Félicitations"
6975
7076#: qml/Components/EdgeDemo.qml:228
7177msgid ""
7278"You have now mastered the edge gestures and can start using the "
7379"phone<br><br>Tap on the screen to start"
7480msgstr ""
81+"Vous maîtrisez maintenant les différents gestes et pouvez commencer à "
82+"utiliser le téléphone<br><br>Appuyez sur l'écran pour commencer"
7583
7684#: qml/Components/PageHeader.qml:365
7785msgid "Recent searches"
@@ -79,28 +87,28 @@ msgstr "Recherches récentes"
7987
8088#: qml/Components/SeeMore.qml:35
8189msgid "See more"
82−msgstr ""
90+msgstr "Voir plus"
8391
8492#: qml/Components/SeeMore.qml:58
8593msgid "See less"
86−msgstr ""
94+msgstr "Voir moins"
8795
88−#: qml/Dash/DashApps.qml:38
96+#: qml/Dash/DashApps.qml:37
8997msgid "Recent"
90−msgstr ""
98+msgstr "Récent"
9199
92100#: qml/Dash/PreviewListView.qml:52
93101#, qt-format
94102msgid "%1 Preview"
95−msgstr ""
103+msgstr "%1 Aperçu"
96104
97105#: qml/Dash/Previews/PreviewActionCombo.qml:34
98106msgid "More..."
99−msgstr ""
107+msgstr "Plus..."
100108
101109#: qml/Dash/Previews/PreviewActionCombo.qml:34
102110msgid "Less..."
103−msgstr ""
111+msgstr "Moins..."
104112
105113#: qml/Dash/Previews/PreviewRatingInput.qml:81
106114msgid "Rate this"
@@ -114,6 +122,10 @@ msgstr "Ajouter un avis"
114122msgid "Send"
115123msgstr "Envoyer"
116124
125+#: qml/Greeter/Greeter.qml:151
126+msgid "Swipe to unlock"
127+msgstr "Faites glisser pour déverrouiller"
128+
117129#: qml/Greeter/Lockscreen.qml:149
118130msgid "Emergency Call"
119131msgstr "Appel d'urgence"
@@ -145,7 +157,7 @@ msgstr "Parlez maintenant…"
145157
146158#: qml/Hud/Hud.qml:94
147159msgid "Speaking..."
148−msgstr ""
160+msgstr "En cours d'écoute..."
149161
150162#: qml/Notifications/NotificationMenuItemFactory.qml:91
151163msgid "Show password"
@@ -153,29 +165,13 @@ msgstr "Afficher le mot de passe"
153165
154166#: qml/Notifications/NotificationMenuItemFactory.qml:103
155167msgid "Please enter SIM PIN"
156−msgstr ""
168+msgstr "Veuillez entrer le code PIN de votre carte SIM"
157169
158170#: qml/Panel/SearchIndicator.qml:27
159171msgid "Search"
160172msgstr "Rechercher"
161173
162−#: qml/Shell.qml:417
174+#: qml/Shell.qml:348
163175#, qt-format
164176msgid "Please enter %1"
165177msgstr "Veuillez saisir %1"
166−
167−#~ msgid "Review"
168−#~ msgstr "Avis"
169−
170−#, qt-format
171−#~ msgid "%1 review"
172−#~ msgid_plural "%1 reviews"
173−#~ msgstr[0] "%1 avis"
174−#~ msgstr[1] "%1 avis"
175−
176−#~ msgid "Comments:"
177−#~ msgstr "Commentaires :"
178−
179−#, qt-format
180−#~ msgid "(%1)"
181−#~ msgstr "(%1)"
po/gd.po+22−36
@@ -7,26 +7,24 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
11−"PO-Revision-Date: 2013-09-30 10:34+0000\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
11+"PO-Revision-Date: 2014-05-17 21:08+0000\n"
1212"Last-Translator: Akerbeltz <fios@akerbeltz.org>\n"
1313"Language-Team: Gaelic; Scottish <gd@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=4; plural=(n==1 || n==11) ? 0 : (n==2 || n==12) ? 1 : "
18−"(n > 2 && n < 20) ? 2 : 3;\n"
19−"X-Launchpad-Export-Date: 2014-03-28 06:48+0000\n"
20−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-18 05:57+0000\n"
18+"X-Generator: Launchpad (build 17007)\n"
2119
2220#: plugins/Unity/Launcher/launcheritem.cpp:43
2321#: plugins/Unity/Launcher/launcheritem.cpp:73
2422msgid "Lock to Launcher"
25−msgstr ""
23+msgstr "Glais ris an lòinsear"
2624
2725#: plugins/Unity/Launcher/launcheritem.cpp:73
2826msgid "Unlock from Launcher"
29−msgstr ""
27+msgstr "Dealaich on lòinsear"
3028
3129#: qml/Components/EdgeDemoOverlay.qml:151
3230msgid "Skip intro"
@@ -79,6 +77,8 @@ msgid ""
7977"You have now mastered the edge gestures and can start using the "
8078"phone<br><br>Tap on the screen to start"
8179msgstr ""
80+"Fhuair thu air na gluasadan oire ceart a dhèanamh a-nis agus is urrainn dhut "
81+"am fòn a chleachdadh<br><br>Thoir gnogag air an sgrìn airson tòiseachadh"
8282
8383#: qml/Components/PageHeader.qml:365
8484msgid "Recent searches"
@@ -86,28 +86,28 @@ msgstr "Na lorg thu o chionn goirid"
8686
8787#: qml/Components/SeeMore.qml:35
8888msgid "See more"
89−msgstr ""
89+msgstr "Seall barrachd"
9090
9191#: qml/Components/SeeMore.qml:58
9292msgid "See less"
93−msgstr ""
93+msgstr "Seall nas lugha"
9494
95−#: qml/Dash/DashApps.qml:38
95+#: qml/Dash/DashApps.qml:37
9696msgid "Recent"
97−msgstr ""
97+msgstr "O chionn goirid"
9898
9999#: qml/Dash/PreviewListView.qml:52
100100#, qt-format
101101msgid "%1 Preview"
102−msgstr ""
102+msgstr "Ro-shealladh %1"
103103
104104#: qml/Dash/Previews/PreviewActionCombo.qml:34
105105msgid "More..."
106−msgstr ""
106+msgstr "Barrachd..."
107107
108108#: qml/Dash/Previews/PreviewActionCombo.qml:34
109109msgid "Less..."
110−msgstr ""
110+msgstr "Nas lugha..."
111111
112112#: qml/Dash/Previews/PreviewRatingInput.qml:81
113113msgid "Rate this"
@@ -121,6 +121,10 @@ msgstr "Cuir lèirmheas ris"
121121msgid "Send"
122122msgstr "Cuir"
123123
124+#: qml/Greeter/Greeter.qml:151
125+msgid "Swipe to unlock"
126+msgstr "Dèan grad-shlaighdeadh gus a' ghlas a thoirt dheth"
127+
124128#: qml/Greeter/Lockscreen.qml:149
125129msgid "Emergency Call"
126130msgstr "Gairm èiginn"
@@ -156,35 +160,17 @@ msgstr "A' bruidhinn..."
156160
157161#: qml/Notifications/NotificationMenuItemFactory.qml:91
158162msgid "Show password"
159−msgstr ""
163+msgstr "Seall am facal-faire"
160164
161165#: qml/Notifications/NotificationMenuItemFactory.qml:103
162166msgid "Please enter SIM PIN"
163−msgstr ""
167+msgstr "Cuir a-steach SIM PIN"
164168
165169#: qml/Panel/SearchIndicator.qml:27
166170msgid "Search"
167171msgstr "Lorg"
168172
169−#: qml/Shell.qml:417
173+#: qml/Shell.qml:348
170174#, qt-format
171175msgid "Please enter %1"
172176msgstr "Cuir a-steach %1"
173−
174−#, qt-format
175−#~ msgid "(%1)"
176−#~ msgstr "(%1)"
177−
178−#~ msgid "Comments:"
179−#~ msgstr "Beachdan"
180−
181−#~ msgid "Review"
182−#~ msgstr "Lèirmheas"
183−
184−#, qt-format
185−#~ msgid "%1 review"
186−#~ msgid_plural "%1 reviews"
187−#~ msgstr[0] "%1 lèirmheas"
188−#~ msgstr[1] "%1 lèirmheas"
189−#~ msgstr[2] "%1 lèirmheasan"
190−#~ msgstr[3] "%1 lèirmheas"
po/gl.po+10−6
@@ -7,15 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
11−"PO-Revision-Date: 2014-04-08 07:04+0000\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
11+"PO-Revision-Date: 2014-05-03 07:31+0000\n"
1212"Last-Translator: Marcos Lans <Unknown>\n"
1313"Language-Team: Galician <gl@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2014-04-09 07:31+0000\n"
18−"X-Generator: Launchpad (build 16976)\n"
17+"X-Launchpad-Export-Date: 2014-05-06 07:34+0000\n"
18+"X-Generator: Launchpad (build 16996)\n"
1919
2020#: plugins/Unity/Launcher/launcheritem.cpp:43
2121#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -86,7 +86,7 @@ msgstr "Ver máis"
8686msgid "See less"
8787msgstr "Ver menos"
8888
89−#: qml/Dash/DashApps.qml:38
89+#: qml/Dash/DashApps.qml:37
9090msgid "Recent"
9191msgstr "Recentes"
9292
@@ -115,6 +115,10 @@ msgstr "Engadir unha opinión"
115115msgid "Send"
116116msgstr "Enviar"
117117
118+#: qml/Greeter/Greeter.qml:151
119+msgid "Swipe to unlock"
120+msgstr "Esvare para desbloquear"
121+
118122#: qml/Greeter/Lockscreen.qml:149
119123msgid "Emergency Call"
120124msgstr "Chamada de emerxencia"
@@ -160,7 +164,7 @@ msgstr "Introduza o PIN da SIM"
160164msgid "Search"
161165msgstr "Buscar"
162166
163−#: qml/Shell.qml:417
167+#: qml/Shell.qml:348
164168#, qt-format
165169msgid "Please enter %1"
166170msgstr "Introduza %1"
po/he.po+19−30
@@ -7,16 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
11−"PO-Revision-Date: 2013-11-20 08:30+0000\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
11+"PO-Revision-Date: 2014-05-15 21:19+0000\n"
1212"Last-Translator: Yaron <sh.yaron@gmail.com>\n"
1313"Language-Team: Hebrew <he@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2014-03-28 06:48+0000\n"
19−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-16 06:52+0000\n"
18+"X-Generator: Launchpad (build 17007)\n"
2019
2120#: plugins/Unity/Launcher/launcheritem.cpp:43
2221#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -72,6 +71,8 @@ msgid ""
7271"You have now mastered the edge gestures and can start using the "
7372"phone<br><br>Tap on the screen to start"
7473msgstr ""
74+"ברגעים אלו סיימת את התמחותך בשימוש במחוות קצה והטלפון פתוח לשימושך<br><br>נא "
75+"לגעת במסך כדי להתחיל"
7576
7677#: qml/Components/PageHeader.qml:365
7778msgid "Recent searches"
@@ -79,28 +80,28 @@ msgstr "חיפושים אחרונים"
7980
8081#: qml/Components/SeeMore.qml:35
8182msgid "See more"
82−msgstr ""
83+msgstr "לראות עוד"
8384
8485#: qml/Components/SeeMore.qml:58
8586msgid "See less"
86−msgstr ""
87+msgstr "לראות פחות"
8788
88−#: qml/Dash/DashApps.qml:38
89+#: qml/Dash/DashApps.qml:37
8990msgid "Recent"
90−msgstr ""
91+msgstr "בשימוש לאחרונה"
9192
9293#: qml/Dash/PreviewListView.qml:52
9394#, qt-format
9495msgid "%1 Preview"
95−msgstr ""
96+msgstr "תצוגה מקדימה של %1"
9697
9798#: qml/Dash/Previews/PreviewActionCombo.qml:34
9899msgid "More..."
99−msgstr ""
100+msgstr "עוד…"
100101
101102#: qml/Dash/Previews/PreviewActionCombo.qml:34
102103msgid "Less..."
103−msgstr ""
104+msgstr "פחות…"
104105
105106#: qml/Dash/Previews/PreviewRatingInput.qml:81
106107msgid "Rate this"
@@ -114,6 +115,10 @@ msgstr "הוספת סקירה"
114115msgid "Send"
115116msgstr "שליחה"
116117
118+#: qml/Greeter/Greeter.qml:151
119+msgid "Swipe to unlock"
120+msgstr "יש להחליק לפתיחה"
121+
117122#: qml/Greeter/Lockscreen.qml:149
118123msgid "Emergency Call"
119124msgstr "שיחת חירום"
@@ -153,29 +158,13 @@ msgstr "הצגת הססמה"
153158
154159#: qml/Notifications/NotificationMenuItemFactory.qml:103
155160msgid "Please enter SIM PIN"
156−msgstr ""
161+msgstr "נא להזין את קוד ה־<U+200F>SIM"
157162
158163#: qml/Panel/SearchIndicator.qml:27
159164msgid "Search"
160165msgstr "חיפוש"
161166
162−#: qml/Shell.qml:417
167+#: qml/Shell.qml:348
163168#, qt-format
164169msgid "Please enter %1"
165170msgstr "נא להזין %1"
166−
167−#, qt-format
168−#~ msgid "(%1)"
169−#~ msgstr "(%1)"
170−
171−#~ msgid "Comments:"
172−#~ msgstr "הערות:"
173−
174−#~ msgid "Review"
175−#~ msgstr "סקירה"
176−
177−#, qt-format
178−#~ msgid "%1 review"
179−#~ msgid_plural "%1 reviews"
180−#~ msgstr[0] "סקירה %1"
181−#~ msgstr[1] "%1 סקירות"
po/hi.po+9−9
@@ -7,16 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
1111"PO-Revision-Date: 2014-01-15 01:49+0000\n"
1212"Last-Translator: Siddhanathan S. <Unknown>\n"
1313"Language-Team: Hindi <hi@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2014-03-28 06:48+0000\n"
19−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-01 06:43+0000\n"
18+"X-Generator: Launchpad (build 16985)\n"
2019
2120#: plugins/Unity/Launcher/launcheritem.cpp:43
2221#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -85,7 +84,7 @@ msgstr ""
8584msgid "See less"
8685msgstr ""
8786
88−#: qml/Dash/DashApps.qml:38
87+#: qml/Dash/DashApps.qml:37
8988msgid "Recent"
9089msgstr ""
9190
@@ -114,6 +113,10 @@ msgstr "समीक्षा दे"
114113msgid "Send"
115114msgstr "भेजें"
116115
116+#: qml/Greeter/Greeter.qml:151
117+msgid "Swipe to unlock"
118+msgstr ""
119+
117120#: qml/Greeter/Lockscreen.qml:149
118121msgid "Emergency Call"
119122msgstr "आपातकालीन कॉल"
@@ -159,10 +162,7 @@ msgstr ""
159162msgid "Search"
160163msgstr "खोजें"
161164
162−#: qml/Shell.qml:417
165+#: qml/Shell.qml:348
163166#, qt-format
164167msgid "Please enter %1"
165168msgstr ""
166−
167−#~ msgid "Review"
168−#~ msgstr "समीक्षा"
po/hr.po+9−7
@@ -7,17 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
1111"PO-Revision-Date: 2013-06-27 04:14+0000\n"
1212"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
1313"Language-Team: Croatian <hr@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
18−"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
19−"X-Launchpad-Export-Date: 2014-03-28 06:49+0000\n"
20−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-01 06:44+0000\n"
18+"X-Generator: Launchpad (build 16985)\n"
2119
2220#: plugins/Unity/Launcher/launcheritem.cpp:43
2321#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -86,7 +84,7 @@ msgstr ""
8684msgid "See less"
8785msgstr ""
8886
89−#: qml/Dash/DashApps.qml:38
87+#: qml/Dash/DashApps.qml:37
9088msgid "Recent"
9189msgstr ""
9290
@@ -115,6 +113,10 @@ msgstr ""
115113msgid "Send"
116114msgstr ""
117115
116+#: qml/Greeter/Greeter.qml:151
117+msgid "Swipe to unlock"
118+msgstr ""
119+
118120#: qml/Greeter/Lockscreen.qml:149
119121msgid "Emergency Call"
120122msgstr ""
@@ -160,7 +162,7 @@ msgstr ""
160162msgid "Search"
161163msgstr "Pretraživanje"
162164
163−#: qml/Shell.qml:417
165+#: qml/Shell.qml:348
164166#, qt-format
165167msgid "Please enter %1"
166168msgstr ""
po/hu.po+9−22
@@ -7,16 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
1111"PO-Revision-Date: 2014-01-14 23:02+0000\n"
1212"Last-Translator: Kristóf Kiszel <Unknown>\n"
1313"Language-Team: Hungarian <hu@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2014-03-28 06:48+0000\n"
19−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-01 06:43+0000\n"
18+"X-Generator: Launchpad (build 16985)\n"
2019
2120#: plugins/Unity/Launcher/launcheritem.cpp:43
2221#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -87,7 +86,7 @@ msgstr ""
8786msgid "See less"
8887msgstr ""
8988
90−#: qml/Dash/DashApps.qml:38
89+#: qml/Dash/DashApps.qml:37
9190msgid "Recent"
9291msgstr ""
9392
@@ -116,6 +115,10 @@ msgstr "Értékelés hozzáadása"
116115msgid "Send"
117116msgstr "Küldés"
118117
118+#: qml/Greeter/Greeter.qml:151
119+msgid "Swipe to unlock"
120+msgstr ""
121+
119122#: qml/Greeter/Lockscreen.qml:149
120123msgid "Emergency Call"
121124msgstr "Vészhívás"
@@ -161,23 +164,7 @@ msgstr ""
161164msgid "Search"
162165msgstr "Keresés"
163166
164−#: qml/Shell.qml:417
167+#: qml/Shell.qml:348
165168#, qt-format
166169msgid "Please enter %1"
167170msgstr "Adja meg a következőt: %1"
168−
169−#, qt-format
170−#~ msgid "%1 review"
171−#~ msgid_plural "%1 reviews"
172−#~ msgstr[0] "%1 értékelés"
173−#~ msgstr[1] "%1 értékelés"
174−
175−#, qt-format
176−#~ msgid "(%1)"
177−#~ msgstr "(%1)"
178−
179−#~ msgid "Comments:"
180−#~ msgstr "Hozzászólások:"
181−
182−#~ msgid "Review"
183−#~ msgstr "Értékelés"
po/hy.po+9−6
@@ -7,16 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
1111"PO-Revision-Date: 2013-06-27 04:43+0000\n"
1212"Last-Translator: iAbaS <sosabazyan@yandex.ru>\n"
1313"Language-Team: Armenian <hy@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2014-03-28 06:48+0000\n"
19−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-01 06:43+0000\n"
18+"X-Generator: Launchpad (build 16985)\n"
2019
2120#: plugins/Unity/Launcher/launcheritem.cpp:43
2221#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -85,7 +84,7 @@ msgstr ""
8584msgid "See less"
8685msgstr ""
8786
88−#: qml/Dash/DashApps.qml:38
87+#: qml/Dash/DashApps.qml:37
8988msgid "Recent"
9089msgstr ""
9190
@@ -114,6 +113,10 @@ msgstr ""
114113msgid "Send"
115114msgstr ""
116115
116+#: qml/Greeter/Greeter.qml:151
117+msgid "Swipe to unlock"
118+msgstr ""
119+
117120#: qml/Greeter/Lockscreen.qml:149
118121msgid "Emergency Call"
119122msgstr ""
@@ -159,7 +162,7 @@ msgstr ""
159162msgid "Search"
160163msgstr "Որոնում"
161164
162−#: qml/Shell.qml:417
165+#: qml/Shell.qml:348
163166#, qt-format
164167msgid "Please enter %1"
165168msgstr ""
po/id.po+9−6
@@ -7,16 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
1111"PO-Revision-Date: 2013-06-26 22:35+0000\n"
1212"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1313"Language-Team: Indonesian <id@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2014-03-28 06:48+0000\n"
19−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-01 06:43+0000\n"
18+"X-Generator: Launchpad (build 16985)\n"
2019
2120#: plugins/Unity/Launcher/launcheritem.cpp:43
2221#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -85,7 +84,7 @@ msgstr ""
8584msgid "See less"
8685msgstr ""
8786
88−#: qml/Dash/DashApps.qml:38
87+#: qml/Dash/DashApps.qml:37
8988msgid "Recent"
9089msgstr ""
9190
@@ -114,6 +113,10 @@ msgstr ""
114113msgid "Send"
115114msgstr ""
116115
116+#: qml/Greeter/Greeter.qml:151
117+msgid "Swipe to unlock"
118+msgstr ""
119+
117120#: qml/Greeter/Lockscreen.qml:149
118121msgid "Emergency Call"
119122msgstr ""
@@ -159,7 +162,7 @@ msgstr ""
159162msgid "Search"
160163msgstr ""
161164
162−#: qml/Shell.qml:417
165+#: qml/Shell.qml:348
163166#, qt-format
164167msgid "Please enter %1"
165168msgstr ""
po/is.po+9−22
@@ -7,16 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
1111"PO-Revision-Date: 2013-09-18 16:22+0000\n"
1212"Last-Translator: Andri Thorlacius <Unknown>\n"
1313"Language-Team: Icelandic <is@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2014-03-28 06:48+0000\n"
19−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-01 06:43+0000\n"
18+"X-Generator: Launchpad (build 16985)\n"
2019
2120#: plugins/Unity/Launcher/launcheritem.cpp:43
2221#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -86,7 +85,7 @@ msgstr ""
8685msgid "See less"
8786msgstr ""
8887
89−#: qml/Dash/DashApps.qml:38
88+#: qml/Dash/DashApps.qml:37
9089msgid "Recent"
9190msgstr ""
9291
@@ -115,6 +114,10 @@ msgstr "Gefa umsögn"
115114msgid "Send"
116115msgstr "Senda"
117116
117+#: qml/Greeter/Greeter.qml:151
118+msgid "Swipe to unlock"
119+msgstr ""
120+
118121#: qml/Greeter/Lockscreen.qml:149
119122msgid "Emergency Call"
120123msgstr "Neyðarsímtal"
@@ -160,23 +163,7 @@ msgstr ""
160163msgid "Search"
161164msgstr "Leita"
162165
163−#: qml/Shell.qml:417
166+#: qml/Shell.qml:348
164167#, qt-format
165168msgid "Please enter %1"
166169msgstr ""
167−
168−#, qt-format
169−#~ msgid "(%1)"
170−#~ msgstr "(%1)"
171−
172−#~ msgid "Comments:"
173−#~ msgstr "Athugasemdir:"
174−
175−#~ msgid "Review"
176−#~ msgstr "Umsögn"
177−
178−#, qt-format
179−#~ msgid "%1 review"
180−#~ msgid_plural "%1 reviews"
181−#~ msgstr[0] "%1 ummæli"
182−#~ msgstr[1] "%1 ummæli"
po/it.po+9−22
@@ -7,16 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
1111"PO-Revision-Date: 2014-01-22 09:15+0000\n"
1212"Last-Translator: Domenico <domenico.verde125@live.it>\n"
1313"Language-Team: Italian <it@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2014-03-28 06:48+0000\n"
19−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-01 06:43+0000\n"
18+"X-Generator: Launchpad (build 16985)\n"
2019
2120#: plugins/Unity/Launcher/launcheritem.cpp:43
2221#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -90,7 +89,7 @@ msgstr ""
9089msgid "See less"
9190msgstr ""
9291
93−#: qml/Dash/DashApps.qml:38
92+#: qml/Dash/DashApps.qml:37
9493msgid "Recent"
9594msgstr ""
9695
@@ -119,6 +118,10 @@ msgstr "Aggiungi una recensione"
119118msgid "Send"
120119msgstr "Invia"
121120
121+#: qml/Greeter/Greeter.qml:151
122+msgid "Swipe to unlock"
123+msgstr ""
124+
122125#: qml/Greeter/Lockscreen.qml:149
123126msgid "Emergency Call"
124127msgstr "Chiamata di emergenza"
@@ -164,23 +167,7 @@ msgstr ""
164167msgid "Search"
165168msgstr "Cerca"
166169
167−#: qml/Shell.qml:417
170+#: qml/Shell.qml:348
168171#, qt-format
169172msgid "Please enter %1"
170173msgstr "Inserire %1"
171−
172−#, qt-format
173−#~ msgid "(%1)"
174−#~ msgstr "(%1)"
175−
176−#, qt-format
177−#~ msgid "%1 review"
178−#~ msgid_plural "%1 reviews"
179−#~ msgstr[0] "%1 recensione"
180−#~ msgstr[1] "%1 recensioni"
181−
182−#~ msgid "Comments:"
183−#~ msgstr "Commenti:"
184−
185−#~ msgid "Review"
186−#~ msgstr "Recensisci"
po/ja.po+9−13
@@ -7,16 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
1111"PO-Revision-Date: 2014-01-18 07:01+0000\n"
1212"Last-Translator: Shushi Kurose <md81bird@hitaki.net>\n"
1313"Language-Team: Japanese <ja@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2014-03-28 06:48+0000\n"
19−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-01 06:43+0000\n"
18+"X-Generator: Launchpad (build 16985)\n"
2019
2120#: plugins/Unity/Launcher/launcheritem.cpp:43
2221#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -85,7 +84,7 @@ msgstr ""
8584msgid "See less"
8685msgstr ""
8786
88−#: qml/Dash/DashApps.qml:38
87+#: qml/Dash/DashApps.qml:37
8988msgid "Recent"
9089msgstr ""
9190
@@ -114,6 +113,10 @@ msgstr ""
114113msgid "Send"
115114msgstr "送信"
116115
116+#: qml/Greeter/Greeter.qml:151
117+msgid "Swipe to unlock"
118+msgstr ""
119+
117120#: qml/Greeter/Lockscreen.qml:149
118121msgid "Emergency Call"
119122msgstr ""
@@ -159,14 +162,7 @@ msgstr ""
159162msgid "Search"
160163msgstr "検索"
161164
162−#: qml/Shell.qml:417
165+#: qml/Shell.qml:348
163166#, qt-format
164167msgid "Please enter %1"
165168msgstr ""
166−
167−#~ msgid "Comments:"
168−#~ msgstr "コメント:"
169−
170−#, qt-format
171−#~ msgid "(%1)"
172−#~ msgstr "(%1)"
po/km.po+12−24
@@ -7,16 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
11−"PO-Revision-Date: 2014-03-04 02:32+0000\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
11+"PO-Revision-Date: 2014-05-19 01:42+0000\n"
1212"Last-Translator: Khoem Sokhem <khoemsokhem@khmeros.info>\n"
1313"Language-Team: Khmer <km@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2014-03-28 06:49+0000\n"
19−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-22 06:49+0000\n"
18+"X-Generator: Launchpad (build 17017)\n"
2019
2120#: plugins/Unity/Launcher/launcheritem.cpp:43
2221#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -89,14 +88,14 @@ msgstr "មើល​ច្រើន​ទៀត"
8988msgid "See less"
9089msgstr "មើល​តិច​ជាង"
9190
92−#: qml/Dash/DashApps.qml:38
91+#: qml/Dash/DashApps.qml:37
9392msgid "Recent"
94−msgstr ""
93+msgstr "បច្ចុប្បន្ន"
9594
9695#: qml/Dash/PreviewListView.qml:52
9796#, qt-format
9897msgid "%1 Preview"
99−msgstr ""
98+msgstr "មើល​ជា​មុន %1"
10099
101100#: qml/Dash/Previews/PreviewActionCombo.qml:34
102101msgid "More..."
@@ -118,6 +117,10 @@ msgstr "បន្ថែម​ការ​ពិនិត្យ"
118117msgid "Send"
119118msgstr "ផ្ញើ"
120119
120+#: qml/Greeter/Greeter.qml:151
121+msgid "Swipe to unlock"
122+msgstr "អូស​ដើម្បី​ដោះសោ"
123+
121124#: qml/Greeter/Lockscreen.qml:149
122125msgid "Emergency Call"
123126msgstr "ការ​ហៅ​ពេល​អាសន្ន"
@@ -163,22 +166,7 @@ msgstr "បញ្ចូល​កូដ PIN របស់​ស៊ីមកាត"
163166msgid "Search"
164167msgstr "ស្វែង​រក"
165168
166−#: qml/Shell.qml:417
169+#: qml/Shell.qml:348
167170#, qt-format
168171msgid "Please enter %1"
169172msgstr "សូម​បញ្ចូល %1"
170−
171−#, qt-format
172−#~ msgid "(%1)"
173−#~ msgstr "(%1)"
174−
175−#, qt-format
176−#~ msgid "%1 review"
177−#~ msgid_plural "%1 reviews"
178−#~ msgstr[0] "ពិនិត្យ​មើល %1"
179−
180−#~ msgid "Comments:"
181−#~ msgstr "មតិយោបល់៖"
182−
183−#~ msgid "Review"
184−#~ msgstr "ការ​ពិនិត្យ"
po/kn.po+9−6
@@ -7,16 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
1111"PO-Revision-Date: 2013-06-27 05:43+0000\n"
1212"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
1313"Language-Team: Kannada <kn@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2014-03-28 06:49+0000\n"
19−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-01 06:43+0000\n"
18+"X-Generator: Launchpad (build 16985)\n"
2019
2120#: plugins/Unity/Launcher/launcheritem.cpp:43
2221#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -85,7 +84,7 @@ msgstr ""
8584msgid "See less"
8685msgstr ""
8786
88−#: qml/Dash/DashApps.qml:38
87+#: qml/Dash/DashApps.qml:37
8988msgid "Recent"
9089msgstr ""
9190
@@ -114,6 +113,10 @@ msgstr ""
114113msgid "Send"
115114msgstr ""
116115
116+#: qml/Greeter/Greeter.qml:151
117+msgid "Swipe to unlock"
118+msgstr ""
119+
117120#: qml/Greeter/Lockscreen.qml:149
118121msgid "Emergency Call"
119122msgstr ""
@@ -159,7 +162,7 @@ msgstr ""
159162msgid "Search"
160163msgstr "ಹುಡುಕು"
161164
162−#: qml/Shell.qml:417
165+#: qml/Shell.qml:348
163166#, qt-format
164167msgid "Please enter %1"
165168msgstr ""
po/ko.po+9−6
@@ -7,16 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
1111"PO-Revision-Date: 2013-10-10 07:04+0000\n"
1212"Last-Translator: Kim Boram <boramism@gmail.com>\n"
1313"Language-Team: Korean <ko@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2014-03-28 06:49+0000\n"
19−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-01 06:43+0000\n"
18+"X-Generator: Launchpad (build 16985)\n"
2019
2120#: plugins/Unity/Launcher/launcheritem.cpp:43
2221#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -85,7 +84,7 @@ msgstr ""
8584msgid "See less"
8685msgstr ""
8786
88−#: qml/Dash/DashApps.qml:38
87+#: qml/Dash/DashApps.qml:37
8988msgid "Recent"
9089msgstr ""
9190
@@ -114,6 +113,10 @@ msgstr ""
114113msgid "Send"
115114msgstr ""
116115
116+#: qml/Greeter/Greeter.qml:151
117+msgid "Swipe to unlock"
118+msgstr ""
119+
117120#: qml/Greeter/Lockscreen.qml:149
118121msgid "Emergency Call"
119122msgstr ""
@@ -159,7 +162,7 @@ msgstr ""
159162msgid "Search"
160163msgstr "검색"
161164
162−#: qml/Shell.qml:417
165+#: qml/Shell.qml:348
163166#, qt-format
164167msgid "Please enter %1"
165168msgstr ""
po/ky.po+9−6
@@ -7,16 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
1111"PO-Revision-Date: 2013-06-27 06:17+0000\n"
1212"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
1313"Language-Team: Kirghiz <ky@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2014-03-28 06:49+0000\n"
19−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-01 06:43+0000\n"
18+"X-Generator: Launchpad (build 16985)\n"
2019
2120#: plugins/Unity/Launcher/launcheritem.cpp:43
2221#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -85,7 +84,7 @@ msgstr ""
8584msgid "See less"
8685msgstr ""
8786
88−#: qml/Dash/DashApps.qml:38
87+#: qml/Dash/DashApps.qml:37
8988msgid "Recent"
9089msgstr ""
9190
@@ -114,6 +113,10 @@ msgstr ""
114113msgid "Send"
115114msgstr ""
116115
116+#: qml/Greeter/Greeter.qml:151
117+msgid "Swipe to unlock"
118+msgstr ""
119+
117120#: qml/Greeter/Lockscreen.qml:149
118121msgid "Emergency Call"
119122msgstr ""
@@ -159,7 +162,7 @@ msgstr ""
159162msgid "Search"
160163msgstr "Издөө"
161164
162−#: qml/Shell.qml:417
165+#: qml/Shell.qml:348
163166#, qt-format
164167msgid "Please enter %1"
165168msgstr ""
po/lo.po+9−13
@@ -7,16 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
1111"PO-Revision-Date: 2013-10-02 10:00+0000\n"
1212"Last-Translator: Anousak <anousak@gmail.com>\n"
1313"Language-Team: Lao <lo@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2014-03-28 06:49+0000\n"
19−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-01 06:43+0000\n"
18+"X-Generator: Launchpad (build 16985)\n"
2019
2120#: plugins/Unity/Launcher/launcheritem.cpp:43
2221#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -85,7 +84,7 @@ msgstr ""
8584msgid "See less"
8685msgstr ""
8786
88−#: qml/Dash/DashApps.qml:38
87+#: qml/Dash/DashApps.qml:37
8988msgid "Recent"
9089msgstr ""
9190
@@ -114,6 +113,10 @@ msgstr ""
114113msgid "Send"
115114msgstr "ສົ່ງ"
116115
116+#: qml/Greeter/Greeter.qml:151
117+msgid "Swipe to unlock"
118+msgstr ""
119+
117120#: qml/Greeter/Lockscreen.qml:149
118121msgid "Emergency Call"
119122msgstr ""
@@ -159,14 +162,7 @@ msgstr ""
159162msgid "Search"
160163msgstr "ຊອກຫາ"
161164
162−#: qml/Shell.qml:417
165+#: qml/Shell.qml:348
163166#, qt-format
164167msgid "Please enter %1"
165168msgstr "ກະລູນາປ້ອນ %1"
166−
167−#, qt-format
168−#~ msgid "(%1)"
169−#~ msgstr "(%1)"
170−
171−#~ msgid "Comments:"
172−#~ msgstr "ຄໍ່ເຫັນ"
po/lt.po+15−30
@@ -7,17 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
11−"PO-Revision-Date: 2014-01-15 12:42+0000\n"
12−"Last-Translator: Gediminas Paulauskas <menesis@pov.lt>\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
11+"PO-Revision-Date: 2014-05-19 17:15+0000\n"
12+"Last-Translator: Mantas Kriaučiūnas <mantas@akl.lt>\n"
1313"Language-Team: Lithuanian <lt@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
18−"(n%100<10 || n%100>=20) ? 1 : 2;\n"
19−"X-Launchpad-Export-Date: 2014-03-28 06:49+0000\n"
20−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-22 06:49+0000\n"
18+"X-Generator: Launchpad (build 17017)\n"
2119
2220#: plugins/Unity/Launcher/launcheritem.cpp:43
2321#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -89,9 +87,9 @@ msgstr ""
8987msgid "See less"
9088msgstr ""
9189
92−#: qml/Dash/DashApps.qml:38
90+#: qml/Dash/DashApps.qml:37
9391msgid "Recent"
94−msgstr ""
92+msgstr "Paskiausieji"
9593
9694#: qml/Dash/PreviewListView.qml:52
9795#, qt-format
@@ -100,11 +98,11 @@ msgstr ""
10098
10199#: qml/Dash/Previews/PreviewActionCombo.qml:34
102100msgid "More..."
103−msgstr ""
101+msgstr "Daugiau..."
104102
105103#: qml/Dash/Previews/PreviewActionCombo.qml:34
106104msgid "Less..."
107−msgstr ""
105+msgstr "Mažiau..."
108106
109107#: qml/Dash/Previews/PreviewRatingInput.qml:81
110108msgid "Rate this"
@@ -118,6 +116,10 @@ msgstr "Pridėkite apžvalgą"
118116msgid "Send"
119117msgstr "Siųsti"
120118
119+#: qml/Greeter/Greeter.qml:151
120+msgid "Swipe to unlock"
121+msgstr "Braukite ir atrakinsite"
122+
121123#: qml/Greeter/Lockscreen.qml:149
122124msgid "Emergency Call"
123125msgstr "Pagalbos skambutis"
@@ -157,30 +159,13 @@ msgstr "Rodyti slaptažodį"
157159
158160#: qml/Notifications/NotificationMenuItemFactory.qml:103
159161msgid "Please enter SIM PIN"
160−msgstr ""
162+msgstr "Įveskite SIM kortelės PIN kodą"
161163
162164#: qml/Panel/SearchIndicator.qml:27
163165msgid "Search"
164166msgstr "Paieška"
165167
166−#: qml/Shell.qml:417
168+#: qml/Shell.qml:348
167169#, qt-format
168170msgid "Please enter %1"
169171msgstr "Prašom įvesti %1"
170−
171−#~ msgid "Comments:"
172−#~ msgstr "Komentarai:"
173−
174−#~ msgid "Review"
175−#~ msgstr "Apžvalga"
176−
177−#, qt-format
178−#~ msgid "%1 review"
179−#~ msgid_plural "%1 reviews"
180−#~ msgstr[0] "%1 apžvalga"
181−#~ msgstr[1] "%1 apžvalgos"
182−#~ msgstr[2] "%1 apžvalgų"
183−
184−#, qt-format
185−#~ msgid "(%1)"
186−#~ msgstr "(%1)"
po/lv.po+27−24
@@ -7,29 +7,28 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
11−"PO-Revision-Date: 2014-01-11 16:48+0000\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
11+"PO-Revision-Date: 2014-05-07 18:17+0000\n"
1212"Last-Translator: Jānis-Marks Gailis <jeanmarc.gailis@gmail.com>\n"
1313"Language-Team: Latvian <lv@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2;\n"
18−"X-Launchpad-Export-Date: 2014-03-28 06:49+0000\n"
19−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-10 08:01+0000\n"
18+"X-Generator: Launchpad (build 16996)\n"
2019
2120#: plugins/Unity/Launcher/launcheritem.cpp:43
2221#: plugins/Unity/Launcher/launcheritem.cpp:73
2322msgid "Lock to Launcher"
24−msgstr ""
23+msgstr "Pieslēgt palaidējam"
2524
2625#: plugins/Unity/Launcher/launcheritem.cpp:73
2726msgid "Unlock from Launcher"
28−msgstr ""
27+msgstr "Atslēgt no palaidēja"
2928
3029#: qml/Components/EdgeDemoOverlay.qml:151
3130msgid "Skip intro"
32−msgstr ""
31+msgstr "Izlaist Intro"
3332
3433#: qml/Components/EdgeDemo.qml:113
3534msgid "Right edge"
@@ -37,7 +36,7 @@ msgstr "Labā mala"
3736
3837#: qml/Components/EdgeDemo.qml:114
3938msgid "Try swiping from the right edge to unlock the phone"
40−msgstr ""
39+msgstr "Mēģiniet iesvelt no labās malas, lai atbloķētu tālruni"
4140
4241#: qml/Components/EdgeDemo.qml:145
4342msgid "Top edge"
@@ -45,7 +44,7 @@ msgstr "Augšējā mala"
4544
4645#: qml/Components/EdgeDemo.qml:146
4746msgid "Try swiping from the top edge to access the indicators"
48−msgstr ""
47+msgstr "Mēģiniet iesvelt no augšējās malas, lai piekļūt pie indikatoriem"
4948
5049#: qml/Components/EdgeDemo.qml:171
5150msgid "Close"
@@ -79,15 +78,15 @@ msgstr "Nesen veiktās meklēšanas"
7978
8079#: qml/Components/SeeMore.qml:35
8180msgid "See more"
82−msgstr ""
81+msgstr "Redzēt vairāk"
8382
8483#: qml/Components/SeeMore.qml:58
8584msgid "See less"
86−msgstr ""
85+msgstr "Redzēt mazāk"
8786
88−#: qml/Dash/DashApps.qml:38
87+#: qml/Dash/DashApps.qml:37
8988msgid "Recent"
90−msgstr ""
89+msgstr "Nesens"
9190
9291#: qml/Dash/PreviewListView.qml:52
9392#, qt-format
@@ -96,36 +95,40 @@ msgstr ""
9695
9796#: qml/Dash/Previews/PreviewActionCombo.qml:34
9897msgid "More..."
99−msgstr ""
98+msgstr "Vairāk..."
10099
101100#: qml/Dash/Previews/PreviewActionCombo.qml:34
102101msgid "Less..."
103−msgstr ""
102+msgstr "Mazāk..."
104103
105104#: qml/Dash/Previews/PreviewRatingInput.qml:81
106105msgid "Rate this"
107−msgstr ""
106+msgstr "Novērtēt šo"
108107
109108#: qml/Dash/Previews/PreviewRatingInput.qml:126
110109msgid "Add a review"
111−msgstr ""
110+msgstr "Komentēt"
112111
113112#: qml/Dash/Previews/PreviewRatingInput.qml:166
114113msgid "Send"
114+msgstr "Sūtīt"
115+
116+#: qml/Greeter/Greeter.qml:151
117+msgid "Swipe to unlock"
115118msgstr ""
116119
117120#: qml/Greeter/Lockscreen.qml:149
118121msgid "Emergency Call"
119−msgstr ""
122+msgstr "Neatliekamās Palīdzības zvans"
120123
121124#: qml/Greeter/PassphraseLockscreen.qml:59
122125#, qt-format
123126msgid "Hello %1"
124−msgstr ""
127+msgstr "Sveiki, %1"
125128
126129#: qml/Greeter/PassphraseLockscreen.qml:59
127130msgid "Hello"
128−msgstr ""
131+msgstr "Sveiki"
129132
130133#: qml/Hud/HudParametrizedActionsPage.qml:132
131134msgid "Confirm"
@@ -149,7 +152,7 @@ msgstr "Runa..."
149152
150153#: qml/Notifications/NotificationMenuItemFactory.qml:91
151154msgid "Show password"
152−msgstr ""
155+msgstr "Rādīt paroli"
153156
154157#: qml/Notifications/NotificationMenuItemFactory.qml:103
155158msgid "Please enter SIM PIN"
@@ -159,7 +162,7 @@ msgstr ""
159162msgid "Search"
160163msgstr "Meklēt"
161164
162−#: qml/Shell.qml:417
165+#: qml/Shell.qml:348
163166#, qt-format
164167msgid "Please enter %1"
165−msgstr ""
168+msgstr "Lūdzu ievadiet %1"
po/ml.po+10−23
@@ -7,16 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
1111"PO-Revision-Date: 2013-11-23 11:44+0000\n"
12−"Last-Translator: STyM Alfazz <Unknown>\n"
12+"Last-Translator: Stym alfaZ <Unknown>\n"
1313"Language-Team: Malayalam <ml@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2014-03-28 06:49+0000\n"
19−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-01 06:43+0000\n"
18+"X-Generator: Launchpad (build 16985)\n"
2019
2120#: plugins/Unity/Launcher/launcheritem.cpp:43
2221#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -87,7 +86,7 @@ msgstr ""
8786msgid "See less"
8887msgstr ""
8988
90−#: qml/Dash/DashApps.qml:38
89+#: qml/Dash/DashApps.qml:37
9190msgid "Recent"
9291msgstr ""
9392
@@ -116,6 +115,10 @@ msgstr "ഒരു അവലോകനം ചേര്‍ക്കുക"
116115msgid "Send"
117116msgstr "അയയ്‌ക്കുക"
118117
118+#: qml/Greeter/Greeter.qml:151
119+msgid "Swipe to unlock"
120+msgstr ""
121+
119122#: qml/Greeter/Lockscreen.qml:149
120123msgid "Emergency Call"
121124msgstr "അടിയന്തിര വിളി"
@@ -161,23 +164,7 @@ msgstr ""
161164msgid "Search"
162165msgstr "തിരയുക"
163166
164−#: qml/Shell.qml:417
167+#: qml/Shell.qml:348
165168#, qt-format
166169msgid "Please enter %1"
167170msgstr "ദയവായി %1 നല്‍കുക"
168−
169−#, qt-format
170−#~ msgid "(%1)"
171−#~ msgstr "(%1)"
172−
173−#~ msgid "Comments:"
174−#~ msgstr "അഭിപ്രായങ്ങള്‍:"
175−
176−#~ msgid "Review"
177−#~ msgstr "അവലോകനം"
178−
179−#, qt-format
180−#~ msgid "%1 review"
181−#~ msgid_plural "%1 reviews"
182−#~ msgstr[0] "%1 അവലോകനം"
183−#~ msgstr[1] "%1 അവലോകനങ്ങള്‍"
po/mr.po+9−6
@@ -7,16 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
1111"PO-Revision-Date: 2014-01-14 19:54+0000\n"
1212"Last-Translator: Rohan Deshmukh <Unknown>\n"
1313"Language-Team: Marathi <mr@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2014-03-28 06:49+0000\n"
19−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-01 06:43+0000\n"
18+"X-Generator: Launchpad (build 16985)\n"
2019
2120#: plugins/Unity/Launcher/launcheritem.cpp:43
2221#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -85,7 +84,7 @@ msgstr ""
8584msgid "See less"
8685msgstr ""
8786
88−#: qml/Dash/DashApps.qml:38
87+#: qml/Dash/DashApps.qml:37
8988msgid "Recent"
9089msgstr ""
9190
@@ -114,6 +113,10 @@ msgstr ""
114113msgid "Send"
115114msgstr ""
116115
116+#: qml/Greeter/Greeter.qml:151
117+msgid "Swipe to unlock"
118+msgstr ""
119+
117120#: qml/Greeter/Lockscreen.qml:149
118121msgid "Emergency Call"
119122msgstr ""
@@ -159,7 +162,7 @@ msgstr ""
159162msgid "Search"
160163msgstr ""
161164
162−#: qml/Shell.qml:417
165+#: qml/Shell.qml:348
163166#, qt-format
164167msgid "Please enter %1"
165168msgstr ""
po/ms.po+9−22
@@ -7,16 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
1111"PO-Revision-Date: 2014-01-17 09:05+0000\n"
1212"Last-Translator: abuyop <Unknown>\n"
1313"Language-Team: Malay <ms@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2014-03-28 06:49+0000\n"
19−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-01 06:43+0000\n"
18+"X-Generator: Launchpad (build 16985)\n"
2019
2120#: plugins/Unity/Launcher/launcheritem.cpp:43
2221#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -85,7 +84,7 @@ msgstr ""
8584msgid "See less"
8685msgstr ""
8786
88−#: qml/Dash/DashApps.qml:38
87+#: qml/Dash/DashApps.qml:37
8988msgid "Recent"
9089msgstr ""
9190
@@ -114,6 +113,10 @@ msgstr "Tambah ulasan"
114113msgid "Send"
115114msgstr "Hantar"
116115
116+#: qml/Greeter/Greeter.qml:151
117+msgid "Swipe to unlock"
118+msgstr ""
119+
117120#: qml/Greeter/Lockscreen.qml:149
118121msgid "Emergency Call"
119122msgstr "panggilan Kecemasan"
@@ -159,23 +162,7 @@ msgstr ""
159162msgid "Search"
160163msgstr "Gelintar"
161164
162−#: qml/Shell.qml:417
165+#: qml/Shell.qml:348
163166#, qt-format
164167msgid "Please enter %1"
165168msgstr "Sila masukkan %1"
166−
167−#~ msgid "Comments:"
168−#~ msgstr "Ulasan:"
169−
170−#~ msgid "Review"
171−#~ msgstr "Tinjauan"
172−
173−#, qt-format
174−#~ msgid "%1 review"
175−#~ msgid_plural "%1 reviews"
176−#~ msgstr[0] "%1 ulasan"
177−#~ msgstr[1] "%1 ulasan"
178−
179−#, qt-format
180−#~ msgid "(%1)"
181−#~ msgstr "(%1)"
po/my.po+9−13
@@ -7,16 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
1111"PO-Revision-Date: 2013-12-12 11:12+0000\n"
1212"Last-Translator: Pyae Sone <Unknown>\n"
1313"Language-Team: Burmese <my@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2014-03-28 06:48+0000\n"
19−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-01 06:43+0000\n"
18+"X-Generator: Launchpad (build 16985)\n"
2019
2120#: plugins/Unity/Launcher/launcheritem.cpp:43
2221#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -85,7 +84,7 @@ msgstr ""
8584msgid "See less"
8685msgstr ""
8786
88−#: qml/Dash/DashApps.qml:38
87+#: qml/Dash/DashApps.qml:37
8988msgid "Recent"
9089msgstr ""
9190
@@ -114,6 +113,10 @@ msgstr ""
114113msgid "Send"
115114msgstr "ပို့မည်"
116115
116+#: qml/Greeter/Greeter.qml:151
117+msgid "Swipe to unlock"
118+msgstr ""
119+
117120#: qml/Greeter/Lockscreen.qml:149
118121msgid "Emergency Call"
119122msgstr "အရေးပေါ်ခေါ်မည်"
@@ -159,14 +162,7 @@ msgstr ""
159162msgid "Search"
160163msgstr "ရှာဖွေ"
161164
162−#: qml/Shell.qml:417
165+#: qml/Shell.qml:348
163166#, qt-format
164167msgid "Please enter %1"
165168msgstr "%1ကိုရိုက်ထည့်ပါ"
166−
167−#, qt-format
168−#~ msgid "(%1)"
169−#~ msgstr "(%1)"
170−
171−#~ msgid "Comments:"
172−#~ msgstr "မှတ်ချက်များ-"
po/nb.po+41−36
@@ -7,125 +7,130 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
11−"PO-Revision-Date: 2013-06-27 07:02+0000\n"
12−"Last-Translator: Joakim Langvand <jlangvand@gmail.com>\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
11+"PO-Revision-Date: 2014-05-19 15:25+0000\n"
12+"Last-Translator: Thor Fjalestad <silvereyerocker@gmail.com>\n"
1313"Language-Team: Norwegian Bokmal <nb@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2014-03-28 06:49+0000\n"
19−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-22 06:49+0000\n"
18+"X-Generator: Launchpad (build 17017)\n"
2019
2120#: plugins/Unity/Launcher/launcheritem.cpp:43
2221#: plugins/Unity/Launcher/launcheritem.cpp:73
2322msgid "Lock to Launcher"
24−msgstr ""
23+msgstr "Lås til oppstarter"
2524
2625#: plugins/Unity/Launcher/launcheritem.cpp:73
2726msgid "Unlock from Launcher"
28−msgstr ""
27+msgstr "Lås opp fra oppstarter"
2928
3029#: qml/Components/EdgeDemoOverlay.qml:151
3130msgid "Skip intro"
32−msgstr ""
31+msgstr "Hopp over introduksjon"
3332
3433#: qml/Components/EdgeDemo.qml:113
3534msgid "Right edge"
36−msgstr ""
35+msgstr "Høyre kant"
3736
3837#: qml/Components/EdgeDemo.qml:114
3938msgid "Try swiping from the right edge to unlock the phone"
40−msgstr ""
39+msgstr "Prøv å sveipe fra høyre side for å låse opp telefonen"
4140
4241#: qml/Components/EdgeDemo.qml:145
4342msgid "Top edge"
44−msgstr ""
43+msgstr "Øvre kant"
4544
4645#: qml/Components/EdgeDemo.qml:146
4746msgid "Try swiping from the top edge to access the indicators"
48−msgstr ""
47+msgstr "Prøv å sveipe fra toppen for å få tilgang til innstillingene"
4948
5049#: qml/Components/EdgeDemo.qml:171
5150msgid "Close"
52−msgstr ""
51+msgstr "Lukk"
5352
5453#: qml/Components/EdgeDemo.qml:172
5554msgid "Swipe up again to close the settings screen"
56−msgstr ""
55+msgstr "Sveip opp igjen for å lukke innstillingsmenyen"
5756
5857#: qml/Components/EdgeDemo.qml:199
5958msgid "Left edge"
60−msgstr ""
59+msgstr "Venstre kant"
6160
6261#: qml/Components/EdgeDemo.qml:200
6362msgid "Swipe from the left to reveal the launcher for quick access to apps"
64−msgstr ""
63+msgstr "Sveip fra venstre for å få tilgang til programoppstarteren"
6564
6665#: qml/Components/EdgeDemo.qml:227
6766msgid "Well done"
68−msgstr ""
67+msgstr "Bra jobba"
6968
7069#: qml/Components/EdgeDemo.qml:228
7170msgid ""
7271"You have now mastered the edge gestures and can start using the "
7372"phone<br><br>Tap on the screen to start"
7473msgstr ""
74+"Du har nå mestret kantbevegelsene, og er klar til å bruke "
75+"telefonen<br><br>Trykk på skjermen for å begynne"
7576
7677#: qml/Components/PageHeader.qml:365
7778msgid "Recent searches"
78−msgstr "Siste søk"
79+msgstr "Nylige søk"
7980
8081#: qml/Components/SeeMore.qml:35
8182msgid "See more"
82−msgstr ""
83+msgstr "Vis mer"
8384
8485#: qml/Components/SeeMore.qml:58
8586msgid "See less"
86−msgstr ""
87+msgstr "Vis mindre"
8788
88−#: qml/Dash/DashApps.qml:38
89+#: qml/Dash/DashApps.qml:37
8990msgid "Recent"
90−msgstr ""
91+msgstr "Nylig"
9192
9293#: qml/Dash/PreviewListView.qml:52
9394#, qt-format
9495msgid "%1 Preview"
95−msgstr ""
96+msgstr "%1-forhåndsvisning"
9697
9798#: qml/Dash/Previews/PreviewActionCombo.qml:34
9899msgid "More..."
99−msgstr ""
100+msgstr "Mer …"
100101
101102#: qml/Dash/Previews/PreviewActionCombo.qml:34
102103msgid "Less..."
103−msgstr ""
104+msgstr "Mindre …"
104105
105106#: qml/Dash/Previews/PreviewRatingInput.qml:81
106107msgid "Rate this"
107−msgstr ""
108+msgstr "Vurder dette"
108109
109110#: qml/Dash/Previews/PreviewRatingInput.qml:126
110111msgid "Add a review"
111−msgstr ""
112+msgstr "Skriv en anmeldelse"
112113
113114#: qml/Dash/Previews/PreviewRatingInput.qml:166
114115msgid "Send"
115−msgstr ""
116+msgstr "Send"
117+
118+#: qml/Greeter/Greeter.qml:151
119+msgid "Swipe to unlock"
120+msgstr "Sveip for å låse opp"
116121
117122#: qml/Greeter/Lockscreen.qml:149
118123msgid "Emergency Call"
119−msgstr ""
124+msgstr "Nødanrop"
120125
121126#: qml/Greeter/PassphraseLockscreen.qml:59
122127#, qt-format
123128msgid "Hello %1"
124−msgstr ""
129+msgstr "Hei, %1"
125130
126131#: qml/Greeter/PassphraseLockscreen.qml:59
127132msgid "Hello"
128−msgstr ""
133+msgstr "Hei"
129134
130135#: qml/Hud/HudParametrizedActionsPage.qml:132
131136msgid "Confirm"
@@ -149,17 +154,17 @@ msgstr "Snakker …"
149154
150155#: qml/Notifications/NotificationMenuItemFactory.qml:91
151156msgid "Show password"
152−msgstr ""
157+msgstr "Vis passord"
153158
154159#: qml/Notifications/NotificationMenuItemFactory.qml:103
155160msgid "Please enter SIM PIN"
156−msgstr ""
161+msgstr "Skriv inn PIN-koden til SIM-kortet"
157162
158163#: qml/Panel/SearchIndicator.qml:27
159164msgid "Search"
160165msgstr "Søk"
161166
162−#: qml/Shell.qml:417
167+#: qml/Shell.qml:348
163168#, qt-format
164169msgid "Please enter %1"
165−msgstr ""
170+msgstr "Skriv inn %1"
po/nl.po+9−22
@@ -7,16 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
1111"PO-Revision-Date: 2014-01-15 16:42+0000\n"
1212"Last-Translator: Hannie Dumoleyn <Unknown>\n"
1313"Language-Team: Dutch <nl@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2014-03-28 06:48+0000\n"
19−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-01 06:43+0000\n"
18+"X-Generator: Launchpad (build 16985)\n"
2019
2120#: plugins/Unity/Launcher/launcheritem.cpp:43
2221#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -85,7 +84,7 @@ msgstr ""
8584msgid "See less"
8685msgstr ""
8786
88−#: qml/Dash/DashApps.qml:38
87+#: qml/Dash/DashApps.qml:37
8988msgid "Recent"
9089msgstr ""
9190
@@ -114,6 +113,10 @@ msgstr "Voeg recensie toe"
114113msgid "Send"
115114msgstr "Versturen"
116115
116+#: qml/Greeter/Greeter.qml:151
117+msgid "Swipe to unlock"
118+msgstr ""
119+
117120#: qml/Greeter/Lockscreen.qml:149
118121msgid "Emergency Call"
119122msgstr "Noodoproep"
@@ -159,23 +162,7 @@ msgstr ""
159162msgid "Search"
160163msgstr "Zoeken"
161164
162−#: qml/Shell.qml:417
165+#: qml/Shell.qml:348
163166#, qt-format
164167msgid "Please enter %1"
165168msgstr "Voer %1 in"
166−
167−#, qt-format
168−#~ msgid "%1 review"
169−#~ msgid_plural "%1 reviews"
170−#~ msgstr[0] "%1 recensie"
171−#~ msgstr[1] "%1 recensies"
172−
173−#, qt-format
174−#~ msgid "(%1)"
175−#~ msgstr "(%1)"
176−
177−#~ msgid "Comments:"
178−#~ msgstr "Reacties:"
179−
180−#~ msgid "Review"
181−#~ msgstr "Recensie"
po/pl.po+9−24
@@ -7,17 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
1111"PO-Revision-Date: 2014-01-10 11:38+0000\n"
1212"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
1313"Language-Team: Polish <pl@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
18−"|| n%100>=20) ? 1 : 2;\n"
19−"X-Launchpad-Export-Date: 2014-03-28 06:49+0000\n"
20−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-01 06:44+0000\n"
18+"X-Generator: Launchpad (build 16985)\n"
2119
2220#: plugins/Unity/Launcher/launcheritem.cpp:43
2321#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -88,7 +86,7 @@ msgstr ""
8886msgid "See less"
8987msgstr ""
9088
91−#: qml/Dash/DashApps.qml:38
89+#: qml/Dash/DashApps.qml:37
9290msgid "Recent"
9391msgstr ""
9492
@@ -117,6 +115,10 @@ msgstr "Dodaj recenzję"
117115msgid "Send"
118116msgstr "Wyślij"
119117
118+#: qml/Greeter/Greeter.qml:151
119+msgid "Swipe to unlock"
120+msgstr ""
121+
120122#: qml/Greeter/Lockscreen.qml:149
121123msgid "Emergency Call"
122124msgstr "Telefon ratunkowy"
@@ -162,24 +164,7 @@ msgstr ""
162164msgid "Search"
163165msgstr "Szukaj"
164166
165−#: qml/Shell.qml:417
167+#: qml/Shell.qml:348
166168#, qt-format
167169msgid "Please enter %1"
168170msgstr "Wprowadź %1"
169−
170−#~ msgid "Comments:"
171−#~ msgstr "Komentarze:"
172−
173−#~ msgid "Review"
174−#~ msgstr "Recenzja"
175−
176−#, qt-format
177−#~ msgid "%1 review"
178−#~ msgid_plural "%1 reviews"
179−#~ msgstr[0] "%1 opinia"
180−#~ msgstr[1] "%1 opinie"
181−#~ msgstr[2] "%1 opinii"
182−
183−#, qt-format
184−#~ msgid "(%1)"
185−#~ msgstr "(%1)"
po/pt.po+9−6
@@ -7,16 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
1111"PO-Revision-Date: 2014-01-14 19:18+0000\n"
1212"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1313"Language-Team: Portuguese <pt@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2014-03-28 06:49+0000\n"
19−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-01 06:44+0000\n"
18+"X-Generator: Launchpad (build 16985)\n"
2019
2120#: plugins/Unity/Launcher/launcheritem.cpp:43
2221#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -85,7 +84,7 @@ msgstr ""
8584msgid "See less"
8685msgstr ""
8786
88−#: qml/Dash/DashApps.qml:38
87+#: qml/Dash/DashApps.qml:37
8988msgid "Recent"
9089msgstr ""
9190
@@ -114,6 +113,10 @@ msgstr ""
114113msgid "Send"
115114msgstr ""
116115
116+#: qml/Greeter/Greeter.qml:151
117+msgid "Swipe to unlock"
118+msgstr ""
119+
117120#: qml/Greeter/Lockscreen.qml:149
118121msgid "Emergency Call"
119122msgstr ""
@@ -159,7 +162,7 @@ msgstr ""
159162msgid "Search"
160163msgstr ""
161164
162−#: qml/Shell.qml:417
165+#: qml/Shell.qml:348
163166#, qt-format
164167msgid "Please enter %1"
165168msgstr ""
po/pt_BR.po+20−31
@@ -7,16 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
11−"PO-Revision-Date: 2014-01-18 23:24+0000\n"
12−"Last-Translator: Fábio Nogueira <deb-user-ba@ubuntu.com>\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
11+"PO-Revision-Date: 2014-05-15 14:31+0000\n"
12+"Last-Translator: Rafael Neri <Unknown>\n"
1313"Language-Team: Brazilian Portuguese <pt_BR@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=2; plural=n > 1;\n"
18−"X-Launchpad-Export-Date: 2014-03-28 06:49+0000\n"
19−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-16 06:52+0000\n"
18+"X-Generator: Launchpad (build 17007)\n"
2019
2120#: plugins/Unity/Launcher/launcheritem.cpp:43
2221#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -74,6 +73,8 @@ msgid ""
7473"You have now mastered the edge gestures and can start using the "
7574"phone<br><br>Tap on the screen to start"
7675msgstr ""
76+"Agora você já domina os gestos das bordas e pode começar a usar o "
77+"telefone<br><br>Toque na tela para iniciar"
7778
7879#: qml/Components/PageHeader.qml:365
7980msgid "Recent searches"
@@ -81,28 +82,28 @@ msgstr "Pesquisas recentes"
8182
8283#: qml/Components/SeeMore.qml:35
8384msgid "See more"
84−msgstr ""
85+msgstr "Ver mais"
8586
8687#: qml/Components/SeeMore.qml:58
8788msgid "See less"
88−msgstr ""
89+msgstr "Ver menos"
8990
90−#: qml/Dash/DashApps.qml:38
91+#: qml/Dash/DashApps.qml:37
9192msgid "Recent"
92−msgstr ""
93+msgstr "Recentes"
9394
9495#: qml/Dash/PreviewListView.qml:52
9596#, qt-format
9697msgid "%1 Preview"
97−msgstr ""
98+msgstr "%1 visualização"
9899
99100#: qml/Dash/Previews/PreviewActionCombo.qml:34
100101msgid "More..."
101−msgstr ""
102+msgstr "Mais..."
102103
103104#: qml/Dash/Previews/PreviewActionCombo.qml:34
104105msgid "Less..."
105−msgstr ""
106+msgstr "Menos..."
106107
107108#: qml/Dash/Previews/PreviewRatingInput.qml:81
108109msgid "Rate this"
@@ -116,6 +117,10 @@ msgstr "Adicionar uma análise"
116117msgid "Send"
117118msgstr "Enviar"
118119
120+#: qml/Greeter/Greeter.qml:151
121+msgid "Swipe to unlock"
122+msgstr "Deslizar para desbloquear"
123+
119124#: qml/Greeter/Lockscreen.qml:149
120125msgid "Emergency Call"
121126msgstr "Chamada de emergência"
@@ -155,29 +160,13 @@ msgstr "Exibir senha"
155160
156161#: qml/Notifications/NotificationMenuItemFactory.qml:103
157162msgid "Please enter SIM PIN"
158−msgstr ""
163+msgstr "Por favor, digite o PIN do cartão SIM"
159164
160165#: qml/Panel/SearchIndicator.qml:27
161166msgid "Search"
162167msgstr "Pesquisar"
163168
164−#: qml/Shell.qml:417
169+#: qml/Shell.qml:348
165170#, qt-format
166171msgid "Please enter %1"
167172msgstr "Por favor, digite %1"
168−
169−#, qt-format
170−#~ msgid "(%1)"
171−#~ msgstr "(%1)"
172−
173−#, qt-format
174−#~ msgid "%1 review"
175−#~ msgid_plural "%1 reviews"
176−#~ msgstr[0] "%1 análise"
177−#~ msgstr[1] "%1 análises"
178−
179−#~ msgid "Comments:"
180−#~ msgstr "Comentários:"
181−
182−#~ msgid "Review"
183−#~ msgstr "Revisão"
po/ro.po+9−7
@@ -7,17 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
1111"PO-Revision-Date: 2013-06-27 07:53+0000\n"
1212"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
1313"Language-Team: Romanian <ro@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=3; plural=(n == 1 ? 0: (((n % 100 > 19) || ((n % 100 "
18−"== 0) && (n != 0))) ? 2: 1));\n"
19−"X-Launchpad-Export-Date: 2014-03-28 06:49+0000\n"
20−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-01 06:44+0000\n"
18+"X-Generator: Launchpad (build 16985)\n"
2119
2220#: plugins/Unity/Launcher/launcheritem.cpp:43
2321#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -86,7 +84,7 @@ msgstr ""
8684msgid "See less"
8785msgstr ""
8886
89−#: qml/Dash/DashApps.qml:38
87+#: qml/Dash/DashApps.qml:37
9088msgid "Recent"
9189msgstr ""
9290
@@ -115,6 +113,10 @@ msgstr ""
115113msgid "Send"
116114msgstr ""
117115
116+#: qml/Greeter/Greeter.qml:151
117+msgid "Swipe to unlock"
118+msgstr ""
119+
118120#: qml/Greeter/Lockscreen.qml:149
119121msgid "Emergency Call"
120122msgstr ""
@@ -160,7 +162,7 @@ msgstr ""
160162msgid "Search"
161163msgstr "Căutare"
162164
163−#: qml/Shell.qml:417
165+#: qml/Shell.qml:348
164166#, qt-format
165167msgid "Please enter %1"
166168msgstr ""
po/ru.po+10−6
@@ -7,15 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
11−"PO-Revision-Date: 2014-04-03 13:07+0000\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
11+"PO-Revision-Date: 2014-05-15 12:57+0000\n"
1212"Last-Translator: Zonov Roman <Unknown>\n"
1313"Language-Team: Russian <ru@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2014-04-04 07:12+0000\n"
18−"X-Generator: Launchpad (build 16976)\n"
17+"X-Launchpad-Export-Date: 2014-05-16 06:52+0000\n"
18+"X-Generator: Launchpad (build 17007)\n"
1919
2020#: plugins/Unity/Launcher/launcheritem.cpp:43
2121#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -91,7 +91,7 @@ msgstr "Подробнее"
9191msgid "See less"
9292msgstr "Вкратце"
9393
94−#: qml/Dash/DashApps.qml:38
94+#: qml/Dash/DashApps.qml:37
9595msgid "Recent"
9696msgstr "Недавние"
9797
@@ -120,6 +120,10 @@ msgstr "Добавьте отзыв"
120120msgid "Send"
121121msgstr "Отправить"
122122
123+#: qml/Greeter/Greeter.qml:151
124+msgid "Swipe to unlock"
125+msgstr "Смахните, чтобы разблокировать"
126+
123127#: qml/Greeter/Lockscreen.qml:149
124128msgid "Emergency Call"
125129msgstr "Экстренный вызов"
@@ -165,7 +169,7 @@ msgstr "Введите PIN код"
165169msgid "Search"
166170msgstr "Поиск"
167171
168−#: qml/Shell.qml:417
172+#: qml/Shell.qml:348
169173#, qt-format
170174msgid "Please enter %1"
171175msgstr "Пожалуйста, введите %1"
po/shn.po+9−6
@@ -7,16 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
1111"PO-Revision-Date: 2013-10-07 11:46+0000\n"
1212"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1313"Language-Team: Shan <shn@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=2; plural=(n == 1) ? 0 : 1;\n"
18−"X-Launchpad-Export-Date: 2014-03-28 06:49+0000\n"
19−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-01 06:44+0000\n"
18+"X-Generator: Launchpad (build 16985)\n"
2019
2120#: plugins/Unity/Launcher/launcheritem.cpp:43
2221#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -85,7 +84,7 @@ msgstr ""
8584msgid "See less"
8685msgstr ""
8786
88−#: qml/Dash/DashApps.qml:38
87+#: qml/Dash/DashApps.qml:37
8988msgid "Recent"
9089msgstr ""
9190
@@ -114,6 +113,10 @@ msgstr ""
114113msgid "Send"
115114msgstr ""
116115
116+#: qml/Greeter/Greeter.qml:151
117+msgid "Swipe to unlock"
118+msgstr ""
119+
117120#: qml/Greeter/Lockscreen.qml:149
118121msgid "Emergency Call"
119122msgstr ""
@@ -159,7 +162,7 @@ msgstr ""
159162msgid "Search"
160163msgstr ""
161164
162−#: qml/Shell.qml:417
165+#: qml/Shell.qml:348
163166#, qt-format
164167msgid "Please enter %1"
165168msgstr ""
po/si.po+9−6
@@ -7,16 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
1111"PO-Revision-Date: 2013-06-26 22:36+0000\n"
1212"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1313"Language-Team: Sinhalese <si@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2014-03-28 06:49+0000\n"
19−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-01 06:44+0000\n"
18+"X-Generator: Launchpad (build 16985)\n"
2019
2120#: plugins/Unity/Launcher/launcheritem.cpp:43
2221#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -85,7 +84,7 @@ msgstr ""
8584msgid "See less"
8685msgstr ""
8786
88−#: qml/Dash/DashApps.qml:38
87+#: qml/Dash/DashApps.qml:37
8988msgid "Recent"
9089msgstr ""
9190
@@ -114,6 +113,10 @@ msgstr ""
114113msgid "Send"
115114msgstr ""
116115
116+#: qml/Greeter/Greeter.qml:151
117+msgid "Swipe to unlock"
118+msgstr ""
119+
117120#: qml/Greeter/Lockscreen.qml:149
118121msgid "Emergency Call"
119122msgstr ""
@@ -159,7 +162,7 @@ msgstr ""
159162msgid "Search"
160163msgstr ""
161164
162−#: qml/Shell.qml:417
165+#: qml/Shell.qml:348
163166#, qt-format
164167msgid "Please enter %1"
165168msgstr ""
po/sl.po+9−25
@@ -7,17 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
1111"PO-Revision-Date: 2014-02-21 16:38+0000\n"
1212"Last-Translator: Damir Jerovšek <Unknown>\n"
1313"Language-Team: Slovenian <sl@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=4; plural=(n%100==1 ? 1 : n%100==2 ? 2 : n%100==3 || "
18−"n%100==4 ? 3 : 0);\n"
19−"X-Launchpad-Export-Date: 2014-03-28 06:49+0000\n"
20−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-01 06:44+0000\n"
18+"X-Generator: Launchpad (build 16985)\n"
2119
2220#: plugins/Unity/Launcher/launcheritem.cpp:43
2321#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -90,7 +88,7 @@ msgstr "Pokaži več"
9088msgid "See less"
9189msgstr "Pokaži manj"
9290
93−#: qml/Dash/DashApps.qml:38
91+#: qml/Dash/DashApps.qml:37
9492msgid "Recent"
9593msgstr ""
9694
@@ -119,6 +117,10 @@ msgstr "Dodaj oceno"
119117msgid "Send"
120118msgstr "Pošlji"
121119
120+#: qml/Greeter/Greeter.qml:151
121+msgid "Swipe to unlock"
122+msgstr ""
123+
122124#: qml/Greeter/Lockscreen.qml:149
123125msgid "Emergency Call"
124126msgstr "Klic v sili"
@@ -164,25 +166,7 @@ msgstr "Vnesite PIN kartice SIM"
164166msgid "Search"
165167msgstr "Iskanje"
166168
167−#: qml/Shell.qml:417
169+#: qml/Shell.qml:348
168170#, qt-format
169171msgid "Please enter %1"
170172msgstr "Vnesite %1"
171−
172−#~ msgid "Review"
173−#~ msgstr "Ocena"
174−
175−#~ msgid "Comments:"
176−#~ msgstr "Opombe:"
177−
178−#, qt-format
179−#~ msgid "%1 review"
180−#~ msgid_plural "%1 reviews"
181−#~ msgstr[0] "%1 ocen"
182−#~ msgstr[1] "%1 ocena"
183−#~ msgstr[2] "%1 oceni"
184−#~ msgstr[3] "%1 ocene"
185−
186−#, qt-format
187−#~ msgid "(%1)"
188−#~ msgstr "(%1)"
po/sq.po+9−16
@@ -7,16 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
1111"PO-Revision-Date: 2014-01-15 13:51+0000\n"
1212"Last-Translator: Besmir Zanaj <besmirzanaj@gmail.com>\n"
1313"Language-Team: Albanian <sq@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2014-03-28 06:48+0000\n"
19−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-01 06:43+0000\n"
18+"X-Generator: Launchpad (build 16985)\n"
2019
2120#: plugins/Unity/Launcher/launcheritem.cpp:43
2221#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -86,7 +85,7 @@ msgstr ""
8685msgid "See less"
8786msgstr ""
8887
89−#: qml/Dash/DashApps.qml:38
88+#: qml/Dash/DashApps.qml:37
9089msgid "Recent"
9190msgstr ""
9291
@@ -115,6 +114,10 @@ msgstr "Shto një rishikim"
115114msgid "Send"
116115msgstr ""
117116
117+#: qml/Greeter/Greeter.qml:151
118+msgid "Swipe to unlock"
119+msgstr ""
120+
118121#: qml/Greeter/Lockscreen.qml:149
119122msgid "Emergency Call"
120123msgstr ""
@@ -160,17 +163,7 @@ msgstr ""
160163msgid "Search"
161164msgstr ""
162165
163−#: qml/Shell.qml:417
166+#: qml/Shell.qml:348
164167#, qt-format
165168msgid "Please enter %1"
166169msgstr ""
167−
168−#, qt-format
169−#~ msgid "%1 review"
170−#~ msgid_plural "%1 reviews"
171−#~ msgstr[0] "%1 rishikim"
172−#~ msgstr[1] "%1 rishikime"
173−
174−#, qt-format
175−#~ msgid "(%1)"
176−#~ msgstr "(%1)"
po/sr.po+9−7
@@ -7,17 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
1111"PO-Revision-Date: 2013-06-27 09:19+0000\n"
1212"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
1313"Language-Team: Serbian <sr@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
18−"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
19−"X-Launchpad-Export-Date: 2014-03-28 06:49+0000\n"
20−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-01 06:44+0000\n"
18+"X-Generator: Launchpad (build 16985)\n"
2119
2220#: plugins/Unity/Launcher/launcheritem.cpp:43
2321#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -86,7 +84,7 @@ msgstr ""
8684msgid "See less"
8785msgstr ""
8886
89−#: qml/Dash/DashApps.qml:38
87+#: qml/Dash/DashApps.qml:37
9088msgid "Recent"
9189msgstr ""
9290
@@ -115,6 +113,10 @@ msgstr ""
115113msgid "Send"
116114msgstr ""
117115
116+#: qml/Greeter/Greeter.qml:151
117+msgid "Swipe to unlock"
118+msgstr ""
119+
118120#: qml/Greeter/Lockscreen.qml:149
119121msgid "Emergency Call"
120122msgstr ""
@@ -160,7 +162,7 @@ msgstr ""
160162msgid "Search"
161163msgstr "Претрага"
162164
163−#: qml/Shell.qml:417
165+#: qml/Shell.qml:348
164166#, qt-format
165167msgid "Please enter %1"
166168msgstr ""
po/sv.po+9−6
@@ -7,16 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
1111"PO-Revision-Date: 2013-06-26 22:36+0000\n"
1212"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1313"Language-Team: Swedish <sv@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2014-03-28 06:49+0000\n"
19−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-01 06:44+0000\n"
18+"X-Generator: Launchpad (build 16985)\n"
2019
2120#: plugins/Unity/Launcher/launcheritem.cpp:43
2221#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -85,7 +84,7 @@ msgstr ""
8584msgid "See less"
8685msgstr ""
8786
88−#: qml/Dash/DashApps.qml:38
87+#: qml/Dash/DashApps.qml:37
8988msgid "Recent"
9089msgstr ""
9190
@@ -114,6 +113,10 @@ msgstr ""
114113msgid "Send"
115114msgstr ""
116115
116+#: qml/Greeter/Greeter.qml:151
117+msgid "Swipe to unlock"
118+msgstr ""
119+
117120#: qml/Greeter/Lockscreen.qml:149
118121msgid "Emergency Call"
119122msgstr ""
@@ -159,7 +162,7 @@ msgstr ""
159162msgid "Search"
160163msgstr ""
161164
162−#: qml/Shell.qml:417
165+#: qml/Shell.qml:348
163166#, qt-format
164167msgid "Please enter %1"
165168msgstr ""
po/sw.po+9−9
@@ -7,16 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
1111"PO-Revision-Date: 2014-01-14 19:28+0000\n"
1212"Last-Translator: Damas Mlabwa <Unknown>\n"
1313"Language-Team: Swahili <sw@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2014-03-28 06:49+0000\n"
19−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-01 06:44+0000\n"
18+"X-Generator: Launchpad (build 16985)\n"
2019
2120#: plugins/Unity/Launcher/launcheritem.cpp:43
2221#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -85,7 +84,7 @@ msgstr ""
8584msgid "See less"
8685msgstr ""
8786
88−#: qml/Dash/DashApps.qml:38
87+#: qml/Dash/DashApps.qml:37
8988msgid "Recent"
9089msgstr ""
9190
@@ -114,6 +113,10 @@ msgstr ""
114113msgid "Send"
115114msgstr "Tuma"
116115
116+#: qml/Greeter/Greeter.qml:151
117+msgid "Swipe to unlock"
118+msgstr ""
119+
117120#: qml/Greeter/Lockscreen.qml:149
118121msgid "Emergency Call"
119122msgstr ""
@@ -159,10 +162,7 @@ msgstr ""
159162msgid "Search"
160163msgstr "Tafuta"
161164
162−#: qml/Shell.qml:417
165+#: qml/Shell.qml:348
163166#, qt-format
164167msgid "Please enter %1"
165168msgstr ""
166−
167−#~ msgid "Comments:"
168−#~ msgstr "Maoni:"
po/ta.po+10−23
@@ -7,16 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
1111"PO-Revision-Date: 2013-10-24 11:36+0000\n"
12−"Last-Translator: Arun Kumar -அருண் குமார் <thangam.arunx@gmail.com>\n"
12+"Last-Translator: Arun Kumar - அருண் குமார் <thangam.arunx@gmail.com>\n"
1313"Language-Team: Ubuntu Tamil Team/Free Tamil Computing/Thamizha\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2014-03-28 06:49+0000\n"
19−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-01 06:44+0000\n"
18+"X-Generator: Launchpad (build 16985)\n"
2019"Language: ta\n"
2120
2221#: plugins/Unity/Launcher/launcheritem.cpp:43
@@ -88,7 +87,7 @@ msgstr ""
8887msgid "See less"
8988msgstr ""
9089
91−#: qml/Dash/DashApps.qml:38
90+#: qml/Dash/DashApps.qml:37
9291msgid "Recent"
9392msgstr ""
9493
@@ -117,6 +116,10 @@ msgstr "ஒரு பரிசீலனையை சேர்"
117116msgid "Send"
118117msgstr "அனுப்பு"
119118
119+#: qml/Greeter/Greeter.qml:151
120+msgid "Swipe to unlock"
121+msgstr ""
122+
120123#: qml/Greeter/Lockscreen.qml:149
121124msgid "Emergency Call"
122125msgstr "அவசர அழைப்பு"
@@ -162,23 +165,7 @@ msgstr ""
162165msgid "Search"
163166msgstr "தெடு"
164167
165−#: qml/Shell.qml:417
168+#: qml/Shell.qml:348
166169#, qt-format
167170msgid "Please enter %1"
168171msgstr "தயவுச்செய்து %1 உள்ளிடு"
169−
170−#, qt-format
171−#~ msgid "(%1)"
172−#~ msgstr "(%1)"
173−
174−#, qt-format
175−#~ msgid "%1 review"
176−#~ msgid_plural "%1 reviews"
177−#~ msgstr[0] "%1 பரிசீலனை"
178−#~ msgstr[1] "%1 பரிசீலனைகள்"
179−
180−#~ msgid "Review"
181−#~ msgstr "மறுஆய்வு"
182−
183−#~ msgid "Comments:"
184−#~ msgstr "கருத்துகள்:"
po/te.po+9−6
@@ -7,16 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
1111"PO-Revision-Date: 2013-06-27 09:57+0000\n"
1212"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
1313"Language-Team: Telugu <te@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2014-03-28 06:49+0000\n"
19−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-01 06:44+0000\n"
18+"X-Generator: Launchpad (build 16985)\n"
2019
2120#: plugins/Unity/Launcher/launcheritem.cpp:43
2221#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -85,7 +84,7 @@ msgstr ""
8584msgid "See less"
8685msgstr ""
8786
88−#: qml/Dash/DashApps.qml:38
87+#: qml/Dash/DashApps.qml:37
8988msgid "Recent"
9089msgstr ""
9190
@@ -114,6 +113,10 @@ msgstr ""
114113msgid "Send"
115114msgstr ""
116115
116+#: qml/Greeter/Greeter.qml:151
117+msgid "Swipe to unlock"
118+msgstr ""
119+
117120#: qml/Greeter/Lockscreen.qml:149
118121msgid "Emergency Call"
119122msgstr ""
@@ -159,7 +162,7 @@ msgstr ""
159162msgid "Search"
160163msgstr ""
161164
162−#: qml/Shell.qml:417
165+#: qml/Shell.qml:348
163166#, qt-format
164167msgid "Please enter %1"
165168msgstr ""
po/tr.po+13−26
@@ -7,16 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
11−"PO-Revision-Date: 2014-03-05 08:54+0000\n"
12−"Last-Translator: Muhammed Yüce <muhammedyuceee@gmail.com>\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
11+"PO-Revision-Date: 2014-05-19 12:52+0000\n"
12+"Last-Translator: Volkan Gezer <Unknown>\n"
1313"Language-Team: Turkish <tr@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2014-03-28 06:49+0000\n"
19−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-22 06:49+0000\n"
18+"X-Generator: Launchpad (build 17017)\n"
2019
2120#: plugins/Unity/Launcher/launcheritem.cpp:43
2221#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -88,14 +87,14 @@ msgstr "Daha fazlası"
8887msgid "See less"
8988msgstr "Daha azını gör"
9089
91−#: qml/Dash/DashApps.qml:38
90+#: qml/Dash/DashApps.qml:37
9291msgid "Recent"
93−msgstr ""
92+msgstr "En son"
9493
9594#: qml/Dash/PreviewListView.qml:52
9695#, qt-format
9796msgid "%1 Preview"
98−msgstr ""
97+msgstr "%1 Önizlemesi"
9998
10099#: qml/Dash/Previews/PreviewActionCombo.qml:34
101100msgid "More..."
@@ -117,6 +116,10 @@ msgstr "Bir inceleme ekle"
117116msgid "Send"
118117msgstr "Gönder"
119118
119+#: qml/Greeter/Greeter.qml:151
120+msgid "Swipe to unlock"
121+msgstr "Açmak için kaydırın"
122+
120123#: qml/Greeter/Lockscreen.qml:149
121124msgid "Emergency Call"
122125msgstr "Acil Arama"
@@ -162,23 +165,7 @@ msgstr "Lütfen SIM PIN'inizi girin"
162165msgid "Search"
163166msgstr "Ara"
164167
165−#: qml/Shell.qml:417
168+#: qml/Shell.qml:348
166169#, qt-format
167170msgid "Please enter %1"
168171msgstr "Lütfen %1 girin"
169−
170−#~ msgid "Review"
171−#~ msgstr "İnceleme"
172−
173−#, qt-format
174−#~ msgid "%1 review"
175−#~ msgid_plural "%1 reviews"
176−#~ msgstr[0] "%1 inceleme"
177−#~ msgstr[1] "%1 inceleme"
178−
179−#, qt-format
180−#~ msgid "(%1)"
181−#~ msgstr "(%1)"
182−
183−#~ msgid "Comments:"
184−#~ msgstr "Yorumlar:"
po/ug.po+12−8
@@ -7,15 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
11−"PO-Revision-Date: 2014-04-14 09:31+0000\n"
12−"Last-Translator: volkhan <Unknown>\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
11+"PO-Revision-Date: 2014-04-22 05:46+0000\n"
12+"Last-Translator: abdurahman <Unknown>\n"
1313"Language-Team: Uyghur <ug@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2014-04-15 07:57+0000\n"
18−"X-Generator: Launchpad (build 16976)\n"
17+"X-Launchpad-Export-Date: 2014-05-01 06:44+0000\n"
18+"X-Generator: Launchpad (build 16985)\n"
1919
2020#: plugins/Unity/Launcher/launcheritem.cpp:43
2121#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -86,14 +86,14 @@ msgstr "جىقراق كۆرۈش"
8686msgid "See less"
8787msgstr "ئازراق كۆرۈش"
8888
89−#: qml/Dash/DashApps.qml:38
89+#: qml/Dash/DashApps.qml:37
9090msgid "Recent"
9191msgstr "يېقىنقى"
9292
9393#: qml/Dash/PreviewListView.qml:52
9494#, qt-format
9595msgid "%1 Preview"
96−msgstr ""
96+msgstr "%1 ئالدىن كۆرۈپ بىقىش"
9797
9898#: qml/Dash/Previews/PreviewActionCombo.qml:34
9999msgid "More..."
@@ -115,6 +115,10 @@ msgstr "باھا قوشۇش"
115115msgid "Send"
116116msgstr "ئەۋەت"
117117
118+#: qml/Greeter/Greeter.qml:151
119+msgid "Swipe to unlock"
120+msgstr ""
121+
118122#: qml/Greeter/Lockscreen.qml:149
119123msgid "Emergency Call"
120124msgstr "جىددىي تېلېفون"
@@ -160,7 +164,7 @@ msgstr "پارولىنى كىرگۈزۈڭPINكارتىڭىزنىڭ SIM"
160164msgid "Search"
161165msgstr "ئىزدە"
162166
163−#: qml/Shell.qml:417
167+#: qml/Shell.qml:348
164168#, qt-format
165169msgid "Please enter %1"
166170msgstr "%1 نى كىرگۈزۈڭ"
po/uk.po+20−33
@@ -7,17 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
11−"PO-Revision-Date: 2013-11-23 12:37+0000\n"
12−"Last-Translator: Ignat Kizenko <Unknown>\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
11+"PO-Revision-Date: 2014-05-15 12:00+0000\n"
12+"Last-Translator: Yuri Chornoivan <yurchor@gmail.com>\n"
1313"Language-Team: Ukrainian <uk@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
18−"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
19−"X-Launchpad-Export-Date: 2014-03-28 06:49+0000\n"
20−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-16 06:52+0000\n"
18+"X-Generator: Launchpad (build 17007)\n"
2119
2220#: plugins/Unity/Launcher/launcheritem.cpp:43
2321#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -76,6 +74,8 @@ msgid ""
7674"You have now mastered the edge gestures and can start using the "
7775"phone<br><br>Tap on the screen to start"
7876msgstr ""
77+"Вами налаштовано дії у відповідь на дотики на краях екрана. Тепер телефоном "
78+"можна користуватися.<br><br>Торкніться екрана, щоб розпочати."
7979
8080#: qml/Components/PageHeader.qml:365
8181msgid "Recent searches"
@@ -83,28 +83,28 @@ msgstr "Нещодавні пошуки"
8383
8484#: qml/Components/SeeMore.qml:35
8585msgid "See more"
86−msgstr ""
86+msgstr "Докладніше"
8787
8888#: qml/Components/SeeMore.qml:58
8989msgid "See less"
90−msgstr ""
90+msgstr "Стисліше"
9191
92−#: qml/Dash/DashApps.qml:38
92+#: qml/Dash/DashApps.qml:37
9393msgid "Recent"
94−msgstr ""
94+msgstr "Нещодавні"
9595
9696#: qml/Dash/PreviewListView.qml:52
9797#, qt-format
9898msgid "%1 Preview"
99−msgstr ""
99+msgstr "Перегляд %1"
100100
101101#: qml/Dash/Previews/PreviewActionCombo.qml:34
102102msgid "More..."
103−msgstr ""
103+msgstr "Більше…"
104104
105105#: qml/Dash/Previews/PreviewActionCombo.qml:34
106106msgid "Less..."
107−msgstr ""
107+msgstr "Менше..."
108108
109109#: qml/Dash/Previews/PreviewRatingInput.qml:81
110110msgid "Rate this"
@@ -118,6 +118,10 @@ msgstr "Додати рецензію"
118118msgid "Send"
119119msgstr "Надіслати"
120120
121+#: qml/Greeter/Greeter.qml:151
122+msgid "Swipe to unlock"
123+msgstr "Проведіть пальцем, щоб розблокувати"
124+
121125#: qml/Greeter/Lockscreen.qml:149
122126msgid "Emergency Call"
123127msgstr "Терміновий виклик"
@@ -157,30 +161,13 @@ msgstr "Показати пароль"
157161
158162#: qml/Notifications/NotificationMenuItemFactory.qml:103
159163msgid "Please enter SIM PIN"
160−msgstr ""
164+msgstr "Введіть PIN-код SIM-картки"
161165
162166#: qml/Panel/SearchIndicator.qml:27
163167msgid "Search"
164168msgstr "Пошук"
165169
166−#: qml/Shell.qml:417
170+#: qml/Shell.qml:348
167171#, qt-format
168172msgid "Please enter %1"
169173msgstr "Будь ласка, введіть %1"
170−
171−#~ msgid "Comments:"
172−#~ msgstr "Коментарі:"
173−
174−#~ msgid "Review"
175−#~ msgstr "Рецензія"
176−
177−#, qt-format
178−#~ msgid "%1 review"
179−#~ msgid_plural "%1 reviews"
180−#~ msgstr[0] "%1 рецензія"
181−#~ msgstr[1] "%1 рецензії"
182−#~ msgstr[2] "%1 рецензій"
183−
184−#, qt-format
185−#~ msgid "(%1)"
186−#~ msgstr "(%1)"
po/unity8.pot+7−3
@@ -8,7 +8,7 @@ msgid ""
88msgstr ""
99"Project-Id-Version: unity8\n"
1010"Report-Msgid-Bugs-To: \n"
11−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
11+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
1212"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
1313"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1414"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -84,7 +84,7 @@ msgstr ""
8484msgid "See less"
8585msgstr ""
8686
87−#: qml/Dash/DashApps.qml:38
87+#: qml/Dash/DashApps.qml:37
8888msgid "Recent"
8989msgstr ""
9090
@@ -113,6 +113,10 @@ msgstr ""
113113msgid "Send"
114114msgstr ""
115115
116+#: qml/Greeter/Greeter.qml:151
117+msgid "Swipe to unlock"
118+msgstr ""
119+
116120#: qml/Greeter/Lockscreen.qml:149
117121msgid "Emergency Call"
118122msgstr ""
@@ -158,7 +162,7 @@ msgstr ""
158162msgid "Search"
159163msgstr ""
160164
161−#: qml/Shell.qml:417
165+#: qml/Shell.qml:348
162166#, qt-format
163167msgid "Please enter %1"
164168msgstr ""
po/vi.po+9−6
@@ -7,16 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
1111"PO-Revision-Date: 2014-01-15 01:19+0000\n"
1212"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1313"Language-Team: Vietnamese <vi@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2014-03-28 06:49+0000\n"
19−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-01 06:44+0000\n"
18+"X-Generator: Launchpad (build 16985)\n"
2019
2120#: plugins/Unity/Launcher/launcheritem.cpp:43
2221#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -85,7 +84,7 @@ msgstr ""
8584msgid "See less"
8685msgstr ""
8786
88−#: qml/Dash/DashApps.qml:38
87+#: qml/Dash/DashApps.qml:37
8988msgid "Recent"
9089msgstr ""
9190
@@ -114,6 +113,10 @@ msgstr ""
114113msgid "Send"
115114msgstr ""
116115
116+#: qml/Greeter/Greeter.qml:151
117+msgid "Swipe to unlock"
118+msgstr ""
119+
117120#: qml/Greeter/Lockscreen.qml:149
118121msgid "Emergency Call"
119122msgstr ""
@@ -159,7 +162,7 @@ msgstr ""
159162msgid "Search"
160163msgstr ""
161164
162−#: qml/Shell.qml:417
165+#: qml/Shell.qml:348
163166#, qt-format
164167msgid "Please enter %1"
165168msgstr ""
po/xh.po+9−6
@@ -7,16 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
1111"PO-Revision-Date: 2013-09-28 13:20+0000\n"
1212"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1313"Language-Team: Xhosa <xh@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2014-03-28 06:49+0000\n"
19−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-01 06:44+0000\n"
18+"X-Generator: Launchpad (build 16985)\n"
2019
2120#: plugins/Unity/Launcher/launcheritem.cpp:43
2221#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -85,7 +84,7 @@ msgstr ""
8584msgid "See less"
8685msgstr ""
8786
88−#: qml/Dash/DashApps.qml:38
87+#: qml/Dash/DashApps.qml:37
8988msgid "Recent"
9089msgstr ""
9190
@@ -114,6 +113,10 @@ msgstr ""
114113msgid "Send"
115114msgstr ""
116115
116+#: qml/Greeter/Greeter.qml:151
117+msgid "Swipe to unlock"
118+msgstr ""
119+
117120#: qml/Greeter/Lockscreen.qml:149
118121msgid "Emergency Call"
119122msgstr ""
@@ -159,7 +162,7 @@ msgstr ""
159162msgid "Search"
160163msgstr ""
161164
162−#: qml/Shell.qml:417
165+#: qml/Shell.qml:348
163166#, qt-format
164167msgid "Please enter %1"
165168msgstr ""
po/zh_CN.po+37−34
@@ -7,71 +7,70 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
11−"PO-Revision-Date: 2013-10-09 13:51+0000\n"
12−"Last-Translator: Aron Xu <Unknown>\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
11+"PO-Revision-Date: 2014-05-19 02:24+0000\n"
12+"Last-Translator: Shuduo Sang <Unknown>\n"
1313"Language-Team: Chinese (Simplified) <zh_CN@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2014-03-28 06:49+0000\n"
19−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-22 06:49+0000\n"
18+"X-Generator: Launchpad (build 17017)\n"
2019
2120#: plugins/Unity/Launcher/launcheritem.cpp:43
2221#: plugins/Unity/Launcher/launcheritem.cpp:73
2322msgid "Lock to Launcher"
24−msgstr ""
23+msgstr "固定到启动器"
2524
2625#: plugins/Unity/Launcher/launcheritem.cpp:73
2726msgid "Unlock from Launcher"
28−msgstr ""
27+msgstr "从启动器移除"
2928
3029#: qml/Components/EdgeDemoOverlay.qml:151
3130msgid "Skip intro"
32−msgstr ""
31+msgstr "跳过简介"
3332
3433#: qml/Components/EdgeDemo.qml:113
3534msgid "Right edge"
36−msgstr ""
35+msgstr "右边缘"
3736
3837#: qml/Components/EdgeDemo.qml:114
3938msgid "Try swiping from the right edge to unlock the phone"
40−msgstr ""
39+msgstr "从右边滑动可以解锁"
4140
4241#: qml/Components/EdgeDemo.qml:145
4342msgid "Top edge"
44−msgstr ""
43+msgstr "上边缘"
4544
4645#: qml/Components/EdgeDemo.qml:146
4746msgid "Try swiping from the top edge to access the indicators"
48−msgstr ""
47+msgstr "从上边缘划入可以访问指示器"
4948
5049#: qml/Components/EdgeDemo.qml:171
5150msgid "Close"
52−msgstr ""
51+msgstr "关闭"
5352
5453#: qml/Components/EdgeDemo.qml:172
5554msgid "Swipe up again to close the settings screen"
56−msgstr ""
55+msgstr "再次向上划动可以关闭设置界面"
5756
5857#: qml/Components/EdgeDemo.qml:199
5958msgid "Left edge"
60−msgstr ""
59+msgstr "左边缘"
6160
6261#: qml/Components/EdgeDemo.qml:200
6362msgid "Swipe from the left to reveal the launcher for quick access to apps"
64−msgstr ""
63+msgstr "从左边划入展开启动器可以快速打开应用"
6564
6665#: qml/Components/EdgeDemo.qml:227
6766msgid "Well done"
68−msgstr ""
67+msgstr "做得好"
6968
7069#: qml/Components/EdgeDemo.qml:228
7170msgid ""
7271"You have now mastered the edge gestures and can start using the "
7372"phone<br><br>Tap on the screen to start"
74−msgstr ""
73+msgstr "您现在已经掌握了边缘滑动手势,可以开始使用手机了<br><br>请点击屏幕开始使用"
7574
7675#: qml/Components/PageHeader.qml:365
7776msgid "Recent searches"
@@ -79,44 +78,48 @@ msgstr "近期搜索"
7978
8079#: qml/Components/SeeMore.qml:35
8180msgid "See more"
82−msgstr ""
81+msgstr "了解更多"
8382
8483#: qml/Components/SeeMore.qml:58
8584msgid "See less"
86−msgstr ""
85+msgstr "显示更少"
8786
88−#: qml/Dash/DashApps.qml:38
87+#: qml/Dash/DashApps.qml:37
8988msgid "Recent"
90−msgstr ""
89+msgstr "最近使用过的"
9190
9291#: qml/Dash/PreviewListView.qml:52
9392#, qt-format
9493msgid "%1 Preview"
95−msgstr ""
94+msgstr "%1 预览"
9695
9796#: qml/Dash/Previews/PreviewActionCombo.qml:34
9897msgid "More..."
99−msgstr ""
98+msgstr "更多..."
10099
101100#: qml/Dash/Previews/PreviewActionCombo.qml:34
102101msgid "Less..."
103−msgstr ""
102+msgstr "更少..."
104103
105104#: qml/Dash/Previews/PreviewRatingInput.qml:81
106105msgid "Rate this"
107−msgstr ""
106+msgstr "评分"
108107
109108#: qml/Dash/Previews/PreviewRatingInput.qml:126
110109msgid "Add a review"
111−msgstr ""
110+msgstr "添加评论"
112111
113112#: qml/Dash/Previews/PreviewRatingInput.qml:166
114113msgid "Send"
115−msgstr ""
114+msgstr "发送"
115+
116+#: qml/Greeter/Greeter.qml:151
117+msgid "Swipe to unlock"
118+msgstr "滑动解锁"
116119
117120#: qml/Greeter/Lockscreen.qml:149
118121msgid "Emergency Call"
119−msgstr ""
122+msgstr "紧急电话"
120123
121124#: qml/Greeter/PassphraseLockscreen.qml:59
122125#, qt-format
@@ -149,17 +152,17 @@ msgstr "讲话中..."
149152
150153#: qml/Notifications/NotificationMenuItemFactory.qml:91
151154msgid "Show password"
152−msgstr ""
155+msgstr "显示密码"
153156
154157#: qml/Notifications/NotificationMenuItemFactory.qml:103
155158msgid "Please enter SIM PIN"
156−msgstr ""
159+msgstr "请输入 SIM PIN"
157160
158161#: qml/Panel/SearchIndicator.qml:27
159162msgid "Search"
160163msgstr "搜索"
161164
162−#: qml/Shell.qml:417
165+#: qml/Shell.qml:348
163166#, qt-format
164167msgid "Please enter %1"
165−msgstr ""
168+msgstr "请输入 %1"
po/zh_HK.po+9−21
@@ -7,16 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
1111"PO-Revision-Date: 2014-01-25 13:32+0000\n"
1212"Last-Translator: Daniel Cheung <daniel.2345@hotmail.com>\n"
1313"Language-Team: Chinese (Hong Kong) <zh_HK@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2014-03-28 06:49+0000\n"
19−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-01 06:44+0000\n"
18+"X-Generator: Launchpad (build 16985)\n"
2019
2120#: plugins/Unity/Launcher/launcheritem.cpp:43
2221#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -85,7 +84,7 @@ msgstr ""
8584msgid "See less"
8685msgstr ""
8786
88−#: qml/Dash/DashApps.qml:38
87+#: qml/Dash/DashApps.qml:37
8988msgid "Recent"
9089msgstr ""
9190
@@ -114,6 +113,10 @@ msgstr "新增評論"
114113msgid "Send"
115114msgstr "傳送"
116115
116+#: qml/Greeter/Greeter.qml:151
117+msgid "Swipe to unlock"
118+msgstr ""
119+
117120#: qml/Greeter/Lockscreen.qml:149
118121msgid "Emergency Call"
119122msgstr "緊急電話"
@@ -159,22 +162,7 @@ msgstr ""
159162msgid "Search"
160163msgstr "搜尋"
161164
162−#: qml/Shell.qml:417
165+#: qml/Shell.qml:348
163166#, qt-format
164167msgid "Please enter %1"
165168msgstr "請輸入 %1"
166−
167−#~ msgid "Comments:"
168−#~ msgstr "評論:"
169−
170−#~ msgid "Review"
171−#~ msgstr "評論"
172−
173−#, qt-format
174−#~ msgid "%1 review"
175−#~ msgid_plural "%1 reviews"
176−#~ msgstr[0] "%1 評論"
177−
178−#, qt-format
179−#~ msgid "(%1)"
180−#~ msgstr "(%1)"
po/zh_TW.po+9−21
@@ -7,16 +7,15 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
10+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
1111"PO-Revision-Date: 2014-01-16 06:04+0000\n"
1212"Last-Translator: Henry Yang <henry9846@hotmail.com>\n"
1313"Language-Team: Chinese (Traditional) <zh_TW@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2014-03-28 06:49+0000\n"
19−"X-Generator: Launchpad (build 16967)\n"
17+"X-Launchpad-Export-Date: 2014-05-01 06:44+0000\n"
18+"X-Generator: Launchpad (build 16985)\n"
2019
2120#: plugins/Unity/Launcher/launcheritem.cpp:43
2221#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -85,7 +84,7 @@ msgstr ""
8584msgid "See less"
8685msgstr ""
8786
88−#: qml/Dash/DashApps.qml:38
87+#: qml/Dash/DashApps.qml:37
8988msgid "Recent"
9089msgstr ""
9190
@@ -114,6 +113,10 @@ msgstr "新增回覆"
114113msgid "Send"
115114msgstr "發送"
116115
116+#: qml/Greeter/Greeter.qml:151
117+msgid "Swipe to unlock"
118+msgstr ""
119+
117120#: qml/Greeter/Lockscreen.qml:149
118121msgid "Emergency Call"
119122msgstr "緊急連絡"
@@ -159,22 +162,7 @@ msgstr ""
159162msgid "Search"
160163msgstr "搜尋"
161164
162−#: qml/Shell.qml:417
165+#: qml/Shell.qml:348
163166#, qt-format
164167msgid "Please enter %1"
165168msgstr ""
166−
167−#~ msgid "Comments:"
168−#~ msgstr "備註:"
169−
170−#~ msgid "Review"
171−#~ msgstr "回覆"
172−
173−#, qt-format
174−#~ msgid "%1 review"
175−#~ msgid_plural "%1 reviews"
176−#~ msgstr[0] "%1 回覆"
177−
178−#, qt-format
179−#~ msgid "(%1)"
180−#~ msgstr "(%1)"
qml/Bottombar/Bottombar.qmldeleted−227
@@ -1,227 +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−
17−import QtQuick 2.0
18−import "../Components"
19−import Utils 0.1
20−import Unity.Application 0.1
21−import Ubuntu.Gestures 0.1
22−import Ubuntu.Components 0.1
23−
24−Item {
25− id: bottombar
26−
27− // Whether there's an application on foreground (as opposed to have shell's Dash on foreground)
28− property bool applicationIsOnForeground
29−
30− property variant theHud
31− property bool enabled: false
32− property bool preventHiding: dragArea.dragging
33− readonly property real bottomEdgeButtonCenterDistance: units.gu(34)
34−
35− state: "hidden"
36−
37− function hide() {
38− dismissTimer.stop()
39− bottombar.state = "hidden"
40− }
41−
42− onApplicationIsOnForegroundChanged: {
43− if (!applicationIsOnForeground) {
44− hide()
45− }
46− }
47−
48− onStateChanged: {
49− if (state == "hidden") {
50− dismissTimer.stop()
51− bottomBarVisibilityCommunicatorShell.forceHidden = false
52− } else {
53− dismissTimer.restart()
54− }
55− }
56−
57− onPreventHidingChanged: {
58− if (!preventHiding) {
59− if (state == "hint" || state == "reveal")
60− hide()
61− }
62−
63− if (dismissTimer.running) {
64− dismissTimer.restart();
65− }
66− }
67−
68− Timer {
69− id: dismissTimer
70− interval: 1000
71− onTriggered: {
72− if (!bottombar.preventHiding) {
73− bottombar.state = "hidden"
74− } else {
75− dismissTimer.restart()
76− }
77− }
78− }
79−
80− HudButton {
81− id: hudButton
82−
83− readonly property bool centeredHud: parent.width < units.gu(68) // Nexus 7 has 67 gu width
84−
85− x: centeredHud ? parent.width / 2 - width / 2 : MathUtils.clamp(dragArea.touchStartX - (width / 2), 0, bottombar.width - width)
86− y: bottombar.height - bottomEdgeButtonCenterDistance - (height / 2) - bottomMargin
87− z: 1
88− visible: opacity != 0
89−
90− mouseOver: {
91− if (dragArea.status === DirectionalDragArea.Recognized) {
92− var touchLocal = mapFromItem(dragArea, dragArea.touchX, dragArea.touchY)
93− return touchLocal.x > 0 && touchLocal.x < width
94− && touchLocal.y > 0 && touchLocal.y < height
95− } else {
96− return false
97− }
98− }
99−
100− onClicked: theHud.show()
101−
102− Behavior on bottomMargin {
103− NumberAnimation{duration: hudButton.opacity < 0.01 ? 200 : 70; easing.type: Easing.OutQuart}
104− }
105−
106− Behavior on opacity {
107− NumberAnimation{duration: 200; easing.type: Easing.OutCubic}
108− }
109− }
110−
111− Connections {
112− target: theHud
113− onShownChanged: {
114− bottomBarVisibilityCommunicatorShell.forceHidden = theHud.shown
115− if (theHud.shown) {
116− bottombar.state = "hidden"
117− }
118− }
119− }
120−
121− EdgeDragArea {
122− id: dragArea
123− objectName: "hudDragArea"
124− width: parent.width
125− height: shell.edgeSize
126− anchors.bottom: parent.bottom
127−
128− distanceThreshold: units.gu(8)
129− enabled: !theHud.shown && bottombar.enabled && applicationIsOnForeground
130− direction: Direction.Upwards
131− maxSilenceTime: 2000
132−
133− property int previousStatus: -1
134− property real touchStartX: -1
135−
136− readonly property real distanceFromThreshold: (-distance) - distanceThreshold // distance is negative
137− readonly property real revealDistance: units.gu(2)
138− readonly property real commitDistance: units.gu(6)
139− readonly property real commitProgress: MathUtils.clamp(distanceFromThreshold / commitDistance, 0, 1)
140−
141− onStatusChanged: {
142− if (status === DirectionalDragArea.WaitingForTouch) {
143− if (previousStatus == DirectionalDragArea.Recognized) {
144− if (hudButton.mouseOver) {
145− hudButton.clicked()
146− }
147− }
148− } else if (status === DirectionalDragArea.Undecided) {
149− if (!hudButton.centeredHud) {
150− touchStartX = touchX
151− }
152− } else if (status === DirectionalDragArea.Recognized) {
153− bottombar.state = "hint"
154− }
155− previousStatus = status
156− }
157−
158− onDistanceChanged: {
159− if (status === DirectionalDragArea.Recognized) {
160− if (distanceFromThreshold > commitDistance)
161− bottombar.state = "shown"
162− else if (distanceFromThreshold > revealDistance)
163− bottombar.state = "reveal"
164− }
165− }
166− }
167−
168− Item {
169− id: dismissArea
170− anchors {
171− top: parent.top
172− left: parent.left
173− right: parent.right
174− }
175− height: parent.height - bottomBarVisibilityCommunicatorShell.position
176−
177− MouseArea {
178− anchors.fill: parent
179− enabled: bottombar.state == "shown"
180− onPressed: {
181− bottomBarVisibilityCommunicatorShell.forceHidden = true
182− bottombar.state = "hidden"
183− }
184− }
185−
186− InputFilterArea {
187− anchors.fill: parent
188− blockInput: (hudButton.opacity == 1)
189− }
190− }
191−
192− MouseArea {
193− anchors {
194− top: dismissArea.bottom
195− left: parent.left
196− right: parent.right
197− bottom: parent.bottom
198− }
199− enabled: bottombar.state == "shown" && bottomBarVisibilityCommunicatorShell.position > 0
200− onPressed: {
201− bottombar.state = "hidden"
202− }
203− }
204−
205− states: [
206− State {
207− name: "hidden"
208− PropertyChanges { target: hudButton; opacity: 0 }
209− PropertyChanges { target: hudButton; bottomMargin: units.gu(-2) }
210− },
211− State {
212− name: "hint"
213− extend: "hidden"
214− PropertyChanges { target: hudButton; opacity: 0.5 }
215− },
216− State {
217− name: "reveal"
218− extend: "hint"
219− PropertyChanges { target: hudButton; bottomMargin: units.gu(-2) + units.gu(2) * dragArea.commitProgress }
220− },
221− State {
222− name: "shown"
223− PropertyChanges { target: hudButton; opacity: 1 }
224− PropertyChanges { target: hudButton; bottomMargin: units.gu(0) }
225− }
226− ]
227−}
qml/Bottombar/HudButton.qmldeleted−64
@@ -1,64 +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−
17−import QtQuick 2.0
18−import Ubuntu.Components 0.1
19−
20−Item {
21− id: item
22−
23− property bool mouseOver
24−
25− property int bottomMargin: units.gu(2)
26−
27− signal clicked()
28−
29− readonly property real scaleOnMouseOver: 1.2
30−
31− width: hudButton.width * scaleOnMouseOver
32− height: hudButton.height * scaleOnMouseOver
33−
34− Item {
35− id: hudButton
36−
37− anchors.centerIn: parent
38− height: units.gu(12)
39− width: height
40− opacity: item.mouseOver || abstractButton.pressed ? 1 : 0.7
41− scale: item.mouseOver || abstractButton.pressed ? scaleOnMouseOver : 1
42− Behavior on opacity {NumberAnimation{duration: 200; easing.type: Easing.OutQuart}}
43− Behavior on scale {NumberAnimation{duration: 200; easing.type: Easing.OutQuart}}
44−
45− AbstractButton {
46− id: abstractButton
47− anchors.fill: parent
48− style: Image {
49− anchors.fill: parent
50− source: "graphics/hud_invoke_button_active.png"
51− }
52−
53− onClicked: item.clicked()
54− }
55−
56− Image {
57− width: units.gu(4)
58− height: width
59− source: "graphics/hud.png"
60− anchors.centerIn: parent
61− fillMode: Image.PreserveAspectFit
62− }
63− }
64−}
qml/Bottombar/graphics/hud@20.pngdeleted

Binary file not shown.

qml/Bottombar/graphics/hud_invoke_button_active@20.pngdeleted

Binary file not shown.

qml/CMakeLists.txt−1
@@ -5,7 +5,6 @@ install(FILES ${QML_JS_FILES}
55 )
66
77set(QML_DIRS
8− Bottombar
98 Components
109 Dash
1110 graphics
qml/Components/FilterGrid.qml+39−26
@@ -28,11 +28,6 @@ import "../Components"
2828Item {
2929 id: root
3030
31− /* If true, the number of elements displayed will be limited by collapsedRowCount.
32− If false, all elements will be displayed, effectively looking the same as a regular
33− ResponsiveGridView. */
34− property bool filter: true
35−
3631 /* Whether, when collapsed, a button should be displayed enabling the user to expand
3732 the grid to its full size. */
3833 readonly property bool expandable: model.count > rowsWhenCollapsed * iconTileGrid.columns
@@ -57,38 +52,56 @@ Item {
5752 property alias delegate: iconTileGrid.delegate
5853 property alias cellWidth: iconTileGrid.cellWidth
5954 property alias cellHeight: iconTileGrid.cellHeight
60− property alias delegateCreationBegin: iconTileGrid.delegateCreationBegin
61− property alias delegateCreationEnd: iconTileGrid.delegateCreationEnd
55+ property alias displayMarginBeginning: iconTileGrid.displayMarginBeginning
56+ property alias displayMarginEnd: iconTileGrid.displayMarginEnd
6257 readonly property alias originY: iconTileGrid.originY
6358 readonly property alias flicking: iconTileGrid.flicking
6459 readonly property alias moving: iconTileGrid.moving
6560 readonly property alias pressDelay: iconTileGrid.pressDelay
6661 property alias highlightIndex: iconTileGrid.highlightIndex
6762 readonly property alias currentItem: iconTileGrid.currentItem
63+ readonly property alias filtered: d.filter
64+
65+ QtObject {
66+ id: d
67+ // We do have filter and collapsed properties because we need to decouple
68+ // the real filtering with the animation since the closing animation
69+ // i.e. setFilter(false. true) we still need to not be filtering until
70+ // the animation finishes otherwise we hide the items when the animation
71+ // is still running
72+ property bool filter: true
73+ property bool collapsed: true
74+ }
6875
69− height: !filterAnimation.running ? childrenRect.height : height
76+ height: d.collapsed ? root.collapsedHeight : root.uncollapsedHeight
7077 clip: filterAnimation.running
7178
72− NumberAnimation {
73− property bool filterEndValue
74− id: filterAnimation
75− target: root
76− property: "height"
77− to: filterEndValue ? root.collapsedHeight : root.uncollapsedHeight
78− // Duration and easing here match the ListViewWithPageHeader::m_contentYAnimation
79− // otherwise since both animations can run at the same time you'll get
80− // some visual weirdness.
81− duration: 200
82− easing.type: Easing.InOutQuad
83− onStopped: {
84− root.filter = filterEndValue;
79+ Behavior on height {
80+ id: heightBehaviour
81+ enabled: false
82+ NumberAnimation {
83+ id: filterAnimation
84+ // Duration and easing here match the ListViewWithPageHeader::m_contentYAnimation
85+ // otherwise since both animations can run at the same time you'll get
86+ // some visual weirdness.
87+ duration: 200
88+ easing.type: Easing.InOutQuad
89+ onRunningChanged: {
90+ if (!running) {
91+ d.filter = d.collapsed;
92+ }
93+ heightBehaviour.enabled = false;
94+ }
8595 }
8696 }
8797
88− function startFilterAnimation(filter) {
89− filterAnimation.filterEndValue = filter
90− filterAnimation.start();
91− }
98+ function setFilter(filter, animate) {
99+ heightBehaviour.enabled = animate;
100+ d.collapsed = filter;
101+ if (!animate || !filter) {
102+ d.filter = filter;
103+ }
104+ }
92105
93106 ResponsiveGridView {
94107 id: iconTileGrid
@@ -105,7 +118,7 @@ Item {
105118
106119 model: LimitProxyModel {
107120 model: root.model
108− limit: (filter && !filterAnimation.running) ? rowsWhenCollapsed * iconTileGrid.columns : -1
121+ limit: d.filter ? rowsWhenCollapsed * iconTileGrid.columns : -1
109122 }
110123 }
111124}
qml/Components/LazyImage.qml+1
@@ -36,6 +36,7 @@ Item {
3636 property alias cache: image.cache
3737 property alias horizontalAlignment: image.horizontalAlignment
3838 property alias verticalAlignment: image.verticalAlignment
39+ property alias sourceImage: image
3940
4041 state: "default"
4142
qml/Components/PageHeader.qml+1−1
@@ -25,7 +25,7 @@ Item {
2525 property bool searchEntryEnabled: false
2626 property alias searchQuery: searchField.text
2727 property ListModel searchHistory
28− property Scope scope
28+ property var scope: null
2929 property alias childItem: itemContainer.children
3030 property alias showBackButton: backButton.visible
3131
qml/Components/ResponsiveGridView.qml+3−3
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.3
1818import Ubuntu.Components 0.1
1919
2020/*
@@ -41,8 +41,8 @@ Item {
4141 readonly property alias moving: gridView.moving
4242 readonly property alias pressDelay: gridView.pressDelay
4343 readonly property alias originY: gridView.originY
44− property alias delegateCreationBegin: gridView.delegateCreationBegin
45− property alias delegateCreationEnd: gridView.delegateCreationEnd
44+ property alias displayMarginBeginning: gridView.displayMarginBeginning
45+ property alias displayMarginEnd: gridView.displayMarginEnd
4646 property alias highlightIndex: gridView.highlightIndex
4747 readonly property alias currentItem: gridView.currentItem
4848
qml/Components/Revealer.qmldeleted−241
@@ -1,241 +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−
17−import QtQuick 2.0
18−import Ubuntu.Components 0.1
19−
20−Item {
21− id: revealer
22−
23− property Showable target
24− property var hintingAnimation: hintingAnimation
25− property string boundProperty: orientation == Qt.Vertical ? "y" : "x"
26− property int orientation: Qt.Vertical
27− property int direction: Qt.LeftToRight
28− property real openedValue: orientation == Qt.Vertical ? y : x
29− property real closedValue: orientation == Qt.Vertical ? y + (direction == Qt.LeftToRight ? -height : height) : x + (direction == Qt.LeftToRight ? -width : width)
30− property real hintDisplacement: 0
31− property real handleSize: units.gu(2)
32− property real dragVelocity: draggingArea.dragVelocity != 0 ? Math.abs(draggingArea.dragVelocity) : -1
33− property real dragVelocityThreshold: units.gu(5)
34− property bool dragging: false
35− property bool pressed: draggingArea.pressed
36− property int lateralPosition: draggingArea.lateralPosition
37− property real dragPosition
38− property bool openOnPress: true
39−
40− signal openPressed(int mouseX, int mouseY)
41− signal openReleased(int mouseX, int mouseY)
42− signal closePressed
43− signal openClicked
44− signal closeClicked
45−
46− dragPosition: {
47− var value
48− if (orientation == Qt.Vertical) {
49− value = draggingArea.dragValue + draggingArea.y
50− if (direction == Qt.RightToLeft) {
51− value += draggingArea.height - height
52− }
53− } else {
54− value = draggingArea.dragValue + draggingArea.x
55− if (direction == Qt.RightToLeft) {
56− value += draggingArea.width - width
57− }
58− }
59− if (__opened) {
60− if (direction == Qt.LeftToRight) {
61− value += handleSize
62− } else {
63− value -= handleSize
64− }
65− } else if (dragging) {
66− if (direction == Qt.LeftToRight) {
67− value += hintDisplacement
68− } else {
69− value -= hintDisplacement
70− }
71− }
72−
73− return value
74− }
75− property var draggingArea: leftDraggingArea.enabled ? leftDraggingArea : rightDraggingArea
76−
77− property real __hintValue: closedValue + (direction == Qt.LeftToRight ? hintDisplacement : -hintDisplacement)
78−
79− function dragToValue(dragPosition) {
80− return dragPosition + closedValue
81− }
82−
83− property bool __opened: target.shown
84− enabled: target.available
85−
86− // Can be replaced with a fake implementation during tests
87− // property var __getCurrentTimeMs: function () { return new Date().getTime() }
88− property var __dateTime: new function() {
89− this.getCurrentTimeMs = function() {return new Date().getTime()}
90− }
91−
92− Component.onCompleted: target[boundProperty] = __opened ? openedValue : closedValue
93− onOpenedValueChanged: if (__opened && !dragging) target[boundProperty] = openedValue
94− onClosedValueChanged: if (!__opened && !dragging) target[boundProperty] = closedValue
95−
96− function __computeValue(dragPosition) {
97− return MathUtils.clamp(dragToValue(dragPosition), __hintValue, openedValue)
98− }
99−
100− function __open() {
101− hintingAnimation.stop()
102− target.show()
103− }
104−
105− function __close() {
106− hintingAnimation.stop()
107− target.hide()
108− }
109−
110− function __hint() {
111− target.showAnimation.stop()
112− target.hideAnimation.stop()
113− hintingAnimation.restart()
114− }
115−
116− function __settle() {
117− hintingAnimation.stop()
118− if (__opened) target.show()
119− else target.hide()
120− }
121−
122− function __startDragging() {
123− hintingAnimation.stop()
124− dragging = true
125− }
126−
127− function __endDragging(dragVelocity) {
128− dragging = false
129− if (revealer.direction == Qt.RightToLeft) {
130− dragVelocity = -dragVelocity
131− }
132− if (Math.abs(dragVelocity) >= dragVelocityThreshold) {
133− if (dragVelocity > 0) __open()
134− else __close()
135− } else {
136− __settle()
137− }
138− }
139−
140− Binding {
141− id: dragBinding
142−
143− target: revealer.target
144− property: revealer.boundProperty
145− value: __computeValue(dragPosition)
146− when: dragging
147− }
148−
149− SmoothedAnimation {
150− id: hintingAnimation
151−
152− target: revealer.target
153− property: revealer.boundProperty
154− duration: 150
155− to: revealer.__hintValue
156− }
157−
158− DraggingArea {
159− id: leftDraggingArea
160−
161− property bool isOpeningArea: revealer.direction == Qt.LeftToRight
162−
163− height: orientation == Qt.Vertical ? handleSize : parent.height
164− width: orientation == Qt.Horizontal ? handleSize : parent.width
165− orientation: revealer.orientation
166− enabled: isOpeningArea ? !revealer.__opened : revealer.__opened
167−
168− __dateTime: revealer.__dateTime
169−
170− onPressed: {
171− if (isOpeningArea) {
172− if (revealer.openOnPress) {
173− revealer.openPressed(mouseX, mouseY)
174− __hint()
175− }
176− } else {
177− revealer.closePressed()
178− }
179− }
180− onReleased: {
181− if (isOpeningArea && revealer.openOnPress) {
182− revealer.openReleased(mouseX, mouseY)
183− __settle()
184− }
185− }
186− onDragStart: __startDragging()
187− onDragEnd: __endDragging(dragVelocity)
188− onClicked: {
189− if (clickValidated) {
190− if (isOpeningArea) {
191− if (revealer.openOnPress) revealer.openClicked()
192− } else {
193− revealer.closeClicked()
194− }
195− }
196− }
197− }
198−
199− DraggingArea {
200− id: rightDraggingArea
201−
202− property bool isOpeningArea: revealer.direction == Qt.RightToLeft
203−
204− x: orientation == Qt.Vertical ? 0 : parent.width - width
205− y: orientation == Qt.Vertical ? parent.height - height : 0
206− height: orientation == Qt.Vertical ? handleSize : parent.height
207− width: orientation == Qt.Horizontal ? handleSize : parent.width
208− orientation: revealer.orientation
209− enabled: isOpeningArea ? !revealer.__opened : revealer.__opened
210−
211− __dateTime: revealer.__dateTime
212−
213− onPressed: {
214− if (isOpeningArea) {
215− if (revealer.openOnPress) {
216− revealer.openPressed(mouseX, mouseY)
217− __hint()
218− }
219− } else {
220− revealer.closePressed()
221− }
222− }
223− onReleased: {
224− if (isOpeningArea && revealer.openOnPress) {
225− revealer.openReleased(mouseX, mouseY)
226− __settle()
227− }
228− }
229− onDragStart: __startDragging()
230− onDragEnd: __endDragging(dragVelocity)
231− onClicked: {
232− if (clickValidated) {
233− if (isOpeningArea) {
234− if (revealer.openOnPress) revealer.openClicked()
235− } else {
236− revealer.closeClicked()
237− }
238− }
239− }
240− }
241−}
qml/Components/ZoomableImage.qmlnew file+153
@@ -0,0 +1,153 @@
1+/*
2+ * Copyright (C) 2014 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+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+import "../Components"
20+
21+/*! \brief Zoomable for image.
22+
23+ This widget shows image contained in source,
24+ can be zoomable accordingly with zoomable.
25+ */
26+
27+Item {
28+ id: root
29+ property alias source: lazyImage.source
30+ property var zoomable: false
31+ property alias imageState: lazyImage.state
32+ property alias scaleTo: lazyImage.scaleTo
33+ property alias asynchronous: lazyImage.asynchronous
34+
35+ Flickable {
36+ id: flickable
37+ objectName: "flickable"
38+ clip: true
39+ contentHeight: imageContainer.height
40+ contentWidth: imageContainer.width
41+
42+ onHeightChanged: image.resetScale()
43+ onWidthChanged: image.resetScale()
44+ anchors.fill: parent
45+
46+ Item {
47+ id: imageContainer
48+ objectName: "imageContainer"
49+ width: Math.max(image.width * image.scale, flickable.width)
50+ height: Math.max(image.height * image.scale, flickable.height)
51+
52+ Item {
53+ id: image
54+ objectName: "image"
55+ property alias imageState: lazyImage.state
56+ property var prevScale
57+ anchors.centerIn: parent
58+
59+ signal imageReloaded
60+
61+ LazyImage {
62+ id: lazyImage
63+ objectName: "lazyImage"
64+ smooth: !flickable.movingVertically
65+ anchors.fill: parent
66+ fillMode: Image.PreserveAspectFit
67+ scaleTo: "fit"
68+
69+ onStateChanged: {
70+ if (state == "ready") {
71+ image.imageReloaded();
72+ }
73+ }
74+ }
75+
76+ onImageReloaded: {
77+ image.height = lazyImage.sourceImage.implicitHeight
78+ image.width = lazyImage.sourceImage.implicitWidth
79+ image.resetScale();
80+ }
81+
82+ function resetScale() {
83+ image.scale = Math.min(flickable.width / image.width, flickable.height / image.height);
84+ pinchArea.minScale = image.scale;
85+ prevScale = Math.min(image.scale, 1);
86+ }
87+
88+ onScaleChanged: {
89+ var currentWidth = width * scale
90+ var currentHeight = height * scale
91+ var scaleRatio = scale / prevScale
92+ if (currentWidth > flickable.width) {
93+ var xpos = flickable.width / 2 + flickable.contentX;
94+ var xoff = xpos * scaleRatio;
95+ flickable.contentX = xoff - flickable.width / 2;
96+ }
97+ if (currentHeight > flickable.height) {
98+ var ypos = flickable.height / 2 + flickable.contentY;
99+ var yoff = ypos * scaleRatio;
100+ flickable.contentY = yoff - flickable.height / 2;
101+ }
102+ prevScale = scale;
103+ }
104+ }
105+ }
106+
107+ PinchArea {
108+ id: pinchArea
109+ objectName: "pinchArea"
110+ property real minScale: 1.0
111+ anchors.fill: parent
112+ enabled: zoomable ? zoomable : false
113+
114+ pinch.target: image
115+ pinch.minimumScale: minScale
116+ pinch.maximumScale: 10
117+
118+ onPinchFinished: flickable.returnToBounds()
119+ }
120+
121+ MouseArea {
122+ id: mouseArea
123+ objectName: "mouseArea"
124+
125+ anchors.fill: parent
126+ enabled: zoomable ? zoomable : false
127+
128+ onWheel: {
129+ var startScale = image.scale;
130+ if (wheel.angleDelta.y > 0) {
131+ image.scale = startScale + 0.1;
132+ } else if (wheel.angleDelta.y < 0) {
133+ if (image.scale > 0.1 && image.scale > pinchArea.minScale) {
134+ image.scale = startScale - 0.1;
135+ }
136+ }
137+ wheel.accepted = true;
138+ }
139+
140+ onPressed: {
141+ mouse.accepted = false;
142+ }
143+
144+ onReleased: {
145+ mouse.accepted = false;
146+ }
147+
148+ onClicked: {
149+ mouse.accepted = false;
150+ }
151+ }
152+ }
153+}
qml/Dash/Card.qmldeleted−236
@@ -1,236 +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−
17−import QtQuick 2.0
18−import Ubuntu.Components 0.1
19−// For image://albumart and image://thumbnailer image providers
20−import Ubuntu.Thumbnailer 0.1
21−
22−AbstractButton {
23− id: root
24− property var template
25− property var components
26− property var cardData
27−
28− property real fontScale: 1.0
29− property int headerAlignment: Text.AlignLeft
30− readonly property int headerHeight: headerLoader.item ? headerLoader.item.height : 0
31− property int fixedHeaderHeight: -1
32− readonly property string title: cardData && cardData["title"] || ""
33−
34− property bool showHeader: true
35−
36− implicitWidth: childrenRect.width
37− implicitHeight: summary.y + summary.height + (summary.text && backgroundLoader.active ? units.gu(1) : 0)
38−
39− Loader {
40− id: backgroundLoader
41− objectName: "backgroundLoader"
42−
43− readonly property bool artAndSummary: components["art"]["field"] && components["summary"] || false
44− active: template["card-layout"] !== "horizontal" && (template["card-background"] || components["background"] || artAndSummary)
45− anchors.fill: parent
46−
47− sourceComponent: UbuntuShape {
48− objectName: "background"
49− radius: "medium"
50− color: getColor(0) || "white"
51− gradientColor: getColor(1) || color
52− anchors.fill: parent
53− image: backgroundImage.source ? backgroundImage : null
54−
55− property real luminance: 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b
56−
57− property Image backgroundImage: Image {
58− objectName: "backgroundImage"
59− source: {
60− if (cardData && typeof cardData["background"] === "string") return cardData["background"]
61− else if (template && typeof template["card-background"] === "string") return template["card-background"]
62− else return ""
63− }
64− }
65−
66− function getColor(index) {
67− if (cardData && typeof cardData["background"] === "object"
68− && (cardData["background"]["type"] === "color" || cardData["background"]["type"] === "gradient")) {
69− return cardData["background"]["elements"][index];
70− } else if (template && typeof template["card-background"] === "object"
71− && (template["card-background"]["type"] === "color" || template["card-background"]["type"] === "gradient")) {
72− return template["card-background"]["elements"][index];
73− } else return undefined;
74− }
75− }
76− }
77−
78− UbuntuShape {
79− id: artShape
80− radius: "medium"
81− objectName: "artShape"
82− anchors.horizontalCenter: template && template["card-layout"] === "horizontal" ? undefined : parent.horizontalCenter
83− anchors.left: template && template["card-layout"] === "horizontal" ? parent.left : undefined
84− visible: cardData && cardData["art"] || false
85−
86− readonly property real aspect: components !== undefined ? components["art"]["aspect-ratio"] : 1
87− readonly property bool aspectSmallerThanImageAspect: aspect < image.aspect
88−
89− Component.onCompleted: updateWidthHeightBindings();
90− onAspectSmallerThanImageAspectChanged: updateWidthHeightBindings();
91−
92− function updateWidthHeightBindings() {
93− if (aspectSmallerThanImageAspect) {
94− width = Qt.binding(function() { return !visible ? 0 : image.width });
95− height = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.height : width / image.aspect });
96− } else {
97− width = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.width : height * image.aspect });
98− height = Qt.binding(function() { return !visible ? 0 : image.height });
99− }
100− }
101−
102− image: Image {
103− objectName: "artImage"
104− source: cardData && cardData["art"] || ""
105− cache: true
106− // FIXME uncomment when having investigated / fixed the crash
107− //sourceSize.width: width > height ? width : 0
108− //sourceSize.height: height > width ? height : 0
109− fillMode: components && components["art"]["fill-mode"] === "fit" ? Image.PreserveAspectFit: Image.PreserveAspectCrop
110−
111− readonly property real aspect: implicitWidth / implicitHeight
112− readonly property bool isHorizontal: template && template["card-layout"] === "horizontal"
113−
114− Component.onCompleted: updateWidthHeightBindings();
115− onIsHorizontalChanged: updateWidthHeightBindings();
116−
117− function updateWidthHeightBindings() {
118− if (isHorizontal) {
119− width = Qt.binding(function() { return height * artShape.aspect });
120− height = Qt.binding(function() { return root.headerHeight });
121− } else {
122− width = Qt.binding(function() { return root.width });
123− height = Qt.binding(function() { return width / artShape.aspect });
124− }
125− }
126− }
127− }
128−
129− Loader {
130− id: overlayLoader
131− anchors {
132− left: artShape.left
133− right: artShape.right
134− bottom: artShape.bottom
135− }
136− active: template && template["overlay"] && artShape.visible && artShape.image.status === Image.Ready || false
137−
138− sourceComponent: ShaderEffect {
139− id: overlay
140−
141− height: headerLoader.item ? headerLoader.item.height : 0
142− opacity: headerLoader.item ? headerLoader.item.opacity * 0.6 : 0
143−
144− property var source: ShaderEffectSource {
145− id: shaderSource
146− sourceItem: artShape
147− onVisibleChanged: if (visible) scheduleUpdate()
148− live: false
149− sourceRect: Qt.rect(0, artShape.height - overlay.height, artShape.width, overlay.height)
150− }
151−
152− vertexShader: "
153− uniform highp mat4 qt_Matrix;
154− attribute highp vec4 qt_Vertex;
155− attribute highp vec2 qt_MultiTexCoord0;
156− varying highp vec2 coord;
157− void main() {
158− coord = qt_MultiTexCoord0;
159− gl_Position = qt_Matrix * qt_Vertex;
160− }"
161−
162− fragmentShader: "
163− varying highp vec2 coord;
164− uniform sampler2D source;
165− uniform lowp float qt_Opacity;
166− void main() {
167− lowp vec4 tex = texture2D(source, coord);
168− gl_FragColor = vec4(0, 0, 0, tex.a) * qt_Opacity;
169− }"
170− }
171− }
172−
173− Loader {
174− id: headerLoader
175− objectName: "cardHeaderLoader"
176−
177− anchors {
178− top: {
179− if (template) {
180− if (template["overlay"]) return overlayLoader.top;
181− if (template["card-layout"] === "horizontal") return artShape.top;
182− }
183− return artShape.bottom;
184− }
185− left: {
186− if (template) {
187− if (!template["overlay"] && template["card-layout"] === "horizontal") return artShape.right;
188− }
189− return parent.left;
190− }
191− right: parent.right
192− }
193− active: cardData && cardData["title"] || cardData && cardData["mascot"] || false
194−
195− sourceComponent: CardHeader {
196− id: header
197− objectName: "cardHeader"
198−
199− mascot: cardData && cardData["mascot"] || ""
200− title: root.title
201− subtitle: cardData && cardData["subtitle"] || ""
202−
203− titleWeight: components && components["subtitle"] ? Font.DemiBold : Font.Normal
204−
205− opacity: showHeader ? 1 : 0
206− inOverlay: root.template && root.template["overlay"] === true
207− fontColor: inOverlay ? "white" : summary.color
208− useMascotShape: !backgroundLoader.active && !inOverlay
209− headerAlignment: root.headerAlignment
210− height: root.fixedHeaderHeight != -1 ? root.fixedHeaderHeight : implicitHeight
211− fontScale: root.fontScale
212−
213− Behavior on opacity { NumberAnimation { duration: UbuntuAnimation.SnapDuration } }
214− }
215− }
216−
217− Label {
218− id: summary
219− objectName: "summaryLabel"
220− anchors {
221− top: headerLoader.active ? headerLoader.bottom : artShape.bottom
222− left: parent.left
223− right: parent.right
224− margins: backgroundLoader.active ? units.gu(1) : 0
225− topMargin: 0
226− }
227− wrapMode: Text.Wrap
228− maximumLineCount: 5
229− elide: Text.ElideRight
230− text: cardData && cardData["summary"] || ""
231− height: text ? implicitHeight : 0
232− fontSize: "small"
233− // TODO karni: Change "grey" to Ubuntu.Components.Palette color once updated.
234− color: backgroundLoader.active && backgroundLoader.item.luminance < 0.7 ? "white" : "grey"
235− }
236−}
qml/Dash/CardCarousel.qml+25−13
@@ -18,7 +18,6 @@ import QtQuick 2.0
1818import Ubuntu.Components 0.1
1919import "../Components"
2020
21−
2221DashRenderer {
2322 id: cardCarousel
2423
@@ -43,27 +42,40 @@ DashRenderer {
4342 cacheBuffer: 1404 // 18px * 13gu * 6
4443 model: cardCarousel.model
4544
46− onClicked: cardCarousel.clicked(index, itemY)
47− onPressAndHold: cardCarousel.pressAndHold(index, itemY)
45+ onClicked: cardCarousel.clicked(index, null)
46+ onPressAndHold: cardCarousel.pressAndHold(index)
4847
4948 property real fontScale: 1 / selectedItemScaleFactor
5049 property real headerHeight: cardTool.headerHeight / selectedItemScaleFactor
5150
52− itemComponent: Card {
53− id: card
54− objectName: "carouselDelegate" + index
55− fixedHeaderHeight: carousel.headerHeight
56− cardData: model
57− template: cardTool.template
58− components: cardTool.components
51+ itemComponent: Loader {
52+ id: loader
5953
6054 property bool explicitlyScaled
6155 property var model
62−
6356 enabled: false
64− showHeader: explicitlyScaled
6557
66− fontScale: carousel.fontScale
58+ sourceComponent: cardTool.cardComponent
59+ onLoaded: {
60+ item.objectName = "carouselDelegate" + index;
61+ item.fixedHeaderHeight = Qt.binding(function() { return carousel.headerHeight; });
62+ item.height = Qt.binding(function() { return cardTool.cardHeight; });
63+ item.cardData = Qt.binding(function() { return model; });
64+ item.template = Qt.binding(function() { return cardTool.template; });
65+ item.components = Qt.binding(function() { return cardTool.components; });
66+ item.fontScale = Qt.binding(function() { return carousel.fontScale; });
67+ item.showHeader = Qt.binding(function() { return loader.explicitlyScaled; });
68+ item.artShapeBorderSource = "none";
69+ }
70+
71+ BorderImage {
72+ anchors {
73+ fill: parent
74+ margins: -units.gu(1)
75+ }
76+ z: -1
77+ source: "graphics/carousel_dropshadow.sci"
78+ }
6779 }
6880 }
6981}
qml/Dash/CardFilterGrid.qml+24−26
@@ -28,9 +28,10 @@ DashRenderer {
2828 verticalSpacing: units.gu(1)
2929 currentItem: filterGrid.currentItem
3030 height: filterGrid.height
31+ filtered: filterGrid.filtered
3132
32− function startFilterAnimation(filter) {
33− filterGrid.startFilterAnimation(filter)
33+ function setFilter(filter, animate) {
34+ filterGrid.setFilter(filter, animate)
3435 }
3536
3637 FilterGrid {
@@ -41,35 +42,32 @@ DashRenderer {
4142 delegateHeight: cardTool.cardHeight
4243 verticalSpacing: genericFilterGrid.verticalSpacing
4344 model: genericFilterGrid.model
44− filter: genericFilterGrid.filter
4545 collapsedRowCount: Math.min(2, cardTool && cardTool.template && cardTool.template["collapsed-rows"] || 2)
46− delegateCreationBegin: genericFilterGrid.delegateCreationBegin
47− delegateCreationEnd: genericFilterGrid.delegateCreationEnd
48− delegate: Loader {
49− asynchronous: true
46+ displayMarginBeginning: genericFilterGrid.displayMarginBeginning
47+ displayMarginEnd: genericFilterGrid.displayMarginEnd
48+ delegate: Item {
5049 width: filterGrid.cellWidth
5150 height: filterGrid.cellHeight
52− Card {
53− id: card
54− width: cardTool.cardWidth
55− height: cardTool.cardHeight
56− fixedHeaderHeight: cardTool.headerHeight
51+ Loader {
52+ id: loader
53+ sourceComponent: cardTool.cardComponent
5754 anchors.horizontalCenter: parent.horizontalCenter
58− objectName: "delegate" + index
59− cardData: model
60− template: cardTool.template
61− components: cardTool.components
62−
63− headerAlignment: cardTool.headerAlignment
64−
65− onClicked: genericFilterGrid.clicked(index, card.y)
66− onPressAndHold: genericFilterGrid.pressAndHold(index, card.y)
55+ onLoaded: {
56+ item.objectName = "delegate" + index;
57+ item.width = Qt.binding(function() { return cardTool.cardWidth; });
58+ item.height = Qt.binding(function() { return cardTool.cardHeight; });
59+ item.fixedArtShapeSize = Qt.binding(function() { return cardTool.artShapeSize; });
60+ item.cardData = Qt.binding(function() { return model; });
61+ item.template = Qt.binding(function() { return cardTool.template; });
62+ item.components = Qt.binding(function() { return cardTool.components; });
63+ item.headerAlignment = Qt.binding(function() { return cardTool.headerAlignment; });
64+ }
65+ Connections {
66+ target: loader.item
67+ onClicked: genericFilterGrid.clicked(index, result)
68+ onPressAndHold: genericFilterGrid.pressAndHold(index)
69+ }
6770 }
6871 }
69−
70− onFilterChanged: {
71− genericFilterGrid.filter = filter
72− filter = Qt.binding(function() { return genericFilterGrid.filter })
73− }
7472 }
7573}
qml/Dash/CardHeader.qmldeleted−126
@@ -1,126 +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−
17−import QtQuick 2.0
18−import Ubuntu.Components 0.1
19−
20−Item {
21− id: root
22− property url mascot: ""
23− property alias title: titleLabel.text
24− property var subtitle
25−
26− property alias titleWeight: titleLabel.font.weight
27− property alias titleSize: titleLabel.fontSize
28−
29− // FIXME: Saviq, used to scale fonts down in Carousel
30− property real fontScale: 1.0
31−
32− property alias headerAlignment: titleLabel.horizontalAlignment
33−
34− property bool inOverlay: false
35− property bool useMascotShape: true
36− property color fontColor: Theme.palette.selected.backgroundText
37−
38− visible: mascot != "" || title
39− implicitHeight: row.height > 0 ? row.height + row.margins * 2 : 0
40−
41− Row {
42− id: row
43− objectName: "outerRow"
44−
45− property real margins: units.gu(1)
46−
47− spacing: mascotShapeLoader.active || mascotImageLoader.active || inOverlay ? margins : 0
48− anchors {
49− top: parent.top; left: parent.left; right: parent.right
50− margins: margins
51− leftMargin: spacing
52− rightMargin: spacing
53− }
54−
55− Loader {
56− id: mascotShapeLoader
57− objectName: "mascotShapeLoader"
58−
59− active: useMascotShape && mascotImageLoader.item && mascotImageLoader.item.status === Image.Ready
60− visible: active
61− anchors.verticalCenter: parent.verticalCenter
62− // TODO karni: Icon aspect-ratio is 8:7.5. Revisit these values to avoid fraction of pixels.
63− width: units.gu(6)
64− height: units.gu(5.625)
65− readonly property int maxSize: Math.max(width, height) * 4
66−
67− sourceComponent: UbuntuShape {
68− image: mascotImageLoader.item
69− }
70− }
71−
72− Loader {
73− id: mascotImageLoader
74− active: root.mascot != ""
75− visible: active && !useMascotShape && item.status === Image.Ready
76− anchors.verticalCenter: parent.verticalCenter
77− sourceComponent: Image {
78− objectName: "mascotImage"
79−
80− source: root.mascot
81− width: source ? mascotShapeLoader.width : 0
82− height: mascotShapeLoader.height
83−
84− sourceSize { width: mascotShapeLoader.maxSize; height: mascotShapeLoader.maxSize }
85− fillMode: Image.PreserveAspectCrop
86− horizontalAlignment: Image.AlignHCenter
87− verticalAlignment: Image.AlignVCenter
88− }
89− }
90−
91− Column {
92− objectName: "column"
93− width: parent.width - x
94− spacing: units.dp(2)
95− anchors.verticalCenter: parent.verticalCenter
96−
97− Label {
98− id: titleLabel
99− objectName: "titleLabel"
100− anchors { left: parent.left; right: parent.right }
101− elide: Text.ElideRight
102− font.weight: Font.Normal
103− fontSize: "small"
104− wrapMode: Text.Wrap
105− maximumLineCount: 2
106− font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale)
107− color: fontColor
108− }
109−
110− Loader {
111− active: titleLabel.text && root.subtitle
112− anchors { left: parent.left; right: parent.right }
113− sourceComponent: Label {
114− id: subtitleLabel
115− objectName: "subtitleLabel"
116− elide: Text.ElideRight
117− fontSize: "small"
118− font.weight: Font.Light
119− font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale)
120− color: fontColor
121− text: root.subtitle
122− }
123− }
124− }
125− }
126−}
qml/Dash/CardTool.qml+30−22
@@ -15,6 +15,7 @@
1515 */
1616
1717import QtQuick 2.0
18+import Dash 0.1
1819
1920/*!
2021 \brief Tool for introspecting Card properties.
@@ -65,6 +66,8 @@ Item {
6566 return layout;
6667 }
6768
69+ property var cardComponent: CardCreatorCache.getCardComponent(cardTool.template, cardTool.components);
70+
6871 // FIXME: Saviq
6972 // Only way for the card below to actually be laid out completely.
7073 // If invisible or in "data" array, some components are not taken into account.
@@ -108,7 +111,7 @@ Item {
108111 if (template["card-size"] >= 12 && template["card-size"] <= 38) return units.gu(template["card-size"]);
109112 return units.gu(18.5);
110113 case "grid":
111− return card.implicitHeight
114+ return cardLoader.item ? cardLoader.item.implicitHeight : 0
112115 case "carousel":
113116 return cardWidth / (components ? components["art"]["aspect-ratio"] : 1)
114117 case undefined:
@@ -122,7 +125,8 @@ Item {
122125 /*!
123126 type:real \brief Height of the card's header.
124127 */
125− readonly property alias headerHeight: card.headerHeight
128+ readonly property int headerHeight: cardLoader.item ? cardLoader.item.headerHeight : 0
129+ readonly property size artShapeSize: cardLoader.item ? cardLoader.item.artShapeSize : 0
126130
127131 /*!
128132 \brief Desired alignment of header components.
@@ -161,15 +165,8 @@ Item {
161165 }
162166 }
163167
164− Card {
165− id: card
166− objectName: "cardToolCard"
167− template: cardTool.template
168− components: cardTool.components
169−
170− width: cardTool.cardWidth || implicitWidth
171− height: cardTool.cardHeight || implicitHeight
172−
168+ Loader {
169+ id: cardLoader
173170 property var fields: ["art", "mascot", "title", "subtitle", "summary"]
174171 property var maxData: {
175172 "art": Qt.resolvedUrl("graphics/checkers.png"),
@@ -178,19 +175,30 @@ Item {
178175 "subtitle": "—",
179176 "summary": "—\n—\n—\n—\n—"
180177 }
181−
182− onComponentsChanged: {
183− var data = {};
184− for (var k in fields) {
185− var component = components[fields[k]];
186− var key = fields[k];
187− if ((typeof component === "string" && component.length > 0) ||
188− (typeof component === "object" && component !== null
189− && typeof component["field"] === "string" && component["field"].length > 0)) {
190− data[key] = maxData[key];
178+ sourceComponent: cardTool.cardComponent
179+ onLoaded: {
180+ item.objectName = "cardToolCard";
181+ item.asynchronous = false;
182+ item.template = Qt.binding(function() { return cardTool.template; });
183+ item.components = Qt.binding(function() { return cardTool.components; });
184+ item.width = Qt.binding(function() { return cardTool.cardWidth || item.implicitWidth; });
185+ item.height = Qt.binding(function() { return cardTool.cardHeight || item.implicitHeight; });
186+ }
187+ Connections {
188+ target: cardLoader.item
189+ onComponentsChanged: {
190+ var data = {};
191+ for (var k in cardLoader.fields) {
192+ var component = cardLoader.item.components[cardLoader.fields[k]];
193+ var key = cardLoader.fields[k];
194+ if ((typeof component === "string" && component.length > 0) ||
195+ (typeof component === "object" && component !== null
196+ && typeof component["field"] === "string" && component["field"].length > 0)) {
197+ data[key] = cardLoader.maxData[key];
198+ }
191199 }
200+ cardLoader.item.cardData = data;
192201 }
193− cardData = data;
194202 }
195203 }
196204}
qml/Dash/DashContent.qml+19−11
@@ -17,6 +17,7 @@
1717import QtQuick 2.0
1818import Ubuntu.Components 0.1
1919import Unity 0.2
20+import Utils 0.1
2021import "../Components"
2122
2223Item {
@@ -137,7 +138,7 @@ Item {
137138
138139 readonly property bool moving: item ? item.moving : false
139140 readonly property var categoryView: item ? item.categoryView : null
140− readonly property Scope theScope: scope
141+ readonly property var theScope: scope
141142
142143 // these are needed for autopilot tests
143144 readonly property string scopeId: scope.id
@@ -183,23 +184,30 @@ Item {
183184 width: parent.width
184185 style: DashContentTabBarStyle {}
185186
186− model: dashContentList.model
187+ SortFilterProxyModel {
188+ id: tabBarModel
187189
188− onSelectedIndexChanged: {
189− if (dashContentList.currentIndex == -1 && tabBar.selectedIndex != -1) {
190− // TODO This together with the Timer below
191− // are a workaround for the first tab sometimes not showing the text.
192− // But Tabs are going away in the future so not sure if makes
193− // sense invetigating what's the problem at this stage
194− selectionModeTimer.restart();
190+ model: dashContentList.model
191+
192+ property int selectedIndex: -1
193+ onSelectedIndexChanged: {
194+ if (dashContentList.currentIndex == -1 && tabBar.selectedIndex != -1) {
195+ // TODO This together with the Timer below
196+ // are a workaround for the first tab sometimes not showing the text.
197+ // But Tabs are going away in the future so not sure if makes
198+ // sense invetigating what's the problem at this stage
199+ selectionModeTimer.restart();
200+ }
201+ dashContentList.currentIndex = selectedIndex;
195202 }
196− dashContentList.currentIndex = selectedIndex;
197203 }
198204
205+ model: tabBarModel.count > 0 ? tabBarModel : null
206+
199207 Connections {
200208 target: dashContentList
201209 onCurrentIndexChanged: {
202− tabBar.selectedIndex = dashContentList.currentIndex
210+ tabBarModel.selectedIndex = dashContentList.currentIndex
203211 }
204212 }
205213
qml/Dash/DashRenderer.qml+8−9
@@ -20,8 +20,8 @@ Item {
2020 // Can the item be expanded?
2121 property bool expandable: false
2222
23− // In case it can be expanded, should we filter it
24− property bool filter: true
23+ // In case it can be expanded, is it filtered
24+ property bool filtered: true
2525
2626 property int collapsedHeight: height
2727
@@ -29,9 +29,9 @@ Item {
2929
3030 property int uncollapsedHeight: height
3131
32− property var delegateCreationBegin: undefined
32+ property int displayMarginBeginning: 0
3333
34− property var delegateCreationEnd: undefined
34+ property int displayMarginEnd: 0
3535
3636 property real originY: 0
3737
@@ -50,14 +50,13 @@ Item {
5050
5151 /// Emitted when the user clicked on an item
5252 /// @param index is the index of the clicked item
53− /// @param itemY is y of the clicked delegate
54− signal clicked(int index, real itemY)
53+ /// @param result result model of the cliked item, used for activation
54+ signal clicked(int index, var result)
5555
5656 /// Emitted when the user pressed and held on an item
5757 /// @param index is the index of the held item
58− /// @param itemY is y of the held delegate
59− signal pressAndHold(int index, real itemY)
58+ signal pressAndHold(int index)
6059
61− function startFilterAnimation(filter) {
60+ function setFilter(filter, animate) {
6261 }
6362}
qml/Dash/GenericScopeView.qml+24−25
@@ -25,7 +25,7 @@ import "../Components/ListItems" as ListItems
2525FocusScope {
2626 id: scopeView
2727
28− property Scope scope: null
28+ property var scope: null
2929 property SortFilterProxyModel categories: categoryFilter
3030 property bool isCurrent: false
3131 property alias moving: categoryView.moving
@@ -122,7 +122,7 @@ FocusScope {
122122 showDivider: false
123123
124124 readonly property bool expandable: rendererLoader.item ? rendererLoader.item.expandable : false
125− readonly property bool filtered: rendererLoader.item ? rendererLoader.item.filter : true
125+ readonly property bool filtered: rendererLoader.item ? rendererLoader.item.filtered : true
126126 readonly property string category: categoryId
127127 readonly property var item: rendererLoader.item
128128
@@ -168,9 +168,7 @@ FocusScope {
168168 item.objectName = Qt.binding(function() { return categoryId })
169169 if (item.expandable) {
170170 var shouldFilter = categoryId != categoryView.expandedCategoryId;
171− if (shouldFilter != item.filter) {
172− item.filter = shouldFilter;
173− }
171+ item.setFilter(shouldFilter, false /*animate*/);
174172 }
175173 updateDelegateCreationRange();
176174 item.cardTool = cardTool;
@@ -189,8 +187,7 @@ FocusScope {
189187 // TODO Technically it is possible that calling activate() will make the scope emit
190188 // previewRequested so that we show a preview but there's no scope that does that yet
191189 // so it's not implemented
192− var item = target.model.get(index);
193− scopeView.scope.activate(item.result)
190+ scopeView.scope.activate(result)
194191 } else {
195192 previewListView.model = target.model;
196193 previewListView.currentIndex = -1
@@ -219,11 +216,8 @@ FocusScope {
219216 var shrinkingVisible = shouldFilter && y + item.collapsedHeight < categoryView.height;
220217 var growingVisible = !shouldFilter && y + height < categoryView.height;
221218 if (!previewListView.open || !shouldFilter) {
222− if (shrinkingVisible || growingVisible) {
223− item.startFilterAnimation(shouldFilter)
224− } else {
225− item.filter = shouldFilter;
226− }
219+ var animate = shrinkingVisible || growingVisible;
220+ item.setFilter(shouldFilter, animate)
227221 if (!shouldFilter && !previewListView.open) {
228222 categoryView.maximizeVisibleArea(index, item.uncollapsedHeight);
229223 }
@@ -238,26 +232,31 @@ FocusScope {
238232 }
239233
240234 function updateDelegateCreationRange() {
241− // Do not update the range if we are overshooting up or down, since we'll come back
242− // to the stable position and delete/create items without any reason
243− if (categoryView.contentY < categoryView.originY) {
244− return;
245− } else if (categoryView.contentHeight > categoryView.height && categoryView.contentY + categoryView.height > categoryView.contentHeight) {
246− return;
235+ if (categoryView.moving) {
236+ // Do not update the range if we are overshooting up or down, since we'll come back
237+ // to the stable position and delete/create items without any reason
238+ if (categoryView.contentY < categoryView.originY) {
239+ return;
240+ } else if (categoryView.contentHeight - categoryView.originY > categoryView.height &&
241+ categoryView.contentY + categoryView.height > categoryView.contentHeight) {
242+ return;
243+ }
247244 }
248245
249− if (item && item.hasOwnProperty("delegateCreationBegin")) {
246+ if (item && item.hasOwnProperty("displayMarginBeginning")) {
247+ // TODO do we need item.originY here, test 1300302 once we have a silo
248+ // and we can run it on the phone
250249 if (baseItem.y + baseItem.height <= 0) {
251250 // Not visible (item at top of the list viewport)
252− item.delegateCreationBegin = item.originY + baseItem.height
253− item.delegateCreationEnd = item.originY + baseItem.height
251+ item.displayMarginBeginning = -baseItem.height;
252+ item.displayMarginEnd = 0;
254253 } else if (baseItem.y >= categoryView.height) {
255254 // Not visible (item at bottom of the list viewport)
256− item.delegateCreationBegin = item.originY
257− item.delegateCreationEnd = item.originY
255+ item.displayMarginBeginning = 0;
256+ item.displayMarginEnd = -baseItem.height;
258257 } else {
259− item.delegateCreationBegin = item.originY + Math.max(-baseItem.y, 0)
260− item.delegateCreationEnd = item.originY + Math.min(categoryView.height + item.delegateCreationBegin, baseItem.height)
258+ item.displayMarginBeginning = -Math.max(-baseItem.y, 0);
259+ item.displayMarginEnd = -Math.max(baseItem.height - categoryView.height + baseItem.y, 0)
261260 }
262261 }
263262 }
qml/Dash/PreviewListView.qml+2−2
@@ -23,7 +23,7 @@ import "Previews" as Previews
2323Item {
2424 id: root
2525
26− property Scope scope: null
26+ property var scope: null
2727 property var pageHeader: null
2828
2929 property alias open: previewListView.open
@@ -116,7 +116,7 @@ Item {
116116
117117 previewModel: {
118118 var previewStack = root.scope.preview(result);
119− return previewStack.get(0);
119+ return previewStack.getPreviewModel(0);
120120 }
121121 }
122122
qml/Dash/Previews/PreviewHeader.qml+86−9
@@ -15,9 +15,10 @@
1515 */
1616
1717import QtQuick 2.0
18+import Ubuntu.Components 0.1
1819import "../"
1920
20−/*! This preview widget shows a header that is the same as the card header
21+/*! This preview widget shows a header
2122 * The title comes in widgetData["title"]
2223 * The mascot comes in widgetData["mascot"]
2324 * The subtitle comes in widgetData["subtitle"]
@@ -28,15 +29,91 @@ PreviewWidget {
2829
2930 height: childrenRect.height
3031
31− CardHeader {
32− objectName: "cardHeader"
33− mascot: root.widgetData["mascot"] || ""
34− title: root.widgetData["title"] || ""
35− subtitle: root.widgetData["subtitle"] || ""
32+ Item {
33+ id: headerRoot
34+ objectName: "innerPreviewHeader"
35+ readonly property url mascot: root.widgetData["mascot"] || ""
36+ readonly property string title: root.widgetData["title"] || ""
37+ readonly property string subtitle: root.widgetData["subtitle"] || ""
38+ readonly property color fontColor: "grey"
39+
40+ implicitHeight: row.height + row.margins * 2
3641 width: parent.width
3742
38− titleSize: "large"
39− // TODO Change "grey" to Ubuntu.Components.Palette color once updated.
40− fontColor: "grey"
43+ Row {
44+ id: row
45+ objectName: "outerRow"
46+
47+ property real margins: units.gu(1)
48+
49+ spacing: mascotShapeLoader.active ? margins : 0
50+ anchors {
51+ top: parent.top; left: parent.left; right: parent.right
52+ margins: margins
53+ leftMargin: spacing
54+ rightMargin: spacing
55+ }
56+
57+ Loader {
58+ id: mascotShapeLoader
59+
60+ anchors.verticalCenter: parent.verticalCenter
61+ // TODO karni: Icon aspect-ratio is 8:7.5. Revisit these values to avoid fraction of pixels.
62+ width: units.gu(6)
63+ height: units.gu(5.625)
64+ readonly property int maxSize: Math.max(width, height) * 4
65+ asynchronous: true
66+
67+ sourceComponent: UbuntuShape {
68+ objectName: "mascotShape"
69+ visible: image.status === Image.Ready
70+ image: Image {
71+ source: headerRoot.mascot
72+ width: source ? mascotShapeLoader.width : 0
73+ height: mascotShapeLoader.height
74+
75+ sourceSize { width: mascotShapeLoader.maxSize; height: mascotShapeLoader.maxSize }
76+ fillMode: Image.PreserveAspectCrop
77+ horizontalAlignment: Image.AlignHCenter
78+ verticalAlignment: Image.AlignVCenter
79+ }
80+ }
81+ }
82+
83+ Column {
84+ objectName: "column"
85+ width: parent.width - x
86+ spacing: units.dp(2)
87+ anchors.verticalCenter: parent.verticalCenter
88+
89+ Label {
90+ id: titleLabel
91+ objectName: "titleLabel"
92+ anchors { left: parent.left; right: parent.right }
93+ elide: Text.ElideRight
94+ font.weight: Font.Normal
95+ fontSize: "large"
96+ wrapMode: Text.Wrap
97+ maximumLineCount: 2
98+ color: headerRoot.fontColor
99+ text: headerRoot.title
100+ }
101+
102+ Loader {
103+ active: titleLabel.text && headerRoot.subtitle
104+ anchors { left: parent.left; right: parent.right }
105+ sourceComponent: Label {
106+ id: subtitleLabel
107+ objectName: "subtitleLabel"
108+ elide: Text.ElideRight
109+ fontSize: "small"
110+ font.weight: Font.Light
111+ color: headerRoot.fontColor
112+ text: headerRoot.subtitle
113+ }
114+ }
115+ }
116+ }
41117 }
118+
42119}
qml/Dash/Previews/PreviewProgress.qml+3−2
@@ -34,11 +34,12 @@ PreviewWidget {
3434 ProgressBar {
3535 id: progressBar
3636 objectName: "progressBar"
37+ anchors.right: parent.right
3738 value: 0
3839 maximumValue: 100
39− implicitHeight: units.gu(5)
40+ implicitHeight: units.gu(4)
4041 height: parent.height
41− width: parent.width
42+ width: (root.width - units.gu(1)) / 2
4243
4344 property var source: widgetData["source"]
4445 // TODO Eventually we will need to support more sources other
qml/Dash/Previews/PreviewRatingInput.qml+2−2
@@ -155,8 +155,8 @@ PreviewWidget {
155155 objectName: "submitButton"
156156
157157 readonly property bool readyToSubmit: {
158− if (reviewTextArea.text === "" ||
159− (widgetData["visible"] === "both" && rating.value < 0)) return false;
158+ if ((widgetData["required"] !== "review" && rating.value < 0) ||
159+ (widgetData["required"] !== "rating" && reviewTextArea.text === "")) return false;
160160 else return true;
161161 }
162162
qml/Dash/Previews/PreviewTextSummary.qml+4−2
@@ -37,6 +37,7 @@ PreviewWidget {
3737 left: parent.left
3838 right: parent.right
3939 }
40+ height: visible ? implicitHeight : 0
4041 fontSize: "large"
4142 // TODO karni: Yet another fix requiring Palette update.
4243 color: "grey" //Theme.palette.selected.backgroundText
@@ -68,7 +69,7 @@ PreviewWidget {
6869 wrapMode: Text.Wrap
6970
7071 Behavior on height {
71− UbuntuNumberAnimation {}
72+ UbuntuNumberAnimation { duration: UbuntuAnimation.SnapDuration }
7273 }
7374 }
7475
@@ -79,8 +80,9 @@ PreviewWidget {
7980 left: parent.left
8081 right: parent.right
8182 top: textLabel.bottom
82− topMargin: units.gu(1)
83+ topMargin: visible ? units.gu(1) : 0
8384 }
85+ height: visible ? implicitHeight : 0
8486 visible: textLabel.lineCount > textLabel.maximumCollapsedLineCount
8587 }
8688}
qml/Dash/Previews/PreviewZoomableImage.qml+4−7
@@ -28,14 +28,11 @@ PreviewWidget {
2828 id: root
2929 implicitHeight: units.gu(22)
3030
31− LazyImage {
31+ ZoomableImage {
32+ id: image
3233 objectName: "image"
33− anchors {
34− top: parent.top
35− bottom: parent.bottom
36− }
37− scaleTo: "height"
3834 source: widgetData["source"]
39− initialWidth: units.gu(13)
35+ zoomable: widgetData["zoomable"] ? widgetData["zoomable"] : false
36+ anchors.fill: parent
4037 }
4138}
qml/Dash/ScopeListView.qml+1−1
@@ -15,7 +15,7 @@
1515 */
1616
1717import QtQuick 2.0
18−import DashViews 0.1
18+import Dash 0.1
1919
2020ListViewWithPageHeader {
2121 maximumFlickVelocity: height * 10
qml/Dash/graphics/carousel_dropshadow@27.pngnew file

Binary file not shown.

qml/Dash/graphics/carousel_dropshadow@27.scinew file+5
@@ -0,0 +1,5 @@
1+border.left: 108
2+border.top: 108
3+border.bottom: 108
4+border.right: 108
5+source: carousel_dropshadow@27.png
qml/Greeter/Clock.qml+3−6
@@ -24,14 +24,11 @@ Item {
2424 implicitWidth: childrenRect.width
2525 implicitHeight: childrenRect.height
2626
27− // Allows to set the current Date. Will be overwritten if active
27+ // Allows to set the current Date. Will be overwritten if visible
2828 property date currentDate
2929
30− // If active, time will be updated through the indicators service
31− property bool active: clock.enabled && clock.visible
32−
3330 Component.onCompleted: {
34− if (active) {
31+ if (visible) {
3532 currentDate = new Date()
3633 }
3734 }
@@ -42,7 +39,7 @@ Item {
4239
4340 busName: "com.canonical.indicator.datetime"
4441 actionsObjectPath: "/com/canonical/indicator/datetime"
45− menuObjectPath: clock.active ? "/com/canonical/indicator/datetime/phone" : ""
42+ menuObjectPath: clock.visible ? "/com/canonical/indicator/datetime/phone" : ""
4643
4744 Indicators.RootActionState {
4845 menu: timeModel.model
qml/Greeter/Greeter.qml+115−42
@@ -28,10 +28,10 @@ Showable {
2828 property url defaultBackground
2929
3030 // 1 when fully shown and 0 when fully hidden
31− property real showProgress: MathUtils.clamp((width + x) / width, 0, 1)
31+ property real showProgress: MathUtils.clamp((width - Math.abs(x)) / width, 0, 1)
3232
3333 showAnimation: StandardAnimation { property: "x"; to: 0 }
34− hideAnimation: StandardAnimation { property: "x"; to: -width }
34+ hideAnimation: __leftHideAnimation
3535
3636 property alias dragHandleWidth: dragHandle.width
3737 property alias model: greeterContentLoader.model
@@ -40,19 +40,81 @@ Showable {
4040 readonly property bool narrowMode: !multiUser && height > width
4141 readonly property bool multiUser: LightDM.Users.count > 1
4242
43− readonly property bool leftTeaserPressed: greeterContentLoader.status == Loader.Ready &&
44− greeterContentLoader.item.leftTeaserPressed
45− readonly property bool rightTeaserPressed: greeterContentLoader.status == Loader.Ready &&
46− greeterContentLoader.item.rightTeaserPressed
47−
4843 readonly property int currentIndex: greeterContentLoader.currentIndex
4944
45+ property var __leftHideAnimation: StandardAnimation { property: "x"; to: -width }
46+ property var __rightHideAnimation: StandardAnimation { property: "x"; to: width }
47+
5048 signal selected(int uid)
5149 signal unlocked(int uid)
50+ signal tease()
51+
52+ function hideRight() {
53+ if (shown) {
54+ hideAnimation = __rightHideAnimation
55+ hide()
56+ }
57+ }
58+
59+ onRequiredChanged: {
60+ // Reset hide animation to default once we're finished with it
61+ if (!required) {
62+ // Put back on left for reliable show direction and so that
63+ // if normal hide() is called, we don't animate from right.
64+ x = -width
65+ hideAnimation = __leftHideAnimation
66+ }
67+ }
68+
69+ // Bi-directional revealer
70+ DraggingArea {
71+ id: dragHandle
72+ anchors.fill: parent
73+ enabled: greeter.narrowMode || !greeter.locked
74+ orientation: Qt.Horizontal
75+ propagateComposedEvents: true
76+
77+ Component.onCompleted: {
78+ // set evaluators to baseline of dragValue == 0
79+ leftEvaluator.reset()
80+ rightEvaluator.reset()
81+ }
82+
83+ function maybeTease() {
84+ if (!greeter.locked || greeter.narrowMode)
85+ greeter.tease();
86+ }
87+
88+ onClicked: maybeTease()
89+ onDragStart: maybeTease()
90+ onPressAndHold: {} // eat event, but no need to tease, as drag will cover it
91+
92+ onDragEnd: {
93+ if (rightEvaluator.shouldAutoComplete())
94+ greeter.hideRight()
95+ else if (leftEvaluator.shouldAutoComplete())
96+ greeter.hide();
97+ else
98+ greeter.show(); // undo drag
99+ }
100+
101+ onDragValueChanged: {
102+ // dragValue is kept as a "step" value since we do this x adjusting on the fly
103+ greeter.x += dragValue
104+ }
105+
106+ EdgeDragEvaluator {
107+ id: rightEvaluator
108+ trackedPosition: dragHandle.dragValue + greeter.x
109+ maxDragDistance: parent.width
110+ direction: Direction.Rightwards
111+ }
52112
53− onRightTeaserPressedChanged: {
54− if (rightTeaserPressed && (!locked || narrowMode) && x == 0) {
55− teasingTimer.start();
113+ EdgeDragEvaluator {
114+ id: leftEvaluator
115+ trackedPosition: dragHandle.dragValue + greeter.x
116+ maxDragDistance: parent.width
117+ direction: Direction.Leftwards
56118 }
57119 }
58120
@@ -82,45 +144,56 @@ Showable {
82144 }
83145 }
84146
85− Timer {
86− id: teasingTimer
87− interval: 200
88− }
147+ onTease: showLabelAnimation.start()
89148
90− states: [
91− State {
92− name: "teasing"
93− when: teasingTimer.running
94− PropertyChanges {
95− target: greeter
96− x: -dragHandle.hintDisplacement
149+ Label {
150+ id: swipeHint
151+ visible: greeter.shown
152+ property real baseOpacity: 0.5
153+ opacity: 0.0
154+ anchors.horizontalCenter: parent.horizontalCenter
155+ anchors.bottom: parent.bottom
156+ anchors.bottomMargin: units.gu(5)
157+ text: i18n.tr("Swipe to unlock")
158+ color: "white"
159+ font.weight: Font.Light
160+
161+ SequentialAnimation on opacity {
162+ id: showLabelAnimation
163+ running: false
164+ loops: 2
165+
166+ StandardAnimation {
167+ from: 0.0
168+ to: swipeHint.baseOpacity
169+ duration: UbuntuAnimation.SleepyDuration
97170 }
98− }
99− ]
100− transitions: [
101− Transition {
102− from: "*"
103− to: "*"
104− NumberAnimation {
105− target: greeter
106− property: "x"
107− duration: 300
108− easing.type: Easing.OutCubic
171+ PauseAnimation { duration: UbuntuAnimation.BriskDuration }
172+ StandardAnimation {
173+ from: swipeHint.baseOpacity
174+ to: 0.0
175+ duration: UbuntuAnimation.SleepyDuration
109176 }
110177 }
111− ]
112−
113− DragHandle {
114− id: dragHandle
178+ }
115179
180+ // right side shadow
181+ Image {
182+ anchors.left: parent.right
116183 anchors.top: parent.top
117184 anchors.bottom: parent.bottom
118− anchors.right: parent.right
119−
120− hintDisplacement: units.gu(2)
121−
122− enabled: greeter.narrowMode || !greeter.locked
185+ visible: parent.required
186+ fillMode: Image.Tile
187+ source: "../graphics/dropshadow_right.png"
188+ }
123189
124− direction: Direction.Leftwards
190+ // left side shadow
191+ Image {
192+ anchors.right: parent.left
193+ anchors.top: parent.top
194+ anchors.bottom: parent.bottom
195+ visible: parent.required
196+ fillMode: Image.Tile
197+ source: "../graphics/dropshadow_left.png"
125198 }
126199}
qml/Greeter/GreeterContent.qml+1−10
@@ -20,15 +20,11 @@ import Ubuntu.Components 0.1
2020import LightDM 0.1 as LightDM
2121import "../Components"
2222
23−MouseArea {
23+Item {
2424 id: root
2525 anchors.fill: parent
2626
2727 property bool ready: background.source == "" || background.status == Image.Ready || background.status == Image.Error
28− property bool leftTeaserPressed: teasingMouseArea.pressed &&
29− teasingMouseArea.mouseX < teasingMouseArea.width / 2
30− property bool rightTeaserPressed: teasingMouseArea.pressed &&
31− teasingMouseArea.mouseX > teasingMouseArea.width / 2
3228
3329 signal selected(int uid)
3430 signal unlocked(int uid)
@@ -74,11 +70,6 @@ MouseArea {
7470 opacity: 0.4
7571 }
7672
77− MouseArea {
78− id: teasingMouseArea
79− anchors.fill: parent
80− }
81−
8273 Loader {
8374 id: loginLoader
8475 objectName: "loginLoader"
qml/Greeter/Infographics.qml+3
@@ -457,5 +457,8 @@ Item {
457457 !circleGrowAnimTimer.running)
458458 infographic.model.nextDataSource()
459459 }
460+
461+ onClicked: mouse.accepted = false
462+ onPressed: mouse.accepted = false
460463 }
461464}
qml/Hud/Hud.qml+1−1
@@ -491,6 +491,6 @@ Item {
491491 anchors.top: hudContentClipper.top
492492 anchors.bottom: hudContentClipper.bottom
493493 fillMode: Image.Tile
494− source: "graphics/dropshadow_right.png"
494+ source: "../graphics/dropshadow_right.png"
495495 }
496496}
qml/Notifications/Notifications.qml+11
@@ -16,6 +16,8 @@
1616
1717import QtQuick 2.0
1818import Ubuntu.Components 0.1
19+import Unity.Notifications 1.0 as UnityNotifications
20+import Utils 0.1
1921import "../Components"
2022
2123ListView {
@@ -25,6 +27,15 @@ ListView {
2527 interactive: false
2628
2729 property real margin
30+ property bool useModal: snapDecisionProxyModel.count > 0
31+
32+ SortFilterProxyModel {
33+ id: snapDecisionProxyModel
34+
35+ model: notificationList.model
36+ filterRole: UnityNotifications.ModelInterface.RoleType
37+ filterRegExp: RegExp(UnityNotifications.Notification.SnapDecision)
38+ }
2839 spacing: delegate.fullscreen ? 0 : units.gu(.5)
2940
3041 currentIndex: (currentIndex < 1 && count > 1) ? 1 : -1
qml/ScopeTool.qml+1−1
@@ -74,7 +74,7 @@ Rectangle {
7474
7575 model: filteredScopes
7676 searchHistory: SearchHistoryModel { }
77− property Scope scope: scopes.get(currentIndex)
77+ property var scope: scopes.getScope(currentIndex)
7878
7979 anchors {
8080 top: parent.top
qml/Shell.qml+79−92
@@ -28,9 +28,7 @@ import "Dash"
2828import "Greeter"
2929import "Launcher"
3030import "Panel"
31−import "Hud"
3231import "Components"
33−import "Bottombar"
3432import "Notifications"
3533import Unity.Notifications 1.0 as NotificationBackend
3634
@@ -148,8 +146,8 @@ FocusScope {
148146
149147 available: !greeter.shown && !lockscreen.shown
150148 hides: [stages, launcher, panel.indicators]
151− shown: disappearingAnimationProgress !== 1.0
152− enabled: disappearingAnimationProgress === 0.0 && edgeDemo.dashEnabled
149+ shown: disappearingAnimationProgress !== 1.0 && greeterWrapper.showProgress !== 1.0
150+ enabled: disappearingAnimationProgress === 0.0 && greeterWrapper.showProgress === 0.0 && edgeDemo.dashEnabled
153151
154152 anchors {
155153 fill: parent
@@ -159,18 +157,14 @@ FocusScope {
159157 contentScale: 1.0 - 0.2 * disappearingAnimationProgress
160158 opacity: 1.0 - disappearingAnimationProgress
161159 property real disappearingAnimationProgress: {
162− if (greeter.shown) {
163− return greeter.showProgress;
160+ if (stages.overlayMode) {
161+ return 0;
164162 } else {
165− if (stages.overlayMode) {
166− return 0;
167− }
168163 return stages.showProgress
169164 }
170165 }
171166
172− // FIXME: only necessary because stages.showProgress and
173− // greeterRevealer.animatedProgress are not animated
167+ // FIXME: only necessary because stages.showProgress is not animated
174168 Behavior on disappearingAnimationProgress { SmoothedAnimation { velocity: 5 }}
175169 }
176170 }
@@ -312,7 +306,7 @@ FocusScope {
312306
313307 readonly property int backgroundTopMargin: -panel.panelHeight
314308
315− hides: [launcher, panel.indicators, hud]
309+ hides: [launcher, panel.indicators]
316310 shown: false
317311 enabled: true
318312 showAnimation: StandardAnimation { property: "opacity"; to: 1 }
@@ -362,59 +356,73 @@ FocusScope {
362356 }
363357 }
364358
365− Greeter {
366− id: greeter
367− objectName: "greeter"
368−
369− available: true
370− hides: [launcher, panel.indicators, hud]
371− shown: true
372−
373− defaultBackground: shell.background
359+ Rectangle {
360+ anchors.fill: parent
361+ color: "black"
362+ opacity: greeterWrapper.showProgress * 0.8
363+ }
374364
365+ Item {
366+ // Just a tiny wrapper to adjust greeter's x without messing with its own dragging
367+ id: greeterWrapper
368+ x: launcher.progress
375369 y: panel.panelHeight
376370 width: parent.width
377371 height: parent.height - panel.panelHeight
378372
379− dragHandleWidth: shell.edgeSize
373+ Behavior on x {SmoothedAnimation{velocity: 600}}
380374
381− onShownChanged: {
382− if (shown) {
383− lockscreen.reset();
384− // If there is only one user, we start authenticating with that one here.
385− // If there are more users, the Greeter will handle that
386− if (LightDM.Users.count == 1) {
387− LightDM.Greeter.authenticate(LightDM.Users.data(0, LightDM.UserRoles.NameRole));
375+ readonly property real showProgress: MathUtils.clamp((1 - x/width) + greeter.showProgress - 1, 0, 1)
376+
377+ Greeter {
378+ id: greeter
379+ objectName: "greeter"
380+
381+ available: true
382+ hides: [launcher, panel.indicators]
383+ shown: true
384+
385+ defaultBackground: shell.background
386+
387+ width: parent.width
388+ height: parent.height
389+
390+ dragHandleWidth: shell.edgeSize
391+
392+ onShownChanged: {
393+ if (shown) {
394+ lockscreen.reset();
395+ // If there is only one user, we start authenticating with that one here.
396+ // If there are more users, the Greeter will handle that
397+ if (LightDM.Users.count == 1) {
398+ LightDM.Greeter.authenticate(LightDM.Users.data(0, LightDM.UserRoles.NameRole));
399+ }
400+ greeter.forceActiveFocus();
388401 }
389− greeter.forceActiveFocus();
390402 }
391− }
392403
393− onUnlocked: greeter.hide()
394− onSelected: {
395− // Update launcher items for new user
396− var user = LightDM.Users.data(uid, LightDM.UserRoles.NameRole);
397− AccountsService.user = user;
398− LauncherModel.setUser(user);
399− }
400−
401− onLeftTeaserPressedChanged: {
402− if (leftTeaserPressed) {
403− launcher.tease();
404+ onUnlocked: greeter.hide()
405+ onSelected: {
406+ // Update launcher items for new user
407+ var user = LightDM.Users.data(uid, LightDM.UserRoles.NameRole);
408+ AccountsService.user = user;
409+ LauncherModel.setUser(user);
404410 }
405− }
406411
407− Binding {
408− target: ApplicationManager
409− property: "suspended"
410− value: greeter.shown && greeter.showProgress == 1
412+ onTease: launcher.tease()
413+
414+ Binding {
415+ target: ApplicationManager
416+ property: "suspended"
417+ value: greeter.shown && greeterWrapper.showProgress == 1
418+ }
411419 }
412420 }
413421
414422 InputFilterArea {
415423 anchors.fill: parent
416424 blockInput: ApplicationManager.focusedApplicationId.length === 0 || greeter.shown || lockscreen.shown || launcher.shown
417− || panel.indicators.shown || hud.shown
425+ || panel.indicators.shown
418426 }
419427
420428 Connections {
@@ -478,47 +486,6 @@ FocusScope {
478486 }
479487 }
480488
481− Hud {
482− id: hud
483−
484− width: parent.width > units.gu(60) ? units.gu(40) : parent.width
485− height: parent.height
486−
487− available: !greeter.shown && !panel.indicators.shown && !lockscreen.shown && edgeDemo.dashEnabled
488− shown: false
489− showAnimation: StandardAnimation { property: "y"; duration: hud.showableAnimationDuration; to: 0; easing.type: Easing.Linear }
490− hideAnimation: StandardAnimation { property: "y"; duration: hud.showableAnimationDuration; to: hudRevealer.closedValue; easing.type: Easing.Linear }
491−
492− Connections {
493− target: ApplicationManager
494− onFocusedApplicationIdChanged: hud.hide()
495− }
496− }
497−
498− Revealer {
499− id: hudRevealer
500−
501− enabled: hud.shown
502− width: hud.width
503− anchors.left: hud.left
504− height: parent.height
505− target: hud.revealerTarget
506− closedValue: height
507− openedValue: 0
508− direction: Qt.RightToLeft
509− orientation: Qt.Vertical
510− handleSize: hud.handleHeight
511− onCloseClicked: target.hide()
512− }
513−
514− Bottombar {
515− id: bottombar
516− theHud: hud
517− anchors.fill: parent
518− enabled: hud.available
519− applicationIsOnForeground: ApplicationManager.focusedApplicationId
520− }
521−
522489 InputFilterArea {
523490 blockInput: launcher.shown
524491 anchors {
@@ -538,7 +505,7 @@ FocusScope {
538505 anchors.bottom: parent.bottom
539506 width: parent.width
540507 dragAreaWidth: shell.edgeSize
541− available: (!greeter.shown || greeter.narrowMode) && edgeDemo.launcherEnabled
508+ available: edgeDemo.launcherEnabled
542509
543510 onShowDashHome: {
544511 if (edgeDemo.running)
@@ -553,6 +520,10 @@ FocusScope {
553520 launcher.hide();
554521 }
555522 }
523+ if (greeter.shown) {
524+ greeter.hideRight();
525+ launcher.hide();
526+ }
556527 }
557528 onDashSwipeChanged: if (dashSwipe && stages.shown) dash.setCurrentScope("clickscope", false, true)
558529 onLauncherApplicationSelected: {
@@ -562,12 +533,28 @@ FocusScope {
562533 onShownChanged: {
563534 if (shown) {
564535 panel.indicators.hide()
565− hud.hide()
566− bottombar.hide()
567536 }
568537 }
569538 }
570539
540+ Rectangle {
541+ id: modalNotificationBackground
542+
543+ visible: notifications.useModal && !greeter.shown && (notifications.state == "narrow")
544+ color: "#000000"
545+ anchors.fill: parent
546+ opacity: 0.5
547+
548+ MouseArea {
549+ anchors.fill: parent
550+ }
551+
552+ InputFilterArea {
553+ anchors.fill: parent
554+ blockInput: modalNotificationBackground.visible
555+ }
556+ }
557+
571558 Notifications {
572559 id: notifications
573560
qml/graphics/dropshadow_left@20.pngnew file

Binary file not shown.

qml/Hud/graphics/dropshadow_right@20.png → qml/graphics/dropshadow_right@20.pngrenamed

Binary file not shown.

run → run.shrenamed+1−1
@@ -78,6 +78,6 @@ else
7878 echo "Unity8 is already running, please stop it first"
7979 exit 1
8080 fi
81− /sbin/initctl start unity8 BINARY="`readlink -f $QML_PHONE_SHELL_PATH` $QML_PHONE_SHELL_ARGS $@"
81+ /sbin/initctl start unity8 BINARY="`readlink -f $QML_PHONE_SHELL_PATH` $QML_PHONE_SHELL_ARGS $@" QML2_IMPORT_PATH=$QML2_IMPORT_PATH LD_LIBRARY_PATH=$LD_LIBRARY_PATH
8282 tailf -n 0 ~/.cache/upstart/unity8.log
8383fi
run_on_device → run_on_device.shrenamed+2−2
@@ -88,7 +88,7 @@ sync_code() {
8888}
8989
9090build() {
91− exec_with_ssh PATH=/usr/lib/ccache:$PATH "cd $CODE_DIR/ && PATH=/usr/lib/ccache:$PATH ./build"
91+ exec_with_ssh PATH=/usr/lib/ccache:$PATH "cd $CODE_DIR/ && PATH=/usr/lib/ccache:$PATH ./build.sh"
9292}
9393
9494run() {
@@ -105,7 +105,7 @@ run() {
105105
106106 exec_with_ssh "stop unity8"
107107 exec_with_ssh "start maliit-server"
108− exec_with_ssh "cd $CODE_DIR/ && ./run $ARGS -- $RUN_OPTIONS"
108+ exec_with_ssh "cd $CODE_DIR/ && ./run.sh $ARGS -- $RUN_OPTIONS"
109109 exec_with_ssh "stop maliit-server"
110110 exec_with_ssh "start unity8"
111111}
src/ApplicationArguments.h+4−8
@@ -28,14 +28,10 @@ class ApplicationArguments : public QObject
2828{
2929 Q_OBJECT
3030public:
31− ApplicationArguments(const QStringList& args) {
32− if (args.contains(QLatin1String("-windowgeometry")) && args.size() > args.indexOf(QLatin1String("-windowgeometry")) + 1) {
33− QStringList geometryArg = args.at(args.indexOf(QLatin1String("-windowgeometry")) + 1).split('x');
34− if (geometryArg.size() == 2) {
35− m_size.rwidth() = geometryArg.at(0).toInt();
36− m_size.rheight() = geometryArg.at(1).toInt();
37− }
38− }
31+ // Not exposed to the app as setSize isn't invokable
32+ void setSize(int width, int height) {
33+ m_size.rwidth() = width;
34+ m_size.rheight() = height;
3935 }
4036
4137 Q_INVOKABLE bool hasGeometry() const { return m_size.isValid(); }
src/main.cpp+43−6
@@ -18,6 +18,7 @@
1818 */
1919
2020// Qt
21+#include <QCommandLineParser>
2122#include <QtQuick/QQuickView>
2223#include <QtGui/QGuiApplication>
2324#include <QtQml/QQmlEngine>
@@ -43,6 +44,32 @@ int startShell(int argc, const char** argv, void* server)
4344
4445 QGuiApplication::setApplicationName("Unity 8");
4546 QGuiApplication *application;
47+
48+ QCommandLineParser parser;
49+ parser.setApplicationDescription("Description: Unity 8 Shell");
50+ parser.addHelpOption();
51+
52+ QCommandLineOption fullscreenOption("fullscreen",
53+ "Run in fullscreen");
54+ parser.addOption(fullscreenOption);
55+
56+ QCommandLineOption framelessOption("frameless",
57+ "Run without window borders");
58+ parser.addOption(framelessOption);
59+
60+ QCommandLineOption mousetouchOption("mousetouch",
61+ "Allow the mouse to provide touch input");
62+ parser.addOption(mousetouchOption);
63+
64+ QCommandLineOption windowGeometryOption(QStringList() << "windowgeometry",
65+ "Specify the window geometry as [<width>x<height>]", "windowgeometry", "1");
66+ parser.addOption(windowGeometryOption);
67+
68+ QCommandLineOption testabilityOption("testability",
69+ "DISCOURAGED: Please set QT_LOAD_TESTABILITY instead. \n \
70+Load the testability driver");
71+ parser.addOption(testabilityOption);
72+
4673 if (isUbuntuMirServer) {
4774 QLibrary unityMir("unity-mir", 1);
4875 unityMir.load();
@@ -59,17 +86,27 @@ int startShell(int argc, const char** argv, void* server)
5986 application = new QGuiApplication(argc, (char**)argv);
6087 }
6188
89+ // Treat args with single dashes the same as arguments with two dashes
90+ // Ex: -fullscreen == --fullscreen
91+ parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions);
92+ parser.process(*application);
93+
6294 QString indicatorProfile = qgetenv("UNITY_INDICATOR_PROFILE");
6395 if (indicatorProfile.isEmpty()) {
6496 indicatorProfile = "phone";
6597 }
6698
67− QStringList args = application->arguments();
68− ApplicationArguments qmlArgs(args);
99+ ApplicationArguments qmlArgs;
100+ if (parser.isSet(windowGeometryOption) &&
101+ parser.value(windowGeometryOption).split('x').size() == 2)
102+ {
103+ QStringList geom = parser.value(windowGeometryOption).split('x');
104+ qmlArgs.setSize(geom.at(0).toInt(), geom.at(1).toInt());
105+ }
69106
70107 // The testability driver is only loaded by QApplication but not by QGuiApplication.
71108 // However, QApplication depends on QWidget which would add some unneeded overhead => Let's load the testability driver on our own.
72− if (args.contains(QLatin1String("-testability")) || getenv("QT_LOAD_TESTABILITY")) {
109+ if (parser.isSet(testabilityOption) || getenv("QT_LOAD_TESTABILITY")) {
73110 QLibrary testLib(QLatin1String("qttestability"));
74111 if (testLib.load()) {
75112 typedef void (*TasInitialize)(void);
@@ -92,14 +129,14 @@ int startShell(int argc, const char** argv, void* server)
92129 view->engine()->setBaseUrl(QUrl::fromLocalFile(::qmlDirectory()));
93130 view->rootContext()->setContextProperty("applicationArguments", &qmlArgs);
94131 view->rootContext()->setContextProperty("indicatorProfile", indicatorProfile);
95− if (args.contains(QLatin1String("-frameless"))) {
132+ if (parser.isSet(framelessOption)) {
96133 view->setFlags(Qt::FramelessWindowHint);
97134 }
98135
99136 // You will need this if you want to interact with touch-only components using a mouse
100137 // Needed only when manually testing on a desktop.
101138 MouseTouchAdaptor *mouseTouchAdaptor = 0;
102− if (args.contains(QLatin1String("-mousetouch"))) {
139+ if (parser.isSet(mousetouchOption)) {
103140 mouseTouchAdaptor = new MouseTouchAdaptor;
104141 application->installNativeEventFilter(mouseTouchAdaptor);
105142 }
@@ -123,7 +160,7 @@ int startShell(int argc, const char** argv, void* server)
123160 view->setSource(source);
124161 view->setColor("transparent");
125162
126− if (qgetenv("QT_QPA_PLATFORM") == "ubuntu" || isUbuntuMirServer || args.contains(QLatin1String("-fullscreen"))) {
163+ if (qgetenv("QT_QPA_PLATFORM") == "ubuntu" || isUbuntuMirServer || parser.isSet(fullscreenOption)) {
127164 view->showFullScreen();
128165 } else {
129166 view->show();
tests/autopilot/unity8/process_helpers.py+11−4
@@ -17,12 +17,19 @@
1717# along with this program. If not, see <http://www.gnu.org/licenses/>.
1818#
1919
20−from autopilot.introspection import (
21− get_proxy_object_for_existing_process,
22− ProcessSearchError,
23−)
2420import logging
2521import subprocess
22+import sys
23+
24+# This has to work in both python 3 (ap 1.5) and py2 (ap legacy 1.4.1) so we
25+# pick the correct location in each case. Remove the py2 branch once we no
26+# longer need to support python 2.
27+if sys.version >= '3':
28+ from autopilot.exceptions import ProcessSearchError
29+else:
30+ from autopilot.introspection import ProcessSearchError
31+from autopilot.introspection import get_proxy_object_for_existing_process
32+
2633from unity8.shell import emulators
2734from unity8.shell.emulators import main_window as main_window_emulator
2835
tests/autopilot/unity8/shell/__init__.py+50−1
@@ -21,8 +21,9 @@
2121
2222from time import sleep
2323from functools import wraps
24−import logging
24+from gi.repository import Notify
2525
26+import logging
2627
2728logger = logging.getLogger(__name__)
2829
@@ -48,6 +49,7 @@ def disable_qml_mocking(fn):
4849 return fn(*args, **kwargs)
4950 return wrapper
5051
52+
5153class DragMixin(object):
5254 def _drag(self, x1, y1, x2, y2):
5355 # XXX This ugly code is here just temporarily, waiting for drag
@@ -69,3 +71,50 @@ class DragMixin(object):
6971 self.touch._finger_move(int(x2), int(y2))
7072 except AttributeError:
7173 self.touch._device.finger_move(int(x2), int(y2))
74+
75+
76+def create_ephemeral_notification(
77+ summary='',
78+ body='',
79+ icon=None,
80+ hints=[],
81+ urgency='NORMAL'
82+):
83+ """Create an ephemeral (non-interactive) notification
84+
85+ :param summary: Summary text for the notification
86+ :param body: Body text to display in the notification
87+ :param icon: Path string to the icon to use
88+ :param hint_strings: List of tuples containing the 'name' and value
89+ for setting the hint strings for the notification
90+ :param urgency: Urgency string for the noticiation, either: 'LOW',
91+ 'NORMAL', 'CRITICAL'
92+ """
93+ Notify.init('Unity8')
94+
95+ logger.info(
96+ "Creating ephemeral: summary(%s), body(%s), urgency(%r) "
97+ "and Icon(%s)",
98+ summary,
99+ body,
100+ urgency,
101+ icon
102+ )
103+
104+ notification = Notify.Notification.new(summary, body, icon)
105+
106+ for hint in hints:
107+ key, value = hint
108+ notification.set_hint_string(key, value)
109+ logger.info("Adding hint to notification: (%s, %s)", key, value)
110+ notification.set_urgency(_get_urgency(urgency))
111+
112+ return notification
113+
114+
115+def _get_urgency(urgency):
116+ """Translates urgency string to enum."""
117+ _urgency_enums = {'LOW': Notify.Urgency.LOW,
118+ 'NORMAL': Notify.Urgency.NORMAL,
119+ 'CRITICAL': Notify.Urgency.CRITICAL}
120+ return _urgency_enums.get(urgency.upper())
tests/autopilot/unity8/shell/emulators/dash.py+3−4
@@ -161,7 +161,7 @@ class GenericScopeView(emulators.UnityEmulatorBase):
161161
162162 """
163163 category_element = self._get_category_element(category)
164− icon = category_element.select_single('Card', title=app_name)
164+ icon = category_element.select_single('AbstractButton', title=app_name)
165165 # FIXME some categories need a long press in order to see the preview.
166166 # Some categories do not show previews, like recent apps.
167167 # --elopio - 2014-1-14
@@ -191,7 +191,7 @@ class DashApps(GenericScopeView):
191191
192192 """
193193 category_element = self._get_category_element(category)
194− application_cards = category_element.select_many('Card')
194+ application_cards = category_element.select_many('AbstractButton')
195195
196196 # sort by y, x
197197 application_cards = sorted(
@@ -201,8 +201,7 @@ class DashApps(GenericScopeView):
201201 result = []
202202 for card in application_cards:
203203 if card.objectName != 'cardToolCard':
204− card_header = card.select_single('CardHeader')
205− result.append(card_header.title)
204+ result.append(card.title)
206205 return result
207206
208207
tests/autopilot/unity8/shell/tests/test_emulators.py+1−1
@@ -196,7 +196,7 @@ class DashAppsEmulatorTestCase(DashBaseTestCase):
196196 category)
197197 grid = category_element.select_single('CardFilterGrid')
198198 filtergrid = grid.select_single('FilterGrid')
199− if (grid.filter):
199+ if (grid.filtered):
200200 return filtergrid.collapsedRowCount * filtergrid.columns
201201 else:
202202 return filtergrid.uncollapsedRowCount * filtergrid.columns
tests/autopilot/unity8/shell/tests/test_notifications.py+97−57
@@ -21,6 +21,7 @@
2121
2222from __future__ import absolute_import
2323
24+from unity8 import shell
2425from unity8.process_helpers import unlock_unity
2526from unity8.shell.tests import UnityTestCase, _get_device_emulation_scenarios
2627
@@ -64,7 +65,8 @@ class NotificationsBase(UnityTestCase):
6465 if os.path.abspath(__file__).startswith('/usr/'):
6566 return '/usr/share/unity8/graphics/' + icon_name
6667 else:
67− return os.path.dirname(__file__) + "/../../../../../qml/graphics/" + icon_name
68+ return os.path.dirname(__file__) + (
69+ "/../../../../../qml/graphics/" + icon_name)
6870
6971 def _get_notifications_list(self):
7072 return self.main_window.select_single(
@@ -209,6 +211,89 @@ class InteractiveNotificationBase(NotificationsBase):
209211 self.touch.tap_object(notification.select_single(objectName="button4"))
210212 self.assert_notification_action_id_was_called("action_decline_4")
211213
214+ def test_modal_sd_without_greeter (self):
215+ """A snap-decision on a phone should block input to shell beneath it when there's no greeter."""
216+ unity_proxy = self.launch_unity()
217+ unlock_unity(unity_proxy)
218+
219+ summary = "Incoming file"
220+ body = "Frank would like to send you the file: essay.pdf"
221+ icon_path = "sync-idle"
222+ hints = [
223+ ("x-canonical-snap-decisions", "true"),
224+ ("x-canonical-non-shaped-icon", "true"),
225+ ]
226+
227+ actions = [
228+ ('action_accept', 'Accept'),
229+ ('action_decline_1', 'Decline'),
230+ ]
231+
232+ self._create_interactive_notification(
233+ summary,
234+ body,
235+ icon_path,
236+ "NORMAL",
237+ actions,
238+ hints
239+ )
240+
241+ # verify that we cannot reveal the launcher (no longer interact with the shell)
242+ time.sleep(1)
243+ self.main_window.show_dash_swiping()
244+ launcher = self.main_window.get_launcher()
245+ self.assertThat(launcher.shown, Eventually(Equals(False)))
246+
247+ # verify and interact with the triggered snap-decision notification
248+ notify_list = self._get_notifications_list()
249+ get_notification = lambda: notify_list.wait_select_single(
250+ 'Notification', objectName='notification1')
251+ notification = get_notification()
252+ self._assert_notification(notification, summary, body, True, False, 1.0)
253+ self.touch.tap_object(notification.select_single(objectName="button0"))
254+ self.assert_notification_action_id_was_called("action_accept")
255+
256+ def test_modal_sd_with_greeter (self):
257+ """A snap-decision on a phone should not block input to the greeter beneath it."""
258+ unity_proxy = self.launch_unity()
259+
260+ summary = "Incoming file"
261+ body = "Frank would like to send you the file: essay.pdf"
262+ icon_path = "sync-idle"
263+ hints = [
264+ ("x-canonical-snap-decisions", "true"),
265+ ("x-canonical-non-shaped-icon", "true"),
266+ ]
267+
268+ actions = [
269+ ('action_accept', 'Accept'),
270+ ('action_decline_1', 'Decline'),
271+ ]
272+
273+ self._create_interactive_notification(
274+ summary,
275+ body,
276+ icon_path,
277+ "NORMAL",
278+ actions,
279+ hints
280+ )
281+
282+ # verify that we can swipe away the greeter (interact with the "shell")
283+ time.sleep(1)
284+ self.main_window.show_dash_swiping()
285+ greeter = self.main_window.get_greeter()
286+ self.assertThat(greeter.shown, Eventually(Equals(False)))
287+
288+ # verify and interact with the triggered snap-decision notification
289+ notify_list = self._get_notifications_list()
290+ get_notification = lambda: notify_list.wait_select_single(
291+ 'Notification', objectName='notification1')
292+ notification = get_notification()
293+ self._assert_notification(notification, summary, body, True, False, 1.0)
294+ self.touch.tap_object(notification.select_single(objectName="button0"))
295+ self.assert_notification_action_id_was_called("action_accept")
296+
212297 def _create_interactive_notification(
213298 self,
214299 summary="",
@@ -354,7 +439,7 @@ class EphemeralNotificationsTests(NotificationsBase):
354439 )
355440 ]
356441
357− notification = self._create_ephemeral_notification(
442+ notification = shell.create_ephemeral_notification(
358443 summary,
359444 body,
360445 icon_path,
@@ -391,7 +476,7 @@ class EphemeralNotificationsTests(NotificationsBase):
391476 )
392477 ]
393478
394− notification = self._create_ephemeral_notification(
479+ notification = shell.create_ephemeral_notification(
395480 summary,
396481 None,
397482 None,
@@ -433,7 +518,7 @@ class EphemeralNotificationsTests(NotificationsBase):
433518 body_critical = 'Dude, this is so urgent you have no idea :)'
434519 icon_path_critical = self._get_icon_path('avatars/anna_olsson.png')
435520
436− notification_normal = self._create_ephemeral_notification(
521+ notification_normal = shell.create_ephemeral_notification(
437522 summary_normal,
438523 body_normal,
439524 icon_path_normal,
@@ -441,7 +526,7 @@ class EphemeralNotificationsTests(NotificationsBase):
441526 )
442527 notification_normal.show()
443528
444− notification_low = self._create_ephemeral_notification(
529+ notification_low = shell.create_ephemeral_notification(
445530 summary_low,
446531 body_low,
447532 icon_path_low,
@@ -449,7 +534,7 @@ class EphemeralNotificationsTests(NotificationsBase):
449534 )
450535 notification_low.show()
451536
452− notification_critical = self._create_ephemeral_notification(
537+ notification_critical = shell.create_ephemeral_notification(
453538 summary_critical,
454539 body_critical,
455540 icon_path_critical,
@@ -510,7 +595,7 @@ class EphemeralNotificationsTests(NotificationsBase):
510595 summary = 'Summary-Body'
511596 body = 'This is a superfluous notification'
512597
513− notification = self._create_ephemeral_notification(summary, body)
598+ notification = shell.create_ephemeral_notification(summary, body)
514599 notification.show()
515600
516601 notification = notify_list.wait_select_single(
@@ -534,7 +619,7 @@ class EphemeralNotificationsTests(NotificationsBase):
534619
535620 summary = 'Summary-Only'
536621
537− notification = self._create_ephemeral_notification(summary)
622+ notification = shell.create_ephemeral_notification(summary)
538623 notification.show()
539624
540625 notification = notify_list.wait_select_single(
@@ -554,7 +639,7 @@ class EphemeralNotificationsTests(NotificationsBase):
554639 body = 'This is the original content of this notification-bubble.'
555640 icon_path = self._get_icon_path('avatars/funky.png')
556641
557− notification = self._create_ephemeral_notification(
642+ notification = shell.create_ephemeral_notification(
558643 summary,
559644 body,
560645 icon_path
@@ -594,7 +679,7 @@ class EphemeralNotificationsTests(NotificationsBase):
594679 icon_path = self._get_icon_path('avatars/anna_olsson.png')
595680 hint_icon = self._get_icon_path('applicationIcons/phone-app.png')
596681
597− notification = self._create_ephemeral_notification(
682+ notification = shell.create_ephemeral_notification(
598683 summary,
599684 body,
600685 icon_path
@@ -638,7 +723,7 @@ class EphemeralNotificationsTests(NotificationsBase):
638723 body = 'Hey Bro Coly!'
639724 icon_path = self._get_icon_path('avatars/amanda.png')
640725 body_sum = body
641− notification = self._create_ephemeral_notification(
726+ notification = shell.create_ephemeral_notification(
642727 summary,
643728 body,
644729 icon_path,
@@ -674,7 +759,7 @@ class EphemeralNotificationsTests(NotificationsBase):
674759 for new_body in bodies:
675760 body = new_body
676761 body_sum += '\n' + body
677− notification = self._create_ephemeral_notification(
762+ notification = shell.create_ephemeral_notification(
678763 summary,
679764 body,
680765 icon_path,
@@ -695,48 +780,3 @@ class EphemeralNotificationsTests(NotificationsBase):
695780 False,
696781 1.0
697782 )
698−
699− def _create_ephemeral_notification(
700− self,
701− summary="",
702− body="",
703− icon=None,
704− hints=[],
705− urgency="NORMAL"
706− ):
707− """Create an ephemeral (non-interactive) notification
708−
709− :param summary: Summary text for the notification
710− :param body: Body text to display in the notification
711− :param icon: Path string to the icon to use
712− :param hint_strings: List of tuples containing the 'name' and value
713− for setting the hint strings for the notification
714− :param urgency: Urgency string for the noticiation, either: 'LOW',
715− 'NORMAL', 'CRITICAL'
716−
717− """
718− logger.info(
719− "Creating ephemeral: summary(%s), body(%s), urgency(%r) "
720− "and Icon(%s)",
721− summary,
722− body,
723− urgency,
724− icon
725− )
726−
727− n = Notify.Notification.new(summary, body, icon)
728−
729− for hint in hints:
730− key, value = hint
731− n.set_hint_string(key, value)
732− logger.info("Adding hint to notification: (%s, %s)", key, value)
733− n.set_urgency(self._get_urgency(urgency))
734−
735− return n
736−
737− def _get_urgency(self, urgency):
738− """Translates urgency string to enum."""
739− _urgency_enums = {'LOW': Notify.Urgency.LOW,
740− 'NORMAL': Notify.Urgency.NORMAL,
741− 'CRITICAL': Notify.Urgency.CRITICAL}
742− return _urgency_enums.get(urgency.upper())
tests/autopilot/unity8/shell/tests/test_upstart.py+2−2
@@ -82,7 +82,7 @@ class UpstartIntegrationTests(UnityTestCase):
8282 ))
8383
8484 def test_no_sigstop(self):
85− self.patch_environment("UPSTART_JOB", "foo")
85+ self.patch_environment("UNITY_MIR_EMITS_SIGSTOP", "")
8686 self._launch_unity()
8787 self._set_proxy()
8888
@@ -91,7 +91,7 @@ class UpstartIntegrationTests(UnityTestCase):
9191 logger.debug("Unity loaded and ready.")
9292
9393 def test_expect_sigstop(self):
94− self.patch_environment("UPSTART_JOB", "unity8")
94+ self.patch_environment("UNITY_MIR_EMITS_SIGSTOP", "1")
9595 self._launch_unity()
9696 self.assertThat(lambda: os.WIFSTOPPED(self._get_status()), Eventually(Equals(True)), "Unity8 should raise SIGSTOP when ready")
9797
tests/mocks/AccountsService/CMakeLists.txt+1−12
@@ -7,15 +7,4 @@ add_library(MockAccountsService-qml MODULE
77
88qt5_use_modules(MockAccountsService-qml DBus Qml)
99
10−# copy files into build directory for shadow builds
11−file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/qmldir"
12− DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
13− )
14−
15−install(TARGETS MockAccountsService-qml
16− DESTINATION ${SHELL_INSTALL_QML}/mocks/AccountsService
17− )
18−
19−install(FILES qmldir
20− DESTINATION ${SHELL_INSTALL_QML}/mocks/AccountsService
21− )
10+add_unity8_mock(AccountsService 0.1 AccountsService TARGETS MockAccountsService-qml)
tests/mocks/AccountsService/qmldir+1
@@ -1,2 +1,3 @@
11module AccountsService
22plugin MockAccountsService-qml
3+typeinfo AccountsService.qmltypes
tests/mocks/CMakeLists.txt+30
@@ -1,3 +1,33 @@
1+include(QmlPlugins)
2+
3+# Set up and optionally install a mock plugin for unity8.
4+#
5+# add_unity8_mock(plugin version path
6+# [PREFIX string] # Install the plugin to the specified prefix under unity8 private plugin directory
7+# [...] # See export_qmlfiles and export_qmlplugin documentation for more options
8+# )
9+
10+macro(add_unity8_mock PLUGIN VERSION PATH)
11+ set(single PREFIX)
12+ cmake_parse_arguments(MOCK "" "${single}" "" ${ARGN})
13+
14+ if(MOCK_PREFIX)
15+ export_qmlfiles(${PLUGIN} ${PATH}
16+ DESTINATION ${SHELL_INSTALL_QML}/${MOCK_PREFIX}
17+ TARGET_PREFIX ${MOCK_PREFIX}-Mock
18+ ${MOCK_UNPARSED_ARGUMENTS}
19+ )
20+ export_qmlplugin(${PLUGIN} ${VERSION} ${PATH}
21+ DESTINATION ${SHELL_INSTALL_QML}/${MOCK_PREFIX}
22+ TARGET_PREFIX ${MOCK_PREFIX}-Mock
23+ ${MOCK_UNPARSED_ARGUMENTS}
24+ )
25+ else()
26+ export_qmlfiles(${PLUGIN} ${PATH} TARGET_PREFIX Mock ${MOCK_UNPARSED_ARGUMENTS})
27+ export_qmlplugin(${PLUGIN} ${VERSION} ${PATH} TARGET_PREFIX Mock ${MOCK_UNPARSED_ARGUMENTS})
28+ endif()
29+endmacro()
30+
131add_subdirectory(AccountsService)
232add_subdirectory(GSettings.1.0)
333add_subdirectory(HudClient)
tests/mocks/GSettings.1.0/CMakeLists.txt+1−4
@@ -17,7 +17,4 @@ target_link_libraries(FakeGSettingsQml
1717
1818qt5_use_modules(FakeGSettingsQml Qml)
1919
20−# copy qmldir file into build directory for shadow builds
21−file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/qmldir"
22− DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
23− )
20+add_unity8_mock(GSettings 1.0 GSettings.1.0 TARGETS FakeGSettingsQml)
tests/mocks/GSettings.1.0/qmldir+1
@@ -1,2 +1,3 @@
11module GSettings
22plugin FakeGSettingsQml
3+typeinfo GSettings.qmltypes
tests/mocks/HudClient/CMakeLists.txt+1−4
@@ -35,7 +35,4 @@ target_link_libraries(FakeHudClientQml
3535
3636qt5_use_modules(FakeHudClientQml Qml)
3737
38−# copy qmldir file into build directory for shadow builds
39−file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/qmldir"
40− DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
41− )
38+add_unity8_mock(HudClient 0.1 HudClient TARGETS FakeHudClientQml)
tests/mocks/HudClient/qmldir+2
@@ -1 +1,3 @@
1+module HudClient
12plugin FakeHudClientQml
3+typeinfo HudClient.qmltypes
tests/mocks/LightDM/CMakeLists.txt+5−12
@@ -43,15 +43,8 @@ target_link_libraries(MockLightDM-qml
4343
4444qt5_use_modules(MockLightDM-qml DBus Gui Qml)
4545
46−# copy qmldir file into build directory for shadow builds
47−file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/qmldir"
48− DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
49− )
50−
51−install(TARGETS MockLightDM-qml
52− DESTINATION ${SHELL_INSTALL_QML}/mocks/LightDM
53− )
54−
55−install(FILES qmldir
56− DESTINATION ${SHELL_INSTALL_QML}/mocks/LightDM
57− )
46+add_unity8_mock(LightDM 0.1 LightDM
47+ PREFIX mocks
48+ TARGETS MockLightDM-qml
49+ ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_CURRENT_BINARY_DIR}/full"
50+)
tests/mocks/LightDM/qmldir+1
@@ -1,2 +1,3 @@
11module LightDM
22plugin MockLightDM-qml
3+typeinfo LightDM.qmltypes
tests/mocks/Powerd/CMakeLists.txt+1−12
@@ -7,15 +7,4 @@ add_library(MockPowerd-qml MODULE
77
88qt5_use_modules(MockPowerd-qml Qml)
99
10−# copy qmldir file into build directory for shadow builds
11−file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/qmldir"
12− DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
13− )
14−
15−install(TARGETS MockPowerd-qml
16− DESTINATION ${SHELL_INSTALL_QML}/mocks/Powerd
17− )
18−
19−install(FILES qmldir
20− DESTINATION ${SHELL_INSTALL_QML}/mocks/Powerd
21− )
10+add_unity8_mock(Powerd 0.1 Powerd TARGETS MockPowerd-qml)
tests/mocks/Powerd/qmldir+1
@@ -1,2 +1,3 @@
11module Powerd
22plugin MockPowerd-qml
3+typeinfo Powerd.qmltypes
tests/mocks/QMenuModel/CMakeLists.txt+2−12
@@ -1,15 +1,3 @@
1−file(GLOB QMLFILES
2− *.qml
3− *.js
4− qmldir
5−)
6−
7−# copy files into build directory for shadow builds
8−add_custom_target(QMenuModelQmlFiles ALL
9− COMMAND cp ${QMLFILES} ${CMAKE_CURRENT_BINARY_DIR}
10− DEPENDS ${QMLFILES}
11−)
12−
131include_directories(
142 ${Qt5Core_INCLUDE_DIRS}
153 ${Qt5Quick_INCLUDE_DIRS}
@@ -32,3 +20,5 @@ qt5_use_modules(QMenuModelQml Core Quick)
3220set_target_properties(QMenuModelQml PROPERTIES
3321 OUTPUT_NAME qmenumodel
3422 VERSION 0)
23+
24+add_unity8_mock(QMenuModel 0.1 QMenuModel TARGETS QMenuModelQml)
tests/mocks/QMenuModel/qmldir+1
@@ -1,5 +1,6 @@
11module QMenuModel
22plugin qmenumodel
3+typeinfo QMenuModel.qmltypes
34
45QDBusActionGroup 0.1 QDBusActionGroup.qml
56UnityMenuAction 0.1 UnityMenuAction.qml
tests/mocks/QtMultimedia/CMakeLists.txt+1−12
@@ -5,15 +5,4 @@ add_library(QtMultimedia-qml MODULE
55
66qt5_use_modules(QtMultimedia-qml Qml)
77
8−# copy qmldir file into build directory for shadow builds
9−file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/qmldir"
10− DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
11− )
12−
13−install(TARGETS QtMultimedia-qml
14− DESTINATION ${SHELL_INSTALL_QML}/mocks/QtMultimedia
15− )
16−
17−install(FILES qmldir
18− DESTINATION ${SHELL_INSTALL_QML}/mocks/QtMultimedia
19− )
8+add_unity8_mock(QtMultimedia 5.0 QtMultimedia TARGETS QtMultimedia-qml)
tests/mocks/QtMultimedia/qmldir+1
@@ -1,2 +1,3 @@
11module QtMultimedia
22plugin QtMultimedia-qml
3+typeinfo QtMultimedia.qmltypes
tests/mocks/Ubuntu/DownloadDaemonListener/CMakeLists.txt+1−9
@@ -7,12 +7,4 @@ add_library(FakeUbuntuDownloadDaemonListenerQml MODULE ${FakeUbuntuDownloadDaemo
77
88qt5_use_modules(FakeUbuntuDownloadDaemonListenerQml Core Quick)
99
10−# copy files into build directory for shadow builds
11−add_custom_target(UbuntuDownloadQmlDirFile ALL
12− COMMAND cp "${CMAKE_CURRENT_SOURCE_DIR}/qmldir" ${CMAKE_CURRENT_BINARY_DIR}
13− DEPENDS qmldir
14−)
15−
16−install(TARGETS FakeUbuntuDownloadDaemonListenerQml
17− DESTINATION ${SHELL_INSTALL_QML}/mocks/Ubuntu/DownloadDaemonListener
18− )
10+add_unity8_mock(Ubuntu.DownloadDaemonListener 0.1 Ubuntu/DownloadDaemonListener TARGETS FakeUbuntuDownloadDaemonListenerQml)
tests/mocks/Ubuntu/DownloadDaemonListener/qmldir+1
@@ -1,2 +1,3 @@
11module Ubuntu.DownloadDaemonListener
22plugin FakeUbuntuDownloadDaemonListenerQml
3+typeinfo DownloadDaemonListener.qmltypes
tests/mocks/Ubuntu/Thumbnailer/CMakeLists.txt+1−7
@@ -1,7 +1 @@
1−# copy files into build directory for shadow builds
2−add_custom_target(UbuntuThumbnailerQmlDirFile ALL
3− COMMAND cp "${CMAKE_CURRENT_SOURCE_DIR}/qmldir" ${CMAKE_CURRENT_BINARY_DIR}
4− DEPENDS qmldir
5−)
6−
7−install(FILES qmldir DESTINATION ${SHELL_INSTALL_QML}/mocks/Ubuntu/Thumbnailer)
1+add_unity8_mock(Ubuntu.Thumbnailer 0.1 Ubuntu/Thumbnailer)
tests/mocks/Ubuntu/Thumbnailer/qmldir+2
@@ -1,2 +1,4 @@
11module Ubuntu.Thumbnailer
2+typeinfo Thumbnailer.qmltypes
3+
24Dummy 0.1 Dummy.qml
tests/mocks/Unity/Application/CMakeLists.txt+9−35
@@ -12,40 +12,14 @@ set(FakeUnityApplicationQml_SOURCES
1212
1313add_library(FakeUnityApplicationQml MODULE ${FakeUnityApplicationQml_SOURCES})
1414
15−qt5_use_modules(FakeUnityApplicationQml Core Quick)
16−
17−# copy files into build directory for shadow builds
18−add_custom_target(UnityAppQmlDirFile ALL
19− COMMAND cp "${CMAKE_CURRENT_SOURCE_DIR}/qmldir" ${CMAKE_CURRENT_BINARY_DIR}
20− DEPENDS qmldir
21−)
22−add_custom_target(InputFilterAreaQmlFile ALL
23− COMMAND cp "${CMAKE_CURRENT_SOURCE_DIR}/InputFilterArea.qml" ${CMAKE_CURRENT_BINARY_DIR}
24− DEPENDS InputFilterArea.qml
25−)
26−add_custom_target(OSKControllerQmlFile ALL
27− COMMAND cp "${CMAKE_CURRENT_SOURCE_DIR}/OSKController.qml" ${CMAKE_CURRENT_BINARY_DIR}
28− DEPENDS OSKController.qml
29−)
15+add_library(NonMirUnityApplicationQml MODULE ${FakeUnityApplicationQml_SOURCES})
16+set_target_properties(NonMirUnityApplicationQml PROPERTIES OUTPUT_NAME FakeUnityApplicationQml)
3017
31−install(TARGETS FakeUnityApplicationQml
32− DESTINATION ${SHELL_INSTALL_QML}/mocks/Unity/Application
33− )
34−
35−install(FILES qmldir InputFilterArea.qml OSKController.qml
36− DESTINATION ${SHELL_INSTALL_QML}/mocks/Unity/Application
37− )
38−
39−# Duplicate the mock to nonmirplugins
40−# In shadow builds we just link it, in real installs we also install it to the other path
41−add_custom_target(OSKControllerQmlFile2 ALL
42− COMMAND mkdir -p ${CMAKE_BINARY_DIR}/nonmirplugins/Unity && rm -f ${CMAKE_BINARY_DIR}/nonmirplugins/Unity/Application && ln -s ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_BINARY_DIR}/nonmirplugins/Unity
43− DEPENDS qmldir
44−)
45−install(TARGETS FakeUnityApplicationQml
46− DESTINATION ${SHELL_INSTALL_QML}/nonmirplugins/Unity/Application
47− )
18+qt5_use_modules(FakeUnityApplicationQml Core Quick)
19+qt5_use_modules(NonMirUnityApplicationQml Core Quick)
4820
49−install(FILES qmldir InputFilterArea.qml OSKController.qml
50− DESTINATION ${SHELL_INSTALL_QML}/nonmirplugins/Unity/Application
51− )
21+add_unity8_mock(Unity.Application 0.1 Unity/Application PREFIX mocks TARGETS FakeUnityApplicationQml)
22+add_unity8_mock(Unity.Application 0.1 Unity/Application
23+ PREFIX nonmirplugins
24+ TARGETS NonMirUnityApplicationQml
25+ BINARY_DIR ${CMAKE_BINARY_DIR}/nonmirplugins)
tests/mocks/Unity/Application/qmldir+2
@@ -1,4 +1,6 @@
11module Unity.Application
22plugin FakeUnityApplicationQml
3+typeinfo Application.qmltypes
4+
35InputFilterArea 0.1 InputFilterArea.qml
46OSKController 0.1 OSKController.qml
tests/mocks/Unity/CMakeLists.txt+9−12
@@ -6,6 +6,7 @@ add_subdirectory(Notifications)
66pkg_search_module(DEE dee-1.0 REQUIRED)
77pkg_search_module(GOBJECT gobject-2.0 REQUIRED)
88pkg_search_module(DEEQT libdee-qt5 REQUIRED)
9+pkg_check_modules(SCOPES_API REQUIRED unity-shell-scopes=1)
910
1011include_directories(
1112 ${CMAKE_CURRENT_BINARY_DIR}
@@ -27,6 +28,13 @@ set(UnityQML_SOURCES
2728 fake_previewstack.cpp
2829 fake_previewwidgetmodel.cpp
2930 fake_unity_plugin.cpp
31+ ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/CategoriesInterface.h
32+ ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/PreviewModelInterface.h
33+ ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/PreviewStackInterface.h
34+ ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/PreviewWidgetModelInterface.h
35+ ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/ResultsModelInterface.h
36+ ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/ScopeInterface.h
37+ ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/ScopesInterface.h
3038)
3139
3240add_library(FakeUnityQml MODULE ${UnityQML_SOURCES})
@@ -39,15 +47,4 @@ target_link_libraries(FakeUnityQml
3947
4048qt5_use_modules(FakeUnityQml Qml)
4149
42−# copy qmldir file into build directory for shadow builds
43−file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/qmldir"
44− DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
45− )
46−
47−install(TARGETS FakeUnityQml
48− DESTINATION ${SHELL_INSTALL_QML}/scopefakes/Unity
49− )
50−
51−install(FILES qmldir
52− DESTINATION ${SHELL_INSTALL_QML}/scopefakes/Unity
53− )
50+add_unity8_mock(Unity 0.2 Unity PREFIX scopefakes TARGETS FakeUnityQml)
tests/mocks/Unity/Indicators/CMakeLists.txt+1−14
@@ -37,17 +37,4 @@ target_link_libraries(IndicatorsFakeQml)
3737
3838qt5_use_modules(IndicatorsFakeQml Core Qml Quick)
3939
40−file(GLOB IndicatorsFake_QMLFILES
41− *.qml
42− qml/FakeMenuPage.qml
43−)
44−
45−# copy qmldir file into build directory for shadow builds
46−file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/qmldir"
47− DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
48−)
49−
50−# copy qmldir file into build directory for shadow builds
51−file(COPY ${IndicatorsFake_QMLFILES}
52− DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
53−)
40+add_unity8_mock(Unity.Indicators 0.1 Unity/Indicators TARGETS IndicatorsFakeQml)
tests/mocks/Unity/Indicators/qml/FakeMenuPage.qml → tests/mocks/Unity/Indicators/FakeMenuPage.qmlrenamed

The content is the same.

tests/mocks/Unity/Indicators/qmldir+1
@@ -1,5 +1,6 @@
11module Unity.Indicators
22plugin IndicatorsFakeQml
3+typeinfo Indicators.qmltypes
34
45CachedUnityMenuModel 0.1 CachedUnityMenuModel.qml
56IndicatorBase 0.1 IndicatorBase.qml
tests/mocks/Unity/Launcher/CMakeLists.txt+1−5
@@ -20,8 +20,4 @@ add_library(MockLauncherPlugin MODULE ${MockLauncherModel_SOURCES})
2020
2121qt5_use_modules(MockLauncherPlugin Core Quick)
2222
23−# copy files into build directory for shadow builds
24−add_custom_target(LauncherPluginQmlDirFile ALL
25− COMMAND cp "${CMAKE_CURRENT_SOURCE_DIR}/qmldir" ${CMAKE_CURRENT_BINARY_DIR}
26− DEPENDS qmldir
27−)
23+add_unity8_mock(Unity.Launcher 0.1 Unity/Launcher TARGETS MockLauncherPlugin)
tests/mocks/Unity/Launcher/qmldir+1
@@ -1,2 +1,3 @@
11module Unity.Launcher
22plugin MockLauncherPlugin
3+typeinfo Launcher.qmltypes
tests/mocks/Unity/Notifications/CMakeLists.txt+1−11
@@ -1,11 +1 @@
1−file(GLOB QMLFILES
2− *.qml
3− *.js
4− qmldir
5−)
6−
7−# copy files into build directory for shadow builds
8−add_custom_target(NotificationsQmlFiles ALL
9− COMMAND cp ${QMLFILES} ${CMAKE_CURRENT_BINARY_DIR}
10− DEPENDS ${QMLFILES}
11−)
1+add_unity8_mock(Unity.Notifications 1.0 Unity/Notifications)
tests/mocks/Unity/Notifications/qmldir+1
@@ -1,2 +1,3 @@
11module Unity.Notifications
22Notification 1.0 notification.js
3+typeinfo Notifications.qmltypes
tests/mocks/Unity/fake_categories.cpp+21−24
@@ -22,24 +22,9 @@
2222#include "fake_resultsmodel.h"
2323
2424Categories::Categories(int category_count, QObject* parent)
25− : QAbstractListModel(parent)
25+ : unity::shell::scopes::CategoriesInterface(parent)
2626 , m_category_count(category_count)
2727{
28− m_roles[Categories::RoleCategoryId] = "categoryId";
29− m_roles[Categories::RoleName] = "name";
30− m_roles[Categories::RoleIcon] = "icon";
31− m_roles[Categories::RoleRawRendererTemplate] = "rawRendererTemplate";
32− m_roles[Categories::RoleRenderer] = "renderer";
33− m_roles[Categories::RoleComponents] = "components";
34− m_roles[Categories::RoleProgressSource] = "progressSource";
35− m_roles[Categories::RoleResults] = "results";
36− m_roles[Categories::RoleCount] = "count";
37−}
38−
39−QHash<int, QByteArray>
40−Categories::roleNames() const
41−{
42− return m_roles;
4328}
4429
4530int Categories::rowCount(const QModelIndex& /*parent*/) const
@@ -65,6 +50,11 @@ void Categories::addSpecialCategory(QString const& categoryId, QString const& na
6550 }
6651}
6752
53+bool Categories::overrideCategoryJson(QString const& categoryId, QString const& json)
54+{
55+ qFatal("Using un-implemented Categories::overrideCategoryJson");
56+}
57+
6858void Categories::countChanged()
6959{
7060 QObject* countObject = sender();
@@ -108,7 +98,12 @@ Categories::data(const QModelIndex& index, int role) const
10898 case RoleRenderer:
10999 {
110100 QVariantMap map;
111− map["category-layout"] = index.row() % 2 == 0 ? "grid" : "carousel";
101+ if (index.row() % 2 == 0) {
102+ map["category-layout"] = "grid";
103+ } else {
104+ map["category-layout"] = "carousel";
105+ map["overlay"] = true;
106+ }
112107 map["card-size"] = "small";
113108 return map;
114109 }
@@ -121,9 +116,6 @@ Categories::data(const QModelIndex& index, int role) const
121116 map["title"] = "HOLA";
122117 return map;
123118 }
124− case RoleProgressSource:
125− qFatal("Using un-implemented RoleProgressSource Categories role");
126− return QVariant();
127119 case RoleResults:
128120 return QVariant();
129121 case RoleCount:
@@ -146,7 +138,14 @@ Categories::data(const QModelIndex& index, int role) const
146138 case RoleRenderer:
147139 {
148140 QVariantMap map;
149− map["category-layout"] = index.row() % 2 == 0 ? "grid" : "carousel";
141+ if (index.row() % 2 == 0) {
142+ map["category-layout"] = "grid";
143+ } else {
144+ map["category-layout"] = "carousel";
145+ map["card-size"] = "medium";
146+ map["collapsed-rows"] = 2;
147+ map["overlay"] = true;
148+ }
150149 map["card-size"] = "small";
151150 return map;
152151 }
@@ -157,11 +156,9 @@ Categories::data(const QModelIndex& index, int role) const
157156 artMap["field"] = "art";
158157 map["art"] = artMap;
159158 map["title"] = "HOLA";
159+ map["subtitle"] = "HOLA";
160160 return map;
161161 }
162− case RoleProgressSource:
163− qFatal("Using un-implemented RoleProgressSource Categories role");
164− return QVariant();
165162 case RoleResults:
166163 return QVariant::fromValue(resultsModel);
167164 case RoleCount:
tests/mocks/Unity/fake_categories.h+5−18
@@ -17,44 +17,31 @@
1717#ifndef FAKE_CATEGORIES_H
1818#define FAKE_CATEGORIES_H
1919
20+#include <unity/shell/scopes/CategoriesInterface.h>
21+
2022// Qt
21−#include <QAbstractListModel>
2223#include <QList>
2324
2425class ResultsModel;
2526
26−class Categories : public QAbstractListModel
27+class Categories : public unity::shell::scopes::CategoriesInterface
2728{
2829 Q_OBJECT
2930
30− Q_ENUMS(Roles)
31−
3231public:
3332 Categories(int category_count, QObject* parent = 0);
34− enum Roles {
35− RoleCategoryId,
36− RoleName,
37− RoleIcon,
38− RoleRawRendererTemplate,
39− RoleRenderer,
40− RoleComponents,
41− RoleProgressSource, // maybe
42− RoleResults,
43− RoleCount
44− };
4533
4634 QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
47− QHash<int, QByteArray> roleNames() const override;
4835 int rowCount(const QModelIndex& parent = QModelIndex()) const override;
4936
50− Q_INVOKABLE void addSpecialCategory(QString const& categoryId, QString const& name, QString const& icon, QString const& rawTemplate, QObject* countObject);
37+ Q_INVOKABLE void addSpecialCategory(QString const& categoryId, QString const& name, QString const& icon, QString const& rawTemplate, QObject* countObject) override;
38+ Q_INVOKABLE bool overrideCategoryJson(QString const& categoryId, QString const& json) override;
5139
5240private Q_SLOTS:
5341 void countChanged();
5442
5543private:
5644 mutable QHash<int, ResultsModel*> m_resultsModels;
57− QHash<int, QByteArray> m_roles;
5845 int m_category_count;
5946
6047 struct CategoryData {
tests/mocks/Unity/fake_previewmodel.cpp+2−15
@@ -27,22 +27,14 @@
2727// Qt
2828#include <QDebug>
2929
30−PreviewModel::PreviewModel(QObject* parent) : QAbstractListModel(parent)
30+PreviewModel::PreviewModel(QObject* parent)
31+ : unity::shell::scopes::PreviewModelInterface(parent)
3132{
3233 // we have one column by default
3334 PreviewWidgetModel* columnModel = new PreviewWidgetModel(this);
3435 m_previewWidgetModels.append(columnModel);
3536}
3637
37−QHash<int, QByteArray> PreviewModel::roleNames() const
38−{
39− QHash<int, QByteArray> roles;
40−
41− roles[Roles::RoleColumnModel] = "columnModel";
42−
43− return roles;
44−}
45−
4638void PreviewModel::setWidgetColumnCount(int count)
4739{
4840 if (count != 1) {
@@ -65,11 +57,6 @@ bool PreviewModel::processingAction() const
6557 return false;
6658}
6759
68−void PreviewModel::setProcessingAction(bool /*processing*/)
69−{
70− qFatal("PreviewModel::setProcessingAction not implemented");
71−}
72−
7360int PreviewModel::rowCount(const QModelIndex&) const
7461{
7562 return m_previewWidgetModels.size();
tests/mocks/Unity/fake_previewmodel.h+7−25
@@ -18,47 +18,29 @@
1818#ifndef FAKE_PREVIEWMODEL_H
1919#define FAKE_PREVIEWMODEL_H
2020
21−#include <QAbstractListModel>
21+#include <unity/shell/scopes/PreviewModelInterface.h>
22+
2223#include <QSharedPointer>
2324#include <QVariantMap>
2425
2526class PreviewWidgetModel;
2627
27−class PreviewModel : public QAbstractListModel
28+class PreviewModel : public unity::shell::scopes::PreviewModelInterface
2829{
2930 Q_OBJECT
3031
31− Q_ENUMS(Roles)
32−
33− Q_PROPERTY(int widgetColumnCount READ widgetColumnCount WRITE setWidgetColumnCount NOTIFY widgetColumnCountChanged)
34− Q_PROPERTY(bool loaded READ loaded NOTIFY loadedChanged)
35− Q_PROPERTY(bool processingAction READ processingAction NOTIFY processingActionChanged)
36−
3732public:
3833 explicit PreviewModel(QObject* parent = 0);
3934
40− enum Roles {
41− RoleColumnModel
42− };
43−
4435 QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
45− QHash<int, QByteArray> roleNames() const override;
4636 int rowCount(const QModelIndex& parent = QModelIndex()) const override;
4737
48− void setWidgetColumnCount(int count);
49− int widgetColumnCount() const;
50− bool loaded() const;
51− bool processingAction() const;
52− void setProcessingAction(bool processing);
53−
54−Q_SIGNALS:
55− void widgetColumnCountChanged();
56− void loadedChanged();
57− void processingActionChanged();
58− void triggered(QString const&, QString const&, QVariantMap const&);
38+ void setWidgetColumnCount(int count) override;
39+ int widgetColumnCount() const override;
40+ bool loaded() const override;
41+ bool processingAction() const override;
5942
6043private:
61− QHash<int, QByteArray> m_roles;
6244 QList<PreviewWidgetModel*> m_previewWidgetModels;
6345};
6446
tests/mocks/Unity/fake_previewstack.cpp+3−11
@@ -21,7 +21,8 @@
2121#include "fake_previewmodel.h"
2222#include "fake_scope.h"
2323
24−PreviewStack::PreviewStack(QObject* parent) : QAbstractListModel(parent)
24+PreviewStack::PreviewStack(QObject* parent)
25+ : unity::shell::scopes::PreviewStackInterface(parent)
2526{
2627 m_previews << new PreviewModel(this);
2728}
@@ -30,15 +31,6 @@ PreviewStack::~PreviewStack()
3031{
3132}
3233
33−QHash<int, QByteArray> PreviewStack::roleNames() const
34−{
35− QHash<int, QByteArray> roles;
36−
37− roles[Roles::RolePreviewModel] = "previewModel";
38−
39− return roles;
40−}
41−
4234void PreviewStack::setWidgetColumnCount(int columnCount)
4335{
4436 if (columnCount != 1) {
@@ -56,7 +48,7 @@ int PreviewStack::rowCount(const QModelIndex&) const
5648 return m_previews.size();
5749}
5850
59−PreviewModel* PreviewStack::get(int index) const
51+unity::shell::scopes::PreviewModelInterface* PreviewStack::getPreviewModel(int index) const
6052{
6153 if (index >= m_previews.size()) {
6254 return nullptr;
tests/mocks/Unity/fake_previewstack.h+6−17
@@ -18,39 +18,28 @@
1818#ifndef FAKE_PREVIEWSTACK_H
1919#define FAKE_PREVIEWSTACK_H
2020
21−#include <QAbstractListModel>
21+#include <unity/shell/scopes/PreviewStackInterface.h>
22+
2223#include <QSharedPointer>
2324#include <QVariantMap>
2425
2526class PreviewModel;
2627
27−class PreviewStack : public QAbstractListModel
28+class PreviewStack : public unity::shell::scopes::PreviewStackInterface
2829{
2930 Q_OBJECT
3031
31− Q_ENUMS(Roles)
32−
33− Q_PROPERTY(int widgetColumnCount READ widgetColumnCount WRITE setWidgetColumnCount NOTIFY widgetColumnCountChanged)
34−
3532public:
3633 explicit PreviewStack(QObject* parent = 0);
3734 virtual ~PreviewStack();
3835
39− enum Roles {
40− RolePreviewModel
41− };
42−
4336 QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
44− QHash<int, QByteArray> roleNames() const override;
4537 int rowCount(const QModelIndex& parent = QModelIndex()) const override;
4638
47− Q_INVOKABLE PreviewModel* get(int index) const;
48−
49− void setWidgetColumnCount(int columnCount);
50− int widgetColumnCount() const;
39+ Q_INVOKABLE unity::shell::scopes::PreviewModelInterface* getPreviewModel(int index) const override;
5140
52−Q_SIGNALS:
53− void widgetColumnCountChanged();
41+ void setWidgetColumnCount(int columnCount) override;
42+ int widgetColumnCount() const override;
5443
5544private:
5645 QList<PreviewModel*> m_previews;
tests/mocks/Unity/fake_previewwidgetmodel.cpp+2−10
@@ -35,12 +35,9 @@ struct PreviewData
3535 }
3636};
3737
38−PreviewWidgetModel::PreviewWidgetModel(QObject* parent) : QAbstractListModel(parent)
38+PreviewWidgetModel::PreviewWidgetModel(QObject* parent)
39+ : unity::shell::scopes::PreviewWidgetModelInterface(parent)
3940{
40− m_roles[Roles::RoleWidgetId] = "widgetId";
41− m_roles[Roles::RoleType] = "type";
42− m_roles[Roles::RoleProperties] = "properties";
43−
4441 populateWidgets();
4542}
4643
@@ -60,11 +57,6 @@ void PreviewWidgetModel::populateWidgets()
6057
6158}
6259
63−QHash<int, QByteArray> PreviewWidgetModel::roleNames() const
64−{
65− return m_roles;
66−}
67−
6860int PreviewWidgetModel::rowCount(const QModelIndex&) const
6961{
7062 return m_previewWidgets.size();
tests/mocks/Unity/fake_previewwidgetmodel.h+3−12
@@ -18,33 +18,24 @@
1818#ifndef FAKE_PREVIEWWIDGETMODEL_H
1919#define FAKE_PREVIEWWIDGETMODEL_H
2020
21−#include <QAbstractListModel>
21+#include <unity/shell/scopes/PreviewWidgetModelInterface.h>
22+
2223#include <QSharedPointer>
2324#include <QVariantMap>
2425
2526class PreviewData;
2627
27−class PreviewWidgetModel : public QAbstractListModel
28+class PreviewWidgetModel : public unity::shell::scopes::PreviewWidgetModelInterface
2829{
2930 Q_OBJECT
3031
31− Q_ENUMS(Roles)
32−
3332public:
3433 explicit PreviewWidgetModel(QObject* parent = 0);
3534
36− enum Roles {
37− RoleWidgetId,
38− RoleType,
39− RoleProperties
40− };
41−
4235 QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
43− QHash<int, QByteArray> roleNames() const override;
4436 int rowCount(const QModelIndex& parent = QModelIndex()) const override;
4537
4638private:
47− QHash<int, QByteArray> m_roles;
4839 QList<QSharedPointer<PreviewData>> m_previewWidgets;
4940
5041 void populateWidgets();
tests/mocks/Unity/fake_resultsmodel.cpp+2−44
@@ -23,25 +23,10 @@
2323#include <paths.h>
2424
2525ResultsModel::ResultsModel(int result_count, int categoryId, QObject* parent)
26− : QAbstractListModel(parent)
26+ : unity::shell::scopes::ResultsModelInterface(parent)
2727 , m_result_count(result_count)
2828 , m_categoryId(categoryId)
2929{
30− m_roles[ResultsModel::RoleUri] = "uri";
31− m_roles[ResultsModel::RoleCategoryId] = "categoryId";
32− m_roles[ResultsModel::RoleDndUri] = "dndUri";
33− m_roles[ResultsModel::RoleResult] = "result";
34− m_roles[ResultsModel::RoleTitle] = "title";
35− m_roles[ResultsModel::RoleArt] = "art";
36− m_roles[ResultsModel::RoleSubtitle] = "subtitle";
37− m_roles[ResultsModel::RoleMascot] = "mascot";
38− m_roles[ResultsModel::RoleEmblem] = "emblem";
39− m_roles[ResultsModel::RoleOldPrice] = "oldPrice";
40− m_roles[ResultsModel::RolePrice] = "price";
41− m_roles[ResultsModel::RoleAltPrice] = "altPrice";
42− m_roles[ResultsModel::RoleRating] = "rating";
43− m_roles[ResultsModel::RoleAltRating] = "altRating";
44− m_roles[ResultsModel::RoleSummary] = "summary";
4530}
4631
4732QString ResultsModel::categoryId() const
@@ -54,12 +39,6 @@ void ResultsModel::setCategoryId(QString const& /*id*/)
5439 qFatal("Calling un-implemented ResultsModel::setCategoryId");
5540}
5641
57−QHash<int, QByteArray>
58−ResultsModel::roleNames() const
59−{
60− return m_roles;
61−}
62−
6342int ResultsModel::rowCount(const QModelIndex& parent) const
6443{
6544 Q_UNUSED(parent);
@@ -72,23 +51,6 @@ int ResultsModel::count() const
7251 return rowCount();
7352}
7453
75−QVariant ResultsModel::get(int row) const
76−{
77− if (row >= m_result_count || row < 0) return QVariantMap();
78−
79− QVariantMap result;
80− QModelIndex modelIndex(index(row));
81− QHashIterator<int, QByteArray> it(roleNames());
82− while (it.hasNext()) {
83− it.next();
84− QVariant val(data(modelIndex, it.key()));
85− if (val.isNull()) continue;
86− result[it.value()] = val;
87− }
88−
89− return result;
90−}
91−
9254QVariant
9355ResultsModel::data(const QModelIndex& index, int role) const
9456{
@@ -103,13 +65,9 @@ ResultsModel::data(const QModelIndex& index, int role) const
10365 case RoleArt:
10466 return qmlDirectory() + "graphics/applicationIcons/dash.png";
10567 case RoleSubtitle:
68+ return QString("Subtitle.%1.%2").arg(m_categoryId).arg(index.row());
10669 case RoleMascot:
10770 case RoleEmblem:
108− case RoleOldPrice:
109− case RolePrice:
110− case RoleAltPrice:
111− case RoleRating:
112− case RoleAltRating:
11371 case RoleSummary:
11472 default:
11573 return QVariant();
tests/mocks/Unity/fake_resultsmodel.h+5−37
@@ -21,58 +21,26 @@
2121#ifndef FAKE_RESULTS_MODEL_H
2222#define FAKE_RESULTS_MODEL_H
2323
24−#include <QAbstractListModel>
24+#include <unity/shell/scopes/ResultsModelInterface.h>
2525
26−class ResultsModel : public QAbstractListModel
26+class ResultsModel : public unity::shell::scopes::ResultsModelInterface
2727{
2828 Q_OBJECT
2929
30− Q_ENUMS(Roles)
31−
32− Q_PROPERTY(QString categoryId READ categoryId WRITE setCategoryId NOTIFY categoryIdChanged)
33− Q_PROPERTY(int count READ count NOTIFY countChanged)
34−
3530public:
3631 explicit ResultsModel(int result_count, int categoryId, QObject* parent = 0);
3732
38− enum Roles {
39− RoleUri,
40− RoleCategoryId,
41− RoleDndUri,
42− RoleResult,
43− // card components
44− RoleTitle,
45− RoleArt,
46− RoleSubtitle,
47− RoleMascot,
48− RoleEmblem,
49− RoleOldPrice,
50− RolePrice,
51− RoleAltPrice,
52− RoleRating,
53− RoleAltRating,
54− RoleSummary
55− };
56−
5733 int rowCount(const QModelIndex& parent = QModelIndex()) const override;
58− QHash<int, QByteArray> roleNames() const override;
5934 QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
6035
61− Q_INVOKABLE QVariant get(int row) const;
62−
6336 /* getters */
64− QString categoryId() const;
65− int count() const;
37+ QString categoryId() const override;
38+ int count() const override;
6639
6740 /* setters */
68− void setCategoryId(QString const& id);
69−
70−Q_SIGNALS:
71− void categoryIdChanged();
72− void countChanged();
41+ void setCategoryId(QString const& id) override;
7342
7443private:
75− QHash<int, QByteArray> m_roles;
7644 int m_result_count;
7745 int m_categoryId;
7846};
tests/mocks/Unity/fake_scope.cpp+3−14
@@ -22,7 +22,7 @@ Scope::Scope(QObject* parent) : Scope(QString(), QString(), false, parent)
2222}
2323
2424Scope::Scope(QString const& id, QString const& name, bool visible, QObject* parent)
25− : QObject(parent)
25+ : unity::shell::scopes::ScopeInterface(parent)
2626 , m_id(id)
2727 , m_name(name)
2828 , m_visible(visible)
@@ -61,15 +61,11 @@ QString Scope::shortcut() const {
6161 return QString("");
6262}
6363
64−bool Scope::connected() const {
65− return true;
66−}
67−
6864bool Scope::searchInProgress() const {
6965 return m_searching;
7066}
7167
72−Categories* Scope::categories() const {
68+unity::shell::scopes::CategoriesInterface* Scope::categories() const {
7369 return m_categories;
7470}
7571
@@ -89,13 +85,6 @@ bool Scope::isActive() const {
8985 return m_isActive;
9086}
9187
92−void Scope::setName(const QString &str) {
93− if (str != m_name) {
94− m_name = str;
95− Q_EMIT nameChanged(m_name);
96− }
97−}
98−
9988void Scope::setSearchQuery(const QString &str) {
10089 if (str != m_searchQuery) {
10190 m_searchQuery = str;
@@ -149,7 +138,7 @@ void Scope::cancelActivation()
149138{
150139}
151140
152−void Scope::closeScope(Scope* /*scope*/)
141+void Scope::closeScope(unity::shell::scopes::ScopeInterface* /*scope*/)
153142{
154143 qFatal("Scope::closeScope is not implemented");
155144}
tests/mocks/Unity/fake_scope.h+26−72
@@ -17,93 +17,47 @@
1717#ifndef FAKE_SCOPE_H
1818#define FAKE_SCOPE_H
1919
20+#include <unity/shell/scopes/ScopeInterface.h>
21+
2022#include "fake_categories.h"
2123#include "fake_previewstack.h"
2224
23−#include <QObject>
2425#include <QTimer>
2526
26−class Preview;
27−
28−class Scope : public QObject
27+class Scope : public unity::shell::scopes::ScopeInterface
2928{
3029 Q_OBJECT
3130
32− Q_PROPERTY(QString id READ id NOTIFY idChanged)
33− Q_PROPERTY(QString name READ name NOTIFY nameChanged)
34− Q_PROPERTY(QString iconHint READ iconHint NOTIFY iconHintChanged)
35− Q_PROPERTY(QString description READ description NOTIFY descriptionChanged)
36− Q_PROPERTY(QString searchHint READ searchHint NOTIFY searchHintChanged)
37− Q_PROPERTY(bool searchInProgress READ searchInProgress WRITE setSearchInProgress NOTIFY searchInProgressChanged)
38− Q_PROPERTY(bool visible READ visible NOTIFY visibleChanged)
39− Q_PROPERTY(QString shortcut READ shortcut NOTIFY shortcutChanged)
40− Q_PROPERTY(Categories* categories READ categories NOTIFY categoriesChanged)
41− //Q_PROPERTY(Filters* filters READ filters NOTIFY filtersChanged)
42−
43− Q_PROPERTY(QString searchQuery READ searchQuery WRITE setSearchQuery NOTIFY searchQueryChanged)
44− Q_PROPERTY(QString noResultsHint READ noResultsHint WRITE setNoResultsHint NOTIFY noResultsHintChanged)
45− Q_PROPERTY(QString formFactor READ formFactor WRITE setFormFactor NOTIFY formFactorChanged)
46− Q_PROPERTY(bool isActive READ isActive WRITE setActive NOTIFY isActiveChanged)
47−
4831public:
4932 Scope(QObject* parent = 0);
5033 Scope(QString const& id, QString const& name, bool visible, QObject* parent = 0);
5134
5235 /* getters */
53− QString id() const;
54− QString name() const;
55− QString iconHint() const;
56− QString description() const;
57− QString searchHint() const;
58− bool visible() const;
59− QString shortcut() const;
60− bool connected() const;
61− bool searchInProgress() const;
62− Categories* categories() const;
63− QString searchQuery() const;
64− QString noResultsHint() const;
65− QString formFactor() const;
66− bool isActive() const;
36+ QString id() const override;
37+ QString name() const override;
38+ QString iconHint() const override;
39+ QString description() const override;
40+ QString searchHint() const override;
41+ bool visible() const override;
42+ QString shortcut() const override;
43+ bool searchInProgress() const override;
44+ unity::shell::scopes::CategoriesInterface* categories() const override;
45+ QString searchQuery() const override;
46+ QString noResultsHint() const override;
47+ QString formFactor() const override;
48+ bool isActive() const override;
6749
6850 /* setters */
69− void setName(const QString& name);
70− void setSearchQuery(const QString& search_query);
71− void setNoResultsHint(const QString& hint);
72− void setFormFactor(const QString& form_factor);
73− void setActive(const bool);
74− void setSearchInProgress(const bool inProg);
75−
76− Q_INVOKABLE void activate(QVariant const& result);
77− Q_INVOKABLE PreviewStack* preview(QVariant const& result);
78− Q_INVOKABLE void cancelActivation();
79− Q_INVOKABLE void closeScope(Scope* scope);
80−
81−Q_SIGNALS:
82− void idChanged();
83− void nameChanged(const QString&);
84− void iconHintChanged(const QString&);
85− void descriptionChanged(const QString&);
86− void searchHintChanged(const QString&);
87− void searchInProgressChanged();
88− void visibleChanged(bool);
89− void shortcutChanged(const QString&);
90− void categoriesChanged();
91− //void filtersChanged();
92− void searchQueryChanged();
93− void noResultsHintChanged();
94− void formFactorChanged();
95− void isActiveChanged(bool);
96−
97− // signals triggered by activate(..) or preview(..) requests.
98− void showDash();
99− void hideDash();
100− void gotoUri(const QString &uri);
101− void activated();
102− void previewRequested(QVariant const& result);
103− void gotoScope(QString const& scopeId);
104− void openScope(Scope* scope);
105−
106− void activateApplication(const QString &desktop);
51+ void setSearchQuery(const QString& search_query) override;
52+ void setNoResultsHint(const QString& hint) override;
53+ void setFormFactor(const QString& form_factor) override;
54+ void setActive(const bool) override;
55+ Q_INVOKABLE void setSearchInProgress(const bool inProg); // This is not invokable in the Interface, here for testing benefits
56+
57+ Q_INVOKABLE void activate(QVariant const& result) override;
58+ Q_INVOKABLE PreviewStack* preview(QVariant const& result) override;
59+ Q_INVOKABLE void cancelActivation() override;
60+ Q_INVOKABLE void closeScope(unity::shell::scopes::ScopeInterface* scope) override;
10761
10862protected:
10963
tests/mocks/Unity/fake_scopes.cpp+11−22
@@ -25,15 +25,10 @@
2525#include <QTimer>
2626
2727Scopes::Scopes(QObject *parent)
28−: QAbstractListModel(parent)
29−, m_loaded(false)
30−, timer(this)
28+ : unity::shell::scopes::ScopesInterface(parent)
29+ , m_loaded(false)
30+ , timer(this)
3131{
32− m_roles[Scopes::RoleScope] = "scope";
33− m_roles[Scopes::RoleId] = "id";
34− m_roles[Scopes::RoleVisible] = "visible";
35− m_roles[Scopes::RoleTitle] = "title";
36−
3732 QObject::connect(this, SIGNAL(rowsInserted(const QModelIndex &, int, int)), this, SIGNAL(countChanged()));
3833 QObject::connect(this, SIGNAL(rowsRemoved(const QModelIndex &, int, int)), this, SIGNAL(countChanged()));
3934 QObject::connect(this, SIGNAL(modelReset()), this, SIGNAL(countChanged()));
@@ -83,11 +78,6 @@ void Scopes::load()
8378 timer.start();
8479}
8580
86−QHash<int, QByteArray> Scopes::roleNames() const
87−{
88− return m_roles;
89−}
90−
9181int Scopes::rowCount(const QModelIndex&) const
9282{
9383 return m_scopes.count();
@@ -114,14 +104,18 @@ QVariant Scopes::data(const QModelIndex& index, int role) const
114104 }
115105}
116106
117−QVariant Scopes::get(int row) const
107+unity::shell::scopes::ScopeInterface* Scopes::getScope(int row) const
118108{
119− return data(QAbstractListModel::index(row), 0);
109+ if (row < 0 || row >= m_scopes.size()) {
110+ return nullptr;
111+ }
112+
113+ return m_scopes[row];
120114}
121115
122−QVariant Scopes::get(QString const&) const
116+unity::shell::scopes::ScopeInterface* Scopes::getScope(QString const&) const
123117{
124− return QVariant();
118+ return nullptr;
125119}
126120
127121QModelIndex Scopes::parent(const QModelIndex&) const
@@ -134,11 +128,6 @@ bool Scopes::loaded() const
134128 return m_loaded;
135129}
136130
137−int Scopes::count() const
138−{
139− return rowCount();
140−}
141−
142131void Scopes::addScope(Scope* scope)
143132{
144133 int index = rowCount();
tests/mocks/Unity/fake_scopes.h+7−24
@@ -19,36 +19,27 @@
1919#ifndef FAKE_SCOPES_H
2020#define FAKE_SCOPES_H
2121
22+#include <unity/shell/scopes/ScopesInterface.h>
23+
2224// Local
2325#include "fake_scope.h"
2426
2527// Qt
26−#include <QAbstractListModel>
2728#include <QList>
2829#include <QTimer>
2930
30−class Scopes : public QAbstractListModel
31+class Scopes : public unity::shell::scopes::ScopesInterface
3132{
3233 Q_OBJECT
33− Q_ENUMS(Roles)
34− Q_PROPERTY(bool loaded READ loaded NOTIFY loadedChanged)
35− Q_PROPERTY(int count READ count NOTIFY countChanged)
3634
3735public:
3836 explicit Scopes(QObject *parent = 0);
3937 ~Scopes();
4038
41− enum Roles {
42− RoleScope,
43− RoleId,
44− RoleVisible,
45− RoleTitle
46− };
47−
48− Q_INVOKABLE int rowCount(const QModelIndex& parent = QModelIndex()) const;
39+ Q_INVOKABLE int rowCount(const QModelIndex& parent = QModelIndex()) const override;
4940
50− Q_INVOKABLE QVariant get(int row) const;
51− Q_INVOKABLE QVariant get(const QString& scope_id) const;
41+ Q_INVOKABLE unity::shell::scopes::ScopeInterface* getScope(int row) const override;
42+ Q_INVOKABLE unity::shell::scopes::ScopeInterface* getScope(const QString& scope_id) const override;
5243
5344 Q_INVOKABLE void addScope(Scope* scope);
5445
@@ -56,23 +47,15 @@ public:
5647 Q_INVOKABLE void load();
5748
5849 QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
59− QHash<int, QByteArray> roleNames() const;
6050 QModelIndex parent ( const QModelIndex & index ) const;
6151
62− bool loaded() const;
63− int count() const;
64−
65−Q_SIGNALS:
66− void activateScopeRequested(const QString& scope_id);
67− void loadedChanged(bool);
68− void countChanged();
52+ bool loaded() const override;
6953
7054private Q_SLOTS:
7155 void updateScopes();
7256
7357private:
7458 QList<Scope*> m_scopes;
75− QHash<int, QByteArray> m_roles;
7659 bool m_loaded;
7760 QTimer timer;
7861};
tests/mocks/Unity/fake_unity_plugin.cpp+3−2
@@ -40,8 +40,9 @@ void FakeUnityPlugin::registerTypes(const char *uri)
4040 Q_ASSERT(uri == QLatin1String("Unity"));
4141
4242 qmlRegisterType<Scopes>(uri, 0, 2, "Scopes");
43− qmlRegisterType<Scope>(uri, 0, 2, "Scope");
44− qmlRegisterUncreatableType<Categories>(uri, 0, 2, "Categories", "Can't create Categories object in QML.");
43+ qmlRegisterType<Scope>(uri, 0, 2, "MockScope");
44+ qmlRegisterUncreatableType<unity::shell::scopes::ScopeInterface>(uri, 0, 2, "Scope", "Can't create Scope object in QML.");
45+ qmlRegisterUncreatableType<unity::shell::scopes::CategoriesInterface>(uri, 0, 2, "Categories", "Can't create Categories object in QML.");
4546 qmlRegisterUncreatableType<ResultsModel>(uri, 0, 2, "ResultsModel", "Can't create ResultsModel object in QML.");
4647 qmlRegisterType<PreviewModel>(uri, 0, 2, "FakePreviewModel");
4748 qmlRegisterUncreatableType<PreviewWidgetModel>(uri, 0, 2, "PreviewWidgetModel", "Can't create new PreviewWidgetModel in QML. Get them from PreviewModel instance.");
tests/mocks/Unity/qmldir+1
@@ -1,2 +1,3 @@
11module Unity
22plugin FakeUnityQml
3+typeinfo Unity.qmltypes
tests/plugins/CMakeLists.txt+1−1
@@ -1,6 +1,6 @@
11add_subdirectory(AccountsService)
22add_subdirectory(LightDM)
3−add_subdirectory(DashViews)
3+add_subdirectory(Dash)
44add_subdirectory(Ubuntu)
55add_subdirectory(Unity)
66add_subdirectory(Utils)
tests/plugins/Dash/CMakeLists.txtnew file+79
@@ -0,0 +1,79 @@
1+# add_qml_test macro
2+include(QmlTest)
3+
4+# There's no cmake var for v8 include path :-/
5+# so create one
6+LIST(GET Qt5Core_INCLUDE_DIRS 0 QtCoreDir0)
7+if(${Qt5Core_VERSION_STRING} VERSION_LESS "5.1.0")
8+ SET(Qt5V8_PRIVATE_INCLUDE_DIR ${QtCoreDir0}/../QtV8/${Qt5Core_VERSION_STRING}/QtV8)
9+else()
10+ SET(Qt5V8_PRIVATE_INCLUDE_DIR ${QtCoreDir0}/QtV8/${Qt5Core_VERSION_STRING}/QtV8)
11+endif()
12+
13+
14+include_directories(
15+ ${Qt5Qml_PRIVATE_INCLUDE_DIRS}
16+ ${Qt5Quick_INCLUDE_DIRS}
17+ ${Qt5Quick_PRIVATE_INCLUDE_DIRS}
18+ ${Qt5V8_PRIVATE_INCLUDE_DIR}
19+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../plugins/Dash
20+ ${CMAKE_CURRENT_BINARY_DIR}
21+ )
22+
23+remove_definitions(-DQT_NO_KEYWORDS)
24+
25+add_definitions(-DDASHVIEWSTEST_FOLDER="${CMAKE_CURRENT_SOURCE_DIR}")
26+add_definitions(-DBUILT_PLUGINS_DIR="${CMAKE_BINARY_DIR}/plugins")
27+
28+macro(add_lvwph_test FILENAME TESTNAME)
29+ add_executable(${TESTNAME}TestExec
30+ ${FILENAME}test.cpp
31+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../plugins/Dash/listviewwithpageheader.cpp)
32+ qt5_use_modules(${TESTNAME}TestExec Test Core Qml)
33+ target_link_libraries(${TESTNAME}TestExec ${Qt5Gui_LIBRARIES} ${Qt5Quick_LIBRARIES})
34+
35+ add_binary_qml_test(${TESTNAME} "" "Dash-qml")
36+endmacro()
37+
38+add_lvwph_test(listviewwithpageheader ListViewWithPageHeader)
39+add_lvwph_test(listviewwithpageheadersection ListViewWithPageHeaderSection)
40+add_lvwph_test(listviewwithpageheadersectionexternalmodel ListViewWithPageHeaderSectionExternalModel)
41+
42+macro(add_dashview_try_test FILENAME TESTNAME)
43+ add_executable(${TESTNAME}TestExec
44+ ${FILENAME}test.cpp
45+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../plugins/Dash/${FILENAME}.cpp
46+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../plugins/Dash/abstractdashview.cpp
47+ )
48+ qt5_use_modules(${TESTNAME}TestExec Test Core Qml)
49+ target_link_libraries(${TESTNAME}TestExec ${Qt5Gui_LIBRARIES} ${Qt5Quick_LIBRARIES})
50+
51+ add_binary_qml_test(${TESTNAME} "" "Dash-qml")
52+
53+ add_executable(${TESTNAME}tryExec
54+ ${FILENAME}try.cpp
55+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../plugins/Dash/${FILENAME}.cpp
56+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../plugins/Dash/abstractdashview.cpp
57+ )
58+ qt5_use_modules(${TESTNAME}tryExec Test Core Qml)
59+ target_link_libraries(${TESTNAME}tryExec ${Qt5Gui_LIBRARIES} ${Qt5Quick_LIBRARIES})
60+ add_custom_target(try${TESTNAME}
61+ ${CMAKE_CURRENT_BINARY_DIR}/${TESTNAME}tryExec
62+ DEPENDS ${TESTNAME}tryExec Dash-qml
63+ )
64+endmacro()
65+
66+add_dashview_try_test(verticaljournal VerticalJournal)
67+add_dashview_try_test(horizontaljournal HorizontalJournal)
68+add_dashview_try_test(organicgrid OrganicGrid)
69+
70+# CardCreator test
71+add_executable(CardCreatorTestExec cardcreatortest.cpp)
72+qt5_use_modules(CardCreatorTestExec Test Core Qml)
73+target_link_libraries(CardCreatorTestExec ${Qt5Gui_LIBRARIES} ${Qt5Quick_LIBRARIES})
74+add_binary_qml_test(CardCreator "" "Dash-qml")
75+
76+# plain qml test
77+set(qmltest_DEFAULT_TARGETS qmluitests)
78+set(qmltest_DEFAULT_NO_ADD_TEST TRUE)
79+add_qml_test(. ListViewWithPageHeaderQML IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins)
tests/plugins/Dash/cardcreator/1.resnew file+79
@@ -0,0 +1,79 @@
1+AbstractButton {
2+ id: root;
3+ property var template;
4+ property var components;
5+ property var cardData;
6+ property var artShapeBorderSource;
7+ property real fontScale: 1.0;
8+ property int headerAlignment: Text.AlignLeft;
9+ property int fixedHeaderHeight: -1;
10+ property size fixedArtShapeSize: Qt.size(-1, -1);
11+ readonly property string title: cardData && cardData["title"] || "";
12+ property bool asynchronous: true;
13+ property bool showHeader: true;
14+ implicitWidth: childrenRect.width;
15+readonly property size artShapeSize: artShapeLoader.item ? Qt.size(artShapeLoader.item.width, artShapeLoader.item.height) : Qt.size(-1, -1);
16+Item {
17+ id: artShapeHolder;
18+ height: root.fixedArtShapeSize.height != -1 ? root.fixedArtShapeSize.height : artShapeLoader.height;
19+ width: root.fixedArtShapeSize.width != -1 ? root.fixedArtShapeSize.width : artShapeLoader.width;
20+ anchors { horizontalCenter: parent.horizontalCenter; }
21+ Loader {
22+ id: artShapeLoader;
23+ objectName: "artShapeLoader";
24+ active: cardData && cardData["art"] || false;
25+ asynchronous: root.asynchronous;
26+ visible: status == Loader.Ready;
27+ sourceComponent: UbuntuShape {
28+ id: artShape;
29+ objectName: "artShape";
30+ radius: "medium";
31+ readonly property real aspect: components !== undefined ? components["art"]["aspect-ratio"] : 1;
32+ readonly property bool aspectSmallerThanImageAspect: aspect < image.aspect;
33+ Component.onCompleted: updateWidthHeightBindings();
34+ onAspectSmallerThanImageAspectChanged: updateWidthHeightBindings();
35+ visible: image.status == Image.Ready;
36+ borderSource: artShapeBorderSource;
37+ function updateWidthHeightBindings() {
38+ if (aspectSmallerThanImageAspect) {
39+ width = Qt.binding(function() { return !visible ? 0 : image.width });
40+ height = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.height : width / image.aspect });
41+ } else {
42+ width = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.width : height * image.aspect });
43+ height = Qt.binding(function() { return !visible ? 0 : image.height });
44+ }
45+ }
46+ image: Image {
47+ objectName: "artImage";
48+ source: cardData && cardData["art"] || "";
49+ cache: true;
50+ asynchronous: root.asynchronous;
51+ fillMode: components && components["art"]["fill-mode"] === "fit" ? Image.PreserveAspectFit: Image.PreserveAspectCrop;
52+ readonly property real aspect: implicitWidth / implicitHeight;
53+ width: root.width;
54+ height: width / artShape.aspect;
55+ }
56+ }
57+ }
58+ }
59+readonly property int headerHeight: titleLabel.height + titleLabel.anchors.topMargin * 2;
60+Label {
61+ id: titleLabel;
62+ objectName: "titleLabel";
63+ anchors { right: parent.right;left: parent.left;
64+top: artShapeHolder.bottom;
65+ topMargin: units.gu(1);
66+ }
67+ elide: Text.ElideRight;
68+ fontSize: "small";
69+ wrapMode: Text.Wrap;
70+ maximumLineCount: 2;
71+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
72+ color: "grey";
73+ visible: showHeader ;
74+ text: root.title;
75+ font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal;
76+ horizontalAlignment: root.headerAlignment;
77+ }
78+implicitHeight: titleLabel.y + titleLabel.height + units.gu(1);
79+}
tests/plugins/Dash/cardcreator/1.tstnew file+3
@@ -0,0 +1,3 @@
1+template: {"card-layout":"vertical","card-size":"small","category-layout":"grid","collapsed-rows":2}
2+components: {"art":{"aspect-ratio":1.6,"field":"art","fill-mode":"fit"},"title":{"field":"title"}}
3+result: 1.res
tests/plugins/Dash/cardcreator/2.resnew file+116
@@ -0,0 +1,116 @@
1+AbstractButton {
2+ id: root;
3+ property var template;
4+ property var components;
5+ property var cardData;
6+ property var artShapeBorderSource;
7+ property real fontScale: 1.0;
8+ property int headerAlignment: Text.AlignLeft;
9+ property int fixedHeaderHeight: -1;
10+ property size fixedArtShapeSize: Qt.size(-1, -1);
11+ readonly property string title: cardData && cardData["title"] || "";
12+ property bool asynchronous: true;
13+ property bool showHeader: true;
14+ implicitWidth: childrenRect.width;
15+Loader {
16+ id: backgroundLoader;
17+ objectName: "backgroundLoader";
18+ anchors.fill: parent;
19+ asynchronous: root.asynchronous;
20+ visible: status == Loader.Ready;
21+ sourceComponent: UbuntuShape {
22+ objectName: "background";
23+ radius: "medium";
24+ color: getColor(0) || "white";
25+ gradientColor: getColor(1) || color;
26+ anchors.fill: parent;
27+ image: backgroundImage.source ? backgroundImage : null;
28+ property real luminance: 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b;
29+ property Image backgroundImage: Image {
30+ objectName: "backgroundImage";
31+ source: {
32+ if (cardData && typeof cardData["background"] === "string") return cardData["background"];
33+ else if (template && typeof template["card-background"] === "string") return template["card-background"];
34+ else return "";
35+ }
36+ }
37+ function getColor(index) {
38+ if (cardData && typeof cardData["background"] === "object"
39+ && (cardData["background"]["type"] === "color" || cardData["background"]["type"] === "gradient")) {
40+ return cardData["background"]["elements"][index];
41+ } else if (template && typeof template["card-background"] === "object"
42+ && (template["card-background"]["type"] === "color" || template["card-background"]["type"] === "gradient")) {
43+ return template["card-background"]["elements"][index];
44+ } else return undefined;
45+ }
46+ }
47+ }
48+readonly property size artShapeSize: Qt.size(-1, -1);
49+readonly property int headerHeight: row.height + row.margins * 2;
50+Row {
51+ id: row;
52+ objectName: "outerRow";
53+ property real margins: units.gu(1);
54+ spacing: margins;
55+ anchors { top: parent.top;
56+ topMargin: units.gu(1);
57+ left: parent.left;
58+}
59+ anchors.right: parent.right;
60+ anchors.margins: margins;
61+data: [ Image {
62+ id: mascotImage;
63+ objectName: "mascotImage";
64+ anchors { verticalCenter: parent.verticalCenter; }
65+ readonly property int maxSize: Math.max(width, height) * 4;
66+ source: cardData && cardData["mascot"];
67+ width: units.gu(6);
68+ height: units.gu(5.625);
69+ sourceSize { width: maxSize; height: maxSize }
70+ fillMode: Image.PreserveAspectCrop;
71+ horizontalAlignment: Image.AlignHCenter;
72+ verticalAlignment: Image.AlignVCenter;
73+ visible: showHeader;
74+ }
75+,
76+Column {
77+ anchors.verticalCenter: parent.verticalCenter;
78+ spacing: units.dp(2);
79+ width: parent.width - x;
80+ data: [
81+Label {
82+ id: titleLabel;
83+ objectName: "titleLabel";
84+ anchors { left: parent.left; right: parent.right }
85+ elide: Text.ElideRight;
86+ fontSize: "small";
87+ wrapMode: Text.Wrap;
88+ maximumLineCount: 2;
89+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
90+ color: backgroundLoader.active && backgroundLoader.item && backgroundLoader.item.luminance < 0.7 ? "white" : "grey";
91+ visible: showHeader ;
92+ text: root.title;
93+ font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal;
94+ horizontalAlignment: root.headerAlignment;
95+ }
96+,
97+Label {
98+ id: subtitleLabel;
99+ objectName: "subtitleLabel";
100+ anchors { left: parent.left; right: parent.right }
101+
102+ elide: Text.ElideRight;
103+ fontSize: "small";
104+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
105+ color: backgroundLoader.active && backgroundLoader.item && backgroundLoader.item.luminance < 0.7 ? "white" : "grey";
106+ visible: titleLabel.visible && titleLabel.text;
107+ text: cardData && cardData["subtitle"] || "";
108+ font.weight: Font.Light;
109+ horizontalAlignment: root.headerAlignment;
110+ }
111+]
112+}
113+]
114+}
115+implicitHeight: row.y + row.height + units.gu(1);
116+}
tests/plugins/Dash/cardcreator/2.tstnew file+3
@@ -0,0 +1,3 @@
1+template: {"card-background":{"elements":["#E9E9E9"],"type":"color"},"card-layout":"vertical","card-size":"medium","category-layout":"grid","collapsed-rows":2}
2+components: {"art":{"aspect-ratio":1,"fill-mode":"crop"},"background":{"field":"background"},"mascot":{"field":"icon"},"subtitle":{"field":"author"},"title":{"field":"title"}}
3+result: 2.res
tests/plugins/Dash/cardcreator/3.resnew file+96
@@ -0,0 +1,96 @@
1+AbstractButton {
2+ id: root;
3+ property var template;
4+ property var components;
5+ property var cardData;
6+ property var artShapeBorderSource;
7+ property real fontScale: 1.0;
8+ property int headerAlignment: Text.AlignLeft;
9+ property int fixedHeaderHeight: -1;
10+ property size fixedArtShapeSize: Qt.size(-1, -1);
11+ readonly property string title: cardData && cardData["title"] || "";
12+ property bool asynchronous: true;
13+ property bool showHeader: true;
14+ implicitWidth: childrenRect.width;
15+readonly property size artShapeSize: artShapeLoader.item ? Qt.size(artShapeLoader.item.width, artShapeLoader.item.height) : Qt.size(-1, -1);
16+Item {
17+ id: artShapeHolder;
18+ height: root.fixedArtShapeSize.height != -1 ? root.fixedArtShapeSize.height : artShapeLoader.height;
19+ width: root.fixedArtShapeSize.width != -1 ? root.fixedArtShapeSize.width : artShapeLoader.width;
20+ anchors { horizontalCenter: parent.horizontalCenter; }
21+ Loader {
22+ id: artShapeLoader;
23+ objectName: "artShapeLoader";
24+ active: cardData && cardData["art"] || false;
25+ asynchronous: root.asynchronous;
26+ visible: status == Loader.Ready;
27+ sourceComponent: UbuntuShape {
28+ id: artShape;
29+ objectName: "artShape";
30+ radius: "medium";
31+ readonly property real aspect: components !== undefined ? components["art"]["aspect-ratio"] : 1;
32+ readonly property bool aspectSmallerThanImageAspect: aspect < image.aspect;
33+ Component.onCompleted: updateWidthHeightBindings();
34+ onAspectSmallerThanImageAspectChanged: updateWidthHeightBindings();
35+ visible: image.status == Image.Ready;
36+ borderSource: artShapeBorderSource;
37+ function updateWidthHeightBindings() {
38+ if (aspectSmallerThanImageAspect) {
39+ width = Qt.binding(function() { return !visible ? 0 : image.width });
40+ height = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.height : width / image.aspect });
41+ } else {
42+ width = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.width : height * image.aspect });
43+ height = Qt.binding(function() { return !visible ? 0 : image.height });
44+ }
45+ }
46+ image: Image {
47+ objectName: "artImage";
48+ source: cardData && cardData["art"] || "";
49+ cache: true;
50+ asynchronous: root.asynchronous;
51+ fillMode: components && components["art"]["fill-mode"] === "fit" ? Image.PreserveAspectFit: Image.PreserveAspectCrop;
52+ readonly property real aspect: implicitWidth / implicitHeight;
53+ width: root.width;
54+ height: width / artShape.aspect;
55+ }
56+ }
57+ }
58+ }
59+readonly property int headerHeight: titleLabel.height + titleLabel.anchors.topMargin * 2 + subtitleLabel.height + subtitleLabel.anchors.topMargin;
60+Label {
61+ id: titleLabel;
62+ objectName: "titleLabel";
63+ anchors { right: parent.right;left: parent.left;
64+top: artShapeHolder.bottom;
65+ topMargin: units.gu(1);
66+}
67+ elide: Text.ElideRight;
68+ fontSize: "small";
69+ wrapMode: Text.Wrap;
70+ maximumLineCount: 2;
71+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
72+ color: "grey";
73+ visible: showHeader ;
74+ text: root.title;
75+ font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal;
76+ horizontalAlignment: root.headerAlignment;
77+ }
78+Label {
79+ id: subtitleLabel;
80+ objectName: "subtitleLabel";
81+ anchors { left: titleLabel.left;
82+ leftMargin: titleLabel.leftMargin;
83+ right: titleLabel.right;
84+ top: titleLabel.bottom;
85+ topMargin: units.dp(2); }
86+ elide: Text.ElideRight;
87+ fontSize: "small";
88+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
89+ color: "grey";
90+ visible: titleLabel.visible && titleLabel.text;
91+ text: cardData && cardData["subtitle"] || "";
92+ font.weight: Font.Light;
93+ horizontalAlignment: root.headerAlignment;
94+ }
95+implicitHeight: subtitleLabel.y + subtitleLabel.height + units.gu(1);
96+}
tests/plugins/Dash/cardcreator/3.tstnew file+3
@@ -0,0 +1,3 @@
1+template: {"card-layout":"vertical","card-size":"small","category-layout":"grid","collapsed-rows":2}
2+components: {"art":{"aspect-ratio":0.75,"field":"art","fill-mode":"crop"},"subtitle":{"field":"price"},"title":{"field":"title"}}
3+result: 3.res
tests/plugins/Dash/cardcreator/4.resnew file+96
@@ -0,0 +1,96 @@
1+AbstractButton {
2+ id: root;
3+ property var template;
4+ property var components;
5+ property var cardData;
6+ property var artShapeBorderSource;
7+ property real fontScale: 1.0;
8+ property int headerAlignment: Text.AlignLeft;
9+ property int fixedHeaderHeight: -1;
10+ property size fixedArtShapeSize: Qt.size(-1, -1);
11+ readonly property string title: cardData && cardData["title"] || "";
12+ property bool asynchronous: true;
13+ property bool showHeader: true;
14+ implicitWidth: childrenRect.width;
15+readonly property size artShapeSize: Qt.size(-1, -1);
16+readonly property int headerHeight: row.height + row.margins * 2;
17+Row {
18+ id: row;
19+ objectName: "outerRow";
20+ property real margins: units.gu(1);
21+ spacing: margins;
22+ anchors { top: parent.top;
23+ topMargin: units.gu(1);
24+ left: parent.left;
25+}
26+ anchors.right: parent.right;
27+ anchors.margins: margins;
28+data: [ Loader {
29+ id: mascotShapeLoader;
30+ objectName: "mascotShapeLoader";
31+ asynchronous: root.asynchronous;
32+ active: mascotImage.status === Image.Ready;
33+ visible: showHeader && active && status == Loader.Ready;
34+ width: units.gu(6);
35+ height: units.gu(5.625);
36+ sourceComponent: UbuntuShape { image: mascotImage }
37+ anchors { verticalCenter: parent.verticalCenter; }
38+ }
39+
40+,
41+Image {
42+ id: mascotImage;
43+ objectName: "mascotImage";
44+ anchors { verticalCenter: parent.verticalCenter; }
45+ readonly property int maxSize: Math.max(width, height) * 4;
46+ source: cardData && cardData["mascot"];
47+ width: units.gu(6);
48+ height: units.gu(5.625);
49+ sourceSize { width: maxSize; height: maxSize }
50+ fillMode: Image.PreserveAspectCrop;
51+ horizontalAlignment: Image.AlignHCenter;
52+ verticalAlignment: Image.AlignVCenter;
53+ visible: false;
54+ }
55+
56+,
57+Column {
58+ anchors.verticalCenter: parent.verticalCenter;
59+ spacing: units.dp(2);
60+ width: parent.width - x;
61+data: [ Label {
62+ id: titleLabel;
63+ objectName: "titleLabel";
64+ anchors { left: parent.left; right: parent.right }
65+ elide: Text.ElideRight;
66+ fontSize: "small";
67+ wrapMode: Text.Wrap;
68+ maximumLineCount: 2;
69+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
70+ color: "grey";
71+ visible: showHeader ;
72+ text: root.title;
73+ font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal;
74+ horizontalAlignment: root.headerAlignment;
75+ }
76+,
77+Label {
78+ id: subtitleLabel;
79+ objectName: "subtitleLabel";
80+ anchors { left: parent.left; right: parent.right }
81+
82+ elide: Text.ElideRight;
83+ fontSize: "small";
84+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
85+ color: "grey";
86+ visible: titleLabel.visible && titleLabel.text;
87+ text: cardData && cardData["subtitle"] || "";
88+ font.weight: Font.Light;
89+ horizontalAlignment: root.headerAlignment;
90+ }
91+]
92+}
93+]
94+}
95+implicitHeight: row.y + row.height + units.gu(1);
96+}
tests/plugins/Dash/cardcreator/4.tstnew file+3
@@ -0,0 +1,3 @@
1+template: {"card-layout":"horizontal","card-size":"large","category-layout":"grid","collapsed-rows":2}
2+components: {"art":{"aspect-ratio":1,"fill-mode":"crop"},"mascot":{"field":"mascot"},"subtitle":{"field":"domain"},"title":{"field":"title"}}
3+result: 4.res
tests/plugins/Dash/cardcreator/5.resnew file+139
@@ -0,0 +1,139 @@
1+AbstractButton {
2+ id: root;
3+ property var template;
4+ property var components;
5+ property var cardData;
6+ property var artShapeBorderSource;
7+ property real fontScale: 1.0;
8+ property int headerAlignment: Text.AlignLeft;
9+ property int fixedHeaderHeight: -1;
10+ property size fixedArtShapeSize: Qt.size(-1, -1);
11+ readonly property string title: cardData && cardData["title"] || "";
12+ property bool asynchronous: true;
13+ property bool showHeader: true;
14+ implicitWidth: childrenRect.width;
15+readonly property size artShapeSize: artShapeLoader.item ? Qt.size(artShapeLoader.item.width, artShapeLoader.item.height) : Qt.size(-1, -1);
16+Item {
17+ id: artShapeHolder;
18+ height: root.fixedArtShapeSize.height != -1 ? root.fixedArtShapeSize.height : artShapeLoader.height;
19+ width: root.fixedArtShapeSize.width != -1 ? root.fixedArtShapeSize.width : artShapeLoader.width;
20+ anchors { horizontalCenter: parent.horizontalCenter; }
21+ Loader {
22+ id: artShapeLoader;
23+ objectName: "artShapeLoader";
24+ active: cardData && cardData["art"] || false;
25+ asynchronous: root.asynchronous;
26+ visible: status == Loader.Ready;
27+ sourceComponent: UbuntuShape {
28+ id: artShape;
29+ objectName: "artShape";
30+ radius: "medium";
31+ readonly property real aspect: components !== undefined ? components["art"]["aspect-ratio"] : 1;
32+ readonly property bool aspectSmallerThanImageAspect: aspect < image.aspect;
33+ Component.onCompleted: updateWidthHeightBindings();
34+ onAspectSmallerThanImageAspectChanged: updateWidthHeightBindings();
35+ visible: image.status == Image.Ready;
36+ borderSource: artShapeBorderSource;
37+ function updateWidthHeightBindings() {
38+ if (aspectSmallerThanImageAspect) {
39+ width = Qt.binding(function() { return !visible ? 0 : image.width });
40+ height = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.height : width / image.aspect });
41+ } else {
42+ width = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.width : height * image.aspect });
43+ height = Qt.binding(function() { return !visible ? 0 : image.height });
44+ }
45+ }
46+ image: Image {
47+ objectName: "artImage";
48+ source: cardData && cardData["art"] || "";
49+ cache: true;
50+ asynchronous: root.asynchronous;
51+ fillMode: components && components["art"]["fill-mode"] === "fit" ? Image.PreserveAspectFit: Image.PreserveAspectCrop;
52+ readonly property real aspect: implicitWidth / implicitHeight;
53+ width: root.width;
54+ height: width / artShape.aspect;
55+ }
56+ }
57+ }
58+ }
59+Loader {
60+ id: overlayLoader;
61+ anchors {
62+ left: artShapeHolder.left;
63+ right: artShapeHolder.right;
64+ bottom: artShapeHolder.bottom;
65+ }
66+ active: artShapeLoader.active && artShapeLoader.item && artShapeLoader.item.image.status === Image.Ready || false;
67+ asynchronous: root.asynchronous;
68+ visible: showHeader && status == Loader.Ready;
69+ sourceComponent: ShaderEffect {
70+ id: overlay;
71+ height: fixedHeaderHeight != -1 ? fixedHeaderHeight : headerHeight;
72+ opacity: 0.6;
73+ property var source: ShaderEffectSource {
74+ id: shaderSource;
75+ sourceItem: artShapeLoader.item;
76+ onVisibleChanged: if (visible) scheduleUpdate();
77+ live: false;
78+ sourceRect: Qt.rect(0, artShapeLoader.height - overlay.height, artShapeLoader.width, overlay.height);
79+ }
80+ vertexShader: "
81+ uniform highp mat4 qt_Matrix;
82+ attribute highp vec4 qt_Vertex;
83+ attribute highp vec2 qt_MultiTexCoord0;
84+ varying highp vec2 coord;
85+ void main() {
86+ coord = qt_MultiTexCoord0;
87+ gl_Position = qt_Matrix * qt_Vertex;
88+ }";
89+ fragmentShader: "
90+ varying highp vec2 coord;
91+ uniform sampler2D source;
92+ uniform lowp float qt_Opacity;
93+ void main() {
94+ lowp vec4 tex = texture2D(source, coord);
95+ gl_FragColor = vec4(0, 0, 0, tex.a) * qt_Opacity;
96+ }";
97+ }
98+ }
99+readonly property int headerHeight: titleLabel.height + titleLabel.anchors.topMargin * 2 + subtitleLabel.height + subtitleLabel.anchors.topMargin;
100+Label {
101+ id: titleLabel;
102+ objectName: "titleLabel";
103+ anchors { left: parent.left;
104+ leftMargin: units.gu(1);
105+ right: parent.right;
106+ top: overlayLoader.top;
107+ topMargin: units.gu(1);
108+}
109+ elide: Text.ElideRight;
110+ fontSize: "small";
111+ wrapMode: Text.Wrap;
112+ maximumLineCount: 2;
113+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
114+ color: "white";
115+ visible: showHeader && overlayLoader.active;
116+ text: root.title;
117+ font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal;
118+ horizontalAlignment: root.headerAlignment;
119+ }
120+Label {
121+ id: subtitleLabel;
122+ objectName: "subtitleLabel";
123+ anchors { left: titleLabel.left;
124+ leftMargin: titleLabel.leftMargin;
125+ right: titleLabel.right;
126+ top: titleLabel.bottom;
127+ topMargin: units.dp(2);
128+ }
129+ elide: Text.ElideRight;
130+ fontSize: "small";
131+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
132+ color: "white";
133+ visible: titleLabel.visible && titleLabel.text;
134+ text: cardData && cardData["subtitle"] || "";
135+ font.weight: Font.Light;
136+ horizontalAlignment: root.headerAlignment;
137+ }
138+implicitHeight: subtitleLabel.y + subtitleLabel.height + units.gu(1);
139+}
tests/plugins/Dash/cardcreator/5.tstnew file+3
@@ -0,0 +1,3 @@
1+template: {"card-layout":"vertical","card-size":"medium","category-layout":"carousel","collapsed-rows":2,"overlay":true}
2+components: {"art":{"aspect-ratio":1,"field":"art","fill-mode":"crop"},"subtitle":{"field":"artist"},"title":{"field":"title"}}
3+result: 5.res
tests/plugins/Dash/cardcreatortest.cppnew file+91
@@ -0,0 +1,91 @@
1+/*
2+ * Copyright (C) 2014 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 <QDir>
18+#include <QQmlEngine>
19+#include <QQuickItem>
20+#include <QQuickView>
21+#include <QtTestGui>
22+
23+class CardCreatorTest : public QObject
24+{
25+ Q_OBJECT
26+
27+private Q_SLOTS:
28+
29+ void initTestCase()
30+ {
31+ }
32+
33+ void init()
34+ {
35+ view = new QQuickView();
36+ view->engine()->addImportPath(BUILT_PLUGINS_DIR);
37+ view->setSource(QUrl::fromLocalFile(DASHVIEWSTEST_FOLDER "/cardcreatortest.qml"));
38+ view->show();
39+ QTest::qWaitForWindowExposed(view);
40+ }
41+
42+ void cleanup()
43+ {
44+ delete view;
45+ }
46+
47+ void testKnownCases()
48+ {
49+ const QString templateString("template: ");
50+ const QString componentsString("components: ");
51+ const QString resultString("result: ");
52+
53+ const QString testDirPath = DASHVIEWSTEST_FOLDER "/cardcreator/";
54+ QDir d(testDirPath);
55+ const QStringList testFiles = d.entryList(QStringList() << "*.tst");
56+ foreach(const QString &testFileName, testFiles) {
57+ qDebug() << testFileName;
58+ QFile testFile(testDirPath + testFileName);
59+ QVERIFY(testFile.open(QIODevice::ReadOnly));
60+ QTextStream ts(&testFile);
61+ const QStringList lines = ts.readAll().split("\n");
62+
63+ QVERIFY(lines[0].startsWith(templateString));
64+ QVERIFY(lines[1].startsWith(componentsString));
65+ QVERIFY(lines[2].startsWith(resultString));
66+ const QString templateJSON = lines[0].mid(templateString.length());
67+ const QString componentsJSON = lines[1].mid(componentsString.length());
68+ const QString resultFileName = lines[2].mid(resultString.length());
69+
70+ QVariant cardStringResult;
71+ QMetaObject::invokeMethod(view->rootObject(), "cardString", Q_RETURN_ARG(QVariant, cardStringResult), Q_ARG(QVariant, templateJSON), Q_ARG(QVariant, componentsJSON));
72+
73+ QFile testResultFile(testDirPath + resultFileName);
74+ QVERIFY(testResultFile.open(QIODevice::ReadOnly));
75+ QTextStream ts2(&testResultFile);
76+ const QString expectedResult = ts2.readAll();
77+ QCOMPARE(cardStringResult.toString().simplified(), expectedResult.simplified());
78+
79+ QVariant createCardComponentResult;
80+ QMetaObject::invokeMethod(view->rootObject(), "createCardComponent", Q_RETURN_ARG(QVariant, createCardComponentResult), Q_ARG(QVariant, templateJSON), Q_ARG(QVariant, componentsJSON));
81+ QVERIFY(createCardComponentResult.toBool());
82+ }
83+ }
84+
85+private:
86+ QQuickView *view;
87+};
88+
89+QTEST_MAIN(CardCreatorTest)
90+
91+#include "cardcreatortest.moc"
tests/plugins/Dash/cardcreatortest.qmlnew file+29
@@ -0,0 +1,29 @@
1+/*
2+ * Copyright (C) 2014 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+import QtQuick 2.2
18+import "../../../plugins/Dash/CardCreator.js" as CardCreator
19+
20+Item {
21+ id: root
22+ function cardString(template, components) {
23+ return CardCreator.cardString(JSON.parse(template), JSON.parse(components));
24+ }
25+
26+ function createCardComponent(template, components) {
27+ return CardCreator.createCardComponent(root, JSON.parse(template), JSON.parse(components)) !== null;
28+ }
29+}
tests/plugins/DashViews/horizontaljournaltest.cpp → tests/plugins/Dash/horizontaljournaltest.cpprenamed+6−6
@@ -258,8 +258,8 @@ private Q_SLOTS:
258258
259259 void testDelegateCreationRanges()
260260 {
261− hj->setDelegateCreationBegin(300);
262− hj->setDelegateCreationEnd(view->height());
261+ hj->setDisplayMarginBeginning(-300);
262+ hj->setDisplayMarginEnd(-(hj->height() - view->height()));
263263
264264 QTRY_COMPARE(hj->m_firstVisibleIndex, 6);
265265 QTRY_COMPARE(hj->m_visibleItems.count(), 7);
@@ -274,8 +274,8 @@ private Q_SLOTS:
274274 QTRY_COMPARE(hj->m_lastInRowIndexPosition[ 7], 210.);
275275 QTRY_COMPARE(hj->m_lastInRowIndexPosition[12], 305.);
276276
277− hj->resetDelegateCreationBegin();
278− hj->resetDelegateCreationEnd();
277+ hj->setDisplayMarginBeginning(0);
278+ hj->setDisplayMarginEnd(0);
279279
280280 // This is exactly the same block as the first again
281281 checkInitialPositions();
@@ -469,8 +469,8 @@ private Q_SLOTS:
469469
470470 void testNegativeDelegateCreationRange()
471471 {
472− hj->setDelegateCreationBegin(0);
473− hj->setDelegateCreationEnd(-100);
472+ hj->setDisplayMarginBeginning(0);
473+ hj->setDisplayMarginEnd(-(hj->height() + 100));
474474
475475 QStringList widthList;
476476 widthList << "100" << "50" << "50" << "30";
tests/plugins/DashViews/horizontaljournaltest.qml → tests/plugins/Dash/horizontaljournaltest.qmlrenamed+1−1
@@ -15,7 +15,7 @@
1515 */
1616
1717import QtQuick 2.1
18−import DashViews 0.1
18+import Dash 0.1
1919
2020Item {
2121
tests/plugins/DashViews/horizontaljournaltry.cpp → tests/plugins/Dash/horizontaljournaltry.cpprenamed

The content is the same.

tests/plugins/DashViews/horizontaljournaltry.qml → tests/plugins/Dash/horizontaljournaltry.qmlrenamed+1−1
@@ -15,7 +15,7 @@
1515 */
1616
1717import QtQuick 2.1
18−import DashViews 0.1
18+import Dash 0.1
1919
2020Item {
2121 id: root
tests/plugins/DashViews/listviewwithpageheadertestsectionexternalmodel.cpp → tests/plugins/Dash/listviewwithpageheadersectionexternalmodeltest.cpprenamed+1−5
@@ -24,11 +24,7 @@
2424#include <QtTestGui>
2525#pragma GCC diagnostic push
2626#pragma GCC diagnostic ignored "-pedantic"
27−#if QT_VERSION < QT_VERSION_CHECK(5, 1, 0)
28−#include <private/qquicklistmodel_p.h>
29−#else
3027#include <private/qqmllistmodel_p.h>
31−#endif
3228#include <private/qquickanimation_p.h>
3329#include <private/qquickitem_p.h>
3430#pragma GCC diagnostic pop
@@ -248,4 +244,4 @@ private:
248244
249245QTEST_MAIN(ListViewWithPageHeaderTestSection)
250246
251−#include "listviewwithpageheadertestsectionexternalmodel.moc"
247+#include "listviewwithpageheadersectionexternalmodeltest.moc"
tests/plugins/DashViews/listviewwithpageheadertestsection.cpp → tests/plugins/Dash/listviewwithpageheadersectiontest.cpprenamed+1−13
@@ -23,11 +23,7 @@
2323#include <QtTestGui>
2424#pragma GCC diagnostic push
2525#pragma GCC diagnostic ignored "-pedantic"
26−#if QT_VERSION < QT_VERSION_CHECK(5, 1, 0)
27−#include <private/qquicklistmodel_p.h>
28−#else
2926#include <private/qqmllistmodel_p.h>
30−#endif
3127#include <private/qquickanimation_p.h>
3228#include <private/qquickitem_p.h>
3329#pragma GCC diagnostic pop
@@ -135,11 +131,7 @@ private Q_SLOTS:
135131 view->engine()->addImportPath(BUILT_PLUGINS_DIR);
136132 view->setSource(QUrl::fromLocalFile(DASHVIEWSTEST_FOLDER "/listviewwithpageheadertestsection.qml"));
137133 lvwph = dynamic_cast<ListViewWithPageHeader*>(view->rootObject()->findChild<QQuickFlickable*>());
138−#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
139− model = view->rootObject()->findChild<QQuickListModel*>();
140−#else
141134 model = view->rootObject()->findChild<QQmlListModel*>();
142−#endif
143135 otherDelegate = view->rootObject()->findChild<QQmlComponent*>();
144136 QVERIFY(lvwph);
145137 QVERIFY(model);
@@ -2156,14 +2148,10 @@ private Q_SLOTS:
21562148private:
21572149 QQuickView *view;
21582150 ListViewWithPageHeader *lvwph;
2159−#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
2160− QQuickListModel *model;
2161−#else
21622151 QQmlListModel *model;
2163−#endif
21642152 QQmlComponent *otherDelegate;
21652153};
21662154
21672155QTEST_MAIN(ListViewWithPageHeaderTestSection)
21682156
2169−#include "listviewwithpageheadertestsection.moc"
2157+#include "listviewwithpageheadersectiontest.moc"
tests/plugins/DashViews/listviewwithpageheadertest.cpp → tests/plugins/Dash/listviewwithpageheadertest.cpprenamed−15
@@ -23,11 +23,7 @@
2323#include <QtTestGui>
2424#pragma GCC diagnostic push
2525#pragma GCC diagnostic ignored "-pedantic"
26−#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
27−#include <private/qquicklistmodel_p.h>
28−#else
2926#include <private/qqmllistmodel_p.h>
30−#endif
3127#include <private/qquickanimation_p.h>
3228#include <private/qquickitem_p.h>
3329#pragma GCC diagnostic pop
@@ -124,11 +120,7 @@ private Q_SLOTS:
124120 view->engine()->addImportPath(BUILT_PLUGINS_DIR);
125121 view->setSource(QUrl::fromLocalFile(DASHVIEWSTEST_FOLDER "/listviewwithpageheadertest.qml"));
126122 lvwph = dynamic_cast<ListViewWithPageHeader*>(view->rootObject()->findChild<QQuickFlickable*>());
127−#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
128− model = view->rootObject()->findChild<QQuickListModel*>();
129−#else
130123 model = view->rootObject()->findChild<QQmlListModel*>();
131−#endif
132124 otherDelegate = view->rootObject()->findChild<QQmlComponent*>();
133125 QVERIFY(lvwph);
134126 QVERIFY(model);
@@ -1747,9 +1739,6 @@ private Q_SLOTS:
17471739
17481740 void testMaximizeVisibleAreaMoveUpAndShowHeader()
17491741 {
1750−#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
1751− QSKIP("This test is extremely unstable in 5.0.x");
1752−#endif
17531742 model->setProperty(0, "size", 800);
17541743 verifyItem(0, 50., 800., false);
17551744
@@ -1913,11 +1902,7 @@ private Q_SLOTS:
19131902private:
19141903 QQuickView *view;
19151904 ListViewWithPageHeader *lvwph;
1916−#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
1917− QQuickListModel *model;
1918−#else
19191905 QQmlListModel *model;
1920−#endif
19211906 QQmlComponent *otherDelegate;
19221907};
19231908
tests/plugins/DashViews/listviewwithpageheadertest.qml → tests/plugins/Dash/listviewwithpageheadertest.qmlrenamed+1−1
@@ -15,7 +15,7 @@
1515 */
1616
1717import QtQuick 2.0
18−import DashViews 0.1
18+import Dash 0.1
1919
2020Rectangle {
2121 width: 300
tests/plugins/DashViews/listviewwithpageheadertestsection.qml → tests/plugins/Dash/listviewwithpageheadertestsection.qmlrenamed+1−1
@@ -15,7 +15,7 @@
1515 */
1616
1717import QtQuick 2.0
18−import DashViews 0.1
18+import Dash 0.1
1919
2020Rectangle {
2121 width: 300
tests/plugins/DashViews/listviewwithpageheadertestsectionexternalmodel.qml → tests/plugins/Dash/listviewwithpageheadertestsectionexternalmodel.qmlrenamed+1−1
@@ -15,7 +15,7 @@
1515 */
1616
1717import QtQuick 2.0
18−import DashViews 0.1
18+import Dash 0.1
1919
2020Rectangle {
2121 width: 300
tests/plugins/DashViews/organicgridtest.cpp → tests/plugins/Dash/organicgridtest.cpprenamed+2−5
@@ -499,17 +499,14 @@ private Q_SLOTS:
499499 QTRY_COMPARE(grid->m_firstVisibleIndex, 0);
500500 QTRY_COMPARE(grid->m_visibleItems.count(), 198);
501501
502− grid->setDelegateCreationBegin(300);
503− grid->setDelegateCreationEnd(400);
502+ grid->setDisplayMarginBeginning(-300);
503+ grid->setDisplayMarginEnd(-(grid->height() - 400));
504504 checkImplicitHeight(2290);
505505
506506 QTRY_COMPARE(grid->m_firstVisibleIndex, 36);
507507 QTRY_COMPARE(grid->m_visibleItems.count(), 54);
508508 checkImplicitHeight(2290);
509509
510− grid->resetDelegateCreationBegin();
511− grid->resetDelegateCreationEnd();
512−
513510 view->resize(470, 470);
514511
515512 grid->setSmallDelegateSize(QSizeF(90, 90));
tests/plugins/DashViews/organicgridtest.qml → tests/plugins/Dash/organicgridtest.qmlrenamed+1−1
@@ -15,7 +15,7 @@
1515 */
1616
1717import QtQuick 2.1
18−import DashViews 0.1
18+import Dash 0.1
1919
2020Item {
2121
tests/plugins/DashViews/organicgridtry.cpp → tests/plugins/Dash/organicgridtry.cpprenamed

The content is the same.

tests/plugins/DashViews/organicgridtry.qml → tests/plugins/Dash/organicgridtry.qmlrenamed+1−1
@@ -15,7 +15,7 @@
1515 */
1616
1717import QtQuick 2.1
18−import DashViews 0.1
18+import Dash 0.1
1919
2020Item {
2121 id: root
tests/plugins/DashViews/tst_listviewwithpageheaderqml.qml → tests/plugins/Dash/tst_ListViewWithPageHeaderQML.qmlrenamed+1−1
@@ -16,7 +16,7 @@
1616
1717import QtQuick 2.0
1818import QtTest 1.0
19−import DashViews 0.1
19+import Dash 0.1
2020
2121Rectangle {
2222 width: 300
tests/plugins/DashViews/verticaljournaltest.cpp → tests/plugins/Dash/verticaljournaltest.cpprenamed+6−6
@@ -263,8 +263,8 @@ private Q_SLOTS:
263263
264264 void testDelegateCreationRanges()
265265 {
266− vj->setDelegateCreationBegin(200);
267− vj->setDelegateCreationEnd(view->height());
266+ vj->setDisplayMarginBeginning(-200);
267+ vj->setDisplayMarginEnd(-(vj->height() - view->height()));
268268
269269 QTRY_COMPARE(vj->m_columnVisibleItems.count(), 3);
270270 QTRY_COMPARE(vj->m_columnVisibleItems[0].count(), 4);
@@ -286,8 +286,8 @@ private Q_SLOTS:
286286 verifyItem(vj->m_columnVisibleItems[1][3], 15, 160, 430, false);
287287 QCOMPARE(vj->implicitHeight(), 690. + 4. * 690. / 16.);
288288
289− vj->resetDelegateCreationBegin();
290− vj->resetDelegateCreationEnd();
289+ vj->setDisplayMarginBeginning(0);
290+ vj->setDisplayMarginEnd(0);
291291
292292 // This is exactly the same block as the first again
293293 checkInitialPositions();
@@ -478,8 +478,8 @@ private Q_SLOTS:
478478
479479 void testNegativeDelegateCreationRange()
480480 {
481− vj->setDelegateCreationBegin(0);
482− vj->setDelegateCreationEnd(-100);
481+ vj->setDisplayMarginBeginning(0);
482+ vj->setDisplayMarginEnd(-(vj->height() + 100));
483483
484484 QStringList heightList;
485485 heightList << "100" << "50" << "50" << "30";
tests/plugins/DashViews/verticaljournaltest.qml → tests/plugins/Dash/verticaljournaltest.qmlrenamed+1−1
@@ -15,7 +15,7 @@
1515 */
1616
1717import QtQuick 2.1
18−import DashViews 0.1
18+import Dash 0.1
1919
2020Item {
2121
tests/plugins/DashViews/verticaljournaltry.cpp → tests/plugins/Dash/verticaljournaltry.cpprenamed

The content is the same.

tests/plugins/DashViews/verticaljournaltry.qml → tests/plugins/Dash/verticaljournaltry.qmlrenamed+1−1
@@ -15,7 +15,7 @@
1515 */
1616
1717import QtQuick 2.1
18−import DashViews 0.1
18+import Dash 0.1
1919
2020Item {
2121 id: root
tests/plugins/DashViews/CMakeLists.txtdeleted−84
@@ -1,84 +0,0 @@
1−# add_qml_test macro
2−include(QmlTest)
3−
4−# There's no cmake var for v8 include path :-/
5−# so create one
6−LIST(GET Qt5Core_INCLUDE_DIRS 0 QtCoreDir0)
7−if(${Qt5Core_VERSION_STRING} VERSION_LESS "5.1.0")
8− SET(Qt5V8_PRIVATE_INCLUDE_DIR ${QtCoreDir0}/../QtV8/${Qt5Core_VERSION_STRING}/QtV8)
9−else()
10− SET(Qt5V8_PRIVATE_INCLUDE_DIR ${QtCoreDir0}/QtV8/${Qt5Core_VERSION_STRING}/QtV8)
11−endif()
12−
13−
14−include_directories(
15− ${Qt5Qml_PRIVATE_INCLUDE_DIRS}
16− ${Qt5Quick_INCLUDE_DIRS}
17− ${Qt5Quick_PRIVATE_INCLUDE_DIRS}
18− ${Qt5V8_PRIVATE_INCLUDE_DIR}
19− ${CMAKE_CURRENT_SOURCE_DIR}/../../../plugins/DashViews
20− ${CMAKE_CURRENT_BINARY_DIR}
21− )
22−
23−remove_definitions(-DQT_NO_KEYWORDS)
24−
25−add_definitions(-DDASHVIEWSTEST_FOLDER="${CMAKE_CURRENT_SOURCE_DIR}")
26−add_definitions(-DBUILT_PLUGINS_DIR="${CMAKE_BINARY_DIR}/plugins")
27−
28−add_executable(listviewwithpageheadertestExec listviewwithpageheadertest.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../../../plugins/DashViews/listviewwithpageheader.cpp)
29−qt5_use_modules(listviewwithpageheadertestExec Test Core Qml)
30−target_link_libraries(listviewwithpageheadertestExec ${Qt5Gui_LIBRARIES} ${Qt5Quick_LIBRARIES})
31−add_custom_target(testlistviewwithpageheader ${CMAKE_CURRENT_BINARY_DIR}/listviewwithpageheadertestExec -o ${CMAKE_BINARY_DIR}/testlistviewwithpageheader.xml,xunitxml -o -,txt)
32−
33−add_executable(listviewwithpageheadertestsectionExec listviewwithpageheadertestsection.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../../../plugins/DashViews/listviewwithpageheader.cpp)
34−qt5_use_modules(listviewwithpageheadertestsectionExec Test Core Qml)
35−target_link_libraries(listviewwithpageheadertestsectionExec ${Qt5Gui_LIBRARIES} ${Qt5Quick_LIBRARIES})
36−add_custom_target(testlistviewwithpageheadersection ${CMAKE_CURRENT_BINARY_DIR}/listviewwithpageheadertestsectionExec -o ${CMAKE_BINARY_DIR}/testlistviewwithpageheadersection.xml,xunitxml -o -,txt)
37−
38−add_executable(listviewwithpageheadertestsectionexternalmodelExec listviewwithpageheadertestsectionexternalmodel.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../../../plugins/DashViews/listviewwithpageheader.cpp)
39−qt5_use_modules(listviewwithpageheadertestsectionexternalmodelExec Test Core Qml)
40−target_link_libraries(listviewwithpageheadertestsectionexternalmodelExec ${Qt5Gui_LIBRARIES} ${Qt5Quick_LIBRARIES})
41−add_custom_target(testlistviewwithpageheadersectionexternalmodel ${CMAKE_CURRENT_BINARY_DIR}/listviewwithpageheadertestsectionexternalmodelExec -o ${CMAKE_BINARY_DIR}/testlistviewwithpageheadersectionexternalmodel.xml,xunitxml -o -,txt)
42−
43−macro(add_dashview_try_test FILENAME TESTNAME)
44− add_executable(${FILENAME}testExec
45− ${FILENAME}test.cpp
46− ${CMAKE_CURRENT_SOURCE_DIR}/../../../plugins/DashViews/${FILENAME}.cpp
47− ${CMAKE_CURRENT_SOURCE_DIR}/../../../plugins/DashViews/abstractdashview.cpp
48− )
49− qt5_use_modules(${FILENAME}testExec Test Core Qml)
50− target_link_libraries(${FILENAME}testExec ${Qt5Gui_LIBRARIES} ${Qt5Quick_LIBRARIES})
51− add_custom_target(test${TESTNAME}
52− ${CMAKE_CURRENT_BINARY_DIR}/${FILENAME}testExec
53− -o ${CMAKE_BINARY_DIR}/test${TESTNAME}.xml,xunitxml
54− -o -,txt
55− DEPENDS ${FILENAME}testExec DashViews-qml
56− )
57−
58− add_executable(${FILENAME}tryExec
59− ${FILENAME}try.cpp
60− ${CMAKE_CURRENT_SOURCE_DIR}/../../../plugins/DashViews/${FILENAME}.cpp
61− ${CMAKE_CURRENT_SOURCE_DIR}/../../../plugins/DashViews/abstractdashview.cpp
62− )
63− qt5_use_modules(${FILENAME}tryExec Test Core Qml)
64− target_link_libraries(${FILENAME}tryExec ${Qt5Gui_LIBRARIES} ${Qt5Quick_LIBRARIES})
65− add_custom_target(try${TESTNAME}
66− ${CMAKE_CURRENT_BINARY_DIR}/${FILENAME}tryExec
67− DEPENDS ${FILENAME}tryExec DashViews-qml
68− )
69−endmacro()
70−
71−add_dashview_try_test(verticaljournal VerticalJournal)
72−add_dashview_try_test(horizontaljournal HorizontalJournal)
73−add_dashview_try_test(organicgrid OrganicGrid)
74−
75−set(qmltest_DEFAULT_NO_ADD_TEST TRUE)
76−add_qml_test(. listviewwithpageheaderqml IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins)
77−
78−add_dependencies(qmluitests testlistviewwithpageheader)
79−add_dependencies(qmluitests testlistviewwithpageheadersection)
80−add_dependencies(qmluitests testlistviewwithpageheadersectionexternalmodel)
81−add_dependencies(qmluitests testlistviewwithpageheaderqml)
82−add_dependencies(qmluitests testVerticalJournal)
83−add_dependencies(qmluitests testHorizontalJournal)
84−add_dependencies(qmluitests testOrganicGrid)
tests/plugins/Ubuntu/Gestures/CMakeLists.txt+1
@@ -20,6 +20,7 @@ macro(add_gesture_ui_test CLASSNAME)
2020 target_link_libraries(${CLASSNAME}TestExec UbuntuGestureQml)
2121
2222 add_binary_qml_test(${CLASSNAME} ${CMAKE_BINARY_DIR}/plugins/Ubuntu/Gestures UbuntuGesturesTestQmlFiles)
23+ add_manual_qml_test(. ${CLASSNAME} IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins)
2324endmacro(add_gesture_ui_test)
2425
2526macro(add_gesture_test CLASSNAME)
tests/plugins/Unity/Indicators/rootactionstatetest.cpp+37
@@ -21,6 +21,7 @@
2121
2222#include <unitymenumodel.h>
2323#include <QtTest>
24+#include <gio/gio.h>
2425
2526class RootActionStateTest : public QObject
2627{
@@ -52,6 +53,42 @@ private Q_SLOTS:
5253 QVERIFY(rootState->menu() == NULL);
5354 delete rootState;
5455 }
56+
57+ void testToQVariantIcons()
58+ {
59+ GVariantBuilder builderIcons;
60+ g_variant_builder_init(&builderIcons, G_VARIANT_TYPE("av"));
61+ for (int i = 0; i < 3; i ++) {
62+
63+ GIcon* icon = NULL;
64+ icon = g_icon_new_for_string (QString("testIcon%1").arg(i).toUtf8().constData(), NULL);
65+
66+ g_variant_builder_add(&builderIcons,
67+ "v",
68+ g_icon_serialize (icon));
69+ g_object_unref(icon);
70+ }
71+
72+ GVariantBuilder builderParams;
73+ g_variant_builder_init(&builderParams, G_VARIANT_TYPE_ARRAY);
74+ GVariant* icons = g_variant_builder_end (&builderIcons);
75+ g_variant_ref_sink (icons);
76+ g_variant_builder_add (&builderParams, "{sv}", g_strdup ("icons"), icons, NULL);
77+
78+ GVariant* params = g_variant_builder_end (&builderParams);
79+
80+ RootActionState rootState;
81+ QVariant result = rootState.toQVariant(params);
82+ g_variant_unref(params);
83+
84+ QVariantMap paramResult = result.toMap();
85+ QVERIFY(paramResult.contains("icons"));
86+
87+ QStringList serializedIcons = paramResult["icons"].toStringList();
88+ QVERIFY(serializedIcons[0] == "image://theme/testIcon0");
89+ QVERIFY(serializedIcons[1] == "image://theme/testIcon1");
90+ QVERIFY(serializedIcons[2] == "image://theme/testIcon2");
91+ }
5592};
5693
5794QTEST_GUILESS_MAIN(RootActionStateTest)
tests/plugins/Unity/Launcher/CMakeLists.txt+3−3
@@ -15,9 +15,9 @@ add_definitions(-DSRCDIR="${CMAKE_CURRENT_SOURCE_DIR}")
1515add_definitions(-DLAUNCHER_TESTING)
1616
1717### LauncherBackendTest
18−set(testBackendCommand ${CMAKE_CURRENT_BINARY_DIR}/launcherbackendtestExec
19− -o ${CMAKE_BINARY_DIR}/launcherbackendtest.xml,xunitxml
20− -o -,txt)
18+set(testBackendCommand dbus-test-runner --task ${CMAKE_CURRENT_BINARY_DIR}/launcherbackendtestExec
19+ --parameter -o --parameter ${CMAKE_BINARY_DIR}/launcherbackendtest.xml,xunitxml
20+ --parameter -o --parameter -,txt)
2121add_test(NAME launcherbackendtest COMMAND ${testBackendCommand})
2222add_custom_target(launcherbackendtest ${testBackendCommand})
2323add_executable(launcherbackendtestExec
tests/plugins/Unity/Launcher/launcherbackendtest.cpp+167
@@ -20,6 +20,10 @@
2020#include "launcherbackend.h"
2121
2222#include <QtTest>
23+#include <QDBusConnection>
24+#include <QDBusMessage>
25+#include <QDBusVariant>
26+
2327
2428class LauncherBackendTest : public QObject
2529{
@@ -66,6 +70,169 @@ private Q_SLOTS:
6670
6771 QCOMPARE(backend.icon(appId), expectedIcon);
6872 }
73+
74+ void testGetItem_data() {
75+ QTest::addColumn<QString>("appId");
76+ QTest::addColumn<bool>("exists");
77+
78+ QTest::newRow("Exists") << "rel-icon" << true;
79+ QTest::newRow("Doesn't Exist") << "does-not-exist" << false;
80+ }
81+
82+ void testGetItem() {
83+ QFETCH(QString, appId);
84+ QFETCH(bool, exists);
85+
86+ LauncherBackend backend;
87+ auto item = backend.getItem(appId);
88+
89+ if (exists) {
90+ QVERIFY(item != nullptr);
91+ } else {
92+ QVERIFY(item == nullptr);
93+ }
94+ }
95+
96+ void testCount_data() {
97+ QTest::addColumn<QString>("appId");
98+ QTest::addColumn<bool>("setCount");
99+ QTest::addColumn<int>("inCount");
100+ QTest::addColumn<bool>("countVisible");
101+ QTest::addColumn<int>("expectedCount");
102+
103+ /* Get baseline data on things working */
104+ QTest::newRow("Baseline") << "rel-icon" << false << 0 << false << -1;
105+
106+ /* Valid count, but not visible */
107+ QTest::newRow("Not visible") << "rel-icon" << true << 42 << false << -1;
108+
109+ /* Turn it on */
110+ QTest::newRow("Visible Count") << "rel-icon" << true << 42 << true << 42;
111+
112+ /* Invalide app to load */
113+ QTest::newRow("Invalid App ID") << "this-app-doesnt-exist" << true << 42 << true << -1;
114+ }
115+
116+ void testCount() {
117+ QFETCH(QString, appId);
118+ QFETCH(bool, setCount);
119+ QFETCH(int, inCount);
120+ QFETCH(bool, countVisible);
121+ QFETCH(int, expectedCount);
122+
123+ LauncherBackend backend;
124+
125+ if (setCount)
126+ backend.setCount(appId, inCount);
127+ backend.setCountVisible(appId, countVisible);
128+
129+ QCOMPARE(backend.count(appId), expectedCount);
130+ }
131+
132+ void testDbusName_data() {
133+ QTest::addColumn<QString>("decoded");
134+ QTest::addColumn<QString>("encoded");
135+
136+ /* Passthrough test */
137+ QTest::newRow("Passthrough") << "fine" << "fine";
138+
139+ /* Number as first characeter */
140+ QTest::newRow("Number first") << "31337" << "_331337";
141+
142+ /* Underscore test */
143+ QTest::newRow("Underscore test") << "this_is_c_style_namespacing" << "this_5Fis_5Fc_5Fstyle_5Fnamespacing";
144+
145+ /* Hyphen test */
146+ QTest::newRow("Hyphen test") << "typical-application" << "typical_2Dapplication";
147+
148+ /* Japanese test */
149+ QTest::newRow("日本語 test") << "日本語" << "_E6_97_A5_E6_9C_AC_E8_AA_9E";
150+ }
151+
152+ void testDbusName() {
153+ QFETCH(QString, decoded);
154+ QFETCH(QString, encoded);
155+
156+ QString encodeOut = LauncherBackend::encodeAppId(decoded);
157+ QCOMPARE(encoded, encodeOut);
158+
159+ QString decodeOut = LauncherBackend::decodeAppId(encoded);
160+ QCOMPARE(decoded, decodeOut);
161+ }
162+
163+ void testDbusIface_data() {
164+ QTest::addColumn<QString>("appId");
165+ QTest::addColumn<bool>("setCount");
166+ QTest::addColumn<int>("inCount");
167+ QTest::addColumn<bool>("countVisible");
168+ QTest::addColumn<int>("expectedCount");
169+
170+ /* Get baseline data on things working */
171+ QTest::newRow("Baseline") << "rel-icon" << false << 0 << false << -1;
172+
173+ /* Turn it on */
174+ QTest::newRow("Visible Count") << "rel-icon" << true << 42 << true << 42;
175+
176+ /* Invalide app to load */
177+ QTest::newRow("Invalid App ID") << "this-app-doesnt-exist" << true << 42 << true << -1;
178+ }
179+
180+ void testDbusIface() {
181+ QFETCH(QString, appId);
182+ QFETCH(bool, setCount);
183+ QFETCH(int, inCount);
184+ QFETCH(bool, countVisible);
185+ QFETCH(int, expectedCount);
186+
187+ QDBusConnection con = QDBusConnection::sessionBus();
188+ QDBusMessage message;
189+ QDBusMessage reply;
190+
191+ LauncherBackend backend;
192+
193+ if (setCount) {
194+ message = QDBusMessage::createMethodCall("com.canonical.Unity.Launcher",
195+ "/com/canonical/Unity/Launcher/" + LauncherBackend::encodeAppId(appId),
196+ "org.freedesktop.DBus.Properties",
197+ "Set");
198+ QVariantList cargs;
199+ cargs.append(QString("com.canonical.Unity.Launcher.Item"));
200+ cargs.append(QString("count"));
201+ cargs.append(QVariant::fromValue(QDBusVariant(inCount)));
202+
203+ message.setArguments(cargs);
204+ reply = con.call(message);
205+ QCOMPARE(reply.type(), QDBusMessage::ReplyMessage);
206+ }
207+
208+ /* Set countVisible */
209+ message = QDBusMessage::createMethodCall("com.canonical.Unity.Launcher",
210+ "/com/canonical/Unity/Launcher/" + LauncherBackend::encodeAppId(appId),
211+ "org.freedesktop.DBus.Properties",
212+ "Set");
213+ QVariantList cvargs;
214+ cvargs.append(QString("com.canonical.Unity.Launcher.Item"));
215+ cvargs.append(QString("countVisible"));
216+ cvargs.append(QVariant::fromValue(QDBusVariant(countVisible)));
217+
218+ message.setArguments(cvargs);
219+ reply = con.call(message);
220+ QCOMPARE(reply.type(), QDBusMessage::ReplyMessage);
221+
222+ /* Get value */
223+ message = QDBusMessage::createMethodCall("com.canonical.Unity.Launcher",
224+ "/com/canonical/Unity/Launcher/" + LauncherBackend::encodeAppId(appId),
225+ "org.freedesktop.DBus.Properties",
226+ "Get");
227+ QVariantList getargs;
228+ getargs.append(QString("com.canonical.Unity.Launcher.Item"));
229+ getargs.append(QString("count"));
230+
231+ message.setArguments(getargs);
232+ reply = con.call(message);
233+ QCOMPARE(reply.type(), QDBusMessage::ReplyMessage);
234+ QCOMPARE(reply.arguments()[0].value<QDBusVariant>().variant().toInt(), expectedCount);
235+ }
69236};
70237
71238QTEST_GUILESS_MAIN(LauncherBackendTest)
tests/plugins/Utils/CMakeLists.txt+2−1
@@ -11,7 +11,8 @@ macro(run_tests)
1111 -o ${CMAKE_BINARY_DIR}/${_test}.xml,xunitxml
1212 -o -,txt)
1313 add_test(NAME ${_test} COMMAND ${testCommand})
14− add_custom_target(${_test} ${testCommand})
14+ set_tests_properties(${_test} PROPERTIES ENVIRONMENT "LC_ALL=C")
15+ add_custom_target(${_test} env "LC_ALL=C" ${testCommand})
1516 add_executable(${_test}Exec ${_test}.cpp modeltest.cpp)
1617 qt5_use_modules(${_test}Exec Test Core Qml)
1718 target_link_libraries(${_test}Exec
tests/qmltests/CMakeLists.txt+5−5
@@ -16,7 +16,7 @@ add_qml_test(utils/Unity/Test UnityTest)
1616
1717set(qmltest_DEFAULT_TARGETS qmluitests)
1818set(qmltest_DEFAULT_NO_ADD_TEST TRUE)
19−set(qmltest_DEFAULT_PROPERTIES "")
19+set(qmltest_DEFAULT_PROPERTIES ENVIRONMENT "LC_ALL=C")
2020
2121add_qml_test(. Shell IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/tests/mocks
2222 ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/LightDM/single")
@@ -28,16 +28,16 @@ add_qml_test(Components LazyImage)
2828add_qml_test(Components Rating)
2929add_qml_test(Components ResponsiveFlowView)
3030add_qml_test(Components ResponsiveGridView)
31−add_qml_test(Components Revealer)
3231add_qml_test(Components SeeMore)
3332add_qml_test(Components Showable)
3433add_qml_test(Components PageHeaderLabel)
34+add_qml_test(Components ZoomableImage)
3535add_qml_test(Dash Dash IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
3636add_qml_test(Dash DashContent IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
37−add_qml_test(Dash Card)
38−add_qml_benchmark(Dash CardBenchmark 1000)
37+add_qml_test(Dash Card IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
38+add_qml_benchmark(Dash CardBenchmark 1000 IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
3939add_qml_test(Dash CardHeader)
40−add_qml_test(Dash CardTool)
40+add_qml_test(Dash CardTool IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
4141add_qml_test(Dash GenericScopeView IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
4242add_qml_test(Dash/Apps RunningApplicationsGrid IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS}
4343 ${CMAKE_BINARY_DIR}/tests/mocks
tests/qmltests/Components/CMakeLists.txt+1
@@ -11,6 +11,7 @@ qt5_use_modules(DragHandleTestExec Test Core Qml Gui Quick)
1111target_link_libraries(DragHandleTestExec UbuntuGestureQml)
1212
1313add_binary_qml_test(DragHandle ${CMAKE_BINARY_DIR}/plugins/Ubuntu/Gestures "")
14+add_manual_qml_test(. DragHandle IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins)
1415
1516add_definitions(-DUBUNTU_GESTURES_PLUGIN_DIR="${CMAKE_BINARY_DIR}/plugins")
1617add_definitions(-DTEST_DIR="${CMAKE_CURRENT_LIST_DIR}")
tests/qmltests/Components/RevealingRectangle.qmldeleted−78
@@ -1,78 +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−
17−import QtQuick 2.0
18−import Ubuntu.Components 0.1
19−import "../../../qml/Components"
20−
21−Item {
22− id: revealingRectangle
23−
24− property int orientation: Qt.Vertical
25− property int direction: Qt.LeftToRight
26− property Revealer revealer: __revealer
27− property Showable showable: __showable
28−
29− Revealer {
30− id: __revealer
31−
32− target: __showable
33− width: target.width
34− height: target.height
35− x: orientation == Qt.Vertical ? 0 : direction == Qt.LeftToRight ? 0 : parent.width - width
36− y: orientation == Qt.Horizontal ? 0 : direction == Qt.LeftToRight ? 0 : parent.height - height
37− handleSize: orientation == Qt.Vertical ? handle.height : handle.width
38− hintDisplacement: handleSize
39− orientation: revealingRectangle.orientation
40− direction: revealingRectangle.direction
41− }
42−
43− Showable {
44− id: __showable
45−
46− width: orientation == Qt.Horizontal ? units.gu(24) : parent.width
47− height: orientation == Qt.Vertical ? units.gu(24) : parent.height
48−
49− shown: false
50− showAnimation: SmoothedAnimation {
51− property: orientation == Qt.Horizontal ? "x" : "y"
52− velocity: __revealer.dragVelocity
53− duration: 200
54− to: __revealer.openedValue
55− }
56− hideAnimation: SmoothedAnimation {
57− property: orientation == Qt.Horizontal ? "x" : "y"
58− velocity: __revealer.dragVelocity
59− duration: 200
60− to: __revealer.closedValue
61− }
62−
63− Rectangle {
64− anchors.fill: parent
65− color: "red"
66− }
67−
68− Rectangle {
69− id: handle
70−
71− x: orientation == Qt.Vertical ? 0 : direction == Qt.LeftToRight ? parent.width - width : 0
72− y: orientation == Qt.Horizontal ? 0 : direction == Qt.LeftToRight ? parent.height - height : 0
73− width: orientation == Qt.Horizontal ? units.gu(2) : parent.width
74− height: orientation == Qt.Vertical ? units.gu(2) : parent.height
75− color: "black"
76− }
77− }
78−}
tests/qmltests/Components/tst_FilterGrid.qml+1−1
@@ -50,6 +50,7 @@ Rectangle {
5050 CheckBox {
5151 id: filterCheckBox
5252 checked: true
53+ onCheckedChanged: filterGrid.setFilter(checked, false /*animate*/)
5354 }
5455 }
5556 }
@@ -99,7 +100,6 @@ Rectangle {
99100 maximumNumberOfColumns: 3
100101 collapsedRowCount:
101102 collapsedRowCountSelector.values[collapsedRowCountSelector.selectedIndex]
102− filter: filterCheckBox.checked
103103 minimumHorizontalSpacing: units.gu(1)
104104 delegateWidth: units.gu(6)
105105 delegateHeight: units.gu(6)
tests/qmltests/Components/tst_PageHeaderLabel.qml+4−4
@@ -26,7 +26,7 @@ Item {
2626 width: units.gu(110)
2727 height: units.gu(30)
2828
29− Scope {
29+ MockScope {
3030 id: scopeMock
3131 }
3232
@@ -148,17 +148,17 @@ Item {
148148
149149 pageHeader.triggerSearch()
150150
151− scopeMock.searchInProgress = false
151+ scopeMock.setSearchInProgress(false);
152152 compare(searchIndicator.running, false, "Search indicator is running.")
153153 tryCompare(primaryImage, "visible", true)
154154
155− scopeMock.searchInProgress = true
155+ scopeMock.setSearchInProgress(true);
156156 compare(searchIndicator.running, true, "Search indicator isn't running.")
157157 tryCompare(primaryImage, "visible", false)
158158 }
159159
160160 function cleanup() {
161− scopeMock.searchInProgress = false;
161+ scopeMock.setSearchInProgress(false);
162162 pageHeader.resetSearch();
163163 }
164164
tests/qmltests/Components/tst_Revealer.qmldeleted−262
@@ -1,262 +0,0 @@
1−/*
2− * Copyright 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−import QtQuick 2.0
18−import QtTest 1.0
19−import Unity.Test 0.1 as UT
20−import ".."
21−
22−/*
23− There's a revealer on each window edge. If you press and hold any edge you
24− should see a black bar appearing from that edge. If you them slide the
25− pointer/finger towards the opposite edge, that black bar should follow
26− the movement up to around the center of the window. Next to the black bar,
27− which represents the "handle" area of the Revealer, You should see a red rectangle,
28− which is the main body of the Showable concrolled by the Revealer (Showable = red
29− + black rects).
30− */
31−Item {
32− width: units.gu(75)
33− height: units.gu(50)
34−
35− RevealingRectangle {
36− id: topRevealingRectangle
37− anchors.fill: parent
38− orientation: Qt.Vertical
39− direction: Qt.LeftToRight
40− }
41−
42− RevealingRectangle {
43− id: bottomRevealingRectangle
44− anchors.fill: parent
45− orientation: Qt.Vertical
46− direction: Qt.RightToLeft
47− }
48−
49− RevealingRectangle {
50− id: leftRevealingRectangle
51− anchors.fill: parent
52− orientation: Qt.Horizontal
53− direction: Qt.LeftToRight
54− }
55−
56− RevealingRectangle {
57− id: rightRevealingRectangle
58− anchors.fill: parent
59− orientation: Qt.Horizontal
60− direction: Qt.RightToLeft
61− }
62−
63− UT.UnityTestCase {
64− name: "Revealer"
65− when: windowShown
66−
67− /*
68− A bit of the showable should be displayed when you press over the
69− handle area of the Revealer.
70−
71− Once released, it should go out of sight again.
72− */
73− function test_showHintOnPress() {
74− var revealer = topRevealingRectangle.revealer
75− var showable = topRevealingRectangle.showable
76−
77− // It starts out of sight
78− compare(showable.y, -showable.height)
79−
80− // (item, x, y, button, modifiers, delay)
81− mousePress(revealer,
82− revealer.width/2,
83− revealer.handleSize/2,
84− Qt.LeftButton, Qt.NoModifier, 0);
85−
86− tryCompare(showable, "y", -showable.height + revealer.handleSize)
87−
88− // (item, x, y, button, modifiers, delay)
89− mouseRelease(revealer,
90− revealer.width/2,
91− revealer.handleSize/2,
92− Qt.LeftButton, Qt.NoModifier, 0);
93−
94− tryCompare(showable, "y", -showable.height)
95− }
96−
97− /*
98− Press over the handle area of the Revealer and drag it to pull
99− its target Showable. Release it half-way and the Showable will
100− continue moving by itself until it's completely shown.
101−
102−
103− Press over the handle area and drag it back to hide the Showable.
104− Release it half-way and it will continue moving by itself until it's
105− completely hidden again.
106− */
107− function test_dragToRevealAndDragBackToHide_top() {
108− var revealer = topRevealingRectangle.revealer
109− var showable = topRevealingRectangle.showable
110− revealer.__dateTime = fakeDateTime
111−
112− // It starts out of sight
113− compare(showable.y, -showable.height)
114−
115− mouseFlick(revealer,
116− revealer.width/2, // from_x
117− revealer.handleSize/2, // from_y
118− revealer.width/2, // to_x
119− showable.height/2); // to_y
120−
121− // Should eventually get fully extended
122− tryCompare(showable, "y", 0)
123−
124− // Now drag it back to get it hidden
125−
126− mouseFlick(revealer,
127− revealer.width/2,
128− showable.height - (revealer.handleSize/2),
129− revealer.width/2,
130− showable.height/2)
131−
132− // Should eventually be completely out of sight
133− tryCompare(showable, "y", -showable.height)
134− }
135−
136− function test_dragToRevealAndDragBackToHide_bottom() {
137− var revealer = bottomRevealingRectangle.revealer
138− var showable = bottomRevealingRectangle.showable
139− var revRect = bottomRevealingRectangle
140− revealer.__dateTime = fakeDateTime
141−
142− // It starts out of sight
143− compare(showable.y, revRect.height)
144−
145− mouseFlick(revealer,
146− revealer.width/2, // from_x
147− revealer.height - revealer.handleSize/2, // from_y
148− revealer.width/2, // to_x
149− revealer.height - showable.height/2); // to_y
150−
151− // Should eventually get fully extended
152− tryCompare(showable, "y", revRect.height - showable.height)
153−
154− // Now drag it back to get it hidden
155−
156− mouseFlick(revealer,
157− revealer.width/2,
158− revealer.handleSize/2,
159− revealer.width/2,
160− revealer.height - showable.height/2)
161−
162− // Should eventually be completely out of sight
163− tryCompare(showable, "y", revRect.height)
164− }
165−
166− function test_dragToRevealAndDragBackToHide_left() {
167− var revealer = leftRevealingRectangle.revealer
168− var showable = leftRevealingRectangle.showable
169− revealer.__dateTime = fakeDateTime
170−
171− // It starts out of sight
172− compare(showable.x, -showable.width)
173−
174− mouseFlick(revealer,
175− revealer.handleSize/2, // from_x
176− revealer.height/2, // from_y
177− showable.width/2, // to_x
178− revealer.height/2) // to_y
179−
180− // Should eventually get fully extended
181− tryCompare(showable, "x", 0)
182−
183− // Now drag it back to get it hidden
184−
185− mouseFlick(revealer,
186− showable.width - (revealer.handleSize/2),
187− revealer.height/2,
188− showable.width/2,
189− revealer.height/2)
190−
191− // Should eventually be completely out of sight
192− tryCompare(showable, "x", -showable.width)
193− }
194−
195− function test_dragToRevealAndDragBackToHide_right() {
196− var revealer = rightRevealingRectangle.revealer
197− var showable = rightRevealingRectangle.showable
198− var revRect = rightRevealingRectangle
199− revealer.__dateTime = fakeDateTime
200−
201− // It starts out of sight
202− compare(showable.x, revRect.width)
203−
204− mouseFlick(revealer,
205− revealer.width - revealer.handleSize/2, // from_x
206− revealer.height/2, // from_y
207− revealer.width - showable.width/2, // to_x
208− revealer.height/2) // to_y
209−
210− // Should eventually get fully extended
211− tryCompare(showable, "x", revRect.width - showable.width)
212−
213− // Now drag it back to get it hidden
214−
215− mouseFlick(revealer,
216− revealer.handleSize/2,
217− revealer.height/2,
218− revealer.width - showable.width/2,
219− revealer.height/2)
220−
221− // Should eventually be completely out of sight
222− tryCompare(showable, "x", revRect.width)
223− }
224−
225− /*
226− Start dragging down (pulling the showable into view) and then,
227− midway, drag a bit upwards and release it.
228− The showable should keep moving away, ending up hidden again.
229− */
230− function test_dragForthAndBackReturnsOriginalState() {
231− var revealer = topRevealingRectangle.revealer
232− var showable = topRevealingRectangle.showable
233− revealer.__dateTime = fakeDateTime
234−
235− // It starts out of sight
236− compare(showable.y, -showable.height)
237−
238− mouseFlick(revealer,
239− revealer.width/2, // from_x
240− revealer.handleSize/2, // from_y
241− revealer.width/2, // to_x
242− showable.height/2, // to_y
243− true /* do press */, false /* don't release */);
244−
245− // Should be about half-extended
246− verify(showable.y > -showable.height*3/4)
247− verify(showable.y < -showable.height*1/4)
248−
249−
250− // Now drag it back a bit
251− mouseFlick(revealer,
252− revealer.width/2, // from_x
253− showable.height/2, // from_y
254− revealer.width/2, // to_x
255− showable.height/4, // to_y
256− false /* don't press */, true /* do release */);
257−
258− // Should eventually be completely out of sight again
259− tryCompare(showable, "y", -showable.height)
260− }
261− }
262−}
tests/qmltests/Components/tst_ZoomableImage.qmlnew file+192
@@ -0,0 +1,192 @@
1+/*
2+ * Copyright 2014 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+import QtQuick 2.0
18+import QtTest 1.0
19+import "../../../qml/Components"
20+import Unity.Test 0.1 as UT
21+
22+Rectangle {
23+ id: root
24+ width: units.gu(30)
25+ height: units.gu(60)
26+ color: "lightgrey"
27+
28+ property var widgetData0: {
29+ "source": "",
30+ "zoomable": false
31+ }
32+
33+ property var widgetData1: {
34+ "source": "../../../qml/graphics/phone_background.jpg",
35+ "zoomable": false
36+ }
37+
38+ property var widgetData2: {
39+ "source": "../../../qml/Dash/graphics/phone/screenshots/gallery@12.png",
40+ "zoomable": true
41+ }
42+
43+ ZoomableImage {
44+ id: zoomableImage
45+ width: parent.width
46+ anchors.fill: parent
47+ asynchronous: false
48+ }
49+
50+ SignalSpy {
51+ id: signalSpy
52+ }
53+
54+ UT.UnityTestCase {
55+ name: "ZoomableImageTest"
56+ when: windowShown
57+
58+ function test_loadImage() {
59+ var lazyImage = findChild(zoomableImage, "lazyImage");
60+
61+ zoomableImage.source = widgetData0["source"];
62+ zoomableImage.zoomable = widgetData0["zoomable"];
63+ waitForRendering(zoomableImage);
64+ tryCompare(zoomableImage, "imageState", "default");
65+
66+ signalSpy.signalName = "onStateChanged";
67+ signalSpy.target = lazyImage;
68+ signalSpy.clear();
69+
70+ zoomableImage.source = widgetData1["source"];
71+ zoomableImage.zoomable = widgetData1["zoomable"];
72+ waitForRendering(lazyImage);
73+ tryCompareFunction(function() { return get_filename(lazyImage.source.toString()) === get_filename(widgetData1["source"]); }, true);
74+ waitForRendering(zoomableImage);
75+ tryCompare(zoomableImage, "imageState", "ready");
76+ compare (signalSpy.count, 1);
77+ }
78+
79+ function get_filename(a) {
80+ var wordsA = a.split("/");
81+ var filenameA = wordsA[wordsA.length-1];
82+ return filenameA;
83+ }
84+
85+ function test_mousewheel() {
86+ var image = findChild(zoomableImage, "image");
87+ var lazyImage = findChild(zoomableImage, "lazyImage");
88+ var flickable = findChild(zoomableImage, "flickable");
89+
90+ zoomableImage.source = widgetData2["source"];
91+ zoomableImage.zoomable = true;
92+ waitForRendering(zoomableImage);
93+
94+ tryCompare(zoomableImage, "imageState", "ready");
95+ tryCompareFunction(function() { return get_filename(lazyImage.source.toString()) === get_filename(widgetData2["source"]); }, true);
96+ waitForRendering(image);
97+
98+ // move mouse to center
99+ mouseMove(zoomableImage, zoomableImage.width / 2, zoomableImage.height / 2);
100+
101+ // Test Zoom-in Zoom-out twice.
102+ for (var c=0; c<2; c++) {
103+ // zoom in
104+ for (var i=0; i<10; i++) {
105+ mouseWheel(zoomableImage, zoomableImage.width / 2, zoomableImage.height / 2, 0, 10);
106+ tryCompare(image, "scale", 1.0 + (i + 1) * 0.1);
107+ compare(flickable.contentWidth, lazyImage.width * image.scale);
108+ compare(flickable.contentHeight, lazyImage.height * image.scale);
109+ }
110+
111+ // zoom out
112+ for (var i=0; i<10; i++) {
113+ mouseWheel(zoomableImage, zoomableImage.width / 2, zoomableImage.height / 2, 0, -10);
114+ tryCompare(image, "scale", 2.0 - (i + 1) * 0.1);
115+ compare(flickable.contentWidth, lazyImage.width * image.scale);
116+ compare(flickable.contentHeight, lazyImage.height * image.scale);
117+ }
118+ }
119+ }
120+
121+ function test_pinch_data() {
122+ return [ { source:widgetData2["source"],
123+ zoomable:false,
124+ answer1: true,
125+ answer2: false,
126+ answer3: true,
127+ answer4: 1.0,
128+ answer5: 1.0 },
129+ { source:widgetData2["source"],
130+ zoomable:true,
131+ answer1: false,
132+ answer2: true,
133+ answer3: false,
134+ answer4: 1.7740461882048026,
135+ answer5: 1.0 }
136+ ]
137+ }
138+
139+ function test_pinch(data) {
140+ var image = findChild(zoomableImage, "image");
141+ var lazyImage = findChild(zoomableImage, "lazyImage");
142+ var flickable = findChild(zoomableImage, "flickable");
143+
144+ signalSpy.signalName = "onScaleChanged";
145+ signalSpy.target = image;
146+ signalSpy.clear();
147+
148+ zoomableImage.source = data.source;
149+ zoomableImage.zoomable = data.zoomable;
150+ waitForRendering(zoomableImage);
151+
152+ tryCompare(zoomableImage, "imageState", "ready");
153+ tryCompareFunction(function() { return get_filename(lazyImage.source.toString()) === get_filename(data.source); }, true);
154+ waitForRendering(image);
155+
156+ var x1Start = zoomableImage.width * 2 / 6;
157+ var y1Start = zoomableImage.height * 2 / 6;
158+ var x1End = zoomableImage.width * 1 / 6;
159+ var y1End = zoomableImage.height * 1 / 6;
160+ var x2Start = zoomableImage.width * 4 / 6;
161+ var y2Start = zoomableImage.height * 4 / 6;
162+ var x2End = zoomableImage.width * 5 / 6;
163+ var y2End = zoomableImage.height * 5 / 6;
164+
165+ var oldScale = image.scale;
166+
167+ // move mouse to center
168+ mouseMove(zoomableImage, zoomableImage.width / 2, zoomableImage.height / 2);
169+
170+ // Test Zoom-in Zoom-out twice.
171+ for (var c=0; c<2; c++) {
172+ wait(3000); // have to delay between two consequent pinch event.
173+ // pinch zoom-in
174+ touchPinch(zoomableImage, x1Start, y1Start, x1End, y1End, x2Start, y2Start, x2End, y2End);
175+
176+ tryCompare(image, "scale", data.answer4);
177+ var newScale = image.scale;
178+ compare(newScale == oldScale, data.answer1, "scale factor not equal: "+ oldScale + "=?" + newScale);
179+ compare(newScale > oldScale, data.answer2, "scale factor didn't changed");
180+ compare(signalSpy.count == 0, data.answer3, "scale signal count error");
181+ compare(newScale, data.answer4, "scale factor error");
182+ compare(flickable.contentWidth, lazyImage.width * image.scale);
183+ compare(flickable.contentHeight, lazyImage.height * image.scale);
184+
185+ wait(3000); // have to delay between two consequent pinch event.
186+ // pinch zoom-out
187+ touchPinch(zoomableImage, x1End, y1End, x1Start, y1Start, x2End, y2End, x2Start, y2Start);
188+ tryCompare(image, "scale", data.answer5);
189+ }
190+ }
191+ }
192+}
tests/qmltests/Dash/Previews/tst_Preview.qml+1−1
@@ -23,7 +23,7 @@ import Unity 0.2 as Unity
2323Rectangle {
2424 id: root
2525 width: units.gu(60)
26− height: units.gu(80)
26+ height: units.gu(60)
2727 color: Theme.palette.selected.background
2828
2929 Item {
tests/qmltests/Dash/Previews/tst_PreviewHeader.qml+66−4
@@ -24,6 +24,12 @@ Rectangle {
2424 width: units.gu(60)
2525 height: units.gu(80)
2626
27+ property var origHeaderjson: {
28+ "title": "THE TITLE",
29+ "subtitle": "Something catchy",
30+ "mascot": "../graphics/play_button.png"
31+ }
32+
2733 property var headerjson: {
2834 "title": "THE TITLE",
2935 "subtitle": "Something catchy",
@@ -43,14 +49,70 @@ Rectangle {
4349 }
4450
4551 UT.UnityTestCase {
52+ id: testCase
4653 name: "PreviewHeaderTest"
4754 when: windowShown
4855
56+ property Item mascot: findChild(previewHeader, "mascotShape")
57+ property Item outerRow: findChild(previewHeader, "outerRow")
58+ property Item column: findChild(previewHeader, "column")
59+
60+ function initTestCase() {
61+ verify(typeof testCase.mascot === "object", "Couldn't find mascot object.");
62+ verify(typeof testCase.outerRow === "object", "Couldn't find outerRow object.");
63+ verify(typeof testCase.column === "object", "Couldn't find column object.");
64+
65+ headerjson.mascot = "";
66+ headerjson.title = "";
67+ headerjson.subtitle = "";
68+ previewHeader.widgetData = headerjson;
69+ }
70+
71+ function test_mascot_data() {
72+ return [
73+ { tag: "Empty", source: "", visible: false },
74+ { tag: "Invalid", source: "bad_path", visible: false },
75+ { tag: "Valid", source: "../graphics/play_button.png", visible: true },
76+ ]
77+ }
78+
79+ function test_mascot(data) {
80+ headerjson.mascot = data.source;
81+ previewHeader.widgetData = headerjson;
82+
83+ tryCompare(testCase.mascot, "visible", data.visible);
84+ }
85+
86+ function test_dimensions_data() {
87+ return [
88+ { tag: "Column width with mascot", object: column, width: previewHeader.width - mascot.width - outerRow.margins * 3, mascot: "artwork/avatar.png" },
89+ { tag: "Header height", object: previewHeader, height: function() { return outerRow.height + outerRow.margins * 2 } },
90+ ]
91+ }
92+
93+ function test_dimensions(data) {
94+ if (data.hasOwnProperty("mascot")) {
95+ headerjson.mascot = data.mascot;
96+ }
97+ previewHeader.widgetData = headerjson;
98+
99+ if (data.hasOwnProperty("width")) {
100+ tryCompare(data.object, "width", data.width);
101+ }
102+
103+ if (data.hasOwnProperty("height")) {
104+ tryCompareFunction(function() { return data.object.height === data.height() }, true);
105+ }
106+ }
107+
49108 function test_json() {
50− var cardHeader = findChild(previewHeader, "cardHeader");
51− compare(cardHeader.title, "THE TITLE");
52− compare(cardHeader.subtitle, "Something catchy");
53− compare(cardHeader.mascot.toString().slice(-24), "graphics/play_button.png");
109+ headerjson = origHeaderjson;
110+ previewHeader.widgetData = headerjson;
111+
112+ var innerPreviewHeader = findChild(previewHeader, "innerPreviewHeader");
113+ compare(innerPreviewHeader.title, "THE TITLE");
114+ compare(innerPreviewHeader.subtitle, "Something catchy");
115+ compare(innerPreviewHeader.mascot.toString().slice(-24), "graphics/play_button.png");
54116 }
55117 }
56118}
tests/qmltests/Dash/Previews/tst_PreviewRatingInput.qml+21−2
@@ -36,6 +36,8 @@ Rectangle {
3636 property var triggeredDataReviewOnly: { "rating": invalidInputRating, "review": validInputText, "author": null }
3737
3838 property var widgetDataBoth: { "visible": "both", "required": "both" }
39+ property var widgetDataBothRequireRating: { "visible": "both", "required": "rating" }
40+ property var widgetDataBothRequireReview: { "visible": "both", "required": "review" }
3941 property var widgetDataRating: { "visible": "rating", "required": "rating" }
4042 property var widgetDataRatingBroken: { "visible": "rating", "required": "review" }
4143 property var widgetDataReview: { "visible": "review", "required": "review" }
@@ -85,6 +87,14 @@ Rectangle {
8587 {tag: "both, rating-only review", widgetData: widgetDataBoth, inputRating: validInputRating, inputText: invalidInputText, emitted: false},
8688 {tag: "both, review-only review", widgetData: widgetDataBoth, inputRating: invalidInputRating, inputText: validInputText, emitted: false},
8789 {tag: "both, complete review", widgetData: widgetDataBoth, inputRating: validInputRating, inputText: validInputText, emitted: true},
90+ {tag: "both require rating, null review", widgetData: widgetDataBothRequireRating, inputRating: invalidInputRating, inputText: invalidInputText, emitted: false},
91+ {tag: "both require rating, rating-only review", widgetData: widgetDataBothRequireRating, inputRating: validInputRating, inputText: invalidInputText, emitted: true},
92+ {tag: "both require rating, review-only review", widgetData: widgetDataBothRequireRating, inputRating: invalidInputRating, inputText: validInputText, emitted: false},
93+ {tag: "both require rating, complete review", widgetData: widgetDataBothRequireRating, inputRating: validInputRating, inputText: validInputText, emitted: true},
94+ {tag: "both require review, null review", widgetData: widgetDataBothRequireReview, inputRating: invalidInputRating, inputText: invalidInputText, emitted: false},
95+ {tag: "both require review, rating-only review", widgetData: widgetDataBothRequireReview, inputRating: validInputRating, inputText: invalidInputText, emitted: false},
96+ {tag: "both require review, review-only review", widgetData: widgetDataBothRequireReview, inputRating: invalidInputRating, inputText: validInputText, emitted: true},
97+ {tag: "both require review, complete review", widgetData: widgetDataBothRequireReview, inputRating: validInputRating, inputText: validInputText, emitted: true},
8898 {tag: "rating, null review", widgetData: widgetDataRating, inputRating: invalidInputRating, inputText: invalidInputText, emitted: false},
8999 {tag: "rating, rating-only review", widgetData: widgetDataRating, inputRating: validInputRating, inputText: invalidInputText, emitted: true},
90100 {tag: "rating, review-only review", widgetData: widgetDataRating, inputRating: invalidInputRating, inputText: validInputText, emitted: false},
@@ -114,7 +124,9 @@ Rectangle {
114124 verify(rating.visible === true);
115125
116126 rating.value = data.inputRating;
117− if (data.widgetData["required"] !== "rating" || data.inputRating < 0) {
127+ if (data.widgetData["required"] !== "rating" ||
128+ data.widgetData["visible"] !== "rating" ||
129+ data.inputRating < 0) {
118130 compare(spy.count, 0);
119131 } else {
120132 compare(spy.count, 1);
@@ -129,7 +141,14 @@ Rectangle {
129141 reviewTextArea.text = data.inputText;
130142 mouseClick(submitButton, submitButton.width / 2, submitButton.height / 2);
131143 switch (data.widgetData["required"]) {
132− case "rating": compare(spy.count, 0); break;
144+ case "rating": {
145+ if (rating.visible === false || data.inputRating < 0) {
146+ compare(spy.count, 0);
147+ } else {
148+ compare(spy.count, 1);
149+ }
150+ break;
151+ }
133152 case "both":
134153 default: {
135154 if (data.inputRating < 0 || data.inputText === "") {
tests/qmltests/Dash/Previews/tst_PreviewTextSummary.qml+5−5
@@ -42,7 +42,7 @@ Rectangle {
4242
4343 PreviewTextSummary {
4444 id: previewTextSummary
45− anchors.fill: parent
45+ anchors { left: parent.left; right: parent.right }
4646 widgetData: widgetDataComplete
4747 }
4848
@@ -51,6 +51,7 @@ Rectangle {
5151 when: windowShown
5252
5353 property var textLabel: findChild(previewTextSummary, "textLabel")
54+ property var titleLabel: findChild(previewTextSummary, "titleLabel")
5455
5556 function init() {
5657 verify(typeof textLabel === "object", "TextLabel object could not be found.")
@@ -61,16 +62,14 @@ Rectangle {
6162 }
6263
6364 function test_optional_title() {
64− var titleLabel = findChild(previewTextSummary, "titleLabel")
65−
6665 // verify titleLabel is visible and textLabel is anchored below it
6766 compare(titleLabel.visible, true)
68− compare(textLabel.y, titleLabel.height)
67+ tryCompare(textLabel, "y", titleLabel.height)
6968
7069 // verify titleLabel disappears and textLabel moves up
7170 previewTextSummary.widgetData = widgetDataNoTitle
7271 compare(titleLabel.visible, false)
73− compare(textLabel.y, 0)
72+ tryCompare(textLabel, "y", 0)
7473 }
7574
7675 function test_see_more() {
@@ -96,6 +95,7 @@ Rectangle {
9695 verify(textLabel.lineCount <= textLabel.maximumCollapsedLineCount)
9796 compare(seeMore.visible, false)
9897 tryCompare(textLabel, "height", textLabel.contentHeight)
98+ tryCompare(previewTextSummary, "height", titleLabel.height + textLabel.height)
9999 }
100100 }
101101}
tests/qmltests/Dash/Previews/tst_PreviewZoomableImage.qml+6−3
@@ -36,7 +36,8 @@ Rectangle {
3636
3737 PreviewZoomableImage {
3838 id: zoomableImage
39− width: parent.width
39+ anchors.fill: parent
40+ widgetData: widgetData1
4041 }
4142
4243 UT.UnityTestCase {
@@ -47,10 +48,12 @@ Rectangle {
4748 var image = findChild(zoomableImage, "image");
4849
4950 zoomableImage.widgetData = widgetData0;
50− tryCompare(image, "state", "default");
51+ waitForRendering(zoomableImage);
52+ tryCompare(image, "imageState", "default");
5153
5254 zoomableImage.widgetData = widgetData1;
53− tryCompare(image, "state", "ready");
55+ waitForRendering(zoomableImage);
56+ tryCompare(image, "imageState", "ready");
5457 }
5558 }
5659}
tests/qmltests/Dash/tst_Card.qml+78−92
@@ -29,8 +29,8 @@ Rectangle {
2929
3030 property string cardData: '
3131 {
32− "art": "../../tests/qmltests/Dash/artwork/music-player-design.png",
33− "mascot": "../../tests/qmltests/Dash/artwork/avatar.png",
32+ "art": "../../../tests/qmltests/Dash/artwork/music-player-design.png",
33+ "mascot": "../../../tests/qmltests/Dash/artwork/avatar.png",
3434 "title": "foo",
3535 "subtitle": "bar",
3636 "summary": "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
@@ -98,21 +98,26 @@ Rectangle {
9898
9999 CardTool {
100100 id: cardTool
101− template: card.template
102− components: card.components
101+ template: Helpers.update(JSON.parse(Helpers.defaultLayout), Helpers.tryParse(layoutArea.text, layoutError))['template'];
102+ components: Helpers.update(JSON.parse(Helpers.defaultLayout), Helpers.tryParse(layoutArea.text, layoutError))['components'];
103103 viewWidth: units.gu(48)
104104 }
105105
106− Card {
107− id: card
108− anchors { top: parent.top; left: parent.left; margins: units.gu(1) }
106+ readonly property var card: loader.item
109107
110− width: cardTool.cardWidth || implicitWidth
111− height: cardTool.cardHeight || implicitHeight
108+ Loader {
109+ id: loader
110+ anchors { top: parent.top; left: parent.left; margins: units.gu(1) }
112111
113− template: Helpers.update(JSON.parse(Helpers.defaultLayout), Helpers.tryParse(layoutArea.text, layoutError))['template'];
114− components: Helpers.update(JSON.parse(Helpers.defaultLayout), Helpers.tryParse(layoutArea.text, layoutError))['components'];
115− cardData: Helpers.mapData(dataArea.text, components, dataError)
112+ sourceComponent: cardTool.cardComponent
113+ onLoaded: {
114+ item.template = Qt.binding(function() { return cardTool.template; });
115+ item.components = Qt.binding(function() { return cardTool.components; });
116+ item.cardData = Qt.binding(function() { return Helpers.mapData(dataArea.text, cardTool.components, dataError); });
117+ item.width = Qt.binding(function() { return cardTool.cardWidth || item.implicitWidth; });
118+ item.height = Qt.binding(function() { return cardTool.cardHeight || item.implicitHeight; });
119+ item.fixedHeaderHeight = Qt.binding(function() { return cardTool.headerHeight; });
120+ }
116121 }
117122
118123 Rectangle {
@@ -181,60 +186,45 @@ Rectangle {
181186
182187 when: windowShown
183188
184− property Item header: findChild(card, "cardHeader")
185− property Item headerLoader: findChild(card, "cardHeaderLoader")
186− property Item title: findChild(header, "titleLabel")
187− property Item art: findChild(card, "artShape")
189+ property Item title: findChild(card, "titleLabel")
190+ property Item subtitle: findChild(card, "subtitleLabel")
191+ property var headerRow: findChild(card, "outerRow")
192+ property var art: findChild(card, "artShape")
188193 property Item artImage: findChild(card, "artImage")
189194 property Item summary: findChild(card, "summaryLabel")
190195 property Item background: findChild(card, "background")
191196 property Item backgroundLoader: findChild(card, "backgroundLoader")
192197 property Item backgroundImage: findChild(card, "backgroundImage")
193−
194− function initTestCase() {
195− verify(typeof testCase.header === "object", "Couldn't find header object.");
196− verify(typeof testCase.art === "object", "Couldn't find art object.");
197− verify(typeof testCase.artImage === "object", "Couldn't find artImage object.");
198− verify(typeof testCase.summary === "object", "Couldn't find summary object.");
199− verify(typeof testCase.artImage === "object", "Couldn't find background object.");
200− verify(typeof testCase.summary === "object", "Couldn't find backgroundImage object.");
201− }
198+ property Item mascotImage: findChild(card, "mascotImage");
202199
203200 function cleanup() {
204201 selector.selectedIndex = -1;
205202 }
206203
207−
208− function test_header_binding_data() {
209− return [
210− { tag: "Mascot", property: "mascot", value: Qt.resolvedUrl("artwork/avatar.png"), index: 0 },
211− { tag: "Title", property: "title", value: "foo", index: 0 },
212− { tag: "Subtitle", property: "subtitle", value: "bar", index: 0 },
213− ];
214− }
215−
216− function test_header_binding(data) {
217− selector.selectedIndex = data.index;
218− tryCompare(testCase.header, data.property, data.value);
219− }
220−
221204 function test_card_binding_data() {
222205 return [
223− { tag: "Art", object: artImage, property: "source", value: Qt.resolvedUrl("artwork/music-player-design.png"), index: 0 },
224− { tag: "Summary", object: summary, property: "text", field: "summary", index: 0 },
225− { tag: "Fit", object: art, fill: Image.PreserveAspectFit, index: 4 },
206+ { tag: "Art", object: "artImage", property: "source", value: Qt.resolvedUrl("artwork/music-player-design.png"), index: 0 },
207+ { tag: "Summary", object: "summary", property: "text", field: "summary", index: 0 },
208+ { tag: "Fit", object: "art", fill: Image.PreserveAspectFit, index: 4 },
209+ { tag: "Mascot", object: "mascotImage", property: "source", value: Qt.resolvedUrl("artwork/avatar.png"), index: 0 },
210+ { tag: "Title", object: "title", property: "text", value: "foo", index: 0 },
211+ { tag: "Subtitle", object: "subtitle", property: "text", value: "bar", index: 0 },
226212 ];
227213 }
228214
229215 function test_card_binding(data) {
230216 selector.selectedIndex = data.index;
217+ waitForRendering(card);
218+
219+ tryCompareFunction(function() { return testCase[data.object] !== null }, true);
220+ var object = testCase[data.object];
231221
232222 if (data.hasOwnProperty('value')) {
233− tryCompare(data.object, data.property, data.value);
223+ tryCompare(object, data.property, data.value);
234224 }
235225
236226 if (data.hasOwnProperty('field')) {
237− tryCompare(data.object, data.property, card.cardData[data.field]);
227+ tryCompare(object, data.property, card.cardData[data.field]);
238228 }
239229 }
240230
@@ -243,31 +233,21 @@ Rectangle {
243233 { tag: "Medium", width: units.gu(18.5), index: 0 },
244234 { tag: "Small", width: units.gu(12), index: 1 },
245235 { tag: "Large", width: units.gu(38), index: 2 },
246− { tag: "Wide", width: units.gu(18.5), aspect: 0.5, index: 0 },
236+ { tag: "Wide", width: units.gu(18.5), index: 0 },
247237 { tag: "Horizontal", width: units.gu(38), index: 5 },
248238 // Make sure card ends with header when there's no summary
249− { tag: "NoSummary", height: function() { return headerLoader.y + headerLoader.height }, index: 6 },
250− { tag: "HorizontalNoSummary", height: function() { return headerLoader.height }, card_layout: "horizontal", index: 6 },
239+ { tag: "NoSummary", height: function() { var cardToolRow = findChild(cardTool, "outerRow");
240+ return cardToolRow.y + cardToolRow.height + units.gu(1) }, index: 6 },
241+ { tag: "HorizontalNoSummary", height: function() { return headerRow.height + units.gu(2) }, card_layout: "horizontal", index: 6 },
251242 ]
252243 }
253244
254245 function test_card_size(data) {
255− waitForRendering(card);
256246 selector.selectedIndex = data.index;
257247
258− if (data.hasOwnProperty("size")) {
259− card.template['card-size'] = data.size;
260− card.templateChanged();
261− }
262−
263248 if (data.hasOwnProperty("card_layout")) {
264− card.template['card-layout'] = data.card_layout;
265− card.templateChanged();
266− }
267−
268− if (data.hasOwnProperty("aspect")) {
269− card.components['art']['aspect-ratio'] = data.aspect;
270− card.componentsChanged();
249+ cardTool.template['card-layout'] = data.card_layout;
250+ cardTool.templateChanged();
271251 }
272252
273253 if (data.hasOwnProperty("width")) {
@@ -288,25 +268,26 @@ Rectangle {
288268 { tag: "Large", width: units.gu(38), index: 2 },
289269 { tag: "Wide", height: units.gu(19), size: "large", index: 3 },
290270 { tag: "Fit", height: units.gu(38), size: "large", width: units.gu(19), index: 4 },
291− { tag: "VerticalWidth", width: function() { return header.width }, index: 0 },
292− { tag: "HorizontalHeight", height: function() { return header.height }, index: 5 },
293− { tag: "HorizontalWidth", width: function() { return headerLoader.x }, index: 5 },
271+ { tag: "VerticalWidth", width: function() { return headerRow.width + units.gu(1) * 2 }, index: 0 },
272+ { tag: "HorizontalHeight", height: function() { return headerRow.height + units.gu(1) * 2 }, index: 5 },
273+ { tag: "HorizontalWidth", width: function() { return headerRow.x - units.gu(1) }, index: 5 },
294274 ]
295275 }
296276
297277 function test_art_size(data) {
298278 selector.selectedIndex = data.index;
299−
300279 if (data.hasOwnProperty("size")) {
301− card.template['card-size'] = data.size;
302− card.templateChanged();
280+ cardTool.template['card-size'] = data.size;
281+ cardTool.templateChanged();
303282 }
304283
305284 if (data.hasOwnProperty("aspect")) {
306− card.components['art']['aspect-ratio'] = data.aspect;
307− card.componentsChanged();
285+ cardTool.components['art']['aspect-ratio'] = data.aspect;
286+ cardTool.componentsChanged();
308287 }
309288
289+ waitForRendering(card);
290+
310291 if (data.hasOwnProperty("width")) {
311292 if (typeof data.width === "function") {
312293 tryCompareFunction(function() { return art.width === data.width() }, true);
@@ -326,38 +307,40 @@ Rectangle {
326307
327308 function test_art_layout_data() {
328309 return [
329− { tag: "Vertical", left: function() { return 0 }, index: 0},
330− { tag: "Horizontal", left: function() { return art.width }, index: 5 },
310+ { tag: "Vertical", left: function() { return units.gu(1); }, index: 0},
311+ { tag: "Horizontal", left: function() { return art.width + units.gu(1); }, index: 5 },
331312 ];
332313 }
333314
334315 function test_art_layout(data) {
335316 selector.selectedIndex = data.index;
317+ waitForRendering(card);
336318
337− tryCompare(testCase.headerLoader, "x", data.left());
319+ tryCompare(headerRow, "x", data.left());
338320 }
339321
340322 function test_header_layout_data() {
341323 return [
342− { tag: "Vertical", top: function() { return art.y + art.height },
343− left: function() { return art.x }, index: 0 },
344− { tag: "Horizontal", top: function() { return art.y },
345− left: function() { return art.x + art.width }, index: 5 },
346− { tag: "Overlay", top: function() { return art.y + art.height - header.height },
347− left: function() { return art.x }, index: 9 },
324+ { tag: "Vertical", top: function() { return art.y + art.height + units.gu(1) },
325+ left: function() { return art.x + units.gu(1) }, index: 0 },
326+ { tag: "Horizontal", top: function() { return art.y + units.gu(1) },
327+ left: function() { return art.x + art.width + units.gu(1) }, index: 5 },
328+ { tag: "Overlay", top: function() { return art.y + art.height - headerRow.height - units.gu(1) },
329+ left: function() { return art.x + units.gu(1) }, index: 9 },
348330 ]
349331 }
350332
351333 function test_header_layout(data) {
352334 selector.selectedIndex = data.index;
335+ waitForRendering(card);
353336
354− tryCompareFunction(function() { return testCase.headerLoader.y === data.top() }, true);
355− tryCompareFunction(function() { return testCase.headerLoader.x === data.left() }, true);
337+ tryCompareFunction(function() { return testCase.headerRow.y === data.top() }, true);
338+ tryCompareFunction(function() { return testCase.headerRow.x === data.left() }, true);
356339 }
357340
358341 function test_summary_layout_data() {
359342 return [
360− { tag: "With header", top: function() { return headerLoader.y + headerLoader.height }, index: 0 },
343+ { tag: "With header", top: function() { return headerRow.y + headerRow.height + units.gu(1); }, index: 0 },
361344 { tag: "Without header", top: function() { return art.y + art.height }, index: 7 },
362345 ]
363346 }
@@ -365,16 +348,16 @@ Rectangle {
365348 function test_summary_layout(data) {
366349 selector.selectedIndex = data.index;
367350
351+ waitForRendering(card);
352+
368353 tryCompareFunction(function() { return testCase.summary.y === data.top() }, true);
369354 }
370355
371356 function test_art_visibility() {
372357 selector.selectedIndex = 8;
373358
374− tryCompare(testCase.artImage, "source", "");
375− compare(testCase.art.visible, false);
376− compare(testCase.art.height, 0);
377− compare(testCase.art.width, 0);
359+ compare(testCase.artImage, null);
360+ compare(testCase.art, null);
378361 }
379362
380363 function test_background_data() {
@@ -402,7 +385,11 @@ Rectangle {
402385
403386 waitForRendering(card);
404387
405− tryCompare(backgroundLoader, "active", data.visible);
388+ if (data.visible) {
389+ tryCompare(backgroundLoader, "active", true);
390+ } else {
391+ compare(backgroundLoader, null);
392+ }
406393
407394 if (data.hasOwnProperty("color")) {
408395 tryCompare(background, "color", data.color);
@@ -449,13 +436,15 @@ Rectangle {
449436
450437 function test_fontColor(data) {
451438 selector.selectedIndex = 10;
439+ waitForRendering(card);
452440
453441 background.color = data.tag;
454442
455443 var fontColor = data.dark ? "grey" : "white";
456444
457445 tryCompareFunction(function() { return Qt.colorEqual(summary.color, fontColor); }, true);
458− tryCompareFunction(function() { return Qt.colorEqual(header.fontColor, fontColor); }, true);
446+ tryCompareFunction(function() { return Qt.colorEqual(title.color, fontColor); }, true);
447+ tryCompareFunction(function() { return Qt.colorEqual(subtitle.color, fontColor); }, true);
459448 }
460449
461450 function test_mascotShape_data() {
@@ -468,15 +457,12 @@ Rectangle {
468457
469458 function test_mascotShape(data) {
470459 selector.selectedIndex = data.index;
460+ waitForRendering(card);
471461
472462 var shape = findChild(card, "mascotShapeLoader");
473− var image = findChild(card, "mascotImage");
474−
475− verify(shape, "Could not find shape.");
476− verify(image, "Could not find image.");
477463
478− tryCompare(shape, "active", data.shape);
479− tryCompare(image, "visible", !data.shape);
464+ compare(shape !== null, data.shape);
465+ tryCompare(mascotImage, "visible", !data.shape);
480466 }
481467 }
482468}
tests/qmltests/Dash/tst_CardBenchmark.qml+10−7
@@ -54,13 +54,16 @@ Rectangle {
5454 Repeater {
5555 id: cardRepeater
5656 model: 0
57− Card {
58− width: cardTool.cardWidth || implicitWidth
59− height: cardTool.cardHeight || implicitHeight
60−
61− template: cardTool.template
62− components: cardTool.components
63− cardData: Helpers.mapData(root.cardData, components)
57+ Loader {
58+ sourceComponent: cardTool.cardComponent
59+ onLoaded: {
60+ item.objectName = "delegate" + index;
61+ item.width = Qt.binding(function() { return cardTool.cardWidth || implicitWidth; });
62+ item.height = Qt.binding(function() { return cardTool.cardHeight || implicitHeight; });
63+ item.cardData = Qt.binding(function() { return Helpers.mapData(root.cardData, cardTool.components); });
64+ item.template = Qt.binding(function() { return cardTool.template; });
65+ item.components = Qt.binding(function() { return cardTool.components; });
66+ }
6467 }
6568 }
6669
tests/qmltests/Dash/tst_CardHeader.qmldeleted−116
@@ -1,116 +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−
17−import QtQuick 2.0
18−import QtTest 1.0
19−import Ubuntu.Components 0.1
20−import Unity.Test 0.1 as UT
21−import "../../../qml/Dash"
22−
23−
24−Rectangle {
25− width: units.gu(40)
26− height: units.gu(72)
27− color: "lightgrey"
28−
29− CardHeader {
30− id: cardHeader
31− anchors { left: parent.left; right: parent.right }
32− }
33−
34− Rectangle {
35− anchors.fill: cardHeader
36− color: "lightblue"
37− opacity: 0.5
38− }
39−
40− UT.UnityTestCase {
41− id: testCase
42− name: "CardHeader"
43−
44− when: windowShown
45−
46− property Item mascot: findChild(cardHeader, "mascotShapeLoader")
47− property Item titleLabel: findChild(cardHeader, "titleLabel")
48− property Item subtitleLabel: findChild(cardHeader, "subtitleLabel")
49− property Item oldPriceLabel: findChild(cardHeader, "oldPriceLabel")
50− property Item outerRow: findChild(cardHeader, "outerRow")
51− property Item column: findChild(cardHeader, "column")
52−
53− function initTestCase() {
54− verify(typeof testCase.mascot === "object", "Couldn't find mascot object.");
55− verify(typeof testCase.titleLabel === "object", "Couldn't find titleLabel object.");
56− verify(typeof testCase.subtitleLabel === "object", "Couldn't find subtitleLabel object.");
57− verify(typeof testCase.oldPriceLabel === "object", "Couldn't find oldPriceLabel object.");
58− }
59−
60− function cleanup() {
61− cardHeader.mascot = "";
62− cardHeader.title = "";
63− cardHeader.subtitle = "";
64− }
65−
66− function test_mascot_data() {
67− return [
68− { tag: "Empty", source: "", visible: false },
69− { tag: "Invalid", source: "bad_path", visible: false },
70− { tag: "Valid", source: Qt.resolvedUrl("artwork/avatar.png"), visible: true },
71− ]
72− }
73−
74− function test_mascot(data) {
75− cardHeader.mascot = data.source;
76− tryCompare(testCase.mascot, "visible", data.visible);
77− }
78−
79− function test_labels_data() {
80− return [
81− { tag: "Empty", visible: false },
82− { tag: "Title only", title: "Foo", visible: true },
83− { tag: "Subtitle only", subtitle: "Bar", visible: false },
84− { tag: "Both", title: "Foo", subtitle: "Bar", visible: true },
85− ]
86− }
87−
88− function test_labels(data) {
89− cardHeader.title = data.title !== undefined ? data.title : "";
90− cardHeader.subtitle = data.subtitle !== undefined ? data.subtitle : "";
91− tryCompare(cardHeader, "visible", data.visible);
92− }
93−
94− function test_dimensions_data() {
95− return [
96− { tag: "Column width", object: column, width: cardHeader.width },
97− { tag: "Column width with mascot", object: column, width: cardHeader.width - mascot.width - outerRow.margins * 3, mascot: "artwork/avatar.png" },
98− { tag: "Header height", object: cardHeader, height: function() { return outerRow.height + outerRow.margins * 2 } },
99− ]
100− }
101−
102− function test_dimensions(data) {
103− if (data.hasOwnProperty("mascot")) {
104− cardHeader.mascot = data.mascot;
105− }
106−
107− if (data.hasOwnProperty("width")) {
108− tryCompare(data.object, "width", data.width);
109− }
110−
111− if (data.hasOwnProperty("height")) {
112− tryCompareFunction(function() { return data.object.height === data.height() }, true);
113− }
114− }
115− }
116−}
tests/qmltests/Dash/tst_CardTool.qml+11−31
@@ -127,26 +127,6 @@ Rectangle {
127127 }
128128 }
129129 }
130−
131− Card {
132− id: card
133− template: cardTool.template;
134− components: cardTool.components;
135− cardData: Helpers.mapData(dataArea.text, components, dataError)
136−
137− width: cardTool.cardWidth || implicitWidth
138− height: cardTool.cardHeight || implicitHeight
139−
140− clip: true
141− headerAlignment: cardTool.headerAlignment
142−
143− Rectangle {
144− anchors.fill: parent
145− color: "transparent"
146− border.width: 1
147− border.color: "green"
148− }
149− }
150130 }
151131
152132 Rectangle {
@@ -257,7 +237,7 @@ Rectangle {
257237 id: testCase
258238 name: "Card"
259239
260− property Card internalCard: findChild(cardTool, "cardToolCard")
240+ property var internalCard: findChild(cardTool, "cardToolCard")
261241
262242 when: windowShown
263243
@@ -272,16 +252,16 @@ Rectangle {
272252
273253 function test_card_size_data() {
274254 return [
275− { tag: "Medium", width: units.gu(18.5), height: function() { return card.height }, index: 0 },
276− { tag: "No art", width: units.gu(18.5), height: function() { return card.height }, index: 1 },
277− { tag: "No summary", width: units.gu(18.5), height: function() { return card.height }, index: 2 },
278− { tag: "Just header", width: units.gu(18.5), height: function() { return card.height }, index: 3 },
279− { tag: "Just title", width: units.gu(18.5), height: function() { return card.height }, index: 4 },
280− { tag: "Title and subtitle", width: units.gu(18.5), height: function() { return card.height }, index: 5 },
281− { tag: "Title and mascot", width: units.gu(18.5), height: function() { return card.height }, index: 6 },
282− { tag: "Small", width: units.gu(12), height: function() { return card.height }, index: 7 },
283− { tag: "Large", width: units.gu(38), height: function() { return card.height }, index: 8 },
284− { tag: "Horizontal", width: units.gu(38), height: function() { return card.height }, index: 9 },
255+ { tag: "Medium", width: units.gu(18.5), height: function() { return internalCard ? internalCard.height : 0 }, index: 0 },
256+ { tag: "No art", width: units.gu(18.5), height: function() { return internalCard ? internalCard.height : 0 }, index: 1 },
257+ { tag: "No summary", width: units.gu(18.5), height: function() { return internalCard ? internalCard.height : 0 }, index: 2 },
258+ { tag: "Just header", width: units.gu(18.5), height: function() { return internalCard ? internalCard.height : 0 }, index: 3 },
259+ { tag: "Just title", width: units.gu(18.5), height: function() { return internalCard ? internalCard.height : 0 }, index: 4 },
260+ { tag: "Title and subtitle", width: units.gu(18.5), height: function() { return internalCard ? internalCard.height : 0 }, index: 5 },
261+ { tag: "Title and mascot", width: units.gu(18.5), height: function() { return internalCard ? internalCard.height : 0 }, index: 6 },
262+ { tag: "Small", width: units.gu(12), height: function() { return internalCard ? internalCard.height : 0 }, index: 7 },
263+ { tag: "Large", width: units.gu(38), height: function() { return internalCard ? internalCard.height : 0 }, index: 8 },
264+ { tag: "Horizontal", width: units.gu(38), height: function() { return internalCard ? internalCard.height : 0 }, index: 9 },
285265 { tag: "OrganicGrid", width: undefined, height: undefined, index: 0, layout_index: 1},
286266 { tag: "Journal", width: undefined, height: units.gu(20), size: 20, index: 0, layout_index: 2 },
287267 { tag: "OversizedJournal", width: undefined, height: units.gu(18.5), size: 40, index: 0, layout_index: 2 },
tests/qmltests/Dash/tst_Dash.qml+1−1
@@ -127,7 +127,7 @@ Item {
127127 var dashContent = findChild(dash, "dashContent");
128128 var current_index = dashContent.currentIndex;
129129
130− tabbar.selectedIndex = data.visualIndex;
130+ tabbar.model.selectedIndex = data.visualIndex;
131131 compare(dashContent.currentIndex, data.shouldBeVisible ? data.visualIndex : current_index);
132132 }
133133 }
tests/qmltests/Dash/tst_DashContent.qml+5−5
@@ -166,7 +166,7 @@ Item {
166166
167167 // test greater than scope count.
168168 var currentScopeIndex = dashContent.currentIndex;
169− dashContent.setCurrentScopeAtIndex(scopesModel.count, true, false);
169+ dashContent.setCurrentScopeAtIndex(8, true, false);
170170 compare(dashContent.currentIndex, currentScopeIndex, "Scope should not change if changing to greater index than count");
171171 }
172172
@@ -195,7 +195,7 @@ Item {
195195 dashContent.setCurrentScopeAtIndex(data.index, true, false);
196196 tryCompareFunction(get_current_item_object_name, data.objectName)
197197 var pageHeader = findChild(dashContent, "pageHeader");
198− compare(pageHeader.scope, scopesModel.get(data.index));
198+ compare(pageHeader.scope, scopesModel.getScope(data.index));
199199 }
200200
201201 function test_is_active_data() {
@@ -212,9 +212,9 @@ Item {
212212 dashContent.setCurrentScopeAtIndex(data.select, true, false);
213213 dashContent.visible = data.visible;
214214
215− tryCompare(scopesModel.get(0), "isActive", data.active0);
216− tryCompare(scopesModel.get(1), "isActive", data.active1);
217− tryCompare(scopesModel.get(2), "isActive", data.active2);
215+ tryCompare(scopesModel.getScope(0), "isActive", data.active0);
216+ tryCompare(scopesModel.getScope(1), "isActive", data.active1);
217+ tryCompare(scopesModel.getScope(2), "isActive", data.active2);
218218 }
219219
220220 function doFindMusicButton(parent) {
tests/qmltests/Dash/tst_GenericScopeView.qml+14−14
@@ -39,7 +39,7 @@ Item {
3939 id: scopes
4040
4141 onLoadedChanged: {
42− genericScopeView.scope = scopes.get(2)
42+ genericScopeView.scope = scopes.getScope(2)
4343 }
4444 }
4545
@@ -67,7 +67,7 @@ Item {
6767 when: scopes.loaded && windowShown
6868
6969 function init() {
70− genericScopeView.scope = scopes.get(2)
70+ genericScopeView.scope = scopes.getScope(2)
7171 shell.width = units.gu(120)
7272 genericScopeView.categoryView.positionAtBeginning();
7373 tryCompare(genericScopeView.categoryView, "contentY", 0)
@@ -96,31 +96,31 @@ Item {
9696
9797 function test_showDash() {
9898 previewListView.open = true;
99− scopes.get(2).showDash();
99+ scopes.getScope(2).showDash();
100100 tryCompare(previewListView, "open", false);
101101 }
102102
103103 function test_hideDash() {
104104 previewListView.open = true;
105− scopes.get(2).hideDash();
105+ scopes.getScope(2).hideDash();
106106 tryCompare(previewListView, "open", false);
107107 }
108108
109109 function test_searchQuery() {
110− genericScopeView.scope = scopes.get(0);
110+ genericScopeView.scope = scopes.getScope(0);
111111 genericScopeView.scope.searchQuery = "test";
112− genericScopeView.scope = scopes.get(1);
112+ genericScopeView.scope = scopes.getScope(1);
113113 genericScopeView.scope.searchQuery = "test2";
114− genericScopeView.scope = scopes.get(0);
114+ genericScopeView.scope = scopes.getScope(0);
115115 tryCompare(genericScopeView.scope, "searchQuery", "test");
116− genericScopeView.scope = scopes.get(1);
116+ genericScopeView.scope = scopes.getScope(1);
117117 tryCompare(genericScopeView.scope, "searchQuery", "test2");
118118 }
119119
120120 function test_changeScope() {
121121 genericScopeView.scope.searchQuery = "test"
122− genericScopeView.scope = scopes.get(1)
123− genericScopeView.scope = scopes.get(2)
122+ genericScopeView.scope = scopes.getScope(1)
123+ genericScopeView.scope = scopes.getScope(2)
124124 tryCompare(genericScopeView.scope, "searchQuery", "test")
125125 }
126126
@@ -140,7 +140,7 @@ Item {
140140 mouseClick(header, header.width / 2, header.height / 2);
141141 tryCompareFunction(function() { middleHeight = category.height; return category.height > initialHeight; }, true);
142142 tryCompare(category, "filtered", false);
143− verify(category.height > middleHeight);
143+ tryCompareFunction(function() { return category.height > middleHeight; }, true);
144144
145145 mouseClick(header, header.width / 2, header.height / 2);
146146 verify(category.expandable);
@@ -165,7 +165,7 @@ Item {
165165
166166 mouseClick(header2, header2.width / 2, header2.height / 2);
167167 tryCompare(category2, "filtered", false);
168− tryCompare(category2FilterGrid, "filter", false);
168+ tryCompare(category2FilterGrid, "filtered", false);
169169
170170 categoryListView.positionAtBeginning();
171171
@@ -182,7 +182,7 @@ Item {
182182 mouseClick(header0, header0.width / 2, header0.height / 2);
183183 tryCompare(category0, "filtered", false);
184184 tryCompare(category2, "filtered", true);
185− tryCompare(category2FilterGrid, "filter", true);
185+ tryCompare(category2FilterGrid, "filtered", true);
186186 mouseClick(header0, header0.width / 2, header0.height / 2);
187187 tryCompare(category0, "filtered", true);
188188 tryCompare(category2, "filtered", true);
@@ -199,7 +199,7 @@ Item {
199199 var header0 = findChild(genericScopeView, "dashSectionHeader0")
200200 mouseClick(header0, header0.width / 2, header0.height / 2);
201201 tryCompare(category, "filtered", false);
202− tryCompare(category.item, "delegateCreationEnd", category.item.delegateCreationBegin + genericScopeView.height);
202+ tryCompareFunction(function() { return category.item.height == genericScopeView.height - category.item.displayMarginBeginning - category.item.displayMarginEnd; }, true);
203203 mouseClick(header0, header0.width / 2, header0.height / 2);
204204 tryCompare(category, "filtered", true);
205205 }
tests/qmltests/Greeter/tst_Clock.qml+3−3
@@ -71,10 +71,10 @@ Rectangle {
7171 var dateString = Qt.formatDate(dateObj, Qt.DefaultLocaleLongDate)
7272 var timeString = Qt.formatTime(dateObj)
7373
74− clock.enabled = false
74+ clock.visible = false
7575 var timeModel = findInvisibleChild(clock, "timeModel")
7676
77− compare(timeModel.menuObjectPath, "", "Clock shouldn't be connected to Indicators when not active.")
77+ compare(timeModel.menuObjectPath, "", "Clock shouldn't be connected to Indicators when not visible.")
7878
7979 clock.currentDate = dateObj
8080
@@ -83,7 +83,7 @@ Rectangle {
8383 var timeLabel = findChild(clock, "timeLabel")
8484 compare(timeLabel.text, timeString, "Not the expected time")
8585
86− clock.enabled = true
86+ clock.visible = true
8787
8888 verify(timeModel.menuObjectPath != "", "Should be connected to Indicators.")
8989 }
tests/qmltests/Greeter/tst_Phone.qml+10−50
@@ -61,6 +61,12 @@ Item {
6161 signalName: "unlocked"
6262 }
6363
64+ SignalSpy {
65+ id: teaseSpy
66+ target: greeter
67+ signalName: "tease"
68+ }
69+
6470 UT.UnityTestCase {
6571 name: "Greeter"
6672 when: windowShown
@@ -82,56 +88,10 @@ Item {
8288 }
8389
8490 function test_teasingArea(data) {
85− tryCompare(greeter, "leftTeaserPressed", false)
86− tryCompare(greeter, "rightTeaserPressed", false)
87− mousePress(greeter, data.posX, greeter.height - units.gu(1))
88− tryCompare(greeter, "leftTeaserPressed", data.leftPressed)
89− tryCompare(greeter, "rightTeaserPressed", data.rightPressed)
90− mouseRelease(greeter, data.posX, greeter.height - units.gu(1))
91− tryCompare(greeter, "leftTeaserPressed", false)
92− tryCompare(greeter, "rightTeaserPressed", false)
93− }
94−
95− function test_teaseLockedUnlocked_data() {
96− return [
97− {tag: "unlocked", locked: false, moved: false},
98− {tag: "locked", locked: true, moved: false},
99− {tag: "moved", locked: false, moved: true}
100− ];
101− }
102−
103− function test_teaseLockedUnlocked(data) {
104− tryCompare(greeter, "rightTeaserPressed", false);
105− tryCompare(greeter, "x", 0);
106− greeter.locked = data.locked;
107−
108− // simulate greeter being in the middle of a swipe
109− if (data.moved) {
110− greeter.x = -units.gu(4);
111− tryCompare(greeter, "x", -units.gu(4));
112− }
113−
114− mouseClick(greeter, greeter.width - units.gu(5), greeter.height - units.gu(1));
115− greeter.minX = 0; // This is needed because the transition actually makes x jump once before animating
116−
117− if (!data.moved) {
118− // Check if it has been moved over by 2 GUs. Give it a 2 pixel grace area
119− // because animation duration and teaseTimer are the same duration and
120− // might cause slight offsets
121− tryCompareFunction(function() { return greeter.minX <= -units.gu(2) + 2}, true);
122− } else {
123− // waiting 100ms to make sure nothing moves
124− wait(100);
125− compare(greeter.minX, 0, "Greeter teasing not disabled even though it's locked or moving.");
126− }
127−
128− // Restore position in case we moved it for the test
129− if (data.moved) {
130− greeter.x = 0;
131− }
132−
133− // Wait until we're back to 0
134− tryCompareFunction(function() { return greeter.x;}, 0);
91+ teaseSpy.clear()
92+ mouseClick(greeter, data.posX, greeter.height - units.gu(1))
93+ teaseSpy.wait()
94+ tryCompare(teaseSpy, "count", 1)
13595 }
13696
13797 function test_statsWelcomeScreen() {
tests/qmltests/Greeter/tst_Tablet.qml+36−8
@@ -54,6 +54,12 @@ Item {
5454 signalName: "selected"
5555 }
5656
57+ SignalSpy {
58+ id: teaseSpy
59+ target: greeter
60+ signalName: "tease"
61+ }
62+
5763 UT.UnityTestCase {
5864 name: "Greeter"
5965 when: windowShown
@@ -325,14 +331,36 @@ Item {
325331 }
326332
327333 function test_teasingArea(data) {
328− tryCompare(greeter, "leftTeaserPressed", false)
329− tryCompare(greeter, "rightTeaserPressed", false)
330− mousePress(greeter, data.posX, greeter.height - units.gu(1))
331− tryCompare(greeter, "leftTeaserPressed", data.leftPressed)
332− tryCompare(greeter, "rightTeaserPressed", data.rightPressed)
333− mouseRelease(greeter, data.posX, greeter.height - units.gu(1))
334− tryCompare(greeter, "leftTeaserPressed", false)
335− tryCompare(greeter, "rightTeaserPressed", false)
334+ teaseSpy.clear()
335+ mouseClick(greeter, data.posX, greeter.height - units.gu(1))
336+ teaseSpy.wait()
337+ tryCompare(teaseSpy, "count", 1)
338+ }
339+
340+ function test_teaseLockedUnlocked_data() {
341+ return [
342+ {tag: "unlocked", locked: false, narrow: false},
343+ {tag: "locked", locked: true, narrow: false},
344+ ];
345+ }
346+
347+ function test_teaseLockedUnlocked(data) {
348+ teaseSpy.clear()
349+ greeter.locked = data.locked;
350+
351+ mouseClick(greeter, greeter.width - units.gu(5), greeter.height - units.gu(1));
352+
353+ if (!data.locked || data.narrow) {
354+ teaseSpy.wait()
355+ tryCompare(teaseSpy, "count", 1);
356+ } else {
357+ // waiting 100ms to make sure nothing happens
358+ wait(100);
359+ compare(teaseSpy.count, 0, "Greeter teasing not disabled even though it's locked.");
360+ }
361+
362+ // Reset value
363+ greeter.locked = false;
336364 }
337365
338366 function test_dbus_set_active_entry() {
tests/qmltests/Panel/Indicators/tst_MenuItemFactory.qml+29−4
@@ -19,6 +19,7 @@ import QtTest 1.0
1919import Unity.Test 0.1 as UT
2020import QMenuModel 0.1
2121import Unity.Indicators 0.1 as Indicators
22+import Utils 0.1 as Utils
2223
2324Item {
2425 id: testView
@@ -42,6 +43,10 @@ Item {
4243 }
4344 }
4445
46+ Utils.GDateTimeFormatter {
47+ id: timeFormatter
48+ }
49+
4550 UT.UnityTestCase {
4651 name: "MenuItemFactory"
4752 when: windowShown
@@ -358,8 +363,10 @@ Item {
358363
359364 function test_create_alarmMenu_data() {
360365 return [
361− {label: "testLabel1", enabled: true, icon: "file:///testIcon1" },
362− {label: "testLabel2", enabled: false, icon: "file:///testIcon2" },
366+ {label: "testLabel1", enabled: true, icon: "file:///testIcon1", color: Qt.rgba(0, 0, 0, 0),
367+ time: new Date(2014, 04, 14).getTime()*1000, timeFormat: "%a %d %b %l:%M %p"},
368+ {label: "testLabel2", enabled: false, icon: "file:///testIcon2", color: Qt.rgba(1, 0, 0, 0),
369+ time: new Date(2015, 12, 31).getTime()*1000, timeFormat: "%A" },
363370 ];
364371 }
365372
@@ -368,6 +375,12 @@ Item {
368375 menuData.label = data.label;
369376 menuData.sensitive = data.enabled;
370377 menuData.icon = data.icon;
378+ menuData.ext = {
379+ 'xCanonicalTime': data.time,
380+ 'xCanonicalTimeFormat': data.timeFormat
381+ };
382+ timeFormatter.format = data.timeFormat;
383+ timeFormatter.time = data.time;
371384
372385 loader.data = menuData;
373386 loader.sourceComponent = factory.load(menuData);
@@ -376,13 +389,16 @@ Item {
376389
377390 compare(loader.item.text, data.label, "Label does not match data");
378391 compare(loader.item.iconSource, data.icon, "Icon does not match data");
392+ compare(loader.item.time, timeFormatter.timeString, "Time does not match data");
379393 compare(loader.item.enabled, data.enabled, "Enabled does not match data");
380394 }
381395
382396 function test_create_appointmentMenu_data() {
383397 return [
384− {label: "testLabel1", enabled: true, icon: "file:///testIcon1" },
385− {label: "testLabel2", enabled: false, icon: "file:///testIcon2" },
398+ {label: "testLabel1", enabled: true, icon: "file:///testIcon1", color: Qt.rgba(0, 0, 0, 0),
399+ time: new Date(2014, 04, 14).getTime()*1000, timeFormat: "%a %d %b %l:%M %p"},
400+ {label: "testLabel2", enabled: false, icon: "file:///testIcon2", color: Qt.rgba(1, 0, 0, 0),
401+ time: new Date(2015, 12, 31).getTime()*1000, timeFormat: "%A" },
386402 ];
387403 }
388404
@@ -391,6 +407,13 @@ Item {
391407 menuData.label = data.label;
392408 menuData.sensitive = data.enabled;
393409 menuData.icon = data.icon;
410+ menuData.ext = {
411+ 'xCanonicalColor': data.colour,
412+ 'xCanonicalTime': data.time,
413+ 'xCanonicalTimeFormat': data.timeFormat
414+ };
415+ timeFormatter.format = data.timeFormat;
416+ timeFormatter.time = data.time;
394417
395418 loader.data = menuData;
396419 loader.sourceComponent = factory.load(menuData);
@@ -399,6 +422,8 @@ Item {
399422
400423 compare(loader.item.text, data.label, "Label does not match data");
401424 compare(loader.item.iconSource, data.icon, "Icon does not match data");
425+ compare(loader.item.time, timeFormatter.timeString, "Time does not match data");
426+ compare(loader.item.eventColor, data.color, "Colour does not match data");
402427 compare(loader.item.enabled, data.enabled, "Enabled does not match data");
403428 }
404429
tests/utils/modules/Unity/Test/CMakeLists.txt+4−7
@@ -1,3 +1,5 @@
1+include(QmlPlugins)
2+
13add_definitions(-DQT_NO_KEYWORDS)
24
35include_directories(
@@ -14,10 +16,5 @@ add_library(UnityTestQml MODULE ${UnityTestQML_SOURCES})
1416
1517qt5_use_modules(UnityTestQml Core Quick Test)
1618
17−# copy qml files into build directory for shadow builds
18−file(GLOB QML_JS_FILES *.js *.qml qmldir)
19−
20−add_custom_target(UnityTestQmlJsFiles ALL
21− COMMAND cp ${QML_JS_FILES} ${CMAKE_CURRENT_BINARY_DIR}
22− DEPENDS ${QML_JS_FILES}
23−)
19+export_qmlfiles(Unity.Test Unity/Test)
20+export_qmlplugin(Unity.Test 0.1 Unity/Test TARGETS UnityTestQml)
tests/utils/modules/Unity/Test/UnityTestCase.qml+26
@@ -260,6 +260,32 @@ TestCase {
260260 }
261261 }
262262
263+ function touchPinch(item, x1Start, y1Start, x1End, y1End, x2Start, y2Start, x2End, y2End) {
264+ // Make sure the item is rendered
265+ waitForRendering(item);
266+
267+ var event1 = touchEvent();
268+ // first finger
269+ event1.press(0, x1Start, y1Start);
270+ event1.commit();
271+ // second finger
272+ event1.stationary(0);
273+ event1.press(1, x2Start, y2Start);
274+ event1.commit();
275+
276+ // pinch
277+ for (var i = 0.0; i < 1.0; i += 0.02) {
278+ event1.move(0, x1Start + (x1End - x1Start) * i, y1Start + (y1End - y1Start) * i);
279+ event1.move(1, x2Start + (x2End - x2Start) * i, y2Start + (y2End - y2Start) * i);
280+ event1.commit();
281+ }
282+
283+ // release
284+ event1.release(0, x1End, y1End);
285+ event1.release(1, x2End, y2End);
286+ event1.commit();
287+ }
288+
263289 function fetchRootItem(item) {
264290 if (item.parent)
265291 return fetchRootItem(item.parent)
tests/utils/modules/Unity/Test/qmldir+2
@@ -1,3 +1,5 @@
11module Unity.Test
22plugin UnityTestQml
3+typeinfo Test.qmltypes
4+
35UnityTestCase 0.1 UnityTestCase.qml
tools/registry-tracker.cpp+33−26
@@ -49,58 +49,66 @@ RegistryTracker::~RegistryTracker()
4949"Registry.Identity = Registry\n" \
5050"Registry.ConfigFile = %1\n" \
5151"Default.Middleware = Zmq\n" \
52−"Zmq.ConfigFile = %2\n"
52+"Zmq.ConfigFile = %2\n" \
53+"Smartscopes.Registry.Identity = %3\n"
5354
5455#define REGISTRY_CONFIG \
5556"[Registry]\n" \
5657"Middleware = Zmq\n" \
57−"Zmq.Endpoint = ipc://%1/Registry\n" \
58−"Zmq.EndpointDir = %2\n" \
59−"Zmq.ConfigFile = %3\n" \
60−"Scope.InstallDir = %4\n" \
61−"Scoperunner.Path = %5\n" \
62−"%6"
58+"Zmq.ConfigFile = %1\n" \
59+"Scope.InstallDir = %2\n" \
60+"Scoperunner.Path = %3\n"
6361
6462#define MW_CONFIG \
6563"[Zmq]\n" \
66−"EndpointDir.Public = %1\n" \
67−"EndpointDir.Private = %2\n"
64+"EndpointDir = %1\n"
6865
6966void RegistryTracker::runRegistry()
7067{
7168 QDir tmp(QDir::temp());
72− m_runtime_config.setFileTemplate(tmp.filePath("Runtime.ini.XXXXXX"));
73− m_registry_config.setFileTemplate(tmp.filePath("Registry.ini.XXXXXX"));
74− m_mw_config.setFileTemplate(tmp.filePath("Zmq.ini.XXXXXX"));
69+ m_runtime_config.setFileTemplate(tmp.filePath("Runtime.XXXXXX.ini"));
70+ m_registry_config.setFileTemplate(tmp.filePath("Registry.XXXXXX.ini"));
71+ m_mw_config.setFileTemplate(tmp.filePath("Zmq.XXXXXX.ini"));
7572
7673 if (!m_runtime_config.open() || !m_registry_config.open() || !m_mw_config.open() || !m_endpoints_dir.isValid()) {
7774 qWarning("Unable to open temporary files!");
7875 return;
7976 }
8077
81− QString scopesLibdir;
78+ QString scopeInstallDir;
79+ QString scopeRegistryBin;
80+ QString scopeRunnerBin;
8281 {
8382 QProcess pkg_config;
83+ QByteArray output;
8484 QStringList arguments;
85− arguments << "--variable=libdir";
85+ arguments << "--variable=scopesdir";
8686 arguments << "libunity-scopes";
8787 pkg_config.start("pkg-config", arguments);
8888 pkg_config.waitForFinished();
89− QByteArray libdir = pkg_config.readAllStandardOutput();
90− scopesLibdir = QDir(QString::fromLocal8Bit(libdir)).path().trimmed();
89+ output = pkg_config.readAllStandardOutput();
90+ scopeInstallDir = QDir(QString::fromLocal8Bit(output)).path().trimmed();
91+
92+ arguments[0] = "--variable=scoperegistry_bin";
93+ pkg_config.start("pkg-config", arguments);
94+ pkg_config.waitForFinished();
95+ output = pkg_config.readAllStandardOutput();
96+ scopeRegistryBin = QString::fromLocal8Bit(output).trimmed();
97+
98+ arguments[0] = "--variable=scoperunner_bin";
99+ pkg_config.start("pkg-config", arguments);
100+ pkg_config.waitForFinished();
101+ output = pkg_config.readAllStandardOutput();
102+ scopeRunnerBin = QString::fromLocal8Bit(output).trimmed();
91103 }
92104
93− if (scopesLibdir.size() == 0) {
105+ if (scopeInstallDir.isEmpty() || scopeRegistryBin.isEmpty() || scopeRunnerBin.isEmpty()) {
94106 qWarning("Unable to find libunity-scopes package config file");
95107 return;
96108 }
97109
98− QString scopeRunnerPath = QDir(scopesLibdir).filePath("scoperunner/scoperunner");
99−
100− QString runtime_ini = QString(RUNTIME_CONFIG).arg(m_registry_config.fileName()).arg(m_mw_config.fileName());
101110 // FIXME: keep in sync with the SSRegistry config
102− QString serverRegistryConfig(m_serverScopes ? "SS.Registry.Identity = SSRegistry\nSS.Registry.Endpoint = ipc:///tmp/SSRegistry" : "");
103− QString scopeInstallDir(scopesLibdir + "/unity-scopes");
111+ QString runtime_ini = QString(RUNTIME_CONFIG).arg(m_registry_config.fileName()).arg(m_mw_config.fileName()).arg(m_serverScopes ? "SSRegistry" : "");
104112 if (!m_systemScopes) {
105113 m_scopeInstallDir.reset(new QTemporaryDir(tmp.filePath("scopes.XXXXXX")));
106114 if (!m_scopeInstallDir->isValid()) {
@@ -108,8 +116,8 @@ void RegistryTracker::runRegistry()
108116 }
109117 scopeInstallDir = m_scopeInstallDir->path();
110118 }
111− QString registry_ini = QString(REGISTRY_CONFIG).arg(m_endpoints_dir.path()).arg(m_endpoints_dir.path()).arg(m_mw_config.fileName()).arg(scopeInstallDir).arg(scopeRunnerPath).arg(serverRegistryConfig);
112− QString mw_ini = QString(MW_CONFIG).arg(m_endpoints_dir.path()).arg(m_endpoints_dir.path());
119+ QString registry_ini = QString(REGISTRY_CONFIG).arg(m_mw_config.fileName()).arg(scopeInstallDir).arg(scopeRunnerBin);
120+ QString mw_ini = QString(MW_CONFIG).arg(m_endpoints_dir.path());
113121
114122 m_runtime_config.write(runtime_ini.toUtf8());
115123 m_registry_config.write(registry_ini.toUtf8());
@@ -121,11 +129,10 @@ void RegistryTracker::runRegistry()
121129
122130 qputenv("UNITY_SCOPES_RUNTIME_PATH", m_runtime_config.fileName().toLocal8Bit());
123131
124− QString registryBin(QDir(scopesLibdir).filePath("scoperegistry/scoperegistry"));
125132 QStringList arguments;
126133 arguments << m_runtime_config.fileName();
127134 arguments << m_scopes;
128135
129136 m_registry.setProcessChannelMode(QProcess::ForwardedChannels);
130− m_registry.start(registryBin, arguments);
137+ m_registry.start(scopeRegistryBin, arguments);
131138}
tools/unlock-device+2−4
@@ -4,7 +4,7 @@
44# Our goal here is to get an Ubuntu Touch device into a testable unlocked state.
55# This will include a reboot.
66
7−WAIT_COMMAND="sleep 20"
7+WAIT_COMMAND="adb reboot; sleep 5; adb wait-for-device; sleep 20"
88
99while getopts s:w: opt; do
1010 case $opt in
@@ -28,10 +28,8 @@ bus.clearSysState(cookie, dbus_interface="com.canonical.powerd");
2828helpers.unlock_unity()
2929'
3030
31−adb reboot
32−sleep 5
33−adb "wait-for-device"
3431eval "$WAIT_COMMAND"
32+
3533UNLOCK_OUTPUT=$(adb shell "sudo -u phablet -i python3 -c '$UNLOCK_SCRIPT'" 2>&1)
3634if echo "$UNLOCK_OUTPUT" | grep 'Greeter unlocked' >/dev/null; then
3735 echo "I: Unlock passed"