on xenial help sign in
Merge from trunk
1ce88f8Michael Terry
cmake/modules/QmlTest.cmake+1−1
@@ -135,7 +135,7 @@ macro(add_binary_qml_test CLASS_NAME LD_PATH DEPS)
135 set(testCommand
135 set(testCommand
136 LD_LIBRARY_PATH=${LD_PATH}
136 LD_LIBRARY_PATH=${LD_PATH}
137 ${CMAKE_CURRENT_BINARY_DIR}/${CLASS_NAME}TestExec
137 ${CMAKE_CURRENT_BINARY_DIR}/${CLASS_NAME}TestExec
138− -o ${CMAKE_BINARY_DIR}/${CLASSNAME}Test.xml,xunitxml
138+ -o ${CMAKE_BINARY_DIR}/${CLASS_NAME}Test.xml,xunitxml
139 -o -,txt)
139 -o -,txt)
140
140
141 add_qmltest_target(test${CLASS_NAME} "${testCommand}" FALSE TRUE)
141 add_qmltest_target(test${CLASS_NAME} "${testCommand}" FALSE TRUE)
debian/changelog+36
@@ -1,3 +1,39 @@
1+unity8 (8.00+14.10.20140731.1-0ubuntu1) utopic; urgency=low
2+
3+ [ Gerry Boland ]
4+ * Fix the run.sh script - pretend to be running with qtmir and emit
5+ SIGSTOP at the right time
6+
7+ [ Ying-Chun Liu ]
8+ * Implement Attribute UI. (LP: #1282460)
9+
10+ [ Albert Astals ]
11+ * Hide search history popup as soon as you start typing As discussed
12+ with Mike and Saviq
13+ * Compile with for scopes-v3 unity-api
14+ * PageHeader: Unfocus search field when search entry is selected
15+ * Show search field if the search query changes
16+ * Test: Add a condition for art.height being > 0 means stuff has
17+ already been layouted a bit without it it can happen that we get 0
18+ for everything at startup and tests still pass
19+ * Remove leftover in test of an old headerless implementation
20+
21+ [ Michael Zanetti ]
22+ * Drop Recent apps category from Dash (LP: #1281092)
23+ * update launcher count emblems to match new spec (LP: #1338984)
24+
25+ [ Bill Filler ]
26+ * disable predictive text for dash search field (LP: #1340409)
27+
28+ [ CI bot ]
29+ * Resync trunk
30+
31+ [ Antti Kaijanmäki ]
32+ * DefaultIndicatorPage: use Loader status to determine the visible
33+ property. (LP: #1350555)
34+
35+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Thu, 31 Jul 2014 16:51:01 +0000
36+
1unity8 (8.00+14.10.20140729.1-0ubuntu1) utopic; urgency=low
37unity8 (8.00+14.10.20140729.1-0ubuntu1) utopic; urgency=low
2
38
3 [ Michael Terry ]
39 [ Michael Terry ]
debian/control+1−1
@@ -24,7 +24,7 @@ Build-Depends: cmake,
24 libpulse-dev,
24 libpulse-dev,
25 libqmenumodel-dev (>= 0.2.8),
25 libqmenumodel-dev (>= 0.2.8),
26 libqt5xmlpatterns5-dev,
26 libqt5xmlpatterns5-dev,
27− libunity-api-dev (>= 7.85),
27+ libunity-api-dev (>= 7.87),
28 libusermetricsoutput1-dev,
28 libusermetricsoutput1-dev,
29 libxcb1-dev,
29 libxcb1-dev,
30 pkg-config,
30 pkg-config,
plugins/Dash/CardAttributes.qmlnew file+65
@@ -0,0 +1,65 @@
1+/*
2+ * Copyright 2014 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.2
18+import QtQuick.Layouts 1.1
19+import Ubuntu.Components 1.1
20+import Ubuntu.Settings.Components 0.1
21+
22+GridLayout {
23+ id: grid
24+ anchors {
25+ left: parent.left;
26+ right: parent.right;
27+ }
28+ columns: 2 + repeater.count % 2
29+ property alias model: repeater.model
30+ property var color
31+
32+ Repeater {
33+ id: repeater
34+ delegate: Row {
35+ spacing: units.gu(0.5)
36+ readonly property int column: index % grid.columns;
37+ Layout.alignment: {
38+ if (column == 0) return Qt.AlignLeft;
39+ if (column == grid.columns - 1 || index == repeater.count - 1) return Qt.AlignRight;
40+ if (column == 1) return Qt.AlignHCenter;
41+ }
42+ Layout.columnSpan: index == repeater.count - 1 && grid.columns == 3 && column == 1 ? 2 : 1
43+ Layout.maximumWidth: Math.max(icon.width, label.x + label.implicitWidth)
44+ Layout.fillWidth: true
45+ StatusIcon {
46+ id: icon
47+ height: units.gu(2)
48+ sets: ["actions", "status", "apps"]
49+ source: "icon" in modelData ? modelData["icon"] : ""
50+ }
51+ Label {
52+ id: label
53+ width: parent.width - x
54+ anchors.verticalCenter: parent.verticalCenter
55+ text: "value" in modelData ? modelData["value"] : "";
56+ elide: Text.ElideRight
57+ maximumLineCount: 1
58+ font.weight: "style" in modelData && modelData["style"] == "highlighted" ? Font.DemiBold : Font.Light
59+ fontSize: "small"
60+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale)
61+ color: grid.color
62+ }
63+ }
64+ }
65+}
plugins/Dash/CardCreator.js+76−7
@@ -193,6 +193,21 @@ var kHeaderColumnCode = 'Column { \n\
193 ] \n\
193 ] \n\
194 }\n';
194 }\n';
195
195
196+// multiple column version of kHeaderColumnCode.
197+function kHeaderColumnCodeGenerator() {
198+ var headerColumnCodeTemplate = 'Column { \n\
199+ anchors.verticalCenter: parent.verticalCenter; \n\
200+ spacing: units.dp(2); \n\
201+ width: parent.width - x;\n\
202+ data: [ \n\
203+ %1 \n\
204+ ]\n\
205+ }\n';
206+ var args = Array.prototype.slice.call(arguments);
207+ var code = headerColumnCodeTemplate.arg(args.join(',\n'));
208+ return code;
209+}
210+
196// %1 is used as anchors of mascotShapeLoader
211// %1 is used as anchors of mascotShapeLoader
197var kMascotShapeLoaderCode = 'Loader { \n\
212var kMascotShapeLoaderCode = 'Loader { \n\
198 id: mascotShapeLoader; \n\
213 id: mascotShapeLoader; \n\
@@ -224,7 +239,7 @@ var kMascotImageCode = 'Image { \n\
224 }\n';
239 }\n';
225
240
226// %1 is used as anchors of titleLabel
241// %1 is used as anchors of titleLabel
227−// %1 is used as color of titleLabel
242+// %2 is used as color of titleLabel
228// %3 is used as extra condition for visible of titleLabel
243// %3 is used as extra condition for visible of titleLabel
229var kTitleLabelCode = 'Label { \n\
244var kTitleLabelCode = 'Label { \n\
230 id: titleLabel; \n\
245 id: titleLabel; \n\
@@ -258,6 +273,15 @@ var kSubtitleLabelCode = 'Label { \n\
258 horizontalAlignment: root.headerAlignment; \n\
273 horizontalAlignment: root.headerAlignment; \n\
259 }\n';
274 }\n';
260
275
276+// %1 is used as anchors of attributesRow
277+var kAttributesRowCode = 'CardAttributes { \n\
278+ id: attributesRow; \n\
279+ objectName: "attributesRow"; \n\
280+ anchors { %1 } \n\
281+ color: %2; \n\
282+ model: cardData && cardData["attributes"] || undefined; \n\
283+ }\n';
284+
261// %1 is used as top anchor of summary
285// %1 is used as top anchor of summary
262// %2 is used as topMargin anchor of summary
286// %2 is used as topMargin anchor of summary
263// %3 is used as color of summary
287// %3 is used as color of summary
@@ -308,6 +332,7 @@ function cardString(template, components) {
308 var headerAsOverlay = hasArt && template && template["overlay"] === true && (hasTitle || hasMascot);
332 var headerAsOverlay = hasArt && template && template["overlay"] === true && (hasTitle || hasMascot);
309 var hasSubtitle = hasTitle && components["subtitle"] || false;
333 var hasSubtitle = hasTitle && components["subtitle"] || false;
310 var hasHeaderRow = hasMascot && hasTitle;
334 var hasHeaderRow = hasMascot && hasTitle;
335+ var hasAttributes = hasTitle && components["attributes"] || false;
311
336
312 if (hasBackground) {
337 if (hasBackground) {
313 code += kBackgroundLoaderCode;
338 code += kBackgroundLoaderCode;
@@ -377,6 +402,14 @@ function cardString(template, components) {
377 code += 'readonly property int headerHeight: row.height;\n'
402 code += 'readonly property int headerHeight: row.height;\n'
378 } else if (hasMascot) {
403 } else if (hasMascot) {
379 code += 'readonly property int headerHeight: mascotImage.height;\n'
404 code += 'readonly property int headerHeight: mascotImage.height;\n'
405+ } else if (hasAttributes) {
406+ if (hasTitle && hasSubtitle) {
407+ code += 'readonly property int headerHeight: titleLabel.height + subtitleLabel.height + subtitleLabel.anchors.topMargin + attributesRow.height + attributesRow.anchors.topMargin;\n'
408+ } else if (hasTitle) {
409+ code += 'readonly property int headerHeight: titleLabel.height + attributesRow.height + attributesRow.anchors.topMargin;\n'
410+ } else {
411+ code += 'readonly property int headerHeight: attributesRow.height;\n'
412+ }
380 } else if (hasSubtitle) {
413 } else if (hasSubtitle) {
381 code += 'readonly property int headerHeight: titleLabel.height + subtitleLabel.height + subtitleLabel.anchors.topMargin;\n'
414 code += 'readonly property int headerHeight: titleLabel.height + subtitleLabel.height + subtitleLabel.anchors.topMargin;\n'
382 } else if (hasTitle) {
415 } else if (hasTitle) {
@@ -425,10 +458,12 @@ function cardString(template, components) {
425
458
426 var titleAnchors;
459 var titleAnchors;
427 var subtitleAnchors;
460 var subtitleAnchors;
461+ var attributesAnchors;
428− if (hasMascot && hasSubtitle) {
462+ if (hasMascot && (hasSubtitle || hasAttributes)) {
429 // Using row + column
463 // Using row + column
430 titleAnchors = 'left: parent.left; right: parent.right';
464 titleAnchors = 'left: parent.left; right: parent.right';
431 subtitleAnchors = titleAnchors;
465 subtitleAnchors = titleAnchors;
466+ attributesAnchors = subtitleAnchors;
432 } else if (hasMascot) {
467 } else if (hasMascot) {
433 // Using row + label
468 // Using row + label
434 titleAnchors = 'verticalCenter: parent.verticalCenter;\n'
469 titleAnchors = 'verticalCenter: parent.verticalCenter;\n'
@@ -438,11 +473,13 @@ function cardString(template, components) {
438 titleAnchors = 'left: parent.left; \n\
473 titleAnchors = 'left: parent.left; \n\
439 leftMargin: units.gu(1); \n\
474 leftMargin: units.gu(1); \n\
440 right: parent.right; \n\
475 right: parent.right; \n\
476+ rightMargin: units.gu(1); \n\
441 top: overlayLoader.top; \n\
477 top: overlayLoader.top; \n\
442 topMargin: units.gu(1);\n';
478 topMargin: units.gu(1);\n';
443 } else {
479 } else {
444 // Using anchors to the mascot/parent
480 // Using anchors to the mascot/parent
445− titleAnchors = "right: parent.right;";
481+ titleAnchors = "right: parent.right;\n";
482+ titleAnchors += "rightMargin: units.gu(1);\n";
446 titleAnchors += headerLeftAnchor;
483 titleAnchors += headerLeftAnchor;
447 titleAnchors += headerVerticalAnchors;
484 titleAnchors += headerVerticalAnchors;
448 if (!headerLeftAnchorHasMargin) {
485 if (!headerLeftAnchorHasMargin) {
@@ -452,8 +489,19 @@ function cardString(template, components) {
452 subtitleAnchors = 'left: titleLabel.left; \n\
489 subtitleAnchors = 'left: titleLabel.left; \n\
453 leftMargin: titleLabel.leftMargin; \n\
490 leftMargin: titleLabel.leftMargin; \n\
454 right: titleLabel.right; \n\
491 right: titleLabel.right; \n\
492+ rightMargin: titleLabel.rightMargin; \n\
455 top: titleLabel.bottom; \n\
493 top: titleLabel.bottom; \n\
456 topMargin: units.dp(2);\n';
494 topMargin: units.dp(2);\n';
495+ if (hasSubtitle) {
496+ attributesAnchors = 'left: subtitleLabel.left; \n\
497+ leftMargin: subtitleLabel.leftMargin; \n\
498+ right: subtitleLabel.right; \n\
499+ rightMargin: subtitleLabel.rightMargin; \n\
500+ top: subtitleLabel.bottom; \n\
501+ topMargin: units.dp(2);\n';
502+ } else {
503+ attributesAnchors = subtitleAnchors;
504+ }
457 }
505 }
458
506
459 var titleLabelVisibleExtra = (headerAsOverlay ? '&& overlayLoader.active': '');
507 var titleLabelVisibleExtra = (headerAsOverlay ? '&& overlayLoader.active': '');
@@ -463,11 +511,27 @@ function cardString(template, components) {
463 subtitleCode += kSubtitleLabelCode.arg(subtitleAnchors).arg(color);
511 subtitleCode += kSubtitleLabelCode.arg(subtitleAnchors).arg(color);
464 }
512 }
465
513
466− if (hasMascot && hasSubtitle) {
514+ if (hasMascot && (hasSubtitle || hasAttributes)) {
467 // If using row + column wrap the code in the column
515 // If using row + column wrap the code in the column
468 titleSubtitleCode = kHeaderColumnCode.arg(titleCode).arg(subtitleCode);
516 titleSubtitleCode = kHeaderColumnCode.arg(titleCode).arg(subtitleCode);
517+ if (hasSubtitle && hasAttributes) {
518+ var attributesCode = kAttributesRowCode.arg(attributesAnchors).arg(color);
519+ titleSubtitleCode = kHeaderColumnCodeGenerator(titleCode, subtitleCode, attributesCode);
520+ } else if (hasSubtitle) {
521+ titleSubtitleCode = kHeaderColumnCode.arg(titleCode).arg(subtitleCode);
522+ } else if (hasAttributes) {
523+ var attributesCode = kAttributesRowCode.arg(attributesAnchors).arg(color);
524+ titleSubtitleCode = kHeaderColumnCode.arg(titleCode).arg(attributesCode);
525+ }
469 } else {
526 } else {
470− titleSubtitleCode = titleCode + subtitleCode;
527+ titleSubtitleCode = titleCode;
528+ if (hasSubtitle) {
529+ titleSubtitleCode = titleSubtitleCode + subtitleCode;
530+ }
531+ if (hasAttributes) {
532+ var attributesCode = kAttributesRowCode.arg(attributesAnchors).arg(color);
533+ titleSubtitleCode = titleSubtitleCode + attributesCode;
534+ }
471 }
535 }
472 }
536 }
473
537
@@ -487,6 +551,7 @@ function cardString(template, components) {
487 else if (headerAsOverlay && hasArt) summaryTopAnchor = "artShapeHolder.bottom";
551 else if (headerAsOverlay && hasArt) summaryTopAnchor = "artShapeHolder.bottom";
488 else if (hasHeaderRow) summaryTopAnchor = "row.bottom";
552 else if (hasHeaderRow) summaryTopAnchor = "row.bottom";
489 else if (hasMascot) summaryTopAnchor = "mascotImage.bottom";
553 else if (hasMascot) summaryTopAnchor = "mascotImage.bottom";
554+ else if (hasAttributes) summaryTopAnchor = "attributesRow.bottom";
490 else if (hasSubtitle) summaryTopAnchor = "subtitleLabel.bottom";
555 else if (hasSubtitle) summaryTopAnchor = "subtitleLabel.bottom";
491 else if (hasTitle) summaryTopAnchor = "titleLabel.bottom";
556 else if (hasTitle) summaryTopAnchor = "titleLabel.bottom";
492 else if (hasArt) summaryTopAnchor = "artShapeHolder.bottom";
557 else if (hasArt) summaryTopAnchor = "artShapeHolder.bottom";
@@ -499,7 +564,7 @@ function cardString(template, components) {
499 color = 'root.scopeStyle ? root.scopeStyle.foreground : "grey"';
564 color = 'root.scopeStyle ? root.scopeStyle.foreground : "grey"';
500 }
565 }
501
566
502− var summaryTopMargin = (hasMascot || hasSubtitle ? 'anchors.margins' : '0');
567+ var summaryTopMargin = (hasMascot || hasSubtitle || hasAttributes ? 'anchors.margins' : '0');
503
568
504 code += kSummaryLabelCode.arg(summaryTopAnchor).arg(summaryTopMargin).arg(color);
569 code += kSummaryLabelCode.arg(summaryTopAnchor).arg(summaryTopMargin).arg(color);
505 }
570 }
@@ -510,6 +575,8 @@ function cardString(template, components) {
510 code += 'implicitHeight: row.y + row.height + units.gu(1);\n';
575 code += 'implicitHeight: row.y + row.height + units.gu(1);\n';
511 } else if (hasMascot) {
576 } else if (hasMascot) {
512 code += 'implicitHeight: mascotImage.y + mascotImage.height;\n';
577 code += 'implicitHeight: mascotImage.y + mascotImage.height;\n';
578+ } else if (hasAttributes) {
579+ code += 'implicitHeight: attributesRow.y + attributesRow.height + units.gu(1);\n';
513 } else if (hasSubtitle) {
580 } else if (hasSubtitle) {
514 code += 'implicitHeight: subtitleLabel.y + subtitleLabel.height + units.gu(1);\n';
581 code += 'implicitHeight: subtitleLabel.y + subtitleLabel.height + units.gu(1);\n';
515 } else if (hasTitle) {
582 } else if (hasTitle) {
@@ -526,8 +593,10 @@ function cardString(template, components) {
526function createCardComponent(parent, template, components) {
593function createCardComponent(parent, template, components) {
527 var imports = 'import QtQuick 2.2; \n\
594 var imports = 'import QtQuick 2.2; \n\
528 import Ubuntu.Components 0.1; \n\
595 import Ubuntu.Components 0.1; \n\
529− import Ubuntu.Thumbnailer 0.1;\n';
596+ import Ubuntu.Thumbnailer 0.1;\n\
597+ import Dash 0.1;\n';
530 var card = cardString(template, components);
598 var card = cardString(template, components);
531 var code = imports + 'Component {\n' + card + '}\n';
599 var code = imports + 'Component {\n' + card + '}\n';
600+
532 return Qt.createQmlObject(code, parent, "createCardComponent");
601 return Qt.createQmlObject(code, parent, "createCardComponent");
533}
602}
plugins/Dash/qmldir+1
@@ -3,3 +3,4 @@ plugin Dash-qml
3typeinfo Dash.qmltypes
3typeinfo Dash.qmltypes
4singleton CardCreatorCache 0.1 CardCreatorCache.qml
4singleton CardCreatorCache 0.1 CardCreatorCache.qml
5ScopeStyle 0.1 ScopeStyle.qml
5ScopeStyle 0.1 ScopeStyle.qml
6+CardAttributes 0.1 CardAttributes.qml
po/fa.po+51−49
@@ -8,200 +8,202 @@ msgstr ""
8"Project-Id-Version: unity8\n"
8"Project-Id-Version: unity8\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2014-07-11 14:59+0200\n"
10"POT-Creation-Date: 2014-07-11 14:59+0200\n"
11−"PO-Revision-Date: 2013-10-31 19:02+0000\n"
11+"PO-Revision-Date: 2014-08-03 13:00+0000\n"
12−"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12+"Last-Translator: Arash Badie Modiri <arashbm@gmail.com>\n"
13"Language-Team: Persian <fa@li.org>\n"
13"Language-Team: Persian <fa@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2014-07-26 07:17+0000\n"
17+"X-Launchpad-Export-Date: 2014-08-04 06:32+0000\n"
18−"X-Generator: Launchpad (build 17131)\n"
18+"X-Generator: Launchpad (build 17147)\n"
19
19
20#: plugins/Unity/Launcher/launcheritem.cpp:43
20#: plugins/Unity/Launcher/launcheritem.cpp:43
21#: plugins/Unity/Launcher/launcheritem.cpp:73
21#: plugins/Unity/Launcher/launcheritem.cpp:73
22msgid "Pin shortcut"
22msgid "Pin shortcut"
23−msgstr ""
23+msgstr "سنجاق کردن میانبر"
24
24
25#: plugins/Unity/Launcher/launcheritem.cpp:73
25#: plugins/Unity/Launcher/launcheritem.cpp:73
26msgid "Unpin shortcut"
26msgid "Unpin shortcut"
27−msgstr ""
27+msgstr "برداشتن سنجاق میانبر"
28
28
29#: qml/Components/EdgeDemoOverlay.qml:151
29#: qml/Components/EdgeDemoOverlay.qml:151
30msgid "Skip intro"
30msgid "Skip intro"
31−msgstr ""
31+msgstr "پرش از مقدّمه"
32
32
33#: qml/Components/EdgeDemo.qml:113
33#: qml/Components/EdgeDemo.qml:113
34msgid "Right edge"
34msgid "Right edge"
35−msgstr ""
35+msgstr "لبه‌ی راست"
36
36
37#: qml/Components/EdgeDemo.qml:114
37#: qml/Components/EdgeDemo.qml:114
38msgid "Try swiping from the right edge to unlock the phone"
38msgid "Try swiping from the right edge to unlock the phone"
39−msgstr ""
39+msgstr "برای باز کردن قفل تلفن، از لبه‌ی راست بکشید"
40
40
41#: qml/Components/EdgeDemo.qml:145
41#: qml/Components/EdgeDemo.qml:145
42msgid "Top edge"
42msgid "Top edge"
43−msgstr ""
43+msgstr "لبه‌ی بالا"
44
44
45#: qml/Components/EdgeDemo.qml:146
45#: qml/Components/EdgeDemo.qml:146
46msgid "Try swiping from the top edge to access the indicators"
46msgid "Try swiping from the top edge to access the indicators"
47−msgstr ""
47+msgstr "برای دست‌رسی به نشانگرها، از لبه‌ی بالا بکشید"
48
48
49#: qml/Components/EdgeDemo.qml:171
49#: qml/Components/EdgeDemo.qml:171
50msgid "Close"
50msgid "Close"
51−msgstr ""
51+msgstr "بستن"
52
52
53#: qml/Components/EdgeDemo.qml:172
53#: qml/Components/EdgeDemo.qml:172
54msgid "Swipe up again to close the settings screen"
54msgid "Swipe up again to close the settings screen"
55−msgstr ""
55+msgstr "برای بستن صفحه‌ی تنظیمات، دوباره به بالا بکشپد"
56
56
57#: qml/Components/EdgeDemo.qml:199
57#: qml/Components/EdgeDemo.qml:199
58msgid "Left edge"
58msgid "Left edge"
59−msgstr ""
59+msgstr "لبه‌ی چپ"
60
60
61#: qml/Components/EdgeDemo.qml:200
61#: qml/Components/EdgeDemo.qml:200
62msgid "Swipe from the left to reveal the launcher for quick access to apps"
62msgid "Swipe from the left to reveal the launcher for quick access to apps"
63−msgstr ""
63+msgstr "برای آشکار شدن اجراگر به منظور دست‌رسی سریع به اپ‌ها از سمت چپ بکشید"
64
64
65#: qml/Components/EdgeDemo.qml:227
65#: qml/Components/EdgeDemo.qml:227
66msgid "Well done"
66msgid "Well done"
67−msgstr ""
67+msgstr "عالی بود"
68
68
69#: qml/Components/EdgeDemo.qml:228
69#: qml/Components/EdgeDemo.qml:228
70msgid ""
70msgid ""
71"You have now mastered the edge gestures and can start using the "
71"You have now mastered the edge gestures and can start using the "
72"phone<br><br>Tap on the screen to start"
72"phone<br><br>Tap on the screen to start"
73msgstr ""
73msgstr ""
74+"هم اکنون در استفاده از ژست های حرکتی مهارت لازم را دارید و می‌توانید استفاده "
75+"از تلفن را آغاز کنید<br><br>برای شروع صفحه را لمس کنید"
74
76
75#: qml/Components/Lockscreen.qml:214
77#: qml/Components/Lockscreen.qml:214
76msgid "Emergency Call"
78msgid "Emergency Call"
77−msgstr ""
79+msgstr "تماس اضطراری"
78
80
79#: qml/Components/Lockscreen.qml:231
81#: qml/Components/Lockscreen.qml:231
80msgid "OK"
82msgid "OK"
81−msgstr ""
83+msgstr "قبول"
82
84
83#: qml/Components/PassphraseLockscreen.qml:60
85#: qml/Components/PassphraseLockscreen.qml:60
84#, qt-format
86#, qt-format
85msgid "Hello %1"
87msgid "Hello %1"
86−msgstr ""
88+msgstr "سلام %1"
87
89
88#: qml/Components/PassphraseLockscreen.qml:60
90#: qml/Components/PassphraseLockscreen.qml:60
89msgid "Hello"
91msgid "Hello"
90−msgstr ""
92+msgstr "سلام"
91
93
92#: qml/Components/PinLockscreen.qml:198
94#: qml/Components/PinLockscreen.qml:198
93msgid "CANCEL"
95msgid "CANCEL"
94−msgstr ""
96+msgstr "لغو"
95
97
96#: qml/Components/PinLockscreen.qml:216
98#: qml/Components/PinLockscreen.qml:216
97msgid "DONE"
99msgid "DONE"
98−msgstr ""
100+msgstr "انجام شد"
99
101
100#: qml/Components/SeeMore.qml:35
102#: qml/Components/SeeMore.qml:35
101msgid "See more"
103msgid "See more"
102−msgstr ""
104+msgstr "بیش‌تر ببینید"
103
105
104#: qml/Components/SeeMore.qml:58 qml/Dash/GenericScopeView.qml:330
106#: qml/Components/SeeMore.qml:58 qml/Dash/GenericScopeView.qml:330
105msgid "See less"
107msgid "See less"
106−msgstr ""
108+msgstr "کم‌تر ببینید"
107
109
108#: qml/Dash/DashApps.qml:37
110#: qml/Dash/DashApps.qml:37
109msgid "Recent"
111msgid "Recent"
110−msgstr ""
112+msgstr "موارد اخیر"
111
113
112#: qml/Dash/GenericScopeView.qml:330
114#: qml/Dash/GenericScopeView.qml:330
113msgid "See all"
115msgid "See all"
114−msgstr ""
116+msgstr "دیدن همه"
115
117
116#: qml/Dash/Previews/PreviewActionCombo.qml:34
118#: qml/Dash/Previews/PreviewActionCombo.qml:34
117msgid "More..."
119msgid "More..."
118−msgstr ""
120+msgstr "بیش‌تر…"
119
121
120#: qml/Dash/Previews/PreviewActionCombo.qml:34
122#: qml/Dash/Previews/PreviewActionCombo.qml:34
121msgid "Less..."
123msgid "Less..."
122−msgstr ""
124+msgstr "کم‌تر…"
123
125
124#: qml/Dash/Previews/PreviewRatingInput.qml:81
126#: qml/Dash/Previews/PreviewRatingInput.qml:81
125msgid "Rate this"
127msgid "Rate this"
126−msgstr ""
128+msgstr "امتیاز دادن"
127
129
128#: qml/Dash/Previews/PreviewRatingInput.qml:126
130#: qml/Dash/Previews/PreviewRatingInput.qml:126
129msgid "Add a review"
131msgid "Add a review"
130−msgstr ""
132+msgstr "افزودن یک بازبینی"
131
133
132#: qml/Dash/Previews/PreviewRatingInput.qml:166
134#: qml/Dash/Previews/PreviewRatingInput.qml:166
133msgid "Send"
135msgid "Send"
134−msgstr ""
136+msgstr "ارسال"
135
137
136#: qml/Greeter/Greeter.qml:157
138#: qml/Greeter/Greeter.qml:157
137msgid "Swipe to unlock"
139msgid "Swipe to unlock"
138−msgstr ""
140+msgstr "برای باز کردن قفل بکشد"
139
141
140#: qml/Hud/HudParametrizedActionsPage.qml:132
142#: qml/Hud/HudParametrizedActionsPage.qml:132
141msgid "Confirm"
143msgid "Confirm"
142−msgstr ""
144+msgstr "تأیید"
143
145
144#: qml/Hud/Hud.qml:61 qml/Hud/Hud.qml:99 qml/Hud/Hud.qml:372
146#: qml/Hud/Hud.qml:61 qml/Hud/Hud.qml:99 qml/Hud/Hud.qml:372
145msgid "Type or say a command"
147msgid "Type or say a command"
146−msgstr ""
148+msgstr "دستوری را بنویسید یا بگویید"
147
149
148#: qml/Hud/Hud.qml:84
150#: qml/Hud/Hud.qml:84
149msgid "Loading. Please Wait..."
151msgid "Loading. Please Wait..."
150−msgstr ""
152+msgstr "در حال بار کردن. لطفاً صبر کنید…"
151
153
152#: qml/Hud/Hud.qml:89
154#: qml/Hud/Hud.qml:89
153msgid "Speak Now..."
155msgid "Speak Now..."
154−msgstr ""
156+msgstr "اکنون صحبت کنید…"
155
157
156#: qml/Hud/Hud.qml:94
158#: qml/Hud/Hud.qml:94
157msgid "Speaking..."
159msgid "Speaking..."
158−msgstr ""
160+msgstr "در حال صحبت کردن…"
159
161
160#: qml/Notifications/NotificationMenuItemFactory.qml:91
162#: qml/Notifications/NotificationMenuItemFactory.qml:91
161msgid "Show password"
163msgid "Show password"
162−msgstr ""
164+msgstr "نمایش گذرواژه"
163
165
164#: qml/Notifications/NotificationMenuItemFactory.qml:103
166#: qml/Notifications/NotificationMenuItemFactory.qml:103
165msgid "Please enter SIM PIN"
167msgid "Please enter SIM PIN"
166−msgstr ""
168+msgstr "لطفاً PIN سیم‌کارت را وارد کنید"
167
169
168#: qml/Panel/ActiveCallHint.qml:77
170#: qml/Panel/ActiveCallHint.qml:77
169msgid "Tap to return to call..."
171msgid "Tap to return to call..."
170−msgstr ""
172+msgstr "برای بازگشت به تماس ضربه بزنید…"
171
173
172#: qml/Panel/ActiveCallHint.qml:90
174#: qml/Panel/ActiveCallHint.qml:90
173msgid "Conference"
175msgid "Conference"
174−msgstr ""
176+msgstr "کنفرانس"
175
177
176#: qml/Panel/Indicators/MenuItemFactory.qml:583
178#: qml/Panel/Indicators/MenuItemFactory.qml:583
177msgid "In queue…"
179msgid "In queue…"
178−msgstr ""
180+msgstr "در صف…"
179
181
180#: qml/Panel/Indicators/MenuItemFactory.qml:587
182#: qml/Panel/Indicators/MenuItemFactory.qml:587
181msgid "Downloading"
183msgid "Downloading"
182−msgstr ""
184+msgstr "در حال بارگیری"
183
185
184#: qml/Panel/Indicators/MenuItemFactory.qml:589
186#: qml/Panel/Indicators/MenuItemFactory.qml:589
185msgid "Paused, tap to resume"
187msgid "Paused, tap to resume"
186−msgstr ""
188+msgstr "مکث شد، برای از سر گیری ضربه بزنید"
187
189
188#: qml/Panel/Indicators/MenuItemFactory.qml:591
190#: qml/Panel/Indicators/MenuItemFactory.qml:591
189msgid "Canceled"
191msgid "Canceled"
190−msgstr ""
192+msgstr "لغو شد"
191
193
192#: qml/Panel/Indicators/MenuItemFactory.qml:593
194#: qml/Panel/Indicators/MenuItemFactory.qml:593
193msgid "Finished"
195msgid "Finished"
194−msgstr ""
196+msgstr "پایان یافت"
195
197
196#: qml/Panel/Indicators/MenuItemFactory.qml:595
198#: qml/Panel/Indicators/MenuItemFactory.qml:595
197msgid "Failed, tap to retry"
199msgid "Failed, tap to retry"
198−msgstr ""
200+msgstr "شکست خورد، برای تلاش دوباره ضربه بزنید"
199
201
200#: qml/Panel/SearchIndicator.qml:27
202#: qml/Panel/SearchIndicator.qml:27
201msgid "Search"
203msgid "Search"
202−msgstr ""
204+msgstr "جست‌وجو"
203
205
204#: qml/Shell.qml:359
206#: qml/Shell.qml:359
205#, qt-format
207#, qt-format
206msgid "Please enter %1"
208msgid "Please enter %1"
207−msgstr ""
209+msgstr "لطفا %1 را وارد کنید"
po/hu.po+6−6
@@ -8,14 +8,14 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2014-07-11 14:59+0200\n"
10"POT-Creation-Date: 2014-07-11 14:59+0200\n"
11−"PO-Revision-Date: 2014-07-30 18:42+0000\n"
11+"PO-Revision-Date: 2014-08-03 17:15+0000\n"
12"Last-Translator: Richard Somlói <ricsipontaz@gmail.com>\n"
12"Last-Translator: Richard Somlói <ricsipontaz@gmail.com>\n"
13"Language-Team: Hungarian <hu@li.org>\n"
13"Language-Team: Hungarian <hu@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2014-07-31 07:15+0000\n"
17+"X-Launchpad-Export-Date: 2014-08-04 06:32+0000\n"
18−"X-Generator: Launchpad (build 17131)\n"
18+"X-Generator: Launchpad (build 17147)\n"
19
19
20#: plugins/Unity/Launcher/launcheritem.cpp:43
20#: plugins/Unity/Launcher/launcheritem.cpp:43
21#: plugins/Unity/Launcher/launcheritem.cpp:73
21#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -44,7 +44,7 @@ msgstr "Felső szél"
44
44
45#: qml/Components/EdgeDemo.qml:146
45#: qml/Components/EdgeDemo.qml:146
46msgid "Try swiping from the top edge to access the indicators"
46msgid "Try swiping from the top edge to access the indicators"
47−msgstr "A jelzők eléréséhez csúsztassa ujját a felső szélről"
47+msgstr "Az állapotmenük eléréséhez csúsztassa ujját a felső szélről"
48
48
49#: qml/Components/EdgeDemo.qml:171
49#: qml/Components/EdgeDemo.qml:171
50msgid "Close"
50msgid "Close"
@@ -87,11 +87,11 @@ msgstr "Oké"
87#: qml/Components/PassphraseLockscreen.qml:60
87#: qml/Components/PassphraseLockscreen.qml:60
88#, qt-format
88#, qt-format
89msgid "Hello %1"
89msgid "Hello %1"
90−msgstr "Szia %1"
90+msgstr "Üdv %1"
91
91
92#: qml/Components/PassphraseLockscreen.qml:60
92#: qml/Components/PassphraseLockscreen.qml:60
93msgid "Hello"
93msgid "Hello"
94−msgstr "Szia"
94+msgstr "Üdv"
95
95
96#: qml/Components/PinLockscreen.qml:198
96#: qml/Components/PinLockscreen.qml:198
97msgid "CANCEL"
97msgid "CANCEL"
po/is.po+6−6
@@ -10,14 +10,14 @@ msgstr ""
10"Project-Id-Version: po_unity8-is\n"
10"Project-Id-Version: po_unity8-is\n"
11"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
11"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
12"POT-Creation-Date: 2014-07-11 14:59+0200\n"
12"POT-Creation-Date: 2014-07-11 14:59+0200\n"
13−"PO-Revision-Date: 2014-07-23 05:57+0000\n"
13+"PO-Revision-Date: 2014-07-31 16:10+0000\n"
14"Last-Translator: Sveinn í Felli <sv1@fellsnet.is>\n"
14"Last-Translator: Sveinn í Felli <sv1@fellsnet.is>\n"
15"Language-Team: Icelandic <translation-team-is@lists.sourceforge.net>\n"
15"Language-Team: Icelandic <translation-team-is@lists.sourceforge.net>\n"
16"MIME-Version: 1.0\n"
16"MIME-Version: 1.0\n"
17"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Type: text/plain; charset=UTF-8\n"
18"Content-Transfer-Encoding: 8bit\n"
18"Content-Transfer-Encoding: 8bit\n"
19−"X-Launchpad-Export-Date: 2014-07-26 07:16+0000\n"
19+"X-Launchpad-Export-Date: 2014-08-01 07:14+0000\n"
20−"X-Generator: Launchpad (build 17131)\n"
20+"X-Generator: Launchpad (build 17141)\n"
21"Language: is\n"
21"Language: is\n"
22
22
23#: plugins/Unity/Launcher/launcheritem.cpp:43
23#: plugins/Unity/Launcher/launcheritem.cpp:43
@@ -117,7 +117,7 @@ msgstr "Nýlegt"
117
117
118#: qml/Dash/GenericScopeView.qml:330
118#: qml/Dash/GenericScopeView.qml:330
119msgid "See all"
119msgid "See all"
120−msgstr ""
120+msgstr "Sjá allt"
121
121
122#: qml/Dash/Previews/PreviewActionCombo.qml:34
122#: qml/Dash/Previews/PreviewActionCombo.qml:34
123msgid "More..."
123msgid "More..."
@@ -173,11 +173,11 @@ msgstr "Settu inn PIN fyrir SIM"
173
173
174#: qml/Panel/ActiveCallHint.qml:77
174#: qml/Panel/ActiveCallHint.qml:77
175msgid "Tap to return to call..."
175msgid "Tap to return to call..."
176−msgstr ""
176+msgstr "Slá til að svara símtali..."
177
177
178#: qml/Panel/ActiveCallHint.qml:90
178#: qml/Panel/ActiveCallHint.qml:90
179msgid "Conference"
179msgid "Conference"
180−msgstr ""
180+msgstr "Ráðstefna"
181
181
182#: qml/Panel/Indicators/MenuItemFactory.qml:583
182#: qml/Panel/Indicators/MenuItemFactory.qml:583
183msgid "In queue…"
183msgid "In queue…"
po/km.po+7−7
@@ -8,14 +8,14 @@ msgstr ""
8"Project-Id-Version: unity8\n"
8"Project-Id-Version: unity8\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2014-07-11 14:59+0200\n"
10"POT-Creation-Date: 2014-07-11 14:59+0200\n"
11−"PO-Revision-Date: 2014-07-16 01:37+0000\n"
11+"PO-Revision-Date: 2014-08-01 04:02+0000\n"
12−"Last-Translator: Khoem Sokhem <khoemsokhem@khmeros.info>\n"
12+"Last-Translator: Sok Sophea <sksophea@gmail.com>\n"
13"Language-Team: Khmer <km@li.org>\n"
13"Language-Team: Khmer <km@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2014-07-26 07:16+0000\n"
17+"X-Launchpad-Export-Date: 2014-08-02 06:39+0000\n"
18−"X-Generator: Launchpad (build 17131)\n"
18+"X-Generator: Launchpad (build 17147)\n"
19
19
20#: plugins/Unity/Launcher/launcheritem.cpp:43
20#: plugins/Unity/Launcher/launcheritem.cpp:43
21#: plugins/Unity/Launcher/launcheritem.cpp:73
21#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -115,7 +115,7 @@ msgstr "បច្ចុប្បន្ន"
115
115
116#: qml/Dash/GenericScopeView.qml:330
116#: qml/Dash/GenericScopeView.qml:330
117msgid "See all"
117msgid "See all"
118−msgstr ""
118+msgstr "មើល​ទាំងអស់"
119
119
120#: qml/Dash/Previews/PreviewActionCombo.qml:34
120#: qml/Dash/Previews/PreviewActionCombo.qml:34
121msgid "More..."
121msgid "More..."
@@ -171,11 +171,11 @@ msgstr "បញ្ចូល​កូដ PIN របស់​ស៊ីមកាត"
171
171
172#: qml/Panel/ActiveCallHint.qml:77
172#: qml/Panel/ActiveCallHint.qml:77
173msgid "Tap to return to call..."
173msgid "Tap to return to call..."
174−msgstr ""
174+msgstr "ប៉ះ​ដើម្បី​ត្រឡប់​ទៅ​ការ​ហៅ..."
175
175
176#: qml/Panel/ActiveCallHint.qml:90
176#: qml/Panel/ActiveCallHint.qml:90
177msgid "Conference"
177msgid "Conference"
178−msgstr ""
178+msgstr "សន្និសីទ"
179
179
180#: qml/Panel/Indicators/MenuItemFactory.qml:583
180#: qml/Panel/Indicators/MenuItemFactory.qml:583
181msgid "In queue…"
181msgid "In queue…"
po/pl.po+7−7
@@ -8,14 +8,14 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2014-07-11 14:59+0200\n"
10"POT-Creation-Date: 2014-07-11 14:59+0200\n"
11−"PO-Revision-Date: 2014-07-19 14:10+0000\n"
11+"PO-Revision-Date: 2014-07-31 13:51+0000\n"
12−"Last-Translator: GTriderXC <gtriderxc@yahoo.com>\n"
12+"Last-Translator: Michał Radwański <radwanski.michal@outlook.com>\n"
13"Language-Team: Polish <pl@li.org>\n"
13"Language-Team: Polish <pl@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2014-07-26 07:17+0000\n"
17+"X-Launchpad-Export-Date: 2014-08-01 07:14+0000\n"
18−"X-Generator: Launchpad (build 17131)\n"
18+"X-Generator: Launchpad (build 17141)\n"
19
19
20#: plugins/Unity/Launcher/launcheritem.cpp:43
20#: plugins/Unity/Launcher/launcheritem.cpp:43
21#: plugins/Unity/Launcher/launcheritem.cpp:73
21#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -115,7 +115,7 @@ msgstr "Ostatnio używane"
115
115
116#: qml/Dash/GenericScopeView.qml:330
116#: qml/Dash/GenericScopeView.qml:330
117msgid "See all"
117msgid "See all"
118−msgstr ""
118+msgstr "Zobacz wszystko"
119
119
120#: qml/Dash/Previews/PreviewActionCombo.qml:34
120#: qml/Dash/Previews/PreviewActionCombo.qml:34
121msgid "More..."
121msgid "More..."
@@ -171,11 +171,11 @@ msgstr "Wprowadź kod PIN karty SIM"
171
171
172#: qml/Panel/ActiveCallHint.qml:77
172#: qml/Panel/ActiveCallHint.qml:77
173msgid "Tap to return to call..."
173msgid "Tap to return to call..."
174−msgstr ""
174+msgstr "Dotknij aby powrócić do połączenia..."
175
175
176#: qml/Panel/ActiveCallHint.qml:90
176#: qml/Panel/ActiveCallHint.qml:90
177msgid "Conference"
177msgid "Conference"
178−msgstr ""
178+msgstr "Konferencja"
179
179
180#: qml/Panel/Indicators/MenuItemFactory.qml:583
180#: qml/Panel/Indicators/MenuItemFactory.qml:583
181msgid "In queue…"
181msgid "In queue…"
po/ru.po+8−8
@@ -8,23 +8,23 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2014-07-11 14:59+0200\n"
10"POT-Creation-Date: 2014-07-11 14:59+0200\n"
11−"PO-Revision-Date: 2014-07-30 12:49+0000\n"
11+"PO-Revision-Date: 2014-07-31 09:39+0000\n"
12"Last-Translator: Jay ZDLin <Unknown>\n"
12"Last-Translator: Jay ZDLin <Unknown>\n"
13"Language-Team: Russian <ru@li.org>\n"
13"Language-Team: Russian <ru@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2014-07-31 07:15+0000\n"
17+"X-Launchpad-Export-Date: 2014-08-01 07:14+0000\n"
18−"X-Generator: Launchpad (build 17131)\n"
18+"X-Generator: Launchpad (build 17141)\n"
19
19
20#: plugins/Unity/Launcher/launcheritem.cpp:43
20#: plugins/Unity/Launcher/launcheritem.cpp:43
21#: plugins/Unity/Launcher/launcheritem.cpp:73
21#: plugins/Unity/Launcher/launcheritem.cpp:73
22msgid "Pin shortcut"
22msgid "Pin shortcut"
23−msgstr ""
23+msgstr "Закрепить ярлык"
24
24
25#: plugins/Unity/Launcher/launcheritem.cpp:73
25#: plugins/Unity/Launcher/launcheritem.cpp:73
26msgid "Unpin shortcut"
26msgid "Unpin shortcut"
27−msgstr ""
27+msgstr "Изъять ярлык"
28
28
29#: qml/Components/EdgeDemoOverlay.qml:151
29#: qml/Components/EdgeDemoOverlay.qml:151
30msgid "Skip intro"
30msgid "Skip intro"
@@ -174,7 +174,7 @@ msgstr "Введите PIN код"
174
174
175#: qml/Panel/ActiveCallHint.qml:77
175#: qml/Panel/ActiveCallHint.qml:77
176msgid "Tap to return to call..."
176msgid "Tap to return to call..."
177−msgstr ""
177+msgstr "Коснитесь для возврата к вызову..."
178
178
179#: qml/Panel/ActiveCallHint.qml:90
179#: qml/Panel/ActiveCallHint.qml:90
180msgid "Conference"
180msgid "Conference"
@@ -190,7 +190,7 @@ msgstr "Загрузка"
190
190
191#: qml/Panel/Indicators/MenuItemFactory.qml:589
191#: qml/Panel/Indicators/MenuItemFactory.qml:589
192msgid "Paused, tap to resume"
192msgid "Paused, tap to resume"
193−msgstr ""
193+msgstr "Приостановлено, коснитесь для возобновления"
194
194
195#: qml/Panel/Indicators/MenuItemFactory.qml:591
195#: qml/Panel/Indicators/MenuItemFactory.qml:591
196msgid "Canceled"
196msgid "Canceled"
@@ -202,7 +202,7 @@ msgstr "Завершено"
202
202
203#: qml/Panel/Indicators/MenuItemFactory.qml:595
203#: qml/Panel/Indicators/MenuItemFactory.qml:595
204msgid "Failed, tap to retry"
204msgid "Failed, tap to retry"
205−msgstr ""
205+msgstr "Сбой, коснитесь для повтора"
206
206
207#: qml/Panel/SearchIndicator.qml:27
207#: qml/Panel/SearchIndicator.qml:27
208msgid "Search"
208msgid "Search"
po/sv.po+6−6
@@ -8,14 +8,14 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2014-07-11 14:59+0200\n"
10"POT-Creation-Date: 2014-07-11 14:59+0200\n"
11−"PO-Revision-Date: 2014-07-25 14:27+0000\n"
11+"PO-Revision-Date: 2014-07-31 08:10+0000\n"
12−"Last-Translator: Josef Andersson <Unknown>\n"
12+"Last-Translator: Peter Hultqvist <phq@silentorbit.com>\n"
13"Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n"
13"Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2014-07-26 07:17+0000\n"
17+"X-Launchpad-Export-Date: 2014-08-01 07:14+0000\n"
18−"X-Generator: Launchpad (build 17131)\n"
18+"X-Generator: Launchpad (build 17141)\n"
19"Language: sv\n"
19"Language: sv\n"
20
20
21#: plugins/Unity/Launcher/launcheritem.cpp:43
21#: plugins/Unity/Launcher/launcheritem.cpp:43
@@ -102,11 +102,11 @@ msgstr "KLAR"
102
102
103#: qml/Components/SeeMore.qml:35
103#: qml/Components/SeeMore.qml:35
104msgid "See more"
104msgid "See more"
105−msgstr "Se mer"
105+msgstr "Visa mer"
106
106
107#: qml/Components/SeeMore.qml:58 qml/Dash/GenericScopeView.qml:330
107#: qml/Components/SeeMore.qml:58 qml/Dash/GenericScopeView.qml:330
108msgid "See less"
108msgid "See less"
109−msgstr "Se mindre"
109+msgstr "Visa mindre"
110
110
111#: qml/Dash/DashApps.qml:37
111#: qml/Dash/DashApps.qml:37
112msgid "Recent"
112msgid "Recent"
qml/Components/PageHeader.qml+24−7
@@ -44,6 +44,12 @@ Item {
44 signal backClicked()
44 signal backClicked()
45
45
46 onScopeStyleChanged: refreshLogo()
46 onScopeStyleChanged: refreshLogo()
47+ onSearchQueryChanged: {
48+ // Make sure we are at the search page if the search query changes behind our feet
49+ if (searchQuery) {
50+ headerContainer.showSearch = true;
51+ }
52+ }
47
53
48 function triggerSearch() {
54 function triggerSearch() {
49 if (searchEntryEnabled) {
55 if (searchEntryEnabled) {
@@ -52,6 +58,12 @@ Item {
52 }
58 }
53 }
59 }
54
60
61+ function closePopup() {
62+ if (headerContainer.popover != null) {
63+ PopupUtils.close(headerContainer.popover);
64+ }
65+ }
66+
55 function resetSearch(keepFocus) {
67 function resetSearch(keepFocus) {
56 if (searchHistory) {
68 if (searchHistory) {
57 searchHistory.addQuery(searchTextField.text);
69 searchHistory.addQuery(searchTextField.text);
@@ -60,9 +72,7 @@ Item {
60 unfocus();
72 unfocus();
61 }
73 }
62 searchTextField.text = "";
74 searchTextField.text = "";
63− if (headerContainer.popover != null) {
75+ closePopup();
64− PopupUtils.close(headerContainer.popover);
65− }
66 }
76 }
67
77
68 function unfocus() {
78 function unfocus() {
@@ -103,9 +113,7 @@ Item {
103 anchors { fill: parent; margins: units.gu(1); bottomMargin: units.gu(3) + bottomContainer.height }
113 anchors { fill: parent; margins: units.gu(1); bottomMargin: units.gu(3) + bottomContainer.height }
104 visible: headerContainer.showSearch
114 visible: headerContainer.showSearch
105 onPressed: {
115 onPressed: {
106− if (headerContainer.popover) {
116+ closePopup();
107− PopupUtils.close(headerContainer.popover);
108− }
109 if (!searchTextField.text) {
117 if (!searchTextField.text) {
110 headerContainer.showSearch = false;
118 headerContainer.showSearch = false;
111 }
119 }
@@ -172,6 +180,7 @@ Item {
172 property var contents: TextField {
180 property var contents: TextField {
173 id: searchTextField
181 id: searchTextField
174 objectName: "searchTextField"
182 objectName: "searchTextField"
183+ inputMethodHints: Qt.ImhNoPredictiveText
175 hasClearButton: false
184 hasClearButton: false
176 anchors {
185 anchors {
177 fill: parent
186 fill: parent
@@ -221,6 +230,12 @@ Item {
221 root.openSearchHistory();
230 root.openSearchHistory();
222 }
231 }
223 }
232 }
233+
234+ onTextChanged: {
235+ if (text != "") {
236+ closePopup();
237+ }
238+ }
224 }
239 }
225 }
240 }
226
241
@@ -298,6 +313,7 @@ Item {
298
313
299 Repeater {
314 Repeater {
300 id: recentSearches
315 id: recentSearches
316+ objectName: "recentSearches"
301 model: searchHistory
317 model: searchHistory
302
318
303 delegate: Standard {
319 delegate: Standard {
@@ -306,7 +322,8 @@ Item {
306 onClicked: {
322 onClicked: {
307 searchHistory.addQuery(text);
323 searchHistory.addQuery(text);
308 searchTextField.text = text;
324 searchTextField.text = text;
309− PopupUtils.close(popover);
325+ closePopup();
326+ unfocus();
310 }
327 }
311 }
328 }
312 }
329 }
qml/Dash/Apps/CloseIcon.qmldeleted−62
@@ -1,62 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−
17−import QtQuick 2.0
18−
19−Item {
20− id: root
21−
22− Image {
23− id: closeIcon
24− anchors.centerIn: parent
25− source: "graphics/close_btn.png"
26−
27− state: (root.enabled) ? "shown" : "hidden"
28−
29− states: [
30− State {
31− name: "shown"
32− PropertyChanges {
33− target: closeIcon
34− height: root.height
35− width: root.width
36− }
37− },
38− State {
39− name: "hidden"
40− PropertyChanges {
41− target: closeIcon
42− height: 0
43− width: 0
44− }
45− }
46−
47− ]
48− transitions: [
49− Transition {
50− to: "shown"
51− NumberAnimation {
52− properties: "width, height"; duration: 300
53− easing { type: Easing.OutBack; overshoot: 5 }
54− }
55− },
56− Transition {
57− to: "hidden"
58− NumberAnimation { properties: "width, height"; duration: 250; }
59− }
60− ]
61− }
62−}
qml/Dash/Apps/RunningApplicationTile.qmldeleted−136
@@ -1,136 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−
17−import QtQuick 2.0
18−import Ubuntu.Components 0.1
19−import Unity.Application 0.1
20−import "../../Components/"
21−import "../../Components/ListItems"
22−
23−AbstractButton {
24− id: root
25− property var application
26−
27− signal requestedApplicationActivation(var application)
28− signal requestedApplicationTermination(var application)
29− signal requestedActivationMode()
30− signal requestedTerminationMode()
31−
32− width: thumbnail.width
33− height: thumbnail.height + labelContainer.height
34−
35− property bool terminationModeEnabled: false
36−
37− onClicked: {
38− if (!terminationModeEnabled)
39− requestedApplicationActivation(application)
40− }
41−
42− onPressAndHold: {
43− if (terminationModeEnabled) {
44− requestedActivationMode()
45− } else {
46− requestedTerminationMode()
47− }
48− }
49−
50− Item {
51− id: thumbnail
52−
53− width: shapedApplicationImage.width
54− height: shapedApplicationImage.height
55−
56− UbuntuShape {
57− id: shapedApplicationImage
58− x: 0
59− y: 0
60− height: applicationImage.height
61− width: applicationImage.width
62− radius: "medium"
63−
64− image: Image {
65− id: applicationImage
66− source: application.screenshot
67− // height : width = ss.height : ss.width
68−
69− property bool isLandscape: sourceSize.width > sourceSize.height
70− property real maxDimension: units.gu(17)
71−
72− width: isLandscape ? Math.min(sourceSize.width, maxDimension) : height * (sourceSize.width / sourceSize.height)
73− height: isLandscape ? width * (sourceSize.height / sourceSize.width) : Math.min(sourceSize.height, maxDimension)
74− fillMode: Image.Stretch
75− }
76−
77− }
78−
79− UbuntuShape {
80− id: borderPressed
81−
82− anchors.fill: shapedApplicationImage
83− radius: "medium"
84− borderSource: "radius_pressed.sci"
85− opacity: root.pressed ? 1.0 : 0.0
86− Behavior on opacity { NumberAnimation { duration: 200; easing.type: Easing.OutQuint } }
87− }
88− }
89−
90− // FIXME: label code duplicated with Tile
91− Item {
92− id: labelContainer
93− anchors {
94− left: thumbnail.left
95− right: thumbnail.right
96− top: thumbnail.bottom
97− }
98− height: units.gu(2)
99−
100− Label {
101− id: label
102− anchors {
103− baseline: parent.bottom
104− left: parent.left
105− right: parent.right
106− }
107− text: (application) ? application.name : ""
108−
109− // TODO karni: Update Ubuntu.Components.Themes.Palette and use theme color instead
110− color: "grey"
111− opacity: 0.9
112− fontSize: "small"
113− elide: Text.ElideMiddle
114− horizontalAlignment: Text.AlignHCenter
115− }
116− }
117−
118− CloseIcon {
119− objectName: "closeIcon " + model.name
120− anchors {
121− left: thumbnail.left
122− leftMargin: -units.gu(1)
123− top: thumbnail.top
124− topMargin: -units.gu(1)
125− }
126− height: units.gu(6)
127− width: units.gu(6)
128− id: closeIcon
129− enabled: root.terminationModeEnabled
130−
131− MouseArea {
132− anchors { fill: parent; margins: -units.gu(1) }
133− onClicked: requestedApplicationTermination(application)
134− }
135− }
136−}
qml/Dash/Apps/RunningApplicationsGrid.qmldeleted−105
@@ -1,105 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−
17−import QtQuick 2.0
18−import "../../Components"
19−
20−import Ubuntu.Gestures 0.1
21−import Unity.Application 0.1
22−
23−ResponsiveFlowView {
24− id: root
25− clip: true
26−
27− signal updateScreenshots
28− property alias enableHeightBehavior: heightBehaviour.enabled
29− property bool enableHeightBehaviorOnNextCreation: model.count === 0
30−
31− Behavior on height {
32− id: heightBehaviour
33− enabled: false
34− NumberAnimation { duration: 200; easing.type: Easing.InOutQuad }
35− }
36−
37− Connections {
38− target: root.model
39− onCountChanged: {
40− heightBehaviour.enabled = true;
41− }
42− }
43−
44− property bool canEnableTerminationMode: true
45−
46− onCanEnableTerminationModeChanged: {
47− if (!canEnableTerminationMode)
48− terminationModeEnabled = false
49− }
50−
51− // when false, it means it's on activation mode
52− property bool terminationModeEnabled: false
53−
54− maximumNumberOfColumns: 10
55− minimumHorizontalSpacing: units.gu(2)
56− referenceDelegateWidth: units.gu(11)
57− verticalSpacing: units.gu(2)
58−
59− delegate: Item {
60− width: runningAppTile.width + root.horizontalSpacing
61− height: runningAppTile.height + root.verticalSpacing
62−
63− RunningApplicationTile {
64− id: runningAppTile
65− objectName: "runningAppTile " + model.name
66− anchors {
67− top: parent.top
68− horizontalCenter: parent.horizontalCenter
69− }
70− application: model
71− onRequestedActivationMode: { root.terminationModeEnabled = false }
72− onRequestedTerminationMode: {
73− if (canEnableTerminationMode)
74− root.terminationModeEnabled = true
75− }
76− onRequestedApplicationTermination: {
77− ApplicationManager.stopApplication(model.appId)
78− }
79− onRequestedApplicationActivation: {
80− ApplicationManager.requestFocusApplication(model.appId)
81− }
82−
83− terminationModeEnabled: root.terminationModeEnabled
84− }
85− }
86−
87− move: Transition {
88− NumberAnimation { properties: "x,y"; duration: 400; easing.type: Easing.OutCubic }
89− }
90−
91− MouseArea {
92− anchors.fill: parent
93− z: -1 // behind all RunningApplicationTiles
94− enabled: root.terminationModeEnabled
95− onPressed: { root.terminationModeEnabled = false; }
96− }
97−
98− PressedOutsideNotifier {
99− anchors.fill: parent
100− enabled: root.terminationModeEnabled
101− onPressedOutside: {
102− root.terminationModeEnabled = false;
103− }
104− }
105−}
qml/Dash/Apps/graphics/close_btn@9.pngdeleted

Binary file not shown.

qml/Dash/CardTool.qml+27−2
@@ -165,15 +165,40 @@ Item {
165 }
165 }
166 }
166 }
167
167
168+ Item {
169+ id: attributesModel
170+ property int numOfAttributes: 0
171+ property var model: []
172+ property bool hasAttributes: {
173+ var attributes = components["attributes"];
174+ var hasAttributesFlag = (attributes != undefined) && attributes["field"];
175+
176+ if (hasAttributesFlag) {
177+ if (attributes["max-count"]) {
178+ numOfAttributes = attributes["max-count"];
179+ }
180+ }
181+ return hasAttributesFlag
182+ }
183+
184+ onNumOfAttributesChanged: {
185+ model = []
186+ for (var i = 0; i < numOfAttributes; i++) {
187+ model.push( {"value":"text"+(i+1), "icon":"image://theme/ok" } );
188+ }
189+ }
190+ }
191+
168 Loader {
192 Loader {
169 id: cardLoader
193 id: cardLoader
170− property var fields: ["art", "mascot", "title", "subtitle", "summary"]
194+ property var fields: ["art", "mascot", "title", "subtitle", "summary", "attributes"]
171 property var maxData: {
195 property var maxData: {
172 "art": Qt.resolvedUrl("graphics/checkers.png"),
196 "art": Qt.resolvedUrl("graphics/checkers.png"),
173 "mascot": Qt.resolvedUrl("graphics/checkers.png"),
197 "mascot": Qt.resolvedUrl("graphics/checkers.png"),
174 "title": "—\n—",
198 "title": "—\n—",
175 "subtitle": "—",
199 "subtitle": "—",
176− "summary": "—\n—\n—\n—\n—"
200+ "summary": "—\n—\n—\n—\n—",
201+ "attributes": attributesModel.model
177 }
202 }
178 sourceComponent: cardTool.cardComponent
203 sourceComponent: cardTool.cardComponent
179 onLoaded: {
204 onLoaded: {
qml/Dash/DashApps.qmldeleted−40
@@ -1,40 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−
17−import QtQuick 2.0
18−import Ubuntu.Components 0.1
19−import Utils 0.1
20−import Unity.Application 0.1
21−import "../Components"
22−import "../Components/ListItems"
23−import "Apps"
24−
25−GenericScopeView {
26− id: scopeView
27− objectName: "DashApps"
28−
29− property var runningApps: ApplicationManager
30−
31− QtObject {
32− id: countObject
33− property int count: scopeView.scope.searchQuery.length == 0 ? scopeView.runningApps.count : 0
34− }
35−
36− onScopeChanged: {
37− scopeView.scope.categories.addSpecialCategory("running.apps.category", i18n.tr("Recent"), "", "{ \"template\": { \"category-layout\": \"running-apps\" } }", countObject);
38− enableHeightBehaviorOnNextCreation = scopeView.runningApps.count === 0
39− }
40−}
qml/Dash/DashContent.qml+1−3
@@ -126,9 +126,7 @@ Item {
126 return (xPositionRelativetoView > -width && xPositionRelativetoView < width) ? 1 : 0
126 return (xPositionRelativetoView > -width && xPositionRelativetoView < width) ? 1 : 0
127 }
127 }
128 asynchronous: true
128 asynchronous: true
129− // TODO This if will eventually go away since we're killing DashApps.qml
130− // once we move app closing to the spread
131− source: (scope.id == "clickscope") ? "DashApps.qml" : "GenericScopeView.qml"
129+ source: "GenericScopeView.qml"
132 objectName: scope.id + " loader"
130 objectName: scope.id + " loader"
133
131
134 readonly property bool moving: item ? item.moving : false
132 readonly property bool moving: item ? item.moving : false
qml/Dash/GenericScopeView.qml+1−10
@@ -18,7 +18,6 @@ import QtQuick 2.0
18import Ubuntu.Components 0.1
18import Ubuntu.Components 0.1
19import Utils 0.1
19import Utils 0.1
20import Unity 0.2
20import Unity 0.2
21−import Unity.Application 0.1
22import Dash 0.1
21import Dash 0.1
23import "../Components"
22import "../Components"
24import "../Components/ListItems" as ListItems
23import "../Components/ListItems" as ListItems
@@ -194,7 +193,6 @@ FocusScope {
194 switch (cardTool.categoryLayout) {
193 switch (cardTool.categoryLayout) {
195 case "carousel": return "CardCarousel.qml";
194 case "carousel": return "CardCarousel.qml";
196 case "vertical-journal": return "CardVerticalJournal.qml";
195 case "vertical-journal": return "CardVerticalJournal.qml";
197− case "running-apps": return "Apps/RunningApplicationsGrid.qml";
198 case "grid":
196 case "grid":
199 default: return "CardGrid.qml";
197 default: return "CardGrid.qml";
200 }
198 }
@@ -205,14 +203,7 @@ FocusScope {
205 item.enableHeightBehavior = scopeView.enableHeightBehaviorOnNextCreation;
203 item.enableHeightBehavior = scopeView.enableHeightBehaviorOnNextCreation;
206 scopeView.enableHeightBehaviorOnNextCreation = false;
204 scopeView.enableHeightBehaviorOnNextCreation = false;
207 }
205 }
208− if (source.toString().indexOf("Apps/RunningApplicationsGrid.qml") != -1) {
209− // TODO: this is still a kludge :D Ideally add some kind of hook so that we
210− // can do this from DashApps.qml or think a better way that needs no special casing
211− item.model = Qt.binding(function() { return runningApps; })
212− item.canEnableTerminationMode = Qt.binding(function() { return scopeView.isCurrent })
213− } else {
214− item.model = Qt.binding(function() { return results })
206+ item.model = Qt.binding(function() { return results })
215− }
216 item.objectName = Qt.binding(function() { return categoryId })
207 item.objectName = Qt.binding(function() { return categoryId })
217 item.scopeStyle = scopeView.scopeStyle;
208 item.scopeStyle = scopeView.scopeStyle;
218 if (baseItem.expandable) {
209 if (baseItem.expandable) {
qml/Launcher/LauncherDelegate.qml+9−6
@@ -70,28 +70,31 @@ Item {
70 height: root.itemHeight - units.gu(1)
70 height: root.itemHeight - units.gu(1)
71 }
71 }
72
72
73− BorderImage {
73+ UbuntuShape {
74 objectName: "countEmblem"
74 objectName: "countEmblem"
75 anchors {
75 anchors {
76 right: parent.right
76 right: parent.right
77 top: parent.top
77 top: parent.top
78 margins: units.dp(3)
78 margins: units.dp(3)
79 }
79 }
80− width: Math.min(root.itemWidth, Math.max(units.gu(3), countLabel.implicitWidth + units.gu(2.5)))
80+ width: Math.min(root.itemWidth, Math.max(units.gu(2), countLabel.implicitWidth + units.gu(1)))
81− height: units.gu(3)
81+ height: units.gu(2)
82− source: "graphics/notification.sci"
82+ color: UbuntuColors.orange
83 visible: root.count > 0
83 visible: root.count > 0
84+ borderSource: "none"
84
85
85 Label {
86 Label {
86 id: countLabel
87 id: countLabel
87 text: root.count
88 text: root.count
88 anchors.centerIn: parent
89 anchors.centerIn: parent
90+ // FIXME: verticalCenter seems to be off wee bit and QML doesn't have a centerLine
91+ // property for Text: https://bugreports.qt-project.org/browse/QTBUG-40479
92+ anchors.verticalCenterOffset: -units.dp(.5)
89 width: root.itemWidth - units.gu(1)
93 width: root.itemWidth - units.gu(1)
90 horizontalAlignment: Text.AlignHCenter
94 horizontalAlignment: Text.AlignHCenter
91 elide: Text.ElideRight
95 elide: Text.ElideRight
92 color: "white"
96 color: "white"
93− fontSize: "small"
97+ fontSize: "x-small"
94− font.bold: true
95 }
98 }
96 }
99 }
97
100
qml/Launcher/graphics/notification@30.pngdeleted

Binary file not shown.

qml/Launcher/graphics/notification@30.scideleted−5
@@ -1,5 +0,0 @@
1−border.left: 36
2−border.top: 36
3−border.bottom: 36
4−border.right: 36
5−source: notification@30.png
qml/Panel/Indicators/DefaultIndicatorPage.qml+1−1
@@ -126,7 +126,7 @@ IndicatorBase {
126 id: loader
126 id: loader
127 objectName: "menuItem" + index
127 objectName: "menuItem" + index
128 asynchronous: false
128 asynchronous: false
129− visible: height > 0
129+ visible: status == Loader.Ready
130
130
131 property int modelIndex: index
131 property int modelIndex: index
132
132
src/main.cpp+7
@@ -25,6 +25,7 @@
25#include <QtQml/QQmlContext>
25#include <QtQml/QQmlContext>
26#include <QLibrary>
26#include <QLibrary>
27#include <QDebug>
27#include <QDebug>
28+#include <csignal>
28#include <libintl.h>
29#include <libintl.h>
29
30
30// local
31// local
@@ -140,6 +141,12 @@ Load the testability driver");
140 view->setSource(source);
141 view->setSource(source);
141 QObject::connect(view->engine(), SIGNAL(quit()), application, SLOT(quit()));
142 QObject::connect(view->engine(), SIGNAL(quit()), application, SLOT(quit()));
142
143
144+ if (!isMirServer && qEnvironmentVariableIsSet("UNITY_MIR_EMITS_SIGSTOP")) {
145+ // Emit SIGSTOP as expected by upstart, under Mir it's qtmir that will raise it.
146+ // see http://upstart.ubuntu.com/cookbook/#expect-stop
147+ raise(SIGSTOP);
148+ }
149+
143 if (isMirServer || parser.isSet(fullscreenOption)) {
150 if (isMirServer || parser.isSet(fullscreenOption)) {
144 view->showFullScreen();
151 view->showFullScreen();
145 } else {
152 } else {
tests/autopilot/unity8/shell/emulators/dash.py−4
@@ -188,10 +188,6 @@ class GenericScopeView(emulators.UnityEmulatorBase):
188 raise emulators.UnityEmulatorException(
188 raise emulators.UnityEmulatorException(
189 'No category found with name {}'.format(category))
189 'No category found with name {}'.format(category))
190
190
191−
192−class DashApps(GenericScopeView):
193− """Autopilot emulator for the applications scope."""
194−
195 def get_applications(self, category):
191 def get_applications(self, category):
196 """Return the list of applications on a category.
192 """Return the list of applications on a category.
197
193
tests/autopilot/unity8/shell/tests/test_emulators.py+1−1
@@ -142,7 +142,7 @@ class DashEmulatorTestCase(DashBaseTestCase):
142 scope_id = 'clickscope'
142 scope_id = 'clickscope'
143 scope = self.dash.open_scope(scope_id)
143 scope = self.dash.open_scope(scope_id)
144 self._assert_scope_is_opened(scope, scope_id)
144 self._assert_scope_is_opened(scope, scope_id)
145− self.assertIsInstance(scope, dash_emulators.DashApps)
145+ self.assertIsInstance(scope, dash_emulators.GenericScopeView)
146
146
147
147
148class GenericScopeViewEmulatorTestCase(DashBaseTestCase):
148class GenericScopeViewEmulatorTestCase(DashBaseTestCase):
tests/autopilot/unity8/shell/tests/test_upstart.py+18−3
@@ -25,7 +25,8 @@ import signal
25import subprocess
25import subprocess
26import time
26import time
27
27
28+import fixtures
28−from testtools.matchers._basic import Equals
29+from testtools.matchers import Equals, MismatchError
29from autopilot.matchers import Eventually
30from autopilot.matchers import Eventually
30from autopilot.introspection import get_proxy_object_for_existing_process
31from autopilot.introspection import get_proxy_object_for_existing_process
31
32
@@ -100,8 +101,21 @@ class UpstartIntegrationTests(UnityTestCase):
100 emulator_base=UnityEmulatorBase,))
101 emulator_base=UnityEmulatorBase,))
101
102
102 def test_no_sigstop(self):
103 def test_no_sigstop(self):
104+ self.useFixture(
105+ fixtures.EnvironmentVariable(
103− self.patch_environment("UNITY_MIR_EMITS_SIGSTOP", "")
106+ 'UNITY_MIR_EMITS_SIGSTOP', newvalue=None))
104 self._launch_unity()
107 self._launch_unity()
108+
109+ try:
110+ self.assertThat(
111+ lambda: os.WIFSTOPPED(self._get_status()),
112+ Eventually(Equals(True)))
113+ except MismatchError:
114+ pass
115+ else:
116+ self.process.send_signal(signal.SIGCONT)
117+ self.fail('Unity8 raised SIGSTOP')
118+
105 self._set_proxy()
119 self._set_proxy()
106
120
107 logger.debug("Unity started, waiting for it to be ready.")
121 logger.debug("Unity started, waiting for it to be ready.")
@@ -109,7 +123,8 @@ class UpstartIntegrationTests(UnityTestCase):
109 logger.debug("Unity loaded and ready.")
123 logger.debug("Unity loaded and ready.")
110
124
111 def test_expect_sigstop(self):
125 def test_expect_sigstop(self):
126+ self.useFixture(
112− self.patch_environment("UNITY_MIR_EMITS_SIGSTOP", "1")
127+ fixtures.EnvironmentVariable('UNITY_MIR_EMITS_SIGSTOP', '1'))
113 self._launch_unity()
128 self._launch_unity()
114 self.assertThat(
129 self.assertThat(
115 lambda: os.WIFSTOPPED(self._get_status()),
130 lambda: os.WIFSTOPPED(self._get_status()),
tests/mocks/Unity/CMakeLists.txt+1−1
@@ -6,7 +6,7 @@ add_subdirectory(Notifications)
6pkg_search_module(DEE dee-1.0 REQUIRED)
6pkg_search_module(DEE dee-1.0 REQUIRED)
7pkg_search_module(GOBJECT gobject-2.0 REQUIRED)
7pkg_search_module(GOBJECT gobject-2.0 REQUIRED)
8pkg_search_module(DEEQT libdee-qt5 REQUIRED)
8pkg_search_module(DEEQT libdee-qt5 REQUIRED)
9−pkg_check_modules(SCOPES_API REQUIRED unity-shell-scopes=2)
9+pkg_check_modules(SCOPES_API REQUIRED unity-shell-scopes=3)
10
10
11include_directories(
11include_directories(
12 ${CMAKE_CURRENT_BINARY_DIR}
12 ${CMAKE_CURRENT_BINARY_DIR}
tests/mocks/Unity/fake_scopes.cpp+5
@@ -125,6 +125,11 @@ bool Scopes::loaded() const
125 return m_loaded;
125 return m_loaded;
126}
126}
127
127
128+unity::shell::scopes::ScopeInterface* Scopes::overviewScope() const
129+{
130+ return nullptr;
131+}
132+
128void Scopes::addScope(Scope* scope)
133void Scopes::addScope(Scope* scope)
129{
134{
130 int index = rowCount();
135 int index = rowCount();
tests/mocks/Unity/fake_scopes.h+1
@@ -50,6 +50,7 @@ public:
50 QModelIndex parent ( const QModelIndex & index ) const;
50 QModelIndex parent ( const QModelIndex & index ) const;
51
51
52 bool loaded() const override;
52 bool loaded() const override;
53+ unity::shell::scopes::ScopeInterface* overviewScope() const override;
53
54
54private Q_SLOTS:
55private Q_SLOTS:
55 void updateScopes();
56 void updateScopes();
tests/plugins/Dash/CMakeLists.txt+1
@@ -79,3 +79,4 @@ set(qmltest_DEFAULT_NO_ADD_TEST TRUE)
79set(qmltest_DEFAULT_PROPERTIES ENVIRONMENT "LC_ALL=C")
79set(qmltest_DEFAULT_PROPERTIES ENVIRONMENT "LC_ALL=C")
80add_qml_test(. ScopeStyle IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins)
80add_qml_test(. ScopeStyle IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins)
81add_qml_test(. ListViewWithPageHeaderQML IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins)
81add_qml_test(. ListViewWithPageHeaderQML IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins)
82+add_qml_test(. CardAttributes IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins)
tests/plugins/Dash/cardcreator/1.res+63−61
@@ -5,8 +5,8 @@ AbstractButton {
5 property var cardData;
5 property var cardData;
6 property var artShapeBorderSource: undefined;
6 property var artShapeBorderSource: undefined;
7 property real fontScale: 1.0;
7 property real fontScale: 1.0;
8− property var scopeStyle: null;
8+ property var scopeStyle: null;
9− property int headerAlignment: Text.AlignLeft;
9+ property int headerAlignment: Text.AlignLeft;
10 property int fixedHeaderHeight: -1;
10 property int fixedHeaderHeight: -1;
11 property size fixedArtShapeSize: Qt.size(-1, -1);
11 property size fixedArtShapeSize: Qt.size(-1, -1);
12 readonly property string title: cardData && cardData["title"] || "";
12 readonly property string title: cardData && cardData["title"] || "";
@@ -16,71 +16,73 @@ AbstractButton {
16onArtShapeBorderSourceChanged: { if (artShapeBorderSource !== undefined && artShapeLoader.item) artShapeLoader.item.borderSource = artShapeBorderSource; }
16onArtShapeBorderSourceChanged: { if (artShapeBorderSource !== undefined && artShapeLoader.item) artShapeLoader.item.borderSource = artShapeBorderSource; }
17readonly property size artShapeSize: artShapeLoader.item ? Qt.size(artShapeLoader.item.width, artShapeLoader.item.height) : Qt.size(-1, -1);
17readonly property size artShapeSize: artShapeLoader.item ? Qt.size(artShapeLoader.item.width, artShapeLoader.item.height) : Qt.size(-1, -1);
18Item {
18Item {
19− id: artShapeHolder;
19+ id: artShapeHolder;
20− height: root.fixedArtShapeSize.height > 0 ? root.fixedArtShapeSize.height : artShapeLoader.height;
20+ height: root.fixedArtShapeSize.height > 0 ? root.fixedArtShapeSize.height : artShapeLoader.height;
21− width: root.fixedArtShapeSize.width > 0 ? root.fixedArtShapeSize.width : artShapeLoader.width;
21+ width: root.fixedArtShapeSize.width > 0 ? root.fixedArtShapeSize.width : artShapeLoader.width;
22− anchors { horizontalCenter: parent.horizontalCenter; }
22+ anchors { horizontalCenter: parent.horizontalCenter; }
23− Loader {
23+ Loader {
24− id: artShapeLoader;
24+ id: artShapeLoader;
25− objectName: "artShapeLoader";
25+ objectName: "artShapeLoader";
26− active: cardData && cardData["art"] || false;
26+ active: cardData && cardData["art"] || false;
27− asynchronous: root.asynchronous;
28− visible: status == Loader.Ready;
29− sourceComponent: UbuntuShape {
30− id: artShape;
31− objectName: "artShape";
32− radius: "medium";
33− visible: image.status == Image.Ready;
34− readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1;
35− readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1;
36− readonly property bool aspectSmallerThanImageAspect: aspect < image.aspect;
37− Component.onCompleted: { updateWidthHeightBindings(); if (artShapeBorderSource !== undefined) borderSource = artShapeBorderSource; }
38− onAspectSmallerThanImageAspectChanged: updateWidthHeightBindings();
39− Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); }
40− function updateWidthHeightBindings() {
41− if (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) {
42− width = root.fixedArtShapeSize.width;
43− height = root.fixedArtShapeSize.height;
44− } else if (aspectSmallerThanImageAspect) {
45− width = Qt.binding(function() { return !visible ? 0 : image.width });
46− height = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.height : width / image.aspect });
47− } else {
48− width = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.width : height * image.aspect });
49− height = Qt.binding(function() { return !visible ? 0 : image.height });
50− }
51− }
52− image: Image {
53− objectName: "artImage";
54− source: cardData && cardData["art"] || "";
55− cache: true;
56 asynchronous: root.asynchronous;
27 asynchronous: root.asynchronous;
28+ visible: status == Loader.Ready;
29+ sourceComponent: UbuntuShape {
30+ id: artShape;
31+ objectName: "artShape";
32+ radius: "medium";
33+ visible: image.status == Image.Ready;
34+ readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1;
35+ readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1;
36+ readonly property bool aspectSmallerThanImageAspect: aspect < image.aspect;
37+ Component.onCompleted: { updateWidthHeightBindings(); if (artShapeBorderSource !== undefined) borderSource = artShapeBorderSource; }
38+ onAspectSmallerThanImageAspectChanged: updateWidthHeightBindings();
39+ Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); }
40+ function updateWidthHeightBindings() {
41+ if (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) {
42+ width = root.fixedArtShapeSize.width;
43+ height = root.fixedArtShapeSize.height;
44+ } else if (aspectSmallerThanImageAspect) {
45+ width = Qt.binding(function() { return !visible ? 0 : image.width });
46+ height = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.height : width / image.aspect });
47+ } else {
48+ width = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.width : height * image.aspect });
49+ height = Qt.binding(function() { return !visible ? 0 : image.height });
50+ }
51+ }
52+ image: Image {
53+ objectName: "artImage";
54+ source: cardData && cardData["art"] || "";
55+ cache: true;
56+ asynchronous: root.asynchronous;
57− fillMode: components && components["art"]["fill-mode"] === "fit" ? Image.PreserveAspectFit: Image.PreserveAspectCrop;
57+ fillMode: components && components["art"]["fill-mode"] === "fit" ? Image.PreserveAspectFit: Image.PreserveAspectCrop;
58− readonly property real aspect: implicitWidth / implicitHeight;
58+ readonly property real aspect: implicitWidth / implicitHeight;
59− width: root.width;
59+ width: root.width;
60− height: width / artShape.aspect;
60+ height: width / artShape.aspect;
61+ }
62+ }
61 }
63 }
62− }
64+ }
63− }
64− }
65readonly property int headerHeight: titleLabel.height;
65readonly property int headerHeight: titleLabel.height;
66Label {
66Label {
67− id: titleLabel;
67+ id: titleLabel;
68− objectName: "titleLabel";
68+ objectName: "titleLabel";
69− anchors { right: parent.right;left: parent.left;
69+ anchors { right: parent.right;
70+rightMargin: units.gu(1);
71+left: parent.left;
70top: artShapeHolder.bottom;
72top: artShapeHolder.bottom;
71 topMargin: units.gu(1);
73 topMargin: units.gu(1);
72leftMargin: units.gu(1);
74leftMargin: units.gu(1);
73− }
75+ }
74− elide: Text.ElideRight;
76+ elide: Text.ElideRight;
75− fontSize: "small";
77+ fontSize: "small";
76− wrapMode: Text.Wrap;
78+ wrapMode: Text.Wrap;
77− maximumLineCount: 2;
79+ maximumLineCount: 2;
78− font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
80+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
79− color: root.scopeStyle ? root.scopeStyle.foreground : "grey";
81+ color: root.scopeStyle ? root.scopeStyle.foreground : "grey";
80− visible: showHeader ;
82+ visible: showHeader ;
81− text: root.title;
83+ text: root.title;
82− font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal;
84+ font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal;
83− horizontalAlignment: root.headerAlignment;
85+ horizontalAlignment: root.headerAlignment;
84− }
86+ }
85implicitHeight: titleLabel.y + titleLabel.height + units.gu(1);
87implicitHeight: titleLabel.y + titleLabel.height + units.gu(1);
86}
88}
tests/plugins/Dash/cardcreator/2.res+94−91
@@ -5,8 +5,8 @@ AbstractButton {
5 property var cardData;
5 property var cardData;
6 property var artShapeBorderSource: undefined;
6 property var artShapeBorderSource: undefined;
7 property real fontScale: 1.0;
7 property real fontScale: 1.0;
8− property var scopeStyle: null;
8+ property var scopeStyle: null;
9− property int headerAlignment: Text.AlignLeft;
9+ property int headerAlignment: Text.AlignLeft;
10 property int fixedHeaderHeight: -1;
10 property int fixedHeaderHeight: -1;
11 property size fixedArtShapeSize: Qt.size(-1, -1);
11 property size fixedArtShapeSize: Qt.size(-1, -1);
12 readonly property string title: cardData && cardData["title"] || "";
12 readonly property string title: cardData && cardData["title"] || "";
@@ -14,104 +14,107 @@ AbstractButton {
14 property bool showHeader: true;
14 property bool showHeader: true;
15 implicitWidth: childrenRect.width;
15 implicitWidth: childrenRect.width;
16Loader {
16Loader {
17− id: backgroundLoader;
17+ id: backgroundLoader;
18− objectName: "backgroundLoader";
18+ objectName: "backgroundLoader";
19− anchors.fill: parent;
19+ anchors.fill: parent;
20− asynchronous: root.asynchronous;
20+ asynchronous: root.asynchronous;
21− visible: status == Loader.Ready;
21+ visible: status == Loader.Ready;
22− sourceComponent: UbuntuShape {
22+ sourceComponent: UbuntuShape {
23− objectName: "background";
23+ objectName: "background";
24− radius: "medium";
24+ radius: "medium";
25− color: getColor(0) || "white";
25+ color: getColor(0) || "white";
26− gradientColor: getColor(1) || color;
26+ gradientColor: getColor(1) || color;
27− anchors.fill: parent;
27+ anchors.fill: parent;
28− image: backgroundImage.source ? backgroundImage : null;
28+ image: backgroundImage.source ? backgroundImage : null;
29− property real luminance: 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b;
29+ property real luminance: 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b;
30− property Image backgroundImage: Image {
30+ property Image backgroundImage: Image {
31− objectName: "backgroundImage";
31+ objectName: "backgroundImage";
32− source: {
32+ source: {
33− if (cardData && typeof cardData["background"] === "string") return cardData["background"];
33+ if (cardData && typeof cardData["background"] === "string") return cardData["background"];
34− else if (template && typeof template["card-background"] === "string") return template["card-background"];
34+ else if (template && typeof template["card-background"] === "string") return template["card-background"];
35− else return "";
35+ else return "";
36− }
36+ }
37− }
37+ }
38− function getColor(index) {
38+ function getColor(index) {
39− if (cardData && typeof cardData["background"] === "object"
39+ if (cardData && typeof cardData["background"] === "object"
40− && (cardData["background"]["type"] === "color" || cardData["background"]["type"] === "gradient")) {
40+ && (cardData["background"]["type"] === "color" || cardData["background"]["type"] === "gradient")) {
41− return cardData["background"]["elements"][index];
41+ return cardData["background"]["elements"][index];
42− } else if (template && typeof template["card-background"] === "object"
42+ } else if (template && typeof template["card-background"] === "object"
43− && (template["card-background"]["type"] === "color" || template["card-background"]["type"] === "gradient")) {
43+ && (template["card-background"]["type"] === "color" || template["card-background"]["type"] === "gradient")) {
44− return template["card-background"]["elements"][index];
44+ return template["card-background"]["elements"][index];
45− } else return undefined;
45+ } else return undefined;
46− }
46+ }
47− }
47+ }
48− }
48+ }
49readonly property size artShapeSize: Qt.size(-1, -1);
49readonly property size artShapeSize: Qt.size(-1, -1);
50readonly property int headerHeight: row.height;
50readonly property int headerHeight: row.height;
51Row {
51Row {
52− id: row;
52+ id: row;
53− objectName: "outerRow";
53+ objectName: "outerRow";
54− property real margins: units.gu(1);
54+ property real margins: units.gu(1);
55− spacing: margins;
55+ spacing: margins;
56− height: root.fixedHeaderHeight != -1 ? root.fixedHeaderHeight : implicitHeight;
56+ height: root.fixedHeaderHeight != -1 ? root.fixedHeaderHeight : implicitHeight;
57− anchors { top: parent.top;
57+ anchors { top: parent.top;
58 topMargin: units.gu(1);
58 topMargin: units.gu(1);
59− left: parent.left;
59+left: parent.left;
60−}
60+ }
61− anchors.right: parent.right;
61+ anchors.right: parent.right;
62− anchors.margins: margins;
62+ anchors.margins: margins;
63−data: [ Image {
63+ data: [ Image {
64− id: mascotImage;
64+ id: mascotImage;
65− objectName: "mascotImage";
65+ objectName: "mascotImage";
66− anchors { verticalCenter: parent.verticalCenter; }
66+ anchors { verticalCenter: parent.verticalCenter; }
67− readonly property int maxSize: Math.max(width, height) * 4;
67+ readonly property int maxSize: Math.max(width, height) * 4;
68− source: cardData && cardData["mascot"];
68+ source: cardData && cardData["mascot"];
69− width: units.gu(6);
69+ width: units.gu(6);
70− height: units.gu(5.625);
70+ height: units.gu(5.625);
71− sourceSize { width: maxSize; height: maxSize }
71+ sourceSize { width: maxSize; height: maxSize }
72− fillMode: Image.PreserveAspectCrop;
72+ fillMode: Image.PreserveAspectCrop;
73− horizontalAlignment: Image.AlignHCenter;
73+ horizontalAlignment: Image.AlignHCenter;
74− verticalAlignment: Image.AlignVCenter;
74+ verticalAlignment: Image.AlignVCenter;
75− visible: showHeader;
76− }
77−,
78−Column {
79− anchors.verticalCenter: parent.verticalCenter;
80− spacing: units.dp(2);
81− width: parent.width - x;
82− data: [ Label {
83− id: titleLabel;
84− objectName: "titleLabel";
85− anchors { left: parent.left; right: parent.right }
86− elide: Text.ElideRight;
87− fontSize: "small";
88− wrapMode: Text.Wrap;
89− maximumLineCount: 2;
90− font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
91− color: backgroundLoader.active && backgroundLoader.item && backgroundLoader.item.luminance < 0.7 ? "white" : (root.scopeStyle ? root.scopeStyle.foreground : "grey");
92− visible: showHeader ;
75+ visible: showHeader;
93− text: root.title;
76+ }
94− font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal;
95− horizontalAlignment: root.headerAlignment;
96− }
97−,
98−Label {
99− id: subtitleLabel;
100− objectName: "subtitleLabel";
101− anchors { left: parent.left; right: parent.right }
102
77
78+ ,
79+ Column {
80+ anchors.verticalCenter: parent.verticalCenter;
81+ spacing: units.dp(2);
82+ width: parent.width - x;
83+ data: [ Label {
84+ id: titleLabel;
85+ objectName: "titleLabel";
86+ anchors { left: parent.left; right: parent.right }
103 elide: Text.ElideRight;
87 elide: Text.ElideRight;
104 fontSize: "small";
88 fontSize: "small";
89+ wrapMode: Text.Wrap;
90+ maximumLineCount: 2;
105 font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
91 font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
106− color: backgroundLoader.active && backgroundLoader.item && backgroundLoader.item.luminance < 0.7 ? "white" : (root.scopeStyle ? root.scopeStyle.foreground : "grey");
92+ color: backgroundLoader.active && backgroundLoader.item && backgroundLoader.item.luminance < 0.7 ? "white" : (root.scopeStyle ? root.scopeStyle.foreground : "grey");
107− visible: titleLabel.visible && titleLabel.text;
93+ visible: showHeader ;
108− text: cardData && cardData["subtitle"] || "";
94+ text: root.title;
109− font.weight: Font.Light;
95+ font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal;
110 horizontalAlignment: root.headerAlignment;
96 horizontalAlignment: root.headerAlignment;
111 }
97 }
98+
99+ ,
100+ Label {
101+ id: subtitleLabel;
102+ objectName: "subtitleLabel";
103+ anchors { left: parent.left; right: parent.right }
104+ elide: Text.ElideRight;
105+ fontSize: "small";
106+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
107+ color: backgroundLoader.active && backgroundLoader.item && backgroundLoader.item.luminance < 0.7 ? "white" : (root.scopeStyle ? root.scopeStyle.foreground : "grey");
108+ visible: titleLabel.visible && titleLabel.text;
109+ text: cardData && cardData["subtitle"] || "";
110+ font.weight: Font.Light;
111+ horizontalAlignment: root.headerAlignment;
112+ }
113+
112−]
114+ ]
113−}
115+ }
116+
114−]
117+ ]
115−}
118+ }
116implicitHeight: row.y + row.height + units.gu(1);
119implicitHeight: row.y + row.height + units.gu(1);
117}
120}
tests/plugins/Dash/cardcreator/3.res+77−74
@@ -5,8 +5,8 @@ AbstractButton {
5 property var cardData;
5 property var cardData;
6 property var artShapeBorderSource: undefined;
6 property var artShapeBorderSource: undefined;
7 property real fontScale: 1.0;
7 property real fontScale: 1.0;
8− property var scopeStyle: null;
8+ property var scopeStyle: null;
9− property int headerAlignment: Text.AlignLeft;
9+ property int headerAlignment: Text.AlignLeft;
10 property int fixedHeaderHeight: -1;
10 property int fixedHeaderHeight: -1;
11 property size fixedArtShapeSize: Qt.size(-1, -1);
11 property size fixedArtShapeSize: Qt.size(-1, -1);
12 readonly property string title: cardData && cardData["title"] || "";
12 readonly property string title: cardData && cardData["title"] || "";
@@ -16,89 +16,92 @@ AbstractButton {
16onArtShapeBorderSourceChanged: { if (artShapeBorderSource !== undefined && artShapeLoader.item) artShapeLoader.item.borderSource = artShapeBorderSource; }
16onArtShapeBorderSourceChanged: { if (artShapeBorderSource !== undefined && artShapeLoader.item) artShapeLoader.item.borderSource = artShapeBorderSource; }
17readonly property size artShapeSize: artShapeLoader.item ? Qt.size(artShapeLoader.item.width, artShapeLoader.item.height) : Qt.size(-1, -1);
17readonly property size artShapeSize: artShapeLoader.item ? Qt.size(artShapeLoader.item.width, artShapeLoader.item.height) : Qt.size(-1, -1);
18Item {
18Item {
19− id: artShapeHolder;
19+ id: artShapeHolder;
20− height: root.fixedArtShapeSize.height > 0 ? root.fixedArtShapeSize.height : artShapeLoader.height;
20+ height: root.fixedArtShapeSize.height > 0 ? root.fixedArtShapeSize.height : artShapeLoader.height;
21− width: root.fixedArtShapeSize.width > 0 ? root.fixedArtShapeSize.width : artShapeLoader.width;
21+ width: root.fixedArtShapeSize.width > 0 ? root.fixedArtShapeSize.width : artShapeLoader.width;
22− anchors { horizontalCenter: parent.horizontalCenter; }
22+ anchors { horizontalCenter: parent.horizontalCenter; }
23− Loader {
23+ Loader {
24− id: artShapeLoader;
24+ id: artShapeLoader;
25− objectName: "artShapeLoader";
25+ objectName: "artShapeLoader";
26− active: cardData && cardData["art"] || false;
26+ active: cardData && cardData["art"] || false;
27− asynchronous: root.asynchronous;
28− visible: status == Loader.Ready;
29− sourceComponent: UbuntuShape {
30− id: artShape;
31− objectName: "artShape";
32− radius: "medium";
33− visible: image.status == Image.Ready;
34− readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1;
35− readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1;
36− readonly property bool aspectSmallerThanImageAspect: aspect < image.aspect;
37− Component.onCompleted: { updateWidthHeightBindings(); if (artShapeBorderSource !== undefined) borderSource = artShapeBorderSource; }
38− onAspectSmallerThanImageAspectChanged: updateWidthHeightBindings();
39− Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); }
40− function updateWidthHeightBindings() {
41− if (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) {
42− width = root.fixedArtShapeSize.width;
43− height = root.fixedArtShapeSize.height;
44− } else if (aspectSmallerThanImageAspect) {
45− width = Qt.binding(function() { return !visible ? 0 : image.width });
46− height = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.height : width / image.aspect });
47− } else {
48− width = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.width : height * image.aspect });
49− height = Qt.binding(function() { return !visible ? 0 : image.height });
50− }
51− }
52− image: Image {
53− objectName: "artImage";
54− source: cardData && cardData["art"] || "";
55− cache: true;
56 asynchronous: root.asynchronous;
27 asynchronous: root.asynchronous;
28+ visible: status == Loader.Ready;
29+ sourceComponent: UbuntuShape {
30+ id: artShape;
31+ objectName: "artShape";
32+ radius: "medium";
33+ visible: image.status == Image.Ready;
34+ readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1;
35+ readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1;
36+ readonly property bool aspectSmallerThanImageAspect: aspect < image.aspect;
37+ Component.onCompleted: { updateWidthHeightBindings(); if (artShapeBorderSource !== undefined) borderSource = artShapeBorderSource; }
38+ onAspectSmallerThanImageAspectChanged: updateWidthHeightBindings();
39+ Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); }
40+ function updateWidthHeightBindings() {
41+ if (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) {
42+ width = root.fixedArtShapeSize.width;
43+ height = root.fixedArtShapeSize.height;
44+ } else if (aspectSmallerThanImageAspect) {
45+ width = Qt.binding(function() { return !visible ? 0 : image.width });
46+ height = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.height : width / image.aspect });
47+ } else {
48+ width = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.width : height * image.aspect });
49+ height = Qt.binding(function() { return !visible ? 0 : image.height });
50+ }
51+ }
52+ image: Image {
53+ objectName: "artImage";
54+ source: cardData && cardData["art"] || "";
55+ cache: true;
56+ asynchronous: root.asynchronous;
57− fillMode: components && components["art"]["fill-mode"] === "fit" ? Image.PreserveAspectFit: Image.PreserveAspectCrop;
57+ fillMode: components && components["art"]["fill-mode"] === "fit" ? Image.PreserveAspectFit: Image.PreserveAspectCrop;
58− readonly property real aspect: implicitWidth / implicitHeight;
58+ readonly property real aspect: implicitWidth / implicitHeight;
59− width: root.width;
59+ width: root.width;
60− height: width / artShape.aspect;
60+ height: width / artShape.aspect;
61+ }
62+ }
61 }
63 }
62− }
64+ }
63− }
64− }
65readonly property int headerHeight: titleLabel.height + subtitleLabel.height + subtitleLabel.anchors.topMargin;
65readonly property int headerHeight: titleLabel.height + subtitleLabel.height + subtitleLabel.anchors.topMargin;
66Label {
66Label {
67− id: titleLabel;
67+ id: titleLabel;
68− objectName: "titleLabel";
68+ objectName: "titleLabel";
69− anchors { right: parent.right;left: parent.left;
69+ anchors { right: parent.right;
70+rightMargin: units.gu(1);
71+left: parent.left;
70top: artShapeHolder.bottom;
72top: artShapeHolder.bottom;
71 topMargin: units.gu(1);
73 topMargin: units.gu(1);
72leftMargin: units.gu(1);
74leftMargin: units.gu(1);
73−}
74− elide: Text.ElideRight;
75− fontSize: "small";
76− wrapMode: Text.Wrap;
77− maximumLineCount: 2;
78− font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
79− color: root.scopeStyle ? root.scopeStyle.foreground : "grey";
80− visible: showHeader ;
81− text: root.title;
82− font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal;
83− horizontalAlignment: root.headerAlignment;
84− }
75+ }
85−Label {
86− id: subtitleLabel;
87− objectName: "subtitleLabel";
88− anchors { left: titleLabel.left;
89− leftMargin: titleLabel.leftMargin;
90− right: titleLabel.right;
91− top: titleLabel.bottom;
92− topMargin: units.dp(2);
93− }
94 elide: Text.ElideRight;
76 elide: Text.ElideRight;
95 fontSize: "small";
77 fontSize: "small";
78+ wrapMode: Text.Wrap;
79+ maximumLineCount: 2;
96 font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
80 font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
97− color: root.scopeStyle ? root.scopeStyle.foreground : "grey";
81+ color: root.scopeStyle ? root.scopeStyle.foreground : "grey";
98− visible: titleLabel.visible && titleLabel.text;
82+ visible: showHeader ;
99− text: cardData && cardData["subtitle"] || "";
83+ text: root.title;
100− font.weight: Font.Light;
84+ font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal;
101 horizontalAlignment: root.headerAlignment;
85 horizontalAlignment: root.headerAlignment;
102 }
86 }
87+Label {
88+ id: subtitleLabel;
89+ objectName: "subtitleLabel";
90+ anchors { left: titleLabel.left;
91+ leftMargin: titleLabel.leftMargin;
92+ right: titleLabel.right;
93+ rightMargin: titleLabel.rightMargin;
94+ top: titleLabel.bottom;
95+ topMargin: units.dp(2);
96+ }
97+ elide: Text.ElideRight;
98+ fontSize: "small";
99+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
100+ color: root.scopeStyle ? root.scopeStyle.foreground : "grey";
101+ visible: titleLabel.visible && titleLabel.text;
102+ text: cardData && cardData["subtitle"] || "";
103+ font.weight: Font.Light;
104+ horizontalAlignment: root.headerAlignment;
105+ }
103implicitHeight: subtitleLabel.y + subtitleLabel.height + units.gu(1);
106implicitHeight: subtitleLabel.y + subtitleLabel.height + units.gu(1);
104}
107}
tests/plugins/Dash/cardcreator/5.res+119−117
@@ -4,9 +4,9 @@ AbstractButton {
4 property var components;
4 property var components;
5 property var cardData;
5 property var cardData;
6 property var artShapeBorderSource: undefined;
6 property var artShapeBorderSource: undefined;
7− property real fontScale: 1.0;
7+ property real fontScale: 1.0;
8− property var scopeStyle: null;
8+ property var scopeStyle: null;
9− property int headerAlignment: Text.AlignLeft;
9+ property int headerAlignment: Text.AlignLeft;
10 property int fixedHeaderHeight: -1;
10 property int fixedHeaderHeight: -1;
11 property size fixedArtShapeSize: Qt.size(-1, -1);
11 property size fixedArtShapeSize: Qt.size(-1, -1);
12 readonly property string title: cardData && cardData["title"] || "";
12 readonly property string title: cardData && cardData["title"] || "";
@@ -16,130 +16,132 @@ AbstractButton {
16onArtShapeBorderSourceChanged: { if (artShapeBorderSource !== undefined && artShapeLoader.item) artShapeLoader.item.borderSource = artShapeBorderSource; }
16onArtShapeBorderSourceChanged: { if (artShapeBorderSource !== undefined && artShapeLoader.item) artShapeLoader.item.borderSource = artShapeBorderSource; }
17readonly property size artShapeSize: artShapeLoader.item ? Qt.size(artShapeLoader.item.width, artShapeLoader.item.height) : Qt.size(-1, -1);
17readonly property size artShapeSize: artShapeLoader.item ? Qt.size(artShapeLoader.item.width, artShapeLoader.item.height) : Qt.size(-1, -1);
18Item {
18Item {
19− id: artShapeHolder;
19+ id: artShapeHolder;
20− height: root.fixedArtShapeSize.height > 0 ? root.fixedArtShapeSize.height : artShapeLoader.height;
20+ height: root.fixedArtShapeSize.height > 0 ? root.fixedArtShapeSize.height : artShapeLoader.height;
21− width: root.fixedArtShapeSize.width > 0 ? root.fixedArtShapeSize.width : artShapeLoader.width;
21+ width: root.fixedArtShapeSize.width > 0 ? root.fixedArtShapeSize.width : artShapeLoader.width;
22− anchors { horizontalCenter: parent.horizontalCenter; }
22+ anchors { horizontalCenter: parent.horizontalCenter; }
23− Loader {
23+ Loader {
24− id: artShapeLoader;
24+ id: artShapeLoader;
25− objectName: "artShapeLoader";
25+ objectName: "artShapeLoader";
26− active: cardData && cardData["art"] || false;
26+ active: cardData && cardData["art"] || false;
27− asynchronous: root.asynchronous;
28− visible: status == Loader.Ready;
29− sourceComponent: UbuntuShape {
30− id: artShape;
31− objectName: "artShape";
32− radius: "medium";
33− visible: image.status == Image.Ready;
34− readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1;
35− readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1;
36− readonly property bool aspectSmallerThanImageAspect: aspect < image.aspect;
37− Component.onCompleted: { updateWidthHeightBindings(); if (artShapeBorderSource !== undefined) borderSource = artShapeBorderSource; }
38− onAspectSmallerThanImageAspectChanged: updateWidthHeightBindings();
39− Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); }
40− function updateWidthHeightBindings() {
41− if (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) {
42− width = root.fixedArtShapeSize.width;
43− height = root.fixedArtShapeSize.height;
44− } else if (aspectSmallerThanImageAspect) {
45− width = Qt.binding(function() { return !visible ? 0 : image.width });
46− height = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.height : width / image.aspect });
47− } else {
48− width = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.width : height * image.aspect });
49− height = Qt.binding(function() { return !visible ? 0 : image.height });
50− }
51− }
52− image: Image {
53− objectName: "artImage";
54− source: cardData && cardData["art"] || "";
55− cache: true;
56 asynchronous: root.asynchronous;
27 asynchronous: root.asynchronous;
28+ visible: status == Loader.Ready;
29+ sourceComponent: UbuntuShape {
30+ id: artShape;
31+ objectName: "artShape";
32+ radius: "medium";
33+ visible: image.status == Image.Ready;
34+ readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1;
35+ readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1;
36+ readonly property bool aspectSmallerThanImageAspect: aspect < image.aspect;
37+ Component.onCompleted: { updateWidthHeightBindings(); if (artShapeBorderSource !== undefined) borderSource = artShapeBorderSource; }
38+ onAspectSmallerThanImageAspectChanged: updateWidthHeightBindings();
39+ Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); }
40+ function updateWidthHeightBindings() {
41+ if (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) {
42+ width = root.fixedArtShapeSize.width;
43+ height = root.fixedArtShapeSize.height;
44+ } else if (aspectSmallerThanImageAspect) {
45+ width = Qt.binding(function() { return !visible ? 0 : image.width });
46+ height = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.height : width / image.aspect });
47+ } else {
48+ width = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.width : height * image.aspect });
49+ height = Qt.binding(function() { return !visible ? 0 : image.height });
50+ }
51+ }
52+ image: Image {
53+ objectName: "artImage";
54+ source: cardData && cardData["art"] || "";
55+ cache: true;
56+ asynchronous: root.asynchronous;
57− fillMode: components && components["art"]["fill-mode"] === "fit" ? Image.PreserveAspectFit: Image.PreserveAspectCrop;
57+ fillMode: components && components["art"]["fill-mode"] === "fit" ? Image.PreserveAspectFit: Image.PreserveAspectCrop;
58− readonly property real aspect: implicitWidth / implicitHeight;
58+ readonly property real aspect: implicitWidth / implicitHeight;
59− width: root.width;
59+ width: root.width;
60− height: width / artShape.aspect;
60+ height: width / artShape.aspect;
61+ }
62+ }
61 }
63 }
62− }
64+ }
63− }
64− }
65Loader {
65Loader {
66− id: overlayLoader;
66+ id: overlayLoader;
67− anchors {
67+ anchors {
68− left: artShapeHolder.left;
68+ left: artShapeHolder.left;
69− right: artShapeHolder.right;
69+ right: artShapeHolder.right;
70− bottom: artShapeHolder.bottom;
70+ bottom: artShapeHolder.bottom;
71− }
71+ }
72− active: artShapeLoader.active && artShapeLoader.item && artShapeLoader.item.image.status === Image.Ready || false;
72+ active: artShapeLoader.active && artShapeLoader.item && artShapeLoader.item.image.status === Image.Ready || false;
73− asynchronous: root.asynchronous;
73+ asynchronous: root.asynchronous;
74− visible: showHeader && status == Loader.Ready;
74+ visible: showHeader && status == Loader.Ready;
75− sourceComponent: ShaderEffect {
75+ sourceComponent: ShaderEffect {
76− id: overlay;
76+ id: overlay;
77− height: (fixedHeaderHeight > 0 ? fixedHeaderHeight : headerHeight) + units.gu(2);
77+ height: (fixedHeaderHeight > 0 ? fixedHeaderHeight : headerHeight) + units.gu(2);
78− opacity: 0.6;
78+ opacity: 0.6;
79− property var source: ShaderEffectSource {
79+ property var source: ShaderEffectSource {
80− id: shaderSource;
80+ id: shaderSource;
81− sourceItem: artShapeLoader.item;
81+ sourceItem: artShapeLoader.item;
82− onVisibleChanged: if (visible) scheduleUpdate();
82+ onVisibleChanged: if (visible) scheduleUpdate();
83− live: false;
83+ live: false;
84− sourceRect: Qt.rect(0, artShapeLoader.height - overlay.height, artShapeLoader.width, overlay.height);
84+ sourceRect: Qt.rect(0, artShapeLoader.height - overlay.height, artShapeLoader.width, overlay.height);
85− }
85+ }
86− vertexShader: "
86+ vertexShader: "
87− uniform highp mat4 qt_Matrix;
87+ uniform highp mat4 qt_Matrix;
88− attribute highp vec4 qt_Vertex;
88+ attribute highp vec4 qt_Vertex;
89− attribute highp vec2 qt_MultiTexCoord0;
89+ attribute highp vec2 qt_MultiTexCoord0;
90− varying highp vec2 coord;
90+ varying highp vec2 coord;
91− void main() {
91+ void main() {
92− coord = qt_MultiTexCoord0;
92+ coord = qt_MultiTexCoord0;
93− gl_Position = qt_Matrix * qt_Vertex;
93+ gl_Position = qt_Matrix * qt_Vertex;
94− }";
94+ }";
95− fragmentShader: "
95+ fragmentShader: "
96− varying highp vec2 coord;
96+ varying highp vec2 coord;
97− uniform sampler2D source;
97+ uniform sampler2D source;
98− uniform lowp float qt_Opacity;
98+ uniform lowp float qt_Opacity;
99− void main() {
99+ void main() {
100− lowp vec4 tex = texture2D(source, coord);
100+ lowp vec4 tex = texture2D(source, coord);
101− gl_FragColor = vec4(0, 0, 0, tex.a) * qt_Opacity;
101+ gl_FragColor = vec4(0, 0, 0, tex.a) * qt_Opacity;
102− }";
102+ }";
103− }
103+ }
104− }
104+ }
105readonly property int headerHeight: titleLabel.height + subtitleLabel.height + subtitleLabel.anchors.topMargin;
105readonly property int headerHeight: titleLabel.height + subtitleLabel.height + subtitleLabel.anchors.topMargin;
106Label {
106Label {
107− id: titleLabel;
107+ id: titleLabel;
108− objectName: "titleLabel";
108+ objectName: "titleLabel";
109− anchors { left: parent.left;
109+ anchors { left: parent.left;
110− leftMargin: units.gu(1);
110+ leftMargin: units.gu(1);
111− right: parent.right;
111+ right: parent.right;
112− top: overlayLoader.top;
113− topMargin: units.gu(1);
112+ rightMargin: units.gu(1);
114−}
115− elide: Text.ElideRight;
116− fontSize: "small";
117− wrapMode: Text.Wrap;
118− maximumLineCount: 2;
119− font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
120− color: "white";
121− visible: showHeader && overlayLoader.active;
113+ top: overlayLoader.top;
122− text: root.title;
123− font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal;
124− horizontalAlignment: root.headerAlignment;
125− }
126−Label {
127− id: subtitleLabel;
128− objectName: "subtitleLabel";
129− anchors { left: titleLabel.left;
130− leftMargin: titleLabel.leftMargin;
131− right: titleLabel.right;
132− top: titleLabel.bottom;
133− topMargin: units.dp(2);
114+ topMargin: units.gu(1);
134− }
115+ }
135 elide: Text.ElideRight;
116 elide: Text.ElideRight;
136 fontSize: "small";
117 fontSize: "small";
118+ wrapMode: Text.Wrap;
119+ maximumLineCount: 2;
137 font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
120 font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
138 color: "white";
121 color: "white";
139− visible: titleLabel.visible && titleLabel.text;
122+ visible: showHeader && overlayLoader.active;
140− text: cardData && cardData["subtitle"] || "";
123+ text: root.title;
141− font.weight: Font.Light;
124+ font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal;
142 horizontalAlignment: root.headerAlignment;
125 horizontalAlignment: root.headerAlignment;
143 }
126 }
127+Label {
128+ id: subtitleLabel;
129+ objectName: "subtitleLabel";
130+ anchors { left: titleLabel.left;
131+ leftMargin: titleLabel.leftMargin;
132+ right: titleLabel.right;
133+ rightMargin: titleLabel.rightMargin;
134+ top: titleLabel.bottom;
135+ topMargin: units.dp(2);
136+ }
137+ elide: Text.ElideRight;
138+ fontSize: "small";
139+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
140+ color: "white";
141+ visible: titleLabel.visible && titleLabel.text;
142+ text: cardData && cardData["subtitle"] || "";
143+ font.weight: Font.Light;
144+ horizontalAlignment: root.headerAlignment;
145+ }
144implicitHeight: subtitleLabel.y + subtitleLabel.height + units.gu(1);
146implicitHeight: subtitleLabel.y + subtitleLabel.height + units.gu(1);
145}
147}
tests/plugins/Dash/cardcreator/7.resnew file+128
@@ -0,0 +1,128 @@
1+AbstractButton {
2+ id: root;
3+ property var template;
4+ property var components;
5+ property var cardData;
6+ property var artShapeBorderSource: undefined;
7+ property real fontScale: 1.0;
8+ property var scopeStyle: null;
9+ property int headerAlignment: Text.AlignLeft;
10+ property int fixedHeaderHeight: -1;
11+ property size fixedArtShapeSize: Qt.size(-1, -1);
12+ readonly property string title: cardData && cardData["title"] || "";
13+ property bool asynchronous: true;
14+ property bool showHeader: true;
15+ implicitWidth: childrenRect.width;
16+Loader {
17+ id: backgroundLoader;
18+ objectName: "backgroundLoader";
19+ anchors.fill: parent;
20+ asynchronous: root.asynchronous;
21+ visible: status == Loader.Ready;
22+ sourceComponent: UbuntuShape {
23+ objectName: "background";
24+ radius: "medium";
25+ color: getColor(0) || "white";
26+ gradientColor: getColor(1) || color;
27+ anchors.fill: parent;
28+ image: backgroundImage.source ? backgroundImage : null;
29+ property real luminance: 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b;
30+ property Image backgroundImage: Image {
31+ objectName: "backgroundImage";
32+ source: {
33+ if (cardData && typeof cardData["background"] === "string") return cardData["background"];
34+ else if (template && typeof template["card-background"] === "string") return template["card-background"];
35+ else return "";
36+ }
37+ }
38+ function getColor(index) {
39+ if (cardData && typeof cardData["background"] === "object"
40+ && (cardData["background"]["type"] === "color" || cardData["background"]["type"] === "gradient")) {
41+ return cardData["background"]["elements"][index];
42+ } else if (template && typeof template["card-background"] === "object"
43+ && (template["card-background"]["type"] === "color" || template["card-background"]["type"] === "gradient")) {
44+ return template["card-background"]["elements"][index];
45+ } else return undefined;
46+ }
47+ }
48+ }
49+readonly property size artShapeSize: Qt.size(-1, -1);
50+readonly property int headerHeight: row.height;
51+Row {
52+ id: row;
53+ objectName: "outerRow";
54+ property real margins: units.gu(1);
55+ spacing: margins;
56+ height: root.fixedHeaderHeight != -1 ? root.fixedHeaderHeight : implicitHeight;
57+ anchors { top: parent.top;
58+ topMargin: units.gu(1);
59+left: parent.left;
60+ }
61+ anchors.right: parent.right;
62+ anchors.margins: margins;
63+ data: [ Image {
64+ id: mascotImage;
65+ objectName: "mascotImage";
66+ anchors { verticalCenter: parent.verticalCenter; }
67+ readonly property int maxSize: Math.max(width, height) * 4;
68+ source: cardData && cardData["mascot"];
69+ width: units.gu(6);
70+ height: units.gu(5.625);
71+ sourceSize { width: maxSize; height: maxSize }
72+ fillMode: Image.PreserveAspectCrop;
73+ horizontalAlignment: Image.AlignHCenter;
74+ verticalAlignment: Image.AlignVCenter;
75+ visible: showHeader;
76+ }
77+
78+ ,
79+ Column {
80+ anchors.verticalCenter: parent.verticalCenter;
81+ spacing: units.dp(2);
82+ width: parent.width - x;
83+ data: [
84+ Label {
85+ id: titleLabel;
86+ objectName: "titleLabel";
87+ anchors { left: parent.left; right: parent.right }
88+ elide: Text.ElideRight;
89+ fontSize: "small";
90+ wrapMode: Text.Wrap;
91+ maximumLineCount: 2;
92+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
93+ color: backgroundLoader.active && backgroundLoader.item && backgroundLoader.item.luminance < 0.7 ? "white" : (root.scopeStyle ? root.scopeStyle.foreground : "grey");
94+ visible: showHeader ;
95+ text: root.title;
96+ font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal;
97+ horizontalAlignment: root.headerAlignment;
98+ }
99+,
100+Label {
101+ id: subtitleLabel;
102+ objectName: "subtitleLabel";
103+ anchors { left: parent.left; right: parent.right }
104+ elide: Text.ElideRight;
105+ fontSize: "small";
106+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
107+ color: backgroundLoader.active && backgroundLoader.item && backgroundLoader.item.luminance < 0.7 ? "white" : (root.scopeStyle ? root.scopeStyle.foreground : "grey");
108+ visible: titleLabel.visible && titleLabel.text;
109+ text: cardData && cardData["subtitle"] || "";
110+ font.weight: Font.Light;
111+ horizontalAlignment: root.headerAlignment;
112+ }
113+,
114+CardAttributes {
115+ id: attributesRow;
116+ objectName: "attributesRow";
117+ anchors { left: parent.left; right: parent.right }
118+ color: backgroundLoader.active && backgroundLoader.item && backgroundLoader.item.luminance < 0.7 ? "white" : (root.scopeStyle ? root.scopeStyle.foreground : "grey");
119+ model: cardData["attributes"]
120+ }
121+
122+ ]
123+ }
124+
125+ ]
126+ }
127+implicitHeight: row.y + row.height + units.gu(1);
128+}
tests/plugins/Dash/cardcreator/7.tstnew file+3
@@ -0,0 +1,3 @@
1+template: {"card-background":{"elements":["#E9E9E9"],"type":"color"},"card-layout":"vertical","card-size":"medium","category-layout":"grid","collapsed-rows":2}
2+components: {"art":{"aspect-ratio":1,"fill-mode":"crop"},"background":{"field":"background"},"mascot":{"field":"icon"},"subtitle":{"field":"author"},"title":{"field":"title"},"attributes":{"field":"attributes","max-count":2}}
3+result: 7.res
tests/plugins/Dash/cardcreatortest.cpp+9−1
@@ -19,6 +19,7 @@
19#include <QQuickItem>
19#include <QQuickItem>
20#include <QQuickView>
20#include <QQuickView>
21#include <QtTestGui>
21#include <QtTestGui>
22+#include <QTemporaryFile>
22
23
23class CardCreatorTest : public QObject
24class CardCreatorTest : public QObject
24{
25{
@@ -74,7 +75,14 @@ private Q_SLOTS:
74 QVERIFY(testResultFile.open(QIODevice::ReadOnly));
75 QVERIFY(testResultFile.open(QIODevice::ReadOnly));
75 QTextStream ts2(&testResultFile);
76 QTextStream ts2(&testResultFile);
76 const QString expectedResult = ts2.readAll();
77 const QString expectedResult = ts2.readAll();
78+ const QString executedResult = cardStringResult.toString();
79+ // Record failed results to /tmp
80+ QTemporaryFile tmpFile(QDir::tempPath() + QDir::separator() + "testCardCreatorFailedResultXXXXXX");
81+ tmpFile.open();
82+ tmpFile.setAutoRemove(false);
83+ tmpFile.write(executedResult.toUtf8().constData());
77− QCOMPARE(cardStringResult.toString().simplified(), expectedResult.simplified());
84+ QCOMPARE(executedResult.simplified(), expectedResult.simplified());
85+ tmpFile.setAutoRemove(true); // Remove the result if it passed
78
86
79 QVariant createCardComponentResult;
87 QVariant createCardComponentResult;
80 QMetaObject::invokeMethod(view->rootObject(), "createCardComponent", Q_RETURN_ARG(QVariant, createCardComponentResult), Q_ARG(QVariant, templateJSON), Q_ARG(QVariant, componentsJSON));
88 QMetaObject::invokeMethod(view->rootObject(), "createCardComponent", Q_RETURN_ARG(QVariant, createCardComponentResult), Q_ARG(QVariant, templateJSON), Q_ARG(QVariant, componentsJSON));
tests/plugins/Dash/listviewwithpageheadersectiontest.cpp−1
@@ -40,7 +40,6 @@ private:
40 QTRY_COMPARE(lvwph->m_visibleItems[visibleIndex]->height(), height);
40 QTRY_COMPARE(lvwph->m_visibleItems[visibleIndex]->height(), height);
41 QCOMPARE(QQuickItemPrivate::get(lvwph->m_visibleItems[visibleIndex]->m_item)->culled, culled);
41 QCOMPARE(QQuickItemPrivate::get(lvwph->m_visibleItems[visibleIndex]->m_item)->culled, culled);
42 QCOMPARE(section(lvwph->m_visibleItems[visibleIndex]->sectionItem()), sectionHeader);
42 QCOMPARE(section(lvwph->m_visibleItems[visibleIndex]->sectionItem()), sectionHeader);
43− QTRY_COMPARE(hasSectionHeaderProperty(lvwph->m_visibleItems[visibleIndex]->m_item), !sectionHeader.isNull());
44 if (!sectionHeader.isNull()) {
43 if (!sectionHeader.isNull()) {
45 QCOMPARE(QQuickItemPrivate::get(lvwph->m_visibleItems[visibleIndex]->sectionItem())->culled, sectionHeaderCulled);
44 QCOMPARE(QQuickItemPrivate::get(lvwph->m_visibleItems[visibleIndex]->sectionItem())->culled, sectionHeaderCulled);
46 QCOMPARE(sectionDelegateIndex(lvwph->m_visibleItems[visibleIndex]->sectionItem()), lvwph->m_firstVisibleIndex + visibleIndex);
45 QCOMPARE(sectionDelegateIndex(lvwph->m_visibleItems[visibleIndex]->sectionItem()), lvwph->m_firstVisibleIndex + visibleIndex);
tests/plugins/Dash/tst_CardAttributes.qmlnew file+54
@@ -0,0 +1,54 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import QtTest 1.0
19+import Dash 0.1
20+
21+Item {
22+ width: units.gu(40)
23+ height: units.gu(4.5)
24+
25+ property var testData: [
26+ [{"value":"text1","icon":"image://theme/ok"},{"value":"text2","icon":"image://theme/cancel"}],
27+ [{"value":"text1","icon":"image://theme/ok"},{"value":"text2","icon":"image://theme/cancel"},{"value":"text3"}],
28+ [{"value":"text1","icon":"image://theme/ok"},{"value":"text2","icon":"image://theme/cancel"},{"value":"text3"},{"value":"text4"}],
29+ [{"value":"text1","icon":"image://theme/ok"},{"value":"text2","icon":"image://theme/cancel"},{"value":"text3","style":"highlighted"},{"value":"text4","icon":"image://theme/close","style":"highlighted"},{"value":"text5"}]
30+ ]
31+
32+ CardAttributes {
33+ id: cardAttributes
34+ model: testData[3]
35+ clip: true
36+ }
37+
38+ TestCase {
39+ name: "CardAttributesTest"
40+ when: windowShown
41+
42+ function init() {
43+ }
44+
45+ function test_columns_data() {
46+ return testData;
47+ }
48+
49+ function test_columns(data) {
50+ cardAttributes.model = data;
51+ compare(cardAttributes.columns, 2 + data.length % 2);
52+ }
53+ }
54+}
tests/qmltests/CMakeLists.txt−1
@@ -40,7 +40,6 @@ add_qml_test(Dash Card)
40add_qml_benchmark(Dash CardBenchmark 1000)
40add_qml_benchmark(Dash CardBenchmark 1000)
41add_qml_test(Dash CardTool)
41add_qml_test(Dash CardTool)
42add_qml_test(Dash GenericScopeView)
42add_qml_test(Dash GenericScopeView)
43−add_qml_test(Dash/Apps RunningApplicationsGrid)
44add_qml_test(Dash/Previews Preview)
43add_qml_test(Dash/Previews Preview)
45add_qml_test(Dash/Previews PreviewActions)
44add_qml_test(Dash/Previews PreviewActions)
46add_qml_test(Dash/Previews PreviewAudioPlayback)
45add_qml_test(Dash/Previews PreviewAudioPlayback)
tests/qmltests/Components/tst_PageHeader.qml+36−6
@@ -36,6 +36,16 @@ Item {
36
36
37 function init() {
37 function init() {
38 searchEnabled = true;
38 searchEnabled = true;
39+
40+ // Reset to initial state
41+ pageHeader.searchQuery = "";
42+ pageHeader.closePopup();
43+ pageHeader.searchHistory.clear();
44+
45+ // Check initial state
46+ var headerContainer = findChild(pageHeader, "headerContainer");
47+ tryCompareFunction(function() { return headerContainer.popover === null; }, true);
48+ compare(pageHeader.searchHistory.count, 0);
39 }
49 }
40
50
41 function test_search_disabled() {
51 function test_search_disabled() {
@@ -80,9 +90,6 @@ Item {
80 }
90 }
81
91
82 function test_history() {
92 function test_history() {
83− pageHeader.searchHistory.clear()
84− compare(pageHeader.searchHistory.count, 0)
85−
86 pageHeader.triggerSearch()
93 pageHeader.triggerSearch()
87 typeString("humppa1")
94 typeString("humppa1")
88 pageHeader.resetSearch()
95 pageHeader.resetSearch()
@@ -166,16 +173,26 @@ Item {
166 tryCompareFunction(function() { return headerContainer.popover !== null; }, true);
173 tryCompareFunction(function() { return headerContainer.popover !== null; }, true);
167
174
168 tryCompare(headerContainer.popover, "visible", true);
175 tryCompare(headerContainer.popover, "visible", true);
176+
177+ var searchTextField = findChild(pageHeader, "searchTextField");
178+ compare(searchTextField.focus, true);
179+
180+ var recentSearches = findChild(headerContainer.popover, "recentSearches");
181+ mouseClick(recentSearches.itemAt(0), 0, 0);
182+
183+ compare(pageHeader.searchQuery, "Search2");
184+ tryCompareFunction(function() { return headerContainer.popover === null; }, true);
185+ compare(searchTextField.focus, false);
169 }
186 }
170
187
171− function test_tap_outside_closes_popup_data() {
188+ function test_popup_closing_data() {
172 return [
189 return [
173 { tag: "with search text", searchText: "foobar", hideSearch: false },
190 { tag: "with search text", searchText: "foobar", hideSearch: false },
174 { tag: "without search text", searchText: "", hideSearch: true }
191 { tag: "without search text", searchText: "", hideSearch: true }
175 ];
192 ];
176 }
193 }
177
194
178− function test_tap_outside_closes_popup(data) {
195+ function test_popup_closing(data) {
179 searchEnabled = true;
196 searchEnabled = true;
180 pageHeader.searchHistory.clear();
197 pageHeader.searchHistory.clear();
181
198
@@ -191,13 +208,26 @@ Item {
191
208
192 pageHeader.searchQuery = data.searchText;
209 pageHeader.searchQuery = data.searchText;
193
210
211+ if (data.searchText == "") {
212+ // When the text is empty the user can also close the
213+ // popup by clicking outside the header instead of by starting a search
194− mouseClick(root, root.width / 2, root.height - 1);
214+ mouseClick(root, root.width / 2, root.height - 1);
215+ }
195
216
196 tryCompare(headerContainer, "showSearch", !data.hideSearch);
217 tryCompare(headerContainer, "showSearch", !data.hideSearch);
197 tryCompareFunction(function() { return headerContainer.popover === null; }, true);
218 tryCompareFunction(function() { return headerContainer.popover === null; }, true);
198
219
199 pageHeader.resetSearch();
220 pageHeader.resetSearch();
200 }
221 }
222+
223+ function test_search_change_shows_search() {
224+ var headerContainer = findChild(pageHeader, "headerContainer");
225+ compare(headerContainer.showSearch, false);
226+ compare(searchQuery, "");
227+
228+ searchQuery = "H";
229+ compare(headerContainer.showSearch, true);
230+ }
201 }
231 }
202
232
203 Column {
233 Column {
tests/qmltests/Dash/Apps/tst_RunningApplicationsGrid.qmldeleted−217
@@ -1,217 +0,0 @@
1−/*
2− * Copyright 2013 Canonical Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−
17−import QtQuick 2.0
18−import QtTest 1.0
19−import "../../../../qml/Dash/Apps"
20−import Unity.Test 0.1 as UT
21−import Unity.Application 0.1
22−import Ubuntu.Components 1.1
23−
24−// Using Rectangle to have an opaque surface because AppManager paints app surfaces behind it.
25−Rectangle {
26− width: units.gu(70)
27− height: units.gu(40)
28−
29− function resetRunningApplications() {
30− while (ApplicationManager.count > 0) {
31− ApplicationManager.stopApplication(ApplicationManager.get(0).appId)
32− }
33−
34− ApplicationManager.startApplication("dialer-app");
35− ApplicationManager.startApplication("webbrowser-app");
36− }
37−
38− Component.onCompleted: {
39− resetRunningApplications()
40− }
41−
42− // The component under test
43− RunningApplicationsGrid {
44− id: runningApplicationsGrid
45− orientationAngle: orientationAngleSelector.selectedIndex * 90
46− anchors.left: parent.left
47− anchors.right: controlPanel.left
48− anchors.top: parent.top
49− anchors.bottom: parent.bottom
50− model: ApplicationManager
51− }
52−
53− Rectangle {
54− id: controlPanel
55− anchors.right: parent.right
56− anchors.top: parent.top
57− anchors.bottom: parent.bottom
58− width: units.gu(20)
59− color: "black"
60−
61− OptionSelector {
62− id: orientationAngleSelector
63− model: ["0","90","180","270"]
64− text: "Orientation Angle"
65− width: parent.width
66− }
67− }
68−
69− UT.UnityTestCase {
70− name: "RunningApplicationsGrid"
71− when: windowShown
72−
73− function init() {
74− runningApplicationsGrid.terminationModeEnabled = false
75− resetRunningApplications()
76− }
77−
78− property var browserTile
79− property var phoneTile
80−
81− property var isBrowserLongPressed: false
82− function onBrowserLongPressed() {isBrowserLongPressed = true}
83−
84− property var isPhoneLongPressed: false
85− function onPhoneLongPressed() {isPhoneLongPressed = true}
86−
87− // Tiles should go to termination mode when any one of them is long-pressed.
88− // Long-pressing when they're in termination mode brings them back to activation mode
89− function test_enterTerminationMode() {
90− browserTile = findChild(runningApplicationsGrid, "runningAppTile Browser")
91− verify(browserTile != undefined)
92− browserTile.onPressAndHold.connect(onBrowserLongPressed)
93−
94− phoneTile = findChild(runningApplicationsGrid, "runningAppTile Dialer")
95− verify(phoneTile != undefined)
96− phoneTile.onPressAndHold.connect(onPhoneLongPressed)
97−
98− compare(browserTile.terminationModeEnabled, false)
99− compare(phoneTile.terminationModeEnabled, false)
100− compare(runningApplicationsGrid.terminationModeEnabled, false)
101−
102− isBrowserLongPressed = false
103− mousePress(browserTile, browserTile.width/2, browserTile.height/2)
104− tryCompareFunction(checkSwitchToTerminationModeAfterLongPress, true)
105−
106− mouseRelease(browserTile, browserTile.width/2, browserTile.height/2)
107−
108− compare(browserTile.terminationModeEnabled, true)
109− compare(phoneTile.terminationModeEnabled, true)
110− compare(runningApplicationsGrid.terminationModeEnabled, true)
111−
112− isPhoneLongPressed = false
113− mousePress(phoneTile, phoneTile.width/2, phoneTile.height/2)
114− tryCompareFunction(checkSwitchToActivationModeAfterLongPress, true)
115−
116− mouseRelease(phoneTile, phoneTile.width/2, phoneTile.height/2)
117−
118− compare(browserTile.terminationModeEnabled, false)
119− compare(phoneTile.terminationModeEnabled, false)
120− compare(runningApplicationsGrid.terminationModeEnabled, false)
121−
122− browserTile.onPressAndHold.disconnect(onBrowserLongPressed)
123− phoneTile.onPressAndHold.disconnect(onPhoneLongPressed)
124− }
125−
126− // Checks that components swicth to termination mode after (and only after) a long
127− // press happens on Browser tile.
128− function checkSwitchToTerminationModeAfterLongPress() {
129− compare(browserTile.terminationModeEnabled, isBrowserLongPressed)
130− compare(phoneTile.terminationModeEnabled, isBrowserLongPressed)
131− compare(runningApplicationsGrid.terminationModeEnabled, isBrowserLongPressed)
132−
133− return isBrowserLongPressed &&
134− browserTile.terminationModeEnabled &&
135− phoneTile.terminationModeEnabled &&
136− runningApplicationsGrid.terminationModeEnabled
137− }
138−
139− // Checks that components swicth to activation mode after (and only after) a long
140− // press happens on Phone tile.
141− function checkSwitchToActivationModeAfterLongPress() {
142− compare(browserTile.terminationModeEnabled, !isPhoneLongPressed)
143− compare(phoneTile.terminationModeEnabled, !isPhoneLongPressed)
144− compare(runningApplicationsGrid.terminationModeEnabled, !isPhoneLongPressed)
145−
146− return isPhoneLongPressed &&
147− !browserTile.terminationModeEnabled &&
148− !phoneTile.terminationModeEnabled &&
149− !runningApplicationsGrid.terminationModeEnabled
150− }
151−
152− // While on termination mode, clicking a running application tile, outside of
153− // the close icon should do nothing
154− function test_clickTileNotClose() {
155− runningApplicationsGrid.terminationModeEnabled = true
156−
157− var browserTile = findChild(runningApplicationsGrid, "runningAppTile Browser")
158− verify(browserTile != undefined)
159−
160− verify(ApplicationManager.findApplication("webbrowser-app") !== null)
161−
162− mouseClick(browserTile, browserTile.width/2, browserTile.height/2)
163−
164− verify(ApplicationManager.findApplication("webbrowser-app") !== null)
165−
166− // The tile for the Browser app should stay there
167− tryCompareFunction(checkBrowserTileExists, true)
168− }
169−
170− // While in termination mode, clicking on a running application tile's close icon
171− // causes the corresponding application to be terminated
172− function test_clickCloseIconToTerminateApp() {
173− runningApplicationsGrid.terminationModeEnabled = true
174−
175− var browserTile = findChild(runningApplicationsGrid, "runningAppTile Browser")
176− var browserTileCloseButton = findChild(runningApplicationsGrid, "closeIcon Browser")
177−
178− verify(browserTile != undefined)
179− verify(browserTileCloseButton != undefined)
180− verify(ApplicationManager.findApplication("webbrowser-app") !== 0)
181−
182− mouseClick(browserTileCloseButton, browserTileCloseButton.width/2, browserTileCloseButton.height/2)
183− wait(0) // spin event loop to start any pending animation
184−
185− verify(ApplicationManager.findApplication("webbrowser-app") === null)
186−
187− // The tile for the Browser app should eventually vanish since the
188− // application has been terminated.
189− tryCompareFunction(checkBrowserTileExists, false)
190− }
191−
192− function checkBrowserTileExists() {
193− return findChild(runningApplicationsGrid, "runningAppTile Browser")
194− != undefined
195− }
196−
197− // While in termination mode, if you click outside any of the tiles, the
198− // termination mode is disabled (i.e. we switch back to activation mode).
199− function test_clickOutsideTilesDisablesTerminationMode() {
200− runningApplicationsGrid.terminationModeEnabled = true
201−
202− var browserTile = findChild(runningApplicationsGrid, "runningAppTile Browser")
203− verify(browserTile != undefined)
204−
205− verify(runningApplicationsGrid.terminationModeEnabled);
206−
207− // Click on the bottom right corner of the grid, where there's no
208− // RunningApplicationTile lying around
209− mouseClick(runningApplicationsGrid,
210− runningApplicationsGrid.width - 1, runningApplicationsGrid.height - 1);
211−
212− wait(0) // spin event loop to ensure that any pending signal emission went through
213−
214− verify(!runningApplicationsGrid.terminationModeEnabled);
215− }
216− }
217−}
tests/qmltests/Dash/CardHelpers.js+5−3
@@ -16,7 +16,7 @@
16
16
17.pragma library
17.pragma library
18
18
19−var components = ["title", "art", "subtitle", "mascot", "emblem", "old-price", "price", "alt-price", "rating", "alt-rating", "summary"]
19+var components = ["title", "art", "subtitle", "mascot", "emblem", "old-price", "price", "alt-price", "rating", "alt-rating", "summary", "attributes"]
20
20
21var defaultLayout = ' \
21var defaultLayout = ' \
22{ \
22{ \
@@ -48,7 +48,8 @@ var defaultLayout = ' \
48 "empty": "image://theme/rating-star-empty" \
48 "empty": "image://theme/rating-star-empty" \
49 }, \
49 }, \
50 "alt-rating": null, \
50 "alt-rating": null, \
51− "summary": null \
51+ "summary": null, \
52+ "attributes": { "max-count": 2 } \
52 }, \
53 }, \
53 "resources": {} \
54 "resources": {} \
54}'
55}'
@@ -59,7 +60,8 @@ var fullMapping = ' \
59 "art": "art", \
60 "art": "art", \
60 "subtitle": "subtitle", \
61 "subtitle": "subtitle", \
61 "mascot": "mascot", \
62 "mascot": "mascot", \
62− "summary": "summary" \
63+ "summary": "summary", \
64+ "attributes": "attributes" \
63}'
65}'
64
66
65
67
tests/qmltests/Dash/tst_Card.qml+4−2
@@ -33,7 +33,8 @@ Rectangle {
33 "mascot": "../../../tests/qmltests/Dash/artwork/avatar.png",
33 "mascot": "../../../tests/qmltests/Dash/artwork/avatar.png",
34 "title": "foo",
34 "title": "foo",
35 "subtitle": "bar",
35 "subtitle": "bar",
36− "summary": "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
36+ "summary": "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.",
37+ "attributes": [{"value":"text1","icon":"image://theme/ok"},{"value":"text2","icon":"image://theme/cancel"}]
37 }'
38 }'
38
39
39 property var cardsModel: [
40 property var cardsModel: [
@@ -110,6 +111,7 @@ Rectangle {
110 anchors { top: parent.top; left: parent.left; margins: units.gu(1) }
111 anchors { top: parent.top; left: parent.left; margins: units.gu(1) }
111
112
112 sourceComponent: cardTool.cardComponent
113 sourceComponent: cardTool.cardComponent
114+ clip: true
113 onLoaded: {
115 onLoaded: {
114 item.template = Qt.binding(function() { return cardTool.template; });
116 item.template = Qt.binding(function() { return cardTool.template; });
115 item.components = Qt.binding(function() { return cardTool.components; });
117 item.components = Qt.binding(function() { return cardTool.components; });
@@ -359,7 +361,7 @@ Rectangle {
359
361
360 waitForRendering(card);
362 waitForRendering(card);
361
363
362− tryCompareFunction(function() { return testCase.summary.y === data.top() }, true);
364+ tryCompareFunction(function() { return art.height > 0 && testCase.summary.y === data.top() }, true);
363 }
365 }
364
366
365 function test_art_visibility() {
367 function test_art_visibility() {
tests/qmltests/tst_Shell.qml+2−6
@@ -313,9 +313,9 @@ Item {
313 - perform long left edge swipe to go minimize the app and go back to the dash.
313 - perform long left edge swipe to go minimize the app and go back to the dash.
314
314
315 Expected Results
315 Expected Results
316− - apps lens shown and Running Apps visible on screen
316+ - apps lens shown
317 */
317 */
318− function test_minimizingAppTakesToRunningApps() {
318+ function test_minimizingAppTakesToDashApps() {
319 var dashApps = findChild(shell, "clickscope");
319 var dashApps = findChild(shell, "clickscope");
320 swipeUntilScopeViewIsReached(dashApps);
320 swipeUntilScopeViewIsReached(dashApps);
321
321
@@ -353,10 +353,6 @@ Item {
353 tryCompare(appsCategoryListView, "moving", false);
353 tryCompare(appsCategoryListView, "moving", false);
354
354
355 verify(itemIsOnScreen(dashApps));
355 verify(itemIsOnScreen(dashApps));
356−
357− var runningApplicationsGrid = findChild(appsCategoryListView, "running.apps.category");
358− verify(runningApplicationsGrid);
359− verify(itemIsOnScreen(runningApplicationsGrid));
360 }
356 }
361
357
362 function test_showInputMethod() {
358 function test_showInputMethod() {