on xenial help sign in
Merge
commitbfdd07abf51dd5f13571ee359b4128e1d570819e authorAlbert Astals <albert.astals@canonical.com> dateTue 20 May 2014, 12:29 (12 years ago) parente671b82bcb22f4
152 files changed+2281−1819
cmake/modules/Plugins.cmake−68 cmake/modules/QmlPlugins.cmake+143 debian/changelog+83 debian/unity8-private.install+1−1 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 plugins/DashViews/abstractdashview.h → plugins/Dash/abstractdashview.h plugins/DashViews/horizontaljournal.cpp → plugins/Dash/horizontaljournal.cpp plugins/DashViews/horizontaljournal.h → plugins/Dash/horizontaljournal.h plugins/DashViews/listviewwithpageheader.cpp → plugins/Dash/listviewwithpageheader.cpp plugins/DashViews/listviewwithpageheader.h → plugins/Dash/listviewwithpageheader.h plugins/DashViews/organicgrid.cpp → plugins/Dash/organicgrid.cpp plugins/DashViews/organicgrid.h → plugins/Dash/organicgrid.h 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 plugins/DashViews/verticaljournal.h → plugins/Dash/verticaljournal.h 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/qmldir+1−1 plugins/Unity/Indicators/rootactionstate.cpp+7−8 plugins/Unity/Launcher/CMakeLists.txt+1−3 plugins/Unity/Launcher/backend/launcherbackend.cpp+29−15 plugins/Unity/Launcher/qmldir+1−1 plugins/Utils/CMakeLists.txt+1−3 plugins/Utils/qmldir+1−1 po/ca.po+9−9 po/es.po+4−4 po/fi.po+4−4 po/gd.po+16−14 po/he.po+13−11 po/km.po+6−6 po/nb.po+34−32 po/pt_BR.po+14−12 po/ru.po+4−4 po/uk.po+14−12 po/zh_CN.po+31−31 qml/Components/Revealer.qml−241 qml/Dash/Card.qml−236 qml/Dash/CardCarousel.qml+23−11 qml/Dash/CardFilterGrid.qml+19−16 qml/Dash/CardHeader.qml−126 qml/Dash/CardTool.qml+30−22 qml/Dash/Previews/PreviewHeader.qml+86−9 qml/Dash/Previews/PreviewTextSummary.qml+4−2 qml/Dash/ScopeListView.qml+1−1 qml/Dash/graphics/carousel_dropshadow@27.png qml/Dash/graphics/carousel_dropshadow@27.sci+5 src/ApplicationArguments.h+4−8 src/main.cpp+43−6 tests/autopilot/unity8/process_helpers.py+11−4 tests/autopilot/unity8/shell/emulators/dash.py+3−4 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+1−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+15−2 tests/mocks/Unity/fake_resultsmodel.cpp+1 tests/mocks/Unity/qmldir+1 tests/plugins/CMakeLists.txt+1−1 tests/plugins/DashViews/CMakeLists.txt → tests/plugins/Dash/CMakeLists.txt+16−9 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 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/listviewwithpageheadersectionexternalmodeltest.cpp → tests/plugins/Dash/listviewwithpageheadersectionexternalmodeltest.cpp tests/plugins/DashViews/listviewwithpageheadersectiontest.cpp → tests/plugins/Dash/listviewwithpageheadersectiontest.cpp tests/plugins/DashViews/listviewwithpageheadertest.cpp → tests/plugins/Dash/listviewwithpageheadertest.cpp 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 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 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/Unity/Indicators/rootactionstatetest.cpp+37 tests/qmltests/CMakeLists.txt+3−4 tests/qmltests/Components/RevealingRectangle.qml−78 tests/qmltests/Components/tst_Revealer.qml−262 tests/qmltests/Dash/Previews/tst_Preview.qml+1−1 tests/qmltests/Dash/Previews/tst_PreviewHeader.qml+66−4 tests/qmltests/Dash/Previews/tst_PreviewTextSummary.qml+5−5 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/utils/modules/Unity/Test/CMakeLists.txt+4−7 tests/utils/modules/Unity/Test/qmldir+2 tools/registry-tracker.cpp+33−26 tools/unlock-device+2−4
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()
debian/changelog+83
@@ -1,3 +1,86 @@
1+unity8 (7.86+14.10.20140516.5-0ubuntu1) utopic; urgency=low
2+
3+ [ Michal Hruby ]
4+ * Updated scope tool to create proper config files after recent
5+ libunity-scopes-api changes.
6+
7+ [ Michał Sawicz ]
8+ * Refactor export_qmlfiles and export_qmlplugins to be more generic
9+ and clean up installed mocks.
10+
11+ [ Albert Astals ]
12+ * Remove empty dirs
13+ * Set the tabbarmodel index as we do on real code It works better :D
14+ (LP: #1317255)
15+
16+ [ Thomi Richards ]
17+ * Use new import location for ProcessSearchError in process_helpers
18+ script.
19+
20+ [ Andrea Cimitan ]
21+ * Adds shadow for the carousel
22+
23+ [ Daniel d'Andrada ]
24+ * Remove Revealer component It's not used anywhere anymore. It's been
25+ replaced by DragHandle.
26+
27+ [ Andy Doan ]
28+ * unlock_device: support more complex reboot/wait cycles Currently
29+ this script only allows you to override how to "wait" on the device.
30+ This changes the logic to also support how you go about rebooting
31+ the device. This is handy for the ubuntu-emulator because adb-reboot
32+ is not currently supported. However, we also have a more
33+ sophisticated, fool-proof way we reboot/wait in the CI lab that
34+ would be nice to take advantage of:
35+ http://bazaar.launchpad.net/~ubuntu-test-case-dev/ubuntu-test-
36+ cases/touch/view/head:/scripts/reboot-and-wait
37+
38+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Fri, 16 May 2014 18:46:32 +0000
39+
40+unity8 (7.86+14.10.20140516.2-0ubuntu1) utopic; urgency=low
41+
42+ [ CI bot ]
43+ * Resync trunk
44+
45+ [ Michael Zanetti ]
46+ * support appid:// entries in gsettings schema and make
47+ findDesktopFile work with short-appid (LP: #1239750)
48+
49+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Fri, 16 May 2014 12:32:40 +0000
50+
51+unity8 (7.86+14.10.20140514.1-0ubuntu1) utopic; urgency=low
52+
53+ [ Antti Kaijanmäki ]
54+ * Indicators/RootActionState: use g_variant_iter_loop to extract
55+ icons.
56+
57+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Wed, 14 May 2014 11:43:55 +0000
58+
59+unity8 (7.86+14.10.20140513-0ubuntu1) utopic; urgency=low
60+
61+ [ Andrea Cimitan ]
62+ * Improve padding in Text preview widget. (LP: #1316683)
63+
64+ [ CI bot ]
65+ * Resync trunk
66+
67+ [ Nick Dedekind ]
68+ * Removed binding loop from Unity.Indicators.MenuContentActivator
69+ Change handler for QMLListProperty used by MenuContent.qml:
70+ menuActivator.content[index].active If we're already asking for the
71+ index, we know it exists already. No need to send a
72+ changeNotification on an implied creation.
73+
74+ [ Josh Arenson ]
75+ * Implements usage-style documentation for unity8 executable. Fixes
76+ lp:1269282 (LP: #1269282)
77+
78+ [ Albert Astals ]
79+ * Create specialized Card code in Javascript instead of having various
80+ copied&pasted files (LP: #1297197)
81+
82+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Tue, 13 May 2014 08:34:02 +0000
83+
184unity8 (7.86+14.10.20140507.3-0ubuntu1) utopic; urgency=low
285
386 [ Michał Sawicz ]
debian/unity8-private.install+1−1
@@ -1,5 +1,5 @@
11usr/lib/*/unity8/qml/AccountsService
2−usr/lib/*/unity8/qml/DashViews
2+usr/lib/*/unity8/qml/Dash
33usr/lib/*/unity8/qml/HudClient
44usr/lib/*/unity8/qml/LightDM
55usr/lib/*/unity8/qml/Powerd
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

The content is the same.

plugins/DashViews/abstractdashview.h → plugins/Dash/abstractdashview.hrenamed

The content is the same.

plugins/DashViews/horizontaljournal.cpp → plugins/Dash/horizontaljournal.cpprenamed

The content is the same.

plugins/DashViews/horizontaljournal.h → plugins/Dash/horizontaljournal.hrenamed

The content is the same.

plugins/DashViews/listviewwithpageheader.cpp → plugins/Dash/listviewwithpageheader.cpprenamed

The content is the same.

plugins/DashViews/listviewwithpageheader.h → plugins/Dash/listviewwithpageheader.hrenamed

The content is the same.

plugins/DashViews/organicgrid.cpp → plugins/Dash/organicgrid.cpprenamed

The content is the same.

plugins/DashViews/organicgrid.h → plugins/Dash/organicgrid.hrenamed

The content is the same.

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

The content is the same.

plugins/DashViews/verticaljournal.h → plugins/Dash/verticaljournal.hrenamed

The content is the same.

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/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+29−15
@@ -31,7 +31,6 @@
3131class LauncherBackendItem
3232{
3333public:
34− QString desktopFile;
3534 QString displayName;
3635 QString icon;
3736 int count;
@@ -107,11 +106,6 @@ void LauncherBackend::setStoredApplications(const QStringList &appIds)
107106
108107QString LauncherBackend::desktopFile(const QString &appId) const
109108{
110− LauncherBackendItem *item = m_itemCache.value(appId, nullptr);
111− if (item) {
112− return item->desktopFile;
113− }
114−
115109 return findDesktopFile(appId);
116110}
117111
@@ -264,13 +258,33 @@ void LauncherBackend::syncFromAccounts()
264258 Q_FOREACH(const QString &entry, gSettings.get("favorites").toStringList()) {
265259 if (entry.startsWith("application://")) {
266260 QString appId = entry;
267− // Transform "application://foobar.desktop" to "foobar"
261+ // Transform "application://foobar.desktop" to "application://foobar"
268262 appId.remove("application://");
269263 if (appId.endsWith(".desktop")) {
270264 appId.chop(8);
271265 }
272266 QString df = findDesktopFile(appId);
273267
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+
274288 if (!df.isEmpty()) {
275289 m_storedApps << appId;
276290
@@ -315,10 +329,13 @@ QString LauncherBackend::findDesktopFile(const QString &appId) const
315329 helper = helper.replace(dashPos, 1, '/');
316330 }
317331
318− Q_FOREACH(const QString &searchDir, searchDirs) {
319− QFileInfo fileInfo(QDir(searchDir), helper + ".desktop");
320− if (fileInfo.exists()) {
321− 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+ }
322339 }
323340 }
324341
@@ -333,7 +350,6 @@ LauncherBackendItem* LauncherBackend::parseDesktopFile(const QString &desktopFil
333350 QSettings settings(desktopFile, QSettings::IniFormat);
334351
335352 LauncherBackendItem* item = new LauncherBackendItem();
336− item->desktopFile = desktopFile;
337353 item->displayName = settings.value("Desktop Entry/Name").toString();
338354
339355 QString iconString = settings.value("Desktop Entry/Icon").toString();
@@ -367,7 +383,7 @@ LauncherBackendItem* LauncherBackend::getItem(const QString &appId) const
367383 qWarning() << "Unable to parse desktop file for" << appId << "path" << df;
368384 }
369385 } else {
370− qDebug() << "Unable to find desktop file for:" << appId;
386+ qWarning() << "Unable to find desktop file for:" << appId;
371387 }
372388 }
373389
@@ -391,7 +407,6 @@ void LauncherBackend::loadFromVariant(const QVariantMap &details)
391407
392408 item = new LauncherBackendItem();
393409
394− item->desktopFile = details.value("desktopFile").toString();
395410 item->displayName = details.value("name").toString();
396411 item->icon = details.value("icon").toString();
397412 item->count = details.value("count").toInt();
@@ -408,7 +423,6 @@ QVariantMap LauncherBackend::itemToVariant(const QString &appId) const
408423 details.insert("id", appId);
409424 details.insert("name", item->displayName);
410425 details.insert("icon", item->icon);
411− details.insert("desktopFile", item->desktopFile);
412426 details.insert("count", item->count);
413427 details.insert("countVisible", item->countVisible);
414428 return details;
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−3
@@ -33,6 +33,4 @@ set_target_properties(Utils-qml PROPERTIES COMPILE_FLAGS -fvisibility=default)
3333
3434qt5_use_modules(Utils-qml Qml Quick DBus Network XmlPatterns Gui Concurrent)
3535
36−# export the qmldir qmltypes and plugin files
37−export_qmlfiles(Utils Utils)
38−export_qmlplugin(Utils 0.1 Utils TARGETS Utils-qml)
36+add_unity8_plugin(Utils 0.1 Utils TARGETS Utils-qml)
plugins/Utils/qmldir+1−1
@@ -1,3 +1,3 @@
11module Utils
22plugin Utils-qml
3−typeinfo plugin.qmltypes
3+typeinfo Utils.qmltypes
po/ca.po+9−9
@@ -8,14 +8,14 @@ msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2014-04-10 11:13-0400\n"
11−"PO-Revision-Date: 2014-01-10 07:45+0000\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−"X-Launchpad-Export-Date: 2014-05-01 06:43+0000\n"
18−"X-Generator: Launchpad (build 16985)\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
@@ -84,11 +84,11 @@ msgstr "Cerques recents"
8484
8585#: qml/Components/SeeMore.qml:35
8686msgid "See more"
87−msgstr ""
87+msgstr "Mostra'n més"
8888
8989#: qml/Components/SeeMore.qml:58
9090msgid "See less"
91−msgstr ""
91+msgstr "Mostra'n menys"
9292
9393#: qml/Dash/DashApps.qml:37
9494msgid "Recent"
@@ -97,15 +97,15 @@ msgstr ""
9797#: qml/Dash/PreviewListView.qml:52
9898#, qt-format
9999msgid "%1 Preview"
100−msgstr ""
100+msgstr "Previsualització de %1"
101101
102102#: qml/Dash/Previews/PreviewActionCombo.qml:34
103103msgid "More..."
104−msgstr ""
104+msgstr "Més..."
105105
106106#: qml/Dash/Previews/PreviewActionCombo.qml:34
107107msgid "Less..."
108−msgstr ""
108+msgstr "Menys..."
109109
110110#: qml/Dash/Previews/PreviewRatingInput.qml:81
111111msgid "Rate this"
@@ -162,7 +162,7 @@ msgstr "Mostra la contrasenya"
162162
163163#: qml/Notifications/NotificationMenuItemFactory.qml:103
164164msgid "Please enter SIM PIN"
165−msgstr ""
165+msgstr "Introduïu el PIN de la targeta SIM"
166166
167167#: qml/Panel/SearchIndicator.qml:27
168168msgid "Search"
po/es.po+4−4
@@ -8,14 +8,14 @@ msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2014-04-10 11:13-0400\n"
11−"PO-Revision-Date: 2014-03-28 22:37+0000\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-05-01 06:44+0000\n"
18−"X-Generator: Launchpad (build 16985)\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
@@ -120,7 +120,7 @@ msgstr "Enviar"
120120
121121#: qml/Greeter/Greeter.qml:151
122122msgid "Swipe to unlock"
123−msgstr ""
123+msgstr "Deslice para desbloquear"
124124
125125#: qml/Greeter/Lockscreen.qml:149
126126msgid "Emergency Call"
po/fi.po+4−4
@@ -8,14 +8,14 @@ msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2014-04-10 11:13-0400\n"
11−"PO-Revision-Date: 2014-04-05 09:57+0000\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-05-01 06:43+0000\n"
18−"X-Generator: Launchpad (build 16985)\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
@@ -117,7 +117,7 @@ msgstr "Lähetä"
117117
118118#: qml/Greeter/Greeter.qml:151
119119msgid "Swipe to unlock"
120−msgstr ""
120+msgstr "Avaa pyyhkäisemällä"
121121
122122#: qml/Greeter/Lockscreen.qml:149
123123msgid "Emergency Call"
po/gd.po+16−14
@@ -8,23 +8,23 @@ msgstr ""
88"Project-Id-Version: unity8\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2014-04-10 11:13-0400\n"
11−"PO-Revision-Date: 2013-09-30 10:34+0000\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−"X-Launchpad-Export-Date: 2014-05-01 06:43+0000\n"
18−"X-Generator: Launchpad (build 16985)\n"
17+"X-Launchpad-Export-Date: 2014-05-18 05:57+0000\n"
18+"X-Generator: Launchpad (build 17007)\n"
1919
2020#: plugins/Unity/Launcher/launcheritem.cpp:43
2121#: plugins/Unity/Launcher/launcheritem.cpp:73
2222msgid "Lock to Launcher"
23−msgstr ""
23+msgstr "Glais ris an lòinsear"
2424
2525#: plugins/Unity/Launcher/launcheritem.cpp:73
2626msgid "Unlock from Launcher"
27−msgstr ""
27+msgstr "Dealaich on lòinsear"
2828
2929#: qml/Components/EdgeDemoOverlay.qml:151
3030msgid "Skip intro"
@@ -77,6 +77,8 @@ msgid ""
7777"You have now mastered the edge gestures and can start using the "
7878"phone<br><br>Tap on the screen to start"
7979msgstr ""
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"
8082
8183#: qml/Components/PageHeader.qml:365
8284msgid "Recent searches"
@@ -84,28 +86,28 @@ msgstr "Na lorg thu o chionn goirid"
8486
8587#: qml/Components/SeeMore.qml:35
8688msgid "See more"
87−msgstr ""
89+msgstr "Seall barrachd"
8890
8991#: qml/Components/SeeMore.qml:58
9092msgid "See less"
91−msgstr ""
93+msgstr "Seall nas lugha"
9294
9395#: qml/Dash/DashApps.qml:37
9496msgid "Recent"
95−msgstr ""
97+msgstr "O chionn goirid"
9698
9799#: qml/Dash/PreviewListView.qml:52
98100#, qt-format
99101msgid "%1 Preview"
100−msgstr ""
102+msgstr "Ro-shealladh %1"
101103
102104#: qml/Dash/Previews/PreviewActionCombo.qml:34
103105msgid "More..."
104−msgstr ""
106+msgstr "Barrachd..."
105107
106108#: qml/Dash/Previews/PreviewActionCombo.qml:34
107109msgid "Less..."
108−msgstr ""
110+msgstr "Nas lugha..."
109111
110112#: qml/Dash/Previews/PreviewRatingInput.qml:81
111113msgid "Rate this"
@@ -121,7 +123,7 @@ msgstr "Cuir"
121123
122124#: qml/Greeter/Greeter.qml:151
123125msgid "Swipe to unlock"
124−msgstr ""
126+msgstr "Dèan grad-shlaighdeadh gus a' ghlas a thoirt dheth"
125127
126128#: qml/Greeter/Lockscreen.qml:149
127129msgid "Emergency Call"
@@ -158,11 +160,11 @@ msgstr "A' bruidhinn..."
158160
159161#: qml/Notifications/NotificationMenuItemFactory.qml:91
160162msgid "Show password"
161−msgstr ""
163+msgstr "Seall am facal-faire"
162164
163165#: qml/Notifications/NotificationMenuItemFactory.qml:103
164166msgid "Please enter SIM PIN"
165−msgstr ""
167+msgstr "Cuir a-steach SIM PIN"
166168
167169#: qml/Panel/SearchIndicator.qml:27
168170msgid "Search"
po/he.po+13−11
@@ -8,14 +8,14 @@ msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2014-04-10 11:13-0400\n"
11−"PO-Revision-Date: 2013-11-20 08:30+0000\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−"X-Launchpad-Export-Date: 2014-05-01 06:43+0000\n"
18−"X-Generator: Launchpad (build 16985)\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
@@ -71,6 +71,8 @@ msgid ""
7171"You have now mastered the edge gestures and can start using the "
7272"phone<br><br>Tap on the screen to start"
7373msgstr ""
74+"ברגעים אלו סיימת את התמחותך בשימוש במחוות קצה והטלפון פתוח לשימושך<br><br>נא "
75+"לגעת במסך כדי להתחיל"
7476
7577#: qml/Components/PageHeader.qml:365
7678msgid "Recent searches"
@@ -78,28 +80,28 @@ msgstr "חיפושים אחרונים"
7880
7981#: qml/Components/SeeMore.qml:35
8082msgid "See more"
81−msgstr ""
83+msgstr "לראות עוד"
8284
8385#: qml/Components/SeeMore.qml:58
8486msgid "See less"
85−msgstr ""
87+msgstr "לראות פחות"
8688
8789#: qml/Dash/DashApps.qml:37
8890msgid "Recent"
89−msgstr ""
91+msgstr "בשימוש לאחרונה"
9092
9193#: qml/Dash/PreviewListView.qml:52
9294#, qt-format
9395msgid "%1 Preview"
94−msgstr ""
96+msgstr "תצוגה מקדימה של %1"
9597
9698#: qml/Dash/Previews/PreviewActionCombo.qml:34
9799msgid "More..."
98−msgstr ""
100+msgstr "עוד…"
99101
100102#: qml/Dash/Previews/PreviewActionCombo.qml:34
101103msgid "Less..."
102−msgstr ""
104+msgstr "פחות…"
103105
104106#: qml/Dash/Previews/PreviewRatingInput.qml:81
105107msgid "Rate this"
@@ -115,7 +117,7 @@ msgstr "שליחה"
115117
116118#: qml/Greeter/Greeter.qml:151
117119msgid "Swipe to unlock"
118−msgstr ""
120+msgstr "יש להחליק לפתיחה"
119121
120122#: qml/Greeter/Lockscreen.qml:149
121123msgid "Emergency Call"
@@ -156,7 +158,7 @@ msgstr "הצגת הססמה"
156158
157159#: qml/Notifications/NotificationMenuItemFactory.qml:103
158160msgid "Please enter SIM PIN"
159−msgstr ""
161+msgstr "נא להזין את קוד ה־<U+200F>SIM"
160162
161163#: qml/Panel/SearchIndicator.qml:27
162164msgid "Search"
po/km.po+6−6
@@ -8,14 +8,14 @@ msgstr ""
88"Project-Id-Version: unity8\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2014-04-10 11:13-0400\n"
11−"PO-Revision-Date: 2014-03-04 02:32+0000\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−"X-Launchpad-Export-Date: 2014-05-01 06:43+0000\n"
18−"X-Generator: Launchpad (build 16985)\n"
17+"X-Launchpad-Export-Date: 2014-05-19 06:25+0000\n"
18+"X-Generator: Launchpad (build 17007)\n"
1919
2020#: plugins/Unity/Launcher/launcheritem.cpp:43
2121#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -90,12 +90,12 @@ msgstr "មើល​តិច​ជាង"
9090
9191#: qml/Dash/DashApps.qml:37
9292msgid "Recent"
93−msgstr ""
93+msgstr "បច្ចុប្បន្ន"
9494
9595#: qml/Dash/PreviewListView.qml:52
9696#, qt-format
9797msgid "%1 Preview"
98−msgstr ""
98+msgstr "មើល​ជា​មុន %1"
9999
100100#: qml/Dash/Previews/PreviewActionCombo.qml:34
101101msgid "More..."
@@ -119,7 +119,7 @@ msgstr "ផ្ញើ"
119119
120120#: qml/Greeter/Greeter.qml:151
121121msgid "Swipe to unlock"
122−msgstr ""
122+msgstr "អូស​ដើម្បី​ដោះសោ"
123123
124124#: qml/Greeter/Lockscreen.qml:149
125125msgid "Emergency Call"
po/nb.po+34−32
@@ -8,69 +8,71 @@ msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2014-04-10 11:13-0400\n"
11−"PO-Revision-Date: 2013-06-27 07:02+0000\n"
12−"Last-Translator: Joakim Langvand <jlangvand@gmail.com>\n"
11+"PO-Revision-Date: 2014-05-15 17:12+0000\n"
12+"Last-Translator: Åka Sikrom <Unknown>\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−"X-Launchpad-Export-Date: 2014-05-01 06:43+0000\n"
18−"X-Generator: Launchpad (build 16985)\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
2222msgid "Lock to Launcher"
23−msgstr ""
23+msgstr "Lås til oppstarter"
2424
2525#: plugins/Unity/Launcher/launcheritem.cpp:73
2626msgid "Unlock from Launcher"
27−msgstr ""
27+msgstr "Lås opp fra oppstarter"
2828
2929#: qml/Components/EdgeDemoOverlay.qml:151
3030msgid "Skip intro"
31−msgstr ""
31+msgstr "Hopp over introduksjon"
3232
3333#: qml/Components/EdgeDemo.qml:113
3434msgid "Right edge"
35−msgstr ""
35+msgstr "Høyre kant"
3636
3737#: qml/Components/EdgeDemo.qml:114
3838msgid "Try swiping from the right edge to unlock the phone"
39−msgstr ""
39+msgstr "Prøv å sveipe fra høyre side for å låse opp telefonen"
4040
4141#: qml/Components/EdgeDemo.qml:145
4242msgid "Top edge"
43−msgstr ""
43+msgstr "Øvre kant"
4444
4545#: qml/Components/EdgeDemo.qml:146
4646msgid "Try swiping from the top edge to access the indicators"
47−msgstr ""
47+msgstr "Prøv å sveipe fra toppen for å få tilgang til innstillingene"
4848
4949#: qml/Components/EdgeDemo.qml:171
5050msgid "Close"
51−msgstr ""
51+msgstr "Lukk"
5252
5353#: qml/Components/EdgeDemo.qml:172
5454msgid "Swipe up again to close the settings screen"
55−msgstr ""
55+msgstr "Sveip opp igjen for å lukke innstillingsmenyen"
5656
5757#: qml/Components/EdgeDemo.qml:199
5858msgid "Left edge"
59−msgstr ""
59+msgstr "Venstre kant"
6060
6161#: qml/Components/EdgeDemo.qml:200
6262msgid "Swipe from the left to reveal the launcher for quick access to apps"
63−msgstr ""
63+msgstr "Sveip fra venstre for å få tilgang til programoppstarteren"
6464
6565#: qml/Components/EdgeDemo.qml:227
6666msgid "Well done"
67−msgstr ""
67+msgstr "Bra jobba"
6868
6969#: qml/Components/EdgeDemo.qml:228
7070msgid ""
7171"You have now mastered the edge gestures and can start using the "
7272"phone<br><br>Tap on the screen to start"
7373msgstr ""
74+"Du har nå mestret kantbevegelsene, og er klar til å bruke "
75+"telefonen<br><br>Trykk på skjermen for å begynne"
7476
7577#: qml/Components/PageHeader.qml:365
7678msgid "Recent searches"
@@ -78,57 +80,57 @@ msgstr "Siste søk"
7880
7981#: qml/Components/SeeMore.qml:35
8082msgid "See more"
81−msgstr ""
83+msgstr "Vis mer"
8284
8385#: qml/Components/SeeMore.qml:58
8486msgid "See less"
85−msgstr ""
87+msgstr "Vis mindre"
8688
8789#: qml/Dash/DashApps.qml:37
8890msgid "Recent"
89−msgstr ""
91+msgstr "Nylig"
9092
9193#: qml/Dash/PreviewListView.qml:52
9294#, qt-format
9395msgid "%1 Preview"
94−msgstr ""
96+msgstr "%1-forhåndsvisning"
9597
9698#: qml/Dash/Previews/PreviewActionCombo.qml:34
9799msgid "More..."
98−msgstr ""
100+msgstr "Mer …"
99101
100102#: qml/Dash/Previews/PreviewActionCombo.qml:34
101103msgid "Less..."
102−msgstr ""
104+msgstr "Mindre …"
103105
104106#: qml/Dash/Previews/PreviewRatingInput.qml:81
105107msgid "Rate this"
106−msgstr ""
108+msgstr "Vurder dette"
107109
108110#: qml/Dash/Previews/PreviewRatingInput.qml:126
109111msgid "Add a review"
110−msgstr ""
112+msgstr "Skriv en anmeldelse"
111113
112114#: qml/Dash/Previews/PreviewRatingInput.qml:166
113115msgid "Send"
114−msgstr ""
116+msgstr "Send"
115117
116118#: qml/Greeter/Greeter.qml:151
117119msgid "Swipe to unlock"
118−msgstr ""
120+msgstr "Sveip for å låse opp"
119121
120122#: qml/Greeter/Lockscreen.qml:149
121123msgid "Emergency Call"
122−msgstr ""
124+msgstr "Nødanrop"
123125
124126#: qml/Greeter/PassphraseLockscreen.qml:59
125127#, qt-format
126128msgid "Hello %1"
127−msgstr ""
129+msgstr "Hei, %1"
128130
129131#: qml/Greeter/PassphraseLockscreen.qml:59
130132msgid "Hello"
131−msgstr ""
133+msgstr "Hei"
132134
133135#: qml/Hud/HudParametrizedActionsPage.qml:132
134136msgid "Confirm"
@@ -152,11 +154,11 @@ msgstr "Snakker …"
152154
153155#: qml/Notifications/NotificationMenuItemFactory.qml:91
154156msgid "Show password"
155−msgstr ""
157+msgstr "Vis passord"
156158
157159#: qml/Notifications/NotificationMenuItemFactory.qml:103
158160msgid "Please enter SIM PIN"
159−msgstr ""
161+msgstr "Skriv inn PIN-koden til SIM-kortet"
160162
161163#: qml/Panel/SearchIndicator.qml:27
162164msgid "Search"
@@ -165,4 +167,4 @@ msgstr "Søk"
165167#: qml/Shell.qml:348
166168#, qt-format
167169msgid "Please enter %1"
168−msgstr ""
170+msgstr "Skriv inn %1"
po/pt_BR.po+14−12
@@ -8,14 +8,14 @@ msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2014-04-10 11:13-0400\n"
11−"PO-Revision-Date: 2014-01-18 23:24+0000\n"
12−"Last-Translator: Fábio Nogueira <deb-user-ba@ubuntu.com>\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−"X-Launchpad-Export-Date: 2014-05-01 06:44+0000\n"
18−"X-Generator: Launchpad (build 16985)\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
@@ -73,6 +73,8 @@ msgid ""
7373"You have now mastered the edge gestures and can start using the "
7474"phone<br><br>Tap on the screen to start"
7575msgstr ""
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"
7678
7779#: qml/Components/PageHeader.qml:365
7880msgid "Recent searches"
@@ -80,28 +82,28 @@ msgstr "Pesquisas recentes"
8082
8183#: qml/Components/SeeMore.qml:35
8284msgid "See more"
83−msgstr ""
85+msgstr "Ver mais"
8486
8587#: qml/Components/SeeMore.qml:58
8688msgid "See less"
87−msgstr ""
89+msgstr "Ver menos"
8890
8991#: qml/Dash/DashApps.qml:37
9092msgid "Recent"
91−msgstr ""
93+msgstr "Recentes"
9294
9395#: qml/Dash/PreviewListView.qml:52
9496#, qt-format
9597msgid "%1 Preview"
96−msgstr ""
98+msgstr "%1 visualização"
9799
98100#: qml/Dash/Previews/PreviewActionCombo.qml:34
99101msgid "More..."
100−msgstr ""
102+msgstr "Mais..."
101103
102104#: qml/Dash/Previews/PreviewActionCombo.qml:34
103105msgid "Less..."
104−msgstr ""
106+msgstr "Menos..."
105107
106108#: qml/Dash/Previews/PreviewRatingInput.qml:81
107109msgid "Rate this"
@@ -117,7 +119,7 @@ msgstr "Enviar"
117119
118120#: qml/Greeter/Greeter.qml:151
119121msgid "Swipe to unlock"
120−msgstr ""
122+msgstr "Deslizar para desbloquear"
121123
122124#: qml/Greeter/Lockscreen.qml:149
123125msgid "Emergency Call"
@@ -158,7 +160,7 @@ msgstr "Exibir senha"
158160
159161#: qml/Notifications/NotificationMenuItemFactory.qml:103
160162msgid "Please enter SIM PIN"
161−msgstr ""
163+msgstr "Por favor, digite o PIN do cartão SIM"
162164
163165#: qml/Panel/SearchIndicator.qml:27
164166msgid "Search"
po/ru.po+4−4
@@ -8,14 +8,14 @@ msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2014-04-10 11:13-0400\n"
11−"PO-Revision-Date: 2014-04-03 13:07+0000\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-05-01 06:44+0000\n"
18−"X-Generator: Launchpad (build 16985)\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
@@ -122,7 +122,7 @@ msgstr "Отправить"
122122
123123#: qml/Greeter/Greeter.qml:151
124124msgid "Swipe to unlock"
125−msgstr ""
125+msgstr "Смахните, чтобы разблокировать"
126126
127127#: qml/Greeter/Lockscreen.qml:149
128128msgid "Emergency Call"
po/uk.po+14−12
@@ -8,14 +8,14 @@ msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2014-04-10 11:13-0400\n"
11−"PO-Revision-Date: 2013-11-23 12:37+0000\n"
12−"Last-Translator: Ignat Kizenko <Unknown>\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−"X-Launchpad-Export-Date: 2014-05-01 06:44+0000\n"
18−"X-Generator: Launchpad (build 16985)\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
@@ -74,6 +74,8 @@ msgid ""
7474"You have now mastered the edge gestures and can start using the "
7575"phone<br><br>Tap on the screen to start"
7676msgstr ""
77+"Вами налаштовано дії у відповідь на дотики на краях екрана. Тепер телефоном "
78+"можна користуватися.<br><br>Торкніться екрана, щоб розпочати."
7779
7880#: qml/Components/PageHeader.qml:365
7981msgid "Recent searches"
@@ -81,28 +83,28 @@ msgstr "Нещодавні пошуки"
8183
8284#: qml/Components/SeeMore.qml:35
8385msgid "See more"
84−msgstr ""
86+msgstr "Докладніше"
8587
8688#: qml/Components/SeeMore.qml:58
8789msgid "See less"
88−msgstr ""
90+msgstr "Стисліше"
8991
9092#: qml/Dash/DashApps.qml:37
9193msgid "Recent"
92−msgstr ""
94+msgstr "Нещодавні"
9395
9496#: qml/Dash/PreviewListView.qml:52
9597#, qt-format
9698msgid "%1 Preview"
97−msgstr ""
99+msgstr "Перегляд %1"
98100
99101#: qml/Dash/Previews/PreviewActionCombo.qml:34
100102msgid "More..."
101−msgstr ""
103+msgstr "Більше…"
102104
103105#: qml/Dash/Previews/PreviewActionCombo.qml:34
104106msgid "Less..."
105−msgstr ""
107+msgstr "Менше..."
106108
107109#: qml/Dash/Previews/PreviewRatingInput.qml:81
108110msgid "Rate this"
@@ -118,7 +120,7 @@ msgstr "Надіслати"
118120
119121#: qml/Greeter/Greeter.qml:151
120122msgid "Swipe to unlock"
121−msgstr ""
123+msgstr "Проведіть пальцем, щоб розблокувати"
122124
123125#: qml/Greeter/Lockscreen.qml:149
124126msgid "Emergency Call"
@@ -159,7 +161,7 @@ msgstr "Показати пароль"
159161
160162#: qml/Notifications/NotificationMenuItemFactory.qml:103
161163msgid "Please enter SIM PIN"
162−msgstr ""
164+msgstr "Введіть PIN-код SIM-картки"
163165
164166#: qml/Panel/SearchIndicator.qml:27
165167msgid "Search"
po/zh_CN.po+31−31
@@ -8,69 +8,69 @@ msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2014-04-10 11:13-0400\n"
11−"PO-Revision-Date: 2013-10-09 13:51+0000\n"
12−"Last-Translator: Aron Xu <Unknown>\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−"X-Launchpad-Export-Date: 2014-05-01 06:44+0000\n"
18−"X-Generator: Launchpad (build 16985)\n"
17+"X-Launchpad-Export-Date: 2014-05-19 06:25+0000\n"
18+"X-Generator: Launchpad (build 17007)\n"
1919
2020#: plugins/Unity/Launcher/launcheritem.cpp:43
2121#: plugins/Unity/Launcher/launcheritem.cpp:73
2222msgid "Lock to Launcher"
23−msgstr ""
23+msgstr "固定到启动器"
2424
2525#: plugins/Unity/Launcher/launcheritem.cpp:73
2626msgid "Unlock from Launcher"
27−msgstr ""
27+msgstr "从启动器移除"
2828
2929#: qml/Components/EdgeDemoOverlay.qml:151
3030msgid "Skip intro"
31−msgstr ""
31+msgstr "跳过简介"
3232
3333#: qml/Components/EdgeDemo.qml:113
3434msgid "Right edge"
35−msgstr ""
35+msgstr "右边缘"
3636
3737#: qml/Components/EdgeDemo.qml:114
3838msgid "Try swiping from the right edge to unlock the phone"
39−msgstr ""
39+msgstr "从右边滑动可以解锁"
4040
4141#: qml/Components/EdgeDemo.qml:145
4242msgid "Top edge"
43−msgstr ""
43+msgstr "上边缘"
4444
4545#: qml/Components/EdgeDemo.qml:146
4646msgid "Try swiping from the top edge to access the indicators"
47−msgstr ""
47+msgstr "从上边缘划入可以访问指示器"
4848
4949#: qml/Components/EdgeDemo.qml:171
5050msgid "Close"
51−msgstr ""
51+msgstr "关闭"
5252
5353#: qml/Components/EdgeDemo.qml:172
5454msgid "Swipe up again to close the settings screen"
55−msgstr ""
55+msgstr "再次向上划动可以关闭设置界面"
5656
5757#: qml/Components/EdgeDemo.qml:199
5858msgid "Left edge"
59−msgstr ""
59+msgstr "左边缘"
6060
6161#: qml/Components/EdgeDemo.qml:200
6262msgid "Swipe from the left to reveal the launcher for quick access to apps"
63−msgstr ""
63+msgstr "从左边划入展开启动器可以快速打开应用"
6464
6565#: qml/Components/EdgeDemo.qml:227
6666msgid "Well done"
67−msgstr ""
67+msgstr "做得好"
6868
6969#: qml/Components/EdgeDemo.qml:228
7070msgid ""
7171"You have now mastered the edge gestures and can start using the "
7272"phone<br><br>Tap on the screen to start"
73−msgstr ""
73+msgstr "您现在已经掌握了边缘滑动手势,可以开始使用手机了<br><br>请点击屏幕开始使用"
7474
7575#: qml/Components/PageHeader.qml:365
7676msgid "Recent searches"
@@ -78,48 +78,48 @@ msgstr "近期搜索"
7878
7979#: qml/Components/SeeMore.qml:35
8080msgid "See more"
81−msgstr ""
81+msgstr "了解更多"
8282
8383#: qml/Components/SeeMore.qml:58
8484msgid "See less"
85−msgstr ""
85+msgstr "显示更少"
8686
8787#: qml/Dash/DashApps.qml:37
8888msgid "Recent"
89−msgstr ""
89+msgstr "最近使用过的"
9090
9191#: qml/Dash/PreviewListView.qml:52
9292#, qt-format
9393msgid "%1 Preview"
94−msgstr ""
94+msgstr "%1 预览"
9595
9696#: qml/Dash/Previews/PreviewActionCombo.qml:34
9797msgid "More..."
98−msgstr ""
98+msgstr "更多..."
9999
100100#: qml/Dash/Previews/PreviewActionCombo.qml:34
101101msgid "Less..."
102−msgstr ""
102+msgstr "更少..."
103103
104104#: qml/Dash/Previews/PreviewRatingInput.qml:81
105105msgid "Rate this"
106−msgstr ""
106+msgstr "评分"
107107
108108#: qml/Dash/Previews/PreviewRatingInput.qml:126
109109msgid "Add a review"
110−msgstr ""
110+msgstr "添加评论"
111111
112112#: qml/Dash/Previews/PreviewRatingInput.qml:166
113113msgid "Send"
114−msgstr ""
114+msgstr "发送"
115115
116116#: qml/Greeter/Greeter.qml:151
117117msgid "Swipe to unlock"
118−msgstr ""
118+msgstr "滑动解锁"
119119
120120#: qml/Greeter/Lockscreen.qml:149
121121msgid "Emergency Call"
122−msgstr ""
122+msgstr "紧急电话"
123123
124124#: qml/Greeter/PassphraseLockscreen.qml:59
125125#, qt-format
@@ -152,11 +152,11 @@ msgstr "讲话中..."
152152
153153#: qml/Notifications/NotificationMenuItemFactory.qml:91
154154msgid "Show password"
155−msgstr ""
155+msgstr "显示密码"
156156
157157#: qml/Notifications/NotificationMenuItemFactory.qml:103
158158msgid "Please enter SIM PIN"
159−msgstr ""
159+msgstr "请输入 SIM PIN"
160160
161161#: qml/Panel/SearchIndicator.qml:27
162162msgid "Search"
@@ -165,4 +165,4 @@ msgstr "搜索"
165165#: qml/Shell.qml:348
166166#, qt-format
167167msgid "Please enter %1"
168−msgstr ""
168+msgstr "请输入 %1"
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/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+23−11
@@ -18,7 +18,6 @@ import QtQuick 2.0
1818import Ubuntu.Components 0.1
1919import "../Components"
2020
21−
2221DashRenderer {
2322 id: cardCarousel
2423
@@ -49,21 +48,34 @@ DashRenderer {
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+19−16
@@ -45,25 +45,28 @@ DashRenderer {
4545 collapsedRowCount: Math.min(2, cardTool && cardTool.template && cardTool.template["collapsed-rows"] || 2)
4646 delegateCreationBegin: genericFilterGrid.delegateCreationBegin
4747 delegateCreationEnd: genericFilterGrid.delegateCreationEnd
48− delegate: Loader {
49− asynchronous: true
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, result)
66− onPressAndHold: genericFilterGrid.pressAndHold(index)
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 }
6972 }
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/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/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/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
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,6 +86,11 @@ 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";
@@ -66,12 +98,17 @@ int startShell(int argc, const char** argv, void* server)
6698
6799 resolveIconTheme();
68100
69− QStringList args = application->arguments();
70− ApplicationArguments qmlArgs(args);
101+ ApplicationArguments qmlArgs;
102+ if (parser.isSet(windowGeometryOption) &&
103+ parser.value(windowGeometryOption).split('x').size() == 2)
104+ {
105+ QStringList geom = parser.value(windowGeometryOption).split('x');
106+ qmlArgs.setSize(geom.at(0).toInt(), geom.at(1).toInt());
107+ }
71108
72109 // The testability driver is only loaded by QApplication but not by QGuiApplication.
73110 // However, QApplication depends on QWidget which would add some unneeded overhead => Let's load the testability driver on our own.
74− if (args.contains(QLatin1String("-testability")) || getenv("QT_LOAD_TESTABILITY")) {
111+ if (parser.isSet(testabilityOption) || getenv("QT_LOAD_TESTABILITY")) {
75112 QLibrary testLib(QLatin1String("qttestability"));
76113 if (testLib.load()) {
77114 typedef void (*TasInitialize)(void);
@@ -94,14 +131,14 @@ int startShell(int argc, const char** argv, void* server)
94131 view->engine()->setBaseUrl(QUrl::fromLocalFile(::qmlDirectory()));
95132 view->rootContext()->setContextProperty("applicationArguments", &qmlArgs);
96133 view->rootContext()->setContextProperty("indicatorProfile", indicatorProfile);
97− if (args.contains(QLatin1String("-frameless"))) {
134+ if (parser.isSet(framelessOption)) {
98135 view->setFlags(Qt::FramelessWindowHint);
99136 }
100137
101138 // You will need this if you want to interact with touch-only components using a mouse
102139 // Needed only when manually testing on a desktop.
103140 MouseTouchAdaptor *mouseTouchAdaptor = 0;
104− if (args.contains(QLatin1String("-mousetouch"))) {
141+ if (parser.isSet(mousetouchOption)) {
105142 mouseTouchAdaptor = new MouseTouchAdaptor;
106143 application->installNativeEventFilter(mouseTouchAdaptor);
107144 }
@@ -125,7 +162,7 @@ int startShell(int argc, const char** argv, void* server)
125162 view->setSource(source);
126163 view->setColor("transparent");
127164
128− if (qgetenv("QT_QPA_PLATFORM") == "ubuntu" || isUbuntuMirServer || args.contains(QLatin1String("-fullscreen"))) {
165+ if (qgetenv("QT_QPA_PLATFORM") == "ubuntu" || isUbuntuMirServer || parser.isSet(fullscreenOption)) {
129166 view->showFullScreen();
130167 } else {
131168 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/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/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+1−12
@@ -47,15 +47,4 @@ target_link_libraries(FakeUnityQml
4747
4848qt5_use_modules(FakeUnityQml Qml)
4949
50−# copy qmldir file into build directory for shadow builds
51−file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/qmldir"
52− DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
53− )
54−
55−install(TARGETS FakeUnityQml
56− DESTINATION ${SHELL_INSTALL_QML}/scopefakes/Unity
57− )
58−
59−install(FILES qmldir
60− DESTINATION ${SHELL_INSTALL_QML}/scopefakes/Unity
61− )
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+15−2
@@ -98,7 +98,12 @@ Categories::data(const QModelIndex& index, int role) const
9898 case RoleRenderer:
9999 {
100100 QVariantMap map;
101− 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+ }
102107 map["card-size"] = "small";
103108 return map;
104109 }
@@ -133,7 +138,14 @@ Categories::data(const QModelIndex& index, int role) const
133138 case RoleRenderer:
134139 {
135140 QVariantMap map;
136− 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+ }
137149 map["card-size"] = "small";
138150 return map;
139151 }
@@ -144,6 +156,7 @@ Categories::data(const QModelIndex& index, int role) const
144156 artMap["field"] = "art";
145157 map["art"] = artMap;
146158 map["title"] = "HOLA";
159+ map["subtitle"] = "HOLA";
147160 return map;
148161 }
149162 case RoleResults:
tests/mocks/Unity/fake_resultsmodel.cpp+1
@@ -65,6 +65,7 @@ ResultsModel::data(const QModelIndex& index, int role) const
6565 case RoleArt:
6666 return qmlDirectory() + "graphics/applicationIcons/dash.png";
6767 case RoleSubtitle:
68+ return QString("Subtitle.%1.%2").arg(m_categoryId).arg(index.row());
6869 case RoleMascot:
6970 case RoleEmblem:
7071 case RoleSummary:
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/DashViews/CMakeLists.txt → tests/plugins/Dash/CMakeLists.txtrenamed+16−9
@@ -16,7 +16,7 @@ include_directories(
1616 ${Qt5Quick_INCLUDE_DIRS}
1717 ${Qt5Quick_PRIVATE_INCLUDE_DIRS}
1818 ${Qt5V8_PRIVATE_INCLUDE_DIR}
19− ${CMAKE_CURRENT_SOURCE_DIR}/../../../plugins/DashViews
19+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../plugins/Dash
2020 ${CMAKE_CURRENT_BINARY_DIR}
2121 )
2222
@@ -28,11 +28,11 @@ add_definitions(-DBUILT_PLUGINS_DIR="${CMAKE_BINARY_DIR}/plugins")
2828macro(add_lvwph_test FILENAME TESTNAME)
2929 add_executable(${TESTNAME}TestExec
3030 ${FILENAME}test.cpp
31− ${CMAKE_CURRENT_SOURCE_DIR}/../../../plugins/DashViews/listviewwithpageheader.cpp)
31+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../plugins/Dash/listviewwithpageheader.cpp)
3232 qt5_use_modules(${TESTNAME}TestExec Test Core Qml)
3333 target_link_libraries(${TESTNAME}TestExec ${Qt5Gui_LIBRARIES} ${Qt5Quick_LIBRARIES})
3434
35− add_binary_qml_test(${TESTNAME} "" "DashViews-qml")
35+ add_binary_qml_test(${TESTNAME} "" "Dash-qml")
3636endmacro()
3737
3838add_lvwph_test(listviewwithpageheader ListViewWithPageHeader)
@@ -42,24 +42,24 @@ add_lvwph_test(listviewwithpageheadersectionexternalmodel ListViewWithPageHeader
4242macro(add_dashview_try_test FILENAME TESTNAME)
4343 add_executable(${TESTNAME}TestExec
4444 ${FILENAME}test.cpp
45− ${CMAKE_CURRENT_SOURCE_DIR}/../../../plugins/DashViews/${FILENAME}.cpp
46− ${CMAKE_CURRENT_SOURCE_DIR}/../../../plugins/DashViews/abstractdashview.cpp
45+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../plugins/Dash/${FILENAME}.cpp
46+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../plugins/Dash/abstractdashview.cpp
4747 )
4848 qt5_use_modules(${TESTNAME}TestExec Test Core Qml)
4949 target_link_libraries(${TESTNAME}TestExec ${Qt5Gui_LIBRARIES} ${Qt5Quick_LIBRARIES})
5050
51− add_binary_qml_test(${TESTNAME} "" "DashViews-qml")
51+ add_binary_qml_test(${TESTNAME} "" "Dash-qml")
5252
5353 add_executable(${TESTNAME}tryExec
5454 ${FILENAME}try.cpp
55− ${CMAKE_CURRENT_SOURCE_DIR}/../../../plugins/DashViews/${FILENAME}.cpp
56− ${CMAKE_CURRENT_SOURCE_DIR}/../../../plugins/DashViews/abstractdashview.cpp
55+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../plugins/Dash/${FILENAME}.cpp
56+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../plugins/Dash/abstractdashview.cpp
5757 )
5858 qt5_use_modules(${TESTNAME}tryExec Test Core Qml)
5959 target_link_libraries(${TESTNAME}tryExec ${Qt5Gui_LIBRARIES} ${Qt5Quick_LIBRARIES})
6060 add_custom_target(try${TESTNAME}
6161 ${CMAKE_CURRENT_BINARY_DIR}/${TESTNAME}tryExec
62− DEPENDS ${TESTNAME}tryExec DashViews-qml
62+ DEPENDS ${TESTNAME}tryExec Dash-qml
6363 )
6464endmacro()
6565
@@ -67,6 +67,13 @@ add_dashview_try_test(verticaljournal VerticalJournal)
6767add_dashview_try_test(horizontaljournal HorizontalJournal)
6868add_dashview_try_test(organicgrid OrganicGrid)
6969
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
7077set(qmltest_DEFAULT_TARGETS qmluitests)
7178set(qmltest_DEFAULT_NO_ADD_TEST TRUE)
7279add_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

The content is the same.

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/listviewwithpageheadersectionexternalmodeltest.cpp → tests/plugins/Dash/listviewwithpageheadersectionexternalmodeltest.cpprenamed

The content is the same.

tests/plugins/DashViews/listviewwithpageheadersectiontest.cpp → tests/plugins/Dash/listviewwithpageheadersectiontest.cpprenamed

The content is the same.

tests/plugins/DashViews/listviewwithpageheadertest.cpp → tests/plugins/Dash/listviewwithpageheadertest.cpprenamed

The content is the same.

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

The content is the same.

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

The content is the same.

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/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/qmltests/CMakeLists.txt+3−4
@@ -28,17 +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)
3534add_qml_test(Components ZoomableImage)
3635add_qml_test(Dash Dash IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
3736add_qml_test(Dash DashContent IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
38−add_qml_test(Dash Card)
39−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})
4039add_qml_test(Dash CardHeader)
41−add_qml_test(Dash CardTool)
40+add_qml_test(Dash CardTool IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
4241add_qml_test(Dash GenericScopeView IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
4342add_qml_test(Dash/Apps RunningApplicationsGrid IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS}
4443 ${CMAKE_BINARY_DIR}/tests/mocks
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_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/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_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/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/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/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"