on xenial help sign in
merged with trunk
3b6df80Nick Dedekind
.bazaar/plugins/makecheck_unity_phablet.py+16−8
@@ -1,5 +1,5 @@
1#!/usr/bin/python
1#!/usr/bin/python
2−# Copyright 2013 Canonical Ltd.
2+# Copyright 2013, 2014 Canonical Ltd.
3#
3#
4# This program is free software; you can redistribute it and/or modify
4# This program is free software; you can redistribute it and/or modify
5# it under the terms of the GNU Lesser General Public License as published by
5# it under the terms of the GNU Lesser General Public License as published by
@@ -13,11 +13,15 @@
13# You should have received a copy of the GNU Lesser General Public License
13# You should have received a copy of the GNU Lesser General Public License
14# along with this program. If not, see <http://www.gnu.org/licenses/>.
14# along with this program. If not, see <http://www.gnu.org/licenses/>.
15
15
16−import os, subprocess
16+import os
17+import subprocess
17−from bzrlib import branch, errors
18+from bzrlib import branch
18−from bzrlib.urlutils import dirname, local_path_from_url
19+from bzrlib.urlutils import local_path_from_url
19
20
21+
22+def execute_makecheck(
23+ local_branch, master_branch, old_revision_number, old_revision_id,
20−def execute_makecheck(local_branch, master_branch, old_revision_number, old_revision_id, future_revision_number, future_revision_id, tree_delta, future_tree):
24+ future_revision_number, future_revision_id, tree_delta, future_tree):
21 if not master_branch.basis_tree().has_filename("qml/Shell.qml"):
25 if not master_branch.basis_tree().has_filename("qml/Shell.qml"):
22 return
26 return
23
27
@@ -27,7 +31,9 @@ def execute_makecheck(local_branch, master_branch, old_revision_number, old_revi
27 os.environ['CTEST_OUTPUT_ON_FAILURE'] = "1"
31 os.environ['CTEST_OUTPUT_ON_FAILURE'] = "1"
28 if (subprocess.call("make -C builddir test", shell=True) != 0):
32 if (subprocess.call("make -C builddir test", shell=True) != 0):
29
33
34+ print("\n\n*** Warning ***\n\n"
30− print("\n\n*** Warning ***\n\nBasic tests failed. This commit will not pass continuous integration.")
35+ "Basic tests failed. This commit will not pass continuous "
36+ "integration.")
31
37
32 branch = local_branch or master_branch
38 branch = local_branch or master_branch
33 revision = branch.repository.get_revision(future_revision_id)
39 revision = branch.repository.get_revision(future_revision_id)
@@ -36,8 +42,10 @@ def execute_makecheck(local_branch, master_branch, old_revision_number, old_revi
36 msg_file.close()
42 msg_file.close()
37
43
38 print("\n\nSaved commit message to $SRC_DIR/message.txt.")
44 print("\n\nSaved commit message to $SRC_DIR/message.txt.")
39− print("You can uncommit this revision, fix the tests and reuse your message running:\n\nbzr commit -F message.txt\n\n")
45+ print("You can uncommit this revision, fix the tests and reuse your "
46+ "message running:\n\nbzr commit -F message.txt\n\n")
40 elif os.path.isfile("message.txt"):
47 elif os.path.isfile("message.txt"):
41 os.remove("message.txt")
48 os.remove("message.txt")
42
49
50+branch.Branch.hooks.install_named_hook(
43−branch.Branch.hooks.install_named_hook('pre_commit', execute_makecheck, 'make check pre-commit')
51+ 'pre_commit', execute_makecheck, 'make check pre-commit')
build.sh+1
@@ -42,6 +42,7 @@ install_dependencies() {
42 equivs \
42 equivs \
43 gsettings-desktop-schemas \
43 gsettings-desktop-schemas \
44 gsettings-ubuntu-schemas \
44 gsettings-ubuntu-schemas \
45+ pay-service \
45 qmenumodel-qml \
46 qmenumodel-qml \
46 qml-module-qtquick-xmllistmodel \
47 qml-module-qtquick-xmllistmodel \
47 qtdeclarative5-gsettings1.0 \
48 qtdeclarative5-gsettings1.0 \
cmake/modules/QmlPlugins.cmake+29−22
@@ -12,6 +12,12 @@ if(NOT TARGET qmlplugindump)
12 set_target_properties(qmlplugindump PROPERTIES IMPORTED_LOCATION ${qmlplugindump_exe})
12 set_target_properties(qmlplugindump PROPERTIES IMPORTED_LOCATION ${qmlplugindump_exe})
13endif()
13endif()
14
14
15+#
16+# A custom target for building the qmltypes files manually.
17+#
18+if (NOT TARGET qmltypes)
19+ add_custom_target(qmltypes)
20+endif()
15
21
16# Creates a target for copying resource files into build dir and optionally installing them.
22# Creates a target for copying resource files into build dir and optionally installing them.
17#
23#
@@ -51,6 +57,7 @@ macro(export_qmlfiles PLUGIN PATH)
51 ${QMLFILES_SEARCH_PATH}/*.png
57 ${QMLFILES_SEARCH_PATH}/*.png
52 ${QMLFILES_SEARCH_PATH}/*.sci
58 ${QMLFILES_SEARCH_PATH}/*.sci
53 ${QMLFILES_SEARCH_PATH}/*.svg
59 ${QMLFILES_SEARCH_PATH}/*.svg
60+ ${QMLFILES_SEARCH_PATH}/*.qmltypes
54 ${QMLFILES_SEARCH_PATH}/qmldir
61 ${QMLFILES_SEARCH_PATH}/qmldir
55 )
62 )
56
63
@@ -69,14 +76,14 @@ macro(export_qmlfiles PLUGIN PATH)
69 DESTINATION ${QMLFILES_DESTINATION}/${PATH}
76 DESTINATION ${QMLFILES_DESTINATION}/${PATH}
70 )
77 )
71 endif()
78 endif()
72−endmacro(export_qmlfiles)
79+endmacro()
73
80
74
81
75−# Creates a target for generating the typeinfo file for a QML plugin and optionally installs it
82+# Creates a target for generating the typeinfo file for a QML plugin and/or installs the plugin
76−# and additional targets.
83+# targets.
77#
84#
78# Files will be copied into ${BINARY_DIR}/${path} or ${CMAKE_CURRENT_BINARY_DIR} and installed
85# 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
86+# into ${DESTINATION}/${path}. If you don't pass BINARY_DIR, it's assumed that current source
80# path ends with ${path}.
87# path ends with ${path}.
81#
88#
82# The generated file will be named after the last segment of the plugin name, e.g. Foo.qmltypes.
89# The generated file will be named after the last segment of the plugin name, e.g. Foo.qmltypes.
@@ -87,15 +94,18 @@ endmacro(export_qmlfiles)
87# [TARGET_PREFIX string] # Will be prefixed to the target name
94# [TARGET_PREFIX string] # Will be prefixed to the target name
88# [ENVIRONMENT string] # Will be added to qmlplugindump's env
95# [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)
96# [TARGETS target1 [target2 ...]] # Targets to depend on and install (e.g. the plugin shared object)
97+# [NO_TYPES] # Do not create the qmltypes target
90# )
98# )
91#
99#
92# Created target:
100# Created target:
93−# - ${TARGET_PREFIX}${plugin}-qmltypes - Generates the qmltypes file in the binary dir.
101+# - ${TARGET_PREFIX}${plugin}-qmltypes - Generates the qmltypes file in the source dir.
102+# It will be made a dependency of the "qmltypes" target.
94
103
95macro(export_qmlplugin PLUGIN VERSION PATH)
104macro(export_qmlplugin PLUGIN VERSION PATH)
105+ set(options NO_TYPES)
96 set(single BINARY_DIR DESTINATION TARGET_PREFIX ENVIRONMENT)
106 set(single BINARY_DIR DESTINATION TARGET_PREFIX ENVIRONMENT)
97 set(multi TARGETS)
107 set(multi TARGETS)
98− cmake_parse_arguments(QMLPLUGIN "" "${single}" "${multi}" ${ARGN})
108+ cmake_parse_arguments(QMLPLUGIN "${options}" "${single}" "${multi}" ${ARGN})
99
109
100 get_target_property(qmlplugindump_executable qmlplugindump LOCATION)
110 get_target_property(qmlplugindump_executable qmlplugindump LOCATION)
101
111
@@ -103,29 +113,26 @@ macro(export_qmlplugin PLUGIN VERSION PATH)
103 set(qmlplugin_dir ${QMLPLUGIN_BINARY_DIR}/${PATH})
113 set(qmlplugin_dir ${QMLPLUGIN_BINARY_DIR}/${PATH})
104 else()
114 else()
105 # Find import path to point qmlplugindump at
115 # Find import path to point qmlplugindump at
106− string(REGEX REPLACE "${PATH}$" "" QMLPLUGIN_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}")
116+ string(REGEX REPLACE "/${PATH}$" "" QMLPLUGIN_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}")
107 set(qmlplugin_dir ${CMAKE_CURRENT_BINARY_DIR})
117 set(qmlplugin_dir ${CMAKE_CURRENT_BINARY_DIR})
108 endif()
118 endif()
109
119
120+ if(NOT QMLPLUGIN_NO_TYPES)
121+ # Relative path for the module
122+ string(REPLACE "${CMAKE_BINARY_DIR}/" "" QMLPLUGIN_MODULE_DIR "${QMLPLUGIN_BINARY_DIR}")
123+
110− # Find the last segment of the plugin name to use as qmltypes basename
124+ # Find the last segment of the plugin name to use as qmltypes basename
111− string(REGEX MATCH "[^.]+$" plugin_suffix ${PLUGIN})
125+ string(REGEX MATCH "[^.]+$" plugin_suffix ${PLUGIN})
112− set(target_prefix ${QMLPLUGIN_TARGET_PREFIX}${PLUGIN})
126+ set(target_prefix ${QMLPLUGIN_TARGET_PREFIX}${PLUGIN})
113− set(qmltypes_path ${qmlplugin_dir}/${plugin_suffix}.qmltypes)
127+ set(qmltypes_path ${CMAKE_CURRENT_SOURCE_DIR}/${plugin_suffix}.qmltypes)
114
128
115− # Only generate typeinfo if not cross compiling
116− if(NOT CMAKE_CROSSCOMPILING)
117− add_custom_target(${target_prefix}-qmltypes ALL
129+ add_custom_target(${target_prefix}-qmltypes
118 COMMAND env ${QMLPLUGIN_ENVIRONMENT} ${qmlplugindump_executable} -notrelocatable
130 COMMAND env ${QMLPLUGIN_ENVIRONMENT} ${qmlplugindump_executable} -notrelocatable
119− ${PLUGIN} ${VERSION} ${QMLPLUGIN_BINARY_DIR} > ${qmltypes_path}
131+ ${PLUGIN} ${VERSION} ${QMLPLUGIN_MODULE_DIR} > ${qmltypes_path}
132+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
120 )
133 )
121 add_dependencies(${target_prefix}-qmltypes ${target_prefix}-qmlfiles ${QMLPLUGIN_TARGETS})
134 add_dependencies(${target_prefix}-qmltypes ${target_prefix}-qmlfiles ${QMLPLUGIN_TARGETS})
122−
135+ add_dependencies(qmltypes ${target_prefix}-qmltypes)
123− if (QMLPLUGIN_DESTINATION)
124− # Install the typeinfo file
125− install(FILES ${qmltypes_path}
126− DESTINATION ${QMLPLUGIN_DESTINATION}/${PATH}
127− )
128− endif()
129 endif()
136 endif()
130
137
131 set_target_properties(${QMLPLUGIN_TARGETS} PROPERTIES
138 set_target_properties(${QMLPLUGIN_TARGETS} PROPERTIES
cmake/modules/autopilot.cmake+2−2
@@ -2,7 +2,7 @@ add_custom_target(autopilot)
2
2
3function(declare_autopilot_test TEST_NAME TEST_SUITE WORKING_DIR)
3function(declare_autopilot_test TEST_NAME TEST_SUITE WORKING_DIR)
4 add_custom_target(autopilot-${TEST_NAME}
4 add_custom_target(autopilot-${TEST_NAME}
5− COMMAND LANG=C UBUNTU_ICON_THEME=ubuntu-mobile QML2_IMPORT_PATH=${SHELL_INSTALL_QML}/mocks python3 -m autopilot.run run ${TEST_SUITE}
5+ COMMAND LANG=C QML2_IMPORT_PATH=${SHELL_INSTALL_QML}/mocks python3 -m autopilot.run run ${TEST_SUITE}
6 WORKING_DIRECTORY ${WORKING_DIR}
6 WORKING_DIRECTORY ${WORKING_DIR}
7 DEPENDS fake_install
7 DEPENDS fake_install
8 )
8 )
@@ -14,7 +14,7 @@ function(declare_autopilot_test TEST_NAME TEST_SUITE WORKING_DIR)
14 add_dependencies(autopilot autopilot-${TEST_NAME})
14 add_dependencies(autopilot autopilot-${TEST_NAME})
15
15
16 add_custom_target(autopilot2-${TEST_NAME}
16 add_custom_target(autopilot2-${TEST_NAME}
17− COMMAND LANG=C UBUNTU_ICON_THEME=ubuntu-mobile QML2_IMPORT_PATH=${SHELL_INSTALL_QML}/mocks python2 -m autopilot.run run ${TEST_SUITE}
17+ COMMAND LANG=C QML2_IMPORT_PATH=${SHELL_INSTALL_QML}/mocks python2 -m autopilot.run run ${TEST_SUITE}
18 WORKING_DIRECTORY ${WORKING_DIR}
18 WORKING_DIRECTORY ${WORKING_DIR}
19 DEPENDS fake_install
19 DEPENDS fake_install
20 )
20 )
debian/changelog+149
@@ -1,3 +1,152 @@
1+unity8 (7.90+14.10.20140703.1-0ubuntu1) utopic; urgency=low
2+
3+ [ Michał Sawicz ]
4+ * Initial code for a payment button widget, to handle purchasing apps
5+ from the click scope.
6+
7+ [ Nick Dedekind ]
8+ * Moved [Message]MenuItemFacotory from Unity.Indicators plugin to qml
9+ folder.
10+
11+ [ Albert Astals ]
12+ * EasingCurve: Initialize members
13+ * Fix valgrind warning by not emitting reset on model destructor That
14+ won't be supported until Qt 5.4 More info at https://bugreports.qt-
15+ project.org/browse/QTBUG-39780 Warning was ==16693== Invalid read of
16+ size 8 ==16693== at 0x72B19A0: QQmlContext::isValid() const
17+ (qqmlcontext.cpp:231) ==16693== by 0x736C82B:
18+ QQmlDelegateModelPrivate::emitChanges() (qqmldelegatemodel.cpp:1412)
19+ ==16693== by 0x7372AE6: QQmlDelegateModel::_q_modelReset()
20+ (qqmldelegatemodel.cpp:1463) ==16693== by 0x7397224:
21+ QQmlDelegateModel::qt_static_metacall(QObject*, QMetaObject::Call,
22+ int, void**) (moc_qqmldelegatemodel_p.cpp:196) ==16693== by
23+ 0x739769E: QQmlDelegateModel::qt_metacall(QMetaObject::Call, int,
24+ void**) (moc_qqmldelegatemodel_p.cpp:292) ==16693== by 0x66379CC:
25+ QMetaObject::activate(QObject*, int, int, void**) (in
26+ /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.3.0) ==16693== by
27+ 0x65AEEFD: QAbstractItemModel::endResetModel() (in /usr/lib/x86_64-
28+ linux-gnu/libQt5Core.so.5.3.0) ==16693== by 0x23461EFD:
29+ FakeIndicatorsModel::unload() (fakeindicatorsmodel.cpp:53) ==16693==
30+ by 0x23461E13: FakeIndicatorsModel::~FakeIndicatorsModel()
31+ (fakeindicatorsmodel.cpp:34) ==16693== by 0x2345C073:
32+ QQmlPrivate::QQmlElement<FakeIndicatorsModel>::~QQmlElement() (in
33+ /home/tsdgeos_work/phablet/unity8/investigate_test_shell_crash/build
34+ dir/tests/mocks/Unity/Indicators/libIndicatorsFakeQml.so) ==16693==
35+ by 0x2345C0A3:
36+ QQmlPrivate::QQmlElement<FakeIndicatorsModel>::~QQmlElement()
37+ (qqmlprivate.h:106) ==16693== by 0x663636B:
38+ QObjectPrivate::deleteChildren() (in /usr/lib/x86_64-linux-
39+ gnu/libQt5Core.so.5.3.0) ==16693== Address 0x1862d448 is 8 bytes
40+ inside a block of size 16 free'd ==16693== at 0x4C2C2BC: operator
41+ delete(void*) (vg_replace_malloc.c:503) ==16693== by 0x72B21B8:
42+ QQmlContextData::destroy() (qqmlcontext.cpp:647) ==16693== by
43+ 0x7293458: QQmlPrivate::qdeclarativeelement_destructor(QObject*)
44+ (qqmlengine.cpp:612) ==16693== by 0x6C0CADD:
45+ QQmlPrivate::QQmlElement<QQuickItem>::~QQmlElement()
46+ (qqmlprivate.h:105) ==16693== by 0x663636B:
47+ QObjectPrivate::deleteChildren() (in /usr/lib/x86_64-linux-
48+ gnu/libQt5Core.so.5.3.0) ==16693== by 0x663F0EB: QObject::~QObject()
49+ (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.3.0) ==16693== by
50+ 0x6BF64B5: QQuickItem::~QQuickItem() (qquickitem.cpp:2064) ==16693==
51+ by 0x6C0CAE5: QQmlPrivate::QQmlElement<QQuickItem>::~QQmlElement()
52+ (qqmlprivate.h:106) ==16693== by 0x663636B:
53+ QObjectPrivate::deleteChildren() (in /usr/lib/x86_64-linux-
54+ gnu/libQt5Core.so.5.3.0) ==16693== by 0x663F0EB: QObject::~QObject()
55+ (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.3.0) ==16693== by
56+ 0x6BF64B5: QQuickItem::~QQuickItem() (qquickitem.cpp:2064) ==16693==
57+ by 0x6C0CAE5: QQmlPrivate::QQmlElement<QQuickItem>::~QQmlElement()
58+ (qqmlprivate.h:106) (LP: #1332598)
59+
60+ [ Michael Zanetti ]
61+ * drop launcher item spacing (LP: #1332022)
62+ * change wording in launcher quicklist (LP: #1332035)
63+
64+ [ Alejandro J. Cura ]
65+ * Initial code for a payment button widget, to handle purchasing apps
66+ from the click scope.
67+
68+ [ Rodney Dawes ]
69+ * Initial code for a payment button widget, to handle purchasing apps
70+ from the click scope.
71+
72+ [ Renato Araujo Oliveira Filho ]
73+ * Create IndicatorsLight.qml component used to control indicator led.
74+ A blue led will pulse if the message indicator is blue and screen is
75+ off.
76+
77+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Thu, 03 Jul 2014 14:47:46 +0000
78+
79+unity8 (7.90+14.10.20140701.2-0ubuntu2) utopic; urgency=medium
80+
81+ * debian/control:
82+ list qtdeclarative5-ubuntu-ui-toolkit-plugin-gles as an alternative
83+ choice, since provides are not versionned, should restore installability
84+ on amd64 and i386
85+
86+ -- Sebastien Bacher <seb128@ubuntu.com> Thu, 03 Jul 2014 13:26:38 +0200
87+
88+unity8 (7.90+14.10.20140701.2-0ubuntu1) utopic; urgency=medium
89+
90+ [ Michał Sawicz ]
91+ * Adapt to suru theme.
92+
93+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Tue, 01 Jul 2014 15:10:35 +0000
94+
95+unity8 (7.89+14.10.20140627-0ubuntu1) utopic; urgency=low
96+
97+ [ Michael Terry ]
98+ * Fix path in launcher mock after moving our mock icons, to avoid a
99+ lot of "icon not found" warnings during qmluitests.
100+ * Fix the testMultiGreeter qmluitest. Incoming method variables are
101+ apparently read-only in Qt5.3. (LP: #1332488)
102+
103+ [ CI bot ]
104+ * Resync trunk
105+
106+ [ Michał Sawicz ]
107+ * Adapt scope mock to new api and quiet unused variable warnings.
108+ * Fix dynamic overlay height. (LP: #1334879)
109+ * Don't center items in CardVerticalJournal, kind of beats the
110+ purpose... Also don't bind unnecessarily.
111+
112+ [ Ying-Chun Liu ]
113+ * Fix LP:1330957 Fix some failed test cases. (LP: #1330957)
114+
115+ [ Albert Astals ]
116+ * Don't seem to need this waitForRendering And makes test fail in 5.3
117+
118+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Fri, 27 Jun 2014 08:47:58 +0000
119+
120+unity8 (7.89+14.10.20140624.1-0ubuntu1) utopic; urgency=low
121+
122+ [ Alberto Aguirre ]
123+ * Update Powerd plugin and Shell.qml to accommodate changes in the
124+ display power state notification.
125+
126+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Tue, 24 Jun 2014 17:11:08 +0000
127+
128+unity8 (7.89+14.10.20140624-0ubuntu1) utopic; urgency=low
129+
130+ [ Ying-Chun Liu ]
131+ * Add logout support. Reviewed by: Daniel d'Andrada (LP: #1302213)
132+
133+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Tue, 24 Jun 2014 08:17:09 +0000
134+
135+unity8 (7.89+14.10.20140623.1-0ubuntu1) utopic; urgency=low
136+
137+ [ Michał Sawicz ]
138+ * Make so that fixedArtShapeSize actually fixes artShapeSize.
139+
140+ [ Albert Astals ]
141+ * Add VerticalJournal integration to Dash/scopes/QML (LP: #1326467)
142+ * Make so that fixedArtShapeSize actually fixes artShapeSize.
143+
144+ [ Mirco Müller ]
145+ * Added the frontend-part of sound-hint support for notifications with
146+ updated QML-tests.
147+
148+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Mon, 23 Jun 2014 11:17:12 +0000
149+
1unity8 (7.89+14.10.20140619.3-0ubuntu1) utopic; urgency=low
150unity8 (7.89+14.10.20140619.3-0ubuntu1) utopic; urgency=low
2
151
3 * New rebuild forced
152 * New rebuild forced
debian/control+10−6
@@ -13,11 +13,13 @@ Build-Depends: cmake,
13 libgles2-mesa-dev[armhf],
13 libgles2-mesa-dev[armhf],
14 libglib2.0-dev,
14 libglib2.0-dev,
15 libgsettings-qt-dev,
15 libgsettings-qt-dev,
16+ libhardware-dev,
16 libhud-client2-dev,
17 libhud-client2-dev,
18+ libpay1-dev,
17 libpulse-dev,
19 libpulse-dev,
18 libqmenumodel-dev (>= 0.2.7),
20 libqmenumodel-dev (>= 0.2.7),
19 libqt5xmlpatterns5-dev,
21 libqt5xmlpatterns5-dev,
20− libunity-api-dev (>= 7.82),
22+ libunity-api-dev (>= 7.83),
21 libunity-mir-dev,
23 libunity-mir-dev,
22 libusermetricsoutput1-dev,
24 libusermetricsoutput1-dev,
23 libxcb1-dev,
25 libxcb1-dev,
@@ -37,8 +39,8 @@ Build-Depends: cmake,
37 qtdeclarative5-dev-tools,
39 qtdeclarative5-dev-tools,
38 qtdeclarative5-private-dev (>= 5.2.1),
40 qtdeclarative5-private-dev (>= 5.2.1),
39 qtdeclarative5-qtmultimedia-plugin,
41 qtdeclarative5-qtmultimedia-plugin,
40− qtdeclarative5-ubuntu-settings-components,
42+ qtdeclarative5-ubuntu-settings-components (>= 0.2),
41− qtdeclarative5-ubuntu-ui-toolkit-plugin,
43+ qtdeclarative5-ubuntu-ui-toolkit-plugin (>= 0.1.48) | qtdeclarative5-ubuntu-ui-toolkit-plugin-gles (>= 0.1.48),
42 ttf-ubuntu-font-family,
44 ttf-ubuntu-font-family,
43Standards-Version: 3.9.4
45Standards-Version: 3.9.4
44Homepage: http://launchpad.net/unity
46Homepage: http://launchpad.net/unity
@@ -51,7 +53,7 @@ Vcs-Browser: https://bazaar.launchpad.net/~unity-team/unity8/trunk
51Package: indicators-client
53Package: indicators-client
52Architecture: amd64 armhf i386
54Architecture: amd64 armhf i386
53Depends: qmenumodel-qml (>= 0.2.7),
55Depends: qmenumodel-qml (>= 0.2.7),
54− qtdeclarative5-ubuntu-ui-toolkit-plugin,
56+ qtdeclarative5-ubuntu-ui-toolkit-plugin (>= 0.1.48) | qtdeclarative5-ubuntu-ui-toolkit-plugin-gles (>= 0.1.48),
55 unity8 (= ${binary:Version}),
57 unity8 (= ${binary:Version}),
56 ${misc:Depends},
58 ${misc:Depends},
57 ${shlibs:Depends},
59 ${shlibs:Depends},
@@ -78,7 +80,7 @@ Depends: gsettings-desktop-schemas,
78 qmenumodel-qml (>= 0.2.7),
80 qmenumodel-qml (>= 0.2.7),
79 qml-module-qtquick-xmllistmodel,
81 qml-module-qtquick-xmllistmodel,
80 qtdeclarative5-gsettings1.0,
82 qtdeclarative5-gsettings1.0,
81− qtdeclarative5-ubuntu-settings-components,
83+ qtdeclarative5-ubuntu-settings-components (>= 0.2),
82 unity-launcher-impl-3,
84 unity-launcher-impl-3,
83 unity8-common (= ${source:Version}),
85 unity8-common (= ${source:Version}),
84 unity8-private (= ${binary:Version}),
86 unity8-private (= ${binary:Version}),
@@ -99,7 +101,7 @@ Description: Unity 8 shell
99Package: unity8-common
101Package: unity8-common
100Architecture: all
102Architecture: all
101Depends: qtdeclarative5-ubuntu-thumbnailer0.1 | ubuntu-thumbnailer-impl,
103Depends: qtdeclarative5-ubuntu-thumbnailer0.1 | ubuntu-thumbnailer-impl,
102− qtdeclarative5-ubuntu-ui-toolkit-plugin,
104+ qtdeclarative5-ubuntu-ui-toolkit-plugin (>= 0.1.48) | qtdeclarative5-ubuntu-ui-toolkit-plugin-gles (>= 0.1.48),
103 qtdeclarative5-unity-notifications-plugin | unity-notifications-impl,
105 qtdeclarative5-unity-notifications-plugin | unity-notifications-impl,
104 ubuntu-thumbnailer-impl-0,
106 ubuntu-thumbnailer-impl-0,
105 unity-application-impl-2,
107 unity-application-impl-2,
@@ -159,7 +161,9 @@ Architecture: any
159Multi-Arch: same
161Multi-Arch: same
160Pre-Depends: ${misc:Pre-Depends},
162Pre-Depends: ${misc:Pre-Depends},
161Depends: gsettings-ubuntu-schemas,
163Depends: gsettings-ubuntu-schemas,
164+ libhardware2,
162 libunity-core-6.0-9,
165 libunity-core-6.0-9,
166+ pay-service,
163 ${misc:Depends},
167 ${misc:Depends},
164 ${shlibs:Depends},
168 ${shlibs:Depends},
165Provides: unity-launcher-impl,
169Provides: unity-launcher-impl,
debian/unity8-private.install+1
@@ -2,6 +2,7 @@ usr/lib/*/unity8/qml/AccountsService
2usr/lib/*/unity8/qml/Dash
2usr/lib/*/unity8/qml/Dash
3usr/lib/*/unity8/qml/HudClient
3usr/lib/*/unity8/qml/HudClient
4usr/lib/*/unity8/qml/LightDM
4usr/lib/*/unity8/qml/LightDM
5+usr/lib/*/unity8/qml/Lights
5usr/lib/*/unity8/qml/Powerd
6usr/lib/*/unity8/qml/Powerd
6usr/lib/*/unity8/qml/SessionBroadcast
7usr/lib/*/unity8/qml/SessionBroadcast
7usr/lib/*/unity8/qml/Ubuntu
8usr/lib/*/unity8/qml/Ubuntu
include/paths.h.in−8
@@ -127,12 +127,4 @@ inline void appendImportPaths(QQmlEngine *engine, const QStringList &paths)
127 engine->setImportPathList(importPathList);
127 engine->setImportPathList(importPathList);
128}
128}
129
129
130−inline void resolveIconTheme() {
131− const char *ubuntuIconTheme = getenv("UBUNTU_ICON_THEME");
132− if (ubuntuIconTheme == NULL) {
133− ubuntuIconTheme = "ubuntu-mobile";
134− }
135− QIcon::setThemeName(ubuntuIconTheme);
136−}
137−
138#endif
130#endif
plugins/AccountsService/AccountsService.qmltypesnew file+22
@@ -0,0 +1,22 @@
1+import QtQuick.tooling 1.1
2+
3+// This file describes the plugin-supplied types contained in the library.
4+// It is used for QML tooling purposes only.
5+//
6+// This file was auto-generated by:
7+// 'qmlplugindump -notrelocatable AccountsService 0.1 plugins'
8+
9+Module {
10+ Component {
11+ name: "AccountsService"
12+ prototype: "QObject"
13+ exports: ["AccountsService/AccountsService 0.1"]
14+ isCreatable: false
15+ isSingleton: true
16+ exportMetaObjectRevisions: [0]
17+ Property { name: "user"; type: "string" }
18+ Property { name: "demoEdges"; type: "bool" }
19+ Property { name: "backgroundFile"; type: "string"; isReadonly: true }
20+ Property { name: "statsWelcomeScreen"; type: "bool"; isReadonly: true }
21+ }
22+}
plugins/CMakeLists.txt+1
@@ -14,6 +14,7 @@ endmacro()
14add_subdirectory(AccountsService)
14add_subdirectory(AccountsService)
15add_subdirectory(HudClient)
15add_subdirectory(HudClient)
16add_subdirectory(LightDM)
16add_subdirectory(LightDM)
17+add_subdirectory(Lights)
17add_subdirectory(Dash)
18add_subdirectory(Dash)
18add_subdirectory(Powerd)
19add_subdirectory(Powerd)
19add_subdirectory(SessionBroadcast)
20add_subdirectory(SessionBroadcast)
plugins/Dash/CardCreator.js+24−14
@@ -55,8 +55,8 @@ var kBackgroundLoaderCode = 'Loader {\n\
55// %3 is used as image height
55// %3 is used as image height
56var kArtShapeHolderCode = 'Item { \n\
56var kArtShapeHolderCode = 'Item { \n\
57 id: artShapeHolder; \n\
57 id: artShapeHolder; \n\
58− height: root.fixedArtShapeSize.height != -1 ? root.fixedArtShapeSize.height : artShapeLoader.height; \n\
58+ height: root.fixedArtShapeSize.height > 0 ? root.fixedArtShapeSize.height : artShapeLoader.height; \n\
59− width: root.fixedArtShapeSize.width != -1 ? root.fixedArtShapeSize.width : artShapeLoader.width; \n\
59+ width: root.fixedArtShapeSize.width > 0 ? root.fixedArtShapeSize.width : artShapeLoader.width; \n\
60 anchors { %1 } \n\
60 anchors { %1 } \n\
61 Loader { \n\
61 Loader { \n\
62 id: artShapeLoader; \n\
62 id: artShapeLoader; \n\
@@ -68,13 +68,18 @@ var kArtShapeHolderCode = 'Item { \n\
68 id: artShape; \n\
68 id: artShape; \n\
69 objectName: "artShape"; \n\
69 objectName: "artShape"; \n\
70 radius: "medium"; \n\
70 radius: "medium"; \n\
71+ visible: image.status == Image.Ready; \n\
72+ readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1; \n\
71− readonly property real aspect: components !== undefined ? components["art"]["aspect-ratio"] : 1; \n\
73+ readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1; \n\
72 readonly property bool aspectSmallerThanImageAspect: aspect < image.aspect; \n\
74 readonly property bool aspectSmallerThanImageAspect: aspect < image.aspect; \n\
73 Component.onCompleted: { updateWidthHeightBindings(); if (artShapeBorderSource !== undefined) borderSource = artShapeBorderSource; } \n\
75 Component.onCompleted: { updateWidthHeightBindings(); if (artShapeBorderSource !== undefined) borderSource = artShapeBorderSource; } \n\
74 onAspectSmallerThanImageAspectChanged: updateWidthHeightBindings(); \n\
76 onAspectSmallerThanImageAspectChanged: updateWidthHeightBindings(); \n\
75− visible: image.status == Image.Ready; \n\
77+ Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); } \n\
76 function updateWidthHeightBindings() { \n\
78 function updateWidthHeightBindings() { \n\
79+ if (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) { \n\
80+ width = root.fixedArtShapeSize.width; \n\
81+ height = root.fixedArtShapeSize.height; \n\
77− if (aspectSmallerThanImageAspect) { \n\
82+ } else if (aspectSmallerThanImageAspect) { \n\
78 width = Qt.binding(function() { return !visible ? 0 : image.width }); \n\
83 width = Qt.binding(function() { return !visible ? 0 : image.width }); \n\
79 height = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.height : width / image.aspect }); \n\
84 height = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.height : width / image.aspect }); \n\
80 } else { \n\
85 } else { \n\
@@ -108,7 +113,7 @@ var kOverlayLoaderCode = 'Loader { \n\
108 visible: showHeader && status == Loader.Ready; \n\
113 visible: showHeader && status == Loader.Ready; \n\
109 sourceComponent: ShaderEffect { \n\
114 sourceComponent: ShaderEffect { \n\
110 id: overlay; \n\
115 id: overlay; \n\
111− height: fixedHeaderHeight != -1 ? fixedHeaderHeight : headerHeight; \n\
116+ height: (fixedHeaderHeight > 0 ? fixedHeaderHeight : headerHeight) + units.gu(2); \n\
112 opacity: 0.6; \n\
117 opacity: 0.6; \n\
113 property var source: ShaderEffectSource { \n\
118 property var source: ShaderEffectSource { \n\
114 id: shaderSource; \n\
119 id: shaderSource; \n\
@@ -145,6 +150,7 @@ var kHeaderRow2Code = 'Row { \n\
145 objectName: "outerRow"; \n\
150 objectName: "outerRow"; \n\
146 property real margins: units.gu(1); \n\
151 property real margins: units.gu(1); \n\
147 spacing: margins; \n\
152 spacing: margins; \n\
153+ height: root.fixedHeaderHeight != -1 ? root.fixedHeaderHeight : implicitHeight; \n\
148 anchors { %1 } \n\
154 anchors { %1 } \n\
149 anchors.right: parent.right; \n\
155 anchors.right: parent.right; \n\
150 anchors.margins: margins;\n\
156 anchors.margins: margins;\n\
@@ -163,6 +169,7 @@ var kHeaderRow3Code = 'Row { \n\
163 objectName: "outerRow"; \n\
169 objectName: "outerRow"; \n\
164 property real margins: units.gu(1); \n\
170 property real margins: units.gu(1); \n\
165 spacing: margins; \n\
171 spacing: margins; \n\
172+ height: root.fixedHeaderHeight != -1 ? root.fixedHeaderHeight : implicitHeight; \n\
166 anchors { %1 } \n\
173 anchors { %1 } \n\
167 anchors.right: parent.right; \n\
174 anchors.right: parent.right; \n\
168 anchors.margins: margins;\n\
175 anchors.margins: margins;\n\
@@ -315,7 +322,7 @@ function cardString(template, components) {
315 anchors = 'left: parent.left';
322 anchors = 'left: parent.left';
316 if (hasMascot || hasTitle) {
323 if (hasMascot || hasTitle) {
317 widthCode = 'height * artShape.aspect'
324 widthCode = 'height * artShape.aspect'
318− heightCode = 'headerHeight';
325+ heightCode = 'headerHeight + 2 * units.gu(1)';
319 } else {
326 } else {
320 // This side of the else is a bit silly, who wants an horizontal layout without mascot and title?
327 // 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
328 // So we define a "random" height of the image height + 2 gu for the margins
@@ -356,23 +363,23 @@ function cardString(template, components) {
356 }
363 }
357 }
364 }
358 var headerLeftAnchor;
365 var headerLeftAnchor;
359− var headerLeftAnchorHasMagin = false;
366+ var headerLeftAnchorHasMargin = false;
360 if (isHorizontal && hasArt) {
367 if (isHorizontal && hasArt) {
361 headerLeftAnchor = 'left: artShapeHolder.right; \n\
368 headerLeftAnchor = 'left: artShapeHolder.right; \n\
362 leftMargin: units.gu(1);\n';
369 leftMargin: units.gu(1);\n';
363− headerLeftAnchorHasMagin = true;
370+ headerLeftAnchorHasMargin = true;
364 } else {
371 } else {
365 headerLeftAnchor = 'left: parent.left;\n';
372 headerLeftAnchor = 'left: parent.left;\n';
366 }
373 }
367
374
368 if (hasHeaderRow) {
375 if (hasHeaderRow) {
369− code += 'readonly property int headerHeight: row.height + row.margins * 2;\n'
376+ code += 'readonly property int headerHeight: row.height;\n'
370 } else if (hasMascot) {
377 } else if (hasMascot) {
371− code += 'readonly property int headerHeight: mascotImage.height + units.gu(1) * 2;\n'
378+ code += 'readonly property int headerHeight: mascotImage.height;\n'
372 } else if (hasSubtitle) {
379 } else if (hasSubtitle) {
373− code += 'readonly property int headerHeight: titleLabel.height + titleLabel.anchors.topMargin * 2 + subtitleLabel.height + subtitleLabel.anchors.topMargin;\n'
380+ code += 'readonly property int headerHeight: titleLabel.height + subtitleLabel.height + subtitleLabel.anchors.topMargin;\n'
374 } else if (hasTitle) {
381 } else if (hasTitle) {
375− code += 'readonly property int headerHeight: titleLabel.height + titleLabel.anchors.topMargin * 2;\n'
382+ code += 'readonly property int headerHeight: titleLabel.height;\n'
376 } else {
383 } else {
377 code += 'readonly property int headerHeight: 0;\n'
384 code += 'readonly property int headerHeight: 0;\n'
378 }
385 }
@@ -385,7 +392,7 @@ function cardString(template, components) {
385 if (!hasHeaderRow) {
392 if (!hasHeaderRow) {
386 anchors += headerLeftAnchor;
393 anchors += headerLeftAnchor;
387 anchors += headerVerticalAnchors;
394 anchors += headerVerticalAnchors;
388− if (!headerLeftAnchorHasMagin) {
395+ if (!headerLeftAnchorHasMargin) {
389 anchors += 'leftMargin: units.gu(1);\n'
396 anchors += 'leftMargin: units.gu(1);\n'
390 }
397 }
391 } else {
398 } else {
@@ -437,6 +444,9 @@ function cardString(template, components) {
437 titleAnchors = "right: parent.right;";
444 titleAnchors = "right: parent.right;";
438 titleAnchors += headerLeftAnchor;
445 titleAnchors += headerLeftAnchor;
439 titleAnchors += headerVerticalAnchors;
446 titleAnchors += headerVerticalAnchors;
447+ if (!headerLeftAnchorHasMargin) {
448+ titleAnchors += 'leftMargin: units.gu(1);\n'
449+ }
440 }
450 }
441 subtitleAnchors = 'left: titleLabel.left; \n\
451 subtitleAnchors = 'left: titleLabel.left; \n\
442 leftMargin: titleLabel.leftMargin; \n\
452 leftMargin: titleLabel.leftMargin; \n\
plugins/Dash/Dash.qmltypesnew file+95
@@ -0,0 +1,95 @@
1+import QtQuick.tooling 1.1
2+
3+// This file describes the plugin-supplied types contained in the library.
4+// It is used for QML tooling purposes only.
5+//
6+// This file was auto-generated by:
7+// 'qmlplugindump -notrelocatable Dash 0.1 plugins'
8+
9+Module {
10+ Component {
11+ name: "AbstractDashView"
12+ defaultProperty: "data"
13+ prototype: "QQuickItem"
14+ Property { name: "model"; type: "QAbstractItemModel"; isPointer: true }
15+ Property { name: "delegate"; type: "QQmlComponent"; isPointer: true }
16+ Property { name: "columnSpacing"; type: "double" }
17+ Property { name: "rowSpacing"; type: "double" }
18+ Property { name: "displayMarginBeginning"; type: "double" }
19+ Property { name: "displayMarginEnd"; type: "double" }
20+ }
21+ Component {
22+ name: "HorizontalJournal"
23+ defaultProperty: "data"
24+ prototype: "AbstractDashView"
25+ exports: ["Dash/HorizontalJournal 0.1"]
26+ exportMetaObjectRevisions: [0]
27+ Property { name: "rowHeight"; type: "double" }
28+ }
29+ Component {
30+ name: "ListViewWithPageHeader"
31+ defaultProperty: "flickableData"
32+ prototype: "QQuickFlickable"
33+ exports: ["Dash/ListViewWithPageHeader 0.1"]
34+ exportMetaObjectRevisions: [0]
35+ Property { name: "model"; type: "QAbstractItemModel"; isPointer: true }
36+ Property { name: "delegate"; type: "QQmlComponent"; isPointer: true }
37+ Property { name: "pageHeader"; type: "QQuickItem"; isPointer: true }
38+ Property { name: "sectionDelegate"; type: "QQmlComponent"; isPointer: true }
39+ Property { name: "sectionProperty"; type: "string" }
40+ Property { name: "forceNoClip"; type: "bool" }
41+ Property { name: "stickyHeaderHeight"; type: "int"; isReadonly: true }
42+ Signal { name: "headerChanged" }
43+ Method { name: "positionAtBeginning" }
44+ Method { name: "showHeader" }
45+ Method {
46+ name: "item"
47+ type: "QQuickItem*"
48+ Parameter { name: "modelIndex"; type: "int" }
49+ }
50+ Method {
51+ name: "maximizeVisibleArea"
52+ type: "bool"
53+ Parameter { name: "modelIndex"; type: "int" }
54+ }
55+ Method {
56+ name: "maximizeVisibleArea"
57+ type: "bool"
58+ Parameter { name: "modelIndex"; type: "int" }
59+ Parameter { name: "itemHeight"; type: "int" }
60+ }
61+ }
62+ Component {
63+ name: "OrganicGrid"
64+ defaultProperty: "data"
65+ prototype: "AbstractDashView"
66+ exports: ["Dash/OrganicGrid 0.1"]
67+ exportMetaObjectRevisions: [0]
68+ Property { name: "smallDelegateSize"; type: "QSizeF" }
69+ Property { name: "bigDelegateSize"; type: "QSizeF" }
70+ }
71+ Component {
72+ name: "VerticalJournal"
73+ defaultProperty: "data"
74+ prototype: "AbstractDashView"
75+ exports: ["Dash/VerticalJournal 0.1"]
76+ exportMetaObjectRevisions: [0]
77+ Property { name: "columnWidth"; type: "double" }
78+ }
79+ Component {
80+ prototype: "QObject"
81+ name: "CardCreatorCache"
82+ exports: ["CardCreatorCache -1.-1"]
83+ exportMetaObjectRevisions: [-1]
84+ isComposite: true
85+ isCreatable: false
86+ isSingleton: true
87+ Property { name: "cache"; type: "QVariant" }
88+ Method {
89+ name: "getCardComponent"
90+ type: "QVariant"
91+ Parameter { name: "template"; type: "QVariant" }
92+ Parameter { name: "components"; type: "QVariant" }
93+ }
94+ }
95+}
plugins/HudClient/HudClient.qmltypesnew file+91
@@ -0,0 +1,91 @@
1+import QtQuick.tooling 1.1
2+
3+// This file describes the plugin-supplied types contained in the library.
4+// It is used for QML tooling purposes only.
5+//
6+// This file was auto-generated by:
7+// 'qmlplugindump -notrelocatable HudClient 0.1 plugins'
8+
9+Module {
10+ Component {
11+ name: "DeeListModel"
12+ prototype: "QAbstractListModel"
13+ Property { name: "name"; type: "string" }
14+ Property { name: "synchronized"; type: "bool"; isReadonly: true }
15+ Property { name: "count"; type: "int"; isReadonly: true }
16+ Signal {
17+ name: "nameChanged"
18+ Parameter { type: "string" }
19+ }
20+ Signal {
21+ name: "synchronizedChanged"
22+ Parameter { type: "bool" }
23+ }
24+ Signal {
25+ name: "roleNamesChanged"
26+ Parameter { type: "QHash<int,QByteArray>" }
27+ }
28+ Method {
29+ name: "get"
30+ type: "QVariantMap"
31+ Parameter { name: "row"; type: "int" }
32+ }
33+ Method { name: "count"; type: "int" }
34+ }
35+ Component {
36+ name: "HudClient"
37+ prototype: "QObject"
38+ exports: ["HudClient/HudClient 0.1"]
39+ exportMetaObjectRevisions: [0]
40+ Property { name: "results"; type: "DeeListModel"; isReadonly: true; isPointer: true }
41+ Property { name: "toolBarModel"; type: "QAbstractItemModel"; isReadonly: true; isPointer: true }
42+ Signal { name: "voiceQueryLoading" }
43+ Signal { name: "voiceQueryListening" }
44+ Signal { name: "voiceQueryHeardSomething" }
45+ Signal { name: "voiceQueryFailed" }
46+ Signal {
47+ name: "voiceQueryFinished"
48+ Parameter { name: "query"; type: "string" }
49+ }
50+ Signal { name: "commandExecuted" }
51+ Signal {
52+ name: "showParametrizedAction"
53+ Parameter { name: "action"; type: "string" }
54+ Parameter { name: "items"; type: "QVariant" }
55+ }
56+ Method {
57+ name: "executeCommand"
58+ Parameter { name: "index"; type: "int" }
59+ }
60+ Method {
61+ name: "setQuery"
62+ Parameter { name: "new_query"; type: "string" }
63+ }
64+ Method { name: "startVoiceQuery" }
65+ Method {
66+ name: "executeParametrizedAction"
67+ Parameter { name: "values"; type: "QVariant" }
68+ }
69+ Method {
70+ name: "updateParametrizedAction"
71+ Parameter { name: "values"; type: "QVariant" }
72+ }
73+ Method { name: "cancelParametrizedAction" }
74+ Method {
75+ name: "executeToolBarAction"
76+ Parameter { name: "action"; type: "HudClientQueryToolbarItems" }
77+ }
78+ }
79+ Component {
80+ name: "VolumePeakDetector"
81+ prototype: "QObject"
82+ exports: ["HudClient/VolumePeakDetector 0.1"]
83+ exportMetaObjectRevisions: [0]
84+ Property { name: "enabled"; type: "bool" }
85+ Property { name: "desiredInterval"; type: "int" }
86+ Signal {
87+ name: "newPeak"
88+ Parameter { name: "volume"; type: "float" }
89+ }
90+ }
91+}
plugins/LightDM/LightDM.qmltypesnew file+241
@@ -0,0 +1,241 @@
1+import QtQuick.tooling 1.1
2+
3+// This file describes the plugin-supplied types contained in the library.
4+// It is used for QML tooling purposes only.
5+//
6+// This file was auto-generated by:
7+// 'qmlplugindump -notrelocatable LightDM 0.1 plugins'
8+
9+Module {
10+ Component {
11+ name: "Greeter"
12+ prototype: "QObject"
13+ exports: ["LightDM/Greeter 0.1"]
14+ isCreatable: false
15+ isSingleton: true
16+ exportMetaObjectRevisions: [0]
17+ Property { name: "authenticated"; type: "bool"; isReadonly: true }
18+ Property { name: "authenticationUser"; type: "string"; isReadonly: true }
19+ Property { name: "promptless"; type: "bool"; isReadonly: true }
20+ Signal {
21+ name: "showMessage"
22+ Parameter { name: "text"; type: "string" }
23+ Parameter { name: "isError"; type: "bool" }
24+ }
25+ Signal {
26+ name: "showPrompt"
27+ Parameter { name: "text"; type: "string" }
28+ Parameter { name: "isSecret"; type: "bool" }
29+ }
30+ Signal { name: "authenticationComplete" }
31+ Signal {
32+ name: "authenticationUserChanged"
33+ Parameter { name: "user"; type: "string" }
34+ }
35+ Signal {
36+ name: "requestAuthenticationUser"
37+ Parameter { name: "user"; type: "string" }
38+ }
39+ Method {
40+ name: "authenticate"
41+ Parameter { name: "username"; type: "string" }
42+ }
43+ Method { name: "authenticate" }
44+ Method {
45+ name: "respond"
46+ Parameter { name: "response"; type: "string" }
47+ }
48+ Method {
49+ name: "startSessionSync"
50+ type: "bool"
51+ Parameter { name: "session"; type: "string" }
52+ }
53+ Method { name: "startSessionSync"; type: "bool" }
54+ }
55+ Component {
56+ name: "QAbstractProxyModel"
57+ prototype: "QAbstractItemModel"
58+ Property { name: "sourceModel"; type: "QAbstractItemModel"; isPointer: true }
59+ }
60+ Component {
61+ name: "QLightDM::UsersModel"
62+ prototype: "QAbstractListModel"
63+ exports: ["LightDM/UserRoles 0.1"]
64+ isCreatable: false
65+ exportMetaObjectRevisions: [0]
66+ Enum {
67+ name: "UserModelRoles"
68+ values: {
69+ "NameRole": 256,
70+ "RealNameRole": 257,
71+ "LoggedInRole": 258,
72+ "BackgroundRole": 259,
73+ "SessionRole": 260,
74+ "HasMessagesRole": 261,
75+ "ImagePathRole": 262,
76+ "BackgroundPathRole": 263
77+ }
78+ }
79+ }
80+ Component {
81+ name: "QSortFilterProxyModel"
82+ prototype: "QAbstractProxyModel"
83+ Property { name: "filterRegExp"; type: "QRegExp" }
84+ Property { name: "filterKeyColumn"; type: "int" }
85+ Property { name: "dynamicSortFilter"; type: "bool" }
86+ Property { name: "filterCaseSensitivity"; type: "Qt::CaseSensitivity" }
87+ Property { name: "sortCaseSensitivity"; type: "Qt::CaseSensitivity" }
88+ Property { name: "isSortLocaleAware"; type: "bool" }
89+ Property { name: "sortRole"; type: "int" }
90+ Property { name: "filterRole"; type: "int" }
91+ Method {
92+ name: "setFilterRegExp"
93+ Parameter { name: "pattern"; type: "string" }
94+ }
95+ Method {
96+ name: "setFilterWildcard"
97+ Parameter { name: "pattern"; type: "string" }
98+ }
99+ Method {
100+ name: "setFilterFixedString"
101+ Parameter { name: "pattern"; type: "string" }
102+ }
103+ Method { name: "clear" }
104+ Method { name: "invalidate" }
105+ }
106+ Component {
107+ name: "QSortFilterProxyModelQML"
108+ prototype: "QSortFilterProxyModel"
109+ Property { name: "model"; type: "QAbstractItemModel"; isPointer: true }
110+ Property { name: "totalCount"; type: "int"; isReadonly: true }
111+ Property { name: "count"; type: "int"; isReadonly: true }
112+ Property { name: "invertMatch"; type: "bool" }
113+ Signal {
114+ name: "invertMatchChanged"
115+ Parameter { type: "bool" }
116+ }
117+ Method {
118+ name: "get"
119+ type: "QVariantMap"
120+ Parameter { name: "row"; type: "int" }
121+ }
122+ Method {
123+ name: "data"
124+ type: "QVariant"
125+ Parameter { name: "row"; type: "int" }
126+ Parameter { name: "role"; type: "int" }
127+ }
128+ Method { name: "count"; type: "int" }
129+ Method {
130+ name: "findFirst"
131+ type: "int"
132+ Parameter { name: "role"; type: "int" }
133+ Parameter { name: "value"; type: "QVariant" }
134+ }
135+ Method {
136+ name: "mapRowToSource"
137+ type: "int"
138+ Parameter { name: "row"; type: "int" }
139+ }
140+ Method {
141+ name: "mapFromSource"
142+ type: "int"
143+ Parameter { name: "row"; type: "int" }
144+ }
145+ Method {
146+ name: "mapToSource"
147+ type: "int"
148+ Parameter { name: "row"; type: "int" }
149+ }
150+ }
151+ Component {
152+ name: "UserMetricsOutput::ColorTheme"
153+ prototype: "QObject"
154+ Property { name: "start"; type: "QColor"; isReadonly: true }
155+ Property { name: "main"; type: "QColor"; isReadonly: true }
156+ Property { name: "end"; type: "QColor"; isReadonly: true }
157+ Signal {
158+ name: "startChanged"
159+ Parameter { name: "color"; type: "QColor" }
160+ }
161+ Signal {
162+ name: "mainChanged"
163+ Parameter { name: "color"; type: "QColor" }
164+ }
165+ Signal {
166+ name: "endChanged"
167+ Parameter { name: "color"; type: "QColor" }
168+ }
169+ }
170+ Component {
171+ name: "UserMetricsOutput::UserMetrics"
172+ prototype: "QObject"
173+ exports: ["LightDM/Infographic 0.1"]
174+ isCreatable: false
175+ isSingleton: true
176+ exportMetaObjectRevisions: [0]
177+ Property { name: "label"; type: "string"; isReadonly: true }
178+ Property { name: "username"; type: "string" }
179+ Property {
180+ name: "firstColor"
181+ type: "UserMetricsOutput::ColorTheme"
182+ isReadonly: true
183+ isPointer: true
184+ }
185+ Property {
186+ name: "secondColor"
187+ type: "UserMetricsOutput::ColorTheme"
188+ isReadonly: true
189+ isPointer: true
190+ }
191+ Property { name: "firstMonth"; type: "QAbstractItemModel"; isReadonly: true; isPointer: true }
192+ Property { name: "secondMonth"; type: "QAbstractItemModel"; isReadonly: true; isPointer: true }
193+ Property { name: "currentDay"; type: "int"; isReadonly: true }
194+ Signal {
195+ name: "labelChanged"
196+ Parameter { name: "label"; type: "string" }
197+ }
198+ Signal {
199+ name: "usernameChanged"
200+ Parameter { name: "username"; type: "string" }
201+ }
202+ Signal {
203+ name: "firstColorChanged"
204+ Parameter { name: "color"; type: "ColorTheme"; isPointer: true }
205+ }
206+ Signal {
207+ name: "firstMonthChanged"
208+ Parameter { name: "firstMonth"; type: "QAbstractItemModel"; isPointer: true }
209+ }
210+ Signal {
211+ name: "currentDayChanged"
212+ Parameter { name: "currentDay"; type: "int" }
213+ }
214+ Signal {
215+ name: "secondColorChanged"
216+ Parameter { name: "color"; type: "ColorTheme"; isPointer: true }
217+ }
218+ Signal {
219+ name: "secondMonthChanged"
220+ Parameter { name: "secondMonth"; type: "QAbstractItemModel"; isPointer: true }
221+ }
222+ Signal { name: "nextDataSource" }
223+ Signal { name: "readyForDataChange" }
224+ Signal { name: "dataAboutToAppear" }
225+ Signal { name: "dataAppeared" }
226+ Signal { name: "dataAboutToChange" }
227+ Signal { name: "dataChanged" }
228+ Signal { name: "dataAboutToDisappear" }
229+ Signal { name: "dataDisappeared" }
230+ Method { name: "nextDataSourceSlot" }
231+ Method { name: "readyForDataChangeSlot" }
232+ }
233+ Component {
234+ name: "UsersModel"
235+ prototype: "QSortFilterProxyModelQML"
236+ exports: ["LightDM/Users 0.1"]
237+ isCreatable: false
238+ isSingleton: true
239+ exportMetaObjectRevisions: [0]
240+ }
241+}
plugins/Lights/CMakeLists.txtnew file+18
@@ -0,0 +1,18 @@
1+include(FindPkgConfig)
2+
3+pkg_check_modules(ANDROID_HEADERS REQUIRED android-headers)
4+pkg_check_modules(ANDROID_HARDWARE REQUIRED libhardware)
5+
6+include_directories(
7+ ${ANDROID_HEADERS_INCLUDE_DIRS}
8+)
9+
10+add_library(Lights-qml MODULE
11+ plugin.cpp
12+ Lights.cpp
13+ )
14+
15+qt5_use_modules(Lights-qml Qml Gui)
16+target_link_libraries(Lights-qml ${ANDROID_HARDWARE_LIBRARIES})
17+
18+add_unity8_plugin(Lights 0.1 Lights TARGETS Lights-qml)
plugins/Lights/Lights.cppnew file+182
@@ -0,0 +1,182 @@
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+ * Author: Renato Araujo Oliveira Filho <renato.filho@canonical.com>
17+ */
18+
19+#include "Lights.h"
20+#include <QtCore/QDebug>
21+
22+extern "C" {
23+#include <hardware/hardware.h>
24+#include <hardware/lights.h>
25+#include <string.h>
26+}
27+
28+Lights::Lights(QObject* parent)
29+ : QObject(parent),
30+ m_lightDevice(0),
31+ m_color("blue"),
32+ m_state(Lights::Off),
33+ m_onMs(1000),
34+ m_offMs(3000)
35+{
36+}
37+
38+Lights::~Lights()
39+{
40+ if (m_lightDevice) {
41+ hw_device_t* device = (hw_device_t*) m_lightDevice;
42+ device->close(device);
43+ }
44+}
45+
46+void Lights::setState(Lights::State newState)
47+{
48+ if (m_state != newState) {
49+ if (newState == Lights::On) {
50+ turnOn();
51+ } else {
52+ turnOff();
53+ }
54+ }
55+}
56+
57+Lights::State Lights::state() const
58+{
59+ return m_state;
60+}
61+
62+void Lights::setColor(const QColor &color)
63+{
64+ if (m_color != color) {
65+ m_color = color;
66+ Q_EMIT colorChanged(m_color);
67+ // FIXME: update the collor if the light is already on
68+ }
69+}
70+
71+QColor Lights::color() const
72+{
73+ return m_color;
74+}
75+
76+int Lights::onMillisec() const
77+{
78+ return m_onMs;
79+}
80+
81+void Lights::setOnMillisec(int onMs)
82+{
83+ if (m_onMs != onMs) {
84+ m_onMs = onMs;
85+ Q_EMIT onMillisecChanged(m_onMs);
86+ // FIXME: update the property if the light is already on
87+ }
88+}
89+
90+int Lights::offMillisec() const
91+{
92+ return m_offMs;
93+}
94+
95+void Lights::setOffMillisec(int offMs)
96+{
97+ if (m_offMs != offMs) {
98+ m_offMs = offMs;
99+ Q_EMIT offMillisecChanged(m_offMs);
100+ // FIXME: update the property if the light is already on
101+ }
102+}
103+
104+bool Lights::init()
105+{
106+ if (m_lightDevice) {
107+ return true;
108+ }
109+
110+ int err;
111+ hw_module_t* module;
112+
113+ err = hw_get_module(LIGHTS_HARDWARE_MODULE_ID, (hw_module_t const**)&module);
114+ if (err == 0) {
115+ hw_device_t* device;
116+ err = module->methods->open(module, LIGHT_ID_NOTIFICATIONS, &device);
117+ if (err == 0) {
118+ m_lightDevice = (light_device_t*)device;
119+ return true;
120+ } else {
121+ qWarning() << "Failed to access notification lights";
122+ }
123+ } else {
124+ qWarning() << "Failed to initialize lights hardware.";
125+ }
126+ return false;
127+}
128+
129+void Lights::turnOn()
130+{
131+ if (!init()) {
132+ qWarning() << "No lights device";
133+ return;
134+ }
135+
136+ if (m_state == Lights::On) {
137+ return;
138+ }
139+
140+ // pulse
141+ light_state_t state;
142+ memset(&state, 0, sizeof(light_state_t));
143+ state.color = m_color.rgba();
144+ state.flashMode = LIGHT_FLASH_TIMED;
145+ state.flashOnMS = m_onMs;
146+ state.flashOffMS = m_offMs;
147+ state.brightnessMode = BRIGHTNESS_MODE_USER;
148+
149+ if (m_lightDevice->set_light(m_lightDevice, &state) != 0) {
150+ qWarning() << "Failed to turn the light off";
151+ } else {
152+ m_state = Lights::On;
153+ Q_EMIT stateChanged(m_state);
154+ }
155+}
156+
157+void Lights::turnOff()
158+{
159+ if (!init()) {
160+ qWarning() << "No lights device";
161+ return;
162+ }
163+
164+ if (m_state == Lights::Off) {
165+ return;
166+ }
167+
168+ light_state_t state;
169+ memset(&state, 0, sizeof(light_state_t));
170+ state.color = 0x00000000;
171+ state.flashMode = LIGHT_FLASH_NONE;
172+ state.flashOnMS = 0;
173+ state.flashOffMS = 0;
174+ state.brightnessMode = 0;
175+
176+ if (m_lightDevice->set_light(m_lightDevice, &state) != 0) {
177+ qWarning() << "Failed to turn the light off";
178+ } else {
179+ m_state = Lights::Off;
180+ Q_EMIT stateChanged(m_state);
181+ }
182+}
plugins/Lights/Lights.hnew file+75
@@ -0,0 +1,75 @@
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+ * Author: Renato Araujo Oliveira Filho <renato.filho@canonical.com>
17+ */
18+
19+#ifndef UNITY_LIGHTS_H
20+#define UNITY_LIGHTS_H
21+
22+#include <QtCore/QObject>
23+#include <QtGui/QColor>
24+
25+struct light_device_t;
26+
27+class Lights: public QObject
28+{
29+ Q_OBJECT
30+ Q_ENUMS(State)
31+ Q_PROPERTY(State state READ state WRITE setState NOTIFY stateChanged)
32+ Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
33+ Q_PROPERTY(int onMillisec READ onMillisec WRITE setOnMillisec NOTIFY onMillisecChanged)
34+ Q_PROPERTY(int offMillisec READ offMillisec WRITE setOffMillisec NOTIFY offMillisecChanged)
35+
36+public:
37+ enum State {
38+ Off,
39+ On,
40+ };
41+
42+ explicit Lights(QObject *parent = 0);
43+ ~Lights();
44+
45+ void setState(State newState);
46+ State state() const;
47+
48+ void setColor(const QColor &color);
49+ QColor color() const;
50+
51+ int onMillisec() const;
52+ void setOnMillisec(int onMs);
53+
54+ int offMillisec() const;
55+ void setOffMillisec(int offMs);
56+
57+Q_SIGNALS:
58+ void stateChanged(State newState);
59+ void colorChanged(const QColor &color);
60+ void onMillisecChanged(int onMs);
61+ void offMillisecChanged(int offMs);
62+
63+private:
64+ light_device_t* m_lightDevice;
65+ QColor m_color;
66+ State m_state;
67+ int m_onMs;
68+ int m_offMs;
69+
70+ bool init();
71+ void turnOff();
72+ void turnOn();
73+};
74+
75+#endif
plugins/Lights/plugin.cppnew file+35
@@ -0,0 +1,35 @@
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+ * Author: Renato Araujo Oliveira Filho <renato.filho@canonical.com>
17+ */
18+
19+#include "plugin.h"
20+#include "Lights.h"
21+
22+#include <QtQml/qqml.h>
23+
24+static QObject *lights_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
25+{
26+ Q_UNUSED(engine)
27+ Q_UNUSED(scriptEngine)
28+ return new Lights();
29+}
30+
31+void LightsPlugin::registerTypes(const char *uri)
32+{
33+ Q_ASSERT(uri == QLatin1String("Lights"));
34+ qmlRegisterSingletonType<Lights>(uri, 0, 1, "Lights", lights_provider);
35+}
plugins/Lights/plugin.hnew file+34
@@ -0,0 +1,34 @@
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+ * Author: Renato Araujo Oliveira Filho <renato.filho@canonical.com>
17+ */
18+
19+#ifndef LIGHTS_PLUGIN_H
20+#define LIGHTS_PLUGIN_H
21+
22+#include <QtQml/QQmlEngine>
23+#include <QtQml/QQmlExtensionPlugin>
24+
25+class LightsPlugin : public QQmlExtensionPlugin
26+{
27+ Q_OBJECT
28+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
29+
30+public:
31+ void registerTypes(const char *uri);
32+};
33+
34+#endif
plugins/Lights/qmldirnew file+3
@@ -0,0 +1,3 @@
1+module Lights
2+plugin Lights-qml
3+typeinfo Lights.qmltypes
plugins/Powerd/Powerd.cpp+16−16
@@ -19,35 +19,35 @@
19#include "Powerd.h"
19#include "Powerd.h"
20#include <QDBusPendingCall>
20#include <QDBusPendingCall>
21
21
22−void autoBrightnessChanged(GSettings *settings, const gchar *key, QDBusInterface *powerd)
22+void autoBrightnessChanged(GSettings *settings, const gchar *key, QDBusInterface *unityScreen)
23{
23{
24 bool value = g_settings_get_boolean(settings, key);
24 bool value = g_settings_get_boolean(settings, key);
25− powerd->asyncCall("userAutobrightnessEnable", QVariant(value));
25+ unityScreen->asyncCall("userAutobrightnessEnable", QVariant(value));
26}
26}
27
27
28Powerd::Powerd(QObject* parent)
28Powerd::Powerd(QObject* parent)
29 : QObject(parent),
29 : QObject(parent),
30− powerd(NULL)
30+ unityScreen(NULL)
31{
31{
32− powerd = new QDBusInterface("com.canonical.powerd",
32+ unityScreen = new QDBusInterface("com.canonical.Unity.Screen",
33− "/com/canonical/powerd",
33+ "/com/canonical/Unity/Screen",
34− "com.canonical.powerd",
34+ "com.canonical.Unity.Screen",
35− QDBusConnection::SM_BUSNAME(), this);
35+ QDBusConnection::SM_BUSNAME(), this);
36
36
37− powerd->connection().connect("com.canonical.powerd",
37+ unityScreen->connection().connect("com.canonical.Unity.Screen",
38− "/com/canonical/powerd",
38+ "/com/canonical/Unity/Screen",
39− "com.canonical.powerd",
39+ "com.canonical.Unity.Screen",
40− "DisplayPowerStateChange",
40+ "DisplayPowerStateChange",
41− this,
41+ this,
42− SIGNAL(displayPowerStateChange(int, unsigned int)));
42+ SIGNAL(displayPowerStateChange(int, int)));
43
43
44 systemSettings = g_settings_new("com.ubuntu.touch.system");
44 systemSettings = g_settings_new("com.ubuntu.touch.system");
45− g_signal_connect(systemSettings, "changed::auto-brightness", G_CALLBACK(autoBrightnessChanged), powerd);
45+ g_signal_connect(systemSettings, "changed::auto-brightness", G_CALLBACK(autoBrightnessChanged), unityScreen);
46− autoBrightnessChanged(systemSettings, "auto-brightness", powerd);
46+ autoBrightnessChanged(systemSettings, "auto-brightness", unityScreen);
47}
47}
48
48
49Powerd::~Powerd()
49Powerd::~Powerd()
50{
50{
51− g_signal_handlers_disconnect_by_data(systemSettings, powerd);
51+ g_signal_handlers_disconnect_by_data(systemSettings, unityScreen);
52 g_object_unref(systemSettings);
52 g_object_unref(systemSettings);
53}
53}
plugins/Powerd/Powerd.h+8−8
@@ -28,15 +28,15 @@ class Powerd: public QObject
28{
28{
29 Q_OBJECT
29 Q_OBJECT
30 Q_ENUMS(Status)
30 Q_ENUMS(Status)
31− Q_FLAGS(DisplayFlag DisplayFlags)
31+ Q_ENUMS(DisplayStateChangeReason)
32
32
33public:
33public:
34− enum DisplayFlag {
34+ enum DisplayStateChangeReason {
35− UseProximity = 1, // Use proximity sensor to override screen state
35+ Unknown = 0,
36− DisableAutoBrightness = 2, // Force autobrightness to be disabled
36+ Inactivity = 1, // Display changed state due to inactivity
37− Bright = 4, // Request the screen to stay bright
37+ PowerKey = 2, // Display changed state due to user pressing power key
38+ Proximity = 3, // Display changed state due to proximity events
38 };
39 };
39− Q_DECLARE_FLAGS(DisplayFlags, DisplayFlag)
40
40
41 enum Status {
41 enum Status {
42 Off,
42 Off,
@@ -47,10 +47,10 @@ public:
47 ~Powerd();
47 ~Powerd();
48
48
49Q_SIGNALS:
49Q_SIGNALS:
50− void displayPowerStateChange(int status, unsigned int flags);
50+ void displayPowerStateChange(int status, int reason);
51
51
52private:
52private:
53− QDBusInterface *powerd;
53+ QDBusInterface *unityScreen;
54 GSettings *systemSettings;
54 GSettings *systemSettings;
55};
55};
56
56
plugins/Powerd/Powerd.qmltypesnew file+46
@@ -0,0 +1,46 @@
1+import QtQuick.tooling 1.1
2+
3+// This file describes the plugin-supplied types contained in the library.
4+// It is used for QML tooling purposes only.
5+//
6+// This file was auto-generated by:
7+// 'qmlplugindump -notrelocatable Powerd 0.1 plugins'
8+
9+Module {
10+ Component {
11+ name: "Powerd"
12+ prototype: "QObject"
13+ exports: ["Powerd/Powerd 0.1"]
14+ isCreatable: false
15+ isSingleton: true
16+ exportMetaObjectRevisions: [0]
17+ Enum {
18+ name: "DisplayFlag"
19+ values: {
20+ "UseProximity": 1,
21+ "DisableAutoBrightness": 2,
22+ "Bright": 4
23+ }
24+ }
25+ Enum {
26+ name: "DisplayFlags"
27+ values: {
28+ "UseProximity": 1,
29+ "DisableAutoBrightness": 2,
30+ "Bright": 4
31+ }
32+ }
33+ Enum {
34+ name: "Status"
35+ values: {
36+ "Off": 0,
37+ "On": 1
38+ }
39+ }
40+ Signal {
41+ name: "displayPowerStateChange"
42+ Parameter { name: "status"; type: "int" }
43+ Parameter { name: "flags"; type: "uint" }
44+ }
45+ }
46+}
plugins/SessionBroadcast/SessionBroadcast.qmltypesnew file+19
@@ -0,0 +1,19 @@
1+import QtQuick.tooling 1.1
2+
3+// This file describes the plugin-supplied types contained in the library.
4+// It is used for QML tooling purposes only.
5+//
6+// This file was auto-generated by:
7+// 'qmlplugindump -notrelocatable SessionBroadcast 0.1 plugins'
8+
9+Module {
10+ Component {
11+ name: "SessionBroadcast"
12+ prototype: "QObject"
13+ exports: ["SessionBroadcast/SessionBroadcast 0.1"]
14+ isCreatable: false
15+ isSingleton: true
16+ exportMetaObjectRevisions: [0]
17+ Signal { name: "showHome" }
18+ }
19+}
plugins/Ubuntu/CMakeLists.txt+1
@@ -1,2 +1,3 @@
1add_subdirectory(Gestures)
1add_subdirectory(Gestures)
2add_subdirectory(DownloadDaemonListener)
2add_subdirectory(DownloadDaemonListener)
3+add_subdirectory(Payments)
plugins/Ubuntu/DownloadDaemonListener/DownloadDaemonListener.qmltypesnew file+60
@@ -0,0 +1,60 @@
1+import QtQuick.tooling 1.1
2+
3+// This file describes the plugin-supplied types contained in the library.
4+// It is used for QML tooling purposes only.
5+//
6+// This file was auto-generated by:
7+// 'qmlplugindump -notrelocatable Ubuntu.DownloadDaemonListener 0.1 plugins'
8+
9+Module {
10+ Component {
11+ name: "DownloadTracker"
12+ prototype: "QObject"
13+ exports: ["Ubuntu.DownloadDaemonListener/DownloadTracker 0.1"]
14+ exportMetaObjectRevisions: [0]
15+ Property { name: "service"; type: "string" }
16+ Property { name: "dbusPath"; type: "string" }
17+ Property { name: "serviceReady"; type: "bool"; isReadonly: true }
18+ Signal {
19+ name: "serviceChanged"
20+ Parameter { name: "service"; type: "string" }
21+ }
22+ Signal {
23+ name: "dbusPathChanged"
24+ Parameter { name: "dbusPath"; type: "string" }
25+ }
26+ Signal {
27+ name: "serviceReadyChanged"
28+ Parameter { name: "serviceReady"; type: "bool" }
29+ }
30+ Signal {
31+ name: "canceled"
32+ Parameter { name: "success"; type: "bool" }
33+ }
34+ Signal {
35+ name: "error"
36+ Parameter { name: "error"; type: "string" }
37+ }
38+ Signal {
39+ name: "finished"
40+ Parameter { name: "path"; type: "string" }
41+ }
42+ Signal {
43+ name: "paused"
44+ Parameter { name: "success"; type: "bool" }
45+ }
46+ Signal {
47+ name: "progress"
48+ Parameter { name: "received"; type: "qulonglong" }
49+ Parameter { name: "total"; type: "qulonglong" }
50+ }
51+ Signal {
52+ name: "resumed"
53+ Parameter { name: "success"; type: "bool" }
54+ }
55+ Signal {
56+ name: "started"
57+ Parameter { name: "success"; type: "bool" }
58+ }
59+ }
60+}
plugins/Ubuntu/Gestures/Gestures.qmltypesnew file+153
@@ -0,0 +1,153 @@
1+import QtQuick.tooling 1.1
2+
3+// This file describes the plugin-supplied types contained in the library.
4+// It is used for QML tooling purposes only.
5+//
6+// This file was auto-generated by:
7+// 'qmlplugindump -notrelocatable Ubuntu.Gestures 0.1 plugins'
8+
9+Module {
10+ Component {
11+ name: "AxisVelocityCalculator"
12+ prototype: "QObject"
13+ exports: ["Ubuntu.Gestures/AxisVelocityCalculator 0.1"]
14+ exportMetaObjectRevisions: [0]
15+ Property { name: "trackedPosition"; type: "double" }
16+ Signal {
17+ name: "trackedPositionChanged"
18+ Parameter { name: "value"; type: "double" }
19+ }
20+ Method { name: "calculate"; type: "double" }
21+ Method { name: "reset" }
22+ }
23+ Component {
24+ name: "Direction"
25+ prototype: "QObject"
26+ exports: ["Ubuntu.Gestures/Direction 0.1"]
27+ isCreatable: false
28+ isSingleton: true
29+ exportMetaObjectRevisions: [0]
30+ Enum {
31+ name: "Type"
32+ values: {
33+ "Rightwards": 0,
34+ "Leftwards": 1,
35+ "Downwards": 2,
36+ "Upwards": 3
37+ }
38+ }
39+ Method {
40+ name: "isHorizontal"
41+ type: "bool"
42+ Parameter { name: "type"; type: "Direction::Type" }
43+ }
44+ Method {
45+ name: "isVertical"
46+ type: "bool"
47+ Parameter { name: "type"; type: "Direction::Type" }
48+ }
49+ Method {
50+ name: "isPositive"
51+ type: "bool"
52+ Parameter { name: "type"; type: "Direction::Type" }
53+ }
54+ }
55+ Component {
56+ name: "DirectionalDragArea"
57+ defaultProperty: "data"
58+ prototype: "QQuickItem"
59+ exports: ["Ubuntu.Gestures/DirectionalDragArea 0.1"]
60+ exportMetaObjectRevisions: [0]
61+ Enum {
62+ name: "Status"
63+ values: {
64+ "WaitingForTouch": 0,
65+ "Undecided": 1,
66+ "Recognized": 2
67+ }
68+ }
69+ Property { name: "direction"; type: "Direction::Type" }
70+ Property { name: "distance"; type: "double"; isReadonly: true }
71+ Property { name: "sceneDistance"; type: "double"; isReadonly: true }
72+ Property { name: "touchX"; type: "double"; isReadonly: true }
73+ Property { name: "touchY"; type: "double"; isReadonly: true }
74+ Property { name: "touchSceneX"; type: "double"; isReadonly: true }
75+ Property { name: "touchSceneY"; type: "double"; isReadonly: true }
76+ Property { name: "status"; type: "Status"; isReadonly: true }
77+ Property { name: "dragging"; type: "bool"; isReadonly: true }
78+ Property { name: "maxDeviation"; type: "double" }
79+ Property { name: "wideningAngle"; type: "double" }
80+ Property { name: "distanceThreshold"; type: "double" }
81+ Property { name: "minSpeed"; type: "double" }
82+ Property { name: "maxSilenceTime"; type: "int" }
83+ Property { name: "compositionTime"; type: "int" }
84+ Signal {
85+ name: "directionChanged"
86+ Parameter { name: "direction"; type: "Direction::Type" }
87+ }
88+ Signal {
89+ name: "statusChanged"
90+ Parameter { name: "value"; type: "Status" }
91+ }
92+ Signal {
93+ name: "draggingChanged"
94+ Parameter { name: "value"; type: "bool" }
95+ }
96+ Signal {
97+ name: "distanceChanged"
98+ Parameter { name: "value"; type: "double" }
99+ }
100+ Signal {
101+ name: "sceneDistanceChanged"
102+ Parameter { name: "value"; type: "double" }
103+ }
104+ Signal {
105+ name: "maxDeviationChanged"
106+ Parameter { name: "value"; type: "double" }
107+ }
108+ Signal {
109+ name: "wideningAngleChanged"
110+ Parameter { name: "value"; type: "double" }
111+ }
112+ Signal {
113+ name: "distanceThresholdChanged"
114+ Parameter { name: "value"; type: "double" }
115+ }
116+ Signal {
117+ name: "minSpeedChanged"
118+ Parameter { name: "value"; type: "double" }
119+ }
120+ Signal {
121+ name: "maxSilenceTimeChanged"
122+ Parameter { name: "value"; type: "int" }
123+ }
124+ Signal {
125+ name: "compositionTimeChanged"
126+ Parameter { name: "value"; type: "int" }
127+ }
128+ Signal {
129+ name: "touchXChanged"
130+ Parameter { name: "value"; type: "double" }
131+ }
132+ Signal {
133+ name: "touchYChanged"
134+ Parameter { name: "value"; type: "double" }
135+ }
136+ Signal {
137+ name: "touchSceneXChanged"
138+ Parameter { name: "value"; type: "double" }
139+ }
140+ Signal {
141+ name: "touchSceneYChanged"
142+ Parameter { name: "value"; type: "double" }
143+ }
144+ }
145+ Component {
146+ name: "PressedOutsideNotifier"
147+ defaultProperty: "data"
148+ prototype: "QQuickItem"
149+ exports: ["Ubuntu.Gestures/PressedOutsideNotifier 0.1"]
150+ exportMetaObjectRevisions: [0]
151+ Signal { name: "pressedOutside" }
152+ }
153+}
plugins/Ubuntu/Payments/CMakeLists.txtnew file+20
@@ -0,0 +1,20 @@
1+include_directories(
2+ ${CMAKE_CURRENT_SOURCE_DIR}
3+ ${CMAKE_CURRENT_BINARY_DIR}
4+)
5+
6+set(PAYMENTS_SOURCES
7+ plugin.cpp
8+ Payments.cpp
9+)
10+
11+add_library(Payments MODULE ${PAYMENTS_SOURCES})
12+
13+qt5_use_modules(Payments Qml Quick DBus Core)
14+
15+add_unity8_plugin(Ubuntu.Payments 0.1 Ubuntu/Payments TARGETS Payments)
16+
17+pkg_check_modules(LIBPAY REQUIRED pay-1)
18+add_definitions(${LIBPAY_CFLAGS} ${LIBPAY_CFLAGS_OTHER})
19+
20+target_link_libraries(Payments ${LIBPAY_LDFLAGS})
plugins/Ubuntu/Payments/Payments.cppnew file+118
@@ -0,0 +1,118 @@
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 "Payments.h"
18+
19+#include <QLocale>
20+
21+#include <libpay/pay-package.h>
22+
23+
24+// The observer callback for the package we are watching.
25+static void observer(PayPackage* /* package */, const char* itemid, PayPackageItemStatus status, void* user_data) {
26+ // This function is called in libpay's thread, so be careful what you call
27+ // Emitting signals should be fine as long as they use Queued or Auto
28+ // connections (the default)
29+ // http://qt-project.org/doc/qt-5/threads-qobject.html#signals-and-slots-across-threads
30+
31+ Payments *self = static_cast<Payments*>(user_data);
32+
33+ // If the item ID is different, ignore it.
34+ if (itemid != self->storeItemId()) {
35+ return;
36+ }
37+
38+ // FIXME: No error reporting from libpay, but we need to show some
39+ // types of errors to the user. https://launchpad.net/bugs/1333403
40+ switch (status) {
41+ case PAY_PACKAGE_ITEM_STATUS_PURCHASED:
42+ Q_EMIT self->purchaseCompleted();
43+ break;
44+ default:
45+ break;
46+ }
47+}
48+
49+Payments::Payments(QObject *parent)
50+ : QObject(parent)
51+{
52+ m_package = pay_package_new("click-scope");
53+ pay_package_item_observer_install(m_package, observer, this);
54+}
55+
56+Payments::~Payments()
57+{
58+ pay_package_item_observer_uninstall(m_package, observer, this);
59+ pay_package_delete(m_package);
60+}
61+
62+QString Payments::currency() const
63+{
64+ return m_currency;
65+}
66+
67+double Payments::price() const
68+{
69+ return m_price;
70+}
71+
72+QString Payments::storeItemId() const
73+{
74+ return m_store_item_id;
75+}
76+
77+QString Payments::formattedPrice() const
78+{
79+ QLocale locale;
80+ return locale.toCurrencyString(m_price, m_currency);
81+}
82+
83+void Payments::setCurrency(const QString &currency)
84+{
85+ if(m_currency != currency) {
86+ m_currency = currency;
87+ Q_EMIT currencyChanged(currency);
88+ Q_EMIT formattedPriceChanged(formattedPrice());
89+ }
90+}
91+
92+void Payments::setPrice(const double price)
93+{
94+ if(m_price != price) {
95+ m_price = price;
96+ Q_EMIT priceChanged(price);
97+ Q_EMIT formattedPriceChanged(formattedPrice());
98+ }
99+}
100+
101+void Payments::setStoreItemId(const QString &store_item_id)
102+{
103+ if (m_store_item_id != store_item_id) {
104+ m_store_item_id = store_item_id;
105+ Q_EMIT storeItemIdChanged(m_store_item_id);
106+ }
107+
108+ if (m_store_item_id.isEmpty()) {
109+ return;
110+ }
111+
112+ pay_package_item_start_verification(m_package, m_store_item_id.toLocal8Bit().data());
113+}
114+
115+void Payments::start()
116+{
117+ pay_package_item_start_purchase(m_package, m_store_item_id.toLocal8Bit().data());
118+}
plugins/Ubuntu/Payments/Payments.hnew file+65
@@ -0,0 +1,65 @@
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+#ifndef PAYMENTS_H
18+#define PAYMENTS_H
19+
20+#include <QObject>
21+
22+#include <libpay/pay-package.h>
23+
24+
25+class Payments : public QObject
26+{
27+ Q_OBJECT
28+ Q_DISABLE_COPY(Payments)
29+ Q_PROPERTY(QString currency READ currency WRITE setCurrency NOTIFY currencyChanged)
30+ Q_PROPERTY(double price READ price WRITE setPrice NOTIFY priceChanged)
31+ Q_PROPERTY(QString storeItemId READ storeItemId WRITE setStoreItemId NOTIFY storeItemIdChanged)
32+ Q_PROPERTY(QString formattedPrice READ formattedPrice NOTIFY formattedPriceChanged)
33+
34+public:
35+ explicit Payments(QObject *parent = 0);
36+ virtual ~Payments();
37+
38+ QString currency() const;
39+ double price() const;
40+ QString storeItemId() const;
41+ QString formattedPrice() const;
42+
43+ void setCurrency(const QString& currency);
44+ void setPrice(const double price);
45+ void setStoreItemId(const QString& store_item_id);
46+ Q_INVOKABLE void start();
47+
48+Q_SIGNALS:
49+ void currencyChanged(const QString& currency);
50+ void priceChanged(const double price);
51+ void storeItemIdChanged(const QString &store_item_id);
52+ void formattedPriceChanged(const QString &formatted_price);
53+
54+ void purchaseError(const QString &error);
55+ void purchaseCompleted();
56+
57+private:
58+ QString m_currency;
59+ double m_price;
60+ QString m_store_item_id;
61+
62+ PayPackage *m_package;
63+};
64+
65+#endif // PAYMENTS_H
plugins/Ubuntu/Payments/Payments.qmltypesnew file+42
@@ -0,0 +1,42 @@
1+import QtQuick.tooling 1.1
2+
3+// This file describes the plugin-supplied types contained in the library.
4+// It is used for QML tooling purposes only.
5+//
6+// This file was auto-generated by:
7+// 'qmlplugindump -notrelocatable Ubuntu.Payments 0.1 plugins'
8+
9+Module {
10+ Component {
11+ name: "Payments"
12+ prototype: "QObject"
13+ exports: ["Ubuntu.Payments/Payments 0.1"]
14+ exportMetaObjectRevisions: [0]
15+ Property { name: "currency"; type: "string" }
16+ Property { name: "price"; type: "double" }
17+ Property { name: "storeItemId"; type: "string" }
18+ Property { name: "formattedPrice"; type: "string"; isReadonly: true }
19+ Signal {
20+ name: "currencyChanged"
21+ Parameter { name: "currency"; type: "string" }
22+ }
23+ Signal {
24+ name: "priceChanged"
25+ Parameter { name: "price"; type: "double" }
26+ }
27+ Signal {
28+ name: "storeItemIdChanged"
29+ Parameter { name: "store_item_id"; type: "string" }
30+ }
31+ Signal {
32+ name: "formattedPriceChanged"
33+ Parameter { name: "formatted_price"; type: "string" }
34+ }
35+ Signal {
36+ name: "purchaseError"
37+ Parameter { name: "error"; type: "string" }
38+ }
39+ Signal { name: "purchaseCompleted" }
40+ Method { name: "start" }
41+ }
42+}
plugins/Ubuntu/Payments/plugin.cppnew file+28
@@ -0,0 +1,28 @@
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 "plugin.h"
18+#include "Payments.h"
19+
20+#include <QtQml>
21+
22+
23+void BackendPlugin::registerTypes(const char *uri)
24+{
25+ Q_ASSERT(uri == QLatin1String("Ubuntu.Payments"));
26+
27+ qmlRegisterType<Payments>(uri, 0, 1, "Payments");
28+}
plugins/Ubuntu/Payments/plugin.hnew file+31
@@ -0,0 +1,31 @@
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+#ifndef PAYMENTS_PLUGIN_H
18+#define PAYMENTS_PLUGIN_H
19+
20+#include <QQmlExtensionPlugin>
21+
22+class BackendPlugin : public QQmlExtensionPlugin
23+{
24+ Q_OBJECT
25+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
26+
27+public:
28+ void registerTypes(const char *uri);
29+};
30+
31+#endif // PAYMENTS_PLUGIN_H
plugins/Ubuntu/Payments/qmldirnew file+3
@@ -0,0 +1,3 @@
1+module Ubuntu.Payments
2+plugin Payments
3+typeinfo Payments.qmltypes
plugins/Unity/CMakeLists.txt+1
@@ -1,2 +1,3 @@
1add_subdirectory(Indicators)
1add_subdirectory(Indicators)
2add_subdirectory(Launcher)
2add_subdirectory(Launcher)
3+add_subdirectory(Session)
plugins/Unity/Indicators/Indicators.qmltypesnew file+278
@@ -0,0 +1,278 @@
1+import QtQuick.tooling 1.1
2+
3+// This file describes the plugin-supplied types contained in the library.
4+// It is used for QML tooling purposes only.
5+//
6+// This file was auto-generated by:
7+// 'qmlplugindump -notrelocatable Unity.Indicators 0.1 plugins'
8+
9+Module {
10+ Component {
11+ name: "ActionState"
12+ prototype: "QObject"
13+ exports: ["Unity.Indicators/ActionState 0.1"]
14+ isCreatable: false
15+ exportMetaObjectRevisions: [0]
16+ Enum {
17+ name: "ActionStates"
18+ values: {
19+ "Label": 0,
20+ "IconSource": 1,
21+ "AccessableName": 2,
22+ "Visible": 3
23+ }
24+ }
25+ }
26+ Component { name: "ActionStateParser"; prototype: "QObject" }
27+ Component {
28+ name: "FlatMenuProxyModelRole"
29+ prototype: "QObject"
30+ exports: ["Unity.Indicators/FlatMenuProxyModelRole 0.1"]
31+ isCreatable: false
32+ exportMetaObjectRevisions: [0]
33+ Enum {
34+ name: "Roles"
35+ values: {
36+ "Action": 1,
37+ "Label": 2,
38+ "Extra": 3,
39+ "Depth": 4,
40+ "hasSection": 5,
41+ "hasSubMenu": 6
42+ }
43+ }
44+ }
45+ Component {
46+ name: "IndicatorsManager"
47+ prototype: "QObject"
48+ exports: ["Unity.Indicators/IndicatorsManager 0.1"]
49+ exportMetaObjectRevisions: [0]
50+ Property { name: "loaded"; type: "bool"; isReadonly: true }
51+ Signal {
52+ name: "loadedChanged"
53+ Parameter { type: "bool" }
54+ }
55+ Signal {
56+ name: "indicatorLoaded"
57+ Parameter { name: "indicator_name"; type: "string" }
58+ }
59+ Signal {
60+ name: "indicatorAboutToBeUnloaded"
61+ Parameter { name: "indicator_name"; type: "string" }
62+ }
63+ Method {
64+ name: "load"
65+ Parameter { name: "profile"; type: "string" }
66+ }
67+ Method { name: "unload" }
68+ }
69+ Component {
70+ name: "IndicatorsModel"
71+ prototype: "QAbstractListModel"
72+ exports: ["Unity.Indicators/IndicatorsModel 0.1"]
73+ exportMetaObjectRevisions: [0]
74+ Property { name: "count"; type: "int"; isReadonly: true }
75+ Signal {
76+ name: "indicatorDataChanged"
77+ Parameter { name: "data"; type: "QVariant" }
78+ }
79+ Method {
80+ name: "load"
81+ Parameter { name: "profile"; type: "string" }
82+ }
83+ Method { name: "unload" }
84+ Method {
85+ name: "data"
86+ type: "QVariant"
87+ Parameter { name: "row"; type: "int" }
88+ Parameter { name: "role"; type: "int" }
89+ }
90+ }
91+ Component {
92+ name: "IndicatorsModelRole"
93+ prototype: "QObject"
94+ exports: ["Unity.Indicators/IndicatorsModelRole 0.1"]
95+ isCreatable: false
96+ exportMetaObjectRevisions: [0]
97+ Enum {
98+ name: "Roles"
99+ values: {
100+ "Identifier": 0,
101+ "Position": 1,
102+ "WidgetSource": 2,
103+ "PageSource": 3,
104+ "IndicatorProperties": 4,
105+ "IsVisible": 5
106+ }
107+ }
108+ }
109+ Component {
110+ name: "MenuContentActivator"
111+ prototype: "QObject"
112+ exports: ["Unity.Indicators/MenuContentActivator 0.1"]
113+ exportMetaObjectRevisions: [0]
114+ Property { name: "baseIndex"; type: "int" }
115+ Property { name: "running"; type: "bool" }
116+ Property { name: "count"; type: "int" }
117+ Property { name: "content"; type: "MenuContentState"; isList: true; isReadonly: true }
118+ Signal {
119+ name: "baseIndexChanged"
120+ Parameter { name: "baseIndex"; type: "int" }
121+ }
122+ Signal {
123+ name: "deltaChanged"
124+ Parameter { name: "delta"; type: "int" }
125+ }
126+ Signal {
127+ name: "runningChanged"
128+ Parameter { name: "running"; type: "bool" }
129+ }
130+ Signal {
131+ name: "countChanged"
132+ Parameter { name: "count"; type: "int" }
133+ }
134+ Method { name: "restart" }
135+ Method { name: "stop" }
136+ Method { name: "clear" }
137+ Method {
138+ name: "isMenuContentActive"
139+ type: "bool"
140+ Parameter { name: "index"; type: "int" }
141+ }
142+ }
143+ Component {
144+ name: "MenuContentState"
145+ prototype: "QObject"
146+ exports: ["Unity.Indicators/MenuContentState 0.1"]
147+ isCreatable: false
148+ exportMetaObjectRevisions: [0]
149+ Property { name: "active"; type: "bool"; isReadonly: true }
150+ }
151+ Component {
152+ name: "ModelPrinter"
153+ prototype: "QObject"
154+ exports: ["Unity.Indicators/ModelPrinter 0.1"]
155+ exportMetaObjectRevisions: [0]
156+ Property { name: "model"; type: "UnityMenuModel"; isPointer: true }
157+ Property { name: "text"; type: "string"; isReadonly: true }
158+ Method { name: "text"; type: "string" }
159+ }
160+ Component {
161+ name: "NetworkActionState"
162+ prototype: "QObject"
163+ exports: ["Unity.Indicators/NetworkActionState 0.1"]
164+ isCreatable: false
165+ exportMetaObjectRevisions: [0]
166+ Enum {
167+ name: "NetworkActionStates"
168+ values: {
169+ "Connection": 1,
170+ "SignalStrength": 2
171+ }
172+ }
173+ }
174+ Component {
175+ name: "NetworkConnection"
176+ prototype: "QObject"
177+ exports: ["Unity.Indicators/NetworkConnection 0.1"]
178+ isCreatable: false
179+ exportMetaObjectRevisions: [0]
180+ Enum {
181+ name: "NetworkConnectionStates"
182+ values: {
183+ "Initial": 0,
184+ "Activating": 1,
185+ "Activated": 2,
186+ "Deactivating": 3
187+ }
188+ }
189+ }
190+ Component {
191+ name: "QAbstractProxyModel"
192+ prototype: "QAbstractItemModel"
193+ Property { name: "sourceModel"; type: "QAbstractItemModel"; isPointer: true }
194+ }
195+ Component { name: "QIdentityProxyModel"; prototype: "QAbstractProxyModel" }
196+ Component {
197+ name: "RootActionState"
198+ prototype: "ActionStateParser"
199+ exports: ["Unity.Indicators/RootActionState 0.1"]
200+ exportMetaObjectRevisions: [0]
201+ Property { name: "menu"; type: "UnityMenuModel"; isPointer: true }
202+ Property { name: "valid"; type: "bool"; isReadonly: true }
203+ Property { name: "title"; type: "string"; isReadonly: true }
204+ Property { name: "leftLabel"; type: "string"; isReadonly: true }
205+ Property { name: "rightLabel"; type: "string"; isReadonly: true }
206+ Property { name: "icons"; type: "QStringList"; isReadonly: true }
207+ Property { name: "accessibleName"; type: "string"; isReadonly: true }
208+ Property { name: "visible"; type: "bool"; isReadonly: true }
209+ Signal { name: "updated" }
210+ Signal { name: "indexChanged" }
211+ }
212+ Component {
213+ name: "UnityMenuModelCache"
214+ prototype: "QObject"
215+ exports: ["Unity.Indicators/UnityMenuModelCache 0.1"]
216+ isCreatable: false
217+ isSingleton: true
218+ exportMetaObjectRevisions: [0]
219+ Method {
220+ name: "model"
221+ type: "UnityMenuModel*"
222+ Parameter { name: "path"; type: "string" }
223+ }
224+ Method {
225+ name: "registerModel"
226+ Parameter { name: "path"; type: "string" }
227+ Parameter { name: "menuModel"; type: "UnityMenuModel"; isPointer: true }
228+ }
229+ }
230+ Component {
231+ name: "UnityMenuModelStack"
232+ prototype: "QObject"
233+ exports: ["Unity.Indicators/UnityMenuModelStack 0.1"]
234+ exportMetaObjectRevisions: [0]
235+ Property { name: "head"; type: "UnityMenuModel"; isPointer: true }
236+ Property { name: "tail"; type: "UnityMenuModel"; isReadonly: true; isPointer: true }
237+ Property { name: "count"; type: "int"; isReadonly: true }
238+ Signal {
239+ name: "headChanged"
240+ Parameter { name: "head"; type: "UnityMenuModel"; isPointer: true }
241+ }
242+ Signal {
243+ name: "tailChanged"
244+ Parameter { name: "tail"; type: "UnityMenuModel"; isPointer: true }
245+ }
246+ Signal {
247+ name: "countChanged"
248+ Parameter { name: "count"; type: "int" }
249+ }
250+ Method {
251+ name: "push"
252+ Parameter { name: "model"; type: "UnityMenuModel"; isPointer: true }
253+ Parameter { name: "menuIndex"; type: "int" }
254+ }
255+ Method { name: "pop"; type: "UnityMenuModel*" }
256+ }
257+ Component {
258+ name: "VisibleIndicatorsModel"
259+ prototype: "QIdentityProxyModel"
260+ exports: ["Unity.Indicators/VisibleIndicatorsModel 0.1"]
261+ exportMetaObjectRevisions: [0]
262+ Property { name: "model"; type: "QAbstractItemModel"; isPointer: true }
263+ Property { name: "visible"; type: "QVariantMap" }
264+ Signal { name: "totalCountChanged" }
265+ Method {
266+ name: "onBeginRowInserted"
267+ Parameter { type: "QModelIndex" }
268+ Parameter { name: "start"; type: "int" }
269+ Parameter { name: "end"; type: "int" }
270+ }
271+ Method {
272+ name: "onRowInserted"
273+ Parameter { type: "QModelIndex" }
274+ Parameter { name: "start"; type: "int" }
275+ Parameter { name: "end"; type: "int" }
276+ }
277+ }
278+}
plugins/Unity/Launcher/Launcher.qmltypesnew file+174
@@ -0,0 +1,174 @@
1+import QtQuick.tooling 1.1
2+
3+// This file describes the plugin-supplied types contained in the library.
4+// It is used for QML tooling purposes only.
5+//
6+// This file was auto-generated by:
7+// 'qmlplugindump -notrelocatable Unity.Launcher 0.1 plugins'
8+
9+Module {
10+ Component {
11+ name: "LauncherItem"
12+ prototype: "unity::shell::launcher::LauncherItemInterface"
13+ exports: ["Unity.Launcher/LauncherItem 0.1"]
14+ isCreatable: false
15+ exportMetaObjectRevisions: [0]
16+ Signal {
17+ name: "favoriteChanged"
18+ Parameter { name: "favorite"; type: "bool" }
19+ }
20+ Signal {
21+ name: "runningChanged"
22+ Parameter { name: "running"; type: "bool" }
23+ }
24+ }
25+ Component {
26+ name: "LauncherModel"
27+ prototype: "unity::shell::launcher::LauncherModelInterface"
28+ exports: ["Unity.Launcher/LauncherModel 0.1"]
29+ isCreatable: false
30+ isSingleton: true
31+ exportMetaObjectRevisions: [0]
32+ Method {
33+ name: "get"
34+ type: "unity::shell::launcher::LauncherItemInterface*"
35+ Parameter { name: "index"; type: "int" }
36+ }
37+ Method {
38+ name: "move"
39+ Parameter { name: "oldIndex"; type: "int" }
40+ Parameter { name: "newIndex"; type: "int" }
41+ }
42+ Method {
43+ name: "pin"
44+ Parameter { name: "appId"; type: "string" }
45+ Parameter { name: "index"; type: "int" }
46+ }
47+ Method {
48+ name: "pin"
49+ Parameter { name: "appId"; type: "string" }
50+ }
51+ Method {
52+ name: "requestRemove"
53+ Parameter { name: "appId"; type: "string" }
54+ }
55+ Method {
56+ name: "quickListActionInvoked"
57+ Parameter { name: "appId"; type: "string" }
58+ Parameter { name: "actionIndex"; type: "int" }
59+ }
60+ Method {
61+ name: "setUser"
62+ Parameter { name: "username"; type: "string" }
63+ }
64+ Method {
65+ name: "getUrlForAppId"
66+ type: "string"
67+ Parameter { name: "appId"; type: "string" }
68+ }
69+ }
70+ Component {
71+ name: "QuickListModel"
72+ prototype: "unity::shell::launcher::QuickListModelInterface"
73+ exports: ["Unity.Launcher/QuickListModel 0.1"]
74+ isCreatable: false
75+ exportMetaObjectRevisions: [0]
76+ }
77+ Component {
78+ name: "unity::shell::launcher::LauncherItemInterface"
79+ prototype: "QObject"
80+ exports: ["Unity.Launcher/LauncherItemInterface 0.1"]
81+ isCreatable: false
82+ exportMetaObjectRevisions: [0]
83+ Property { name: "appId"; type: "string"; isReadonly: true }
84+ Property { name: "name"; type: "string"; isReadonly: true }
85+ Property { name: "icon"; type: "string"; isReadonly: true }
86+ Property { name: "pinned"; type: "bool"; isReadonly: true }
87+ Property { name: "running"; type: "bool"; isReadonly: true }
88+ Property { name: "recent"; type: "bool"; isReadonly: true }
89+ Property { name: "progress"; type: "int"; isReadonly: true }
90+ Property { name: "count"; type: "int"; isReadonly: true }
91+ Property { name: "focused"; type: "bool"; isReadonly: true }
92+ Property {
93+ name: "quickList"
94+ type: "unity::shell::launcher::QuickListModelInterface"
95+ isReadonly: true
96+ isPointer: true
97+ }
98+ Signal {
99+ name: "pinnedChanged"
100+ Parameter { name: "pinned"; type: "bool" }
101+ }
102+ Signal {
103+ name: "runningChanged"
104+ Parameter { name: "running"; type: "bool" }
105+ }
106+ Signal {
107+ name: "recentChanged"
108+ Parameter { name: "running"; type: "bool" }
109+ }
110+ Signal {
111+ name: "progressChanged"
112+ Parameter { name: "progress"; type: "int" }
113+ }
114+ Signal {
115+ name: "countChanged"
116+ Parameter { name: "count"; type: "int" }
117+ }
118+ Signal {
119+ name: "focusedChanged"
120+ Parameter { name: "focused"; type: "bool" }
121+ }
122+ }
123+ Component {
124+ name: "unity::shell::launcher::LauncherModelInterface"
125+ prototype: "QAbstractListModel"
126+ exports: ["Unity.Launcher/LauncherModelInterface 0.1"]
127+ isCreatable: false
128+ exportMetaObjectRevisions: [0]
129+ Property {
130+ name: "applicationManager"
131+ type: "unity::shell::application::ApplicationManagerInterface"
132+ isPointer: true
133+ }
134+ Method {
135+ name: "move"
136+ Parameter { name: "oldIndex"; type: "int" }
137+ Parameter { name: "newIndex"; type: "int" }
138+ }
139+ Method {
140+ name: "get"
141+ type: "unity::shell::launcher::LauncherItemInterface*"
142+ Parameter { name: "index"; type: "int" }
143+ }
144+ Method {
145+ name: "pin"
146+ Parameter { name: "appId"; type: "string" }
147+ Parameter { name: "index"; type: "int" }
148+ }
149+ Method {
150+ name: "pin"
151+ Parameter { name: "appId"; type: "string" }
152+ }
153+ Method {
154+ name: "requestRemove"
155+ Parameter { name: "appId"; type: "string" }
156+ }
157+ Method {
158+ name: "quickListActionInvoked"
159+ Parameter { name: "appId"; type: "string" }
160+ Parameter { name: "actionIndex"; type: "int" }
161+ }
162+ Method {
163+ name: "setUser"
164+ Parameter { name: "username"; type: "string" }
165+ }
166+ }
167+ Component {
168+ name: "unity::shell::launcher::QuickListModelInterface"
169+ prototype: "QAbstractListModel"
170+ exports: ["Unity.Launcher/QuickListInterface 0.1"]
171+ isCreatable: false
172+ exportMetaObjectRevisions: [0]
173+ }
174+}
plugins/Unity/Launcher/launcheritem.cpp+2−2
@@ -40,7 +40,7 @@ LauncherItem::LauncherItem(const QString &appId, const QString &name, const QStr
40 m_quickList->appendAction(nameAction);
40 m_quickList->appendAction(nameAction);
41 QuickListEntry pinningAction;
41 QuickListEntry pinningAction;
42 pinningAction.setActionId("pin_item");
42 pinningAction.setActionId("pin_item");
43− pinningAction.setText(gettext("Lock to Launcher"));
43+ pinningAction.setText(gettext("Pin shortcut"));
44 m_quickList->appendAction(pinningAction);
44 m_quickList->appendAction(pinningAction);
45}
45}
46
46
@@ -70,7 +70,7 @@ void LauncherItem::setPinned(bool pinned)
70 m_pinned = pinned;
70 m_pinned = pinned;
71 QuickListEntry entry;
71 QuickListEntry entry;
72 entry.setActionId("pin_item");
72 entry.setActionId("pin_item");
73− entry.setText(pinned ? gettext("Unlock from Launcher") : gettext("Lock to Launcher"));
73+ entry.setText(pinned ? gettext("Unpin shortcut") : gettext("Pin shortcut"));
74 m_quickList->updateAction(entry);
74 m_quickList->updateAction(entry);
75 Q_EMIT pinnedChanged(pinned);
75 Q_EMIT pinnedChanged(pinned);
76 }
76 }
plugins/Unity/Session/CMakeLists.txtnew file+17
@@ -0,0 +1,17 @@
1+include_directories(
2+ ${CMAKE_CURRENT_SOURCE_DIR}
3+)
4+
5+set(QMLSESSIONPLUGIN_SRC
6+ plugin.cpp
7+ dbusunitysessionservice.cpp
8+ )
9+
10+add_library(UnitySession-qml MODULE
11+ ${QMLSESSIONPLUGIN_SRC}
12+ )
13+
14+qt5_use_modules(UnitySession-qml DBus Qml)
15+
16+# export the qmldir and qmltypes files
17+add_unity8_plugin(Unity.Session 0.1 Unity/Session TARGETS UnitySession-qml)
plugins/Unity/Session/Session.qmltypesnew file+25
@@ -0,0 +1,25 @@
1+import QtQuick.tooling 1.1
2+
3+// This file describes the plugin-supplied types contained in the library.
4+// It is used for QML tooling purposes only.
5+//
6+// This file was auto-generated by:
7+// 'qmlplugindump -notrelocatable Unity.Session 0.1 plugins'
8+
9+Module {
10+ Component {
11+ name: "DBusUnitySessionService"
12+ prototype: "QObject"
13+ exports: ["Unity.Session/DBusUnitySessionService 0.1"]
14+ isCreatable: false
15+ isSingleton: true
16+ exportMetaObjectRevisions: [0]
17+ Signal {
18+ name: "logoutRequested"
19+ Parameter { name: "have_inhibitors"; type: "bool" }
20+ }
21+ Signal { name: "logoutReady" }
22+ Method { name: "Logout" }
23+ Method { name: "RequestLogout" }
24+ }
25+}
plugins/Unity/Session/dbusunitysessionservice.cppnew file+46
@@ -0,0 +1,46 @@
1+/*
2+ * Copyright (C) 2014 Canonical, Ltd.
3+ *
4+ * This program is free software: you can redistribute it and/or modify it under
5+ * the terms of the GNU Lesser General Public License version 3, as published by
6+ * the Free Software Foundation.
7+ *
8+ * This program is distributed in the hope that it will be useful, but WITHOUT
9+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
10+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11+ * Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+// local
18+#include "dbusunitysessionservice.h"
19+
20+// Qt
21+#include <QDBusConnection>
22+
23+DBusUnitySessionService::DBusUnitySessionService() : QObject()
24+{
25+ QDBusConnection connection = QDBusConnection::sessionBus();
26+
27+ connection.registerService("com.canonical.Unity");
28+ connection.registerObject("/com/canonical/Unity/Session", this,
29+ QDBusConnection::ExportScriptableSignals
30+ | QDBusConnection::ExportScriptableSlots
31+ | QDBusConnection::ExportScriptableInvokables);
32+}
33+
34+DBusUnitySessionService::~DBusUnitySessionService()
35+{
36+}
37+
38+void DBusUnitySessionService::Logout()
39+{
40+ Q_EMIT logoutReady();
41+}
42+
43+void DBusUnitySessionService::RequestLogout()
44+{
45+ Q_EMIT logoutRequested(false);
46+}
plugins/Unity/Session/dbusunitysessionservice.hnew file+82
@@ -0,0 +1,82 @@
1+/*
2+ * Copyright (C) 2014 Canonical, Ltd.
3+ *
4+ * This program is free software: you can redistribute it and/or modify it under
5+ * the terms of the GNU Lesser General Public License version 3, as published by
6+ * the Free Software Foundation.
7+ *
8+ * This program is distributed in the hope that it will be useful, but WITHOUT
9+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
10+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11+ * Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#ifndef DBUSUNITYSESSIONSERVICE_H
18+#define DBUSUNITYSESSIONSERVICE_H
19+
20+#include <QObject>
21+
22+/**
23+ * DBusUnitySessionService provides com.canonical.Unity.Session dbus
24+ * interface.
25+ *
26+ * com.canonical.Unity.Session interface provides public methods
27+ * and signals to handle Logout/Reboot/Shutdown.
28+ */
29+class DBusUnitySessionService : public QObject
30+{
31+ Q_OBJECT
32+ Q_CLASSINFO("D-Bus Interface", "com.canonical.Unity.Session")
33+
34+public:
35+ DBusUnitySessionService();
36+ ~DBusUnitySessionService();
37+
38+Q_SIGNALS:
39+ /**
40+ * logoutRequested signal
41+ *
42+ * This signal is emitted when some applications request the system to
43+ * logout.
44+ * @param have_inhibitors if there are any special running applications
45+ * which inhibit the logout.
46+ */
47+ void logoutRequested(bool have_inhibitors);
48+
49+ /**
50+ * logoutReady signal
51+ *
52+ * This signal is emitted when all the apps are closed. And the system
53+ * is safe to logout.
54+ */
55+ void logoutReady();
56+
57+public Q_SLOTS:
58+ /**
59+ * Logout the system.
60+ *
61+ * This method directly logout the system without user's confirmation.
62+ * Ordinary applications should avoid calling this method. Please call
63+ * RequestLogout() to ask the user to decide logout or not.
64+ * This method will stop all the running applications and then signal
65+ * logoutReady when all the apps stopped.
66+ */
67+ Q_SCRIPTABLE void Logout();
68+
69+ /**
70+ * Issue a logout request.
71+ *
72+ * This method emit the logoutRequested signal to the shell with a boolean
73+ * which indicates if there's any inhibitors. The shell should receive
74+ * this signal and display a dialog to ask the user to confirm the logout
75+ * action. If confirmed, shell can call Logout() method to kill the apps
76+ * and then logout
77+ */
78+ Q_SCRIPTABLE void RequestLogout();
79+
80+};
81+
82+#endif // DBUSUNITYSESSIONSERVICE_H
plugins/Unity/Session/plugin.cppnew 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+ * Authors: Ying-Chun Liu (PaulLiu) <paul.liu@canonical.com>
17+ */
18+
19+#include "plugin.h"
20+#include "dbusunitysessionservice.h"
21+
22+#include <QAbstractItemModel>
23+#include <QDBusConnection>
24+#include <QtQml/qqml.h>
25+
26+static QObject *dbusunitysessionservice_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
27+{
28+ Q_UNUSED(engine)
29+ Q_UNUSED(scriptEngine)
30+
31+ return new DBusUnitySessionService();
32+}
33+
34+void SessionPlugin::registerTypes(const char *uri)
35+{
36+ qmlRegisterType<QAbstractItemModel>();
37+
38+ Q_ASSERT(uri == QLatin1String("Unity.Session"));
39+ qmlRegisterSingletonType<DBusUnitySessionService>(uri, 0, 1, "DBusUnitySessionService", dbusunitysessionservice_provider);
40+}
plugins/Unity/Session/plugin.hnew file+34
@@ -0,0 +1,34 @@
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+ * Authors: Ying-Chun Liu (PaulLiu) <paul.liu@canonical.com>
17+ */
18+
19+#ifndef SESSION_PLUGIN_H
20+#define SESSION_PLUGIN_H
21+
22+#include <QtQml/QQmlEngine>
23+#include <QtQml/QQmlExtensionPlugin>
24+
25+class SessionPlugin : public QQmlExtensionPlugin
26+{
27+ Q_OBJECT
28+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
29+
30+public:
31+ void registerTypes(const char *uri);
32+};
33+
34+#endif
plugins/Unity/Session/qmldirnew file+3
@@ -0,0 +1,3 @@
1+module Unity.Session
2+plugin UnitySession-qml
3+typeinfo UnitySession.qmltypes
plugins/Utils/Utils.qmltypesnew file+143
@@ -0,0 +1,143 @@
1+import QtQuick.tooling 1.1
2+
3+// This file describes the plugin-supplied types contained in the library.
4+// It is used for QML tooling purposes only.
5+//
6+// This file was auto-generated by:
7+// 'qmlplugindump -notrelocatable Utils 0.1 plugins'
8+
9+Module {
10+ Component {
11+ name: "EasingCurve"
12+ prototype: "QObject"
13+ exports: ["Utils/EasingCurve 0.1"]
14+ exportMetaObjectRevisions: [0]
15+ Property { name: "type"; type: "QEasingCurve::Type" }
16+ Property { name: "period"; type: "double" }
17+ Property { name: "progress"; type: "double" }
18+ Property { name: "value"; type: "double"; isReadonly: true }
19+ }
20+ Component {
21+ name: "QAbstractProxyModel"
22+ prototype: "QAbstractItemModel"
23+ Property { name: "sourceModel"; type: "QAbstractItemModel"; isPointer: true }
24+ }
25+ Component { name: "QIdentityProxyModel"; prototype: "QAbstractProxyModel" }
26+ Component {
27+ name: "QLimitProxyModelQML"
28+ prototype: "QIdentityProxyModel"
29+ exports: ["Utils/LimitProxyModel 0.1"]
30+ exportMetaObjectRevisions: [0]
31+ Property { name: "model"; type: "QAbstractItemModel"; isPointer: true }
32+ Property { name: "limit"; type: "int" }
33+ Property { name: "count"; type: "int"; isReadonly: true }
34+ Signal { name: "totalCountChanged" }
35+ }
36+ Component {
37+ name: "QSortFilterProxyModel"
38+ prototype: "QAbstractProxyModel"
39+ Property { name: "filterRegExp"; type: "QRegExp" }
40+ Property { name: "filterKeyColumn"; type: "int" }
41+ Property { name: "dynamicSortFilter"; type: "bool" }
42+ Property { name: "filterCaseSensitivity"; type: "Qt::CaseSensitivity" }
43+ Property { name: "sortCaseSensitivity"; type: "Qt::CaseSensitivity" }
44+ Property { name: "isSortLocaleAware"; type: "bool" }
45+ Property { name: "sortRole"; type: "int" }
46+ Property { name: "filterRole"; type: "int" }
47+ Method {
48+ name: "setFilterRegExp"
49+ Parameter { name: "pattern"; type: "string" }
50+ }
51+ Method {
52+ name: "setFilterWildcard"
53+ Parameter { name: "pattern"; type: "string" }
54+ }
55+ Method {
56+ name: "setFilterFixedString"
57+ Parameter { name: "pattern"; type: "string" }
58+ }
59+ Method { name: "clear" }
60+ Method { name: "invalidate" }
61+ }
62+ Component {
63+ name: "QSortFilterProxyModelQML"
64+ prototype: "QSortFilterProxyModel"
65+ exports: ["Utils/SortFilterProxyModel 0.1"]
66+ exportMetaObjectRevisions: [0]
67+ Property { name: "model"; type: "QAbstractItemModel"; isPointer: true }
68+ Property { name: "totalCount"; type: "int"; isReadonly: true }
69+ Property { name: "count"; type: "int"; isReadonly: true }
70+ Property { name: "invertMatch"; type: "bool" }
71+ Signal {
72+ name: "invertMatchChanged"
73+ Parameter { type: "bool" }
74+ }
75+ Method {
76+ name: "get"
77+ type: "QVariantMap"
78+ Parameter { name: "row"; type: "int" }
79+ }
80+ Method {
81+ name: "data"
82+ type: "QVariant"
83+ Parameter { name: "row"; type: "int" }
84+ Parameter { name: "role"; type: "int" }
85+ }
86+ Method { name: "count"; type: "int" }
87+ Method {
88+ name: "findFirst"
89+ type: "int"
90+ Parameter { name: "role"; type: "int" }
91+ Parameter { name: "value"; type: "QVariant" }
92+ }
93+ Method {
94+ name: "mapRowToSource"
95+ type: "int"
96+ Parameter { name: "row"; type: "int" }
97+ }
98+ Method {
99+ name: "mapFromSource"
100+ type: "int"
101+ Parameter { name: "row"; type: "int" }
102+ }
103+ Method {
104+ name: "mapToSource"
105+ type: "int"
106+ Parameter { name: "row"; type: "int" }
107+ }
108+ }
109+ Component {
110+ name: "TimeFormatter"
111+ prototype: "QObject"
112+ exports: ["Utils/GDateTimeFormatter 0.1", "Utils/TimeFormatter 0.1"]
113+ exportMetaObjectRevisions: [0, 0]
114+ Property { name: "format"; type: "string" }
115+ Property { name: "timeString"; type: "string"; isReadonly: true }
116+ Property { name: "time"; type: "qlonglong" }
117+ Signal {
118+ name: "formatChanged"
119+ Parameter { name: "format"; type: "string" }
120+ }
121+ Signal {
122+ name: "timeStringChanged"
123+ Parameter { name: "timeString"; type: "string" }
124+ }
125+ Signal {
126+ name: "timeChanged"
127+ Parameter { name: "time"; type: "qlonglong" }
128+ }
129+ }
130+ Component {
131+ name: "UnityMenuModelPaths"
132+ prototype: "QObject"
133+ exports: ["Utils/UnityMenuModelPaths 0.1"]
134+ exportMetaObjectRevisions: [0]
135+ Property { name: "source"; type: "QVariant" }
136+ Property { name: "busName"; type: "QByteArray"; isReadonly: true }
137+ Property { name: "actions"; type: "QVariantMap"; isReadonly: true }
138+ Property { name: "menuObjectPath"; type: "QByteArray"; isReadonly: true }
139+ Property { name: "busNameHint"; type: "QByteArray" }
140+ Property { name: "actionsHint"; type: "QByteArray" }
141+ Property { name: "menuObjectPathHint"; type: "QByteArray" }
142+ }
143+}
plugins/Utils/easingcurve.cpp+3−1
@@ -20,7 +20,9 @@
20
20
21
21
22EasingCurve::EasingCurve(QObject *parent):
22EasingCurve::EasingCurve(QObject *parent):
23− QObject(parent)
23+ QObject(parent),
24+ m_progress(0),
25+ m_value(0)
24{
26{
25
27
26}
28}
po/ast.po+8−8
@@ -8,14 +8,14 @@ msgstr ""
8"Project-Id-Version: unity8\n"
8"Project-Id-Version: unity8\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2014-06-13 09:55+0200\n"
10"POT-Creation-Date: 2014-06-13 09:55+0200\n"
11−"PO-Revision-Date: 2014-04-04 02:16+0000\n"
11+"PO-Revision-Date: 2014-07-03 17:18+0000\n"
12−"Last-Translator: Xuacu Saturio <xuacusk8@gmail.com>\n"
12+"Last-Translator: albacoru <albacoru@gmail.com>\n"
13"Language-Team: Asturian <ast@li.org>\n"
13"Language-Team: Asturian <ast@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2014-06-17 06:51+0000\n"
17+"X-Launchpad-Export-Date: 2014-07-04 06:31+0000\n"
18−"X-Generator: Launchpad (build 17045)\n"
18+"X-Generator: Launchpad (build 17086)\n"
19
19
20#: plugins/Unity/Launcher/launcheritem.cpp:43
20#: plugins/Unity/Launcher/launcheritem.cpp:43
21#: plugins/Unity/Launcher/launcheritem.cpp:73
21#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -82,7 +82,7 @@ msgstr "Llamada d'emerxencia"
82
82
83#: qml/Components/Lockscreen.qml:231
83#: qml/Components/Lockscreen.qml:231
84msgid "OK"
84msgid "OK"
85−msgstr ""
85+msgstr "Aceutar"
86
86
87#: qml/Components/PageHeader.qml:365
87#: qml/Components/PageHeader.qml:365
88msgid "Recent searches"
88msgid "Recent searches"
@@ -99,11 +99,11 @@ msgstr "Hola"
99
99
100#: qml/Components/PinLockscreen.qml:198
100#: qml/Components/PinLockscreen.qml:198
101msgid "CANCEL"
101msgid "CANCEL"
102−msgstr ""
102+msgstr "ENCABOXAR"
103
103
104#: qml/Components/PinLockscreen.qml:216
104#: qml/Components/PinLockscreen.qml:216
105msgid "DONE"
105msgid "DONE"
106−msgstr ""
106+msgstr "FECHO"
107
107
108#: qml/Components/SeeMore.qml:35
108#: qml/Components/SeeMore.qml:35
109msgid "See more"
109msgid "See more"
@@ -139,7 +139,7 @@ msgstr "Unviar"
139
139
140#: qml/Greeter/Greeter.qml:157
140#: qml/Greeter/Greeter.qml:157
141msgid "Swipe to unlock"
141msgid "Swipe to unlock"
142−msgstr ""
142+msgstr "Esliza pa desbloquiar"
143
143
144#: qml/Hud/HudParametrizedActionsPage.qml:132
144#: qml/Hud/HudParametrizedActionsPage.qml:132
145msgid "Confirm"
145msgid "Confirm"
po/es.po+7−7
@@ -8,14 +8,14 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2014-06-13 09:55+0200\n"
10"POT-Creation-Date: 2014-06-13 09:55+0200\n"
11−"PO-Revision-Date: 2014-06-02 06:28+0000\n"
11+"PO-Revision-Date: 2014-06-26 03:08+0000\n"
12−"Last-Translator: benjisp94 <benjisp94@gmail.com>\n"
12+"Last-Translator: Adolfo Jayme <fitoschido@gmail.com>\n"
13"Language-Team: Spanish <es@li.org>\n"
13"Language-Team: Spanish <es@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2014-06-17 06:51+0000\n"
17+"X-Launchpad-Export-Date: 2014-06-27 07:13+0000\n"
18−"X-Generator: Launchpad (build 17045)\n"
18+"X-Generator: Launchpad (build 17077)\n"
19
19
20#: plugins/Unity/Launcher/launcheritem.cpp:43
20#: plugins/Unity/Launcher/launcheritem.cpp:43
21#: plugins/Unity/Launcher/launcheritem.cpp:73
21#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -83,7 +83,7 @@ msgstr "Llamada de emergencia"
83
83
84#: qml/Components/Lockscreen.qml:231
84#: qml/Components/Lockscreen.qml:231
85msgid "OK"
85msgid "OK"
86−msgstr ""
86+msgstr "Aceptar"
87
87
88#: qml/Components/PageHeader.qml:365
88#: qml/Components/PageHeader.qml:365
89msgid "Recent searches"
89msgid "Recent searches"
@@ -100,11 +100,11 @@ msgstr "Hola"
100
100
101#: qml/Components/PinLockscreen.qml:198
101#: qml/Components/PinLockscreen.qml:198
102msgid "CANCEL"
102msgid "CANCEL"
103−msgstr ""
103+msgstr "CANCELAR"
104
104
105#: qml/Components/PinLockscreen.qml:216
105#: qml/Components/PinLockscreen.qml:216
106msgid "DONE"
106msgid "DONE"
107−msgstr ""
107+msgstr "HECHO"
108
108
109#: qml/Components/SeeMore.qml:35
109#: qml/Components/SeeMore.qml:35
110msgid "See more"
110msgid "See more"
po/sl.po+6−6
@@ -8,14 +8,14 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2014-06-13 09:55+0200\n"
10"POT-Creation-Date: 2014-06-13 09:55+0200\n"
11−"PO-Revision-Date: 2014-05-22 14:07+0000\n"
11+"PO-Revision-Date: 2014-06-23 09:29+0000\n"
12"Last-Translator: Damir Jerovšek <Unknown>\n"
12"Last-Translator: Damir Jerovšek <Unknown>\n"
13"Language-Team: Slovenian <sl@li.org>\n"
13"Language-Team: Slovenian <sl@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2014-06-17 06:51+0000\n"
17+"X-Launchpad-Export-Date: 2014-06-24 06:33+0000\n"
18−"X-Generator: Launchpad (build 17045)\n"
18+"X-Generator: Launchpad (build 17065)\n"
19
19
20#: plugins/Unity/Launcher/launcheritem.cpp:43
20#: plugins/Unity/Launcher/launcheritem.cpp:43
21#: plugins/Unity/Launcher/launcheritem.cpp:73
21#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -82,7 +82,7 @@ msgstr "Klic v sili"
82
82
83#: qml/Components/Lockscreen.qml:231
83#: qml/Components/Lockscreen.qml:231
84msgid "OK"
84msgid "OK"
85−msgstr ""
85+msgstr "V REDU"
86
86
87#: qml/Components/PageHeader.qml:365
87#: qml/Components/PageHeader.qml:365
88msgid "Recent searches"
88msgid "Recent searches"
@@ -99,11 +99,11 @@ msgstr "Pozdravljeni"
99
99
100#: qml/Components/PinLockscreen.qml:198
100#: qml/Components/PinLockscreen.qml:198
101msgid "CANCEL"
101msgid "CANCEL"
102−msgstr ""
102+msgstr "PREKLIČI"
103
103
104#: qml/Components/PinLockscreen.qml:216
104#: qml/Components/PinLockscreen.qml:216
105msgid "DONE"
105msgid "DONE"
106−msgstr ""
106+msgstr "KONČANO"
107
107
108#: qml/Components/SeeMore.qml:35
108#: qml/Components/SeeMore.qml:35
109msgid "See more"
109msgid "See more"
qml/Components/ResponsiveVerticalJournal.qmlnew file+74
@@ -0,0 +1,74 @@
1+/*
2+ * Copyright (C) 2013-2014 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+import "../Components"
20+import Dash 0.1
21+
22+/*!
23+ \brief A responsive wrapper around VerticalJournal.
24+
25+ Based on defined column width, delegates are laid out in columns following
26+ a top-left most position rule.
27+
28+ Example:
29+ +-----+ +-----+ +-----+
30+ | | | 2 | | |
31+ | | | | | |
32+ | 1 | +-----+ | 3 |
33+ | | +-----+ | |
34+ | | | | +-----+
35+ +-----+ | 4 | +-----+
36+ +-----+ | | | 5 |
37+ | 6 | +-----+ | |
38+ | | +-----+
39+ +-----+
40+*/
41+Item {
42+ property real minimumColumnSpacing: units.gu(1)
43+
44+ property alias columnWidth: verticalJournalView.columnWidth
45+ property alias rowSpacing: verticalJournalView.rowSpacing
46+ property alias model: verticalJournalView.model
47+ property alias delegate: verticalJournalView.delegate
48+ property alias displayMarginBeginning: verticalJournalView.displayMarginBeginning
49+ property alias displayMarginEnd: verticalJournalView.displayMarginEnd
50+ implicitHeight: verticalJournalView.implicitHeight
51+
52+ VerticalJournal {
53+ id: verticalJournalView
54+ objectName: "responsiveVerticalJournalView"
55+ anchors {
56+ fill: parent
57+ leftMargin: columnSpacing / 2
58+ rightMargin: columnSpacing / 2
59+ topMargin: rowSpacing / 2
60+ bottomMargin: rowSpacing / 2
61+ }
62+ clip: parent.height != implicitHeight
63+
64+ function px2gu(pixels) {
65+ return Math.floor(pixels / units.gu(1))
66+ }
67+
68+ columnSpacing: {
69+ // parent.width = columns * columnWidth + (columns-1) * spacing + spacing(margins)
70+ var expectedColumns = Math.max(1, Math.floor(parent.width / (columnWidth + minimumColumnSpacing)));
71+ Math.floor((parent.width - expectedColumns * columnWidth) / expectedColumns);
72+ }
73+ }
74+}
qml/Dash/CardCarousel.qml−2
@@ -27,9 +27,7 @@ DashRenderer {
27 property alias selectedItemScaleFactor: carousel.selectedItemScaleFactor
27 property alias selectedItemScaleFactor: carousel.selectedItemScaleFactor
28 property alias tileAspectRatio: carousel.tileAspectRatio
28 property alias tileAspectRatio: carousel.tileAspectRatio
29
29
30− currentItem: carousel.currentItem
31 height: carousel.implicitHeight + units.gu(6)
30 height: carousel.implicitHeight + units.gu(6)
32− verticalSpacing: units.gu(3)
33
31
34 Carousel {
32 Carousel {
35 id: carousel
33 id: carousel
qml/Dash/CardFilterGrid.qml+1−4
@@ -22,11 +22,8 @@ DashRenderer {
22
22
23 expandable: filterGrid.expandable
23 expandable: filterGrid.expandable
24 collapsedHeight: filterGrid.collapsedHeight
24 collapsedHeight: filterGrid.collapsedHeight
25− margins: filterGrid.margins
26 uncollapsedHeight: filterGrid.uncollapsedHeight
25 uncollapsedHeight: filterGrid.uncollapsedHeight
27 originY: filterGrid.originY
26 originY: filterGrid.originY
28− verticalSpacing: units.gu(1)
29− currentItem: filterGrid.currentItem
30 height: filterGrid.height
27 height: filterGrid.height
31 filtered: filterGrid.filtered
28 filtered: filterGrid.filtered
32
29
@@ -40,7 +37,7 @@ DashRenderer {
40 minimumHorizontalSpacing: units.gu(1)
37 minimumHorizontalSpacing: units.gu(1)
41 delegateWidth: cardTool.cardWidth
38 delegateWidth: cardTool.cardWidth
42 delegateHeight: cardTool.cardHeight
39 delegateHeight: cardTool.cardHeight
43− verticalSpacing: genericFilterGrid.verticalSpacing
40+ verticalSpacing: units.gu(1)
44 model: genericFilterGrid.model
41 model: genericFilterGrid.model
45 collapsedRowCount: Math.min(2, cardTool && cardTool.template && cardTool.template["collapsed-rows"] || 2)
42 collapsedRowCount: Math.min(2, cardTool && cardTool.template && cardTool.template["collapsed-rows"] || 2)
46 displayMarginBeginning: genericFilterGrid.displayMarginBeginning
43 displayMarginBeginning: genericFilterGrid.displayMarginBeginning
qml/Dash/CardVerticalJournal.qmlnew file+86
@@ -0,0 +1,86 @@
1+/*
2+ * Copyright (C) 2014 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+import "../Components"
20+
21+DashRenderer {
22+ id: root
23+
24+ readonly property double collapseLimit: units.gu(35)
25+
26+ uncollapsedHeight: cardVerticalJournal.implicitHeight
27+ collapsedHeight: Math.min(collapseLimit, cardVerticalJournal.implicitHeight)
28+ expandable: uncollapsedHeight > collapseLimit
29+
30+ // This minHeight is used as bootstrapper for the height. Vertical Journal
31+ // is special by the fact that it doesn't know how to calculate its implicit height unless we give it
32+ // enough height that it can start creating its children so we make sure it has enough height for that
33+ // in case the model is non empty
34+ readonly property double minHeight: root.model.count > 1 ? cardVerticalJournal.rowSpacing + 1 : 0
35+ height: filtered ? Math.max(collapsedHeight, minHeight) : uncollapsedHeight
36+
37+ Behavior on height {
38+ id: heightBehaviour
39+ enabled: false
40+ animation: UbuntuNumberAnimation {
41+ onRunningChanged: {
42+ if (!running) {
43+ heightBehaviour.enabled = false
44+ }
45+ }
46+ }
47+ }
48+
49+ function setFilter(filter, animate) {
50+ heightBehaviour.enabled = animate;
51+ filtered = filter;
52+ }
53+
54+ ResponsiveVerticalJournal {
55+ id: cardVerticalJournal
56+
57+ model: root.model
58+
59+ anchors.fill: parent
60+ rowSpacing: minimumColumnSpacing
61+ columnWidth: cardTool.cardWidth
62+
63+ displayMarginBeginning: root.displayMarginBeginning
64+ displayMarginEnd: root.displayMarginEnd
65+
66+ delegate: Loader {
67+ id: loader
68+ sourceComponent: cardTool.cardComponent
69+ width: cardTool.cardWidth
70+ onLoaded: {
71+ item.objectName = "delegate" + index;
72+ item.fixedArtShapeSize = Qt.binding(function() { return cardTool.artShapeSize; });
73+ item.fixedHeaderHeight = Qt.binding(function() { return cardTool.headerHeight; });
74+ item.cardData = Qt.binding(function() { return model; });
75+ item.template = Qt.binding(function() { return cardTool.template; });
76+ item.components = Qt.binding(function() { return cardTool.components; });
77+ item.headerAlignment = Qt.binding(function() { return cardTool.headerAlignment; });
78+ }
79+ Connections {
80+ target: loader.item
81+ onClicked: root.clicked(index, result)
82+ onPressAndHold: root.pressAndHold(index)
83+ }
84+ }
85+ }
86+}
qml/Dash/DashRenderer.qml−7
@@ -25,8 +25,6 @@ Item {
25
25
26 property int collapsedHeight: height
26 property int collapsedHeight: height
27
27
28− property int margins: 0
29−
30 property int uncollapsedHeight: height
28 property int uncollapsedHeight: height
31
29
32 property int displayMarginBeginning: 0
30 property int displayMarginBeginning: 0
@@ -35,11 +33,6 @@ Item {
35
33
36 property real originY: 0
34 property real originY: 0
37
35
38− property real verticalSpacing: 0
39−
40− // The current item of the renderer
41− property var currentItem
42−
43 // The model to renderer
36 // The model to renderer
44 property var model
37 property var model
45
38
qml/Dash/GenericScopeView.qml+10−1
@@ -1,5 +1,5 @@
1/*
1/*
2− * Copyright (C) 2013 Canonical, Ltd.
2+ * Copyright (C) 2013-2014 Canonical, Ltd.
3 *
3 *
4 * This program is free software; you can redistribute it and/or modify
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
5 * it under the terms of the GNU General Public License as published by
@@ -147,6 +147,7 @@ FocusScope {
147 source: {
147 source: {
148 switch (cardTool.categoryLayout) {
148 switch (cardTool.categoryLayout) {
149 case "carousel": return "CardCarousel.qml";
149 case "carousel": return "CardCarousel.qml";
150+ case "vertical-journal": return "CardVerticalJournal.qml";
150 case "running-apps": return "Apps/RunningApplicationsGrid.qml";
151 case "running-apps": return "Apps/RunningApplicationsGrid.qml";
151 case "grid":
152 case "grid":
152 default: return "CardFilterGrid.qml";
153 default: return "CardFilterGrid.qml";
@@ -202,6 +203,14 @@ FocusScope {
202 previewListView.currentIndex = index;
203 previewListView.currentIndex = index;
203 previewListView.open = true
204 previewListView.open = true
204 }
205 }
206+ onExpandableChanged: {
207+ // This can happen with the VJ that doesn't know how height it will be on creation
208+ // so doesn't set expandable until a bit too late for onLoaded
209+ if (rendererLoader.item.expandable) {
210+ var shouldFilter = baseItem.category != categoryView.expandedCategoryId;
211+ rendererLoader.item.setFilter(shouldFilter, false /*animate*/);
212+ }
213+ }
205 }
214 }
206 Connections {
215 Connections {
207 target: categoryView
216 target: categoryView
qml/Dash/Previews/PreviewPayments.qmlnew file+56
@@ -0,0 +1,56 @@
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.1
18+import Ubuntu.Components 0.1
19+import Ubuntu.Payments 0.1
20+
21+/*! \brief Preview widget for a purchase button.
22+ *
23+ * When clicked, this button starts the payments service.
24+ * Then it waits until the purchase finishes or fails.
25+ * Those events trigger the corresponding actions.
26+ */
27+
28+PreviewWidget {
29+ id: root
30+
31+ implicitHeight: paymentButton.implicitHeight
32+ implicitWidth: paymentButton.implicitWidth
33+
34+ Button {
35+ id: paymentButton
36+ objectName: "paymentButton"
37+
38+ color: Theme.palette.selected.foreground
39+ text: paymentClient.formattedPrice
40+ onClicked: paymentClient.start()
41+ anchors.right: parent.right
42+ width: (root.width - units.gu(1)) / 2
43+
44+ Payments {
45+ id: paymentClient
46+
47+ property var source: widgetData["source"]
48+
49+ price: source["price"]
50+ currency: source["currency"]
51+ storeItemId: source["store_item_id"]
52+ onPurchaseCompleted: root.triggered(widgetId, "purchaseCompleted", source)
53+ onPurchaseError: root.triggered(widgetId, "purchaseError", source)
54+ }
55+ }
56+}
qml/Dash/Previews/PreviewWidgetFactory.qml+1
@@ -48,6 +48,7 @@ Loader {
48 case "header": return "PreviewHeader.qml";
48 case "header": return "PreviewHeader.qml";
49 case "image": return "PreviewZoomableImage.qml";
49 case "image": return "PreviewZoomableImage.qml";
50 case "progress": return "PreviewProgress.qml";
50 case "progress": return "PreviewProgress.qml";
51+ case "payments": return "PreviewPayments.qml";
51 case "rating-input": return "PreviewRatingInput.qml";
52 case "rating-input": return "PreviewRatingInput.qml";
52 case "reviews": return "PreviewRatingDisplay.qml";
53 case "reviews": return "PreviewRatingDisplay.qml";
53 case "text": return "PreviewTextSummary.qml";
54 case "text": return "PreviewTextSummary.qml";
qml/Greeter/LoginList.qml+4−4
@@ -257,13 +257,13 @@ Item {
257
257
258 onShowMessage: {
258 onShowMessage: {
259 // inefficient, but we only rarely deal with messages
259 // inefficient, but we only rarely deal with messages
260− text = text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/\n/g, "<br>");
260+ var html = text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/\n/g, "<br>")
261 if (isError)
261 if (isError)
262− text = "<font color=\"#df382c\">" + text + "</font>"
262+ html = "<font color=\"#df382c\">" + html + "</font>"
263 if (infoLabel.text == "")
263 if (infoLabel.text == "")
264− infoLabel.text = text;
264+ infoLabel.text = html
265 else
265 else
266− infoLabel.text = infoLabel.text + "<br>" + text;
266+ infoLabel.text = infoLabel.text + "<br>" + html
267 }
267 }
268
268
269 onShowPrompt: {
269 onShowPrompt: {
qml/Launcher/LauncherDelegate.qml+1
@@ -63,6 +63,7 @@ Item {
63 id: iconImage
63 id: iconImage
64 sourceSize.width: iconShape.width
64 sourceSize.width: iconShape.width
65 sourceSize.height: iconShape.height
65 sourceSize.height: iconShape.height
66+ fillMode: Image.PreserveAspectCrop
66 source: root.iconName
67 source: root.iconName
67 }
68 }
68 }
69 }
qml/Launcher/LauncherPanel.qml−1
@@ -104,7 +104,6 @@ Item {
104 highlightRangeMode: ListView.ApplyRange
104 highlightRangeMode: ListView.ApplyRange
105 preferredHighlightBegin: (height - itemHeight) / 2
105 preferredHighlightBegin: (height - itemHeight) / 2
106 preferredHighlightEnd: (height + itemHeight) / 2
106 preferredHighlightEnd: (height + itemHeight) / 2
107− spacing: units.gu(0.5)
108
107
109 // The size of the area the ListView is extended to make sure items are not
108 // The size of the area the ListView is extended to make sure items are not
110 // destroyed when dragging them outside the list. This needs to be at least
109 // destroyed when dragging them outside the list. This needs to be at least
qml/Notifications/Notification.qml+13
@@ -15,6 +15,7 @@
15 */
15 */
16
16
17import QtQuick 2.0
17import QtQuick 2.0
18+import QtMultimedia 5.0
18import Ubuntu.Components 0.1
19import Ubuntu.Components 0.1
19import Unity.Notifications 1.0
20import Unity.Notifications 1.0
20import QMenuModel 0.1
21import QMenuModel 0.1
@@ -66,6 +67,18 @@ Item {
66 return result;
67 return result;
67 }
68 }
68
69
70+ Audio {
71+ id: sound
72+ objectName: "sound"
73+ source: hints["suppress-sound"] != "" ? hints["sound-file"] : undefined
74+ }
75+
76+ onOpacityChanged: {
77+ if (opacity == 1.0 && hints["suppress-sound"] != "true" && sound.source) {
78+ sound.play();
79+ }
80+ }
81+
69 Behavior on height {
82 Behavior on height {
70 id: normalHeightBehavior
83 id: normalHeightBehavior
71
84
qml/Panel/Indicators/DefaultIndicatorWidget.qml+21−29
@@ -19,11 +19,12 @@
19
19
20import QtQuick 2.0
20import QtQuick 2.0
21import Ubuntu.Components 0.1
21import Ubuntu.Components 0.1
22+import Ubuntu.Settings.Components 0.1
22
23
23IndicatorBase {
24IndicatorBase {
24 id: indicatorWidget
25 id: indicatorWidget
25
26
26− property int iconSize: height
27+ property int iconSize: units.gu(2)
27 property alias leftLabel: itemLeftLabel.text
28 property alias leftLabel: itemLeftLabel.text
28 property alias rightLabel: itemRightLabel.text
29 property alias rightLabel: itemRightLabel.text
29 property var icons: undefined
30 property var icons: undefined
@@ -31,9 +32,16 @@ IndicatorBase {
31 width: itemRow.width
32 width: itemRow.width
32 enabled: false
33 enabled: false
33
34
35+ // FIXME: For now we will enable led indicator support only for messaging indicator
36+ // in the future we should export a led API insted of doing that,
37+ Loader {
38+ id: indicatorLed
39+ // only load source Component if the icons contains the new message icon
40+ source: (indicatorWidget.icons && (String(indicatorWidget.icons).indexOf("indicator-messages-new") != -1)) ? Qt.resolvedUrl("IndicatorsLight.qml") : ""
41+ }
42+
34 Row {
43 Row {
35 id: itemRow
44 id: itemRow
36− width: childrenRect.width
37 objectName: "itemRow"
45 objectName: "itemRow"
38 anchors {
46 anchors {
39 top: parent.top
47 top: parent.top
@@ -43,7 +51,7 @@ IndicatorBase {
43
51
44 Label {
52 Label {
45 id: itemLeftLabel
53 id: itemLeftLabel
46− width: guRoundUp(implicitWidth)
54+ width: contentWidth + units.gu(1)
47 objectName: "leftLabel"
55 objectName: "leftLabel"
48 color: Theme.palette.selected.backgroundText
56 color: Theme.palette.selected.backgroundText
49 opacity: 0.8
57 opacity: 0.8
@@ -51,10 +59,10 @@ IndicatorBase {
51 fontSize: "medium"
59 fontSize: "medium"
52 anchors.verticalCenter: parent.verticalCenter
60 anchors.verticalCenter: parent.verticalCenter
53 visible: text != ""
61 visible: text != ""
62+ horizontalAlignment: Text.AlignHCenter
54 }
63 }
55
64
56 Row {
65 Row {
57− width: childrenRect.width
58 anchors {
66 anchors {
59 top: parent.top
67 top: parent.top
60 bottom: parent.bottom
68 bottom: parent.bottom
@@ -64,22 +72,16 @@ IndicatorBase {
64 model: indicatorWidget.icons
72 model: indicatorWidget.icons
65
73
66 Item {
74 Item {
67− width: guRoundUp(itemImage.width)
75+ width: itemImage.width + units.gu(1)
68− height: indicatorWidget.iconSize
76+ anchors { top: parent.top; bottom: parent.bottom }
69
77
70− Image {
78+ StatusIcon {
71 id: itemImage
79 id: itemImage
72− objectName: "itemImage"
80+ height: indicatorWidget.iconSize
73− visible: source != ""
81+ anchors.centerIn: parent
74 source: modelData
82 source: modelData
75− height: parent.height
83+ sets: ["status", "actions"]
76− anchors.horizontalCenter: parent.horizontalCenter
84+ color: "#CCCCCC"
77− fillMode: Image.PreserveAspectFit
78−
79− sourceSize {
80− width: indicatorWidget.iconSize
81− height: indicatorWidget.iconSize
82− }
83 }
85 }
84 }
86 }
85 }
87 }
@@ -87,7 +89,7 @@ IndicatorBase {
87
89
88 Label {
90 Label {
89 id: itemRightLabel
91 id: itemRightLabel
90− width: guRoundUp(implicitWidth)
92+ width: contentWidth + units.gu(1)
91 objectName: "rightLabel"
93 objectName: "rightLabel"
92 color: Theme.palette.selected.backgroundText
94 color: Theme.palette.selected.backgroundText
93 opacity: 0.8
95 opacity: 0.8
@@ -95,20 +97,10 @@ IndicatorBase {
95 fontSize: "medium"
97 fontSize: "medium"
96 anchors.verticalCenter: parent.verticalCenter
98 anchors.verticalCenter: parent.verticalCenter
97 visible: text != ""
99 visible: text != ""
100+ horizontalAlignment: Text.AlignHCenter
98 }
101 }
99 }
102 }
100
103
101− // TODO: Use toolkit function https://bugs.launchpad.net/ubuntu-ui-toolkit/+bug/1242575
102− function guRoundUp(width) {
103− if (width == 0) {
104− return 0;
105− }
106− var gu1 = units.gu(1.0);
107− var mod = (width % gu1);
108−
109− return mod == 0 ? width : width + (gu1 - mod);
110− }
111−
112 onRootActionStateChanged: {
104 onRootActionStateChanged: {
113 if (rootActionState == undefined) {
105 if (rootActionState == undefined) {
114 leftLabel = "";
106 leftLabel = "";
qml/Panel/Indicators/IndicatorBase.qml+3−4
@@ -18,8 +18,7 @@
18 */
18 */
19
19
20import QtQuick 2.0
20import QtQuick 2.0
21−import QMenuModel 0.1 as QMenuModel
22−import Unity.Indicators 0.1 as Indicators
21+import Unity.Indicators 0.1
23
22
24Item {
23Item {
25 id: indicatorItem
24 id: indicatorItem
@@ -36,14 +35,14 @@ Item {
36
35
37 property alias menuModel: cachedModel.model
36 property alias menuModel: cachedModel.model
38
37
39− Indicators.CachedUnityMenuModel {
38+ CachedUnityMenuModel {
40 id: cachedModel
39 id: cachedModel
41 busName: indicatorItem.busName
40 busName: indicatorItem.busName
42 actionsObjectPath: indicatorItem.actionsObjectPath
41 actionsObjectPath: indicatorItem.actionsObjectPath
43 menuObjectPath: indicatorItem.deviceMenuObjectPath
42 menuObjectPath: indicatorItem.deviceMenuObjectPath
44 }
43 }
45
44
46− property var rootActionState: Indicators.RootActionState {
45+ property RootActionState rootActionState: RootActionState {
47 menu: menuModel
46 menu: menuModel
48 onUpdated: indicatorItem.rootActionStateChanged()
47 onUpdated: indicatorItem.rootActionStateChanged()
49 }
48 }
tests/mocks/Unity/Indicators/IndicatorBase.qml → qml/Panel/Indicators/IndicatorsLight.qmlrenamed+14−14
@@ -1,5 +1,5 @@
1/*
1/*
2− * Copyright 2013 Canonical Ltd.
2+ * Copyright 2014 Canonical Ltd.
3 *
3 *
4 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
5 * it under the terms of the GNU Lesser General Public License as published by
@@ -14,25 +14,25 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
15 *
16 * Authors:
16 * Authors:
17− * Nick Dedekind <nick.dedekind@canonical.com>
17+ * Renato Araujo Oliveira Filho <renato@canonical.com>
18 */
18 */
19
19
20import QtQuick 2.0
20import QtQuick 2.0
21−import QMenuModel 0.1
21+import Powerd 0.1
22+import Lights 0.1
22
23
23−Item {
24+QtObject {
24− id: indicatorBase
25+ id: root
25
26
26− //const
27+ Component.onDestruction: Lights.state = Lights.Off
27− property string busName
28− property string actionsObjectPath
29− property string menuObjectPath
30− property string rootMenuType: "com.canonical.indicator.root"
31− property string deviceMenuObjectPath: menuObjectPath
32
28
33− property var menuModel: UnityMenuModel {}
29+ // QtObject does not have children
30+ property var _connections: Connections {
31+ id: powerConnection
34
32
35− property RootActionState rootActionState: RootActionState {
33+ target: Powerd
36− onUpdated: indicatorBase.rootActionStateChanged()
34+ onDisplayPowerStateChange: {
35+ Lights.state = (status === Powerd.Off) ? Lights.On : Lights.Off
36+ }
37 }
37 }
38}
38}
qml/Panel/Indicators/MenuItemFactory.qml+1−1
@@ -169,7 +169,7 @@ Item {
169
169
170 Component {
170 Component {
171 id: standardMenu;
171 id: standardMenu;
172− ListItems.Standard {
172+ Menus.StandardMenu {
173 objectName: "standardMenu"
173 objectName: "standardMenu"
174 property QtObject menuData: null
174 property QtObject menuData: null
175 property int menuIndex: -1
175 property int menuIndex: -1
qml/Panel/Panel.qml+1−1
@@ -21,7 +21,7 @@ import "../Components"
21Item {
21Item {
22 id: root
22 id: root
23 readonly property real panelHeight: units.gu(3) + units.dp(2)
23 readonly property real panelHeight: units.gu(3) + units.dp(2)
24− property real indicatorsMenuWidth: (shell.width > units.gu(60)) ? units.gu(40) : shell.width
24+ property real indicatorsMenuWidth: width
25 property alias indicators: indicatorsMenu
25 property alias indicators: indicatorsMenu
26 property bool fullscreenMode: false
26 property bool fullscreenMode: false
27 property bool searchVisible: true
27 property bool searchVisible: true
qml/Shell.qml+26−1
@@ -31,6 +31,7 @@ import "Panel"
31import "Components"
31import "Components"
32import "Notifications"
32import "Notifications"
33import Unity.Notifications 1.0 as NotificationBackend
33import Unity.Notifications 1.0 as NotificationBackend
34+import Unity.Session 0.1
34
35
35FocusScope {
36FocusScope {
36 id: shell
37 id: shell
@@ -267,6 +268,30 @@ FocusScope {
267 }
268 }
268 }
269 }
269
270
271+ Connections {
272+ target: DBusUnitySessionService
273+
274+ function closeAllApps() {
275+ while (true) {
276+ var app = ApplicationManager.get(0);
277+ if (app === null) {
278+ break;
279+ }
280+ ApplicationManager.stopApplication(app.appId);
281+ }
282+ }
283+
284+ onLogoutRequested: {
285+ // TODO: Display a dialog to ask the user to confirm.
286+ DBusUnitySessionService.Logout();
287+ }
288+
289+ onLogoutReady: {
290+ closeAllApps();
291+ Qt.quit();
292+ }
293+ }
294+
270 Loader {
295 Loader {
271 id: applicationsDisplayLoader
296 id: applicationsDisplayLoader
272 anchors.fill: parent
297 anchors.fill: parent
@@ -427,7 +452,7 @@ FocusScope {
427 onDisplayPowerStateChange: {
452 onDisplayPowerStateChange: {
428 // We ignore any display-off signals when the proximity sensor
453 // We ignore any display-off signals when the proximity sensor
429 // is active. This usually indicates something like a phone call.
454 // is active. This usually indicates something like a phone call.
430− if (status == Powerd.Off && (flags & Powerd.UseProximity) == 0) {
455+ if (status == Powerd.Off && reason != Powerd.Proximity) {
431 greeter.showNow();
456 greeter.showNow();
432 }
457 }
433
458
run.sh−6
@@ -57,12 +57,6 @@ if $KEYLOCK; then
57 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD/builddir/tests/mocks/libusermetrics:$PWD/builddir/tests/mocks/LightDM/single-passphrase
57 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD/builddir/tests/mocks/libusermetrics:$PWD/builddir/tests/mocks/LightDM/single-passphrase
58fi
58fi
59
59
60−# Force icon theme if running on the desktop, otherwise gnome theme (if running
61−# on Ubuntu Desktop) will be used and icons won't be found
62−if [ -n "$DESKTOP_SESSION" ]; then
63− export UBUNTU_ICON_THEME=ubuntu-mobile
64−fi
65−
66QML_PHONE_SHELL_ARGS=""
60QML_PHONE_SHELL_ARGS=""
67if $MOUSE_TOUCH; then
61if $MOUSE_TOUCH; then
68 QML_PHONE_SHELL_ARGS="$QML_PHONE_SHELL_ARGS -mousetouch"
62 QML_PHONE_SHELL_ARGS="$QML_PHONE_SHELL_ARGS -mousetouch"
src/CMakeLists.txt+1
@@ -19,6 +19,7 @@ add_executable(${SHELL_APP}
19 ApplicationArguments.h
19 ApplicationArguments.h
20 main.cpp
20 main.cpp
21 MouseTouchAdaptor.cpp
21 MouseTouchAdaptor.cpp
22+ CachingNetworkManagerFactory.cpp
22 ${QML_FILES} # This is to make qml and image files appear in the IDE's project tree
23 ${QML_FILES} # This is to make qml and image files appear in the IDE's project tree
23)
24)
24
25
src/CachingNetworkManagerFactory.cppnew file+62
@@ -0,0 +1,62 @@
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+
18+#include "CachingNetworkManagerFactory.h"
19+
20+#include <QNetworkDiskCache>
21+#include <QNetworkAccessManager>
22+#include <QStandardPaths>
23+#include <QNetworkConfigurationManager>
24+
25+CachingNetworkAccessManager::CachingNetworkAccessManager(QObject *parent)
26+ : QNetworkAccessManager(parent)
27+{
28+ m_networkManager = new QNetworkConfigurationManager(this);
29+
30+ QObject::connect(m_networkManager, &QNetworkConfigurationManager::onlineStateChanged, this, &CachingNetworkAccessManager::onlineStateChanged);
31+ m_isOnline = m_networkManager->isOnline();
32+}
33+
34+void CachingNetworkAccessManager::onlineStateChanged(bool isOnline)
35+{
36+ m_isOnline = isOnline;
37+}
38+
39+QNetworkReply* CachingNetworkAccessManager::createRequest(Operation op, const QNetworkRequest &request, QIODevice *outgoingData)
40+{
41+ if (!m_isOnline) {
42+ QNetworkRequest req(request);
43+ req.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::AlwaysCache);
44+ return QNetworkAccessManager::createRequest(op, req, outgoingData);
45+ }
46+
47+ return QNetworkAccessManager::createRequest(op, request, outgoingData);
48+}
49+
50+CachingNetworkManagerFactory::CachingNetworkManagerFactory()
51+{
52+}
53+
54+QNetworkAccessManager *CachingNetworkManagerFactory::create(QObject *parent) {
55+ QNetworkAccessManager *manager = new CachingNetworkAccessManager(parent);
56+
57+ QNetworkDiskCache* cache = new QNetworkDiskCache(manager);
58+ cache->setCacheDirectory(QString("%1/network").arg(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)));
59+
60+ manager->setCache(cache);
61+ return manager;
62+}
src/CachingNetworkManagerFactory.hnew file+50
@@ -0,0 +1,50 @@
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+
18+#ifndef CACHINGNETWORKMANAGERFACTORY_H
19+#define CACHINGNETWORKMANAGERFACTORY_H
20+
21+#include <QQmlNetworkAccessManagerFactory>
22+#include <QNetworkAccessManager>
23+
24+class QNetworkConfigurationManager;
25+
26+class CachingNetworkAccessManager : public QNetworkAccessManager
27+{
28+public:
29+ CachingNetworkAccessManager(QObject *parent = 0);
30+
31+protected:
32+ QNetworkReply* createRequest(Operation op, const QNetworkRequest &req, QIODevice *outgoingData = 0) override;
33+
34+private Q_SLOTS:
35+ void onlineStateChanged(bool isOnline);
36+
37+private:
38+ QNetworkConfigurationManager* m_networkManager;
39+ bool m_isOnline;
40+};
41+
42+class CachingNetworkManagerFactory : public QQmlNetworkAccessManagerFactory
43+{
44+public:
45+ CachingNetworkManagerFactory();
46+
47+ QNetworkAccessManager *create(QObject *parent) override;
48+};
49+
50+#endif // CACHINGNETWORKMANAGERFACTORY_H
src/Panel/Indicators/client/indicatorsclient.cpp−1
@@ -32,7 +32,6 @@ IndicatorsClient::IndicatorsClient(int &argc, char **argv)
32 m_view(0)
32 m_view(0)
33{
33{
34 m_application = new QApplication(argc, argv);
34 m_application = new QApplication(argc, argv);
35− resolveIconTheme();
36
35
37 QStringList args = m_application->arguments();
36 QStringList args = m_application->arguments();
38
37
src/main.cpp+6−4
@@ -34,15 +34,15 @@
34#include <paths.h>
34#include <paths.h>
35#include "MouseTouchAdaptor.h"
35#include "MouseTouchAdaptor.h"
36#include "ApplicationArguments.h"
36#include "ApplicationArguments.h"
37+#include "CachingNetworkManagerFactory.h"
37
38
38#include <unity-mir/qmirserver.h>
39#include <unity-mir/qmirserver.h>
39
40
40−
41int startShell(int argc, const char** argv, void* server)
41int startShell(int argc, const char** argv, void* server)
42{
42{
43 const bool isUbuntuMirServer = qgetenv("QT_QPA_PLATFORM") == "ubuntumirserver";
43 const bool isUbuntuMirServer = qgetenv("QT_QPA_PLATFORM") == "ubuntumirserver";
44
44
45− QGuiApplication::setApplicationName("Unity 8");
45+ QGuiApplication::setApplicationName("unity8");
46 QGuiApplication *application;
46 QGuiApplication *application;
47
47
48 QCommandLineParser parser;
48 QCommandLineParser parser;
@@ -96,8 +96,6 @@ Load the testability driver");
96 indicatorProfile = "phone";
96 indicatorProfile = "phone";
97 }
97 }
98
98
99− resolveIconTheme();
100−
101 ApplicationArguments qmlArgs;
99 ApplicationArguments qmlArgs;
102 if (parser.isSet(windowGeometryOption) &&
100 if (parser.isSet(windowGeometryOption) &&
103 parser.value(windowGeometryOption).split('x').size() == 2)
101 parser.value(windowGeometryOption).split('x').size() == 2)
@@ -159,8 +157,12 @@ Load the testability driver");
159 }
157 }
160 appendImportPaths(view->engine(), ::fallbackImportPaths());
158 appendImportPaths(view->engine(), ::fallbackImportPaths());
161
159
160+ CachingNetworkManagerFactory *managerFactory = new CachingNetworkManagerFactory();
161+ view->engine()->setNetworkAccessManagerFactory(managerFactory);
162+
162 view->setSource(source);
163 view->setSource(source);
163 view->setColor("transparent");
164 view->setColor("transparent");
165+ QObject::connect(view->engine(), SIGNAL(quit()), application, SLOT(quit()));
164
166
165 if (qgetenv("QT_QPA_PLATFORM") == "ubuntu" || isUbuntuMirServer || parser.isSet(fullscreenOption)) {
167 if (qgetenv("QT_QPA_PLATFORM") == "ubuntu" || isUbuntuMirServer || parser.isSet(fullscreenOption)) {
166 view->showFullScreen();
168 view->showFullScreen();
tests/autopilot/unity8/process_helpers.py+4−3
@@ -75,7 +75,7 @@ def unlock_unity(unity_proxy_obj=None):
75 main_window_emulator.QQuickView)
75 main_window_emulator.QQuickView)
76
76
77 greeter = main_window.get_greeter()
77 greeter = main_window.get_greeter()
78− if greeter.created == False:
78+ if greeter.created is False:
79 raise RuntimeWarning("Greeter appears to be already unlocked.")
79 raise RuntimeWarning("Greeter appears to be already unlocked.")
80
80
81 # Because of potential input jerkiness under heavy load,
81 # Because of potential input jerkiness under heavy load,
@@ -98,7 +98,8 @@ def unlock_unity(unity_proxy_obj=None):
98
98
99def lock_unity(unity_proxy_obj=None):
99def lock_unity(unity_proxy_obj=None):
100 """Helper function that attempts to lock the unity greeter."""
100 """Helper function that attempts to lock the unity greeter."""
101− import evdev, time
101+ import evdev
102+ import time
102 uinput = evdev.UInput(name='unity8-autopilot-power-button',
103 uinput = evdev.UInput(name='unity8-autopilot-power-button',
103 devnode='/dev/autopilot-uinput')
104 devnode='/dev/autopilot-uinput')
104 # One press and release to turn screen off (locking unity)
105 # One press and release to turn screen off (locking unity)
@@ -172,7 +173,7 @@ def _get_unity_status():
172
173
173def _get_unity_pid():
174def _get_unity_pid():
174 status = _get_unity_status()
175 status = _get_unity_status()
175− if not "start/" in status:
176+ if "start/" not in status:
176 raise CannotAccessUnity("Unity is not in the running state.")
177 raise CannotAccessUnity("Unity is not in the running state.")
177 return int(status.split()[-1])
178 return int(status.split()[-1])
178
179
tests/autopilot/unity8/shell/tests/__init__.py+1−2
@@ -142,12 +142,11 @@ class UnityTestCase(AutopilotTestCase):
142 self._data_dirs_mock_enabled = True
142 self._data_dirs_mock_enabled = True
143 self._environment = {}
143 self._environment = {}
144
144
145− #### FIXME: This is a work around re: lp:1238417 ####
145+ # FIXME: This is a work around re: lp:1238417
146 if model() != "Desktop":
146 if model() != "Desktop":
147 from autopilot.input import _uinput
147 from autopilot.input import _uinput
148 _uinput._touch_device = _uinput.create_touch_device()
148 _uinput._touch_device = _uinput.create_touch_device()
149 self.addCleanup(_uinput._touch_device.close)
149 self.addCleanup(_uinput._touch_device.close)
150− ####
151
150
152 self.touch = Touch.create()
151 self.touch = Touch.create()
153 self._setup_display_details()
152 self._setup_display_details()
tests/autopilot/unity8/shell/tests/disabled_test_hud.py+44−13
@@ -20,12 +20,13 @@
20from __future__ import absolute_import
20from __future__ import absolute_import
21
21
22from unity8.process_helpers import unlock_unity
22from unity8.process_helpers import unlock_unity
23−from unity8.shell import with_lightdm_mock, DragMixin
23+from unity8.shell import DragMixin
24from unity8.shell.tests import UnityTestCase, _get_device_emulation_scenarios
24from unity8.shell.tests import UnityTestCase, _get_device_emulation_scenarios
25
25
26from testtools.matchers import Equals
26from testtools.matchers import Equals
27from autopilot.matchers import Eventually
27from autopilot.matchers import Eventually
28
28
29+
29class TestHud(UnityTestCase, DragMixin):
30class TestHud(UnityTestCase, DragMixin):
30
31
31 """Tests the Shell HUD."""
32 """Tests the Shell HUD."""
@@ -33,10 +34,14 @@ class TestHud(UnityTestCase, DragMixin):
33 scenarios = _get_device_emulation_scenarios()
34 scenarios = _get_device_emulation_scenarios()
34
35
35 def test_show_hud_button_appears(self):
36 def test_show_hud_button_appears(self):
36− """Swiping up while an app is active must show the 'show hud' button, following some behaviours.
37+ """Swiping up while an app is active must show the 'show hud' button.
38+
39+ It should follow some behaviours.
37 The button must disappear not opening the HUD when releasing the
40 The button must disappear not opening the HUD when releasing the
38− mouse again somewhere on the screen except on the button itself following a timeout.
41+ mouse again somewhere on the screen except on the button itself
42+ following a timeout.
39− The button must disappear when touching somewhere on the screen except the button itself.
43+ The button must disappear when touching somewhere on the screen
44+ except the button itself.
40
45
41 """
46 """
42 unity_proxy = self.launch_unity()
47 unity_proxy = self.launch_unity()
@@ -55,29 +60,47 @@ class TestHud(UnityTestCase, DragMixin):
55
60
56 self.touch.press(swipe_coords.start_x, swipe_coords.start_y)
61 self.touch.press(swipe_coords.start_x, swipe_coords.start_y)
57 self.addCleanup(self._maybe_release_finger)
62 self.addCleanup(self._maybe_release_finger)
63+ self._drag(
64+ swipe_coords.start_x,
65+ swipe_coords.start_y,
66+ swipe_coords.start_x,
58− self._drag(swipe_coords.start_x, swipe_coords.start_y, swipe_coords.start_x, swipe_coords.start_y - int(edge_drag_area.distanceThreshold) - 5)
67+ swipe_coords.start_y - int(edge_drag_area.distanceThreshold) - 5)
59 self.assertThat(hud_show_button.opacity, Eventually(Equals(0.5)))
68 self.assertThat(hud_show_button.opacity, Eventually(Equals(0.5)))
69+ self.assertThat(
70+ hud_show_button.bottomMargin,
60− self.assertThat(hud_show_button.bottomMargin, Eventually(Equals(initialBottomMargin)))
71+ Eventually(Equals(initialBottomMargin)))
72+ self._drag(
73+ swipe_coords.start_x,
61− self._drag(swipe_coords.start_x, swipe_coords.start_y - int(edge_drag_area.distanceThreshold) - 5, swipe_coords.end_x, swipe_coords.start_y - int(edge_drag_area.distanceThreshold) - int(edge_drag_area.commitDistance) - 5)
74+ swipe_coords.start_y - int(edge_drag_area.distanceThreshold) - 5,
75+ swipe_coords.end_x,
76+ swipe_coords.start_y - int(edge_drag_area.distanceThreshold) -
77+ int(edge_drag_area.commitDistance) - 5)
62 self.assertThat(hud_show_button.opacity, Eventually(Equals(1.0)))
78 self.assertThat(hud_show_button.opacity, Eventually(Equals(1.0)))
63 self.assertThat(hud_show_button.bottomMargin, Eventually(Equals(0.0)))
79 self.assertThat(hud_show_button.bottomMargin, Eventually(Equals(0.0)))
64− self.touch.release();
80+ self.touch.release()
65 self.assertThat(hud.shown, Equals(False))
81 self.assertThat(hud.shown, Equals(False))
66 self.assertThat(hud_show_button.opacity, Eventually(Equals(0.0)))
82 self.assertThat(hud_show_button.opacity, Eventually(Equals(0.0)))
67
83
68 self.touch.press(swipe_coords.start_x, swipe_coords.start_y)
84 self.touch.press(swipe_coords.start_x, swipe_coords.start_y)
85+ self._drag(
86+ swipe_coords.start_x,
87+ swipe_coords.start_y,
88+ swipe_coords.start_x,
69− self._drag(swipe_coords.start_x, swipe_coords.start_y, swipe_coords.start_x, swipe_coords.end_y - int(hud_show_button.height))
89+ swipe_coords.end_y - int(hud_show_button.height))
70 self.assertThat(hud.shown, Equals(False))
90 self.assertThat(hud.shown, Equals(False))
71 self.assertThat(hud_show_button.opacity, Eventually(Equals(1.0)))
91 self.assertThat(hud_show_button.opacity, Eventually(Equals(1.0)))
72 self.touch.release()
92 self.touch.release()
73 self.assertThat(hud_show_button.opacity, Eventually(Equals(1.0)))
93 self.assertThat(hud_show_button.opacity, Eventually(Equals(1.0)))
94+ self.touch.tap(
95+ swipe_coords.end_x,
74− self.touch.tap(swipe_coords.end_x, swipe_coords.end_y - int(hud_show_button.height))
96+ swipe_coords.end_y - int(hud_show_button.height))
75 self.assertThat(hud.shown, Equals(False))
97 self.assertThat(hud.shown, Equals(False))
76 self.assertThat(hud_show_button.opacity, Eventually(Equals(0.0)))
98 self.assertThat(hud_show_button.opacity, Eventually(Equals(0.0)))
77
99
78 def test_show_hud_appears(self):
100 def test_show_hud_appears(self):
79 """Releasing the touch on the 'show hud' button must display the hud.
101 """Releasing the touch on the 'show hud' button must display the hud.
80− Test that the hud button stays on screen and tapping it opens the hud.
102+ Test that the hud button stays on screen and tapping it opens the
103+ hud.
81
104
82 """
105 """
83 unity_proxy = self.launch_unity()
106 unity_proxy = self.launch_unity()
@@ -94,7 +117,11 @@ class TestHud(UnityTestCase, DragMixin):
94
117
95 self.touch.press(swipe_coords.start_x, swipe_coords.start_y)
118 self.touch.press(swipe_coords.start_x, swipe_coords.start_y)
96 self.addCleanup(self._maybe_release_finger)
119 self.addCleanup(self._maybe_release_finger)
97− self._drag(swipe_coords.start_x, swipe_coords.start_y, swipe_coords.start_x, swipe_coords.end_y)
120+ self._drag(
121+ swipe_coords.start_x,
122+ swipe_coords.start_y,
123+ swipe_coords.start_x,
124+ swipe_coords.end_y)
98 self.assertThat(hud.shown, Eventually(Equals(False)))
125 self.assertThat(hud.shown, Eventually(Equals(False)))
99 self.assertThat(hud_show_button.opacity, Eventually(Equals(1.0)))
126 self.assertThat(hud_show_button.opacity, Eventually(Equals(1.0)))
100 self.touch.release()
127 self.touch.release()
@@ -105,7 +132,11 @@ class TestHud(UnityTestCase, DragMixin):
105 self.assertThat(hud.shown, Eventually(Equals(False)))
132 self.assertThat(hud.shown, Eventually(Equals(False)))
106
133
107 self.touch.press(swipe_coords.start_x, swipe_coords.start_y)
134 self.touch.press(swipe_coords.start_x, swipe_coords.start_y)
135+ self._drag(
136+ swipe_coords.start_x,
137+ swipe_coords.start_y,
138+ swipe_coords.start_x,
108− self._drag(swipe_coords.start_x, swipe_coords.start_y, swipe_coords.start_x, swipe_coords.end_y - int(hud_show_button.height))
139+ swipe_coords.end_y - int(hud_show_button.height))
109 self.assertThat(hud.shown, Equals(False))
140 self.assertThat(hud.shown, Equals(False))
110 self.assertThat(hud_show_button.opacity, Eventually(Equals(1.0)))
141 self.assertThat(hud_show_button.opacity, Eventually(Equals(1.0)))
111 self.touch.release()
142 self.touch.release()
tests/autopilot/unity8/shell/tests/test_emulators.py−2
@@ -32,8 +32,6 @@ try:
32except ImportError:
32except ImportError:
33 import mock
33 import mock
34
34
35−from testtools.matchers import Contains, HasLength
36−
37from unity8 import process_helpers
35from unity8 import process_helpers
38from unity8.shell import emulators, fixture_setup, tests
36from unity8.shell import emulators, fixture_setup, tests
39from unity8.shell.emulators import dash as dash_emulators
37from unity8.shell.emulators import dash as dash_emulators
tests/autopilot/unity8/shell/tests/test_lock_screen.py+4−5
@@ -1,7 +1,7 @@
1# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
1# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2#
2#
3# Unity Autopilot Test Suite
3# Unity Autopilot Test Suite
4−# Copyright (C) 2012-2013 Canonical
4+# Copyright (C) 2012, 2013, 2014 Canonical
5#
5#
6# This program is free software: you can redistribute it and/or modify
6# This program is free software: you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
7# it under the terms of the GNU General Public License as published by
@@ -25,9 +25,7 @@ from unity8.shell import with_lightdm_mock
25from unity8.shell.tests import UnityTestCase, _get_device_emulation_scenarios
25from unity8.shell.tests import UnityTestCase, _get_device_emulation_scenarios
26
26
27from autopilot.matchers import Eventually
27from autopilot.matchers import Eventually
28−from autopilot.platform import model
29import sys
28import sys
30−from testtools import skipUnless
31from testtools.matchers import Equals
29from testtools.matchers import Equals
32import logging
30import logging
33
31
@@ -133,7 +131,7 @@ class TestLockscreen(UnityTestCase):
133 if not isinstance(code, basestring):
131 if not isinstance(code, basestring):
134 raise TypeError(
132 raise TypeError(
135 "'code' parameter must be a string, not %r."
133 "'code' parameter must be a string, not %r."
136− % type(passphrase)
134+ % type(code)
137 )
135 )
138 for num in code:
136 for num in code:
139 if not num.isdigit():
137 if not num.isdigit():
@@ -190,7 +188,8 @@ class TestLockscreen(UnityTestCase):
190 current_text = prompt.text
188 current_text = prompt.text
191 self.keyboard.type(character)
189 self.keyboard.type(character)
192 try:
190 try:
191+ self.assertThat(
193− self.assertThat(prompt.text, Eventually(Equals(current_text + character)))
192+ prompt.text, Eventually(Equals(current_text + character)))
194 except AssertionError:
193 except AssertionError:
195 if retries > 0:
194 if retries > 0:
196 self._type_character(character, prompt, retries-1)
195 self._type_character(character, prompt, retries-1)
tests/autopilot/unity8/shell/tests/test_notifications.py+15−10
@@ -211,8 +211,8 @@ class InteractiveNotificationBase(NotificationsBase):
211 self.touch.tap_object(notification.select_single(objectName="button4"))
211 self.touch.tap_object(notification.select_single(objectName="button4"))
212 self.assert_notification_action_id_was_called("action_decline_4")
212 self.assert_notification_action_id_was_called("action_decline_4")
213
213
214− def test_modal_sd_without_greeter (self):
214+ def test_modal_sd_without_greeter(self):
215− """A snap-decision on a phone should block input to shell beneath it when there's no greeter."""
215+ """Snap-decision should block input to shell without greeter."""
216 unity_proxy = self.launch_unity()
216 unity_proxy = self.launch_unity()
217 unlock_unity(unity_proxy)
217 unlock_unity(unity_proxy)
218
218
@@ -238,7 +238,8 @@ class InteractiveNotificationBase(NotificationsBase):
238 hints
238 hints
239 )
239 )
240
240
241− # verify that we cannot reveal the launcher (no longer interact with the shell)
241+ # verify that we cannot reveal the launcher (no longer interact with
242+ # the shell)
242 time.sleep(1)
243 time.sleep(1)
243 self.main_window.show_dash_swiping()
244 self.main_window.show_dash_swiping()
244 launcher = self.main_window.get_launcher()
245 launcher = self.main_window.get_launcher()
@@ -249,13 +250,14 @@ class InteractiveNotificationBase(NotificationsBase):
249 get_notification = lambda: notify_list.wait_select_single(
250 get_notification = lambda: notify_list.wait_select_single(
250 'Notification', objectName='notification1')
251 'Notification', objectName='notification1')
251 notification = get_notification()
252 notification = get_notification()
253+ self._assert_notification(
252− self._assert_notification(notification, summary, body, True, False, 1.0)
254+ notification, summary, body, True, False, 1.0)
253 self.touch.tap_object(notification.select_single(objectName="button0"))
255 self.touch.tap_object(notification.select_single(objectName="button0"))
254 self.assert_notification_action_id_was_called("action_accept")
256 self.assert_notification_action_id_was_called("action_accept")
255
257
256− def test_modal_sd_with_greeter (self):
258+ def test_modal_sd_with_greeter(self):
257− """A snap-decision on a phone should not block input to the greeter beneath it."""
259+ """A snap-decision should not block input to the greeter beneath it."""
258− unity_proxy = self.launch_unity()
260+ self.launch_unity()
259
261
260 summary = "Incoming file"
262 summary = "Incoming file"
261 body = "Frank would like to send you the file: essay.pdf"
263 body = "Frank would like to send you the file: essay.pdf"
@@ -290,7 +292,8 @@ class InteractiveNotificationBase(NotificationsBase):
290 get_notification = lambda: notify_list.wait_select_single(
292 get_notification = lambda: notify_list.wait_select_single(
291 'Notification', objectName='notification1')
293 'Notification', objectName='notification1')
292 notification = get_notification()
294 notification = get_notification()
295+ self._assert_notification(
293− self._assert_notification(notification, summary, body, True, False, 1.0)
296+ notification, summary, body, True, False, 1.0)
294 self.touch.tap_object(notification.select_single(objectName="button0"))
297 self.touch.tap_object(notification.select_single(objectName="button0"))
295 self.assert_notification_action_id_was_called("action_accept")
298 self.assert_notification_action_id_was_called("action_accept")
296
299
@@ -663,7 +666,8 @@ class EphemeralNotificationsTests(NotificationsBase):
663 icon_path = self._get_icon_path('avatars/amanda.png')
666 icon_path = self._get_icon_path('avatars/amanda.png')
664 notification.update(summary, body, icon_path)
667 notification.update(summary, body, icon_path)
665 notification.show()
668 notification.show()
669+ self._assert_notification(
666− self._assert_notification(get_notification(), summary, body, True, False, 1.0)
670+ get_notification(), summary, body, True, False, 1.0)
667
671
668 def test_update_notification_layout_change(self):
672 def test_update_notification_layout_change(self):
669 """Notification must allow updating its contents and layout while
673 """Notification must allow updating its contents and layout while
@@ -710,7 +714,8 @@ class EphemeralNotificationsTests(NotificationsBase):
710 notification.show()
714 notification.show()
711
715
712 self.assertThat(get_notification, Eventually(NotEquals(None)))
716 self.assertThat(get_notification, Eventually(NotEquals(None)))
717+ self._assert_notification(
713− self._assert_notification(get_notification(), summary, body, False, False, 1.0)
718+ get_notification(), summary, body, False, False, 1.0)
714
719
715 def test_append_hint(self):
720 def test_append_hint(self):
716 """Notification has to accumulate body-text using append-hint."""
721 """Notification has to accumulate body-text using append-hint."""
tests/autopilot/unity8/shell/tests/test_system_integration.py+10−5
@@ -23,19 +23,24 @@ import subprocess
23import unittest
23import unittest
24
24
25from autopilot import platform
25from autopilot import platform
26−from unity8.shell.emulators import UnityEmulatorBase
27from unity8.shell.tests import UnityTestCase, _get_device_emulation_scenarios
26from unity8.shell.tests import UnityTestCase, _get_device_emulation_scenarios
28
27
29−from testtools.matchers._basic import Equals
30
28
31class SystemIntegrationTests(UnityTestCase):
29class SystemIntegrationTests(UnityTestCase):
32
30
33 scenarios = _get_device_emulation_scenarios()
31 scenarios = _get_device_emulation_scenarios()
34
32
33+ @unittest.skipIf(
34+ platform.model() == "Desktop",
35− @unittest.skipIf(platform.model() == "Desktop", "Test is broken on otto, see bug 1281634.")
35+ "Test is broken on otto, see bug 1281634.")
36 def test_networkmanager_integration(self):
36 def test_networkmanager_integration(self):
37 self.launch_unity()
37 self.launch_unity()
38
38
39 # invoke policykit to check permissions
39 # invoke policykit to check permissions
40+ pid = subprocess.check_output(
40− pid = subprocess.check_output(["pidof", "-s", "unity8"], universal_newlines=True)
41+ ["pidof", "-s", "unity8"], universal_newlines=True)
42+ subprocess.check_call(
43+ "pkcheck --action-id "
41− subprocess.check_call("pkcheck --action-id org.freedesktop.NetworkManager.enable-disable-network --process " + pid, shell=True)
44+ "org.freedesktop.NetworkManager.enable-disable-network "
45+ "--process " + pid,
46+ shell=True)
tests/autopilot/unity8/shell/tests/test_upstart.py+20−11
@@ -1,7 +1,7 @@
1# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
1# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2#
2#
3# Unity Autopilot Test Suite
3# Unity Autopilot Test Suite
4−# Copyright (C) 2013 Canonical
4+# Copyright (C) 2013, 2014 Canonical
5#
5#
6# This program is free software: you can redistribute it and/or modify
6# This program is free software: you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
7# it under the terms of the GNU General Public License as published by
@@ -42,19 +42,24 @@ import sys
42if sys.version_info < (3,):
42if sys.version_info < (3,):
43 range = xrange
43 range = xrange
44
44
45+
45class UpstartIntegrationTests(UnityTestCase):
46class UpstartIntegrationTests(UnityTestCase):
46
47
47 scenarios = _get_device_emulation_scenarios()
48 scenarios = _get_device_emulation_scenarios()
48
49
49 def _get_status(self):
50 def _get_status(self):
51+ pid, status = os.waitpid(
50− pid, status = os.waitpid(self.process.pid, os.WUNTRACED | os.WCONTINUED | os.WNOHANG)
52+ self.process.pid, os.WUNTRACED | os.WCONTINUED | os.WNOHANG)
53+ logger.debug(
51− logger.debug("Got status: {0}; stopped: {1}; continued: {2}"\
54+ "Got status: {0}; stopped: {1}; continued: {2}".format(
52− .format(status, os.WIFSTOPPED(status), os.WIFCONTINUED(status)))
55+ status, os.WIFSTOPPED(status), os.WIFCONTINUED(status)))
53 return status
56 return status
54
57
55 def _launch_unity(self):
58 def _launch_unity(self):
56 self.patch_environment("QT_LOAD_TESTABILITY", "1")
59 self.patch_environment("QT_LOAD_TESTABILITY", "1")
60+ self.process = subprocess.Popen(
57− self.process = subprocess.Popen([get_binary_path()] + self.unity_geometry_args)
61+ [get_binary_path()] + self.unity_geometry_args)
62+
58 def ensure_stopped():
63 def ensure_stopped():
59 self.process.terminate()
64 self.process.terminate()
60 for i in range(10):
65 for i in range(10):
@@ -76,10 +81,10 @@ class UpstartIntegrationTests(UnityTestCase):
76 self.addCleanup(ensure_stopped)
81 self.addCleanup(ensure_stopped)
77
82
78 def _set_proxy(self):
83 def _set_proxy(self):
79− super(UpstartIntegrationTests, self)._set_proxy(get_proxy_object_for_existing_process(
84+ super(UpstartIntegrationTests, self)._set_proxy(
85+ get_proxy_object_for_existing_process(
80− pid=self.process.pid,
86+ pid=self.process.pid,
81− emulator_base=UnityEmulatorBase,
87+ emulator_base=UnityEmulatorBase,))
82− ))
83
88
84 def test_no_sigstop(self):
89 def test_no_sigstop(self):
85 self.patch_environment("UNITY_MIR_EMITS_SIGSTOP", "")
90 self.patch_environment("UNITY_MIR_EMITS_SIGSTOP", "")
@@ -93,10 +98,14 @@ class UpstartIntegrationTests(UnityTestCase):
93 def test_expect_sigstop(self):
98 def test_expect_sigstop(self):
94 self.patch_environment("UNITY_MIR_EMITS_SIGSTOP", "1")
99 self.patch_environment("UNITY_MIR_EMITS_SIGSTOP", "1")
95 self._launch_unity()
100 self._launch_unity()
101+ self.assertThat(
102+ lambda: os.WIFSTOPPED(self._get_status()),
96− self.assertThat(lambda: os.WIFSTOPPED(self._get_status()), Eventually(Equals(True)), "Unity8 should raise SIGSTOP when ready")
103+ Eventually(Equals(True)), "Unity8 should raise SIGSTOP when ready")
97
104
98 self.process.send_signal(signal.SIGCONT)
105 self.process.send_signal(signal.SIGCONT)
106+ self.assertThat(
107+ lambda: os.WIFCONTINUED(self._get_status()),
99− self.assertThat(lambda: os.WIFCONTINUED(self._get_status()), Eventually(Equals(True)), "Unity8 should have resumed")
108+ Eventually(Equals(True)), "Unity8 should have resumed")
100
109
101 logger.debug("Unity started, waiting for it to be ready.")
110 logger.debug("Unity started, waiting for it to be ready.")
102 self._set_proxy()
111 self._set_proxy()
tests/mocks/AccountsService/AccountsService.cpp+3−1
@@ -18,9 +18,11 @@
18
18
19#include "AccountsService.h"
19#include "AccountsService.h"
20
20
21+#include <paths.h>
22+
21AccountsService::AccountsService(QObject* parent)
23AccountsService::AccountsService(QObject* parent)
22 : QObject(parent),
24 : QObject(parent),
23− m_backgroundFile(TOP_SRCDIR "/qml/graphics/phone_background.jpg"),
25+ m_backgroundFile(qmlDirectory() + "graphics/phone_background.jpg"),
24 m_statsWelcomeScreen(true)
26 m_statsWelcomeScreen(true)
25{
27{
26}
28}
tests/mocks/AccountsService/AccountsService.qmltypesnew file+22
@@ -0,0 +1,22 @@
1+import QtQuick.tooling 1.1
2+
3+// This file describes the plugin-supplied types contained in the library.
4+// It is used for QML tooling purposes only.
5+//
6+// This file was auto-generated by:
7+// 'qmlplugindump -notrelocatable AccountsService 0.1 tests/mocks'
8+
9+Module {
10+ Component {
11+ name: "AccountsService"
12+ prototype: "QObject"
13+ exports: ["AccountsService/AccountsService 0.1"]
14+ isCreatable: false
15+ isSingleton: true
16+ exportMetaObjectRevisions: [0]
17+ Property { name: "user"; type: "string" }
18+ Property { name: "demoEdges"; type: "bool" }
19+ Property { name: "backgroundFile"; type: "string" }
20+ Property { name: "statsWelcomeScreen"; type: "bool" }
21+ }
22+}
tests/mocks/AccountsService/CMakeLists.txt−2
@@ -1,5 +1,3 @@
1−add_definitions(-DTOP_SRCDIR="${CMAKE_SOURCE_DIR}")
2−
3add_library(MockAccountsService-qml MODULE
1add_library(MockAccountsService-qml MODULE
4 AccountsService.cpp
2 AccountsService.cpp
5 plugin.cpp
3 plugin.cpp
tests/mocks/GSettings.1.0/GSettings.qmltypesnew file+42
@@ -0,0 +1,42 @@
1+import QtQuick.tooling 1.1
2+
3+// This file describes the plugin-supplied types contained in the library.
4+// It is used for QML tooling purposes only.
5+//
6+// This file was auto-generated by:
7+// 'qmlplugindump -notrelocatable GSettings 1.0 tests/mocks'
8+
9+Module {
10+ Component {
11+ name: "GSettingsControllerQml"
12+ prototype: "QObject"
13+ exports: ["GSettings/GSettingsController 1.0"]
14+ isCreatable: false
15+ isSingleton: true
16+ exportMetaObjectRevisions: [0]
17+ Method {
18+ name: "setPictureUri"
19+ Parameter { name: "str"; type: "string" }
20+ }
21+ }
22+ Component {
23+ name: "GSettingsQml"
24+ prototype: "QObject"
25+ exports: ["GSettings/GSettings 1.0"]
26+ exportMetaObjectRevisions: [0]
27+ Property { name: "schema"; type: "GSettingsSchemaQml"; isReadonly: true; isPointer: true }
28+ Property { name: "pictureUri"; type: "string" }
29+ Signal {
30+ name: "pictureUriChanged"
31+ Parameter { type: "string" }
32+ }
33+ }
34+ Component {
35+ name: "GSettingsSchemaQml"
36+ prototype: "QObject"
37+ exports: ["GSettings/GSettingsSchema 1.0"]
38+ isCreatable: false
39+ exportMetaObjectRevisions: [0]
40+ Property { name: "id"; type: "QByteArray" }
41+ }
42+}
tests/mocks/HudClient/HudClient.qmltypesnew file+113
@@ -0,0 +1,113 @@
1+import QtQuick.tooling 1.1
2+
3+// This file describes the plugin-supplied types contained in the library.
4+// It is used for QML tooling purposes only.
5+//
6+// This file was auto-generated by:
7+// 'qmlplugindump -notrelocatable HudClient 0.1 tests/mocks'
8+
9+Module {
10+ Component {
11+ name: "DeeListModel"
12+ prototype: "QAbstractListModel"
13+ Property { name: "name"; type: "string" }
14+ Property { name: "synchronized"; type: "bool"; isReadonly: true }
15+ Property { name: "count"; type: "int"; isReadonly: true }
16+ Signal {
17+ name: "nameChanged"
18+ Parameter { type: "string" }
19+ }
20+ Signal {
21+ name: "synchronizedChanged"
22+ Parameter { type: "bool" }
23+ }
24+ Signal {
25+ name: "roleNamesChanged"
26+ Parameter { type: "QHash<int,QByteArray>" }
27+ }
28+ Method {
29+ name: "get"
30+ type: "QVariantMap"
31+ Parameter { name: "row"; type: "int" }
32+ }
33+ Method { name: "count"; type: "int" }
34+ }
35+ Component {
36+ name: "HudClient"
37+ prototype: "QObject"
38+ exports: ["HudClient/HudClient 0.1"]
39+ exportMetaObjectRevisions: [0]
40+ Property { name: "results"; type: "DeeListModel"; isReadonly: true; isPointer: true }
41+ Property { name: "toolBarModel"; type: "QAbstractItemModel"; isReadonly: true; isPointer: true }
42+ Signal { name: "voiceQueryLoading" }
43+ Signal { name: "voiceQueryListening" }
44+ Signal { name: "voiceQueryHeardSomething" }
45+ Signal { name: "voiceQueryFailed" }
46+ Signal {
47+ name: "voiceQueryFinished"
48+ Parameter { name: "query"; type: "string" }
49+ }
50+ Signal { name: "commandExecuted" }
51+ Signal {
52+ name: "showParametrizedAction"
53+ Parameter { name: "action"; type: "string" }
54+ Parameter { name: "items"; type: "QVariant" }
55+ }
56+ Method {
57+ name: "executeCommand"
58+ Parameter { name: "index"; type: "int" }
59+ }
60+ Method {
61+ name: "setQuery"
62+ Parameter { name: "new_query"; type: "string" }
63+ }
64+ Method { name: "startVoiceQuery" }
65+ Method {
66+ name: "executeParametrizedAction"
67+ Parameter { name: "values"; type: "QVariant" }
68+ }
69+ Method {
70+ name: "updateParametrizedAction"
71+ Parameter { name: "values"; type: "QVariant" }
72+ }
73+ Method { name: "cancelParametrizedAction" }
74+ Method {
75+ name: "executeToolBarAction"
76+ Parameter { name: "action"; type: "HudClientQueryToolbarItems" }
77+ }
78+ }
79+ Component {
80+ name: "HudClientStub"
81+ prototype: "QObject"
82+ exports: ["HudClient/HudClientStub 0.1"]
83+ exportMetaObjectRevisions: [0]
84+ Property { name: "lastExecutedToolbarItem"; type: "int"; isReadonly: true }
85+ Property { name: "lastSetQuery"; type: "string"; isReadonly: true }
86+ Property { name: "lastExecutedCommandRow"; type: "int"; isReadonly: true }
87+ Property { name: "lastExecutedParametrizedCommandRow"; type: "int"; isReadonly: true }
88+ Property { name: "lastParametrizedCommandCommited"; type: "bool"; isReadonly: true }
89+ Property { name: "activatedActions"; type: "QVariantMap"; isReadonly: true }
90+ Method { name: "reset" }
91+ Method { name: "fullScreenToolbarItemValue"; type: "int" }
92+ Method { name: "helpToolbarItemValue"; type: "int" }
93+ Method { name: "preferencesToolbarItemValue"; type: "int" }
94+ Method { name: "undoToolbarItemValue"; type: "int" }
95+ Method {
96+ name: "setHelpToolbarItemEnabled"
97+ Parameter { name: "enabled"; type: "bool" }
98+ }
99+ }
100+ Component { name: "HudToolBarModel"; prototype: "QAbstractListModel" }
101+ Component {
102+ name: "VolumePeakDetector"
103+ prototype: "QObject"
104+ exports: ["HudClient/VolumePeakDetector 0.1"]
105+ exportMetaObjectRevisions: [0]
106+ Property { name: "enabled"; type: "bool" }
107+ Property { name: "desiredInterval"; type: "int" }
108+ Signal {
109+ name: "newPeak"
110+ Parameter { name: "volume"; type: "float" }
111+ }
112+ }
113+}
tests/mocks/LightDM/LightDM.qmltypesnew file+241
@@ -0,0 +1,241 @@
1+import QtQuick.tooling 1.1
2+
3+// This file describes the plugin-supplied types contained in the library.
4+// It is used for QML tooling purposes only.
5+//
6+// This file was auto-generated by:
7+// 'qmlplugindump -notrelocatable LightDM 0.1 tests/mocks'
8+
9+Module {
10+ Component {
11+ name: "Greeter"
12+ prototype: "QObject"
13+ exports: ["LightDM/Greeter 0.1"]
14+ isCreatable: false
15+ isSingleton: true
16+ exportMetaObjectRevisions: [0]
17+ Property { name: "authenticated"; type: "bool"; isReadonly: true }
18+ Property { name: "authenticationUser"; type: "string"; isReadonly: true }
19+ Property { name: "promptless"; type: "bool"; isReadonly: true }
20+ Signal {
21+ name: "showMessage"
22+ Parameter { name: "text"; type: "string" }
23+ Parameter { name: "isError"; type: "bool" }
24+ }
25+ Signal {
26+ name: "showPrompt"
27+ Parameter { name: "text"; type: "string" }
28+ Parameter { name: "isSecret"; type: "bool" }
29+ }
30+ Signal { name: "authenticationComplete" }
31+ Signal {
32+ name: "authenticationUserChanged"
33+ Parameter { name: "user"; type: "string" }
34+ }
35+ Signal {
36+ name: "requestAuthenticationUser"
37+ Parameter { name: "user"; type: "string" }
38+ }
39+ Method {
40+ name: "authenticate"
41+ Parameter { name: "username"; type: "string" }
42+ }
43+ Method { name: "authenticate" }
44+ Method {
45+ name: "respond"
46+ Parameter { name: "response"; type: "string" }
47+ }
48+ Method {
49+ name: "startSessionSync"
50+ type: "bool"
51+ Parameter { name: "session"; type: "string" }
52+ }
53+ Method { name: "startSessionSync"; type: "bool" }
54+ }
55+ Component {
56+ name: "QAbstractProxyModel"
57+ prototype: "QAbstractItemModel"
58+ Property { name: "sourceModel"; type: "QAbstractItemModel"; isPointer: true }
59+ }
60+ Component {
61+ name: "QLightDM::UsersModel"
62+ prototype: "QAbstractListModel"
63+ exports: ["LightDM/UserRoles 0.1"]
64+ isCreatable: false
65+ exportMetaObjectRevisions: [0]
66+ Enum {
67+ name: "UserModelRoles"
68+ values: {
69+ "NameRole": 256,
70+ "RealNameRole": 257,
71+ "LoggedInRole": 258,
72+ "BackgroundRole": 259,
73+ "SessionRole": 260,
74+ "HasMessagesRole": 261,
75+ "ImagePathRole": 262,
76+ "BackgroundPathRole": 263
77+ }
78+ }
79+ }
80+ Component {
81+ name: "QSortFilterProxyModel"
82+ prototype: "QAbstractProxyModel"
83+ Property { name: "filterRegExp"; type: "QRegExp" }
84+ Property { name: "filterKeyColumn"; type: "int" }
85+ Property { name: "dynamicSortFilter"; type: "bool" }
86+ Property { name: "filterCaseSensitivity"; type: "Qt::CaseSensitivity" }
87+ Property { name: "sortCaseSensitivity"; type: "Qt::CaseSensitivity" }
88+ Property { name: "isSortLocaleAware"; type: "bool" }
89+ Property { name: "sortRole"; type: "int" }
90+ Property { name: "filterRole"; type: "int" }
91+ Method {
92+ name: "setFilterRegExp"
93+ Parameter { name: "pattern"; type: "string" }
94+ }
95+ Method {
96+ name: "setFilterWildcard"
97+ Parameter { name: "pattern"; type: "string" }
98+ }
99+ Method {
100+ name: "setFilterFixedString"
101+ Parameter { name: "pattern"; type: "string" }
102+ }
103+ Method { name: "clear" }
104+ Method { name: "invalidate" }
105+ }
106+ Component {
107+ name: "QSortFilterProxyModelQML"
108+ prototype: "QSortFilterProxyModel"
109+ Property { name: "model"; type: "QAbstractItemModel"; isPointer: true }
110+ Property { name: "totalCount"; type: "int"; isReadonly: true }
111+ Property { name: "count"; type: "int"; isReadonly: true }
112+ Property { name: "invertMatch"; type: "bool" }
113+ Signal {
114+ name: "invertMatchChanged"
115+ Parameter { type: "bool" }
116+ }
117+ Method {
118+ name: "get"
119+ type: "QVariantMap"
120+ Parameter { name: "row"; type: "int" }
121+ }
122+ Method {
123+ name: "data"
124+ type: "QVariant"
125+ Parameter { name: "row"; type: "int" }
126+ Parameter { name: "role"; type: "int" }
127+ }
128+ Method { name: "count"; type: "int" }
129+ Method {
130+ name: "findFirst"
131+ type: "int"
132+ Parameter { name: "role"; type: "int" }
133+ Parameter { name: "value"; type: "QVariant" }
134+ }
135+ Method {
136+ name: "mapRowToSource"
137+ type: "int"
138+ Parameter { name: "row"; type: "int" }
139+ }
140+ Method {
141+ name: "mapFromSource"
142+ type: "int"
143+ Parameter { name: "row"; type: "int" }
144+ }
145+ Method {
146+ name: "mapToSource"
147+ type: "int"
148+ Parameter { name: "row"; type: "int" }
149+ }
150+ }
151+ Component {
152+ name: "UserMetricsOutput::ColorTheme"
153+ prototype: "QObject"
154+ Property { name: "start"; type: "QColor"; isReadonly: true }
155+ Property { name: "main"; type: "QColor"; isReadonly: true }
156+ Property { name: "end"; type: "QColor"; isReadonly: true }
157+ Signal {
158+ name: "startChanged"
159+ Parameter { name: "color"; type: "QColor" }
160+ }
161+ Signal {
162+ name: "mainChanged"
163+ Parameter { name: "color"; type: "QColor" }
164+ }
165+ Signal {
166+ name: "endChanged"
167+ Parameter { name: "color"; type: "QColor" }
168+ }
169+ }
170+ Component {
171+ name: "UserMetricsOutput::UserMetrics"
172+ prototype: "QObject"
173+ exports: ["LightDM/Infographic 0.1"]
174+ isCreatable: false
175+ isSingleton: true
176+ exportMetaObjectRevisions: [0]
177+ Property { name: "label"; type: "string"; isReadonly: true }
178+ Property { name: "username"; type: "string" }
179+ Property {
180+ name: "firstColor"
181+ type: "UserMetricsOutput::ColorTheme"
182+ isReadonly: true
183+ isPointer: true
184+ }
185+ Property {
186+ name: "secondColor"
187+ type: "UserMetricsOutput::ColorTheme"
188+ isReadonly: true
189+ isPointer: true
190+ }
191+ Property { name: "firstMonth"; type: "QAbstractItemModel"; isReadonly: true; isPointer: true }
192+ Property { name: "secondMonth"; type: "QAbstractItemModel"; isReadonly: true; isPointer: true }
193+ Property { name: "currentDay"; type: "int"; isReadonly: true }
194+ Signal {
195+ name: "labelChanged"
196+ Parameter { name: "label"; type: "string" }
197+ }
198+ Signal {
199+ name: "usernameChanged"
200+ Parameter { name: "username"; type: "string" }
201+ }
202+ Signal {
203+ name: "firstColorChanged"
204+ Parameter { name: "color"; type: "ColorTheme"; isPointer: true }
205+ }
206+ Signal {
207+ name: "firstMonthChanged"
208+ Parameter { name: "firstMonth"; type: "QAbstractItemModel"; isPointer: true }
209+ }
210+ Signal {
211+ name: "currentDayChanged"
212+ Parameter { name: "currentDay"; type: "int" }
213+ }
214+ Signal {
215+ name: "secondColorChanged"
216+ Parameter { name: "color"; type: "ColorTheme"; isPointer: true }
217+ }
218+ Signal {
219+ name: "secondMonthChanged"
220+ Parameter { name: "secondMonth"; type: "QAbstractItemModel"; isPointer: true }
221+ }
222+ Signal { name: "nextDataSource" }
223+ Signal { name: "readyForDataChange" }
224+ Signal { name: "dataAboutToAppear" }
225+ Signal { name: "dataAppeared" }
226+ Signal { name: "dataAboutToChange" }
227+ Signal { name: "dataChanged" }
228+ Signal { name: "dataAboutToDisappear" }
229+ Signal { name: "dataDisappeared" }
230+ Method { name: "nextDataSourceSlot" }
231+ Method { name: "readyForDataChangeSlot" }
232+ }
233+ Component {
234+ name: "UsersModel"
235+ prototype: "QSortFilterProxyModelQML"
236+ exports: ["LightDM/Users 0.1"]
237+ isCreatable: false
238+ isSingleton: true
239+ exportMetaObjectRevisions: [0]
240+ }
241+}
tests/mocks/Powerd/Powerd.h+7−7
@@ -25,15 +25,15 @@ class Powerd: public QObject
25{
25{
26 Q_OBJECT
26 Q_OBJECT
27 Q_ENUMS(Status)
27 Q_ENUMS(Status)
28− Q_FLAGS(DisplayFlag DisplayFlags)
28+ Q_ENUMS(DisplayStateChangeReason)
29
29
30public:
30public:
31− enum DisplayFlag {
31+ enum DisplayStateChangeReason {
32− UseProximity = 1, // Use proximity sensor to override screen state
32+ Unknown = 0,
33− DisableAutoBrightness = 2, // Force autobrightness to be disabled
33+ Inactivity = 1, // Display changed state due to inactivity
34− Bright = 4, // Request the screen to stay bright
34+ PowerKey = 2, // Display changed state due to user pressing power key
35+ Proximity = 3, // Display changed state due to proximity events
35 };
36 };
36− Q_DECLARE_FLAGS(DisplayFlags, DisplayFlag)
37
37
38 enum Status {
38 enum Status {
39 Off,
39 Off,
@@ -43,7 +43,7 @@ public:
43 explicit Powerd(QObject *parent = 0);
43 explicit Powerd(QObject *parent = 0);
44
44
45Q_SIGNALS:
45Q_SIGNALS:
46− void displayPowerStateChange(int status, unsigned int flags);
46+ void displayPowerStateChange(int status, int reason);
47};
47};
48
48
49#endif
49#endif
tests/mocks/Powerd/Powerd.qmltypesnew file+46
@@ -0,0 +1,46 @@
1+import QtQuick.tooling 1.1
2+
3+// This file describes the plugin-supplied types contained in the library.
4+// It is used for QML tooling purposes only.
5+//
6+// This file was auto-generated by:
7+// 'qmlplugindump -notrelocatable Powerd 0.1 tests/mocks'
8+
9+Module {
10+ Component {
11+ name: "Powerd"
12+ prototype: "QObject"
13+ exports: ["Powerd/Powerd 0.1"]
14+ isCreatable: false
15+ isSingleton: true
16+ exportMetaObjectRevisions: [0]
17+ Enum {
18+ name: "DisplayFlag"
19+ values: {
20+ "UseProximity": 1,
21+ "DisableAutoBrightness": 2,
22+ "Bright": 4
23+ }
24+ }
25+ Enum {
26+ name: "DisplayFlags"
27+ values: {
28+ "UseProximity": 1,
29+ "DisableAutoBrightness": 2,
30+ "Bright": 4
31+ }
32+ }
33+ Enum {
34+ name: "Status"
35+ values: {
36+ "Off": 0,
37+ "On": 1
38+ }
39+ }
40+ Signal {
41+ name: "displayPowerStateChange"
42+ Parameter { name: "status"; type: "int" }
43+ Parameter { name: "flags"; type: "uint" }
44+ }
45+ }
46+}
tests/mocks/QMenuModel/QMenuModel.qmltypesnew file+77
@@ -0,0 +1,77 @@
1+import QtQuick.tooling 1.1
2+
3+// This file describes the plugin-supplied types contained in the library.
4+// It is used for QML tooling purposes only.
5+//
6+// This file was auto-generated by:
7+// 'qmlplugindump -notrelocatable QMenuModel 0.1 tests/mocks'
8+
9+Module {
10+ Component {
11+ name: "ActionStateParser"
12+ prototype: "QObject"
13+ exports: ["QMenuModel/ActionStateParser 0.1"]
14+ exportMetaObjectRevisions: [0]
15+ }
16+ Component {
17+ name: "UnityMenuModel"
18+ prototype: "QAbstractListModel"
19+ exports: ["QMenuModel/UnityMenuModel 0.1"]
20+ exportMetaObjectRevisions: [0]
21+ Property { name: "modelData"; type: "QVariant" }
22+ Property { name: "busName"; type: "QByteArray" }
23+ Property { name: "actions"; type: "QVariantMap" }
24+ Property { name: "menuObjectPath"; type: "QByteArray" }
25+ Property { name: "actionStateParser"; type: "ActionStateParser"; isPointer: true }
26+ Method {
27+ name: "insertRow"
28+ Parameter { name: "row"; type: "int" }
29+ Parameter { name: "data"; type: "QVariant" }
30+ }
31+ Method {
32+ name: "appendRow"
33+ Parameter { name: "data"; type: "QVariant" }
34+ }
35+ Method {
36+ name: "removeRow"
37+ Parameter { name: "row"; type: "int" }
38+ }
39+ Method {
40+ name: "submenu"
41+ type: "QObject*"
42+ Parameter { name: "position"; type: "int" }
43+ Parameter { name: "actionStateParser"; type: "QQmlComponent"; isPointer: true }
44+ }
45+ Method {
46+ name: "submenu"
47+ type: "QObject*"
48+ Parameter { name: "position"; type: "int" }
49+ }
50+ Method {
51+ name: "loadExtendedAttributes"
52+ type: "bool"
53+ Parameter { name: "position"; type: "int" }
54+ Parameter { name: "schema"; type: "QVariantMap" }
55+ }
56+ Method {
57+ name: "get"
58+ type: "QVariant"
59+ Parameter { name: "row"; type: "int" }
60+ Parameter { name: "role"; type: "QByteArray" }
61+ }
62+ Method {
63+ name: "activate"
64+ Parameter { name: "index"; type: "int" }
65+ Parameter { name: "parameter"; type: "QVariant" }
66+ }
67+ Method {
68+ name: "activate"
69+ Parameter { name: "index"; type: "int" }
70+ }
71+ Method {
72+ name: "changeState"
73+ Parameter { name: "index"; type: "int" }
74+ Parameter { name: "parameter"; type: "QVariant" }
75+ }
76+ }
77+}
tests/mocks/QtMultimedia/QtMultimedia.qmltypesnew file+52
@@ -0,0 +1,52 @@
1+import QtQuick.tooling 1.1
2+
3+// This file describes the plugin-supplied types contained in the library.
4+// It is used for QML tooling purposes only.
5+//
6+// This file was auto-generated by:
7+// 'qmlplugindump -notrelocatable QtMultimedia 5.0 tests/mocks'
8+
9+Module {
10+ Component {
11+ name: "Audio"
12+ prototype: "QObject"
13+ exports: ["QtMultimedia/Audio 5.0"]
14+ exportMetaObjectRevisions: [0]
15+ Enum {
16+ name: "PlaybackState"
17+ values: {
18+ "PlayingState": 0,
19+ "PausedState": 1,
20+ "StoppedState": 2
21+ }
22+ }
23+ Property { name: "source"; type: "QUrl" }
24+ Property { name: "playbackState"; type: "PlaybackState"; isReadonly: true }
25+ Property { name: "position"; type: "int"; isReadonly: true }
26+ Property { name: "duration"; type: "int"; isReadonly: true }
27+ Property { name: "errorString"; type: "string"; isReadonly: true }
28+ Signal {
29+ name: "sourceChanged"
30+ Parameter { name: "source"; type: "QUrl" }
31+ }
32+ Signal {
33+ name: "playbackStateChanged"
34+ Parameter { name: "playbackState"; type: "PlaybackState" }
35+ }
36+ Signal {
37+ name: "positionChanged"
38+ Parameter { name: "position"; type: "int" }
39+ }
40+ Signal {
41+ name: "durationChanged"
42+ Parameter { name: "duration"; type: "int" }
43+ }
44+ Signal {
45+ name: "errorStringChanged"
46+ Parameter { name: "errorString"; type: "string" }
47+ }
48+ Method { name: "pause" }
49+ Method { name: "play" }
50+ Method { name: "stop" }
51+ }
52+}
tests/mocks/Ubuntu/CMakeLists.txt+1
@@ -1,2 +1,3 @@
1add_subdirectory(DownloadDaemonListener)
1add_subdirectory(DownloadDaemonListener)
2+add_subdirectory(Payments)
2add_subdirectory(Thumbnailer)
3add_subdirectory(Thumbnailer)
tests/mocks/Ubuntu/DownloadDaemonListener/DownloadDaemonListener.qmltypesnew file+60
@@ -0,0 +1,60 @@
1+import QtQuick.tooling 1.1
2+
3+// This file describes the plugin-supplied types contained in the library.
4+// It is used for QML tooling purposes only.
5+//
6+// This file was auto-generated by:
7+// 'qmlplugindump -notrelocatable Ubuntu.DownloadDaemonListener 0.1 tests/mocks'
8+
9+Module {
10+ Component {
11+ name: "MockDownloadTracker"
12+ prototype: "QObject"
13+ exports: ["Ubuntu.DownloadDaemonListener/DownloadTracker 0.1"]
14+ exportMetaObjectRevisions: [0]
15+ Property { name: "service"; type: "string" }
16+ Property { name: "dbusPath"; type: "string" }
17+ Property { name: "serviceReady"; type: "bool"; isReadonly: true }
18+ Signal {
19+ name: "serviceChanged"
20+ Parameter { name: "service"; type: "string" }
21+ }
22+ Signal {
23+ name: "dbusPathChanged"
24+ Parameter { name: "dbusPath"; type: "string" }
25+ }
26+ Signal {
27+ name: "serviceReadyChanged"
28+ Parameter { name: "serviceReady"; type: "bool" }
29+ }
30+ Signal {
31+ name: "canceled"
32+ Parameter { name: "success"; type: "bool" }
33+ }
34+ Signal {
35+ name: "error"
36+ Parameter { name: "error"; type: "string" }
37+ }
38+ Signal {
39+ name: "finished"
40+ Parameter { name: "path"; type: "string" }
41+ }
42+ Signal {
43+ name: "paused"
44+ Parameter { name: "success"; type: "bool" }
45+ }
46+ Signal {
47+ name: "progress"
48+ Parameter { name: "received"; type: "qulonglong" }
49+ Parameter { name: "total"; type: "qulonglong" }
50+ }
51+ Signal {
52+ name: "resumed"
53+ Parameter { name: "success"; type: "bool" }
54+ }
55+ Signal {
56+ name: "started"
57+ Parameter { name: "success"; type: "bool" }
58+ }
59+ }
60+}
tests/mocks/Ubuntu/Payments/CMakeLists.txtnew file+10
@@ -0,0 +1,10 @@
1+set(FakeUbuntuPaymentsQml_SOURCES
2+ plugin.cpp
3+ MockPayments.cpp
4+ )
5+
6+add_library(FakeUbuntuPaymentsQml MODULE ${FakeUbuntuPaymentsQml_SOURCES})
7+
8+qt5_use_modules(FakeUbuntuPaymentsQml Qml Quick Core)
9+
10+add_unity8_mock(Ubuntu.Payments 0.1 Ubuntu/Payments TARGETS FakeUbuntuPaymentsQml)
tests/mocks/Ubuntu/Payments/MockPayments.cppnew file+89
@@ -0,0 +1,89 @@
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 "MockPayments.h"
18+
19+#include <QLocale>
20+
21+
22+MockPayments::MockPayments(QObject *parent)
23+ : QObject(parent)
24+{
25+}
26+
27+QString MockPayments::currency() const
28+{
29+ return m_currency;
30+}
31+
32+double MockPayments::price() const
33+{
34+ return m_price;
35+}
36+
37+QString MockPayments::storeItemId() const
38+{
39+ return m_store_item_id;
40+}
41+
42+QString MockPayments::formattedPrice() const
43+{
44+ QLocale locale;
45+ return locale.toCurrencyString(m_price, m_currency);
46+}
47+
48+void MockPayments::setCurrency(const QString &currency)
49+{
50+ if(m_currency != currency) {
51+ m_currency = currency;
52+ Q_EMIT currencyChanged(currency);
53+ Q_EMIT formattedPriceChanged(formattedPrice());
54+ }
55+}
56+
57+void MockPayments::setPrice(const double price)
58+{
59+ if(m_price != price) {
60+ m_price = price;
61+ Q_EMIT priceChanged(price);
62+ Q_EMIT formattedPriceChanged(formattedPrice());
63+ }
64+}
65+
66+void MockPayments::setStoreItemId(const QString &store_item_id)
67+{
68+ if (m_store_item_id != store_item_id) {
69+ m_store_item_id = store_item_id;
70+ Q_EMIT storeItemIdChanged(m_store_item_id);
71+ }
72+
73+ if (m_store_item_id.isEmpty()) {
74+ return;
75+ }
76+}
77+
78+void MockPayments::start()
79+{
80+ if (!m_store_item_id.isEmpty()) {
81+ if (m_store_item_id == "com.example.invalid") {
82+ Q_EMIT purchaseError("Purchase failed.");
83+ } else {
84+ Q_EMIT purchaseCompleted();
85+ }
86+ } else {
87+ Q_EMIT purchaseError("No item ID supplied.");
88+ }
89+}
tests/mocks/Ubuntu/Payments/MockPayments.hnew file+60
@@ -0,0 +1,60 @@
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+#ifndef MOCK_PAYMENTS_H
18+#define MOCK_PAYMENTS_H
19+
20+#include <QObject>
21+
22+
23+class MockPayments : public QObject
24+{
25+ Q_OBJECT
26+ Q_DISABLE_COPY(MockPayments)
27+ Q_PROPERTY(QString currency READ currency WRITE setCurrency NOTIFY currencyChanged)
28+ Q_PROPERTY(double price READ price WRITE setPrice NOTIFY priceChanged)
29+ Q_PROPERTY(QString storeItemId READ storeItemId WRITE setStoreItemId NOTIFY storeItemIdChanged)
30+ Q_PROPERTY(QString formattedPrice READ formattedPrice NOTIFY formattedPriceChanged)
31+
32+public:
33+ explicit MockPayments(QObject *parent = 0);
34+
35+ QString currency() const;
36+ double price() const;
37+ QString storeItemId() const;
38+ QString formattedPrice() const;
39+
40+ void setCurrency(const QString& currency);
41+ void setPrice(const double price);
42+ void setStoreItemId(const QString& store_item_id);
43+ Q_INVOKABLE void start();
44+
45+Q_SIGNALS:
46+ void currencyChanged(const QString& currency);
47+ void priceChanged(const double price);
48+ void storeItemIdChanged(const QString &store_item_id);
49+ void formattedPriceChanged(const QString &formatted_price);
50+
51+ void purchaseError(const QString &error);
52+ void purchaseCompleted();
53+
54+private:
55+ QString m_currency;
56+ double m_price;
57+ QString m_store_item_id;
58+};
59+
60+#endif // MOCK_PAYMENTS_H
tests/mocks/Ubuntu/Payments/Payments.qmltypesnew file+42
@@ -0,0 +1,42 @@
1+import QtQuick.tooling 1.1
2+
3+// This file describes the plugin-supplied types contained in the library.
4+// It is used for QML tooling purposes only.
5+//
6+// This file was auto-generated by:
7+// 'qmlplugindump -notrelocatable Ubuntu.Payments 0.1 tests/mocks'
8+
9+Module {
10+ Component {
11+ name: "MockPayments"
12+ prototype: "QObject"
13+ exports: ["Ubuntu.Payments/Payments 0.1"]
14+ exportMetaObjectRevisions: [0]
15+ Property { name: "currency"; type: "string" }
16+ Property { name: "price"; type: "double" }
17+ Property { name: "storeItemId"; type: "string" }
18+ Property { name: "formattedPrice"; type: "string"; isReadonly: true }
19+ Signal {
20+ name: "currencyChanged"
21+ Parameter { name: "currency"; type: "string" }
22+ }
23+ Signal {
24+ name: "priceChanged"
25+ Parameter { name: "price"; type: "double" }
26+ }
27+ Signal {
28+ name: "storeItemIdChanged"
29+ Parameter { name: "store_item_id"; type: "string" }
30+ }
31+ Signal {
32+ name: "formattedPriceChanged"
33+ Parameter { name: "formatted_price"; type: "string" }
34+ }
35+ Signal {
36+ name: "purchaseError"
37+ Parameter { name: "error"; type: "string" }
38+ }
39+ Signal { name: "purchaseCompleted" }
40+ Method { name: "start" }
41+ }
42+}
tests/mocks/Ubuntu/Payments/plugin.cppnew file+28
@@ -0,0 +1,28 @@
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 "plugin.h"
18+#include "MockPayments.h"
19+
20+#include <QtQml>
21+
22+
23+void BackendPlugin::registerTypes(const char *uri)
24+{
25+ Q_ASSERT(uri == QLatin1String("Ubuntu.Payments"));
26+
27+ qmlRegisterType<MockPayments>(uri, 0, 1, "Payments");
28+}
tests/mocks/Ubuntu/Payments/plugin.hnew file+31
@@ -0,0 +1,31 @@
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+#ifndef PAYMENTS_PLUGIN_H
18+#define PAYMENTS_PLUGIN_H
19+
20+#include <QQmlExtensionPlugin>
21+
22+class BackendPlugin : public QQmlExtensionPlugin
23+{
24+ Q_OBJECT
25+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
26+
27+public:
28+ void registerTypes(const char *uri);
29+};
30+
31+#endif // PAYMENTS_PLUGIN_H
tests/mocks/Ubuntu/Payments/qmldirnew file+3
@@ -0,0 +1,3 @@
1+module Ubuntu.Payments
2+plugin FakeUbuntuPaymentsQml
3+typeinfo Payments.qmltypes
tests/mocks/Ubuntu/Thumbnailer/Thumbnailer.qmltypesnew file+17
@@ -0,0 +1,17 @@
1+import QtQuick.tooling 1.1
2+
3+// This file describes the plugin-supplied types contained in the library.
4+// It is used for QML tooling purposes only.
5+//
6+// This file was auto-generated by:
7+// 'qmlplugindump -notrelocatable Ubuntu.Thumbnailer 0.1 tests/mocks'
8+
9+Module {
10+ Component {
11+ name: "QQmlTypeNotAvailable"
12+ prototype: "QObject"
13+ exports: ["Ubuntu.Thumbnailer/__ThumbnailerIgnoreMe 0.1"]
14+ isCreatable: false
15+ exportMetaObjectRevisions: [0]
16+ }
17+}
tests/mocks/Unity/Application/Application.qmltypesnew file+313
@@ -0,0 +1,313 @@
1+import QtQuick.tooling 1.1
2+
3+// This file describes the plugin-supplied types contained in the library.
4+// It is used for QML tooling purposes only.
5+//
6+// This file was auto-generated by:
7+// 'qmlplugindump -notrelocatable Unity.Application 0.1 tests/mocks'
8+
9+Module {
10+ Component {
11+ name: "ApplicationImage"
12+ defaultProperty: "data"
13+ prototype: "QQuickItem"
14+ exports: ["Unity.Application/ApplicationImage 0.1"]
15+ exportMetaObjectRevisions: [0]
16+ Enum {
17+ name: "FillMode"
18+ values: {
19+ "Stretch": 0,
20+ "PreserveAspectCrop": 1
21+ }
22+ }
23+ Property { name: "source"; type: "ApplicationInfo"; isPointer: true }
24+ Property { name: "fillMode"; type: "FillMode" }
25+ Property { name: "ready"; type: "bool" }
26+ Method { name: "scheduleUpdate" }
27+ Method { name: "updateFromCache" }
28+ }
29+ Component {
30+ name: "ApplicationInfo"
31+ prototype: "unity::shell::application::ApplicationInfoInterface"
32+ exports: ["Unity.Application/ApplicationInfo 0.1"]
33+ exportMetaObjectRevisions: [0]
34+ Property { name: "fullscreen"; type: "bool" }
35+ Property { name: "stage"; type: "Stage" }
36+ Property { name: "imageQml"; type: "string" }
37+ Property { name: "windowQml"; type: "string" }
38+ Signal { name: "appIdChanged" }
39+ Signal { name: "nameChanged" }
40+ Signal { name: "commentChanged" }
41+ Signal { name: "iconChanged" }
42+ Signal { name: "stateChanged" }
43+ Signal { name: "focusedChanged" }
44+ Signal { name: "screenshotChanged" }
45+ }
46+ Component {
47+ name: "ApplicationManager"
48+ prototype: "unity::shell::application::ApplicationManagerInterface"
49+ exports: ["Unity.Application/ApplicationManager 0.1"]
50+ isCreatable: false
51+ isSingleton: true
52+ exportMetaObjectRevisions: [0]
53+ Enum {
54+ name: "Role"
55+ values: {
56+ "Dash": 0,
57+ "Default": 1,
58+ "Indicators": 2,
59+ "Notifications": 3,
60+ "Greeter": 4,
61+ "Launcher": 5,
62+ "OnScreenKeyboard": 6,
63+ "ShutdownDialog": 7
64+ }
65+ }
66+ Enum {
67+ name: "StageHint"
68+ values: {
69+ "MainStage": 0,
70+ "IntegrationStage": 1,
71+ "ShareStage": 2,
72+ "ContentPickingStage": 3,
73+ "SideStage": 4,
74+ "ConfigurationStage": 5
75+ }
76+ }
77+ Enum {
78+ name: "FormFactorHint"
79+ values: {
80+ "DesktopFormFactor": 0,
81+ "PhoneFormFactor": 1,
82+ "TabletFormFactor": 2
83+ }
84+ }
85+ Enum {
86+ name: "FavoriteApplication"
87+ values: {
88+ "CameraApplication": 0,
89+ "GalleryApplication": 1,
90+ "BrowserApplication": 2,
91+ "ShareApplication": 3,
92+ "PhoneApplication": 4,
93+ "DialerApplication": 5,
94+ "MessagingApplication": 6,
95+ "AddressbookApplication": 7
96+ }
97+ }
98+ Enum {
99+ name: "ExecFlags"
100+ values: {
101+ "NoFlag": 0,
102+ "ForceMainStage": 1
103+ }
104+ }
105+ Property { name: "keyboardHeight"; type: "int"; isReadonly: true }
106+ Property { name: "keyboardVisible"; type: "bool"; isReadonly: true }
107+ Property { name: "sideStageWidth"; type: "int"; isReadonly: true }
108+ Property { name: "stageHint"; type: "StageHint"; isReadonly: true }
109+ Property { name: "formFactorHint"; type: "FormFactorHint"; isReadonly: true }
110+ Property { name: "fake"; type: "bool"; isReadonly: true }
111+ Property { name: "rightMargin"; type: "int" }
112+ Signal {
113+ name: "focusRequested"
114+ Parameter { name: "favoriteApplication"; type: "FavoriteApplication" }
115+ }
116+ Signal {
117+ name: "focusRequested"
118+ Parameter { name: "appId"; type: "string" }
119+ }
120+ Method {
121+ name: "get"
122+ type: "ApplicationInfo*"
123+ Parameter { name: "index"; type: "int" }
124+ }
125+ Method {
126+ name: "findApplication"
127+ type: "ApplicationInfo*"
128+ Parameter { name: "appId"; type: "string" }
129+ }
130+ Method {
131+ name: "move"
132+ Parameter { name: "from"; type: "int" }
133+ Parameter { name: "to"; type: "int" }
134+ }
135+ Method {
136+ name: "requestFocusApplication"
137+ type: "bool"
138+ Parameter { name: "appId"; type: "string" }
139+ }
140+ Method {
141+ name: "focusApplication"
142+ type: "bool"
143+ Parameter { name: "appId"; type: "string" }
144+ }
145+ Method { name: "unfocusCurrentApplication" }
146+ Method {
147+ name: "startApplication"
148+ type: "ApplicationInfo*"
149+ Parameter { name: "appId"; type: "string" }
150+ Parameter { name: "arguments"; type: "QStringList" }
151+ }
152+ Method {
153+ name: "startApplication"
154+ type: "ApplicationInfo*"
155+ Parameter { name: "appId"; type: "string" }
156+ }
157+ Method {
158+ name: "startApplication"
159+ type: "ApplicationInfo*"
160+ Parameter { name: "appId"; type: "string" }
161+ Parameter { name: "flags"; type: "ExecFlags" }
162+ Parameter { name: "arguments"; type: "QStringList" }
163+ }
164+ Method {
165+ name: "startApplication"
166+ type: "ApplicationInfo*"
167+ Parameter { name: "appId"; type: "string" }
168+ Parameter { name: "flags"; type: "ExecFlags" }
169+ }
170+ Method {
171+ name: "stopApplication"
172+ type: "bool"
173+ Parameter { name: "appId"; type: "string" }
174+ }
175+ Method {
176+ name: "updateScreenshot"
177+ type: "bool"
178+ Parameter { name: "appId"; type: "string" }
179+ }
180+ Method { name: "availableApplications"; type: "QStringList" }
181+ }
182+ Component {
183+ name: "unity::shell::application::ApplicationInfoInterface"
184+ prototype: "QObject"
185+ exports: ["Unity.Application/ApplicationInfoInterface 0.1"]
186+ isCreatable: false
187+ exportMetaObjectRevisions: [0]
188+ Enum {
189+ name: "Stage"
190+ values: {
191+ "MainStage": 0,
192+ "SideStage": 1
193+ }
194+ }
195+ Enum {
196+ name: "State"
197+ values: {
198+ "Starting": 0,
199+ "Running": 1,
200+ "Suspended": 2,
201+ "Stopped": 3
202+ }
203+ }
204+ Property { name: "appId"; type: "string"; isReadonly: true }
205+ Property { name: "name"; type: "string"; isReadonly: true }
206+ Property { name: "comment"; type: "string"; isReadonly: true }
207+ Property { name: "icon"; type: "QUrl"; isReadonly: true }
208+ Property { name: "stage"; type: "Stage"; isReadonly: true }
209+ Property { name: "state"; type: "State"; isReadonly: true }
210+ Property { name: "focused"; type: "bool"; isReadonly: true }
211+ Property { name: "screenshot"; type: "QUrl"; isReadonly: true }
212+ Signal {
213+ name: "nameChanged"
214+ Parameter { name: "name"; type: "string" }
215+ }
216+ Signal {
217+ name: "commentChanged"
218+ Parameter { name: "comment"; type: "string" }
219+ }
220+ Signal {
221+ name: "iconChanged"
222+ Parameter { name: "icon"; type: "QUrl" }
223+ }
224+ Signal {
225+ name: "stageChanged"
226+ Parameter { name: "stage"; type: "Stage" }
227+ }
228+ Signal {
229+ name: "stateChanged"
230+ Parameter { name: "state"; type: "State" }
231+ }
232+ Signal {
233+ name: "focusedChanged"
234+ Parameter { name: "focused"; type: "bool" }
235+ }
236+ Signal {
237+ name: "screenshotChanged"
238+ Parameter { name: "screenshot"; type: "QUrl" }
239+ }
240+ }
241+ Component {
242+ name: "unity::shell::application::ApplicationManagerInterface"
243+ prototype: "QAbstractListModel"
244+ exports: ["Unity.Application/ApplicationManagerInterface 0.1"]
245+ isCreatable: false
246+ exportMetaObjectRevisions: [0]
247+ Enum {
248+ name: "Roles"
249+ values: {
250+ "RoleAppId": 256,
251+ "RoleName": 257,
252+ "RoleComment": 258,
253+ "RoleIcon": 259,
254+ "RoleStage": 260,
255+ "RoleState": 261,
256+ "RoleFocused": 262,
257+ "RoleScreenshot": 263
258+ }
259+ }
260+ Property { name: "count"; type: "int"; isReadonly: true }
261+ Property { name: "focusedApplicationId"; type: "string"; isReadonly: true }
262+ Property { name: "suspended"; type: "bool" }
263+ Signal {
264+ name: "focusRequested"
265+ Parameter { name: "appId"; type: "string" }
266+ }
267+ Signal {
268+ name: "applicationAdded"
269+ Parameter { name: "appId"; type: "string" }
270+ }
271+ Signal {
272+ name: "applicationRemoved"
273+ Parameter { name: "appId"; type: "string" }
274+ }
275+ Method {
276+ name: "get"
277+ type: "unity::shell::application::ApplicationInfoInterface*"
278+ Parameter { name: "index"; type: "int" }
279+ }
280+ Method {
281+ name: "findApplication"
282+ type: "unity::shell::application::ApplicationInfoInterface*"
283+ Parameter { name: "appId"; type: "string" }
284+ }
285+ Method {
286+ name: "requestFocusApplication"
287+ type: "bool"
288+ Parameter { name: "appId"; type: "string" }
289+ }
290+ Method {
291+ name: "focusApplication"
292+ type: "bool"
293+ Parameter { name: "appId"; type: "string" }
294+ }
295+ Method { name: "unfocusCurrentApplication" }
296+ Method {
297+ name: "startApplication"
298+ type: "unity::shell::application::ApplicationInfoInterface*"
299+ Parameter { name: "appId"; type: "string" }
300+ Parameter { name: "arguments"; type: "QStringList" }
301+ }
302+ Method {
303+ name: "stopApplication"
304+ type: "bool"
305+ Parameter { name: "appId"; type: "string" }
306+ }
307+ Method {
308+ name: "updateScreenshot"
309+ type: "bool"
310+ Parameter { name: "appId"; type: "string" }
311+ }
312+ }
313+}
tests/mocks/Unity/Application/CMakeLists.txt+2−1
@@ -22,4 +22,5 @@ add_unity8_mock(Unity.Application 0.1 Unity/Application PREFIX mocks TARGETS Fak
22add_unity8_mock(Unity.Application 0.1 Unity/Application
22add_unity8_mock(Unity.Application 0.1 Unity/Application
23 PREFIX nonmirplugins
23 PREFIX nonmirplugins
24 TARGETS NonMirUnityApplicationQml
24 TARGETS NonMirUnityApplicationQml
25− BINARY_DIR ${CMAKE_BINARY_DIR}/nonmirplugins)
25+ BINARY_DIR ${CMAKE_BINARY_DIR}/nonmirplugins
26+ NO_TYPES)
tests/mocks/Unity/Indicators/Indicators.qmltypesnew file+210
@@ -0,0 +1,210 @@
1+import QtQuick.tooling 1.1
2+
3+// This file describes the plugin-supplied types contained in the library.
4+// It is used for QML tooling purposes only.
5+//
6+// This file was auto-generated by:
7+// 'qmlplugindump -notrelocatable Unity.Indicators 0.1 tests/mocks'
8+
9+Module {
10+ Component {
11+ name: "ActionState"
12+ prototype: "QObject"
13+ exports: ["Unity.Indicators/ActionState 0.1"]
14+ isCreatable: false
15+ exportMetaObjectRevisions: [0]
16+ Enum {
17+ name: "ActionStates"
18+ values: {
19+ "Label": 0,
20+ "IconSource": 1,
21+ "AccessableName": 2,
22+ "Visible": 3
23+ }
24+ }
25+ }
26+ Component {
27+ name: "FakeIndicatorsModel"
28+ prototype: "QAbstractListModel"
29+ exports: ["Unity.Indicators/FakeIndicatorsModel 0.1"]
30+ exportMetaObjectRevisions: [0]
31+ Property { name: "count"; type: "int"; isReadonly: true }
32+ Method {
33+ name: "load"
34+ Parameter { name: "profile"; type: "string" }
35+ }
36+ Method { name: "unload" }
37+ Method {
38+ name: "append"
39+ Parameter { name: "row"; type: "QVariantMap" }
40+ }
41+ Method {
42+ name: "data"
43+ type: "QVariant"
44+ Parameter { name: "row"; type: "int" }
45+ Parameter { name: "role"; type: "int" }
46+ }
47+ }
48+ Component {
49+ name: "FlatMenuProxyModelRole"
50+ prototype: "QObject"
51+ exports: ["Unity.Indicators/FlatMenuProxyModelRole 0.1"]
52+ isCreatable: false
53+ exportMetaObjectRevisions: [0]
54+ Enum {
55+ name: "Roles"
56+ values: {
57+ "Action": 1,
58+ "Label": 2,
59+ "Extra": 3,
60+ "Depth": 4,
61+ "hasSection": 5,
62+ "hasSubMenu": 6
63+ }
64+ }
65+ }
66+ Component {
67+ name: "IndicatorsModelRole"
68+ prototype: "QObject"
69+ exports: ["Unity.Indicators/IndicatorsModelRole 0.1"]
70+ isCreatable: false
71+ exportMetaObjectRevisions: [0]
72+ Enum {
73+ name: "Roles"
74+ values: {
75+ "Identifier": 0,
76+ "Position": 1,
77+ "WidgetSource": 2,
78+ "PageSource": 3,
79+ "IndicatorProperties": 4,
80+ "IsVisible": 5
81+ }
82+ }
83+ }
84+ Component {
85+ name: "MenuContentActivator"
86+ prototype: "QObject"
87+ exports: ["Unity.Indicators/MenuContentActivator 0.1"]
88+ exportMetaObjectRevisions: [0]
89+ Property { name: "baseIndex"; type: "int" }
90+ Property { name: "running"; type: "bool" }
91+ Property { name: "count"; type: "int" }
92+ Property { name: "content"; type: "MenuContentState"; isList: true; isReadonly: true }
93+ Signal {
94+ name: "baseIndexChanged"
95+ Parameter { name: "baseIndex"; type: "int" }
96+ }
97+ Signal {
98+ name: "deltaChanged"
99+ Parameter { name: "delta"; type: "int" }
100+ }
101+ Signal {
102+ name: "runningChanged"
103+ Parameter { name: "running"; type: "bool" }
104+ }
105+ Signal {
106+ name: "countChanged"
107+ Parameter { name: "count"; type: "int" }
108+ }
109+ Method { name: "restart" }
110+ Method { name: "stop" }
111+ Method { name: "clear" }
112+ Method {
113+ name: "isMenuContentActive"
114+ type: "bool"
115+ Parameter { name: "index"; type: "int" }
116+ }
117+ }
118+ Component {
119+ name: "MenuContentState"
120+ prototype: "QObject"
121+ exports: ["Unity.Indicators/MenuContentState 0.1"]
122+ isCreatable: false
123+ exportMetaObjectRevisions: [0]
124+ Property { name: "active"; type: "bool"; isReadonly: true }
125+ }
126+ Component {
127+ name: "NetworkActionState"
128+ prototype: "QObject"
129+ exports: ["Unity.Indicators/NetworkActionState 0.1"]
130+ isCreatable: false
131+ exportMetaObjectRevisions: [0]
132+ Enum {
133+ name: "NetworkActionStates"
134+ values: {
135+ "Connection": 1,
136+ "SignalStrength": 2
137+ }
138+ }
139+ }
140+ Component {
141+ name: "NetworkConnection"
142+ prototype: "QObject"
143+ exports: ["Unity.Indicators/NetworkConnection 0.1"]
144+ isCreatable: false
145+ exportMetaObjectRevisions: [0]
146+ Enum {
147+ name: "NetworkConnectionStates"
148+ values: {
149+ "Initial": 0,
150+ "Activating": 1,
151+ "Activated": 2,
152+ "Deactivating": 3
153+ }
154+ }
155+ }
156+ Component {
157+ name: "QAbstractProxyModel"
158+ prototype: "QAbstractItemModel"
159+ Property { name: "sourceModel"; type: "QAbstractItemModel"; isPointer: true }
160+ }
161+ Component { name: "QIdentityProxyModel"; prototype: "QAbstractProxyModel" }
162+ Component {
163+ name: "UnityMenuModelStack"
164+ prototype: "QObject"
165+ exports: ["Unity.Indicators/UnityMenuModelStack 0.1"]
166+ exportMetaObjectRevisions: [0]
167+ Property { name: "head"; type: "UnityMenuModel"; isPointer: true }
168+ Property { name: "tail"; type: "UnityMenuModel"; isReadonly: true; isPointer: true }
169+ Property { name: "count"; type: "int"; isReadonly: true }
170+ Signal {
171+ name: "headChanged"
172+ Parameter { name: "head"; type: "UnityMenuModel"; isPointer: true }
173+ }
174+ Signal {
175+ name: "tailChanged"
176+ Parameter { name: "tail"; type: "UnityMenuModel"; isPointer: true }
177+ }
178+ Signal {
179+ name: "countChanged"
180+ Parameter { name: "count"; type: "int" }
181+ }
182+ Method {
183+ name: "push"
184+ Parameter { name: "model"; type: "UnityMenuModel"; isPointer: true }
185+ Parameter { name: "menuIndex"; type: "int" }
186+ }
187+ Method { name: "pop"; type: "UnityMenuModel*" }
188+ }
189+ Component {
190+ name: "VisibleIndicatorsModel"
191+ prototype: "QIdentityProxyModel"
192+ exports: ["Unity.Indicators/VisibleIndicatorsModel 0.1"]
193+ exportMetaObjectRevisions: [0]
194+ Property { name: "model"; type: "QAbstractItemModel"; isPointer: true }
195+ Property { name: "visible"; type: "QVariantMap" }
196+ Signal { name: "totalCountChanged" }
197+ Method {
198+ name: "onBeginRowInserted"
199+ Parameter { type: "QModelIndex" }
200+ Parameter { name: "start"; type: "int" }
201+ Parameter { name: "end"; type: "int" }
202+ }
203+ Method {
204+ name: "onRowInserted"
205+ Parameter { type: "QModelIndex" }
206+ Parameter { name: "start"; type: "int" }
207+ Parameter { name: "end"; type: "int" }
208+ }
209+ }
210+}
tests/mocks/Unity/Indicators/fakeindicatorsmodel.cpp+1−1
@@ -31,7 +31,7 @@ FakeIndicatorsModel::FakeIndicatorsModel(QObject *parent)
31/*! \internal */
31/*! \internal */
32FakeIndicatorsModel::~FakeIndicatorsModel()
32FakeIndicatorsModel::~FakeIndicatorsModel()
33{
33{
34− unload();
34+ qDeleteAll(m_indicators);
35}
35}
36
36
37int FakeIndicatorsModel::count() const
37int FakeIndicatorsModel::count() const
tests/mocks/Unity/Indicators/qmldir−1
@@ -3,7 +3,6 @@ plugin IndicatorsFakeQml
3typeinfo Indicators.qmltypes
3typeinfo Indicators.qmltypes
4
4
5CachedUnityMenuModel 0.1 CachedUnityMenuModel.qml
5CachedUnityMenuModel 0.1 CachedUnityMenuModel.qml
6−IndicatorBase 0.1 IndicatorBase.qml
7IndicatorsModel 0.1 IndicatorsModel.qml
6IndicatorsModel 0.1 IndicatorsModel.qml
8FakeMenuPage 0.1 FakeMenuPage.qml
7FakeMenuPage 0.1 FakeMenuPage.qml
9RootActionState 0.1 RootActionState.qml
8RootActionState 0.1 RootActionState.qml
tests/mocks/Unity/Launcher/CMakeLists.txt−2
@@ -1,7 +1,5 @@
1pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=3)
1pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=3)
2
2
3−add_definitions(-DTOP_SRCDIR="${CMAKE_SOURCE_DIR}")
4−
5include_directories(
3include_directories(
6 ${CMAKE_CURRENT_SOURCE_DIR}
4 ${CMAKE_CURRENT_SOURCE_DIR}
7)
5)
tests/mocks/Unity/Launcher/Launcher.qmltypesnew file+171
@@ -0,0 +1,171 @@
1+import QtQuick.tooling 1.1
2+
3+// This file describes the plugin-supplied types contained in the library.
4+// It is used for QML tooling purposes only.
5+//
6+// This file was auto-generated by:
7+// 'qmlplugindump -notrelocatable Unity.Launcher 0.1 tests/mocks'
8+
9+Module {
10+ Component {
11+ name: "MockLauncherItem"
12+ prototype: "unity::shell::launcher::LauncherItemInterface"
13+ exports: ["Unity.Launcher/LauncherItem 0.1"]
14+ isCreatable: false
15+ exportMetaObjectRevisions: [0]
16+ }
17+ Component {
18+ name: "MockLauncherModel"
19+ prototype: "unity::shell::launcher::LauncherModelInterface"
20+ exports: ["Unity.Launcher/LauncherModel 0.1"]
21+ isCreatable: false
22+ isSingleton: true
23+ exportMetaObjectRevisions: [0]
24+ Signal {
25+ name: "quickListTriggered"
26+ Parameter { name: "appId"; type: "string" }
27+ Parameter { name: "index"; type: "int" }
28+ }
29+ Method {
30+ name: "get"
31+ type: "unity::shell::launcher::LauncherItemInterface*"
32+ Parameter { name: "index"; type: "int" }
33+ }
34+ Method {
35+ name: "move"
36+ Parameter { name: "oldIndex"; type: "int" }
37+ Parameter { name: "newIndex"; type: "int" }
38+ }
39+ Method {
40+ name: "pin"
41+ Parameter { name: "appId"; type: "string" }
42+ Parameter { name: "index"; type: "int" }
43+ }
44+ Method {
45+ name: "pin"
46+ Parameter { name: "appId"; type: "string" }
47+ }
48+ Method {
49+ name: "requestRemove"
50+ Parameter { name: "appId"; type: "string" }
51+ }
52+ Method {
53+ name: "quickListActionInvoked"
54+ Parameter { name: "appId"; type: "string" }
55+ Parameter { name: "actionIndex"; type: "int" }
56+ }
57+ Method {
58+ name: "setUser"
59+ Parameter { name: "username"; type: "string" }
60+ }
61+ Method {
62+ name: "getUrlForAppId"
63+ type: "string"
64+ Parameter { name: "appId"; type: "string" }
65+ }
66+ }
67+ Component {
68+ name: "MockQuickListModel"
69+ prototype: "unity::shell::launcher::QuickListModelInterface"
70+ exports: ["Unity.Launcher/QuickListModel 0.1"]
71+ isCreatable: false
72+ exportMetaObjectRevisions: [0]
73+ }
74+ Component {
75+ name: "unity::shell::launcher::LauncherItemInterface"
76+ prototype: "QObject"
77+ exports: ["Unity.Launcher/LauncherItemInterface 0.1"]
78+ isCreatable: false
79+ exportMetaObjectRevisions: [0]
80+ Property { name: "appId"; type: "string"; isReadonly: true }
81+ Property { name: "name"; type: "string"; isReadonly: true }
82+ Property { name: "icon"; type: "string"; isReadonly: true }
83+ Property { name: "pinned"; type: "bool"; isReadonly: true }
84+ Property { name: "running"; type: "bool"; isReadonly: true }
85+ Property { name: "recent"; type: "bool"; isReadonly: true }
86+ Property { name: "progress"; type: "int"; isReadonly: true }
87+ Property { name: "count"; type: "int"; isReadonly: true }
88+ Property { name: "focused"; type: "bool"; isReadonly: true }
89+ Property {
90+ name: "quickList"
91+ type: "unity::shell::launcher::QuickListModelInterface"
92+ isReadonly: true
93+ isPointer: true
94+ }
95+ Signal {
96+ name: "pinnedChanged"
97+ Parameter { name: "pinned"; type: "bool" }
98+ }
99+ Signal {
100+ name: "runningChanged"
101+ Parameter { name: "running"; type: "bool" }
102+ }
103+ Signal {
104+ name: "recentChanged"
105+ Parameter { name: "running"; type: "bool" }
106+ }
107+ Signal {
108+ name: "progressChanged"
109+ Parameter { name: "progress"; type: "int" }
110+ }
111+ Signal {
112+ name: "countChanged"
113+ Parameter { name: "count"; type: "int" }
114+ }
115+ Signal {
116+ name: "focusedChanged"
117+ Parameter { name: "focused"; type: "bool" }
118+ }
119+ }
120+ Component {
121+ name: "unity::shell::launcher::LauncherModelInterface"
122+ prototype: "QAbstractListModel"
123+ exports: ["Unity.Launcher/LauncherModelInterface 0.1"]
124+ isCreatable: false
125+ exportMetaObjectRevisions: [0]
126+ Property {
127+ name: "applicationManager"
128+ type: "unity::shell::application::ApplicationManagerInterface"
129+ isPointer: true
130+ }
131+ Method {
132+ name: "move"
133+ Parameter { name: "oldIndex"; type: "int" }
134+ Parameter { name: "newIndex"; type: "int" }
135+ }
136+ Method {
137+ name: "get"
138+ type: "unity::shell::launcher::LauncherItemInterface*"
139+ Parameter { name: "index"; type: "int" }
140+ }
141+ Method {
142+ name: "pin"
143+ Parameter { name: "appId"; type: "string" }
144+ Parameter { name: "index"; type: "int" }
145+ }
146+ Method {
147+ name: "pin"
148+ Parameter { name: "appId"; type: "string" }
149+ }
150+ Method {
151+ name: "requestRemove"
152+ Parameter { name: "appId"; type: "string" }
153+ }
154+ Method {
155+ name: "quickListActionInvoked"
156+ Parameter { name: "appId"; type: "string" }
157+ Parameter { name: "actionIndex"; type: "int" }
158+ }
159+ Method {
160+ name: "setUser"
161+ Parameter { name: "username"; type: "string" }
162+ }
163+ }
164+ Component {
165+ name: "unity::shell::launcher::QuickListModelInterface"
166+ prototype: "QAbstractListModel"
167+ exports: ["Unity.Launcher/QuickListModelInterface 0.1"]
168+ isCreatable: false
169+ exportMetaObjectRevisions: [0]
170+ }
171+}
tests/mocks/Unity/Launcher/MockLauncherItem.cpp+3−1
@@ -20,6 +20,8 @@
20#include "MockLauncherItem.h"
20#include "MockLauncherItem.h"
21#include "MockQuickListModel.h"
21#include "MockQuickListModel.h"
22
22
23+#include <paths.h>
24+
23using namespace unity::shell::launcher;
25using namespace unity::shell::launcher;
24
26
25MockLauncherItem::MockLauncherItem(const QString &appId, const QString& desktopFile, const QString& name, const QString& icon, QObject* parent):
27MockLauncherItem::MockLauncherItem(const QString &appId, const QString& desktopFile, const QString& name, const QString& icon, QObject* parent):
@@ -27,7 +29,7 @@ MockLauncherItem::MockLauncherItem(const QString &appId, const QString& desktopF
27 m_appId(appId),
29 m_appId(appId),
28 m_desktopFile(desktopFile),
30 m_desktopFile(desktopFile),
29 m_name(name),
31 m_name(name),
30− m_icon(TOP_SRCDIR "/graphics/applicationIcons/" + icon + ".png"),
32+ m_icon(qmlDirectory() + "graphics/applicationIcons/" + icon + ".png"),
31 m_pinned(false),
33 m_pinned(false),
32 m_running(false),
34 m_running(false),
33 m_recent(false),
35 m_recent(false),
tests/mocks/Unity/Notifications/Notifications.qmltypesnew file+10
@@ -0,0 +1,10 @@
1+import QtQuick.tooling 1.1
2+
3+// This file describes the plugin-supplied types contained in the library.
4+// It is used for QML tooling purposes only.
5+//
6+// This file was auto-generated by:
7+// 'qmlplugindump -notrelocatable Unity.Notifications 1.0 tests/mocks'
8+
9+Module {
10+}
tests/mocks/Unity/Unity.qmltypesnew file+345
@@ -0,0 +1,345 @@
1+import QtQuick.tooling 1.1
2+
3+// This file describes the plugin-supplied types contained in the library.
4+// It is used for QML tooling purposes only.
5+//
6+// This file was auto-generated by:
7+// 'qmlplugindump -notrelocatable Unity 0.2 tests/mocks'
8+
9+Module {
10+ Component {
11+ name: "Categories"
12+ prototype: "unity::shell::scopes::CategoriesInterface"
13+ Method {
14+ name: "addSpecialCategory"
15+ Parameter { name: "categoryId"; type: "string" }
16+ Parameter { name: "name"; type: "string" }
17+ Parameter { name: "icon"; type: "string" }
18+ Parameter { name: "rawTemplate"; type: "string" }
19+ Parameter { name: "countObject"; type: "QObject"; isPointer: true }
20+ }
21+ Method {
22+ name: "overrideCategoryJson"
23+ type: "bool"
24+ Parameter { name: "categoryId"; type: "string" }
25+ Parameter { name: "json"; type: "string" }
26+ }
27+ }
28+ Component {
29+ name: "PreviewModel"
30+ prototype: "unity::shell::scopes::PreviewModelInterface"
31+ exports: ["Unity/FakePreviewModel 0.2"]
32+ exportMetaObjectRevisions: [0]
33+ }
34+ Component {
35+ name: "PreviewStack"
36+ prototype: "unity::shell::scopes::PreviewStackInterface"
37+ exports: ["Unity/PreviewStack 0.2"]
38+ isCreatable: false
39+ exportMetaObjectRevisions: [0]
40+ Method {
41+ name: "getPreviewModel"
42+ type: "unity::shell::scopes::PreviewModelInterface*"
43+ Parameter { name: "index"; type: "int" }
44+ }
45+ }
46+ Component {
47+ name: "PreviewWidgetModel"
48+ prototype: "unity::shell::scopes::PreviewWidgetModelInterface"
49+ exports: ["Unity/PreviewWidgetModel 0.2"]
50+ isCreatable: false
51+ exportMetaObjectRevisions: [0]
52+ }
53+ Component {
54+ name: "ResultsModel"
55+ prototype: "unity::shell::scopes::ResultsModelInterface"
56+ exports: ["Unity/ResultsModel 0.2"]
57+ isCreatable: false
58+ exportMetaObjectRevisions: [0]
59+ }
60+ Component {
61+ name: "Scope"
62+ prototype: "unity::shell::scopes::ScopeInterface"
63+ exports: ["Unity/MockScope 0.2"]
64+ exportMetaObjectRevisions: [0]
65+ Method {
66+ name: "setSearchInProgress"
67+ Parameter { name: "inProg"; type: "bool" }
68+ }
69+ Method {
70+ name: "activate"
71+ Parameter { name: "result"; type: "QVariant" }
72+ }
73+ Method {
74+ name: "preview"
75+ type: "PreviewStack*"
76+ Parameter { name: "result"; type: "QVariant" }
77+ }
78+ Method { name: "cancelActivation" }
79+ Method {
80+ name: "closeScope"
81+ Parameter { name: "scope"; type: "unity::shell::scopes::ScopeInterface"; isPointer: true }
82+ }
83+ Method {
84+ name: "getDepartment"
85+ type: "unity::shell::scopes::DepartmentInterface*"
86+ Parameter { name: "id"; type: "string" }
87+ }
88+ Method {
89+ name: "loadDepartment"
90+ Parameter { name: "id"; type: "string" }
91+ }
92+ }
93+ Component {
94+ name: "Scopes"
95+ prototype: "unity::shell::scopes::ScopesInterface"
96+ exports: ["Unity/Scopes 0.2"]
97+ exportMetaObjectRevisions: [0]
98+ Method {
99+ name: "rowCount"
100+ type: "int"
101+ Parameter { name: "parent"; type: "QModelIndex" }
102+ }
103+ Method { name: "rowCount"; type: "int" }
104+ Method {
105+ name: "getScope"
106+ type: "unity::shell::scopes::ScopeInterface*"
107+ Parameter { name: "row"; type: "int" }
108+ }
109+ Method {
110+ name: "getScope"
111+ type: "unity::shell::scopes::ScopeInterface*"
112+ Parameter { name: "scope_id"; type: "string" }
113+ }
114+ Method {
115+ name: "addScope"
116+ Parameter { name: "scope"; type: "Scope"; isPointer: true }
117+ }
118+ Method { name: "clear" }
119+ Method { name: "load" }
120+ }
121+ Component {
122+ name: "unity::shell::scopes::CategoriesInterface"
123+ prototype: "QAbstractListModel"
124+ exports: ["Unity/Categories 0.2"]
125+ isCreatable: false
126+ exportMetaObjectRevisions: [0]
127+ Enum {
128+ name: "Roles"
129+ values: {
130+ "RoleCategoryId": 0,
131+ "RoleName": 1,
132+ "RoleIcon": 2,
133+ "RoleRawRendererTemplate": 3,
134+ "RoleRenderer": 4,
135+ "RoleComponents": 5,
136+ "RoleResults": 6,
137+ "RoleCount": 7
138+ }
139+ }
140+ Method {
141+ name: "overrideCategoryJson"
142+ type: "bool"
143+ Parameter { name: "categoryId"; type: "string" }
144+ Parameter { name: "json"; type: "string" }
145+ }
146+ Method {
147+ name: "addSpecialCategory"
148+ Parameter { name: "categoryId"; type: "string" }
149+ Parameter { name: "name"; type: "string" }
150+ Parameter { name: "icon"; type: "string" }
151+ Parameter { name: "rawTemplate"; type: "string" }
152+ Parameter { name: "countObject"; type: "QObject"; isPointer: true }
153+ }
154+ }
155+ Component {
156+ name: "unity::shell::scopes::DepartmentInterface"
157+ prototype: "QAbstractListModel"
158+ exports: ["Unity/Department 0.2"]
159+ isCreatable: false
160+ exportMetaObjectRevisions: [0]
161+ Enum {
162+ name: "Roles"
163+ values: {
164+ "RoleDepartmentId": 0,
165+ "RoleLabel": 1,
166+ "RoleHasChildren": 2,
167+ "RoleIsActive": 3
168+ }
169+ }
170+ Property { name: "departmentId"; type: "string"; isReadonly: true }
171+ Property { name: "label"; type: "string"; isReadonly: true }
172+ Property { name: "allLabel"; type: "string"; isReadonly: true }
173+ Property { name: "parentDepartmentId"; type: "string"; isReadonly: true }
174+ Property { name: "parentLabel"; type: "string"; isReadonly: true }
175+ Property { name: "loaded"; type: "bool"; isReadonly: true }
176+ Property { name: "isRoot"; type: "bool"; isReadonly: true }
177+ Property { name: "count"; type: "int"; isReadonly: true }
178+ }
179+ Component {
180+ name: "unity::shell::scopes::PreviewModelInterface"
181+ prototype: "QAbstractListModel"
182+ Enum {
183+ name: "Roles"
184+ values: {
185+ "RoleColumnModel": 0
186+ }
187+ }
188+ Property { name: "widgetColumnCount"; type: "int" }
189+ Property { name: "loaded"; type: "bool"; isReadonly: true }
190+ Property { name: "processingAction"; type: "bool"; isReadonly: true }
191+ Signal {
192+ name: "triggered"
193+ Parameter { type: "string" }
194+ Parameter { type: "string" }
195+ Parameter { type: "QVariantMap" }
196+ }
197+ }
198+ Component {
199+ name: "unity::shell::scopes::PreviewStackInterface"
200+ prototype: "QAbstractListModel"
201+ Enum {
202+ name: "Roles"
203+ values: {
204+ "RolePreviewModel": 0
205+ }
206+ }
207+ Property { name: "widgetColumnCount"; type: "int" }
208+ Method {
209+ name: "getPreviewModel"
210+ type: "unity::shell::scopes::PreviewModelInterface*"
211+ Parameter { name: "index"; type: "int" }
212+ }
213+ }
214+ Component {
215+ name: "unity::shell::scopes::PreviewWidgetModelInterface"
216+ prototype: "QAbstractListModel"
217+ Enum {
218+ name: "Roles"
219+ values: {
220+ "RoleWidgetId": 0,
221+ "RoleType": 1,
222+ "RoleProperties": 2
223+ }
224+ }
225+ }
226+ Component {
227+ name: "unity::shell::scopes::ResultsModelInterface"
228+ prototype: "QAbstractListModel"
229+ Enum {
230+ name: "Roles"
231+ values: {
232+ "RoleUri": 0,
233+ "RoleCategoryId": 1,
234+ "RoleDndUri": 2,
235+ "RoleResult": 3,
236+ "RoleTitle": 4,
237+ "RoleArt": 5,
238+ "RoleSubtitle": 6,
239+ "RoleMascot": 7,
240+ "RoleEmblem": 8,
241+ "RoleSummary": 9,
242+ "RoleAttributes": 10,
243+ "RoleBackground": 11
244+ }
245+ }
246+ Property { name: "categoryId"; type: "string" }
247+ Property { name: "count"; type: "int"; isReadonly: true }
248+ }
249+ Component {
250+ name: "unity::shell::scopes::ScopeInterface"
251+ prototype: "QObject"
252+ exports: ["Unity/Scope 0.2"]
253+ isCreatable: false
254+ exportMetaObjectRevisions: [0]
255+ Property { name: "id"; type: "string"; isReadonly: true }
256+ Property { name: "name"; type: "string"; isReadonly: true }
257+ Property { name: "iconHint"; type: "string"; isReadonly: true }
258+ Property { name: "description"; type: "string"; isReadonly: true }
259+ Property { name: "searchHint"; type: "string"; isReadonly: true }
260+ Property { name: "searchInProgress"; type: "bool"; isReadonly: true }
261+ Property { name: "visible"; type: "bool"; isReadonly: true }
262+ Property { name: "shortcut"; type: "string"; isReadonly: true }
263+ Property {
264+ name: "categories"
265+ type: "unity::shell::scopes::CategoriesInterface"
266+ isReadonly: true
267+ isPointer: true
268+ }
269+ Property { name: "searchQuery"; type: "string" }
270+ Property { name: "noResultsHint"; type: "string" }
271+ Property { name: "formFactor"; type: "string" }
272+ Property { name: "isActive"; type: "bool" }
273+ Property { name: "currentDepartmentId"; type: "string"; isReadonly: true }
274+ Property { name: "hasDepartments"; type: "bool"; isReadonly: true }
275+ Signal { name: "showDash" }
276+ Signal { name: "hideDash" }
277+ Signal {
278+ name: "gotoUri"
279+ Parameter { name: "uri"; type: "string" }
280+ }
281+ Signal {
282+ name: "previewRequested"
283+ Parameter { name: "result"; type: "QVariant" }
284+ }
285+ Signal {
286+ name: "gotoScope"
287+ Parameter { name: "scopeId"; type: "string" }
288+ }
289+ Signal {
290+ name: "openScope"
291+ Parameter { name: "scope"; type: "unity::shell::scopes::ScopeInterface"; isPointer: true }
292+ }
293+ Signal {
294+ name: "activateApplication"
295+ Parameter { name: "desktop"; type: "string" }
296+ }
297+ Method {
298+ name: "activate"
299+ Parameter { name: "result"; type: "QVariant" }
300+ }
301+ Method {
302+ name: "preview"
303+ type: "unity::shell::scopes::PreviewStackInterface*"
304+ Parameter { name: "result"; type: "QVariant" }
305+ }
306+ Method { name: "cancelActivation" }
307+ Method {
308+ name: "closeScope"
309+ Parameter { name: "scope"; type: "unity::shell::scopes::ScopeInterface"; isPointer: true }
310+ }
311+ Method {
312+ name: "getDepartment"
313+ type: "unity::shell::scopes::DepartmentInterface*"
314+ Parameter { name: "departmentId"; type: "string" }
315+ }
316+ Method {
317+ name: "loadDepartment"
318+ Parameter { name: "departmentId"; type: "string" }
319+ }
320+ }
321+ Component {
322+ name: "unity::shell::scopes::ScopesInterface"
323+ prototype: "QAbstractListModel"
324+ Enum {
325+ name: "Roles"
326+ values: {
327+ "RoleScope": 0,
328+ "RoleId": 1,
329+ "RoleVisible": 2,
330+ "RoleTitle": 3
331+ }
332+ }
333+ Property { name: "loaded"; type: "bool"; isReadonly: true }
334+ Method {
335+ name: "getScope"
336+ type: "unity::shell::scopes::ScopeInterface*"
337+ Parameter { name: "row"; type: "int" }
338+ }
339+ Method {
340+ name: "getScope"
341+ type: "unity::shell::scopes::ScopeInterface*"
342+ Parameter { name: "scopeId"; type: "string" }
343+ }
344+ }
345+}
tests/mocks/Unity/fake_categories.cpp+1−1
@@ -50,7 +50,7 @@ void Categories::addSpecialCategory(QString const& categoryId, QString const& na
50 }
50 }
51}
51}
52
52
53−bool Categories::overrideCategoryJson(QString const& categoryId, QString const& json)
53+bool Categories::overrideCategoryJson(QString const& /* categoryId */, QString const& /* json */)
54{
54{
55 qFatal("Using un-implemented Categories::overrideCategoryJson");
55 qFatal("Using un-implemented Categories::overrideCategoryJson");
56}
56}
tests/mocks/Unity/fake_scope.cpp+5
@@ -155,6 +155,11 @@ bool Scope::hasDepartments() const
155 return true;
155 return true;
156}
156}
157
157
158+QVariantMap Scope::customizations() const
159+{
160+ return QVariantMap();
161+}
162+
158unity::shell::scopes::DepartmentInterface* Scope::getDepartment(const QString& id)
163unity::shell::scopes::DepartmentInterface* Scope::getDepartment(const QString& id)
159{
164{
160 if (id.isEmpty())
165 if (id.isEmpty())
tests/mocks/Unity/fake_scope.h+2
@@ -64,6 +64,8 @@ public:
64 Q_INVOKABLE unity::shell::scopes::DepartmentInterface* getDepartment(const QString& id) override;
64 Q_INVOKABLE unity::shell::scopes::DepartmentInterface* getDepartment(const QString& id) override;
65 Q_INVOKABLE void loadDepartment(const QString& id) override;
65 Q_INVOKABLE void loadDepartment(const QString& id) override;
66
66
67+ QVariantMap customizations() const override;
68+
67protected:
69protected:
68
70
69 QString m_id;
71 QString m_id;
tests/plugins/Dash/cardcreator/1.res+15−9
@@ -16,8 +16,8 @@ onArtShapeBorderSourceChanged: { if (artShapeBorderSource !== undefined && artSh
16readonly property size artShapeSize: artShapeLoader.item ? Qt.size(artShapeLoader.item.width, artShapeLoader.item.height) : Qt.size(-1, -1);
16readonly property size artShapeSize: artShapeLoader.item ? Qt.size(artShapeLoader.item.width, artShapeLoader.item.height) : Qt.size(-1, -1);
17Item {
17Item {
18 id: artShapeHolder;
18 id: artShapeHolder;
19− height: root.fixedArtShapeSize.height != -1 ? root.fixedArtShapeSize.height : artShapeLoader.height;
19+ height: root.fixedArtShapeSize.height > 0 ? root.fixedArtShapeSize.height : artShapeLoader.height;
20− width: root.fixedArtShapeSize.width != -1 ? root.fixedArtShapeSize.width : artShapeLoader.width;
20+ width: root.fixedArtShapeSize.width > 0 ? root.fixedArtShapeSize.width : artShapeLoader.width;
21 anchors { horizontalCenter: parent.horizontalCenter; }
21 anchors { horizontalCenter: parent.horizontalCenter; }
22 Loader {
22 Loader {
23 id: artShapeLoader;
23 id: artShapeLoader;
@@ -28,14 +28,19 @@ Item {
28 sourceComponent: UbuntuShape {
28 sourceComponent: UbuntuShape {
29 id: artShape;
29 id: artShape;
30 objectName: "artShape";
30 objectName: "artShape";
31− radius: "medium";
31+ radius: "medium";
32− readonly property real aspect: components !== undefined ? components["art"]["aspect-ratio"] : 1;
33− readonly property bool aspectSmallerThanImageAspect: aspect < image.aspect;
34− Component.onCompleted: { updateWidthHeightBindings(); if (artShapeBorderSource !== undefined) borderSource = artShapeBorderSource; }
35− onAspectSmallerThanImageAspectChanged: updateWidthHeightBindings();
36 visible: image.status == Image.Ready;
32 visible: image.status == Image.Ready;
33+ readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1;
34+ readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1;
35+ readonly property bool aspectSmallerThanImageAspect: aspect < image.aspect;
36+ Component.onCompleted: { updateWidthHeightBindings(); if (artShapeBorderSource !== undefined) borderSource = artShapeBorderSource; }
37+ onAspectSmallerThanImageAspectChanged: updateWidthHeightBindings();
38+ Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); }
37 function updateWidthHeightBindings() {
39 function updateWidthHeightBindings() {
40+ if (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) {
41+ width = root.fixedArtShapeSize.width;
42+ height = root.fixedArtShapeSize.height;
38− if (aspectSmallerThanImageAspect) {
43+ } else if (aspectSmallerThanImageAspect) {
39 width = Qt.binding(function() { return !visible ? 0 : image.width });
44 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 });
45 height = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.height : width / image.aspect });
41 } else {
46 } else {
@@ -56,13 +61,14 @@ Item {
56 }
61 }
57 }
62 }
58 }
63 }
59−readonly property int headerHeight: titleLabel.height + titleLabel.anchors.topMargin * 2;
64+readonly property int headerHeight: titleLabel.height;
60Label {
65Label {
61 id: titleLabel;
66 id: titleLabel;
62 objectName: "titleLabel";
67 objectName: "titleLabel";
63 anchors { right: parent.right;left: parent.left;
68 anchors { right: parent.right;left: parent.left;
64top: artShapeHolder.bottom;
69top: artShapeHolder.bottom;
65 topMargin: units.gu(1);
70 topMargin: units.gu(1);
71+leftMargin: units.gu(1);
66 }
72 }
67 elide: Text.ElideRight;
73 elide: Text.ElideRight;
68 fontSize: "small";
74 fontSize: "small";
tests/plugins/Dash/cardcreator/2.res+2−1
@@ -46,12 +46,13 @@ Loader {
46 }
46 }
47 }
47 }
48readonly property size artShapeSize: Qt.size(-1, -1);
48readonly property size artShapeSize: Qt.size(-1, -1);
49−readonly property int headerHeight: row.height + row.margins * 2;
49+readonly property int headerHeight: row.height;
50Row {
50Row {
51 id: row;
51 id: row;
52 objectName: "outerRow";
52 objectName: "outerRow";
53 property real margins: units.gu(1);
53 property real margins: units.gu(1);
54 spacing: margins;
54 spacing: margins;
55+ height: root.fixedHeaderHeight != -1 ? root.fixedHeaderHeight : implicitHeight;
55 anchors { top: parent.top;
56 anchors { top: parent.top;
56 topMargin: units.gu(1);
57 topMargin: units.gu(1);
57 left: parent.left;
58 left: parent.left;
tests/plugins/Dash/cardcreator/3.res+21−15
@@ -16,8 +16,8 @@ onArtShapeBorderSourceChanged: { if (artShapeBorderSource !== undefined && artSh
16readonly property size artShapeSize: artShapeLoader.item ? Qt.size(artShapeLoader.item.width, artShapeLoader.item.height) : Qt.size(-1, -1);
16readonly property size artShapeSize: artShapeLoader.item ? Qt.size(artShapeLoader.item.width, artShapeLoader.item.height) : Qt.size(-1, -1);
17Item {
17Item {
18 id: artShapeHolder;
18 id: artShapeHolder;
19− height: root.fixedArtShapeSize.height != -1 ? root.fixedArtShapeSize.height : artShapeLoader.height;
19+ height: root.fixedArtShapeSize.height > 0 ? root.fixedArtShapeSize.height : artShapeLoader.height;
20− width: root.fixedArtShapeSize.width != -1 ? root.fixedArtShapeSize.width : artShapeLoader.width;
20+ width: root.fixedArtShapeSize.width > 0 ? root.fixedArtShapeSize.width : artShapeLoader.width;
21 anchors { horizontalCenter: parent.horizontalCenter; }
21 anchors { horizontalCenter: parent.horizontalCenter; }
22 Loader {
22 Loader {
23 id: artShapeLoader;
23 id: artShapeLoader;
@@ -29,19 +29,24 @@ Item {
29 id: artShape;
29 id: artShape;
30 objectName: "artShape";
30 objectName: "artShape";
31 radius: "medium";
31 radius: "medium";
32− readonly property real aspect: components !== undefined ? components["art"]["aspect-ratio"] : 1;
33− readonly property bool aspectSmallerThanImageAspect: aspect < image.aspect;
34− Component.onCompleted: { updateWidthHeightBindings(); if (artShapeBorderSource !== undefined) borderSource = artShapeBorderSource; }
35− onAspectSmallerThanImageAspectChanged: updateWidthHeightBindings();
36 visible: image.status == Image.Ready;
32 visible: image.status == Image.Ready;
33+ readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1;
34+ readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1;
35+ readonly property bool aspectSmallerThanImageAspect: aspect < image.aspect;
36+ Component.onCompleted: { updateWidthHeightBindings(); if (artShapeBorderSource !== undefined) borderSource = artShapeBorderSource; }
37+ onAspectSmallerThanImageAspectChanged: updateWidthHeightBindings();
38+ Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); }
37− function updateWidthHeightBindings() {
39+ function updateWidthHeightBindings() {
40+ if (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) {
41+ width = root.fixedArtShapeSize.width;
42+ height = root.fixedArtShapeSize.height;
38− if (aspectSmallerThanImageAspect) {
43+ } else if (aspectSmallerThanImageAspect) {
39− width = Qt.binding(function() { return !visible ? 0 : image.width });
44+ 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 });
45+ height = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.height : width / image.aspect });
41− } else {
46+ } else {
42− width = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.width : height * image.aspect });
47+ 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 });
48+ height = Qt.binding(function() { return !visible ? 0 : image.height });
44− }
49+ }
45 }
50 }
46 image: Image {
51 image: Image {
47 objectName: "artImage";
52 objectName: "artImage";
@@ -56,13 +61,14 @@ Item {
56 }
61 }
57 }
62 }
58 }
63 }
59−readonly property int headerHeight: titleLabel.height + titleLabel.anchors.topMargin * 2 + subtitleLabel.height + subtitleLabel.anchors.topMargin;
64+readonly property int headerHeight: titleLabel.height + subtitleLabel.height + subtitleLabel.anchors.topMargin;
60Label {
65Label {
61 id: titleLabel;
66 id: titleLabel;
62 objectName: "titleLabel";
67 objectName: "titleLabel";
63 anchors { right: parent.right;left: parent.left;
68 anchors { right: parent.right;left: parent.left;
64top: artShapeHolder.bottom;
69top: artShapeHolder.bottom;
65 topMargin: units.gu(1);
70 topMargin: units.gu(1);
71+leftMargin: units.gu(1);
66}
72}
67 elide: Text.ElideRight;
73 elide: Text.ElideRight;
68 fontSize: "small";
74 fontSize: "small";
tests/plugins/Dash/cardcreator/4.res+2−1
@@ -13,12 +13,13 @@ AbstractButton {
13 property bool showHeader: true;
13 property bool showHeader: true;
14 implicitWidth: childrenRect.width;
14 implicitWidth: childrenRect.width;
15readonly property size artShapeSize: Qt.size(-1, -1);
15readonly property size artShapeSize: Qt.size(-1, -1);
16−readonly property int headerHeight: row.height + row.margins * 2;
16+readonly property int headerHeight: row.height;
17Row {
17Row {
18 id: row;
18 id: row;
19 objectName: "outerRow";
19 objectName: "outerRow";
20 property real margins: units.gu(1);
20 property real margins: units.gu(1);
21 spacing: margins;
21 spacing: margins;
22+ height: root.fixedHeaderHeight != -1 ? root.fixedHeaderHeight : implicitHeight;
22 anchors { top: parent.top;
23 anchors { top: parent.top;
23 topMargin: units.gu(1);
24 topMargin: units.gu(1);
24 left: parent.left;
25 left: parent.left;
tests/plugins/Dash/cardcreator/5.res+21−16
@@ -16,8 +16,8 @@ onArtShapeBorderSourceChanged: { if (artShapeBorderSource !== undefined && artSh
16readonly property size artShapeSize: artShapeLoader.item ? Qt.size(artShapeLoader.item.width, artShapeLoader.item.height) : Qt.size(-1, -1);
16readonly property size artShapeSize: artShapeLoader.item ? Qt.size(artShapeLoader.item.width, artShapeLoader.item.height) : Qt.size(-1, -1);
17Item {
17Item {
18 id: artShapeHolder;
18 id: artShapeHolder;
19− height: root.fixedArtShapeSize.height != -1 ? root.fixedArtShapeSize.height : artShapeLoader.height;
19+ height: root.fixedArtShapeSize.height > 0 ? root.fixedArtShapeSize.height : artShapeLoader.height;
20− width: root.fixedArtShapeSize.width != -1 ? root.fixedArtShapeSize.width : artShapeLoader.width;
20+ width: root.fixedArtShapeSize.width > 0 ? root.fixedArtShapeSize.width : artShapeLoader.width;
21 anchors { horizontalCenter: parent.horizontalCenter; }
21 anchors { horizontalCenter: parent.horizontalCenter; }
22 Loader {
22 Loader {
23 id: artShapeLoader;
23 id: artShapeLoader;
@@ -29,19 +29,24 @@ Item {
29 id: artShape;
29 id: artShape;
30 objectName: "artShape";
30 objectName: "artShape";
31 radius: "medium";
31 radius: "medium";
32− readonly property real aspect: components !== undefined ? components["art"]["aspect-ratio"] : 1;
33− readonly property bool aspectSmallerThanImageAspect: aspect < image.aspect;
34− Component.onCompleted: { updateWidthHeightBindings(); if (artShapeBorderSource !== undefined) borderSource = artShapeBorderSource; }
35− onAspectSmallerThanImageAspectChanged: updateWidthHeightBindings();
36 visible: image.status == Image.Ready;
32 visible: image.status == Image.Ready;
33+ readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1;
34+ readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1;
35+ readonly property bool aspectSmallerThanImageAspect: aspect < image.aspect;
36+ Component.onCompleted: { updateWidthHeightBindings(); if (artShapeBorderSource !== undefined) borderSource = artShapeBorderSource; }
37+ onAspectSmallerThanImageAspectChanged: updateWidthHeightBindings();
38+ Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); }
37− function updateWidthHeightBindings() {
39+ function updateWidthHeightBindings() {
40+ if (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) {
41+ width = root.fixedArtShapeSize.width;
42+ height = root.fixedArtShapeSize.height;
38− if (aspectSmallerThanImageAspect) {
43+ } else if (aspectSmallerThanImageAspect) {
39− width = Qt.binding(function() { return !visible ? 0 : image.width });
44+ 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 });
45+ height = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.height : width / image.aspect });
41− } else {
46+ } else {
42− width = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.width : height * image.aspect });
47+ 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 });
48+ height = Qt.binding(function() { return !visible ? 0 : image.height });
44− }
49+ }
45 }
50 }
46 image: Image {
51 image: Image {
47 objectName: "artImage";
52 objectName: "artImage";
@@ -68,7 +73,7 @@ Loader {
68 visible: showHeader && status == Loader.Ready;
73 visible: showHeader && status == Loader.Ready;
69 sourceComponent: ShaderEffect {
74 sourceComponent: ShaderEffect {
70 id: overlay;
75 id: overlay;
71− height: fixedHeaderHeight != -1 ? fixedHeaderHeight : headerHeight;
76+ height: (fixedHeaderHeight > 0 ? fixedHeaderHeight : headerHeight) + units.gu(2);
72 opacity: 0.6;
77 opacity: 0.6;
73 property var source: ShaderEffectSource {
78 property var source: ShaderEffectSource {
74 id: shaderSource;
79 id: shaderSource;
@@ -96,7 +101,7 @@ Loader {
96 }";
101 }";
97 }
102 }
98 }
103 }
99−readonly property int headerHeight: titleLabel.height + titleLabel.anchors.topMargin * 2 + subtitleLabel.height + subtitleLabel.anchors.topMargin;
104+readonly property int headerHeight: titleLabel.height + subtitleLabel.height + subtitleLabel.anchors.topMargin;
100Label {
105Label {
101 id: titleLabel;
106 id: titleLabel;
102 objectName: "titleLabel";
107 objectName: "titleLabel";
tests/plugins/Unity/CMakeLists.txt+1
@@ -1,2 +1,3 @@
1add_subdirectory(Indicators)
1add_subdirectory(Indicators)
2add_subdirectory(Launcher)
2add_subdirectory(Launcher)
3+add_subdirectory(Session)
tests/plugins/Unity/Session/CMakeLists.txtnew file+20
@@ -0,0 +1,20 @@
1+include_directories(
2+ ${CMAKE_CURRENT_BINARY_DIR}
3+ ${CMAKE_SOURCE_DIR}/plugins/Unity/Session
4+)
5+
6+add_definitions(-DSM_BUSNAME=sessionBus)
7+add_definitions(-DSRCDIR="${CMAKE_CURRENT_SOURCE_DIR}")
8+add_definitions(-DSESSION_TESTING)
9+
10+### SessionBackendTest
11+set(testBackendCommand dbus-test-runner --task ${CMAKE_CURRENT_BINARY_DIR}/sessionbackendtestExec
12+ --parameter -o --parameter ${CMAKE_BINARY_DIR}/sessionbackendtest.xml,xunitxml
13+ --parameter -o --parameter -,txt)
14+add_test(NAME sessionbackendtest COMMAND ${testBackendCommand})
15+add_custom_target(sessionbackendtest ${testBackendCommand})
16+add_executable(sessionbackendtestExec
17+ sessionbackendtest.cpp
18+ ${CMAKE_SOURCE_DIR}/plugins/Unity/Session/dbusunitysessionservice.cpp
19+)
20+qt5_use_modules(sessionbackendtestExec Test Core Qml DBus)
tests/plugins/Unity/Session/sessionbackendtest.cppnew file+64
@@ -0,0 +1,64 @@
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 Lesser 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 Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Ying-Chun Liu (PaulLiu) <paul.liu@canonical.com>
18+ */
19+
20+#include <QtTest>
21+#include <QDBusConnection>
22+#include <QDBusMessage>
23+#include <QDBusInterface>
24+#include <QDBusReply>
25+#include <QDBusVariant>
26+
27+#include "dbusunitysessionservice.h"
28+
29+class SessionBackendTest : public QObject
30+{
31+ Q_OBJECT
32+
33+private Q_SLOTS:
34+
35+ void initTestCase() {
36+ }
37+
38+ void testDbusIfaceMethods_data() {
39+ QTest::addColumn<QString>("method");
40+
41+ QTest::newRow("Logout") << "RequestLogout";
42+ }
43+
44+ void testDbusIfaceMethods() {
45+ QFETCH(QString, method);
46+
47+ DBusUnitySessionService dbusUnitySessionService;
48+
49+ QDBusConnection con = QDBusConnection::sessionBus();
50+ QDBusInterface interface ("com.canonical.Unity",
51+ "/com/canonical/Unity/Session",
52+ "com.canonical.Unity.Session",
53+ con);
54+ QDBusReply<void> reply;
55+
56+ QCOMPARE(interface.isValid(), true);
57+ reply = interface.call(method);
58+ QCOMPARE(reply.isValid(), true);
59+
60+ }
61+};
62+
63+QTEST_GUILESS_MAIN(SessionBackendTest)
64+#include "sessionbackendtest.moc"
tests/qmltests/CMakeLists.txt+2
@@ -29,6 +29,7 @@ add_qml_test(Components LazyImage)
29add_qml_test(Components Rating)
29add_qml_test(Components Rating)
30add_qml_test(Components ResponsiveFlowView)
30add_qml_test(Components ResponsiveFlowView)
31add_qml_test(Components ResponsiveGridView)
31add_qml_test(Components ResponsiveGridView)
32+add_qml_test(Components ResponsiveVerticalJournal IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/plugins)
32add_qml_test(Components SeeMore)
33add_qml_test(Components SeeMore)
33add_qml_test(Components Showable)
34add_qml_test(Components Showable)
34add_qml_test(Components PageHeaderLabel)
35add_qml_test(Components PageHeaderLabel)
@@ -45,6 +46,7 @@ add_qml_test(Dash/Previews PreviewActions)
45add_qml_test(Dash/Previews PreviewAudioPlayback)
46add_qml_test(Dash/Previews PreviewAudioPlayback)
46add_qml_test(Dash/Previews PreviewHeader)
47add_qml_test(Dash/Previews PreviewHeader)
47add_qml_test(Dash/Previews PreviewImageGallery)
48add_qml_test(Dash/Previews PreviewImageGallery)
49+add_qml_test(Dash/Previews PreviewPayments)
48add_qml_test(Dash/Previews PreviewProgress)
50add_qml_test(Dash/Previews PreviewProgress)
49add_qml_test(Dash/Previews PreviewRatingDisplay)
51add_qml_test(Dash/Previews PreviewRatingDisplay)
50add_qml_test(Dash/Previews PreviewRatingInput)
52add_qml_test(Dash/Previews PreviewRatingInput)
tests/qmltests/Components/tst_LazyImage.qml−1
@@ -152,7 +152,6 @@ Rectangle {
152
152
153 function test_lazyimage(data) {
153 function test_lazyimage(data) {
154 data.func();
154 data.func();
155− waitForRendering(baseRect);
156
155
157 if (data.transition) {
156 if (data.transition) {
158 // wait for the transition to complete
157 // wait for the transition to complete
tests/qmltests/Components/tst_ResponsiveVerticalJournal.qmlnew file+183
@@ -0,0 +1,183 @@
1+/*
2+ * Copyright 2013-2014 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import QtTest 1.0
19+import ".."
20+import "../../../qml/Components"
21+import Ubuntu.Components.ListItems 0.1 as ListItem
22+import Ubuntu.Components 0.1
23+import Utils 0.1
24+import Unity.Test 0.1 as UT
25+
26+Item {
27+ width: units.gu(80) + controls.width
28+ height: units.gu(80)
29+
30+ Column {
31+ id: controls
32+ width: units.gu(40)
33+ height: parent.height
34+ anchors.top: parent.top
35+ anchors.right: parent.right
36+ ListItem.ValueSelector {
37+ id: cardSizeSelector
38+ text: "card-size"
39+ // small, medium, large card sizes
40+ values: [units.gu(12), units.gu(18.5), units.gu(38)]
41+ selectedIndex: 0
42+ }
43+ ListItem.ValueSelector {
44+ id: minColumnSpacingSelector
45+ text: "minColumnSpacing"
46+ values: [0, units.gu(2), units.gu(8), units.gu(25)]
47+ selectedIndex: 0
48+ }
49+ ListItem.ValueSelector {
50+ id: rowSpacingSelector
51+ text: "rowSpacing"
52+ values: [units.gu(1), units.gu(2), units.gu(4), units.gu(8)]
53+ selectedIndex: 1
54+ }
55+ }
56+
57+ ListModel {
58+ id: fakeModel
59+ ListElement { name: "A" }
60+ ListElement { name: "B" }
61+ ListElement { name: "C" }
62+ ListElement { name: "D" }
63+ ListElement { name: "E" }
64+ ListElement { name: "F" }
65+ ListElement { name: "G" }
66+ ListElement { name: "H" }
67+ ListElement { name: "I" }
68+ ListElement { name: "J" }
69+ ListElement { name: "K" }
70+ ListElement { name: "L" }
71+ ListElement { name: "M" }
72+ ListElement { name: "N" }
73+ ListElement { name: "O" }
74+ ListElement { name: "P" }
75+ ListElement { name: "Q" }
76+ ListElement { name: "R" }
77+ ListElement { name: "S" }
78+ ListElement { name: "T" }
79+ ListElement { name: "U" }
80+ }
81+
82+ SortFilterProxyModel {
83+ id: wrappedFakeModel
84+ model: fakeModel
85+ }
86+
87+ Rectangle {
88+ id: journalRect
89+ height: parent.height
90+ color: "grey"
91+ anchors.top: parent.top
92+ anchors.left: parent.left
93+ anchors.right: controls.left
94+
95+ ResponsiveVerticalJournal {
96+ id: journal
97+ anchors.fill: parent
98+ model: wrappedFakeModel
99+ minimumColumnSpacing: minColumnSpacingSelector.values[minColumnSpacingSelector.selectedIndex]
100+ rowSpacing: rowSpacingSelector.values[rowSpacingSelector.selectedIndex]
101+ columnWidth: cardSizeSelector.values[cardSizeSelector.selectedIndex]
102+
103+ delegate: Rectangle {
104+ id: delegateItem
105+ // So that it can be identified by test code
106+ property bool isJournalDelegate: true
107+ objectName: "delegate" + index
108+ color: "grey"
109+ border.color: "red"
110+ border.width: 1
111+
112+ // width derived from Card's template['card-size']
113+ width: cardSizeSelector.values[cardSizeSelector.selectedIndex]
114+ height: Math.max(units.gu(8), Math.floor(Math.random() * 300))
115+
116+ Rectangle {
117+ color: "green"
118+ anchors.centerIn: parent
119+ width: units.gu(6)
120+ height: units.gu(6)
121+ Text {
122+ anchors.centerIn: parent
123+ text: name
124+ }
125+ }
126+
127+ Text { x:0; y:0; text:"(" + parent.x + ", " + parent.y + ")"}
128+ }
129+ }
130+ }
131+
132+ UT.UnityTestCase {
133+ name: "ResponsiveVerticalJournal"
134+ when: windowShown
135+
136+ function test_minimumColumnSpacing_data() {
137+ return [{minColumnSpacingIndex: 0, expectedColumns: 2},
138+ {minColumnSpacingIndex: 1, expectedColumns: 2},
139+ {minColumnSpacingIndex: 2, expectedColumns: 1}]
140+ }
141+
142+ // Test how minimumColumnSpacing affects column count.
143+ function test_minimumColumnSpacing(data) {
144+ cardSizeSelector.selectedIndex = 2 // large card
145+
146+ minColumnSpacingSelector.selectedIndex = data.minColumnSpacingIndex
147+
148+ tryCompareFunction(countJournalDelegatesOnFirstRow, data.expectedColumns)
149+ }
150+
151+ function test_maximumNumberOfColumns_data() {
152+ return [{cardSizeIndex: 0, expectedColumns: 6},
153+ {cardSizeIndex: 1, expectedColumns: 4},
154+ {cardSizeIndex: 2, expectedColumns: 2}]
155+ }
156+
157+ // Test how maximumNumberOfColumns and columnWidth affect column count.
158+ function test_maximumNumberOfColumns(data) {
159+ minColumnSpacingSelector.selectedIndex = 0 // no spacing
160+
161+ cardSizeSelector.selectedIndex = data.cardSizeIndex // columnWidth
162+
163+ tryCompareFunction(countJournalDelegatesOnFirstRow, data.expectedColumns)
164+ }
165+
166+ function countJournalDelegatesOnFirstRow() {
167+ return __countJournalDelegatesOnFirstRow(journal.visibleChildren, 0)
168+ }
169+
170+ function __countJournalDelegatesOnFirstRow(objList, total) {
171+ for (var i = 0; i < objList.length; ++i) {
172+ var child = objList[i];
173+ if (child.isJournalDelegate !== undefined && child.y === 0) {
174+ ++total;
175+ } else {
176+ total = __countJournalDelegatesOnFirstRow(
177+ child.visibleChildren, total)
178+ }
179+ }
180+ return total
181+ }
182+ }
183+}
tests/qmltests/Dash/Previews/tst_PreviewPayments.qmlnew file+100
@@ -0,0 +1,100 @@
1+/*
2+ * Copyright 2014 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import QtTest 1.0
19+import "../../../../qml/Dash/Previews"
20+import Unity.Test 0.1 as UT
21+import Ubuntu.Components 0.1
22+
23+Rectangle {
24+ id: root
25+ width: units.gu(60)
26+ height: units.gu(80)
27+
28+ property var jsonPurchase: {
29+ "source": { "price" : 0.99, "currency": "USD", "store_item_id": "com.example.package" }
30+ }
31+
32+ property var jsonPurchaseError: {
33+ "source": { "price" : 0.99, "currency": "USD", "store_item_id": "com.example.invalid" }
34+ }
35+
36+ SignalSpy {
37+ id: spy
38+ target: previewPayments
39+ signalName: "triggered"
40+ }
41+
42+ PreviewPayments {
43+ id: previewPayments
44+ widgetId: "previewPayments"
45+ width: units.gu(30)
46+ }
47+
48+ UT.UnityTestCase {
49+ name: "PreviewPaymentsTest"
50+ when: windowShown
51+
52+ function cleanup()
53+ {
54+ spy.clear();
55+ }
56+
57+ function test_purchase_text_display() {
58+ previewPayments.widgetData = jsonPurchase;
59+
60+ var button = findChild(root, "paymentButton");
61+ verify(button != null, "Button not found.");
62+ compare(button.text, "0.99USD");
63+ }
64+
65+ function test_purchase_completed() {
66+ // Exercise the purchaseCompleted signal here.
67+ previewPayments.widgetData = jsonPurchase;
68+
69+ var button = findChild(root, "paymentButton");
70+ verify(button != null, "Button not found.");
71+
72+ mouseClick(button, button.width / 2, button.height / 2);
73+
74+ spy.wait();
75+
76+ var args = spy.signalArguments[0];
77+ compare(args[0], "previewPayments");
78+ compare(args[1], "purchaseCompleted");
79+ compare(args[2], jsonPurchase["source"]);
80+ }
81+
82+ function test_purchase_error() {
83+ // The mock Payments triggers an error when com.example.invalid is
84+ // passed to it as store_item_id. Exercise it here
85+ previewPayments.widgetData = jsonPurchaseError;
86+
87+ var button = findChild(root, "paymentButton");
88+ verify(button != null, "Button not found.");
89+
90+ mouseClick(button, button.width / 2, button.height / 2);
91+
92+ spy.wait();
93+
94+ var args = spy.signalArguments[0];
95+ compare(args[0], "previewPayments");
96+ compare(args[1], "purchaseError");
97+ compare(args[2], jsonPurchaseError["source"]);
98+ }
99+ }
100+}
tests/qmltests/Dash/tst_Card.qml+9
@@ -305,6 +305,15 @@ Rectangle {
305 }
305 }
306 }
306 }
307
307
308+ function test_art_shape_fixed_size() {
309+ selector.selectedIndex = 6;
310+ card.fixedArtShapeSize = Qt.size( units.gu(8), units.gu(4) );
311+ waitForRendering(card);
312+ tryCompare(art, "width", units.gu(8));
313+ tryCompare(art, "height", units.gu(4));
314+ tryCompare(art, "fixedArtShapeSizeAspect", 2);
315+ }
316+
308 function test_art_layout_data() {
317 function test_art_layout_data() {
309 return [
318 return [
310 { tag: "Vertical", left: function() { return units.gu(1); }, index: 0},
319 { tag: "Vertical", left: function() { return units.gu(1); }, index: 0},
tests/qmltests/Notifications/tst_Notifications.qml+29−12
@@ -21,6 +21,7 @@ import "../../../qml/Notifications"
21import Ubuntu.Components 0.1
21import Ubuntu.Components 0.1
22import Unity.Test 0.1
22import Unity.Test 0.1
23import Unity.Notifications 1.0
23import Unity.Notifications 1.0
24+import QtMultimedia 5.0
24
25
25Row {
26Row {
26 id: rootRow
27 id: rootRow
@@ -245,7 +246,8 @@ Row {
245 nonShapedIcon: false,
246 nonShapedIcon: false,
246 secondaryIconVisible: true,
247 secondaryIconVisible: true,
247 buttonRowVisible: true,
248 buttonRowVisible: true,
248− buttonTinted: true
249+ buttonTinted: true,
250+ hasSound: false
249 },
251 },
250 {
252 {
251 tag: "Ephemeral notification - icon-summary layout",
253 tag: "Ephemeral notification - icon-summary layout",
@@ -263,12 +265,15 @@ Row {
263 nonShapedIcon: false,
265 nonShapedIcon: false,
264 secondaryIconVisible: true,
266 secondaryIconVisible: true,
265 buttonRowVisible: false,
267 buttonRowVisible: false,
266− buttonTinted: false
268+ buttonTinted: false,
269+ hasSound: false
267 },
270 },
268 {
271 {
269 tag: "Ephemeral notification - check suppression of secondary icon for icon-summary layout",
272 tag: "Ephemeral notification - check suppression of secondary icon for icon-summary layout",
270 type: Notification.Ephemeral,
273 type: Notification.Ephemeral,
271− hints: {"x-canonical-private-button-tint": "false"},
274+ hints: {"x-canonical-private-button-tint": "false",
275+ "sound-file": "dummy.ogg",
276+ "suppress-sound": "true"},
272 summary: "New comment successfully published",
277 summary: "New comment successfully published",
273 body: "",
278 body: "",
274 icon: "",
279 icon: "",
@@ -282,12 +287,14 @@ Row {
282 nonShapedIcon: false,
287 nonShapedIcon: false,
283 secondaryIconVisible: true,
288 secondaryIconVisible: true,
284 buttonRowVisible: false,
289 buttonRowVisible: false,
285− buttonTinted: false
290+ buttonTinted: false,
291+ hasSound: false
286 },
292 },
287 {
293 {
288 tag: "Interactive notification",
294 tag: "Interactive notification",
289 type: Notification.Interactive,
295 type: Notification.Interactive,
290− hints: {"x-canonical-private-button-tint": "false"},
296+ hints: {"x-canonical-private-button-tint": "false",
297+ "sound-file": "dummy.ogg"},
291 summary: "Interactive notification",
298 summary: "Interactive notification",
292 body: "This is a notification that can be clicked",
299 body: "This is a notification that can be clicked",
293 icon: "../graphics/avatars/amanda.png",
300 icon: "../graphics/avatars/amanda.png",
@@ -300,12 +307,14 @@ Row {
300 nonShapedIcon: false,
307 nonShapedIcon: false,
301 secondaryIconVisible: false,
308 secondaryIconVisible: false,
302 buttonRowVisible: false,
309 buttonRowVisible: false,
303− buttonTinted: false
310+ buttonTinted: false,
311+ hasSound: true
304 },
312 },
305 {
313 {
306 tag: "Snap Decision without secondary icon and no button-tint",
314 tag: "Snap Decision without secondary icon and no button-tint",
307 type: Notification.SnapDecision,
315 type: Notification.SnapDecision,
308− hints: {"x-canonical-private-button-tint": "false"},
316+ hints: {"x-canonical-private-button-tint": "false",
317+ "sound-file": "dummy.ogg"},
309 summary: "Bro Coly",
318 summary: "Bro Coly",
310 body: "At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.",
319 body: "At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.",
311 icon: "../graphics/avatars/anna_olsson.png",
320 icon: "../graphics/avatars/anna_olsson.png",
@@ -319,12 +328,14 @@ Row {
319 nonShapedIcon: false,
328 nonShapedIcon: false,
320 secondaryIconVisible: false,
329 secondaryIconVisible: false,
321 buttonRowVisible: true,
330 buttonRowVisible: true,
322− buttonTinted: false
331+ buttonTinted: false,
332+ hasSound: true
323 },
333 },
324 {
334 {
325 tag: "Ephemeral notification",
335 tag: "Ephemeral notification",
326 type: Notification.Ephemeral,
336 type: Notification.Ephemeral,
327− hints: {"x-canonical-private-button-tint": "false"},
337+ hints: {"x-canonical-private-button-tint": "false",
338+ "sound-file": "dummy.ogg"},
328 summary: "Cole Raby",
339 summary: "Cole Raby",
329 body: "I did not expect it to be that late.",
340 body: "I did not expect it to be that late.",
330 icon: "../graphics/avatars/funky.png",
341 icon: "../graphics/avatars/funky.png",
@@ -337,13 +348,15 @@ Row {
337 nonShapedIcon: false,
348 nonShapedIcon: false,
338 secondaryIconVisible: true,
349 secondaryIconVisible: true,
339 buttonRowVisible: false,
350 buttonRowVisible: false,
340− buttonTinted: false
351+ buttonTinted: false,
352+ hasSound: true
341 },
353 },
342 {
354 {
343 tag: "Ephemeral notification with non-shaped icon",
355 tag: "Ephemeral notification with non-shaped icon",
344 type: Notification.Ephemeral,
356 type: Notification.Ephemeral,
345 hints: {"x-canonical-private-button-tint": "false",
357 hints: {"x-canonical-private-button-tint": "false",
346− "x-canonical-non-shaped-icon": "true"},
358+ "x-canonical-non-shaped-icon": "true",
359+ "sound-file": "dummy.ogg"},
347 summary: "Contacts",
360 summary: "Contacts",
348 body: "Synchronised contacts-database with cloud-storage.",
361 body: "Synchronised contacts-database with cloud-storage.",
349 icon: "../graphics/applicationIcons/contacts-app.png",
362 icon: "../graphics/applicationIcons/contacts-app.png",
@@ -356,7 +369,8 @@ Row {
356 nonShapedIcon: true,
369 nonShapedIcon: true,
357 secondaryIconVisible: false,
370 secondaryIconVisible: false,
358 buttonRowVisible: false,
371 buttonRowVisible: false,
359− buttonTinted: false
372+ buttonTinted: false,
373+ hasSound: true
360 }
374 }
361 ]
375 ]
362 }
376 }
@@ -419,6 +433,9 @@ Row {
419 compare(bodyLabel.visible, data.bodyVisible, "body-text visibility is incorrect")
433 compare(bodyLabel.visible, data.bodyVisible, "body-text visibility is incorrect")
420 compare(buttonRow.visible, data.buttonRowVisible, "button visibility is incorrect")
434 compare(buttonRow.visible, data.buttonRowVisible, "button visibility is incorrect")
421
435
436+ var audioItem = findInvisibleChild(notification, "sound")
437+ tryCompare(audioItem, "playbackState", data.hasSound ? Audio.PlayingState : Audio.StoppedState)
438+
422 if(data.buttonRowVisible) {
439 if(data.buttonRowVisible) {
423 var buttonCancel = findChild(buttonRow, "button1")
440 var buttonCancel = findChild(buttonRow, "button1")
424 var buttonAccept = findChild(buttonRow, "button0")
441 var buttonAccept = findChild(buttonRow, "button0")
tests/qmltests/Panel/Indicators/tst_DefaultIndicatorPage.qml+1
@@ -31,6 +31,7 @@ Item {
31 anchors.fill: parent
31 anchors.fill: parent
32 contentActive: true
32 contentActive: true
33
33
34+ menuModel: UnityMenuModel {}
34 busName: "test"
35 busName: "test"
35 actionsObjectPath: "test"
36 actionsObjectPath: "test"
36 menuObjectPath: "test"
37 menuObjectPath: "test"
tests/qmltests/Panel/Indicators/tst_DefaultIndicatorWidget.qml+3−40
@@ -33,6 +33,7 @@ Item {
33 top: parent.top
33 top: parent.top
34 }
34 }
35
35
36+ menuModel: UnityMenuModel {}
36 busName: "test"
37 busName: "test"
37 actionsObjectPath: "test"
38 actionsObjectPath: "test"
38 deviceMenuObjectPath: "test"
39 deviceMenuObjectPath: "test"
@@ -41,12 +42,6 @@ Item {
41
42
42 iconSize: units.gu(3.2)
43 iconSize: units.gu(3.2)
43 height: units.gu(3)
44 height: units.gu(3)
44−
45− rootActionState {
46− icons: [ "image://theme/audio-volume-high", "image://theme/audio-volume-low" ]
47− leftLabel: "left"
48− rightLabel: "right"
49− }
50 }
45 }
51
46
52 UT.UnityTestCase {
47 UT.UnityTestCase {
@@ -57,41 +52,9 @@ Item {
57 widget.rootActionState.icons = [];
52 widget.rootActionState.icons = [];
58 widget.rootActionState.leftLabel = "";
53 widget.rootActionState.leftLabel = "";
59 widget.rootActionState.rightLabel = "";
54 widget.rootActionState.rightLabel = "";
60− wait(50);
55+ waitForRendering(widget)
61− }
62−
63− function test_guRoundedWidth_data() {
64− return [
65− { tag: "empty", icons: [], leftLabel: "", rightLabel: "" },
66− { tag: "1-icon-no-label", icons: [ "image://theme/audio-volume-high" ], leftLabel: "", rightLabel: "" },
67− { tag: "2-icon-no-label", icons: [ "image://theme/audio-volume-high", "image://theme/audio-volume-low" ], leftLabel: "", rightLabel: "" },
68− { tag: "no-icon-l-label", icons: [], leftLabel: "left", rightLabel: "" },
69− { tag: "no-icon-lr-label", icons: [], leftLabel: "left", rightLabel: "right" },
70− { tag: "1-icon-l-label", icons: [ "image://theme/audio-volume-high" ], leftLabel: "left", rightLabel: "" },
71− { tag: "1-icon-lr-label", icons: [ "image://theme/audio-volume-high" ], leftLabel: "left", rightLabel: "right" },
72− { tag: "2-icon-l-label", icons: [ "image://theme/audio-volume-high", "image://theme/audio-volume-low" ], leftLabel: "left", rightLabel: "" },
73− { tag: "2-icon-lr-label", icons: [ "image://theme/audio-volume-high", "image://theme/audio-volume-low" ], leftLabel: "left", rightLabel: "right" }
74− ];
75− }
76−
77− function test_guRoundedWidth(data) {
78− widget.rootActionState.icons = data.icons
79− widget.rootActionState.leftLabel = data.leftLabel;
80− widget.rootActionState.rightLabel = data.rightLabel;
81− wait(50);
82−
83− compare(widget.width, guRoundUp(widget.width));
84− }
85− }
86−
87− // TODO: Use toolkit function https://bugs.launchpad.net/ubuntu-ui-toolkit/+bug/1242575
88− function guRoundUp(width) {
89− if (width == 0) {
90− return 0;
91 }
56 }
92− var gu1 = units.gu(1.0);
93− var mod = (width % gu1);
94
57
95− return mod == 0 ? width : width + (gu1 - mod);
58+ // FIXME: add tests
96 }
59 }
97}
60}
tests/qmltests/tst_Shell.qml+1−1
@@ -195,7 +195,7 @@ Item {
195 tryCompare(mainApp, "state", ApplicationInfo.Running);
195 tryCompare(mainApp, "state", ApplicationInfo.Running);
196
196
197 // Try to suspend while proximity is engaged...
197 // Try to suspend while proximity is engaged...
198− Powerd.displayPowerStateChange(Powerd.Off, Powerd.UseProximity);
198+ Powerd.displayPowerStateChange(Powerd.Off, Powerd.Proximity);
199 tryCompare(greeter, "showProgress", 0);
199 tryCompare(greeter, "showProgress", 0);
200
200
201 // Now really suspend
201 // Now really suspend
tests/utils/modules/Unity/Test/Test.qmltypesnew file+59
@@ -0,0 +1,59 @@
1+import QtQuick.tooling 1.1
2+
3+// This file describes the plugin-supplied types contained in the library.
4+// It is used for QML tooling purposes only.
5+//
6+// This file was auto-generated by:
7+// 'qmlplugindump -notrelocatable Unity.Test 0.1 tests/utils/modules'
8+
9+Module {
10+ Component {
11+ name: "TestUtil"
12+ prototype: "QObject"
13+ exports: ["Unity.Test/Util 0.1"]
14+ isCreatable: false
15+ isSingleton: true
16+ exportMetaObjectRevisions: [0]
17+ Method {
18+ name: "isInstanceOf"
19+ type: "bool"
20+ Parameter { type: "QObject"; isPointer: true }
21+ Parameter { type: "string" }
22+ }
23+ Method { name: "touchEvent"; type: "TouchEventSequenceWrapper*" }
24+ }
25+ Component {
26+ name: "TouchEventSequenceWrapper"
27+ prototype: "QObject"
28+ exports: ["Unity.Test/TouchEventSequence 0.1"]
29+ isCreatable: false
30+ exportMetaObjectRevisions: [0]
31+ Method {
32+ name: "commit"
33+ Parameter { name: "processEvents"; type: "bool" }
34+ }
35+ Method { name: "commit" }
36+ Method {
37+ name: "move"
38+ Parameter { name: "touchId"; type: "int" }
39+ Parameter { name: "x"; type: "int" }
40+ Parameter { name: "y"; type: "int" }
41+ }
42+ Method {
43+ name: "press"
44+ Parameter { name: "touchId"; type: "int" }
45+ Parameter { name: "x"; type: "int" }
46+ Parameter { name: "y"; type: "int" }
47+ }
48+ Method {
49+ name: "release"
50+ Parameter { name: "touchId"; type: "int" }
51+ Parameter { name: "x"; type: "int" }
52+ Parameter { name: "y"; type: "int" }
53+ }
54+ Method {
55+ name: "stationary"
56+ Parameter { name: "touchId"; type: "int" }
57+ }
58+ }
59+}
tests/whitespace/check_whitespace.py+22−12
@@ -1,7 +1,7 @@
1#! /usr/bin/env python3
1#! /usr/bin/env python3
2
2
3#
3#
4−# Copyright (C) 2013 Canonical Ltd
4+# Copyright (C) 2013, 2014 Canonical Ltd
5#
5#
6# This program is free software: you can redistribute it and/or modify
6# This program is free software: you can redistribute it and/or modify
7# it under the terms of the GNU General Public License version 3 as
7# it under the terms of the GNU General Public License version 3 as
@@ -19,8 +19,8 @@
19#
19#
20
20
21#
21#
22−# Little helper program to test that source files do not contain trailing whitespace
22+# Little helper program to test that source files do not contain trailing
23−# or tab indentation.
23+# whitespace or tab indentation.
24#
24#
25# Usage: check_whitespace.py directory [ignore_prefix]
25# Usage: check_whitespace.py directory [ignore_prefix]
26#
26#
@@ -31,18 +31,20 @@
31# See the file_pat definition below for a list of files that are checked.
31# See the file_pat definition below for a list of files that are checked.
32#
32#
33
33
34+from __future__ import print_function
35+
34import argparse
36import argparse
35import os
37import os
36import re
38import re
37import sys
39import sys
38
40
39−# Print msg on stderr, preceded by program name and followed by newline
40
41
42+# Print msg on stderr, preceded by program name and followed by newline
41def error(msg):
43def error(msg):
42 print(os.path.basename(sys.argv[0]) + ": " + msg, file=sys.stderr)
44 print(os.path.basename(sys.argv[0]) + ": " + msg, file=sys.stderr)
43
45
44−# Function to raise errors encountered by os.walk
45
46
47+# Function to raise errors encountered by os.walk
46def raise_error(e):
48def raise_error(e):
47 raise e
49 raise e
48
50
@@ -52,6 +54,7 @@ def raise_error(e):
52whitespace_pat = re.compile(r'.*[ \t]$')
54whitespace_pat = re.compile(r'.*[ \t]$')
53tab_indent_pat = re.compile(r'^ *\t')
55tab_indent_pat = re.compile(r'^ *\t')
54
56
57+
55def scan_for_bad_whitespace(file_path):
58def scan_for_bad_whitespace(file_path):
56 global tab_indent_pat, whitespace_pat
59 global tab_indent_pat, whitespace_pat
57 errors = []
60 errors = []
@@ -69,7 +72,9 @@ def scan_for_bad_whitespace(file_path):
69 plural = 's'
72 plural = 's'
70 else:
73 else:
71 plural = ''
74 plural = ''
75+ print(
76+ "%s: bad whitespace in line%s %s" % (
72− print("%s: bad whitespace in line%s %s" % (file_path, plural, ", ".join((str(i) for i in errors))))
77+ file_path, plural, ", ".join((str(i) for i in errors))))
73 elif errors:
78 elif errors:
74 print("%s: bad whitespace in multiple lines" % file_path)
79 print("%s: bad whitespace in multiple lines" % file_path)
75 if newlines_at_end:
80 if newlines_at_end:
@@ -78,15 +83,20 @@ def scan_for_bad_whitespace(file_path):
78
83
79# Parse args
84# Parse args
80
85
86+parser = argparse.ArgumentParser(
81−parser = argparse.ArgumentParser(description = 'Test that source files do not contain trailing whitespace.')
87+ description='Test that source files do not contain trailing whitespace.')
88+parser.add_argument(
89+ 'dir', nargs=1,
82−parser.add_argument('dir', nargs = 1, help = 'The directory to (recursively) search for source files')
90+ help='The directory to (recursively) search for source files')
91+parser.add_argument(
83−parser.add_argument('ignore_prefix', nargs = '?', default=None,
92+ 'ignore_prefix', nargs='?', default=None,
84− help = 'Ignore source files with a path that starts with the given prefix.')
93+ help='Ignore source files with a path that starts with the given prefix.')
85args = parser.parse_args()
94args = parser.parse_args()
86
95
87# Files we want to check for trailing whitespace.
96# Files we want to check for trailing whitespace.
88
97
98+file_pat = (
89−file_pat = r'(.*\.(c|cpp|h|hpp|hh|in|install|js|py|qml|sh)$)|(.*CMakeLists\.txt$)'
99+ r'(.*\.(c|cpp|h|hpp|hh|in|install|js|py|qml|sh)$)|(.*CMakeLists\.txt$)')
90pat = re.compile(file_pat)
100pat = re.compile(file_pat)
91
101
92# Find all the files with matching file extension in the specified
102# Find all the files with matching file extension in the specified
@@ -97,7 +107,7 @@ ignore = args.ignore_prefix and os.path.abspath(args.ignore_prefix) or None
97
107
98found_whitespace = False
108found_whitespace = False
99try:
109try:
100− for root, dirs, files in os.walk(directory, onerror = raise_error):
110+ for root, dirs, files in os.walk(directory, onerror=raise_error):
101 for file in files:
111 for file in files:
102 path = os.path.join(root, file)
112 path = os.path.join(root, file)
103 if not (ignore and path.startswith(ignore)) and pat.match(file):
113 if not (ignore and path.startswith(ignore)) and pat.match(file):
tools/scopetool.cpp−2
@@ -77,8 +77,6 @@ int main(int argc, char *argv[])
77 tracker.reset(new RegistryTracker(extraScopes, systemScopes, serverScopes));
77 tracker.reset(new RegistryTracker(extraScopes, systemScopes, serverScopes));
78 }
78 }
79
79
80− resolveIconTheme();
81−
82 bindtextdomain("unity8", translationDirectory().toUtf8().data());
80 bindtextdomain("unity8", translationDirectory().toUtf8().data());
83
81
84 QQuickView* view = new QQuickView();
82 QQuickView* view = new QQuickView();