Merge lp:~bzoltan/ubuntu-ui-toolkit/Landing-2017-03-06 into lp:ubuntu-ui-toolkit
- Landing-2017-03-06
- Merge into trunk
Proposed by
Zoltan Balogh
Status: | Merged |
---|---|
Approved by: | Zoltan Balogh |
Approved revision: | no longer in the source branch. |
Merged at revision: | 1389 |
Proposed branch: | lp:~bzoltan/ubuntu-ui-toolkit/Landing-2017-03-06 |
Merge into: | lp:ubuntu-ui-toolkit |
Diff against target: |
1395 lines (+474/-143) 41 files modified
components.api (+1/-0) debian/changelog (+40/-0) examples/ubuntu-ui-toolkit-gallery/Toggles.qml (+43/-0) src/UbuntuToolkit/menu.cpp (+2/-1) src/UbuntuToolkit/menubar.cpp (+2/-1) src/UbuntuToolkit/menugroup.cpp (+2/-1) src/UbuntuToolkit/privates/uccontenthub.cpp (+45/-45) src/UbuntuToolkit/privates/uccontenthub_p.h (+17/-14) src/UbuntuToolkit/sortfiltermodel.cpp (+5/-2) src/UbuntuToolkit/ucapplication.cpp (+0/-3) src/UbuntuToolkit/ucmainwindow.cpp (+9/-7) src/UbuntuToolkit/ucmainwindow_p.h (+2/-0) src/UbuntuToolkit/ucqquickimageextension.cpp (+53/-2) src/UbuntuToolkit/ucqquickimageextension_p.h (+1/-0) src/UbuntuToolkit/ucslotslayout.cpp (+1/-0) src/UbuntuToolkit/ucstylehints.cpp (+1/-0) src/imports/Components/1.3/ListItemPopover.qml (+2/-1) src/imports/Components/1.3/OptionSelector.qml (+6/-0) src/imports/Components/1.3/TextField.qml (+6/-1) src/imports/Components/1.3/UbuntuListView.qml (+1/-0) src/imports/Components/ListItems/1.3/LabelVisual.qml (+2/-1) src/imports/Components/ListItems/1.3/ThinDivider.qml (+2/-2) src/imports/Components/Popups/1.3/popupUtils.js (+1/-1) src/imports/Components/Themes/Ambiance/1.3/CheckBoxStyle.qml (+17/-3) src/imports/Components/Themes/Ambiance/1.3/PageHeaderStyle.qml (+2/-1) tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/popups.py (+2/-0) tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_listitem.ListItemTestCase.qml (+9/-2) tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_listitem.py (+13/-1) tests/unit/components/tst_sortfiltermodel.qml (+14/-3) tests/unit/contenthub/tst_contenthub.cpp (+17/-22) tests/unit/mainwindow/VisualRoot.qml (+0/-1) tests/unit/mainwindow/tst_mainwindow.cpp (+33/-10) tests/unit/qquick_image_extension/borderInName.sci (+0/-7) tests/unit/qquick_image_extension/data/borderInName.sci (+7/-0) tests/unit/qquick_image_extension/data/hundred_faces.qml (+13/-0) tests/unit/qquick_image_extension/data/test@18.sci (+7/-0) tests/unit/qquick_image_extension/qquick_image_extension.pro (+1/-1) tests/unit/qquick_image_extension/test@18.sci (+0/-7) tests/unit/qquick_image_extension/tst_qquick_image_extension.cpp (+38/-3) tests/unit/visual/tst_optionselector.13.qml (+9/-0) tests/unit/visual/tst_toggles.13.qml (+48/-0) |
To merge this branch: | bzr merge lp:~bzoltan/ubuntu-ui-toolkit/Landing-2017-03-06 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Zoltan Balogh | Approve | ||
Review via email: mp+319093@code.launchpad.net |
Commit message
landing
Description of the change
landing
To post a comment you must log in.
Revision history for this message
Zoltan Balogh (bzoltan) : | # |
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'components.api' |
2 | --- components.api 2017-01-26 11:59:45 +0000 |
3 | +++ components.api 2017-03-06 16:02:52 +0000 |
4 | @@ -731,6 +731,7 @@ |
5 | Ubuntu.Components.OptionSelector 1.3: Empty |
6 | property bool colourImage |
7 | property double containerHeight |
8 | + readonly property int count |
9 | property bool currentlyExpanded |
10 | property Component delegate |
11 | property bool expanded |
12 | |
13 | === modified file 'debian/changelog' |
14 | --- debian/changelog 2017-01-30 11:30:04 +0000 |
15 | +++ debian/changelog 2017-03-06 16:02:52 +0000 |
16 | @@ -1,3 +1,43 @@ |
17 | +ubuntu-ui-toolkit (1.3.2184+17.04) UNRELEASED; urgency=medium |
18 | + |
19 | + [ Adnane Belmadiaf ] |
20 | + * Add support for CheckBox label when set |
21 | + * Add more tests for checkbox. Fixes LP: #1333228, LP: #1442851. |
22 | + * Make sure we resets partial text input from the input method. |
23 | + Fixes LP: #1630872. |
24 | + * Fix ListItem title/subtitle alignment & elide in RTL mode. |
25 | + Fixes LP: #1665944. |
26 | + * Fix PageHeader title alignment & elide in RTL mode. Fixes LP: #1665942. |
27 | + * Fix UbuntuListView docs. Fixes LP: #1486940. |
28 | + * Add count prop to OptionSelector. Fixes LP: #1341559. |
29 | + * Replace the hardcoded color with a theme color. Fixes LP: #1664758. |
30 | + * Fix the import statement for Menu, MenuBar and MenuGroup. |
31 | + Fixes LP: #1660604. |
32 | + |
33 | + [ Albert Astals Cid ] |
34 | + * Fix memory leak in UCStyleHints |
35 | + * ThinDivider: Anchors can't be null, set to undefined |
36 | + * No need to call UCUnits::resolveResource to learn we just need to load it |
37 | + normally because the fact that we already loaded it normally means we need |
38 | + to load it normally. Fixes LP: #1558663. |
39 | + * Fix conditional jump or move depends on uninitialised value(s) |
40 | + |
41 | + [ Christian Dywan ] |
42 | + * Initialize UCApplication with no side effects. Fixes LP: #1662868. |
43 | + * Unit test case insensitive FilterBehavior.pattern. Fixes LP: #1663924. |
44 | + * ListItemPopover delegate should (in)visible as per action Bug 1662220: |
45 | + [ListItem] Popupmenu shows traces of disabled actions |
46 | + |
47 | + [ Olivier Tilloy ] |
48 | + * Check that window is not null before accessing its activeFocusItem property. |
49 | + Fixes LP: #1664620. |
50 | + |
51 | + [ Lukáš Tinkl ] |
52 | + * Unbreak the startup race between unity8/qtmir and UITK trying talk to |
53 | + content-hub. Fixes LP: #1663106. |
54 | + |
55 | + -- Zoltán Balogh <zoltan@bakter.hu> Mon, 06 Mar 2017 17:51:04 +0200 |
56 | + |
57 | ubuntu-ui-toolkit (1.3.2166+17.04.20170130) zesty; urgency=medium |
58 | |
59 | [ Andrea Bernabei ] |
60 | |
61 | === modified file 'examples/ubuntu-ui-toolkit-gallery/Toggles.qml' |
62 | --- examples/ubuntu-ui-toolkit-gallery/Toggles.qml 2015-04-25 08:18:45 +0000 |
63 | +++ examples/ubuntu-ui-toolkit-gallery/Toggles.qml 2017-03-06 16:02:52 +0000 |
64 | @@ -55,6 +55,49 @@ |
65 | checked: true |
66 | } |
67 | } |
68 | + |
69 | + TemplateRow { |
70 | + title: i18n.tr("Checkbox with label") |
71 | + |
72 | + CheckBox { |
73 | + objectName: "checkbox_checked_lbl" |
74 | + checked: true |
75 | + text: "This a checkbox label" |
76 | + } |
77 | + } |
78 | + |
79 | + TemplateRow { |
80 | + title: i18n.tr("Disabled checkbox with label") |
81 | + |
82 | + CheckBox { |
83 | + objectName: "checkbox_disabled_checked_lbl" |
84 | + checked: true |
85 | + enabled: false |
86 | + text: "This a checkbox label" |
87 | + } |
88 | + } |
89 | + |
90 | + TemplateRow { |
91 | + title: i18n.tr("Disabled checkbox with label") |
92 | + |
93 | + CheckBox { |
94 | + objectName: "checkbox_disabled_checked_lbl" |
95 | + checked: false |
96 | + enabled: false |
97 | + text: "This a checkbox label" |
98 | + } |
99 | + } |
100 | + |
101 | + TemplateRow { |
102 | + title: i18n.tr("Checkbox with multiline label") |
103 | + |
104 | + CheckBox { |
105 | + objectName: "checkbox_checked_lbl" |
106 | + checked: true |
107 | + text: "This is a checkbox with a built-in label spanning several lines that won't be ellipsized but increase in height instead" |
108 | + width: parent.width |
109 | + } |
110 | + } |
111 | } |
112 | |
113 | |
114 | |
115 | === modified file 'src/UbuntuToolkit/menu.cpp' |
116 | --- src/UbuntuToolkit/menu.cpp 2016-09-09 18:16:57 +0000 |
117 | +++ src/UbuntuToolkit/menu.cpp 2017-03-06 16:02:52 +0000 |
118 | @@ -303,7 +303,7 @@ |
119 | |
120 | /*! |
121 | * \qmltype Menu |
122 | - * \inqmlmodule Ubuntu.Components |
123 | + * \inqmlmodule Ubuntu.Components.Labs |
124 | * \ingroup ubuntu |
125 | * \brief Menu defines a context menu or submenu structure of a MenuBar |
126 | * |
127 | @@ -311,6 +311,7 @@ |
128 | * \qml |
129 | * import QtQuick 2.4 |
130 | * import Ubuntu.Components 1.3 |
131 | + * import Ubuntu.Components.Labs 1.0 |
132 | * Menu { |
133 | * text: "&File" |
134 | * |
135 | |
136 | === modified file 'src/UbuntuToolkit/menubar.cpp' |
137 | --- src/UbuntuToolkit/menubar.cpp 2016-09-09 17:49:07 +0000 |
138 | +++ src/UbuntuToolkit/menubar.cpp 2017-03-06 16:02:52 +0000 |
139 | @@ -104,7 +104,7 @@ |
140 | |
141 | /*! |
142 | * \qmltype MenuBar |
143 | - * \inqmlmodule Ubuntu.Components 1.3 |
144 | + * \inqmlmodule Ubuntu.Components.Labs |
145 | * \ingroup ubuntu |
146 | * \brief MenuBar defines an application menu bar structure |
147 | * |
148 | @@ -112,6 +112,7 @@ |
149 | * \qml |
150 | * import QtQuick 2.4 |
151 | * import Ubuntu.Components 1.3 |
152 | + * import Ubuntu.Components.Labs 1.0 |
153 | * MainView { |
154 | * MenuBar { |
155 | * Menu { |
156 | |
157 | === modified file 'src/UbuntuToolkit/menugroup.cpp' |
158 | --- src/UbuntuToolkit/menugroup.cpp 2016-09-09 17:49:07 +0000 |
159 | +++ src/UbuntuToolkit/menugroup.cpp 2017-03-06 16:02:52 +0000 |
160 | @@ -23,7 +23,7 @@ |
161 | |
162 | /*! |
163 | * \qmltype MenuGroup |
164 | - * \inqmlmodule Ubuntu.Components |
165 | + * \inqmlmodule Ubuntu.Components.Labs |
166 | * \ingroup ubuntu |
167 | * \brief Logical list of items for a menu. |
168 | * |
169 | @@ -31,6 +31,7 @@ |
170 | * \qml |
171 | * import QtQuick 2.4 |
172 | * import Ubuntu.Components 1.3 |
173 | + * import Ubuntu.Components.Labs 1.0 |
174 | * Menu { |
175 | * text: "Edit" |
176 | * |
177 | |
178 | === modified file 'src/UbuntuToolkit/privates/uccontenthub.cpp' |
179 | --- src/UbuntuToolkit/privates/uccontenthub.cpp 2017-01-26 14:29:30 +0000 |
180 | +++ src/UbuntuToolkit/privates/uccontenthub.cpp 2017-03-06 16:02:52 +0000 |
181 | @@ -21,8 +21,10 @@ |
182 | #include <QtCore/QLoggingCategory> |
183 | #include <QtCore/QMimeData> |
184 | #include <QtDBus/QDBusConnection> |
185 | +#include <QtDBus/QDBusConnectionInterface> |
186 | #include <QtDBus/QDBusInterface> |
187 | #include <QtDBus/QDBusReply> |
188 | +#include <QtDBus/QDBusServiceWatcher> |
189 | #include <QtQuick/QQuickItem> |
190 | |
191 | Q_LOGGING_CATEGORY(ucContentHub, "ubuntu.components.UCContentHub", QtMsgType::QtWarningMsg) |
192 | @@ -40,11 +42,17 @@ |
193 | UT_NAMESPACE_BEGIN |
194 | |
195 | UCContentHub::UCContentHub(QObject *parent) |
196 | - : QObject(parent), |
197 | - m_dbusIface(0), |
198 | - m_contentHubIface(0), |
199 | - m_canPaste(false), |
200 | - m_targetItem(0) |
201 | + : QObject(parent) |
202 | +{ |
203 | + if (QDBusConnection::sessionBus().interface()->isServiceRegistered(contentHubService)) { // content hub already running |
204 | + init(); |
205 | + } else { |
206 | + m_watcher = new QDBusServiceWatcher(contentHubService, QDBusConnection::sessionBus(), QDBusServiceWatcher::WatchForRegistration, this); |
207 | + connect(m_watcher, &QDBusServiceWatcher::serviceRegistered, this, &UCContentHub::init); |
208 | + } |
209 | +} |
210 | + |
211 | +void UCContentHub::init() |
212 | { |
213 | m_dbusIface = new QDBusInterface(dbusService, |
214 | dbusObjectPath, |
215 | @@ -76,24 +84,13 @@ |
216 | SLOT(onPasteboardChanged()) |
217 | ); |
218 | |
219 | - m_canPaste = checkPasteFormats(); |
220 | - } |
221 | -} |
222 | - |
223 | -UCContentHub::~UCContentHub() |
224 | -{ |
225 | - if (m_dbusIface) { |
226 | - delete m_dbusIface; |
227 | - } |
228 | - |
229 | - if (m_contentHubIface) { |
230 | - delete m_contentHubIface; |
231 | + onPasteboardChanged(); |
232 | } |
233 | } |
234 | |
235 | void UCContentHub::requestPaste(QQuickItem *targetItem) |
236 | { |
237 | - if (!m_contentHubIface->isValid()) { |
238 | + if (!m_contentHubIface || !m_contentHubIface->isValid()) { |
239 | CONTENT_HUB_TRACE("Invalid Content Hub DBusInterface"); |
240 | return; |
241 | } |
242 | @@ -106,12 +103,12 @@ |
243 | m_contentHubIface->call(QStringLiteral("RequestPasteByAppId"), appProfile); |
244 | } |
245 | |
246 | -bool UCContentHub::canPaste() |
247 | +bool UCContentHub::canPaste() const |
248 | { |
249 | return m_canPaste; |
250 | } |
251 | |
252 | -void UCContentHub::onPasteSelected(QString appId, QByteArray mimedata, bool pasteAsRichText) |
253 | +void UCContentHub::onPasteSelected(const QString &appId, const QByteArray &mimedata, bool pasteAsRichText) |
254 | { |
255 | if (getAppProfile() != appId) { |
256 | return; |
257 | @@ -138,15 +135,39 @@ |
258 | |
259 | void UCContentHub::onPasteboardChanged() |
260 | { |
261 | - if (checkPasteFormats() != m_canPaste) { |
262 | - m_canPaste = !m_canPaste; |
263 | + if (!m_contentHubIface || !m_contentHubIface->isValid()) { |
264 | + CONTENT_HUB_TRACE("Invalid Content Hub DBusInterface"); |
265 | + return; |
266 | + } |
267 | + |
268 | + QDBusPendingCall pcall = m_contentHubIface->asyncCall(QStringLiteral("PasteFormats")); |
269 | + QDBusPendingCallWatcher * watcher = new QDBusPendingCallWatcher(pcall, this); |
270 | + connect(watcher, &QDBusPendingCallWatcher::finished, [this](QDBusPendingCallWatcher * call) { |
271 | + QDBusPendingReply<QStringList> reply = *call; |
272 | + call->deleteLater(); |
273 | + if (reply.isValid()) { |
274 | + // TODO: ContentHub clipboard keeps a list of all available paste formats. |
275 | + // Probably apps could make use of this information to check if a specific |
276 | + // data type is available, instead of only checking if list is empty or not. |
277 | + // (LP: #1657111) |
278 | + setCanPaste(!reply.value().isEmpty()); |
279 | + } else { |
280 | + CONTENT_HUB_TRACE("Invalid return from DBus call PasteFormats"); |
281 | + } |
282 | + }); |
283 | +} |
284 | + |
285 | +void UCContentHub::setCanPaste(bool value) |
286 | +{ |
287 | + if (value != m_canPaste) { |
288 | + m_canPaste = value; |
289 | Q_EMIT canPasteChanged(); |
290 | } |
291 | } |
292 | |
293 | -QString UCContentHub::getAppProfile() |
294 | +QString UCContentHub::getAppProfile() const |
295 | { |
296 | - if (!m_dbusIface->isValid()) { |
297 | + if (!m_dbusIface || !m_dbusIface->isValid()) { |
298 | CONTENT_HUB_TRACE("Invalid DBus DBusInterface"); |
299 | return QString(); |
300 | } |
301 | @@ -194,25 +215,4 @@ |
302 | return mimeData; |
303 | } |
304 | |
305 | -bool UCContentHub::checkPasteFormats() |
306 | -{ |
307 | - if (!m_contentHubIface->isValid()) { |
308 | - CONTENT_HUB_TRACE("Invalid Content Hub DBusInterface"); |
309 | - return false; |
310 | - } |
311 | - |
312 | - QDBusReply<QStringList> reply = m_contentHubIface->call(QStringLiteral("PasteFormats")); |
313 | - if (reply.isValid()) { |
314 | - // TODO: ContentHub clipboard keeps a list of all available paste formats. |
315 | - // Probably apps could make use of this information to check if a specific |
316 | - // data type is available, instead of only checking if list is empty or not. |
317 | - // (LP: #1657111) |
318 | - return !reply.value().isEmpty(); |
319 | - } else { |
320 | - CONTENT_HUB_TRACE("Invalid return from DBus call PasteFormats"); |
321 | - } |
322 | - |
323 | - return false; |
324 | -} |
325 | - |
326 | UT_NAMESPACE_END |
327 | |
328 | === modified file 'src/UbuntuToolkit/privates/uccontenthub_p.h' |
329 | --- src/UbuntuToolkit/privates/uccontenthub_p.h 2017-01-17 19:30:01 +0000 |
330 | +++ src/UbuntuToolkit/privates/uccontenthub_p.h 2017-03-06 16:02:52 +0000 |
331 | @@ -25,6 +25,7 @@ |
332 | |
333 | class QMimeData; |
334 | class QDBusInterface; |
335 | +class QDBusServiceWatcher; |
336 | class QQuickItem; |
337 | |
338 | UT_NAMESPACE_BEGIN |
339 | @@ -32,35 +33,37 @@ |
340 | class UBUNTUTOOLKIT_EXPORT UCContentHub : public QObject |
341 | { |
342 | Q_OBJECT |
343 | - |
344 | + friend class tst_UCContentHub; |
345 | Q_PROPERTY(bool canPaste READ canPaste NOTIFY canPasteChanged) |
346 | |
347 | public: |
348 | - UCContentHub(QObject* parent = 0); |
349 | - ~UCContentHub(); |
350 | + UCContentHub(QObject* parent = nullptr); |
351 | + ~UCContentHub() = default; |
352 | |
353 | Q_INVOKABLE void requestPaste(QQuickItem *targetItem); |
354 | |
355 | - bool canPaste(); |
356 | - QString getAppProfile(); |
357 | + bool canPaste() const; |
358 | + QString getAppProfile() const; |
359 | QMimeData* deserializeMimeData(const QByteArray &serializedMimeData); |
360 | |
361 | Q_SIGNALS: |
362 | void pasteSelected(QQuickItem *targetItem, const QString &data); |
363 | void canPasteChanged(); |
364 | |
365 | -public Q_SLOTS: |
366 | - void onPasteSelected(QString appId, QByteArray mimedata, bool pasteAsRichText); |
367 | +private Q_SLOTS: |
368 | + void init(); |
369 | + void onPasteSelected(const QString &appId, const QByteArray &mimedata, bool pasteAsRichText); |
370 | void onPasteboardChanged(); |
371 | |
372 | private: |
373 | - bool checkPasteFormats(); |
374 | - |
375 | - QDBusInterface *m_dbusIface; |
376 | - QDBusInterface *m_contentHubIface; |
377 | - |
378 | - bool m_canPaste; |
379 | - QQuickItem *m_targetItem; |
380 | + void setCanPaste(bool value); |
381 | + QDBusInterface *m_dbusIface{nullptr}; |
382 | + QDBusInterface *m_contentHubIface{nullptr}; |
383 | + |
384 | + bool m_canPaste{false}; |
385 | + QQuickItem *m_targetItem{nullptr}; |
386 | + |
387 | + QDBusServiceWatcher * m_watcher{nullptr}; |
388 | }; |
389 | |
390 | UT_NAMESPACE_END |
391 | |
392 | === modified file 'src/UbuntuToolkit/sortfiltermodel.cpp' |
393 | --- src/UbuntuToolkit/sortfiltermodel.cpp 2016-09-12 09:03:50 +0000 |
394 | +++ src/UbuntuToolkit/sortfiltermodel.cpp 2017-03-06 16:02:52 +0000 |
395 | @@ -52,7 +52,8 @@ |
396 | * } |
397 | * ListElement { |
398 | * title: "Elephants Dream" |
399 | - * producer: "Blender" |
400 | + * // lowercase b |
401 | + * producer: "blender" |
402 | * } |
403 | * ListElement { |
404 | * title: "Big Buck Bunny" |
405 | @@ -69,7 +70,8 @@ |
406 | * sortCaseSensitivity: Qt.CaseInsensitive |
407 | * |
408 | * filter.property: "producer" |
409 | - * filter.pattern: /blender/ |
410 | + * // case insensitive matches |
411 | + * filter.pattern: /blender/i |
412 | * } |
413 | * |
414 | * ListView { |
415 | @@ -154,6 +156,7 @@ |
416 | * \li /possible/ matches anywhere in a word, so both "impossible" and "possible". |
417 | * \li /^sign/ matches "sign". But not "assignment" because ^ means start. |
418 | * \li /vest$/ matches "safety vest" and "vest" but not "vested". |
419 | + * \li /bar/i matches "bar", "Bar" or "BAR" regardless of case. |
420 | * \endlist |
421 | * |
422 | * For more advanced uses it's recommended to read up on Javascript regular expressions. |
423 | |
424 | === modified file 'src/UbuntuToolkit/ucapplication.cpp' |
425 | --- src/UbuntuToolkit/ucapplication.cpp 2017-01-12 15:20:31 +0000 |
426 | +++ src/UbuntuToolkit/ucapplication.cpp 2017-03-06 16:02:52 +0000 |
427 | @@ -39,8 +39,6 @@ |
428 | UCApplication::UCApplication(QObject* parent) : QObject(parent), m_context(0) |
429 | , m_inputMethod(QGuiApplication::inputMethod()) |
430 | { |
431 | - // Unset organization by default to skip an extra folder component |
432 | - QCoreApplication::setOrganizationName(QStringLiteral("")); |
433 | // Make sure we receive application name changes from C++ modules |
434 | connect(QCoreApplication::instance(), &QCoreApplication::applicationNameChanged, |
435 | this, &UCApplication::applicationNameChanged); |
436 | @@ -70,7 +68,6 @@ |
437 | to how Unity uses it to distinguish running applications. |
438 | */ |
439 | QCoreApplication::setApplicationName(applicationName); |
440 | - QCoreApplication::setOrganizationName(QCoreApplication::organizationName()); |
441 | /* |
442 | Ensure that LocalStorage and WebKit use the same location |
443 | Docs are ambiguous: in practise applicationName is ignored by default |
444 | |
445 | === modified file 'src/UbuntuToolkit/ucmainwindow.cpp' |
446 | --- src/UbuntuToolkit/ucmainwindow.cpp 2017-01-18 17:23:48 +0000 |
447 | +++ src/UbuntuToolkit/ucmainwindow.cpp 2017-03-06 16:02:52 +0000 |
448 | @@ -163,11 +163,7 @@ |
449 | return; |
450 | |
451 | d->m_applicationName = applicationName; |
452 | - |
453 | - if (applicationName != QStringLiteral("")) { |
454 | - UbuntuI18n::instance()->setDomain(applicationName); |
455 | - UCApplication::instance()->setApplicationName(applicationName); |
456 | - } |
457 | + updateApplication(applicationName, d->m_organizationName); |
458 | Q_EMIT applicationNameChanged(applicationName); |
459 | } |
460 | |
461 | @@ -192,11 +188,17 @@ |
462 | return; |
463 | |
464 | d->m_organizationName = organizationName; |
465 | + updateApplication(d->m_applicationName, organizationName); |
466 | + Q_EMIT organizationNameChanged(organizationName); |
467 | +} |
468 | |
469 | - if (organizationName != QStringLiteral("")) { |
470 | +void UCMainWindow::updateApplication(QString applicationName, QString organizationName) |
471 | +{ |
472 | + if (applicationName != QStringLiteral("")) { |
473 | + UbuntuI18n::instance()->setDomain(applicationName); |
474 | QCoreApplication::setOrganizationName(organizationName); |
475 | + UCApplication::instance()->setApplicationName(applicationName); |
476 | } |
477 | - Q_EMIT organizationNameChanged(organizationName); |
478 | } |
479 | |
480 | /*! |
481 | |
482 | === modified file 'src/UbuntuToolkit/ucmainwindow_p.h' |
483 | --- src/UbuntuToolkit/ucmainwindow_p.h 2017-01-16 16:52:57 +0000 |
484 | +++ src/UbuntuToolkit/ucmainwindow_p.h 2017-03-06 16:02:52 +0000 |
485 | @@ -76,6 +76,8 @@ |
486 | #endif |
487 | |
488 | private: |
489 | + void updateApplication(QString applicationName, QString organizationName); |
490 | + |
491 | Q_DECLARE_PRIVATE(UCMainWindow) |
492 | }; |
493 | |
494 | |
495 | === modified file 'src/UbuntuToolkit/ucqquickimageextension.cpp' |
496 | --- src/UbuntuToolkit/ucqquickimageextension.cpp 2016-09-12 09:03:50 +0000 |
497 | +++ src/UbuntuToolkit/ucqquickimageextension.cpp 2017-03-06 16:02:52 +0000 |
498 | @@ -22,7 +22,13 @@ |
499 | #include <QtCore/QFile> |
500 | #include <QtCore/QFileInfo> |
501 | #include <QtGui/QGuiApplication> |
502 | +#include <QtQuick/private/qquickitem_p.h> |
503 | #include <QtQuick/private/qquickimagebase_p.h> |
504 | +#include <QtQuick/private/qquickpixmapcache_p.h> |
505 | + |
506 | +#define foreach Q_FOREACH |
507 | +#include <QtQml/private/qqmlengine_p.h> |
508 | +#undef foreach |
509 | |
510 | #include "ucunits_p.h" |
511 | |
512 | @@ -61,11 +67,35 @@ |
513 | return m_source; |
514 | } |
515 | |
516 | + |
517 | void UCQQuickImageExtension::setSource(const QUrl& url) |
518 | { |
519 | if (url != m_source) { |
520 | m_source = url; |
521 | - reloadSource(); |
522 | + // We need to wait until the component is complete |
523 | + // so that m_image->sourceSize() is actually valid |
524 | + if (QQuickItemPrivate::get(m_image)->componentComplete) { |
525 | + reloadSource(); |
526 | + } else { |
527 | + // This is a bit convoluted but i couldn't find a better way to get notified of when |
528 | + // the image actually finishes constructing. |
529 | + // Since what we're interested in reloadSource() is the image having the sourceSize set, |
530 | + // what we do is connect to the sourceSizeChanged signal. |
531 | + // The problem is that this signal isn't fired if the Image {} doesn't have sourceSize set |
532 | + // so we tell the engine to fire the sourceSizeChanged signal when the image finishes constructing |
533 | + // This way if the Image {} has a sourceSize set the lambda gets called because of it |
534 | + // and if there's no sourceSize set the lambda gets called because we registered the finalize callback |
535 | + |
536 | + connect(m_image, &QQuickImageBase::sourceSizeChanged, |
537 | + this, |
538 | + [&] { |
539 | + QObject::disconnect(m_image, &QQuickImageBase::sourceSizeChanged, this, nullptr); |
540 | + reloadSource(); |
541 | + }); |
542 | + |
543 | + QQmlEnginePrivate *engPriv = QQmlEnginePrivate::get(qmlEngine(m_image)); |
544 | + engPriv->registerFinalizeCallback(m_image, m_image->metaObject()->indexOfSignal("sourceSizeChanged()")); |
545 | + } |
546 | } |
547 | } |
548 | |
549 | @@ -80,6 +110,25 @@ |
550 | return; |
551 | } |
552 | |
553 | + // If the url we're trying to load is already in the cache and |
554 | + // the devicePixelRatio is 1, we save calling UCUnits::resolveResource |
555 | + // and just set that image directly. |
556 | + // UCUnits::resolveResource is not cheap (does a stat on disk) |
557 | + if (qFuzzyCompare(qGuiApp->devicePixelRatio(), (qreal)1.0)) { |
558 | + QSize ss = m_image->sourceSize(); |
559 | + if (ss.isNull() && m_image->image().isNull()) { |
560 | + // For some reason QQuickImage returns 0x0 as sourceSize |
561 | + // when the sourceSize is not set (and the image has not yet been loaded) |
562 | + // so set it back to -1x-1 |
563 | + ss = QSize(-1, -1); |
564 | + } |
565 | + |
566 | + if (QQuickPixmap::isCached(m_source, ss)) { |
567 | + m_image->setSource(m_source); |
568 | + return; |
569 | + } |
570 | + } |
571 | + |
572 | QString resolved = UCUnits::instance()->resolveResource(m_source); |
573 | |
574 | if (resolved.isEmpty()) { |
575 | @@ -98,7 +147,9 @@ |
576 | || selectedFilePath.endsWith(QStringLiteral(".svgz"))) { |
577 | // Take care to pass the original fragment |
578 | QUrl selectedFileUrl(QUrl::fromLocalFile(selectedFilePath)); |
579 | - selectedFileUrl.setFragment(fragment); |
580 | + if (m_source.hasFragment()) { |
581 | + selectedFileUrl.setFragment(fragment); |
582 | + } |
583 | m_image->setSource(selectedFileUrl); |
584 | } else { |
585 | // Need to scale the pixel-based image to suit the devicePixelRatio setting ourselves. |
586 | |
587 | === modified file 'src/UbuntuToolkit/ucqquickimageextension_p.h' |
588 | --- src/UbuntuToolkit/ucqquickimageextension_p.h 2016-09-09 17:49:07 +0000 |
589 | +++ src/UbuntuToolkit/ucqquickimageextension_p.h 2017-03-06 16:02:52 +0000 |
590 | @@ -19,6 +19,7 @@ |
591 | #ifndef UCQQUICKIMAGEEXTENSION_P_H |
592 | #define UCQQUICKIMAGEEXTENSION_P_H |
593 | |
594 | +#include <QtCore/QEvent> |
595 | #include <QtCore/QByteArray> |
596 | #include <QtCore/QObject> |
597 | #include <QtCore/QSharedPointer> |
598 | |
599 | === modified file 'src/UbuntuToolkit/ucslotslayout.cpp' |
600 | --- src/UbuntuToolkit/ucslotslayout.cpp 2016-10-07 14:33:47 +0000 |
601 | +++ src/UbuntuToolkit/ucslotslayout.cpp 2017-03-06 16:02:52 +0000 |
602 | @@ -32,6 +32,7 @@ |
603 | : QQuickItemPrivate() |
604 | , mainSlot(Q_NULLPTR) |
605 | , m_parentItem(Q_NULLPTR) |
606 | + , mainSlotHeight(0) |
607 | , maxSlotsHeight(0) |
608 | , _q_cachedHeight(-1) |
609 | , maxNumberOfLeadingSlots(1) |
610 | |
611 | === modified file 'src/UbuntuToolkit/ucstylehints.cpp' |
612 | --- src/UbuntuToolkit/ucstylehints.cpp 2016-09-12 09:03:50 +0000 |
613 | +++ src/UbuntuToolkit/ucstylehints.cpp 2017-03-06 16:02:52 +0000 |
614 | @@ -273,6 +273,7 @@ |
615 | |
616 | newBinding->setTarget(change->property()); |
617 | PropertyChange::setBinding(change, newBinding); |
618 | + m_propertyBackup << change; |
619 | } |
620 | } |
621 | |
622 | |
623 | === modified file 'src/imports/Components/1.3/ListItemPopover.qml' |
624 | --- src/imports/Components/1.3/ListItemPopover.qml 2015-07-01 12:06:34 +0000 |
625 | +++ src/imports/Components/1.3/ListItemPopover.qml 2017-03-06 16:02:52 +0000 |
626 | @@ -24,6 +24,7 @@ |
627 | contentWidth: units.gu(25) |
628 | |
629 | delegate: ListItem { |
630 | + visible: action.visible |
631 | contentItem.anchors { |
632 | leftMargin: units.gu(2) |
633 | rightMargin: units.gu(2) |
634 | @@ -35,7 +36,7 @@ |
635 | Label { |
636 | anchors.verticalCenter: parent.verticalCenter |
637 | text: action.text |
638 | - color: '#5D5D5D' |
639 | + color: theme.palette.normal.backgroundText |
640 | } |
641 | |
642 | onClicked: popover.hide() |
643 | |
644 | === modified file 'src/imports/Components/1.3/OptionSelector.qml' |
645 | --- src/imports/Components/1.3/OptionSelector.qml 2016-08-22 10:18:57 +0000 |
646 | +++ src/imports/Components/1.3/OptionSelector.qml 2017-03-06 16:02:52 +0000 |
647 | @@ -155,6 +155,12 @@ |
648 | } |
649 | |
650 | /*! |
651 | + \qmlproperty int count |
652 | + This property holds the number of items in the OptionSelector. |
653 | + */ |
654 | + property alias count: list.count |
655 | + |
656 | + /*! |
657 | \qmlproperty int selectedIndex |
658 | The index of the currently selected element in our list. |
659 | */ |
660 | |
661 | === modified file 'src/imports/Components/1.3/TextField.qml' |
662 | --- src/imports/Components/1.3/TextField.qml 2017-01-18 13:00:07 +0000 |
663 | +++ src/imports/Components/1.3/TextField.qml 2017-03-06 16:02:52 +0000 |
664 | @@ -988,7 +988,12 @@ |
665 | name: control.hasClearButton && !control.readOnly ? "edit-clear" : "" |
666 | } |
667 | |
668 | - onClicked: editor.text = "" |
669 | + onClicked: { |
670 | + //FIXME: Invoke editor.clear() once the SDK moves to Qt 5.7 |
671 | + // http://doc.qt.io/qt-5/qml-qtquick-textinput.html#clear-method |
672 | + editor.text = ""; |
673 | + Qt.inputMethod.reset(); |
674 | + } |
675 | } |
676 | |
677 | // hint text |
678 | |
679 | === modified file 'src/imports/Components/1.3/UbuntuListView.qml' |
680 | --- src/imports/Components/1.3/UbuntuListView.qml 2016-10-06 15:02:31 +0000 |
681 | +++ src/imports/Components/1.3/UbuntuListView.qml 2017-03-06 16:02:52 +0000 |
682 | @@ -79,6 +79,7 @@ |
683 | |
684 | \qml |
685 | import QtQuick 2.4 |
686 | + import QtQuick.XmlListModel 2.0 |
687 | import Ubuntu.Components 1.3 |
688 | |
689 | UbuntuListView { |
690 | |
691 | === modified file 'src/imports/Components/ListItems/1.3/LabelVisual.qml' |
692 | --- src/imports/Components/ListItems/1.3/LabelVisual.qml 2016-01-27 13:58:29 +0000 |
693 | +++ src/imports/Components/ListItems/1.3/LabelVisual.qml 2017-03-06 16:02:52 +0000 |
694 | @@ -30,7 +30,8 @@ |
695 | return item.parent.hasOwnProperty("pointerTarget") || label.isInsideOverlay(item.parent) |
696 | } |
697 | |
698 | - elide: Text.ElideRight |
699 | + horizontalAlignment: Qt.application.layoutDirection == Qt.RightToLeft ? Text.AlignRight: Text.AlignLeft |
700 | + elide: Qt.application.layoutDirection == Qt.RightToLeft ? Text.ElideLeft: Text.ElideRight |
701 | color: selected |
702 | ? theme.palette.selected.backgroundText |
703 | : (secondary |
704 | |
705 | === modified file 'src/imports/Components/ListItems/1.3/ThinDivider.qml' |
706 | --- src/imports/Components/ListItems/1.3/ThinDivider.qml 2015-07-05 21:04:55 +0000 |
707 | +++ src/imports/Components/ListItems/1.3/ThinDivider.qml 2017-03-06 16:02:52 +0000 |
708 | @@ -47,8 +47,8 @@ |
709 | */ |
710 | Rectangle { |
711 | anchors { |
712 | - left: (parent) ? parent.left : null |
713 | - right: (parent) ? parent.right : null |
714 | + left: (parent) ? parent.left : undefined |
715 | + right: (parent) ? parent.right : undefined |
716 | } |
717 | height: (visible) ? units.dp(2) : 0 |
718 | // a private property to catch theme background color change |
719 | |
720 | === modified file 'src/imports/Components/Popups/1.3/popupUtils.js' |
721 | --- src/imports/Components/Popups/1.3/popupUtils.js 2017-01-16 17:03:26 +0000 |
722 | +++ src/imports/Components/Popups/1.3/popupUtils.js 2017-03-06 16:02:52 +0000 |
723 | @@ -72,7 +72,7 @@ |
724 | |
725 | var popupObject; |
726 | // If there's an active item, save it so we can restore it later |
727 | - var prevFocusItem = (typeof window !== "undefined") ? window.activeFocusItem : null; |
728 | + var prevFocusItem = (typeof window !== "undefined") && window ? window.activeFocusItem : null; |
729 | if (params !== undefined) { |
730 | popupObject = popupComponent.createObject(rootObject, params); |
731 | } else { |
732 | |
733 | === modified file 'src/imports/Components/Themes/Ambiance/1.3/CheckBoxStyle.qml' |
734 | --- src/imports/Components/Themes/Ambiance/1.3/CheckBoxStyle.qml 2016-01-27 15:17:56 +0000 |
735 | +++ src/imports/Components/Themes/Ambiance/1.3/CheckBoxStyle.qml 2017-03-06 16:02:52 +0000 |
736 | @@ -57,7 +57,7 @@ |
737 | property real iconPadding: units.gu(0.4) |
738 | |
739 | implicitWidth: units.gu(2) |
740 | - implicitHeight: units.gu(2) |
741 | + implicitHeight: Math.max(checkBoxLbl.contentHeight, units.gu(2)) |
742 | |
743 | FocusShape { |
744 | } |
745 | @@ -65,10 +65,12 @@ |
746 | UbuntuShape { |
747 | id: background |
748 | anchors { |
749 | - fill: parent |
750 | margins: checkBoxStyle.backgroundPadding |
751 | } |
752 | - property real iconSize: Math.min(width, height) - 2*checkBoxStyle.iconPadding |
753 | + width: units.gu(2) |
754 | + height: units.gu(2) |
755 | + |
756 | + property real iconSize: units.gu(2) - 2*checkBoxStyle.iconPadding |
757 | |
758 | Icon { |
759 | color: checkBoxStyle.iconColor |
760 | @@ -164,4 +166,16 @@ |
761 | } |
762 | ] |
763 | } |
764 | + |
765 | + Label { |
766 | + id: checkBoxLbl |
767 | + text: styledItem.text |
768 | + anchors.left: background.right |
769 | + anchors.leftMargin: units.gu(1) |
770 | + anchors.right: parent.right |
771 | + height: parent.height |
772 | + enabled: styledItem.enabled |
773 | + visible: styledItem.text |
774 | + wrapMode: Text.WordWrap |
775 | + } |
776 | } |
777 | |
778 | === modified file 'src/imports/Components/Themes/Ambiance/1.3/PageHeaderStyle.qml' |
779 | --- src/imports/Components/Themes/Ambiance/1.3/PageHeaderStyle.qml 2016-09-19 07:24:45 +0000 |
780 | +++ src/imports/Components/Themes/Ambiance/1.3/PageHeaderStyle.qml 2017-03-06 16:02:52 +0000 |
781 | @@ -121,6 +121,7 @@ |
782 | id: titleLabel |
783 | objectName: "header_title_label" |
784 | text: styledItem.title |
785 | + horizontalAlignment: Qt.application.layoutDirection == Qt.RightToLeft ? Text.AlignRight: Text.AlignLeft |
786 | |
787 | anchors { |
788 | left: parent.left |
789 | @@ -131,7 +132,7 @@ |
790 | color: pageHeaderStyle.foregroundColor |
791 | font.weight: pageHeaderStyle.fontWeight |
792 | textSize: pageHeaderStyle.textSize |
793 | - elide: Text.ElideRight |
794 | + elide: Qt.application.layoutDirection == Qt.RightToLeft ? Text.ElideLeft: Text.ElideRight |
795 | } |
796 | } |
797 | } |
798 | |
799 | === modified file 'tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/popups.py' |
800 | --- tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/popups.py 2016-08-12 11:42:43 +0000 |
801 | +++ tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/popups.py 2017-03-06 16:02:52 +0000 |
802 | @@ -79,6 +79,8 @@ |
803 | name = introspection.get_classname_from_path(path) |
804 | if name == b'OverflowPanel': |
805 | return True |
806 | + if name == b'ListItemPopover': |
807 | + return True |
808 | |
809 | return False |
810 | |
811 | |
812 | === modified file 'tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_listitem.ListItemTestCase.qml' |
813 | --- tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_listitem.ListItemTestCase.qml 2015-03-03 13:20:06 +0000 |
814 | +++ tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_listitem.ListItemTestCase.qml 2017-03-06 16:02:52 +0000 |
815 | @@ -15,7 +15,7 @@ |
816 | */ |
817 | |
818 | import QtQuick 2.0 |
819 | -import Ubuntu.Components 1.2 |
820 | +import Ubuntu.Components 1.3 |
821 | |
822 | MainView { |
823 | width: units.gu(48) |
824 | @@ -25,7 +25,10 @@ |
825 | Page { |
826 | id: testPage |
827 | objectName: "test_page" |
828 | - title: listView.ViewItems.selectMode ? "In selection mode" : "No action triggered" |
829 | + header: PageHeader { |
830 | + objectName: 'test_header' |
831 | + title: listView.ViewItems.selectMode ? "In selection mode" : "No action triggered" |
832 | + } |
833 | ListView { |
834 | id: listView |
835 | objectName: "test_view" |
836 | @@ -40,6 +43,10 @@ |
837 | iconName: "delete" |
838 | objectName: 'delete_action' |
839 | onTriggered: testPage.title = objectName + " action triggered"; |
840 | + }, |
841 | + Action { |
842 | + visible: false |
843 | + objectName: 'invisible_action' |
844 | } |
845 | ] |
846 | } |
847 | |
848 | === modified file 'tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_listitem.py' |
849 | --- tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_listitem.py 2015-09-22 15:56:35 +0000 |
850 | +++ tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_listitem.py 2017-03-06 16:02:52 +0000 |
851 | @@ -17,6 +17,7 @@ |
852 | import os |
853 | |
854 | import ubuntuuitoolkit |
855 | +from autopilot.introspection import dbus |
856 | from ubuntuuitoolkit import tests |
857 | |
858 | |
859 | @@ -34,7 +35,9 @@ |
860 | 'UCListItem', objectName='listitem0') |
861 | self.test_page = self.main_view.select_single( |
862 | objectName='test_page') |
863 | - self.assertEqual(self.test_page.title, 'No action triggered') |
864 | + header = self.test_page.select_single( |
865 | + 'PageHeader', objectName='test_header') |
866 | + self.assertEqual(header.title, 'No action triggered') |
867 | |
868 | def test_trigger_delete(self): |
869 | self.test_listitem.trigger_leading_action('delete_action') |
870 | @@ -96,3 +99,12 @@ |
871 | 'UCListItem', objectName='listitem3') |
872 | listItem3.toggle_selected() |
873 | self.assertTrue(listItem3.selected) |
874 | + |
875 | + def test_popover(self): |
876 | + self.pointing_device.click_object(self.test_listitem, button=3) |
877 | + popover = self.main_view.wait_select_single( |
878 | + 'ListItemPopover', objectName='listItemContextMenu') |
879 | + self.assertRaises( |
880 | + ubuntuuitoolkit._custom_proxy_objects._common.ToolkitException, |
881 | + popover.click_action_button, 'invisible_action') |
882 | + popover.click_action_button('delete_action') |
883 | |
884 | === modified file 'tests/unit/components/tst_sortfiltermodel.qml' |
885 | --- tests/unit/components/tst_sortfiltermodel.qml 2015-03-03 13:20:06 +0000 |
886 | +++ tests/unit/components/tst_sortfiltermodel.qml 2017-03-06 16:02:52 +0000 |
887 | @@ -25,7 +25,7 @@ |
888 | id: things |
889 | ListElement { foo: "pub"; alpha: "bee"; num: 200 } |
890 | ListElement { foo: "den"; alpha: "cow"; num: 300 } |
891 | - ListElement { foo: "bar"; alpha: "ant"; num: 100 } |
892 | + ListElement { foo: "Bar"; alpha: "ant"; num: 100 } |
893 | } |
894 | |
895 | SortFilterModel { |
896 | @@ -72,6 +72,13 @@ |
897 | filter.pattern: /e/ |
898 | } |
899 | |
900 | + SortFilterModel { |
901 | + id: caseSensitivity |
902 | + model: things |
903 | + filter.property: "foo" |
904 | + filter.pattern: /bar/i |
905 | + } |
906 | + |
907 | function test_passthrough() { |
908 | compare(unmodified.count, things.count) |
909 | } |
910 | @@ -84,7 +91,7 @@ |
911 | compare(alphabetic.get(2).alpha, "cow") |
912 | |
913 | // Ensure different columns work also |
914 | - compare(alphaSecond.get(0).foo, "bar") |
915 | + compare(alphaSecond.get(0).foo, "Bar") |
916 | |
917 | // Descending |
918 | compare(alphabeticRe.sort.order, Qt.DescendingOrder) |
919 | @@ -98,7 +105,7 @@ |
920 | |
921 | // Changing roles |
922 | alphabetic.sort.property = "foo" |
923 | - compare(alphabetic.get(0).foo, "bar") |
924 | + compare(alphabetic.get(0).foo, "Bar") |
925 | compare(alphabetic.get(1).foo, "den") |
926 | compare(alphabetic.get(2).foo, "pub") |
927 | // Sanity check |
928 | @@ -120,4 +127,8 @@ |
929 | compare(bee.count, 1) |
930 | compare(bee.get(0).alpha, "bee") |
931 | } |
932 | + |
933 | + function test_case_sensitivity() { |
934 | + compare(caseSensitivity.get(0).foo, "Bar") |
935 | + } |
936 | } |
937 | |
938 | === modified file 'tests/unit/contenthub/tst_contenthub.cpp' |
939 | --- tests/unit/contenthub/tst_contenthub.cpp 2017-01-26 16:02:48 +0000 |
940 | +++ tests/unit/contenthub/tst_contenthub.cpp 2017-03-06 16:02:52 +0000 |
941 | @@ -68,12 +68,10 @@ |
942 | tst_UCContentHub() {} |
943 | |
944 | private: |
945 | - MockContentService *mockService; |
946 | - UCContentHub *contentHub; |
947 | - QSignalSpy *pasteRequestedSpy; |
948 | - QSignalSpy *pasteSelectedSpy; |
949 | - |
950 | - const int testTimeout = 5000; |
951 | + MockContentService *mockService{nullptr}; |
952 | + UCContentHub *contentHub{nullptr}; |
953 | + QSignalSpy *pasteRequestedSpy{nullptr}; |
954 | + QSignalSpy *pasteSelectedSpy{nullptr}; |
955 | |
956 | const QString dummyAppId = "DummyAppId"; |
957 | |
958 | @@ -143,11 +141,11 @@ |
959 | QDBusConnection connection = QDBusConnection::sessionBus(); |
960 | connection.registerObject("/", mockService); |
961 | connection.registerService("com.ubuntu.content.dbus.Service"); |
962 | - pasteRequestedSpy = new QSignalSpy(mockService, SIGNAL(PasteRequested())); |
963 | + pasteRequestedSpy = new QSignalSpy(mockService, &MockContentService::PasteRequested); |
964 | |
965 | qRegisterMetaType<QQuickItem*>(); |
966 | contentHub = new UCContentHub(); |
967 | - pasteSelectedSpy = new QSignalSpy(contentHub, SIGNAL(pasteSelected(QQuickItem*, const QString&))); |
968 | + pasteSelectedSpy = new QSignalSpy(contentHub, &UCContentHub::pasteSelected); |
969 | } |
970 | |
971 | void cleanupTestCase() |
972 | @@ -155,6 +153,7 @@ |
973 | delete pasteRequestedSpy; |
974 | delete pasteSelectedSpy; |
975 | delete contentHub; |
976 | + delete mockService; |
977 | } |
978 | |
979 | void cleanup() |
980 | @@ -187,8 +186,7 @@ |
981 | QMimeData textPaste; |
982 | textPaste.setText(sampleHtml); |
983 | contentHub->onPasteSelected(contentHub->getAppProfile(), serializeMimeData(textPaste), false); |
984 | - pasteSelectedSpy->wait(testTimeout); |
985 | - QCOMPARE(pasteSelectedSpy->count(), 1); |
986 | + QTRY_COMPARE(pasteSelectedSpy->count(), 1); |
987 | QList<QVariant> args = pasteSelectedSpy->takeFirst(); |
988 | QVERIFY(args.at(1).toString() == textPaste.text()); |
989 | } |
990 | @@ -198,8 +196,7 @@ |
991 | QMimeData htmlPaste; |
992 | htmlPaste.setHtml(sampleHtml); |
993 | contentHub->onPasteSelected(contentHub->getAppProfile(), serializeMimeData(htmlPaste), false); |
994 | - pasteSelectedSpy->wait(testTimeout); |
995 | - QCOMPARE(pasteSelectedSpy->count(), 1); |
996 | + QTRY_COMPARE(pasteSelectedSpy->count(), 1); |
997 | QList<QVariant> args = pasteSelectedSpy->takeFirst(); |
998 | QVERIFY(args.at(1).toString() == htmlPaste.text()); |
999 | } |
1000 | @@ -209,8 +206,7 @@ |
1001 | QMimeData htmlPaste; |
1002 | htmlPaste.setHtml(sampleHtml); |
1003 | contentHub->onPasteSelected(contentHub->getAppProfile(), serializeMimeData(htmlPaste), true); |
1004 | - pasteSelectedSpy->wait(testTimeout); |
1005 | - QCOMPARE(pasteSelectedSpy->count(), 1); |
1006 | + QTRY_COMPARE(pasteSelectedSpy->count(), 1); |
1007 | QList<QVariant> args = pasteSelectedSpy->takeFirst(); |
1008 | QVERIFY(args.at(1).toString() == htmlPaste.html()); |
1009 | } |
1010 | @@ -220,8 +216,7 @@ |
1011 | QMimeData textPaste; |
1012 | textPaste.setText(sampleText); |
1013 | contentHub->onPasteSelected(dummyAppId, serializeMimeData(textPaste), false); |
1014 | - pasteSelectedSpy->wait(testTimeout); |
1015 | - QCOMPARE(pasteSelectedSpy->count(), 0); |
1016 | + QTRY_COMPARE(pasteSelectedSpy->count(), 0); |
1017 | } |
1018 | |
1019 | void test_KeyboardShortcutOnTextField() |
1020 | @@ -230,10 +225,10 @@ |
1021 | testCase->rootObject()->forceActiveFocus(); |
1022 | QQuickItem *textField = testCase->findItem<QQuickItem*>("textField"); |
1023 | QTest::keyClick(textField->window(), Qt::Key_Tab); |
1024 | - QTRY_COMPARE_WITH_TIMEOUT(textField->property("activeFocus").toBool(), true, testTimeout); |
1025 | + QTRY_COMPARE(textField->property("activeFocus").toBool(), true); |
1026 | + QTRY_COMPARE(contentHub->canPaste(), true); |
1027 | QTest::keyClick(textField->window(), Qt::Key_V, Qt::ControlModifier|Qt::ShiftModifier); |
1028 | - pasteRequestedSpy->wait(testTimeout); |
1029 | - QCOMPARE(pasteRequestedSpy->count(), 1); |
1030 | + QTRY_COMPARE(pasteRequestedSpy->count(), 1); |
1031 | } |
1032 | |
1033 | void test_KeyboardShortcutOnTextArea() |
1034 | @@ -242,10 +237,10 @@ |
1035 | testCase->rootObject()->forceActiveFocus(); |
1036 | QQuickItem *textArea = testCase->findItem<QQuickItem*>("textArea"); |
1037 | QTest::keyClick(textArea->window(), Qt::Key_Tab); |
1038 | - QTRY_COMPARE_WITH_TIMEOUT(textArea->property("activeFocus").toBool(), true, testTimeout); |
1039 | + QTRY_COMPARE(textArea->property("activeFocus").toBool(), true); |
1040 | + QTRY_COMPARE(contentHub->canPaste(), true); |
1041 | QTest::keyClick(textArea->window(), Qt::Key_V, Qt::ControlModifier|Qt::ShiftModifier); |
1042 | - pasteRequestedSpy->wait(testTimeout); |
1043 | - QCOMPARE(pasteRequestedSpy->count(), 1); |
1044 | + QTRY_COMPARE(pasteRequestedSpy->count(), 1); |
1045 | } |
1046 | }; |
1047 | |
1048 | |
1049 | === modified file 'tests/unit/mainwindow/VisualRoot.qml' |
1050 | --- tests/unit/mainwindow/VisualRoot.qml 2017-01-16 14:18:21 +0000 |
1051 | +++ tests/unit/mainwindow/VisualRoot.qml 2017-03-06 16:02:52 +0000 |
1052 | @@ -20,7 +20,6 @@ |
1053 | |
1054 | MainWindow { |
1055 | objectName: "visualRoot" |
1056 | - applicationName: "org.gnu.wildebeest" |
1057 | visualRoot: myRoot |
1058 | |
1059 | Rectangle { |
1060 | |
1061 | === modified file 'tests/unit/mainwindow/tst_mainwindow.cpp' |
1062 | --- tests/unit/mainwindow/tst_mainwindow.cpp 2017-01-16 17:44:23 +0000 |
1063 | +++ tests/unit/mainwindow/tst_mainwindow.cpp 2017-03-06 16:02:52 +0000 |
1064 | @@ -33,10 +33,7 @@ |
1065 | #include <QtCore/QCryptographicHash> |
1066 | #include <QtCore/QSettings> |
1067 | |
1068 | -#include <QtQuick/QQuickItem> |
1069 | -#include <QtQuick/QQuickView> |
1070 | #include <QtGui/QGuiApplication> |
1071 | -#include <QtQml/QQmlEngine> |
1072 | #include <QtQml/QQmlContext> |
1073 | #include <QtQml/QQmlComponent> |
1074 | |
1075 | @@ -103,18 +100,22 @@ |
1076 | |
1077 | private Q_SLOTS: |
1078 | |
1079 | - void initTestCase() |
1080 | - { |
1081 | - } |
1082 | - |
1083 | - void cleanupTestCase() |
1084 | - { |
1085 | + void cleanup() |
1086 | + { |
1087 | + // Delete engine, and thereby also the UCApplication instance |
1088 | + QObject* engine(UCApplication::instance()->parent()); |
1089 | + delete engine; |
1090 | + QCoreApplication::setApplicationName(QStringLiteral("")); |
1091 | + QCoreApplication::setOrganizationName(QStringLiteral("")); |
1092 | } |
1093 | |
1094 | // Note: tests/unit/mainview13 contains the UCApplication bits |
1095 | |
1096 | void testCase_AppName() |
1097 | { |
1098 | + // Sanity check: no name set yet |
1099 | + QCOMPARE(QStringLiteral("mainwindow"), QCoreApplication::applicationName()); |
1100 | + |
1101 | QString applicationName("org.gnu.wildebeest"); |
1102 | QQuickWindow *mainWindow(loadTest("AppName.qml")); |
1103 | QVERIFY(mainWindow); |
1104 | @@ -125,6 +126,9 @@ |
1105 | |
1106 | void testCase_OrganizationName() |
1107 | { |
1108 | + // Sanity check: no organization set yet |
1109 | + QCOMPARE(QStringLiteral(""), QCoreApplication::organizationName()); |
1110 | + |
1111 | QString applicationName("tv.island.pacific"); |
1112 | QString organizationName("pacifist"); |
1113 | QQuickWindow *mainWindow(loadTest("OrganizationName.qml")); |
1114 | @@ -135,9 +139,28 @@ |
1115 | QCOMPARE(organizationName, QCoreApplication::organizationName()); |
1116 | } |
1117 | |
1118 | + void testCase_NoOrganizationName() |
1119 | + { |
1120 | + // Sanity check: no organization set yet |
1121 | + QCOMPARE(QStringLiteral(""), QCoreApplication::organizationName()); |
1122 | + |
1123 | + // Custom values set outside of QML |
1124 | + QString applicationName("com.example.random"); |
1125 | + QString organizationName(QStringLiteral("Example")); |
1126 | + QCoreApplication::setApplicationName(applicationName); |
1127 | + QCoreApplication::setOrganizationName(organizationName); |
1128 | + |
1129 | + QQuickWindow *mainWindow(loadTest("VisualRoot.qml")); |
1130 | + QVERIFY(mainWindow); |
1131 | + // MainView shouldn't interfere as applicationName wasn't set in QML |
1132 | + QCOMPARE(QStringLiteral(""), mainWindow->property("applicationName").toString()); |
1133 | + QCOMPARE(applicationName, QCoreApplication::applicationName()); |
1134 | + QCOMPARE(QStringLiteral(""), mainWindow->property("organizationName").toString()); |
1135 | + QCOMPARE(organizationName, QCoreApplication::organizationName()); |
1136 | + } |
1137 | + |
1138 | void testCase_VisualRoot() |
1139 | { |
1140 | - QString applicationName("tv.island.pacific"); |
1141 | QQuickWindow *mainWindow(loadTest("VisualRoot.qml")); |
1142 | QVERIFY(mainWindow); |
1143 | QQuickItem* myLabel(testItem(mainWindow, "myLabel")); |
1144 | |
1145 | === removed file 'tests/unit/qquick_image_extension/borderInName.sci' |
1146 | --- tests/unit/qquick_image_extension/borderInName.sci 2013-05-06 16:33:54 +0000 |
1147 | +++ tests/unit/qquick_image_extension/borderInName.sci 1970-01-01 00:00:00 +0000 |
1148 | @@ -1,7 +0,0 @@ |
1149 | -source: "borderInName.png" |
1150 | -border.left: 9 |
1151 | -border.right: 2 |
1152 | -border.top: 9 |
1153 | -border.bottom: 0 |
1154 | -horizontalTileMode: Stretch |
1155 | -verticalTileMode: Stretch |
1156 | |
1157 | === added directory 'tests/unit/qquick_image_extension/data' |
1158 | === added file 'tests/unit/qquick_image_extension/data/borderInName.sci' |
1159 | --- tests/unit/qquick_image_extension/data/borderInName.sci 1970-01-01 00:00:00 +0000 |
1160 | +++ tests/unit/qquick_image_extension/data/borderInName.sci 2017-03-06 16:02:52 +0000 |
1161 | @@ -0,0 +1,7 @@ |
1162 | +source: "borderInName.png" |
1163 | +border.left: 9 |
1164 | +border.right: 2 |
1165 | +border.top: 9 |
1166 | +border.bottom: 0 |
1167 | +horizontalTileMode: Stretch |
1168 | +verticalTileMode: Stretch |
1169 | |
1170 | === added file 'tests/unit/qquick_image_extension/data/face.png' |
1171 | Binary files tests/unit/qquick_image_extension/data/face.png 1970-01-01 00:00:00 +0000 and tests/unit/qquick_image_extension/data/face.png 2017-03-06 16:02:52 +0000 differ |
1172 | === added file 'tests/unit/qquick_image_extension/data/hundred_faces.qml' |
1173 | --- tests/unit/qquick_image_extension/data/hundred_faces.qml 1970-01-01 00:00:00 +0000 |
1174 | +++ tests/unit/qquick_image_extension/data/hundred_faces.qml 2017-03-06 16:02:52 +0000 |
1175 | @@ -0,0 +1,13 @@ |
1176 | + |
1177 | +import QtQuick 2.4 |
1178 | +import Ubuntu.Components 1.3 |
1179 | + |
1180 | +Repeater { |
1181 | + width: 400 |
1182 | + height: 600 |
1183 | + |
1184 | + model: 100 |
1185 | + delegate: Image { |
1186 | + source: "face.png" |
1187 | + } |
1188 | +} |
1189 | |
1190 | === added file 'tests/unit/qquick_image_extension/data/test@18.sci' |
1191 | --- tests/unit/qquick_image_extension/data/test@18.sci 1970-01-01 00:00:00 +0000 |
1192 | +++ tests/unit/qquick_image_extension/data/test@18.sci 2017-03-06 16:02:52 +0000 |
1193 | @@ -0,0 +1,7 @@ |
1194 | +source: "test@18.png" |
1195 | +border.left: 9 |
1196 | +border.right: 2 |
1197 | +border.top: 9 |
1198 | +border.bottom: 0 |
1199 | +horizontalTileMode: Stretch |
1200 | +verticalTileMode: Stretch |
1201 | |
1202 | === modified file 'tests/unit/qquick_image_extension/qquick_image_extension.pro' |
1203 | --- tests/unit/qquick_image_extension/qquick_image_extension.pro 2016-05-31 09:02:35 +0000 |
1204 | +++ tests/unit/qquick_image_extension/qquick_image_extension.pro 2017-03-06 16:02:52 +0000 |
1205 | @@ -1,3 +1,3 @@ |
1206 | include(../test-include.pri) |
1207 | SOURCES += tst_qquick_image_extension.cpp |
1208 | -QT += quick-private |
1209 | +QT += core-private quick-private |
1210 | |
1211 | === removed file 'tests/unit/qquick_image_extension/test@18.sci' |
1212 | --- tests/unit/qquick_image_extension/test@18.sci 2013-05-06 16:33:54 +0000 |
1213 | +++ tests/unit/qquick_image_extension/test@18.sci 1970-01-01 00:00:00 +0000 |
1214 | @@ -1,7 +0,0 @@ |
1215 | -source: "test@18.png" |
1216 | -border.left: 9 |
1217 | -border.right: 2 |
1218 | -border.top: 9 |
1219 | -border.bottom: 0 |
1220 | -horizontalTileMode: Stretch |
1221 | -verticalTileMode: Stretch |
1222 | |
1223 | === modified file 'tests/unit/qquick_image_extension/tst_qquick_image_extension.cpp' |
1224 | --- tests/unit/qquick_image_extension/tst_qquick_image_extension.cpp 2016-09-09 17:49:07 +0000 |
1225 | +++ tests/unit/qquick_image_extension/tst_qquick_image_extension.cpp 2017-03-06 16:02:52 +0000 |
1226 | @@ -23,6 +23,8 @@ |
1227 | #define protected public |
1228 | #include <UbuntuToolkit/private/ucqquickimageextension_p.h> |
1229 | #undef protected |
1230 | +#include <QtCore/private/qabstractfileengine_p.h> |
1231 | +#include <QQuickView> |
1232 | |
1233 | UT_USE_NAMESPACE |
1234 | |
1235 | @@ -32,6 +34,20 @@ |
1236 | return QDir::temp().entryList(nameFilters, QDir::Files).count(); |
1237 | } |
1238 | |
1239 | +int nFaces = 0; |
1240 | + |
1241 | +class DummyFileEngineHandler : public QAbstractFileEngineHandler |
1242 | +{ |
1243 | +public: |
1244 | + QAbstractFileEngine *create(const QString &fileName) const |
1245 | + { |
1246 | + if (fileName.endsWith("/face.png")) |
1247 | + nFaces++; |
1248 | + |
1249 | + return nullptr; |
1250 | + } |
1251 | +}; |
1252 | + |
1253 | class tst_UCQQuickImageExtension : public QObject |
1254 | { |
1255 | Q_OBJECT |
1256 | @@ -78,7 +94,7 @@ |
1257 | |
1258 | void rewriteContainsBorderInName() { |
1259 | UCQQuickImageExtension image; |
1260 | - QString sciFilePath = "borderInName.sci"; |
1261 | + QString sciFilePath = "data/borderInName.sci"; |
1262 | QString result; |
1263 | |
1264 | QTextStream resultStream(&result); |
1265 | @@ -86,7 +102,7 @@ |
1266 | |
1267 | QString expected; |
1268 | QTextStream expectedStream(&expected); |
1269 | - expectedStream << "source: \"image://scaling/1/./borderInName.png\"" << endl; |
1270 | + expectedStream << "source: \"image://scaling/1/data/borderInName.png\"" << endl; |
1271 | expectedStream << "border.left: 9" << endl; |
1272 | expectedStream << "border.right: 2" << endl; |
1273 | expectedStream << "border.top: 9" << endl; |
1274 | @@ -105,7 +121,7 @@ |
1275 | QQuickImageBase baseImage; |
1276 | UCQQuickImageExtension* image1 = new UCQQuickImageExtension(&baseImage); |
1277 | UCQQuickImageExtension* image2 = new UCQQuickImageExtension(&baseImage); |
1278 | - QUrl sciFileUrl = QUrl::fromLocalFile("./test.sci"); |
1279 | + QUrl sciFileUrl = QUrl::fromLocalFile("./data/test.sci"); |
1280 | |
1281 | unsigned int initialNumberOfSciFiles = numberOfTemporarySciFiles(); |
1282 | |
1283 | @@ -124,6 +140,25 @@ |
1284 | delete image2; |
1285 | QCOMPARE(numberOfTemporarySciFiles(), initialNumberOfSciFiles + 1); |
1286 | } |
1287 | + |
1288 | + void onlyOneStatRepeatedImage() { |
1289 | + DummyFileEngineHandler handler; |
1290 | + |
1291 | + QQuickView view(QUrl::fromLocalFile("./data/hundred_faces.qml")); |
1292 | + |
1293 | + // Wait until the app is idle |
1294 | + bool idle = false; |
1295 | + while (!idle) { |
1296 | + QEventLoop l; |
1297 | + idle = !l.processEvents(); |
1298 | + } |
1299 | + // We have actually loaded the image |
1300 | + QVERIFY(nFaces > 0); |
1301 | + // The number at the moment of writing this test is 4, but we |
1302 | + // can't know what Qt does internally, so i'm going for a relatively safe <10 |
1303 | + // the important part is that is not 100 times (i.e. one for every Image item) |
1304 | + QVERIFY(nFaces < 10); |
1305 | + } |
1306 | }; |
1307 | |
1308 | QTEST_MAIN(tst_UCQQuickImageExtension) |
1309 | |
1310 | === modified file 'tests/unit/visual/tst_optionselector.13.qml' |
1311 | --- tests/unit/visual/tst_optionselector.13.qml 2016-09-19 11:13:19 +0000 |
1312 | +++ tests/unit/visual/tst_optionselector.13.qml 2017-03-06 16:02:52 +0000 |
1313 | @@ -183,8 +183,17 @@ |
1314 | function test_custom_data() { |
1315 | return test_arrow_select_data() |
1316 | } |
1317 | + |
1318 | function test_custom(data) { |
1319 | test_arrow_select(data, customSelector, 2); |
1320 | } |
1321 | + |
1322 | + function test_count() { |
1323 | + var selector = defaultSelector; |
1324 | + sections.selectedIndex = 0; |
1325 | + selector.forceActiveFocus(); |
1326 | + waitForRendering(selector); |
1327 | + compare(selector.count, customModel.count); |
1328 | + } |
1329 | } |
1330 | } |
1331 | |
1332 | === modified file 'tests/unit/visual/tst_toggles.13.qml' |
1333 | --- tests/unit/visual/tst_toggles.13.qml 2016-06-15 13:46:51 +0000 |
1334 | +++ tests/unit/visual/tst_toggles.13.qml 2017-03-06 16:02:52 +0000 |
1335 | @@ -39,6 +39,23 @@ |
1336 | property bool checkedNow: true |
1337 | onClicked: checkedNow = checked |
1338 | } |
1339 | + |
1340 | + CheckBox { |
1341 | + id: testCheckLbl |
1342 | + checked: true |
1343 | + text: "This a checkbox label" |
1344 | + property bool checkedNow: true |
1345 | + onClicked: checkedNow = checked |
1346 | + } |
1347 | + |
1348 | + CheckBox { |
1349 | + id: testCheckLblDisabled |
1350 | + checked: false |
1351 | + enabled: false |
1352 | + text: "This a checkbox label" |
1353 | + property bool checkedNow: false |
1354 | + onClicked: checkedNow = checked |
1355 | + } |
1356 | } |
1357 | |
1358 | UbuntuTestCase { |
1359 | @@ -75,6 +92,37 @@ |
1360 | clickedSpy.wait(400); |
1361 | compare(data.testItem.checkedNow, data.testItem.checked); |
1362 | } |
1363 | + |
1364 | + |
1365 | + function test_toggle_lbl_checked_data() { |
1366 | + return [ |
1367 | + {tag: "CheckBox", testItem: testCheckLbl, mouse: true}, |
1368 | + ]; |
1369 | + } |
1370 | + |
1371 | + function test_toggle_lbl_checked(data) { |
1372 | + data.testItem.checkedNow = data.testItem.checked; |
1373 | + data.testItem.forceActiveFocus(); |
1374 | + clickedSpy.target = data.testItem; |
1375 | + mouseClick(data.testItem, centerOf(data.testItem).x, centerOf(data.testItem).y); |
1376 | + clickedSpy.wait(400); |
1377 | + compare(data.testItem.checkedNow, data.testItem.checked); |
1378 | + } |
1379 | + |
1380 | + function test_toggle_lbl_checked_disabled_data() { |
1381 | + return [ |
1382 | + {tag: "CheckBox", testItem: testCheckLblDisabled, mouse: true}, |
1383 | + ]; |
1384 | + } |
1385 | + |
1386 | + function test_toggle_lbl_checked_disabled(data) { |
1387 | + data.testItem.checkedNow = data.testItem.checked; |
1388 | + data.testItem.forceActiveFocus(); |
1389 | + clickedSpy.target = data.testItem; |
1390 | + mouseClick(data.testItem, centerOf(data.testItem).x, centerOf(data.testItem).y); |
1391 | + compare(clickedSpy.count, 0); |
1392 | + compare(data.testItem.checkedNow, data.testItem.checked); |
1393 | + } |
1394 | } |
1395 | } |
1396 |