Merge lp:~bzoltan/ubuntu-ui-toolkit/Landing-2017-03-06 into lp:ubuntu-ui-toolkit

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
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'
1171Binary 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

Subscribers

People subscribed via source and target branches

to status/vote changes: