on xenial help sign in
Merge trunk.
5906727Michał Sawicz
debian/control+1
@@ -102,6 +102,7 @@ Depends: gir1.2-glib-2.0,
102 libqt5test5,
102 libqt5test5,
103 libqt5widgets5,
103 libqt5widgets5,
104 python-evdev,
104 python-evdev,
105+ python-fixtures,
105 python-gi,
106 python-gi,
106 python-mock,
107 python-mock,
107 unity8 (>= ${source:Version}),
108 unity8 (>= ${source:Version}),
debian/unity8-fake-env.install+1
@@ -1,2 +1,3 @@
1usr/lib/*/unity8/qml/mocks
1usr/lib/*/unity8/qml/mocks
2+usr/lib/*/unity8/qml/scopefakes
2usr/share/unity8/mocks
3usr/share/unity8/mocks
plugins/DashViews/CMakeLists.txt+2−1
@@ -24,9 +24,10 @@ remove_definitions(-DQT_NO_KEYWORDS)
24set(QMLPLUGIN_SRC
24set(QMLPLUGIN_SRC
25 plugin.cpp
25 plugin.cpp
26 listviewwithpageheader.cpp
26 listviewwithpageheader.cpp
27− abstractjournal.cpp
27+ abstractdashview.cpp
28 verticaljournal.cpp
28 verticaljournal.cpp
29 horizontaljournal.cpp
29 horizontaljournal.cpp
30+ organicgrid.cpp
30 )
31 )
31
32
32add_library(DashViews-qml MODULE
33add_library(DashViews-qml MODULE
plugins/DashViews/abstractjournal.cpp → plugins/DashViews/abstractdashview.cpprenamed+34−34
@@ -1,5 +1,5 @@
1/*
1/*
2− * Copyright (C) 2013 Canonical, Ltd.
2+ * Copyright (C) 2013, 2014 Canonical, Ltd.
3 *
3 *
4 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
5 * it under the terms of the GNU General Public License as published by
@@ -14,11 +14,11 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
15 */
16
16
17−#include "abstractjournal.h"
17+#include "abstractdashview.h"
18
18
19static const qreal bufferRatio = 0.5;
19static const qreal bufferRatio = 0.5;
20
20
21−AbstractJournal::AbstractJournal()
21+AbstractDashView::AbstractDashView()
22 : m_delegateModel(nullptr)
22 : m_delegateModel(nullptr)
23 , m_asyncRequestedIndex(-1)
23 , m_asyncRequestedIndex(-1)
24 , m_columnSpacing(0)
24 , m_columnSpacing(0)
@@ -35,12 +35,12 @@ AbstractJournal::AbstractJournal()
35 connect(this, SIGNAL(heightChanged()), this, SLOT(onHeightChanged()));
35 connect(this, SIGNAL(heightChanged()), this, SLOT(onHeightChanged()));
36}
36}
37
37
38−QAbstractItemModel *AbstractJournal::model() const
38+QAbstractItemModel *AbstractDashView::model() const
39{
39{
40 return m_delegateModel ? m_delegateModel->model().value<QAbstractItemModel *>() : nullptr;
40 return m_delegateModel ? m_delegateModel->model().value<QAbstractItemModel *>() : nullptr;
41}
41}
42
42
43−void AbstractJournal::setModel(QAbstractItemModel *model)
43+void AbstractDashView::setModel(QAbstractItemModel *model)
44{
44{
45 if (model != this->model()) {
45 if (model != this->model()) {
46 if (!m_delegateModel) {
46 if (!m_delegateModel) {
@@ -65,12 +65,12 @@ void AbstractJournal::setModel(QAbstractItemModel *model)
65 }
65 }
66}
66}
67
67
68−QQmlComponent *AbstractJournal::delegate() const
68+QQmlComponent *AbstractDashView::delegate() const
69{
69{
70 return m_delegateModel ? m_delegateModel->delegate() : nullptr;
70 return m_delegateModel ? m_delegateModel->delegate() : nullptr;
71}
71}
72
72
73−void AbstractJournal::setDelegate(QQmlComponent *delegate)
73+void AbstractDashView::setDelegate(QQmlComponent *delegate)
74{
74{
75 if (delegate != this->delegate()) {
75 if (delegate != this->delegate()) {
76 if (!m_delegateModel) {
76 if (!m_delegateModel) {
@@ -87,12 +87,12 @@ void AbstractJournal::setDelegate(QQmlComponent *delegate)
87 }
87 }
88}
88}
89
89
90−qreal AbstractJournal::columnSpacing() const
90+qreal AbstractDashView::columnSpacing() const
91{
91{
92 return m_columnSpacing;
92 return m_columnSpacing;
93}
93}
94
94
95−void AbstractJournal::setColumnSpacing(qreal columnSpacing)
95+void AbstractDashView::setColumnSpacing(qreal columnSpacing)
96{
96{
97 if (columnSpacing != m_columnSpacing) {
97 if (columnSpacing != m_columnSpacing) {
98 m_columnSpacing = columnSpacing;
98 m_columnSpacing = columnSpacing;
@@ -104,12 +104,12 @@ void AbstractJournal::setColumnSpacing(qreal columnSpacing)
104 }
104 }
105}
105}
106
106
107−qreal AbstractJournal::rowSpacing() const
107+qreal AbstractDashView::rowSpacing() const
108{
108{
109 return m_rowSpacing;
109 return m_rowSpacing;
110}
110}
111
111
112−void AbstractJournal::setRowSpacing(qreal rowSpacing)
112+void AbstractDashView::setRowSpacing(qreal rowSpacing)
113{
113{
114 if (rowSpacing != m_rowSpacing) {
114 if (rowSpacing != m_rowSpacing) {
115 m_rowSpacing = rowSpacing;
115 m_rowSpacing = rowSpacing;
@@ -121,12 +121,12 @@ void AbstractJournal::setRowSpacing(qreal rowSpacing)
121 }
121 }
122}
122}
123
123
124−qreal AbstractJournal::delegateCreationBegin() const
124+qreal AbstractDashView::delegateCreationBegin() const
125{
125{
126 return m_delegateCreationBegin;
126 return m_delegateCreationBegin;
127}
127}
128
128
129−void AbstractJournal::setDelegateCreationBegin(qreal begin)
129+void AbstractDashView::setDelegateCreationBegin(qreal begin)
130{
130{
131 m_delegateCreationBeginValid = true;
131 m_delegateCreationBeginValid = true;
132 if (m_delegateCreationBegin == begin)
132 if (m_delegateCreationBegin == begin)
@@ -138,7 +138,7 @@ void AbstractJournal::setDelegateCreationBegin(qreal begin)
138 emit delegateCreationBeginChanged();
138 emit delegateCreationBeginChanged();
139}
139}
140
140
141−void AbstractJournal::resetDelegateCreationBegin()
141+void AbstractDashView::resetDelegateCreationBegin()
142{
142{
143 m_delegateCreationBeginValid = false;
143 m_delegateCreationBeginValid = false;
144 if (m_delegateCreationBegin == 0)
144 if (m_delegateCreationBegin == 0)
@@ -150,12 +150,12 @@ void AbstractJournal::resetDelegateCreationBegin()
150 emit delegateCreationBeginChanged();
150 emit delegateCreationBeginChanged();
151}
151}
152
152
153−qreal AbstractJournal::delegateCreationEnd() const
153+qreal AbstractDashView::delegateCreationEnd() const
154{
154{
155 return m_delegateCreationEnd;
155 return m_delegateCreationEnd;
156}
156}
157
157
158−void AbstractJournal::setDelegateCreationEnd(qreal end)
158+void AbstractDashView::setDelegateCreationEnd(qreal end)
159{
159{
160 m_delegateCreationEndValid = true;
160 m_delegateCreationEndValid = true;
161 if (m_delegateCreationEnd == end)
161 if (m_delegateCreationEnd == end)
@@ -167,7 +167,7 @@ void AbstractJournal::setDelegateCreationEnd(qreal end)
167 emit delegateCreationEndChanged();
167 emit delegateCreationEndChanged();
168}
168}
169
169
170−void AbstractJournal::resetDelegateCreationEnd()
170+void AbstractDashView::resetDelegateCreationEnd()
171{
171{
172 m_delegateCreationEndValid = false;
172 m_delegateCreationEndValid = false;
173 if (m_delegateCreationEnd == 0)
173 if (m_delegateCreationEnd == 0)
@@ -179,7 +179,7 @@ void AbstractJournal::resetDelegateCreationEnd()
179 emit delegateCreationEndChanged();
179 emit delegateCreationEndChanged();
180}
180}
181
181
182−void AbstractJournal::createDelegateModel()
182+void AbstractDashView::createDelegateModel()
183{
183{
184#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
184#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
185 m_delegateModel = new QQuickVisualDataModel(qmlContext(this), this);
185 m_delegateModel = new QQuickVisualDataModel(qmlContext(this), this);
@@ -192,9 +192,9 @@ void AbstractJournal::createDelegateModel()
192 m_delegateModel->componentComplete();
192 m_delegateModel->componentComplete();
193}
193}
194
194
195−void AbstractJournal::refill()
195+void AbstractDashView::refill()
196{
196{
197− if (!isComponentComplete()) {
197+ if (!isComponentComplete() || height() < 0) {
198 return;
198 return;
199 }
199 }
200
200
@@ -215,7 +215,7 @@ void AbstractJournal::refill()
215 }
215 }
216}
216}
217
217
218−bool AbstractJournal::addVisibleItems(qreal fillFromY, qreal fillToY, bool asynchronous)
218+bool AbstractDashView::addVisibleItems(qreal fillFromY, qreal fillToY, bool asynchronous)
219{
219{
220 if (!delegate())
220 if (!delegate())
221 return false;
221 return false;
@@ -247,7 +247,7 @@ bool AbstractJournal::addVisibleItems(qreal fillFromY, qreal fillToY, bool async
247 return changed;
247 return changed;
248}
248}
249
249
250−QQuickItem *AbstractJournal::createItem(int modelIndex, bool asynchronous)
250+QQuickItem *AbstractDashView::createItem(int modelIndex, bool asynchronous)
251{
251{
252 if (asynchronous && m_asyncRequestedIndex != -1)
252 if (asynchronous && m_asyncRequestedIndex != -1)
253 return nullptr;
253 return nullptr;
@@ -276,12 +276,12 @@ QQuickItem *AbstractJournal::createItem(int modelIndex, bool asynchronous)
276#endif
276#endif
277 return nullptr;
277 return nullptr;
278 } else {
278 } else {
279− positionItem(modelIndex, item);
279+ addItemToView(modelIndex, item);
280 return item;
280 return item;
281 }
281 }
282}
282}
283
283
284−void AbstractJournal::releaseItem(QQuickItem *item)
284+void AbstractDashView::releaseItem(QQuickItem *item)
285{
285{
286#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
286#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
287 QQuickVisualModel::ReleaseFlags flags = m_delegateModel->release(item);
287 QQuickVisualModel::ReleaseFlags flags = m_delegateModel->release(item);
@@ -294,20 +294,20 @@ void AbstractJournal::releaseItem(QQuickItem *item)
294 }
294 }
295}
295}
296
296
297−void AbstractJournal::setImplicitHeightDirty()
297+void AbstractDashView::setImplicitHeightDirty()
298{
298{
299 m_implicitHeightDirty = true;
299 m_implicitHeightDirty = true;
300}
300}
301
301
302#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
302#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
303−void AbstractJournal::itemCreated(int modelIndex, QQuickItem *item)
303+void AbstractDashView::itemCreated(int modelIndex, QQuickItem *item)
304{
304{
305#else
305#else
306−void AbstractJournal::itemCreated(int modelIndex, QObject *object)
306+void AbstractDashView::itemCreated(int modelIndex, QObject *object)
307{
307{
308 QQuickItem *item = qmlobject_cast<QQuickItem*>(object);
308 QQuickItem *item = qmlobject_cast<QQuickItem*>(object);
309 if (!item) {
309 if (!item) {
310− qWarning() << "AbstractJournal::itemCreated got a non item for index" << modelIndex;
310+ qWarning() << "AbstractDashView::itemCreated got a non item for index" << modelIndex;
311 return;
311 return;
312 }
312 }
313#endif
313#endif
@@ -326,9 +326,9 @@ void AbstractJournal::itemCreated(int modelIndex, QObject *object)
326}
326}
327
327
328#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
328#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
329−void AbstractJournal::onModelUpdated(const QQuickChangeSet &changeSet, bool reset)
329+void AbstractDashView::onModelUpdated(const QQuickChangeSet &changeSet, bool reset)
330#else
330#else
331−void AbstractJournal::onModelUpdated(const QQmlChangeSet &changeSet, bool reset)
331+void AbstractDashView::onModelUpdated(const QQmlChangeSet &changeSet, bool reset)
332#endif
332#endif
333{
333{
334 if (reset) {
334 if (reset) {
@@ -340,18 +340,18 @@ void AbstractJournal::onModelUpdated(const QQmlChangeSet &changeSet, bool reset)
340}
340}
341
341
342
342
343−void AbstractJournal::relayout()
343+void AbstractDashView::relayout()
344{
344{
345 m_needsRelayout = true;
345 m_needsRelayout = true;
346 polish();
346 polish();
347}
347}
348
348
349−void AbstractJournal::onHeightChanged()
349+void AbstractDashView::onHeightChanged()
350{
350{
351 polish();
351 polish();
352}
352}
353
353
354−void AbstractJournal::updatePolish()
354+void AbstractDashView::updatePolish()
355{
355{
356 if (!model())
356 if (!model())
357 return;
357 return;
@@ -375,7 +375,7 @@ void AbstractJournal::updatePolish()
375 }
375 }
376}
376}
377
377
378−void AbstractJournal::componentComplete()
378+void AbstractDashView::componentComplete()
379{
379{
380 if (m_delegateModel)
380 if (m_delegateModel)
381 m_delegateModel->componentComplete();
381 m_delegateModel->componentComplete();
plugins/DashViews/abstractjournal.h → plugins/DashViews/abstractdashview.hrenamed+7−6
@@ -1,5 +1,5 @@
1/*
1/*
2− * Copyright (C) 2013 Canonical, Ltd.
2+ * Copyright (C) 2013, 2014 Canonical, Ltd.
3 *
3 *
4 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
5 * it under the terms of the GNU General Public License as published by
@@ -14,8 +14,8 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
15 */
16
16
17−#ifndef ABSTRACTJOURNAL_H
17+#ifndef ABSTRACTDASHVIEW_H
18−#define ABSTRACTJOURNAL_H
18+#define ABSTRACTDASHVIEW_H
19
19
20#include <QQuickItem>
20#include <QQuickItem>
21
21
@@ -31,7 +31,7 @@ class QQmlComponent;
31#endif
31#endif
32#pragma GCC diagnostic pop
32#pragma GCC diagnostic pop
33
33
34−class AbstractJournal : public QQuickItem
34+class AbstractDashView : public QQuickItem
35{
35{
36 Q_OBJECT
36 Q_OBJECT
37
37
@@ -50,9 +50,10 @@ class AbstractJournal : public QQuickItem
50
50
51friend class VerticalJournalTest;
51friend class VerticalJournalTest;
52friend class HorizontalJournalTest;
52friend class HorizontalJournalTest;
53+friend class OrganicGridTest;
53
54
54public:
55public:
55− AbstractJournal();
56+ AbstractDashView();
56
57
57 QAbstractItemModel *model() const;
58 QAbstractItemModel *model() const;
58 void setModel(QAbstractItemModel *model);
59 void setModel(QAbstractItemModel *model);
@@ -110,7 +111,7 @@ private:
110
111
111 virtual void findBottomModelIndexToAdd(int *modelIndex, qreal *yPos) = 0;
112 virtual void findBottomModelIndexToAdd(int *modelIndex, qreal *yPos) = 0;
112 virtual void findTopModelIndexToAdd(int *modelIndex, qreal *yPos) = 0;
113 virtual void findTopModelIndexToAdd(int *modelIndex, qreal *yPos) = 0;
113− virtual void positionItem(int modelIndex, QQuickItem *item) = 0;
114+ virtual void addItemToView(int modelIndex, QQuickItem *item) = 0;
114 virtual bool removeNonVisibleItems(qreal bufferFromY, qreal bufferToY) = 0;
115 virtual bool removeNonVisibleItems(qreal bufferFromY, qreal bufferToY) = 0;
115 virtual void cleanupExistingItems() = 0;
116 virtual void cleanupExistingItems() = 0;
116 virtual void doRelayout() = 0;
117 virtual void doRelayout() = 0;
plugins/DashViews/horizontaljournal.cpp+4−3
@@ -118,7 +118,7 @@ bool HorizontalJournal::removeNonVisibleItems(qreal bufferFromY, qreal bufferToY
118 return changed;
118 return changed;
119}
119}
120
120
121−void HorizontalJournal::positionItem(int modelIndex, QQuickItem *item)
121+void HorizontalJournal::addItemToView(int modelIndex, QQuickItem *item)
122{
122{
123 if (item->height() != m_rowHeight) {
123 if (item->height() != m_rowHeight) {
124 qWarning() << "Item" << modelIndex << "height is not the one that the rowHeight mandates, resetting it";
124 qWarning() << "Item" << modelIndex << "height is not the one that the rowHeight mandates, resetting it";
@@ -159,7 +159,7 @@ void HorizontalJournal::positionItem(int modelIndex, QQuickItem *item)
159 m_firstVisibleIndex = modelIndex;
159 m_firstVisibleIndex = modelIndex;
160 m_visibleItems.prepend(item);
160 m_visibleItems.prepend(item);
161 } else {
161 } else {
162− qWarning() << "HorizontalJournal::positionItem - Got unexpected modelIndex"
162+ qWarning() << "HorizontalJournal::addItemToView - Got unexpected modelIndex"
163 << modelIndex << m_firstVisibleIndex << m_visibleItems.count();
163 << modelIndex << m_firstVisibleIndex << m_visibleItems.count();
164 }
164 }
165 }
165 }
@@ -173,6 +173,7 @@ void HorizontalJournal::cleanupExistingItems()
173 m_visibleItems.clear();
173 m_visibleItems.clear();
174 m_lastInRowIndexPosition.clear();
174 m_lastInRowIndexPosition.clear();
175 m_firstVisibleIndex = -1;
175 m_firstVisibleIndex = -1;
176+ setImplicitHeightDirty();
176}
177}
177
178
178void HorizontalJournal::calculateImplicitHeight()
179void HorizontalJournal::calculateImplicitHeight()
@@ -232,7 +233,7 @@ void HorizontalJournal::doRelayout()
232 m_visibleItems.clear();
233 m_visibleItems.clear();
233 m_lastInRowIndexPosition.clear();
234 m_lastInRowIndexPosition.clear();
234 Q_FOREACH(QQuickItem *item, allItems) {
235 Q_FOREACH(QQuickItem *item, allItems) {
235− positionItem(i, item);
236+ addItemToView(i, item);
236 ++i;
237 ++i;
237 }
238 }
238 } else {
239 } else {
plugins/DashViews/horizontaljournal.h+3−3
@@ -17,7 +17,7 @@
17#ifndef HORIZONTALJOURNAL_H
17#ifndef HORIZONTALJOURNAL_H
18#define HORIZONTALJOURNAL_H
18#define HORIZONTALJOURNAL_H
19
19
20−#include "abstractjournal.h"
20+#include "abstractdashview.h"
21
21
22 /** A horizontal journal is a view that creates delegates
22 /** A horizontal journal is a view that creates delegates
23 * based on a model and layouts them one after the other
23 * based on a model and layouts them one after the other
@@ -26,7 +26,7 @@
26 *
26 *
27 * All delegates are forced to rowHeight if they don't have it.
27 * All delegates are forced to rowHeight if they don't have it.
28 */
28 */
29− class HorizontalJournal : public AbstractJournal
29+ class HorizontalJournal : public AbstractDashView
30{
30{
31 Q_OBJECT
31 Q_OBJECT
32
32
@@ -47,7 +47,7 @@ private:
47 void findBottomModelIndexToAdd(int *modelIndex, qreal *yPos) override;
47 void findBottomModelIndexToAdd(int *modelIndex, qreal *yPos) override;
48 void findTopModelIndexToAdd(int *modelIndex, qreal *yPos) override;
48 void findTopModelIndexToAdd(int *modelIndex, qreal *yPos) override;
49 bool removeNonVisibleItems(qreal bufferFromY, qreal bufferToY) override;
49 bool removeNonVisibleItems(qreal bufferFromY, qreal bufferToY) override;
50− void positionItem(int modelIndex, QQuickItem *item) override;
50+ void addItemToView(int modelIndex, QQuickItem *item) override;
51 void cleanupExistingItems() override;
51 void cleanupExistingItems() override;
52 void calculateImplicitHeight() override;
52 void calculateImplicitHeight() override;
53 void doRelayout() override;
53 void doRelayout() override;
plugins/DashViews/organicgrid.cppnew file+268
@@ -0,0 +1,268 @@
1+/*
2+ * Copyright (C) 2014 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#include "organicgrid.h"
18+
19+#pragma GCC diagnostic push
20+#pragma GCC diagnostic ignored "-pedantic"
21+#include <private/qquickitem_p.h>
22+#pragma GCC diagnostic pop
23+
24+static const qreal bufferRatio = 0.5;
25+
26+OrganicGrid::OrganicGrid()
27+ : m_firstVisibleIndex(-1)
28+ , m_numberOfModulesPerRow(-1)
29+{
30+}
31+
32+QSizeF OrganicGrid::smallDelegateSize() const
33+{
34+ return m_smallDelegateSize;
35+}
36+
37+void OrganicGrid::setSmallDelegateSize(const QSizeF &size)
38+{
39+ if (m_smallDelegateSize != size) {
40+ m_smallDelegateSize = size;
41+ Q_EMIT smallDelegateSizeChanged();
42+
43+ if (isComponentComplete()) {
44+ relayout();
45+ }
46+ }
47+}
48+
49+QSizeF OrganicGrid::bigDelegateSize() const
50+{
51+ return m_bigDelegateSize;
52+}
53+
54+void OrganicGrid::setBigDelegateSize(const QSizeF &size)
55+{
56+ if (m_bigDelegateSize != size) {
57+ m_bigDelegateSize = size;
58+ Q_EMIT bigDelegateSizeChanged();
59+
60+ if (isComponentComplete()) {
61+ relayout();
62+ }
63+ }
64+}
65+
66+QPointF OrganicGrid::positionForIndex(int modelIndex) const
67+{
68+ const qreal moduleHeight = m_smallDelegateSize.height() + rowSpacing() + m_bigDelegateSize.height();
69+ const qreal moduleWidth = m_smallDelegateSize.width() * 2 + columnSpacing() * 2 + m_bigDelegateSize.width();
70+ const int itemsPerRow = m_numberOfModulesPerRow * 6;
71+ const int rowIndex = floor(modelIndex / itemsPerRow);
72+ const int columnIndex = floor((modelIndex - rowIndex * itemsPerRow) / 6);
73+
74+ qreal yPos = (moduleHeight + rowSpacing()) * rowIndex;
75+ const int moduleIndex = modelIndex % 6;
76+ if (moduleIndex == 2) {
77+ yPos += m_smallDelegateSize.height() + rowSpacing();
78+ } else if (moduleIndex == 3 || moduleIndex == 5) {
79+ yPos += m_bigDelegateSize.height() + rowSpacing();
80+ }
81+
82+ qreal xPos = (moduleWidth + columnSpacing()) * columnIndex;
83+ if (moduleIndex == 1) {
84+ xPos += m_smallDelegateSize.width() + columnSpacing();
85+ } else if (moduleIndex == 3) {
86+ xPos += m_bigDelegateSize.width() + columnSpacing();
87+ } else if (moduleIndex == 4) {
88+ xPos += (m_smallDelegateSize.width() + columnSpacing()) * 2;
89+ } else if (moduleIndex == 5) {
90+ xPos += m_bigDelegateSize.width() + m_smallDelegateSize.width() + columnSpacing() * 2;
91+ }
92+
93+ return QPointF(xPos, yPos);
94+}
95+
96+QSizeF OrganicGrid::sizeForIndex(int modelIndex) const
97+{
98+ const int moduleIndex = modelIndex % 6;
99+ if (moduleIndex == 0 || moduleIndex == 1 || moduleIndex == 3 || moduleIndex == 5) {
100+ return m_smallDelegateSize;
101+ } else {
102+ return m_bigDelegateSize;
103+ }
104+}
105+
106+void OrganicGrid::findBottomModelIndexToAdd(int *modelIndex, qreal *yPos)
107+{
108+ if (m_visibleItems.isEmpty()) {
109+ *modelIndex = 0;
110+ *yPos = 0;
111+ } else {
112+ *modelIndex = m_firstVisibleIndex + m_visibleItems.count();
113+ // We create stuff in a 6-module basis, so always return back
114+ // the y position of the first item
115+ const int firstModuleIndex = ((*modelIndex) / 6) * 6;
116+ *yPos = positionForIndex(firstModuleIndex).y();
117+ }
118+}
119+
120+void OrganicGrid::findTopModelIndexToAdd(int *modelIndex, qreal *yPos)
121+{
122+ if (m_visibleItems.isEmpty()) {
123+ *modelIndex = 0;
124+ *yPos = 0;
125+ } else {
126+ *modelIndex = m_firstVisibleIndex - 1;
127+ // We create stuff in a 6-module basis, so always return back
128+ // the y position of the last item bottom
129+ const int lastModuleIndex = ((*modelIndex) / 6) * 6 + 5;
130+ *yPos = positionForIndex(lastModuleIndex).y();
131+ *yPos += sizeForIndex(lastModuleIndex).height();
132+ }
133+}
134+
135+void OrganicGrid::addItemToView(int modelIndex, QQuickItem *item)
136+{
137+ // modelIndex has to be either m_firstVisibleIndex - 1 or m_firstVisibleIndex + m_visibleItems.count() or the first
138+ if (modelIndex == m_firstVisibleIndex + m_visibleItems.count()) {
139+ m_visibleItems << item;
140+ } else if (modelIndex == m_firstVisibleIndex - 1) {
141+ m_firstVisibleIndex = modelIndex;
142+ m_visibleItems.prepend(item);
143+ } else if (modelIndex == 0) {
144+ m_firstVisibleIndex = 0;
145+ m_visibleItems << item;
146+ } else {
147+ qWarning() << "OrganicGrid::addItemToView - Got unexpected modelIndex"
148+ << modelIndex << m_firstVisibleIndex << m_visibleItems.count();
149+ return;
150+ }
151+
152+ const QPointF pos = positionForIndex(modelIndex);
153+ item->setPosition(pos);
154+
155+ item->setSize(sizeForIndex(modelIndex));
156+}
157+
158+bool OrganicGrid::removeNonVisibleItems(qreal bufferFromY, qreal bufferToY)
159+{
160+ bool changed = false;
161+
162+ // As adding, we also remove in a 6-module basis
163+ int lastModuleIndex = (m_firstVisibleIndex / 6) * 6 + 5;
164+ bool removeIndex = positionForIndex(lastModuleIndex).y() + sizeForIndex(lastModuleIndex).height() < bufferFromY;
165+ while (removeIndex && !m_visibleItems.isEmpty()) {
166+ releaseItem(m_visibleItems.takeFirst());
167+ changed = true;
168+ m_firstVisibleIndex++;
169+
170+ lastModuleIndex = (m_firstVisibleIndex / 6) * 6 + 5;
171+ removeIndex = positionForIndex(lastModuleIndex).y() + sizeForIndex(lastModuleIndex).height() < bufferFromY;
172+ }
173+
174+ int firstModuleIndex = ((m_firstVisibleIndex + m_visibleItems.count() - 1) / 6) * 6;
175+ removeIndex = positionForIndex(firstModuleIndex).y() > bufferToY;
176+ while (removeIndex && !m_visibleItems.isEmpty()) {
177+ releaseItem(m_visibleItems.takeLast());
178+ changed = true;
179+
180+ firstModuleIndex = ((m_firstVisibleIndex + m_visibleItems.count() - 1) / 6) * 6;
181+ removeIndex = positionForIndex(firstModuleIndex).y() > bufferToY;
182+ }
183+
184+ if (m_visibleItems.isEmpty()) {
185+ m_firstVisibleIndex = -1;
186+ }
187+
188+ return changed;
189+}
190+
191+void OrganicGrid::cleanupExistingItems()
192+{
193+ Q_FOREACH(QQuickItem *item, m_visibleItems)
194+ releaseItem(item);
195+ m_visibleItems.clear();
196+ m_firstVisibleIndex = -1;
197+ setImplicitHeightDirty();
198+}
199+
200+void OrganicGrid::doRelayout()
201+{
202+ const qreal moduleWidth = m_smallDelegateSize.width() * 2 + columnSpacing() * 2 + m_bigDelegateSize.width();
203+ m_numberOfModulesPerRow = floor((width() + columnSpacing()) / (moduleWidth + columnSpacing()));
204+ m_numberOfModulesPerRow = qMax(1, m_numberOfModulesPerRow);
205+
206+ int i = m_firstVisibleIndex;
207+ const QList<QQuickItem*> allItems = m_visibleItems;
208+ m_visibleItems.clear();
209+ Q_FOREACH(QQuickItem *item, allItems) {
210+ addItemToView(i, item);
211+ ++i;
212+ }
213+}
214+
215+void OrganicGrid::updateItemCulling(qreal visibleFromY, qreal visibleToY)
216+{
217+ Q_FOREACH(QQuickItem *item, m_visibleItems) {
218+ QQuickItemPrivate::get(item)->setCulled(item->y() + item->height() <= visibleFromY || item->y() >= visibleToY);
219+ }
220+}
221+
222+void OrganicGrid::calculateImplicitHeight()
223+{
224+ const qreal moduleHeight = m_smallDelegateSize.height() + rowSpacing() + m_bigDelegateSize.height();
225+ const int itemCount = !model() ? 0 : model()->rowCount();
226+ const int itemsPerRow = m_numberOfModulesPerRow * 6;
227+ const int fullRows = floor(itemCount / itemsPerRow);
228+ const qreal fullRowsHeight = fullRows == 0 ? 0 : fullRows * moduleHeight + rowSpacing() * (fullRows - 1);
229+
230+ const int remainingItems = itemCount - fullRows * itemsPerRow;
231+ if (remainingItems == 0) {
232+ setImplicitHeight(fullRowsHeight);
233+ } else if (remainingItems <= 2) {
234+ setImplicitHeight(fullRowsHeight + m_smallDelegateSize.height() + rowSpacing());
235+ } else {
236+ setImplicitHeight(fullRowsHeight + rowSpacing() + moduleHeight);
237+ }
238+}
239+
240+#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
241+void OrganicGrid::processModelRemoves(const QVector<QQuickChangeSet::Remove> &removes)
242+#else
243+void OrganicGrid::processModelRemoves(const QVector<QQmlChangeSet::Remove> &removes)
244+#endif
245+{
246+#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
247+ Q_FOREACH(const QQuickChangeSet::Remove &remove, removes) {
248+#else
249+ Q_FOREACH(const QQmlChangeSet::Remove &remove, removes) {
250+#endif
251+ for (int i = remove.count - 1; i >= 0; --i) {
252+ const int indexToRemove = remove.index + i;
253+ // We only support removing from the end
254+ const int lastIndex = m_firstVisibleIndex + m_visibleItems.count() - 1;
255+ if (indexToRemove == lastIndex) {
256+ releaseItem(m_visibleItems.takeLast());
257+ } else {
258+ if (indexToRemove < lastIndex) {
259+ qFatal("OrganicGrid only supports removal from the end of the model");
260+ }
261+ }
262+ }
263+ }
264+ if (m_visibleItems.isEmpty()) {
265+ m_firstVisibleIndex = -1;
266+ }
267+ setImplicitHeightDirty();
268+}
plugins/DashViews/organicgrid.hnew file+95
@@ -0,0 +1,95 @@
1+/*
2+ * Copyright (C) 2014 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#ifndef ORGANICGRID_H
18+#define ORGANICGRID_H
19+
20+#include "abstractdashview.h"
21+
22+ /** An Organic Grid is is a view that creates delegates
23+ * based on a model and layouts them in groups of six items (called module).
24+ *
25+ * In each module there are 4 items that are forced to the small delegate size
26+ * and two that are forced to the big delegate size.
27+ *
28+ * Example:
29+ *
30+ * +---+ +---+ +-----+
31+ * | 1 | | 2 | | |
32+ * +---+ +---+ | 5 |
33+ * +-----+ | |
34+ * | | +-----+
35+ * | 3 | +---+ +---+
36+ * | | | 4 | | 6 |
37+ * +-----+ +---+ +---+
38+ *
39+ * Modules are positioned one after the other in a grid like fashion, i.e.
40+ *
41+ * +---+ +---+
42+ * | 1 | | 2 |
43+ * +---+ +---+
44+ * +---+ +---+
45+ * | 3 | | 4 |
46+ * +---+ +---+
47+ */
48+
49+class OrganicGrid : public AbstractDashView
50+{
51+ Q_OBJECT
52+
53+ Q_PROPERTY(QSizeF smallDelegateSize READ smallDelegateSize WRITE setSmallDelegateSize NOTIFY smallDelegateSizeChanged)
54+ Q_PROPERTY(QSizeF bigDelegateSize READ bigDelegateSize WRITE setBigDelegateSize NOTIFY bigDelegateSizeChanged)
55+
56+friend class OrganicGridTest;
57+
58+public:
59+ OrganicGrid();
60+
61+ QSizeF smallDelegateSize() const;
62+ void setSmallDelegateSize(const QSizeF &size);
63+
64+ QSizeF bigDelegateSize() const;
65+ void setBigDelegateSize(const QSizeF &size);
66+
67+Q_SIGNALS:
68+ void smallDelegateSizeChanged();
69+ void bigDelegateSizeChanged();
70+private:
71+ QPointF positionForIndex(int modelIndex) const;
72+ QSizeF sizeForIndex(int modelIndex) const;
73+
74+ void findBottomModelIndexToAdd(int *modelIndex, qreal *yPos) override;
75+ void findTopModelIndexToAdd(int *modelIndex, qreal *yPos) override;
76+ void addItemToView(int modelIndex, QQuickItem *item) override;
77+ bool removeNonVisibleItems(qreal bufferFromY, qreal bufferToY) override;
78+ void cleanupExistingItems() override;
79+ void doRelayout() override;
80+ void updateItemCulling(qreal visibleFromY, qreal visibleToY) override;
81+ void calculateImplicitHeight() override;
82+#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
83+ void processModelRemoves(const QVector<QQuickChangeSet::Remove> &removes) override;
84+#else
85+ void processModelRemoves(const QVector<QQmlChangeSet::Remove> &removes) override;
86+#endif
87+
88+ QSizeF m_smallDelegateSize;
89+ QSizeF m_bigDelegateSize;
90+ int m_firstVisibleIndex;
91+ int m_numberOfModulesPerRow;
92+ QList<QQuickItem*> m_visibleItems;
93+};
94+
95+#endif
plugins/DashViews/plugin.cpp+2
@@ -19,6 +19,7 @@
19
19
20#include "horizontaljournal.h"
20#include "horizontaljournal.h"
21#include "listviewwithpageheader.h"
21#include "listviewwithpageheader.h"
22+#include "organicgrid.h"
22#include "verticaljournal.h"
23#include "verticaljournal.h"
23
24
24#include <QAbstractItemModel>
25#include <QAbstractItemModel>
@@ -29,5 +30,6 @@ void DashViewsPlugin::registerTypes(const char *uri)
29 qmlRegisterType<QAbstractItemModel>();
30 qmlRegisterType<QAbstractItemModel>();
30 qmlRegisterType<HorizontalJournal>(uri, 0, 1, "HorizontalJournal");
31 qmlRegisterType<HorizontalJournal>(uri, 0, 1, "HorizontalJournal");
31 qmlRegisterType<ListViewWithPageHeader>(uri, 0, 1, "ListViewWithPageHeader");
32 qmlRegisterType<ListViewWithPageHeader>(uri, 0, 1, "ListViewWithPageHeader");
33+ qmlRegisterType<OrganicGrid>(uri, 0, 1, "OrganicGrid");
32 qmlRegisterType<VerticalJournal>(uri, 0, 1, "VerticalJournal");
34 qmlRegisterType<VerticalJournal>(uri, 0, 1, "VerticalJournal");
33}
35}
plugins/DashViews/verticaljournal.cpp+4−3
@@ -79,7 +79,7 @@ void VerticalJournal::findBottomModelIndexToAdd(int *modelIndex, qreal *yPos)
79
79
80void VerticalJournal::findTopModelIndexToAdd(int *modelIndex, qreal *yPos)
80void VerticalJournal::findTopModelIndexToAdd(int *modelIndex, qreal *yPos)
81{
81{
82− *modelIndex = INT_MAX;
82+ *modelIndex = 0;
83 *yPos = std::numeric_limits<qreal>::lowest();
83 *yPos = std::numeric_limits<qreal>::lowest();
84 int columnToAddTo = -1;
84 int columnToAddTo = -1;
85
85
@@ -130,7 +130,7 @@ bool VerticalJournal::removeNonVisibleItems(qreal bufferFromY, qreal bufferToY)
130 return changed;
130 return changed;
131}
131}
132
132
133−void VerticalJournal::positionItem(int modelIndex, QQuickItem *item)
133+void VerticalJournal::addItemToView(int modelIndex, QQuickItem *item)
134{
134{
135 if (item->width() != m_columnWidth) {
135 if (item->width() != m_columnWidth) {
136 qWarning() << "Item" << modelIndex << "width is not the one that the columnWidth mandates, resetting it";
136 qWarning() << "Item" << modelIndex << "width is not the one that the columnWidth mandates, resetting it";
@@ -179,6 +179,7 @@ void VerticalJournal::cleanupExistingItems()
179 column.clear();
179 column.clear();
180 }
180 }
181 m_indexColumnMap.clear();
181 m_indexColumnMap.clear();
182+ setImplicitHeightDirty();
182}
183}
183
184
184void VerticalJournal::calculateImplicitHeight()
185void VerticalJournal::calculateImplicitHeight()
@@ -220,7 +221,7 @@ void VerticalJournal::doRelayout()
220 if (!allItems.isEmpty()) {
221 if (!allItems.isEmpty()) {
221 if (allItems.first().m_modelIndex == 0) {
222 if (allItems.first().m_modelIndex == 0) {
222 Q_FOREACH(const ViewItem &item, allItems)
223 Q_FOREACH(const ViewItem &item, allItems)
223− positionItem(item.m_modelIndex, item.m_item);
224+ addItemToView(item.m_modelIndex, item.m_item);
224 } else {
225 } else {
225 Q_FOREACH(const ViewItem &item, allItems)
226 Q_FOREACH(const ViewItem &item, allItems)
226 releaseItem(item.m_item);
227 releaseItem(item.m_item);
plugins/DashViews/verticaljournal.h+3−3
@@ -17,7 +17,7 @@
17#ifndef VERTICALJOURNAL_H
17#ifndef VERTICALJOURNAL_H
18#define VERTICALJOURNAL_H
18#define VERTICALJOURNAL_H
19
19
20−#include "abstractjournal.h"
20+#include "abstractdashview.h"
21
21
22 /** A vertical journal is a view that creates delegates
22 /** A vertical journal is a view that creates delegates
23 * based on a model and layouts them in columns following
23 * based on a model and layouts them in columns following
@@ -51,7 +51,7 @@
51 *
51 *
52 */
52 */
53
53
54−class VerticalJournal : public AbstractJournal
54+class VerticalJournal : public AbstractDashView
55{
55{
56 Q_OBJECT
56 Q_OBJECT
57
57
@@ -85,7 +85,7 @@ private:
85 void findBottomModelIndexToAdd(int *modelIndex, qreal *yPos) override;
85 void findBottomModelIndexToAdd(int *modelIndex, qreal *yPos) override;
86 void findTopModelIndexToAdd(int *modelIndex, qreal *yPos) override;
86 void findTopModelIndexToAdd(int *modelIndex, qreal *yPos) override;
87 bool removeNonVisibleItems(qreal bufferFromY, qreal bufferToY) override;
87 bool removeNonVisibleItems(qreal bufferFromY, qreal bufferToY) override;
88− void positionItem(int modelIndex, QQuickItem *item) override;
88+ void addItemToView(int modelIndex, QQuickItem *item) override;
89 void cleanupExistingItems() override;
89 void cleanupExistingItems() override;
90 void calculateImplicitHeight() override;
90 void calculateImplicitHeight() override;
91 void doRelayout() override;
91 void doRelayout() override;
po/am.ponew file+158
@@ -0,0 +1,158 @@
1+# Amharic translation for unity8
2+# Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014
3+# This file is distributed under the same license as the unity8 package.
4+# FIRST AUTHOR <EMAIL@ADDRESS>, 2014.
5+#
6+msgid ""
7+msgstr ""
8+"Project-Id-Version: unity8\n"
9+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10+"POT-Creation-Date: 2013-11-29 09:21+0100\n"
11+"PO-Revision-Date: 2014-01-18 19:28+0000\n"
12+"Last-Translator: samson <Unknown>\n"
13+"Language-Team: Amharic <am@li.org>\n"
14+"MIME-Version: 1.0\n"
15+"Content-Type: text/plain; charset=UTF-8\n"
16+"Content-Transfer-Encoding: 8bit\n"
17+"Plural-Forms: nplurals=2; plural=n > 1;\n"
18+"X-Launchpad-Export-Date: 2014-01-19 06:02+0000\n"
19+"X-Generator: Launchpad (build 16901)\n"
20+
21+#: Components/EdgeDemoOverlay.qml:151
22+msgid "Skip intro"
23+msgstr ""
24+
25+#: Components/EdgeDemo.qml:112
26+msgid "Right edge"
27+msgstr "የቀኝ ጠርዝ"
28+
29+#: Components/EdgeDemo.qml:113
30+msgid "Try swiping from the right edge to unlock the phone"
31+msgstr ""
32+
33+#: Components/EdgeDemo.qml:144
34+msgid "Top edge"
35+msgstr "የላይ ጠርዝ"
36+
37+#: Components/EdgeDemo.qml:145
38+msgid "Try swiping from the top edge to access the indicators"
39+msgstr ""
40+
41+#: Components/EdgeDemo.qml:170
42+msgid "Close"
43+msgstr "መዝጊያ"
44+
45+#: Components/EdgeDemo.qml:171
46+msgid "Swipe up again to close the settings screen"
47+msgstr ""
48+
49+#: Components/EdgeDemo.qml:198
50+msgid "Left edge"
51+msgstr "የግራ ጠርዝ"
52+
53+#: Components/EdgeDemo.qml:199
54+msgid "Swipe from the left to reveal the launcher for quick access to apps"
55+msgstr ""
56+
57+#: Components/EdgeDemo.qml:226
58+msgid "Well done"
59+msgstr ""
60+
61+#: Components/EdgeDemo.qml:227
62+msgid ""
63+"You have now mastered the edge gestures and can start using the "
64+"phone<br><br>Tap anywhere to start"
65+msgstr ""
66+
67+#: Components/PageHeader.qml:364
68+msgid "Recent searches"
69+msgstr ""
70+
71+#: Dash/Apps/AppPreview.qml:135
72+msgid "Rate this"
73+msgstr ""
74+
75+#. TRANSLATORS: Number of persons who rated this app/video/whatever
76+#: Dash/Previews/Header.qml:93
77+#, qt-format
78+msgid "(%1)"
79+msgstr "(%1)"
80+
81+#. TRANSLATORS: Number of persons who wrote reviews for this app/video/whatever
82+#: Dash/Previews/Header.qml:105
83+#, qt-format
84+msgid "%1 review"
85+msgid_plural "%1 reviews"
86+msgstr[0] ""
87+msgstr[1] ""
88+
89+#: Dash/Previews/Reviews.qml:74
90+msgid "Add a review"
91+msgstr ""
92+
93+#: Dash/Previews/Reviews.qml:86
94+msgid "Review"
95+msgstr ""
96+
97+#: Dash/Previews/Reviews.qml:121
98+msgid "Send"
99+msgstr "መላኪያ"
100+
101+#: Dash/Previews/Reviews.qml:139
102+msgid "Comments:"
103+msgstr "አስተያየቶች:"
104+
105+#: Greeter/Lockscreen.qml:149
106+msgid "Emergency Call"
107+msgstr ""
108+
109+#: Greeter/PassphraseLockscreen.qml:59
110+#, qt-format
111+msgid "Hello %1"
112+msgstr "ሰላም %1"
113+
114+#: Greeter/PassphraseLockscreen.qml:59
115+msgid "Hello"
116+msgstr "ሰላም"
117+
118+#: Hud/HudParametrizedActionsPage.qml:132
119+msgid "Confirm"
120+msgstr "ማረጋገጫ"
121+
122+#: Hud/Hud.qml:61 Hud/Hud.qml:99 Hud/Hud.qml:372
123+msgid "Type or say a command"
124+msgstr "ትእዛዝ ይናገሩ ወይንም ይጻፉ"
125+
126+#: Hud/Hud.qml:84
127+msgid "Loading. Please Wait..."
128+msgstr "እባክዎን ይቆዩ በመጫን ላይ..."
129+
130+#: Hud/Hud.qml:89
131+msgid "Speak Now..."
132+msgstr "አሁን ይናገሩ..."
133+
134+#: Hud/Hud.qml:94
135+msgid "Speaking..."
136+msgstr "በመናገር ላይ..."
137+
138+#: Notifications/NotificationMenuItemFactory.qml:89
139+msgid "Show password"
140+msgstr "የመግቢያ ቃል ማሳያ"
141+
142+#: Panel/SearchIndicator.qml:27
143+msgid "Search"
144+msgstr "መፈለጊያ"
145+
146+#: plugins/Unity/Launcher/launcheritem.cpp:43
147+#: plugins/Unity/Launcher/launcheritem.cpp:73
148+msgid "Lock to Launcher"
149+msgstr "ማስነሻው ላይ መቆለፊያ"
150+
151+#: plugins/Unity/Launcher/launcheritem.cpp:73
152+msgid "Unlock from Launcher"
153+msgstr "ከማስነሻው ላይ ማላቀቂያ"
154+
155+#: Shell.qml:439
156+#, qt-format
157+msgid "Please enter %1"
158+msgstr "እባክዎን ያስገቡ %1"
po/bs.ponew file+159
@@ -0,0 +1,159 @@
1+# Bosnian translation for unity8
2+# Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014
3+# This file is distributed under the same license as the unity8 package.
4+# FIRST AUTHOR <EMAIL@ADDRESS>, 2014.
5+#
6+msgid ""
7+msgstr ""
8+"Project-Id-Version: unity8\n"
9+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10+"POT-Creation-Date: 2013-11-29 09:21+0100\n"
11+"PO-Revision-Date: 2014-01-16 22:33+0000\n"
12+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13+"Language-Team: Bosnian <bs@li.org>\n"
14+"MIME-Version: 1.0\n"
15+"Content-Type: text/plain; charset=UTF-8\n"
16+"Content-Transfer-Encoding: 8bit\n"
17+"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
18+"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
19+"X-Launchpad-Export-Date: 2014-01-17 07:08+0000\n"
20+"X-Generator: Launchpad (build 16901)\n"
21+
22+#: Components/EdgeDemoOverlay.qml:151
23+msgid "Skip intro"
24+msgstr ""
25+
26+#: Components/EdgeDemo.qml:112
27+msgid "Right edge"
28+msgstr ""
29+
30+#: Components/EdgeDemo.qml:113
31+msgid "Try swiping from the right edge to unlock the phone"
32+msgstr ""
33+
34+#: Components/EdgeDemo.qml:144
35+msgid "Top edge"
36+msgstr ""
37+
38+#: Components/EdgeDemo.qml:145
39+msgid "Try swiping from the top edge to access the indicators"
40+msgstr ""
41+
42+#: Components/EdgeDemo.qml:170
43+msgid "Close"
44+msgstr ""
45+
46+#: Components/EdgeDemo.qml:171
47+msgid "Swipe up again to close the settings screen"
48+msgstr ""
49+
50+#: Components/EdgeDemo.qml:198
51+msgid "Left edge"
52+msgstr ""
53+
54+#: Components/EdgeDemo.qml:199
55+msgid "Swipe from the left to reveal the launcher for quick access to apps"
56+msgstr ""
57+
58+#: Components/EdgeDemo.qml:226
59+msgid "Well done"
60+msgstr ""
61+
62+#: Components/EdgeDemo.qml:227
63+msgid ""
64+"You have now mastered the edge gestures and can start using the "
65+"phone<br><br>Tap anywhere to start"
66+msgstr ""
67+
68+#: Components/PageHeader.qml:364
69+msgid "Recent searches"
70+msgstr ""
71+
72+#: Dash/Apps/AppPreview.qml:135
73+msgid "Rate this"
74+msgstr ""
75+
76+#. TRANSLATORS: Number of persons who rated this app/video/whatever
77+#: Dash/Previews/Header.qml:93
78+#, qt-format
79+msgid "(%1)"
80+msgstr ""
81+
82+#. TRANSLATORS: Number of persons who wrote reviews for this app/video/whatever
83+#: Dash/Previews/Header.qml:105
84+#, qt-format
85+msgid "%1 review"
86+msgid_plural "%1 reviews"
87+msgstr[0] ""
88+msgstr[1] ""
89+
90+#: Dash/Previews/Reviews.qml:74
91+msgid "Add a review"
92+msgstr ""
93+
94+#: Dash/Previews/Reviews.qml:86
95+msgid "Review"
96+msgstr ""
97+
98+#: Dash/Previews/Reviews.qml:121
99+msgid "Send"
100+msgstr ""
101+
102+#: Dash/Previews/Reviews.qml:139
103+msgid "Comments:"
104+msgstr ""
105+
106+#: Greeter/Lockscreen.qml:149
107+msgid "Emergency Call"
108+msgstr ""
109+
110+#: Greeter/PassphraseLockscreen.qml:59
111+#, qt-format
112+msgid "Hello %1"
113+msgstr ""
114+
115+#: Greeter/PassphraseLockscreen.qml:59
116+msgid "Hello"
117+msgstr ""
118+
119+#: Hud/HudParametrizedActionsPage.qml:132
120+msgid "Confirm"
121+msgstr ""
122+
123+#: Hud/Hud.qml:61 Hud/Hud.qml:99 Hud/Hud.qml:372
124+msgid "Type or say a command"
125+msgstr ""
126+
127+#: Hud/Hud.qml:84
128+msgid "Loading. Please Wait..."
129+msgstr ""
130+
131+#: Hud/Hud.qml:89
132+msgid "Speak Now..."
133+msgstr ""
134+
135+#: Hud/Hud.qml:94
136+msgid "Speaking..."
137+msgstr ""
138+
139+#: Notifications/NotificationMenuItemFactory.qml:89
140+msgid "Show password"
141+msgstr ""
142+
143+#: Panel/SearchIndicator.qml:27
144+msgid "Search"
145+msgstr ""
146+
147+#: plugins/Unity/Launcher/launcheritem.cpp:43
148+#: plugins/Unity/Launcher/launcheritem.cpp:73
149+msgid "Lock to Launcher"
150+msgstr ""
151+
152+#: plugins/Unity/Launcher/launcheritem.cpp:73
153+msgid "Unlock from Launcher"
154+msgstr ""
155+
156+#: Shell.qml:439
157+#, qt-format
158+msgid "Please enter %1"
159+msgstr ""
po/ckb.po+38−36
@@ -8,151 +8,153 @@ 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: 2013-11-29 09:21+0100\n"
10"POT-Creation-Date: 2013-11-29 09:21+0100\n"
11−"PO-Revision-Date: 2014-01-14 20:05+0000\n"
11+"PO-Revision-Date: 2014-01-21 11:05+0000\n"
12−"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12+"Last-Translator: Aras <aras.noori@gmail.com>\n"
13"Language-Team: Kurdish (Sorani) <ckb@li.org>\n"
13"Language-Team: Kurdish (Sorani) <ckb@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"Plural-Forms: nplurals=2; plural=n != 1;\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2014-01-15 06:35+0000\n"
18+"X-Launchpad-Export-Date: 2014-01-22 06:16+0000\n"
19−"X-Generator: Launchpad (build 16890)\n"
19+"X-Generator: Launchpad (build 16901)\n"
20
20
21#: Components/EdgeDemoOverlay.qml:151
21#: Components/EdgeDemoOverlay.qml:151
22msgid "Skip intro"
22msgid "Skip intro"
23−msgstr ""
23+msgstr "پێشەکیی بپەڕێنە"
24
24
25#: Components/EdgeDemo.qml:112
25#: Components/EdgeDemo.qml:112
26msgid "Right edge"
26msgid "Right edge"
27−msgstr ""
27+msgstr "لێواری ڕاست"
28
28
29#: Components/EdgeDemo.qml:113
29#: Components/EdgeDemo.qml:113
30msgid "Try swiping from the right edge to unlock the phone"
30msgid "Try swiping from the right edge to unlock the phone"
31−msgstr ""
31+msgstr "لێواری ڕاست ڕابکێشە بۆ کردنەوەی مۆبایلەکە"
32
32
33#: Components/EdgeDemo.qml:144
33#: Components/EdgeDemo.qml:144
34msgid "Top edge"
34msgid "Top edge"
35−msgstr ""
35+msgstr "لێواری سەرەوە"
36
36
37#: Components/EdgeDemo.qml:145
37#: Components/EdgeDemo.qml:145
38msgid "Try swiping from the top edge to access the indicators"
38msgid "Try swiping from the top edge to access the indicators"
39−msgstr ""
39+msgstr "لێواری سەرەوە ڕابکێشە بۆ گەیشتن بە نیشاندەرەکان"
40
40
41#: Components/EdgeDemo.qml:170
41#: Components/EdgeDemo.qml:170
42msgid "Close"
42msgid "Close"
43−msgstr ""
43+msgstr "داخستن"
44
44
45#: Components/EdgeDemo.qml:171
45#: Components/EdgeDemo.qml:171
46msgid "Swipe up again to close the settings screen"
46msgid "Swipe up again to close the settings screen"
47−msgstr ""
47+msgstr "ڕایکێشەوە سەرەوە جارێکی تر بۆ داخستنی پەردەی ڕێکخستنەکان"
48
48
49#: Components/EdgeDemo.qml:198
49#: Components/EdgeDemo.qml:198
50msgid "Left edge"
50msgid "Left edge"
51−msgstr ""
51+msgstr "لێواری چەپ"
52
52
53#: Components/EdgeDemo.qml:199
53#: Components/EdgeDemo.qml:199
54msgid "Swipe from the left to reveal the launcher for quick access to apps"
54msgid "Swipe from the left to reveal the launcher for quick access to apps"
55−msgstr ""
55+msgstr "لە چەپەوە بچۆرەوە سەر دەستپێک بۆئەوەی بتوانی هەموو ئەپەکان ببینی"
56
56
57#: Components/EdgeDemo.qml:226
57#: Components/EdgeDemo.qml:226
58msgid "Well done"
58msgid "Well done"
59−msgstr ""
59+msgstr "دەستخۆش"
60
60
61#: Components/EdgeDemo.qml:227
61#: Components/EdgeDemo.qml:227
62msgid ""
62msgid ""
63"You have now mastered the edge gestures and can start using the "
63"You have now mastered the edge gestures and can start using the "
64"phone<br><br>Tap anywhere to start"
64"phone<br><br>Tap anywhere to start"
65msgstr ""
65msgstr ""
66+"ئێستا شارەزایییت پەیدا کرد لە جوڵەی لێوارەکان و دەتوانی مۆبایلەکە بەکار "
67+"بهێنییت<br><br>پەنجە بە شوێنێکدا بنێ بۆ دەست پێ کردن"
66
68
67#: Components/PageHeader.qml:364
69#: Components/PageHeader.qml:364
68msgid "Recent searches"
70msgid "Recent searches"
69−msgstr ""
71+msgstr "دوایین گەڕانەکان"
70
72
71#: Dash/Apps/AppPreview.qml:135
73#: Dash/Apps/AppPreview.qml:135
72msgid "Rate this"
74msgid "Rate this"
73−msgstr ""
75+msgstr "پلە دابنی بۆی"
74
76
75#. TRANSLATORS: Number of persons who rated this app/video/whatever
77#. TRANSLATORS: Number of persons who rated this app/video/whatever
76#: Dash/Previews/Header.qml:93
78#: Dash/Previews/Header.qml:93
77#, qt-format
79#, qt-format
78msgid "(%1)"
80msgid "(%1)"
79−msgstr ""
81+msgstr "(%1)"
80
82
81#. TRANSLATORS: Number of persons who wrote reviews for this app/video/whatever
83#. TRANSLATORS: Number of persons who wrote reviews for this app/video/whatever
82#: Dash/Previews/Header.qml:105
84#: Dash/Previews/Header.qml:105
83#, qt-format
85#, qt-format
84msgid "%1 review"
86msgid "%1 review"
85msgid_plural "%1 reviews"
87msgid_plural "%1 reviews"
86−msgstr[0] ""
88+msgstr[0] "%1 پێداچوونەوە"
87−msgstr[1] ""
89+msgstr[1] "%1 پێداچوونەوەکان"
88
90
89#: Dash/Previews/Reviews.qml:74
91#: Dash/Previews/Reviews.qml:74
90msgid "Add a review"
92msgid "Add a review"
91−msgstr ""
93+msgstr "پێداچوونەوە زۆر بکە"
92
94
93#: Dash/Previews/Reviews.qml:86
95#: Dash/Previews/Reviews.qml:86
94msgid "Review"
96msgid "Review"
95−msgstr ""
97+msgstr "پێداچوونەوە"
96
98
97#: Dash/Previews/Reviews.qml:121
99#: Dash/Previews/Reviews.qml:121
98msgid "Send"
100msgid "Send"
99−msgstr ""
101+msgstr "ناردن"
100
102
101#: Dash/Previews/Reviews.qml:139
103#: Dash/Previews/Reviews.qml:139
102msgid "Comments:"
104msgid "Comments:"
103−msgstr ""
105+msgstr "لێدوانەکان:"
104
106
105#: Greeter/Lockscreen.qml:149
107#: Greeter/Lockscreen.qml:149
106msgid "Emergency Call"
108msgid "Emergency Call"
107−msgstr ""
109+msgstr "هێڵی فریاگوزاری"
108
110
109#: Greeter/PassphraseLockscreen.qml:59
111#: Greeter/PassphraseLockscreen.qml:59
110#, qt-format
112#, qt-format
111msgid "Hello %1"
113msgid "Hello %1"
112−msgstr ""
114+msgstr "سڵاو %1"
113
115
114#: Greeter/PassphraseLockscreen.qml:59
116#: Greeter/PassphraseLockscreen.qml:59
115msgid "Hello"
117msgid "Hello"
116−msgstr ""
118+msgstr "سڵاو"
117
119
118#: Hud/HudParametrizedActionsPage.qml:132
120#: Hud/HudParametrizedActionsPage.qml:132
119msgid "Confirm"
121msgid "Confirm"
120−msgstr ""
122+msgstr "پشتڕاستکردنەوە"
121
123
122#: Hud/Hud.qml:61 Hud/Hud.qml:99 Hud/Hud.qml:372
124#: Hud/Hud.qml:61 Hud/Hud.qml:99 Hud/Hud.qml:372
123msgid "Type or say a command"
125msgid "Type or say a command"
124−msgstr ""
126+msgstr "فەرمانێک بێژە یان بنووسە"
125
127
126#: Hud/Hud.qml:84
128#: Hud/Hud.qml:84
127msgid "Loading. Please Wait..."
129msgid "Loading. Please Wait..."
128−msgstr ""
130+msgstr "لە بارکردندایە. تکایە چاوەڕێ بکە..."
129
131
130#: Hud/Hud.qml:89
132#: Hud/Hud.qml:89
131msgid "Speak Now..."
133msgid "Speak Now..."
132−msgstr ""
134+msgstr "ئێستا قسە بکە"
133
135
134#: Hud/Hud.qml:94
136#: Hud/Hud.qml:94
135msgid "Speaking..."
137msgid "Speaking..."
136−msgstr ""
138+msgstr "قسە دەکات..."
137
139
138#: Notifications/NotificationMenuItemFactory.qml:89
140#: Notifications/NotificationMenuItemFactory.qml:89
139msgid "Show password"
141msgid "Show password"
140−msgstr ""
142+msgstr "تێپەڕەوشە پیشان بدە"
141
143
142#: Panel/SearchIndicator.qml:27
144#: Panel/SearchIndicator.qml:27
143msgid "Search"
145msgid "Search"
144−msgstr ""
146+msgstr "گەڕان"
145
147
146#: plugins/Unity/Launcher/launcheritem.cpp:43
148#: plugins/Unity/Launcher/launcheritem.cpp:43
147#: plugins/Unity/Launcher/launcheritem.cpp:73
149#: plugins/Unity/Launcher/launcheritem.cpp:73
148msgid "Lock to Launcher"
150msgid "Lock to Launcher"
149−msgstr ""
151+msgstr "چەسباندن بە لانچرەوە"
150
152
151#: plugins/Unity/Launcher/launcheritem.cpp:73
153#: plugins/Unity/Launcher/launcheritem.cpp:73
152msgid "Unlock from Launcher"
154msgid "Unlock from Launcher"
153−msgstr ""
155+msgstr "ھەڵکەندن لە لانچر"
154
156
155#: Shell.qml:439
157#: Shell.qml:439
156#, qt-format
158#, qt-format
157msgid "Please enter %1"
159msgid "Please enter %1"
158−msgstr ""
160+msgstr "تکایە %1 بنووسە"
po/eu.ponew file+160
@@ -0,0 +1,160 @@
1+# Basque translation for unity8
2+# Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014
3+# This file is distributed under the same license as the unity8 package.
4+# FIRST AUTHOR <EMAIL@ADDRESS>, 2014.
5+#
6+msgid ""
7+msgstr ""
8+"Project-Id-Version: unity8\n"
9+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10+"POT-Creation-Date: 2013-11-29 09:21+0100\n"
11+"PO-Revision-Date: 2014-01-18 12:16+0000\n"
12+"Last-Translator: Ibai Oihanguren Sala <Unknown>\n"
13+"Language-Team: Basque <eu@li.org>\n"
14+"MIME-Version: 1.0\n"
15+"Content-Type: text/plain; charset=UTF-8\n"
16+"Content-Transfer-Encoding: 8bit\n"
17+"Plural-Forms: nplurals=2; plural=n != 1;\n"
18+"X-Launchpad-Export-Date: 2014-01-19 06:02+0000\n"
19+"X-Generator: Launchpad (build 16901)\n"
20+
21+#: Components/EdgeDemoOverlay.qml:151
22+msgid "Skip intro"
23+msgstr "Saltatu aurkezpena"
24+
25+#: Components/EdgeDemo.qml:112
26+msgid "Right edge"
27+msgstr "Eskuineko ertza"
28+
29+#: Components/EdgeDemo.qml:113
30+msgid "Try swiping from the right edge to unlock the phone"
31+msgstr "Probatu eskuineko ertzetik irristatzen telefonoa desblokeatzeko"
32+
33+#: Components/EdgeDemo.qml:144
34+msgid "Top edge"
35+msgstr "Goiko ertza"
36+
37+#: Components/EdgeDemo.qml:145
38+msgid "Try swiping from the top edge to access the indicators"
39+msgstr "Probatu goiko ertzetik irristatzen adierazleak ikusteko"
40+
41+#: Components/EdgeDemo.qml:170
42+msgid "Close"
43+msgstr "Itxi"
44+
45+#: Components/EdgeDemo.qml:171
46+msgid "Swipe up again to close the settings screen"
47+msgstr "Irristatu gora berriro ezarpenen leihoa ixteko"
48+
49+#: Components/EdgeDemo.qml:198
50+msgid "Left edge"
51+msgstr "Ezkerreko ertza"
52+
53+#: Components/EdgeDemo.qml:199
54+msgid "Swipe from the left to reveal the launcher for quick access to apps"
55+msgstr ""
56+"Irristatu ezkerretik abiarazlea erakutsi eta aplikazioak eskura berehala "
57+"izateko"
58+
59+#: Components/EdgeDemo.qml:226
60+msgid "Well done"
61+msgstr "Bikain"
62+
63+#: Components/EdgeDemo.qml:227
64+msgid ""
65+"You have now mastered the edge gestures and can start using the "
66+"phone<br><br>Tap anywhere to start"
67+msgstr ""
68+
69+#: Components/PageHeader.qml:364
70+msgid "Recent searches"
71+msgstr ""
72+
73+#: Dash/Apps/AppPreview.qml:135
74+msgid "Rate this"
75+msgstr ""
76+
77+#. TRANSLATORS: Number of persons who rated this app/video/whatever
78+#: Dash/Previews/Header.qml:93
79+#, qt-format
80+msgid "(%1)"
81+msgstr ""
82+
83+#. TRANSLATORS: Number of persons who wrote reviews for this app/video/whatever
84+#: Dash/Previews/Header.qml:105
85+#, qt-format
86+msgid "%1 review"
87+msgid_plural "%1 reviews"
88+msgstr[0] ""
89+msgstr[1] ""
90+
91+#: Dash/Previews/Reviews.qml:74
92+msgid "Add a review"
93+msgstr ""
94+
95+#: Dash/Previews/Reviews.qml:86
96+msgid "Review"
97+msgstr ""
98+
99+#: Dash/Previews/Reviews.qml:121
100+msgid "Send"
101+msgstr ""
102+
103+#: Dash/Previews/Reviews.qml:139
104+msgid "Comments:"
105+msgstr ""
106+
107+#: Greeter/Lockscreen.qml:149
108+msgid "Emergency Call"
109+msgstr ""
110+
111+#: Greeter/PassphraseLockscreen.qml:59
112+#, qt-format
113+msgid "Hello %1"
114+msgstr ""
115+
116+#: Greeter/PassphraseLockscreen.qml:59
117+msgid "Hello"
118+msgstr ""
119+
120+#: Hud/HudParametrizedActionsPage.qml:132
121+msgid "Confirm"
122+msgstr ""
123+
124+#: Hud/Hud.qml:61 Hud/Hud.qml:99 Hud/Hud.qml:372
125+msgid "Type or say a command"
126+msgstr ""
127+
128+#: Hud/Hud.qml:84
129+msgid "Loading. Please Wait..."
130+msgstr ""
131+
132+#: Hud/Hud.qml:89
133+msgid "Speak Now..."
134+msgstr ""
135+
136+#: Hud/Hud.qml:94
137+msgid "Speaking..."
138+msgstr ""
139+
140+#: Notifications/NotificationMenuItemFactory.qml:89
141+msgid "Show password"
142+msgstr ""
143+
144+#: Panel/SearchIndicator.qml:27
145+msgid "Search"
146+msgstr ""
147+
148+#: plugins/Unity/Launcher/launcheritem.cpp:43
149+#: plugins/Unity/Launcher/launcheritem.cpp:73
150+msgid "Lock to Launcher"
151+msgstr ""
152+
153+#: plugins/Unity/Launcher/launcheritem.cpp:73
154+msgid "Unlock from Launcher"
155+msgstr ""
156+
157+#: Shell.qml:439
158+#, qt-format
159+msgid "Please enter %1"
160+msgstr ""
po/it.po+7−7
@@ -8,15 +8,15 @@ 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: 2013-11-29 09:21+0100\n"
10"POT-Creation-Date: 2013-11-29 09:21+0100\n"
11−"PO-Revision-Date: 2013-10-07 09:34+0000\n"
11+"PO-Revision-Date: 2014-01-22 09:15+0000\n"
12−"Last-Translator: Claudio Arseni <claudio.arseni@gmail.com>\n"
12+"Last-Translator: Domenico <domenico.verde125@live.it>\n"
13"Language-Team: Italian <it@li.org>\n"
13"Language-Team: Italian <it@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"Plural-Forms: nplurals=2; plural=n != 1;\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-12-29 06:04+0000\n"
18+"X-Launchpad-Export-Date: 2014-01-23 06:00+0000\n"
19−"X-Generator: Launchpad (build 16877)\n"
19+"X-Generator: Launchpad (build 16901)\n"
20
20
21#: Components/EdgeDemoOverlay.qml:151
21#: Components/EdgeDemoOverlay.qml:151
22msgid "Skip intro"
22msgid "Skip intro"
@@ -144,7 +144,7 @@ msgstr "Sto parlando..."
144
144
145#: Notifications/NotificationMenuItemFactory.qml:89
145#: Notifications/NotificationMenuItemFactory.qml:89
146msgid "Show password"
146msgid "Show password"
147−msgstr ""
147+msgstr "Mostra password"
148
148
149#: Panel/SearchIndicator.qml:27
149#: Panel/SearchIndicator.qml:27
150msgid "Search"
150msgid "Search"
@@ -153,11 +153,11 @@ msgstr "Cerca"
153#: plugins/Unity/Launcher/launcheritem.cpp:43
153#: plugins/Unity/Launcher/launcheritem.cpp:43
154#: plugins/Unity/Launcher/launcheritem.cpp:73
154#: plugins/Unity/Launcher/launcheritem.cpp:73
155msgid "Lock to Launcher"
155msgid "Lock to Launcher"
156−msgstr ""
156+msgstr "Blocca nel Launcher"
157
157
158#: plugins/Unity/Launcher/launcheritem.cpp:73
158#: plugins/Unity/Launcher/launcheritem.cpp:73
159msgid "Unlock from Launcher"
159msgid "Unlock from Launcher"
160−msgstr ""
160+msgstr "Sblocca dal Launcher"
161
161
162#: Shell.qml:439
162#: Shell.qml:439
163#, qt-format
163#, qt-format
po/ja.po+20−20
@@ -8,15 +8,15 @@ 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: 2013-11-29 09:21+0100\n"
10"POT-Creation-Date: 2013-11-29 09:21+0100\n"
11−"PO-Revision-Date: 2013-06-26 22:36+0000\n"
11+"PO-Revision-Date: 2014-01-18 07:01+0000\n"
12−"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12+"Last-Translator: Shushi Kurose <md81bird@hitaki.net>\n"
13"Language-Team: Japanese <ja@li.org>\n"
13"Language-Team: Japanese <ja@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"Plural-Forms: nplurals=1; plural=0;\n"
17"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2013-12-29 06:04+0000\n"
18+"X-Launchpad-Export-Date: 2014-01-19 06:02+0000\n"
19−"X-Generator: Launchpad (build 16877)\n"
19+"X-Generator: Launchpad (build 16901)\n"
20
20
21#: Components/EdgeDemoOverlay.qml:151
21#: Components/EdgeDemoOverlay.qml:151
22msgid "Skip intro"
22msgid "Skip intro"
@@ -24,7 +24,7 @@ msgstr ""
24
24
25#: Components/EdgeDemo.qml:112
25#: Components/EdgeDemo.qml:112
26msgid "Right edge"
26msgid "Right edge"
27−msgstr ""
27+msgstr "右端"
28
28
29#: Components/EdgeDemo.qml:113
29#: Components/EdgeDemo.qml:113
30msgid "Try swiping from the right edge to unlock the phone"
30msgid "Try swiping from the right edge to unlock the phone"
@@ -32,7 +32,7 @@ msgstr ""
32
32
33#: Components/EdgeDemo.qml:144
33#: Components/EdgeDemo.qml:144
34msgid "Top edge"
34msgid "Top edge"
35−msgstr ""
35+msgstr "上端"
36
36
37#: Components/EdgeDemo.qml:145
37#: Components/EdgeDemo.qml:145
38msgid "Try swiping from the top edge to access the indicators"
38msgid "Try swiping from the top edge to access the indicators"
@@ -40,7 +40,7 @@ msgstr ""
40
40
41#: Components/EdgeDemo.qml:170
41#: Components/EdgeDemo.qml:170
42msgid "Close"
42msgid "Close"
43−msgstr ""
43+msgstr "閉じる"
44
44
45#: Components/EdgeDemo.qml:171
45#: Components/EdgeDemo.qml:171
46msgid "Swipe up again to close the settings screen"
46msgid "Swipe up again to close the settings screen"
@@ -48,7 +48,7 @@ msgstr ""
48
48
49#: Components/EdgeDemo.qml:198
49#: Components/EdgeDemo.qml:198
50msgid "Left edge"
50msgid "Left edge"
51−msgstr ""
51+msgstr "左端"
52
52
53#: Components/EdgeDemo.qml:199
53#: Components/EdgeDemo.qml:199
54msgid "Swipe from the left to reveal the launcher for quick access to apps"
54msgid "Swipe from the left to reveal the launcher for quick access to apps"
@@ -66,7 +66,7 @@ msgstr ""
66
66
67#: Components/PageHeader.qml:364
67#: Components/PageHeader.qml:364
68msgid "Recent searches"
68msgid "Recent searches"
69−msgstr ""
69+msgstr "最近の検索"
70
70
71#: Dash/Apps/AppPreview.qml:135
71#: Dash/Apps/AppPreview.qml:135
72msgid "Rate this"
72msgid "Rate this"
@@ -76,7 +76,7 @@ msgstr ""
76#: Dash/Previews/Header.qml:93
76#: Dash/Previews/Header.qml:93
77#, qt-format
77#, qt-format
78msgid "(%1)"
78msgid "(%1)"
79−msgstr ""
79+msgstr "(%1)"
80
80
81#. TRANSLATORS: Number of persons who wrote reviews for this app/video/whatever
81#. TRANSLATORS: Number of persons who wrote reviews for this app/video/whatever
82#: Dash/Previews/Header.qml:105
82#: Dash/Previews/Header.qml:105
@@ -96,11 +96,11 @@ msgstr ""
96
96
97#: Dash/Previews/Reviews.qml:121
97#: Dash/Previews/Reviews.qml:121
98msgid "Send"
98msgid "Send"
99−msgstr ""
99+msgstr "送信"
100
100
101#: Dash/Previews/Reviews.qml:139
101#: Dash/Previews/Reviews.qml:139
102msgid "Comments:"
102msgid "Comments:"
103−msgstr ""
103+msgstr "コメント:"
104
104
105#: Greeter/Lockscreen.qml:149
105#: Greeter/Lockscreen.qml:149
106msgid "Emergency Call"
106msgid "Emergency Call"
@@ -113,11 +113,11 @@ msgstr ""
113
113
114#: Greeter/PassphraseLockscreen.qml:59
114#: Greeter/PassphraseLockscreen.qml:59
115msgid "Hello"
115msgid "Hello"
116−msgstr ""
116+msgstr "こんにちは"
117
117
118#: Hud/HudParametrizedActionsPage.qml:132
118#: Hud/HudParametrizedActionsPage.qml:132
119msgid "Confirm"
119msgid "Confirm"
120−msgstr ""
120+msgstr "確認"
121
121
122#: Hud/Hud.qml:61 Hud/Hud.qml:99 Hud/Hud.qml:372
122#: Hud/Hud.qml:61 Hud/Hud.qml:99 Hud/Hud.qml:372
123msgid "Type or say a command"
123msgid "Type or say a command"
@@ -125,11 +125,11 @@ msgstr ""
125
125
126#: Hud/Hud.qml:84
126#: Hud/Hud.qml:84
127msgid "Loading. Please Wait..."
127msgid "Loading. Please Wait..."
128−msgstr ""
128+msgstr "読み込み中です。お待ちください..."
129
129
130#: Hud/Hud.qml:89
130#: Hud/Hud.qml:89
131msgid "Speak Now..."
131msgid "Speak Now..."
132−msgstr ""
132+msgstr "音声入力を開始..."
133
133
134#: Hud/Hud.qml:94
134#: Hud/Hud.qml:94
135msgid "Speaking..."
135msgid "Speaking..."
@@ -137,20 +137,20 @@ msgstr ""
137
137
138#: Notifications/NotificationMenuItemFactory.qml:89
138#: Notifications/NotificationMenuItemFactory.qml:89
139msgid "Show password"
139msgid "Show password"
140−msgstr ""
140+msgstr "パスワードを表示"
141
141
142#: Panel/SearchIndicator.qml:27
142#: Panel/SearchIndicator.qml:27
143msgid "Search"
143msgid "Search"
144−msgstr ""
144+msgstr "検索"
145
145
146#: plugins/Unity/Launcher/launcheritem.cpp:43
146#: plugins/Unity/Launcher/launcheritem.cpp:43
147#: plugins/Unity/Launcher/launcheritem.cpp:73
147#: plugins/Unity/Launcher/launcheritem.cpp:73
148msgid "Lock to Launcher"
148msgid "Lock to Launcher"
149−msgstr ""
149+msgstr "Launcherに登録"
150
150
151#: plugins/Unity/Launcher/launcheritem.cpp:73
151#: plugins/Unity/Launcher/launcheritem.cpp:73
152msgid "Unlock from Launcher"
152msgid "Unlock from Launcher"
153−msgstr ""
153+msgstr "Launcherへの登録を解除"
154
154
155#: Shell.qml:439
155#: Shell.qml:439
156#, qt-format
156#, qt-format
po/ms.ponew file+160
@@ -0,0 +1,160 @@
1+# Malay translation for unity8
2+# Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014
3+# This file is distributed under the same license as the unity8 package.
4+# FIRST AUTHOR <EMAIL@ADDRESS>, 2014.
5+#
6+msgid ""
7+msgstr ""
8+"Project-Id-Version: unity8\n"
9+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10+"POT-Creation-Date: 2013-11-29 09:21+0100\n"
11+"PO-Revision-Date: 2014-01-17 09:05+0000\n"
12+"Last-Translator: abuyop <Unknown>\n"
13+"Language-Team: Malay <ms@li.org>\n"
14+"MIME-Version: 1.0\n"
15+"Content-Type: text/plain; charset=UTF-8\n"
16+"Content-Transfer-Encoding: 8bit\n"
17+"Plural-Forms: nplurals=2; plural=n != 1;\n"
18+"X-Launchpad-Export-Date: 2014-01-18 07:11+0000\n"
19+"X-Generator: Launchpad (build 16901)\n"
20+
21+#: Components/EdgeDemoOverlay.qml:151
22+msgid "Skip intro"
23+msgstr "Langkau pengenalan"
24+
25+#: Components/EdgeDemo.qml:112
26+msgid "Right edge"
27+msgstr "Pinggir kanan"
28+
29+#: Components/EdgeDemo.qml:113
30+msgid "Try swiping from the right edge to unlock the phone"
31+msgstr "Cuba meleret dari pinggir kanan untuk buka aktifkan telefon"
32+
33+#: Components/EdgeDemo.qml:144
34+msgid "Top edge"
35+msgstr "Pinggir atas"
36+
37+#: Components/EdgeDemo.qml:145
38+msgid "Try swiping from the top edge to access the indicators"
39+msgstr "Cuba meleret dari pinggir atas untuk buka aktifkan telefon"
40+
41+#: Components/EdgeDemo.qml:170
42+msgid "Close"
43+msgstr "Tutup"
44+
45+#: Components/EdgeDemo.qml:171
46+msgid "Swipe up again to close the settings screen"
47+msgstr "Leret ke atas sekali lagi untuk menutup skrin tetapan"
48+
49+#: Components/EdgeDemo.qml:198
50+msgid "Left edge"
51+msgstr "Pinggir kiri"
52+
53+#: Components/EdgeDemo.qml:199
54+msgid "Swipe from the left to reveal the launcher for quick access to apps"
55+msgstr "Leret dari kiri untuk munculkan pelancar untuk capaian pantas ke apl"
56+
57+#: Components/EdgeDemo.qml:226
58+msgid "Well done"
59+msgstr "Bagus"
60+
61+#: Components/EdgeDemo.qml:227
62+msgid ""
63+"You have now mastered the edge gestures and can start using the "
64+"phone<br><br>Tap anywhere to start"
65+msgstr ""
66+"Anda kini sudah mahir gerak isyarat pinggir dan boleh mulakan "
67+"telefon<br><br>Ketik dimana shaja untuk mula"
68+
69+#: Components/PageHeader.qml:364
70+msgid "Recent searches"
71+msgstr "Gelintar baru-baru ini"
72+
73+#: Dash/Apps/AppPreview.qml:135
74+msgid "Rate this"
75+msgstr "Kadar ini"
76+
77+#. TRANSLATORS: Number of persons who rated this app/video/whatever
78+#: Dash/Previews/Header.qml:93
79+#, qt-format
80+msgid "(%1)"
81+msgstr "(%1)"
82+
83+#. TRANSLATORS: Number of persons who wrote reviews for this app/video/whatever
84+#: Dash/Previews/Header.qml:105
85+#, qt-format
86+msgid "%1 review"
87+msgid_plural "%1 reviews"
88+msgstr[0] "%1 ulasan"
89+msgstr[1] "%1 ulasan"
90+
91+#: Dash/Previews/Reviews.qml:74
92+msgid "Add a review"
93+msgstr "Tambah ulasan"
94+
95+#: Dash/Previews/Reviews.qml:86
96+msgid "Review"
97+msgstr "Tinjauan"
98+
99+#: Dash/Previews/Reviews.qml:121
100+msgid "Send"
101+msgstr "Hantar"
102+
103+#: Dash/Previews/Reviews.qml:139
104+msgid "Comments:"
105+msgstr "Ulasan:"
106+
107+#: Greeter/Lockscreen.qml:149
108+msgid "Emergency Call"
109+msgstr "panggilan Kecemasan"
110+
111+#: Greeter/PassphraseLockscreen.qml:59
112+#, qt-format
113+msgid "Hello %1"
114+msgstr "Hai %1"
115+
116+#: Greeter/PassphraseLockscreen.qml:59
117+msgid "Hello"
118+msgstr "Hello"
119+
120+#: Hud/HudParametrizedActionsPage.qml:132
121+msgid "Confirm"
122+msgstr "Sahkan"
123+
124+#: Hud/Hud.qml:61 Hud/Hud.qml:99 Hud/Hud.qml:372
125+msgid "Type or say a command"
126+msgstr "Taip atau sebut satu perintah"
127+
128+#: Hud/Hud.qml:84
129+msgid "Loading. Please Wait..."
130+msgstr "Memuatkan. Tunggu Sebentar..."
131+
132+#: Hud/Hud.qml:89
133+msgid "Speak Now..."
134+msgstr "Cakap Sekarang..."
135+
136+#: Hud/Hud.qml:94
137+msgid "Speaking..."
138+msgstr "Bercakap..."
139+
140+#: Notifications/NotificationMenuItemFactory.qml:89
141+msgid "Show password"
142+msgstr "Tunjuk kata laluan"
143+
144+#: Panel/SearchIndicator.qml:27
145+msgid "Search"
146+msgstr "Gelintar"
147+
148+#: plugins/Unity/Launcher/launcheritem.cpp:43
149+#: plugins/Unity/Launcher/launcheritem.cpp:73
150+msgid "Lock to Launcher"
151+msgstr "Kunci ke Pelancar"
152+
153+#: plugins/Unity/Launcher/launcheritem.cpp:73
154+msgid "Unlock from Launcher"
155+msgstr "Tanggalkan dari Pelancar"
156+
157+#: Shell.qml:439
158+#, qt-format
159+msgid "Please enter %1"
160+msgstr "Sila masukkan %1"
po/pt_BR.po+9−7
@@ -8,15 +8,15 @@ 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: 2013-11-29 09:21+0100\n"
10"POT-Creation-Date: 2013-11-29 09:21+0100\n"
11−"PO-Revision-Date: 2013-10-01 13:05+0000\n"
11+"PO-Revision-Date: 2014-01-18 23:24+0000\n"
12−"Last-Translator: Rafael Neri <Unknown>\n"
12+"Last-Translator: Fábio Nogueira <deb-user-ba@ubuntu.com>\n"
13"Language-Team: Brazilian Portuguese <pt_BR@li.org>\n"
13"Language-Team: Brazilian Portuguese <pt_BR@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"Plural-Forms: nplurals=2; plural=n > 1;\n"
17"Plural-Forms: nplurals=2; plural=n > 1;\n"
18−"X-Launchpad-Export-Date: 2013-12-29 06:04+0000\n"
18+"X-Launchpad-Export-Date: 2014-01-19 06:02+0000\n"
19−"X-Generator: Launchpad (build 16877)\n"
19+"X-Generator: Launchpad (build 16901)\n"
20
20
21#: Components/EdgeDemoOverlay.qml:151
21#: Components/EdgeDemoOverlay.qml:151
22msgid "Skip intro"
22msgid "Skip intro"
@@ -65,6 +65,8 @@ msgid ""
65"You have now mastered the edge gestures and can start using the "
65"You have now mastered the edge gestures and can start using the "
66"phone<br><br>Tap anywhere to start"
66"phone<br><br>Tap anywhere to start"
67msgstr ""
67msgstr ""
68+"Agora você já domina o uso dos gestos de borda e pode começar a utilizar o "
69+"telefone<br><br>Toque na tela para começar"
68
70
69#: Components/PageHeader.qml:364
71#: Components/PageHeader.qml:364
70msgid "Recent searches"
72msgid "Recent searches"
@@ -139,7 +141,7 @@ msgstr "Falando..."
139
141
140#: Notifications/NotificationMenuItemFactory.qml:89
142#: Notifications/NotificationMenuItemFactory.qml:89
141msgid "Show password"
143msgid "Show password"
142−msgstr ""
144+msgstr "Exibir senha"
143
145
144#: Panel/SearchIndicator.qml:27
146#: Panel/SearchIndicator.qml:27
145msgid "Search"
147msgid "Search"
@@ -148,11 +150,11 @@ msgstr "Pesquisar"
148#: plugins/Unity/Launcher/launcheritem.cpp:43
150#: plugins/Unity/Launcher/launcheritem.cpp:43
149#: plugins/Unity/Launcher/launcheritem.cpp:73
151#: plugins/Unity/Launcher/launcheritem.cpp:73
150msgid "Lock to Launcher"
152msgid "Lock to Launcher"
151−msgstr ""
153+msgstr "Bloquear no lançador"
152
154
153#: plugins/Unity/Launcher/launcheritem.cpp:73
155#: plugins/Unity/Launcher/launcheritem.cpp:73
154msgid "Unlock from Launcher"
156msgid "Unlock from Launcher"
155−msgstr ""
157+msgstr "Desbloquear do lançador"
156
158
157#: Shell.qml:439
159#: Shell.qml:439
158#, qt-format
160#, qt-format
po/ru.po+7−6
@@ -8,16 +8,16 @@ 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: 2013-11-29 09:21+0100\n"
10"POT-Creation-Date: 2013-11-29 09:21+0100\n"
11−"PO-Revision-Date: 2014-01-14 19:17+0000\n"
11+"PO-Revision-Date: 2014-01-26 15:56+0000\n"
12−"Last-Translator: alex <sos987@gmail.com>\n"
12+"Last-Translator: Zonov Roman <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"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
17"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
18"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
18"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
19−"X-Launchpad-Export-Date: 2014-01-15 06:35+0000\n"
19+"X-Launchpad-Export-Date: 2014-01-27 05:48+0000\n"
20−"X-Generator: Launchpad (build 16890)\n"
20+"X-Generator: Launchpad (build 16914)\n"
21
21
22#: Components/EdgeDemoOverlay.qml:151
22#: Components/EdgeDemoOverlay.qml:151
23msgid "Skip intro"
23msgid "Skip intro"
@@ -91,8 +91,9 @@ msgstr "(%1)"
91#, qt-format
91#, qt-format
92msgid "%1 review"
92msgid "%1 review"
93msgid_plural "%1 reviews"
93msgid_plural "%1 reviews"
94+msgstr[0] "%1 отзыв"
94−msgstr[0] "%1 отзыва"
95+msgstr[1] "%1 отзыва"
95−msgstr[1] "%1 отзывов"
96+msgstr[2] "%1 отзывов"
96
97
97#: Dash/Previews/Reviews.qml:74
98#: Dash/Previews/Reviews.qml:74
98msgid "Add a review"
99msgid "Add a review"
po/ug.po+7−7
@@ -8,15 +8,15 @@ 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: 2013-11-29 09:21+0100\n"
10"POT-Creation-Date: 2013-11-29 09:21+0100\n"
11−"PO-Revision-Date: 2013-10-09 22:38+0000\n"
11+"PO-Revision-Date: 2014-01-17 04:33+0000\n"
12"Last-Translator: Gheyret T.Kenji <Unknown>\n"
12"Last-Translator: Gheyret T.Kenji <Unknown>\n"
13"Language-Team: Uyghur <ug@li.org>\n"
13"Language-Team: Uyghur <ug@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"Plural-Forms: nplurals=1; plural=0;\n"
17"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2013-12-29 06:04+0000\n"
18+"X-Launchpad-Export-Date: 2014-01-18 07:11+0000\n"
19−"X-Generator: Launchpad (build 16877)\n"
19+"X-Generator: Launchpad (build 16901)\n"
20
20
21#: Components/EdgeDemoOverlay.qml:151
21#: Components/EdgeDemoOverlay.qml:151
22msgid "Skip intro"
22msgid "Skip intro"
@@ -91,7 +91,7 @@ msgstr ""
91
91
92#: Dash/Previews/Reviews.qml:86
92#: Dash/Previews/Reviews.qml:86
93msgid "Review"
93msgid "Review"
94−msgstr ""
94+msgstr "تەكشۈر"
95
95
96#: Dash/Previews/Reviews.qml:121
96#: Dash/Previews/Reviews.qml:121
97msgid "Send"
97msgid "Send"
@@ -136,7 +136,7 @@ msgstr "سۆزلەۋاتىسىز…"
136
136
137#: Notifications/NotificationMenuItemFactory.qml:89
137#: Notifications/NotificationMenuItemFactory.qml:89
138msgid "Show password"
138msgid "Show password"
139−msgstr ""
139+msgstr "ئىم كۆرسەت"
140
140
141#: Panel/SearchIndicator.qml:27
141#: Panel/SearchIndicator.qml:27
142msgid "Search"
142msgid "Search"
@@ -145,11 +145,11 @@ msgstr "ئىزدە"
145#: plugins/Unity/Launcher/launcheritem.cpp:43
145#: plugins/Unity/Launcher/launcheritem.cpp:43
146#: plugins/Unity/Launcher/launcheritem.cpp:73
146#: plugins/Unity/Launcher/launcheritem.cpp:73
147msgid "Lock to Launcher"
147msgid "Lock to Launcher"
148−msgstr ""
148+msgstr "ئىجراچىغا سولىۋەت"
149
149
150#: plugins/Unity/Launcher/launcheritem.cpp:73
150#: plugins/Unity/Launcher/launcheritem.cpp:73
151msgid "Unlock from Launcher"
151msgid "Unlock from Launcher"
152−msgstr ""
152+msgstr "ئىجراچىدىن چىقار"
153
153
154#: Shell.qml:439
154#: Shell.qml:439
155#, qt-format
155#, qt-format
po/zh_HK.ponew file+157
@@ -0,0 +1,157 @@
1+# Chinese (Hong Kong) translation for unity8
2+# Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014
3+# This file is distributed under the same license as the unity8 package.
4+# FIRST AUTHOR <EMAIL@ADDRESS>, 2014.
5+#
6+msgid ""
7+msgstr ""
8+"Project-Id-Version: unity8\n"
9+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10+"POT-Creation-Date: 2013-11-29 09:21+0100\n"
11+"PO-Revision-Date: 2014-01-25 13:32+0000\n"
12+"Last-Translator: Daniel Cheung <daniel.2345@hotmail.com>\n"
13+"Language-Team: Chinese (Hong Kong) <zh_HK@li.org>\n"
14+"MIME-Version: 1.0\n"
15+"Content-Type: text/plain; charset=UTF-8\n"
16+"Content-Transfer-Encoding: 8bit\n"
17+"Plural-Forms: nplurals=1; plural=0;\n"
18+"X-Launchpad-Export-Date: 2014-01-26 05:18+0000\n"
19+"X-Generator: Launchpad (build 16914)\n"
20+
21+#: Components/EdgeDemoOverlay.qml:151
22+msgid "Skip intro"
23+msgstr "跳過介紹"
24+
25+#: Components/EdgeDemo.qml:112
26+msgid "Right edge"
27+msgstr "右邊緣"
28+
29+#: Components/EdgeDemo.qml:113
30+msgid "Try swiping from the right edge to unlock the phone"
31+msgstr "試從右邊緣輕掃解鎖手機"
32+
33+#: Components/EdgeDemo.qml:144
34+msgid "Top edge"
35+msgstr "頂部邊緣"
36+
37+#: Components/EdgeDemo.qml:145
38+msgid "Try swiping from the top edge to access the indicators"
39+msgstr "試從頂部邊緣輕掃存取指示器"
40+
41+#: Components/EdgeDemo.qml:170
42+msgid "Close"
43+msgstr "關閉"
44+
45+#: Components/EdgeDemo.qml:171
46+msgid "Swipe up again to close the settings screen"
47+msgstr "再向上掃一次以關閉設定畫面"
48+
49+#: Components/EdgeDemo.qml:198
50+msgid "Left edge"
51+msgstr "左邊緣"
52+
53+#: Components/EdgeDemo.qml:199
54+msgid "Swipe from the left to reveal the launcher for quick access to apps"
55+msgstr "從左邊緣輕掃以顯示啟動器快速訪問應用"
56+
57+#: Components/EdgeDemo.qml:226
58+msgid "Well done"
59+msgstr "做得好"
60+
61+#: Components/EdgeDemo.qml:227
62+msgid ""
63+"You have now mastered the edge gestures and can start using the "
64+"phone<br><br>Tap anywhere to start"
65+msgstr "現在你已經掌握了邊緣手勢,可以開始使用手機<br><br>點擊任意位置以開始"
66+
67+#: Components/PageHeader.qml:364
68+msgid "Recent searches"
69+msgstr "最近的搜尋"
70+
71+#: Dash/Apps/AppPreview.qml:135
72+msgid "Rate this"
73+msgstr "評價"
74+
75+#. TRANSLATORS: Number of persons who rated this app/video/whatever
76+#: Dash/Previews/Header.qml:93
77+#, qt-format
78+msgid "(%1)"
79+msgstr "(%1)"
80+
81+#. TRANSLATORS: Number of persons who wrote reviews for this app/video/whatever
82+#: Dash/Previews/Header.qml:105
83+#, qt-format
84+msgid "%1 review"
85+msgid_plural "%1 reviews"
86+msgstr[0] "%1 評論"
87+
88+#: Dash/Previews/Reviews.qml:74
89+msgid "Add a review"
90+msgstr "新增評論"
91+
92+#: Dash/Previews/Reviews.qml:86
93+msgid "Review"
94+msgstr "評論"
95+
96+#: Dash/Previews/Reviews.qml:121
97+msgid "Send"
98+msgstr "傳送"
99+
100+#: Dash/Previews/Reviews.qml:139
101+msgid "Comments:"
102+msgstr "評論:"
103+
104+#: Greeter/Lockscreen.qml:149
105+msgid "Emergency Call"
106+msgstr "緊急電話"
107+
108+#: Greeter/PassphraseLockscreen.qml:59
109+#, qt-format
110+msgid "Hello %1"
111+msgstr "您好 %1"
112+
113+#: Greeter/PassphraseLockscreen.qml:59
114+msgid "Hello"
115+msgstr "您好"
116+
117+#: Hud/HudParametrizedActionsPage.qml:132
118+msgid "Confirm"
119+msgstr "確認"
120+
121+#: Hud/Hud.qml:61 Hud/Hud.qml:99 Hud/Hud.qml:372
122+msgid "Type or say a command"
123+msgstr "輸入或說出指令"
124+
125+#: Hud/Hud.qml:84
126+msgid "Loading. Please Wait..."
127+msgstr "正載入。請稍候..."
128+
129+#: Hud/Hud.qml:89
130+msgid "Speak Now..."
131+msgstr "馬上講..."
132+
133+#: Hud/Hud.qml:94
134+msgid "Speaking..."
135+msgstr "正在講..."
136+
137+#: Notifications/NotificationMenuItemFactory.qml:89
138+msgid "Show password"
139+msgstr "顯示密碼"
140+
141+#: Panel/SearchIndicator.qml:27
142+msgid "Search"
143+msgstr "搜尋"
144+
145+#: plugins/Unity/Launcher/launcheritem.cpp:43
146+#: plugins/Unity/Launcher/launcheritem.cpp:73
147+msgid "Lock to Launcher"
148+msgstr "鎖定至啟動器"
149+
150+#: plugins/Unity/Launcher/launcheritem.cpp:73
151+msgid "Unlock from Launcher"
152+msgstr "從啟動器解除鎖定"
153+
154+#: Shell.qml:439
155+#, qt-format
156+msgid "Please enter %1"
157+msgstr "請輸入 %1"
po/zh_TW.po+1−1
@@ -15,7 +15,7 @@ msgstr ""
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"Plural-Forms: nplurals=1; plural=0;\n"
17"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2014-01-16 06:09+0000\n"
18+"X-Launchpad-Export-Date: 2014-01-17 07:08+0000\n"
19"X-Generator: Launchpad (build 16901)\n"
19"X-Generator: Launchpad (build 16901)\n"
20
20
21#: Components/EdgeDemoOverlay.qml:151
21#: Components/EdgeDemoOverlay.qml:151
qml/Dash/Apps/AppPreview.qml+1
@@ -97,6 +97,7 @@ GenericPreview {
97 spacing: units.gu(1)
97 spacing: units.gu(1)
98
98
99 Label {
99 Label {
100+ objectName: "descriptionLabel"
100 anchors { left: parent.left; right: parent.right }
101 anchors { left: parent.left; right: parent.right }
101 text: root.previewData.description
102 text: root.previewData.description
102 fontSize: "medium"
103 fontSize: "medium"
tests/autopilot/unity8/shell/emulators/__init__.py+1−1
@@ -25,7 +25,7 @@ class UnityEmulatorBase(introspection.CustomEmulatorBase):
25
25
26 def __init__(self, *args):
26 def __init__(self, *args):
27 super(UnityEmulatorBase, self).__init__(*args)
27 super(UnityEmulatorBase, self).__init__(*args)
28− self.pointing_device = input.Touch.create()
28+ self.pointing_device = input.Pointer(device=input.Touch.create())
29
29
30
30
31class UnityEmulatorException(Exception):
31class UnityEmulatorException(Exception):
tests/autopilot/unity8/shell/emulators/dash.py+53−2
@@ -138,8 +138,59 @@ class Dash(emulators.UnityEmulatorBase):
138
138
139
139
140class GenericScopeView(emulators.UnityEmulatorBase):
140class GenericScopeView(emulators.UnityEmulatorBase):
141− """Autopilot emulators for generic scopes."""
141+ """Autopilot emulator for generic scopes."""
142
142
143
143
144class DashApps(emulators.UnityEmulatorBase):
144class DashApps(emulators.UnityEmulatorBase):
145− """Autopilot emulators for the applications scope."""
145+ """Autopilot emulator for the applications scope."""
146+
147+ def get_applications(self, category):
148+ """Return the list of applications on a category.
149+
150+ :parameter category: The name of the category.
151+
152+ """
153+ category_element = self._get_category_element(category)
154+ application_tiles = category_element.select_many('Tile')
155+ # TODO return them on the same order they are displayed.
156+ # --elopio - 2014-1-15
157+ return [tile.text for tile in application_tiles]
158+
159+ def _get_category_element(self, category):
160+ try:
161+ return self.select_single(
162+ 'Base', objectName='dashCategory{}'.format(category))
163+ except dbus.StateNotFoundError:
164+ raise emulators.UnityEmulatorException(
165+ 'No category found with name {}'.format(category))
166+
167+ @autopilot_logging.log_action(logger.info)
168+ def open_preview(self, category, app_name):
169+ """Open the preview of an application.
170+
171+ :parameter category: The name of the category where the application is.
172+ :app_name: The name of the application.
173+
174+ """
175+ category_element = self._get_category_element(category)
176+ icon = category_element.select_single('Tile', text=app_name)
177+ # FIXME some categories need a long press in order to see the preview.
178+ # Some categories do not show previews, like recent apps.
179+ # --elopio - 2014-1-14
180+ self.pointing_device.click_object(icon)
181+ return self.get_root_instance().wait_select_single(AppPreview)
182+
183+
184+class AppPreview(emulators.UnityEmulatorBase):
185+ """Autopilot emulator for the application preview."""
186+
187+ def get_details(self):
188+ """Return the details of the application showed in its preview."""
189+ title = self.select_single('Label', objectName='titleLabel').text
190+ publisher = self.select_single(
191+ 'Label', objectName='subtitleLabel').text
192+ description = self.select_single(
193+ 'Label', objectName='descriptionLabel').text
194+ # TODO return screenshots, icon, rating and reviews.
195+ # --elopio - 2014-1-15
196+ return dict(title=title, publisher=publisher, description=description)
tests/autopilot/unity8/shell/tests/test_emulators.py+89−2
@@ -17,23 +17,43 @@
17# along with this program. If not, see <http://www.gnu.org/licenses/>.
17# along with this program. If not, see <http://www.gnu.org/licenses/>.
18#
18#
19
19
20+"""Tests for the Dash autopilot emulators.
21+
22+The autopilot emulators are helpers for tests that check a user journey that
23+involves the dash. The code for some of those tests will not be inside this
24+branch, but in projects that depend on unity or that test the whole system
25+integration. So, we need to test the helpers in order to make sure that we
26+don't break them for those external projects.
27+
28+"""
29+
30+import os
31+import sysconfig
32+
20import mock
33import mock
21
34
35+import fixtures
36+from testtools.matchers import Contains, HasLength
37+
38+import unity8
22from unity8 import process_helpers
39from unity8 import process_helpers
23from unity8.shell import emulators, tests
40from unity8.shell import emulators, tests
24from unity8.shell.emulators import dash as dash_emulators
41from unity8.shell.emulators import dash as dash_emulators
25
42
26
43
27−class DashEmulatorTestCase(tests.UnityTestCase):
44+class DashBaseTestCase(tests.UnityTestCase):
28
45
29 scenarios = tests._get_device_emulation_scenarios()
46 scenarios = tests._get_device_emulation_scenarios()
30
47
31 def setUp(self):
48 def setUp(self):
32− super(DashEmulatorTestCase, self).setUp()
49+ super(DashBaseTestCase, self).setUp()
33 unity_proxy = self.launch_unity()
50 unity_proxy = self.launch_unity()
34 process_helpers.unlock_unity(unity_proxy)
51 process_helpers.unlock_unity(unity_proxy)
35 self.dash = self.main_window.get_dash()
52 self.dash = self.main_window.get_dash()
36
53
54+
55+class DashEmulatorTestCase(DashBaseTestCase):
56+
37 def test_open_unexisting_scope(self):
57 def test_open_unexisting_scope(self):
38 scope_name = 'unexisting'
58 scope_name = 'unexisting'
39 with mock.patch.object(self.dash, 'pointing_device') as mock_pointer:
59 with mock.patch.object(self.dash, 'pointing_device') as mock_pointer:
@@ -118,3 +138,70 @@ class DashEmulatorTestCase(tests.UnityTestCase):
118 scope = self.dash.open_scope(self._get_scope_name_from_id(scope_id))
138 scope = self.dash.open_scope(self._get_scope_name_from_id(scope_id))
119 self._assert_scope_is_opened(scope, scope_id)
139 self._assert_scope_is_opened(scope, scope_id)
120 self.assertIsInstance(scope, dash_emulators.DashApps)
140 self.assertIsInstance(scope, dash_emulators.DashApps)
141+
142+
143+class DashAppsEmulatorTestCase(DashBaseTestCase):
144+
145+ available_applications = [
146+ 'Title.1', 'Title.21', 'Title.41', 'Title.61', 'Title.81',
147+ 'Title.101', 'Title.121', 'Title.141', 'Title.161', 'Title.181',
148+ 'Title.201', 'Title.221', 'Title.241', 'Title.261', 'Title.281']
149+
150+ def setUp(self):
151+ self._use_scope_fakes()
152+ super(DashAppsEmulatorTestCase, self).setUp()
153+ self.applications_scope = self.dash.open_scope('applications')
154+
155+ def _use_scope_fakes(self):
156+ self.useFixture(
157+ fixtures.EnvironmentVariable(
158+ 'QML2_IMPORT_PATH',
159+ newvalue=self._get_fake_scopes_library_path()))
160+
161+ def _get_fake_scopes_library_path(self):
162+ if unity8.running_installed_tests():
163+ mock_path = 'qml/scopefakes/'
164+ else:
165+ mock_path = os.path.join(
166+ '../lib/', sysconfig.get_config_var('MULTIARCH'),
167+ 'unity8/qml/scopefakes/')
168+ lib_path = unity8.get_lib_path()
169+ ld_library_path = os.path.abspath(os.path.join(lib_path, mock_path))
170+
171+ if not os.path.exists(ld_library_path):
172+ raise RuntimeError(
173+ 'Expected library path does not exists: %s.' % (
174+ ld_library_path))
175+ return ld_library_path
176+
177+ def test_get_applications_with_unexisting_category(self):
178+ exception = self.assertRaises(
179+ emulators.UnityEmulatorException,
180+ self.applications_scope.get_applications,
181+ 'unexisting category')
182+
183+ self.assertEqual(
184+ 'No category found with name unexisting category', str(exception))
185+
186+ def test_get_applications_should_return_list_with_names(self):
187+ category = 'installed'
188+ expected_apps_count = self._get_number_of_application_slots(category)
189+ expected_applications = self.available_applications[
190+ :expected_apps_count]
191+
192+ applications = self.applications_scope.get_applications(category)
193+
194+ self.assertThat(applications, HasLength(expected_apps_count))
195+ for expected in expected_applications:
196+ self.assertThat(applications, Contains(expected))
197+
198+ def _get_number_of_application_slots(self, category):
199+ category_element = self.applications_scope._get_category_element(
200+ category)
201+ grid = category_element.select_single('GenericFilterGrid')
202+ return grid.columns * grid.rows
203+
204+ def test_open_preview(self):
205+ preview = self.applications_scope.open_preview('installed', 'Title.1')
206+ self.assertIsInstance(preview, dash_emulators.AppPreview)
207+ self.assertTrue(preview.isCurrent)
tests/mocks/Unity/CMakeLists.txt+9−2
@@ -1,5 +1,7 @@
1add_subdirectory(Application)
1add_subdirectory(Application)
2add_subdirectory(Indicators)
2add_subdirectory(Indicators)
3+add_subdirectory(Launcher)
4+add_subdirectory(Notifications)
3
5
4pkg_search_module(DEE dee-1.0 REQUIRED)
6pkg_search_module(DEE dee-1.0 REQUIRED)
5pkg_search_module(GOBJECT gobject-2.0 REQUIRED)
7pkg_search_module(GOBJECT gobject-2.0 REQUIRED)
@@ -41,5 +43,10 @@ file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/qmldir"
41 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
43 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
42 )
44 )
43
45
44−add_subdirectory(Launcher)
46+install(TARGETS FakeUnityQml
45−add_subdirectory(Notifications)
47+ DESTINATION ${SHELL_INSTALL_QML}/scopefakes/Unity
48+ )
49+
50+install(FILES qmldir
51+ DESTINATION ${SHELL_INSTALL_QML}/scopefakes/Unity
52+ )
tests/mocks/Unity/fake_applications_scope.cpp+2−1
@@ -1,5 +1,5 @@
1/*
1/*
2− * Copyright (C) 2013 Canonical, Ltd.
2+ * Copyright (C) 2013, 2014 Canonical, Ltd.
3 *
3 *
4 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
5 * it under the terms of the GNU General Public License as published by
@@ -30,6 +30,7 @@ ApplicationsScope::ApplicationsScope(bool visible, QObject* parent)
30 m_id = "applications.scope";
30 m_id = "applications.scope";
31 m_name = "Applications";
31 m_name = "Applications";
32 m_visible = visible;
32 m_visible = visible;
33+ m_previewRendererName = "preview-application";
33 m_categories->setModel(createCategoriesModel());
34 m_categories->setModel(createCategoriesModel());
34}
35}
35
36
tests/mocks/Unity/fake_preview.cpp+5−3
@@ -1,5 +1,5 @@
1/*
1/*
2− * Copyright (C) 2013 Canonical, Ltd.
2+ * Copyright (C) 2013, 2014 Canonical, Ltd.
3 *
3 *
4 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
5 * it under the terms of the GNU General Public License as published by
@@ -16,13 +16,15 @@
16
16
17#include "fake_preview.h"
17#include "fake_preview.h"
18
18
19−Preview::Preview(QObject *parent): QObject(parent)
19+Preview::Preview(const QString &rendererName, QObject *parent):
20+ QObject(parent),
21+ m_rendererName(rendererName)
20{
22{
21}
23}
22
24
23QString Preview::rendererName() const
25QString Preview::rendererName() const
24{
26{
25− return "generic-preview";
27+ return m_rendererName;
26}
28}
27
29
28QString Preview::title() const
30QString Preview::title() const
tests/mocks/Unity/fake_preview.h+5−2
@@ -1,5 +1,5 @@
1/*
1/*
2− * Copyright (C) 2013 Canonical, Ltd.
2+ * Copyright (C) 2013, 2014 Canonical, Ltd.
3 *
3 *
4 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
5 * it under the terms of the GNU General Public License as published by
@@ -38,7 +38,7 @@ class Q_DECL_EXPORT Preview : public QObject
38 Q_PROPERTY(QString image READ image NOTIFY previewChanged)
38 Q_PROPERTY(QString image READ image NOTIFY previewChanged)
39
39
40public:
40public:
41− explicit Preview(QObject *parent = 0);
41+ explicit Preview(const QString &rendererName, QObject *parent = 0);
42
42
43 QString rendererName() const;
43 QString rendererName() const;
44 QString title() const;
44 QString title() const;
@@ -55,6 +55,9 @@ public:
55
55
56Q_SIGNALS:
56Q_SIGNALS:
57 void previewChanged();
57 void previewChanged();
58+
59+private:
60+ QString m_rendererName;
58};
61};
59
62
60Q_DECLARE_METATYPE(Preview *)
63Q_DECLARE_METATYPE(Preview *)
tests/mocks/Unity/fake_scope.cpp+3−2
@@ -1,5 +1,5 @@
1/*
1/*
2− * Copyright (C) 2013 Canonical, Ltd.
2+ * Copyright (C) 2013, 2014 Canonical, Ltd.
3 *
3 *
4 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
5 * it under the terms of the GNU General Public License as published by
@@ -38,6 +38,7 @@ Scope::Scope(QString const& id, QString const& name, bool visible, QObject* pare
38 , m_isActive(false)
38 , m_isActive(false)
39 , m_categories(new Categories(this))
39 , m_categories(new Categories(this))
40 , m_results(new DeeListModel(this))
40 , m_results(new DeeListModel(this))
41+ , m_previewRendererName("preview-generic")
41{
42{
42 DeeModel* results_model = create_results_model(20, 300);
43 DeeModel* results_model = create_results_model(20, 300);
43 m_categories->setResultModel(results_model);
44 m_categories->setResultModel(results_model);
@@ -47,7 +48,7 @@ Scope::Scope(QString const& id, QString const& name, bool visible, QObject* pare
47 m_timer.setInterval(1000);
48 m_timer.setInterval(1000);
48 m_timer.setSingleShot(true);
49 m_timer.setSingleShot(true);
49 connect(&m_timer, &QTimer::timeout, [this]() {
50 connect(&m_timer, &QTimer::timeout, [this]() {
50− Preview *p = new Preview(this);
51+ Preview *p = new Preview(m_previewRendererName, this);
51 Q_EMIT previewReady(p);
52 Q_EMIT previewReady(p);
52 });
53 });
53}
54}
tests/mocks/Unity/fake_scope.h+3−1
@@ -1,5 +1,5 @@
1/*
1/*
2− * Copyright (C) 2013 Canonical, Ltd.
2+ * Copyright (C) 2013, 2014 Canonical, Ltd.
3 *
3 *
4 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
5 * it under the terms of the GNU General Public License as published by
@@ -116,6 +116,8 @@ protected:
116 bool m_searching;
116 bool m_searching;
117 bool m_isActive;
117 bool m_isActive;
118
118
119+ QString m_previewRendererName;
120+
119 Categories* m_categories;
121 Categories* m_categories;
120 DeeListModel* m_results;
122 DeeListModel* m_results;
121
123
tests/plugins/DashViews/CMakeLists.txt+12−15
@@ -40,22 +40,17 @@ qt5_use_modules(listviewwithpageheadertestsectionexternalmodelExec Test Core Qml
40target_link_libraries(listviewwithpageheadertestsectionexternalmodelExec ${Qt5Gui_LIBRARIES} ${Qt5Quick_LIBRARIES})
40target_link_libraries(listviewwithpageheadertestsectionexternalmodelExec ${Qt5Gui_LIBRARIES} ${Qt5Quick_LIBRARIES})
41add_custom_target(testlistviewwithpageheadersectionexternalmodel ${CMAKE_CURRENT_BINARY_DIR}/listviewwithpageheadertestsectionexternalmodelExec -o ${CMAKE_BINARY_DIR}/testlistviewwithpageheadersectionexternalmodel.xml,xunitxml -o -,txt)
41add_custom_target(testlistviewwithpageheadersectionexternalmodel ${CMAKE_CURRENT_BINARY_DIR}/listviewwithpageheadertestsectionexternalmodelExec -o ${CMAKE_BINARY_DIR}/testlistviewwithpageheadersectionexternalmodel.xml,xunitxml -o -,txt)
42
42
43−macro(add_journal_try_test FILENAME)
43+macro(add_dashview_try_test FILENAME TESTNAME)
44− # Capitalite the first letter for the test/try name targets
45− string(SUBSTRING ${FILENAME} 0 1 FIRST_LETTER)
46− string(TOUPPER ${FIRST_LETTER} FIRST_LETTER)
47− string(REGEX REPLACE "^.(.*)" "${FIRST_LETTER}\\1" CUSTOM_TARGET_NAME "${FILENAME}")
48−
49 add_executable(${FILENAME}testExec
44 add_executable(${FILENAME}testExec
50 ${FILENAME}test.cpp
45 ${FILENAME}test.cpp
51 ${CMAKE_CURRENT_SOURCE_DIR}/../../../plugins/DashViews/${FILENAME}.cpp
46 ${CMAKE_CURRENT_SOURCE_DIR}/../../../plugins/DashViews/${FILENAME}.cpp
52− ${CMAKE_CURRENT_SOURCE_DIR}/../../../plugins/DashViews/abstractjournal.cpp
47+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../plugins/DashViews/abstractdashview.cpp
53 )
48 )
54 qt5_use_modules(${FILENAME}testExec Test Core Qml)
49 qt5_use_modules(${FILENAME}testExec Test Core Qml)
55 target_link_libraries(${FILENAME}testExec ${Qt5Gui_LIBRARIES} ${Qt5Quick_LIBRARIES})
50 target_link_libraries(${FILENAME}testExec ${Qt5Gui_LIBRARIES} ${Qt5Quick_LIBRARIES})
56− add_custom_target(test${CUSTOM_TARGET_NAME}
51+ add_custom_target(test${TESTNAME}
57 ${CMAKE_CURRENT_BINARY_DIR}/${FILENAME}testExec
52 ${CMAKE_CURRENT_BINARY_DIR}/${FILENAME}testExec
58− -o ${CMAKE_BINARY_DIR}/test${CUSTOM_TARGET_NAME}.xml,xunitxml
53+ -o ${CMAKE_BINARY_DIR}/test${TESTNAME}.xml,xunitxml
59 -o -,txt
54 -o -,txt
60 DEPENDS ${FILENAME}testExec DashViews-qml
55 DEPENDS ${FILENAME}testExec DashViews-qml
61 )
56 )
@@ -63,18 +58,19 @@ macro(add_journal_try_test FILENAME)
63 add_executable(${FILENAME}tryExec
58 add_executable(${FILENAME}tryExec
64 ${FILENAME}try.cpp
59 ${FILENAME}try.cpp
65 ${CMAKE_CURRENT_SOURCE_DIR}/../../../plugins/DashViews/${FILENAME}.cpp
60 ${CMAKE_CURRENT_SOURCE_DIR}/../../../plugins/DashViews/${FILENAME}.cpp
66− ${CMAKE_CURRENT_SOURCE_DIR}/../../../plugins/DashViews/abstractjournal.cpp
61+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../plugins/DashViews/abstractdashview.cpp
67 )
62 )
68 qt5_use_modules(${FILENAME}tryExec Test Core Qml)
63 qt5_use_modules(${FILENAME}tryExec Test Core Qml)
69 target_link_libraries(${FILENAME}tryExec ${Qt5Gui_LIBRARIES} ${Qt5Quick_LIBRARIES})
64 target_link_libraries(${FILENAME}tryExec ${Qt5Gui_LIBRARIES} ${Qt5Quick_LIBRARIES})
70− add_custom_target(try${CUSTOM_TARGET_NAME}
65+ add_custom_target(try${TESTNAME}
71 ${CMAKE_CURRENT_BINARY_DIR}/${FILENAME}tryExec
66 ${CMAKE_CURRENT_BINARY_DIR}/${FILENAME}tryExec
72 DEPENDS ${FILENAME}tryExec DashViews-qml
67 DEPENDS ${FILENAME}tryExec DashViews-qml
73 )
68 )
74endmacro()
69endmacro()
75
70
76−add_journal_try_test(verticaljournal)
71+add_dashview_try_test(verticaljournal VerticalJournal)
77−add_journal_try_test(horizontaljournal)
72+add_dashview_try_test(horizontaljournal HorizontalJournal)
73+add_dashview_try_test(organicgrid OrganicGrid)
78
74
79set(qmltest_DEFAULT_NO_ADD_TEST TRUE)
75set(qmltest_DEFAULT_NO_ADD_TEST TRUE)
80add_qml_test(. listviewwithpageheaderqml IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins)
76add_qml_test(. listviewwithpageheaderqml IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins)
@@ -83,5 +79,6 @@ add_dependencies(qmluitests testlistviewwithpageheader)
83add_dependencies(qmluitests testlistviewwithpageheadersection)
79add_dependencies(qmluitests testlistviewwithpageheadersection)
84add_dependencies(qmluitests testlistviewwithpageheadersectionexternalmodel)
80add_dependencies(qmluitests testlistviewwithpageheadersectionexternalmodel)
85add_dependencies(qmluitests testlistviewwithpageheaderqml)
81add_dependencies(qmluitests testlistviewwithpageheaderqml)
86−add_dependencies(qmluitests testVerticaljournal)
82+add_dependencies(qmluitests testVerticalJournal)
87−add_dependencies(qmluitests testHorizontaljournal)
83+add_dependencies(qmluitests testHorizontalJournal)
84+add_dependencies(qmluitests testOrganicGrid)
tests/plugins/DashViews/horizontaljournaltest.cpp+35−9
@@ -126,9 +126,9 @@ private Q_SLOTS:
126 view->engine()->addImportPath(BUILT_PLUGINS_DIR);
126 view->engine()->addImportPath(BUILT_PLUGINS_DIR);
127
127
128 model = new WidthModel();
128 model = new WidthModel();
129− QStringList heightList;
129+ QStringList widthList;
130− heightList << "100" << "50" << "125" << "10" << "40" << "70" << "200" << "110" << "160" << "20" << "20" << "65" << "80" << "200" << "300" << "130" << "400" << "300" << "500" << "10";
130+ widthList << "100" << "50" << "125" << "10" << "40" << "70" << "200" << "110" << "160" << "20" << "20" << "65" << "80" << "200" << "300" << "130" << "400" << "300" << "500" << "10";
131− model->setStringList(heightList);
131+ model->setStringList(widthList);
132
132
133 view->setSource(QUrl::fromLocalFile(DASHVIEWSTEST_FOLDER "/horizontaljournaltest.qml"));
133 view->setSource(QUrl::fromLocalFile(DASHVIEWSTEST_FOLDER "/horizontaljournaltest.qml"));
134
134
@@ -336,9 +336,9 @@ private Q_SLOTS:
336
336
337 void testModelReset()
337 void testModelReset()
338 {
338 {
339− QStringList heightList;
339+ QStringList widthList;
340− heightList << "100" << "50" << "125" << "25" << "50" << "50";
340+ widthList << "100" << "50" << "125" << "25" << "50" << "50";
341− model->setStringList(heightList);
341+ model->setStringList(widthList);
342
342
343 QTRY_COMPARE(hj->m_firstVisibleIndex, 0);
343 QTRY_COMPARE(hj->m_firstVisibleIndex, 0);
344 QTRY_COMPARE(hj->m_visibleItems.count(), 6);
344 QTRY_COMPARE(hj->m_visibleItems.count(), 6);
@@ -386,9 +386,9 @@ private Q_SLOTS:
386 void testModelAppendRemoveLast()
386 void testModelAppendRemoveLast()
387 {
387 {
388 WidthModel *model2 = new WidthModel();
388 WidthModel *model2 = new WidthModel();
389− QStringList heightList;
389+ QStringList widthList;
390− heightList << "100" << "50" << "125" << "25" << "50" << "50";
390+ widthList << "100" << "50" << "125" << "25" << "50" << "50";
391− model2->setStringList(heightList);
391+ model2->setStringList(widthList);
392 hj->setModel(model2);
392 hj->setModel(model2);
393 delete model;
393 delete model;
394 model = model2;
394 model = model2;
@@ -454,6 +454,32 @@ private Q_SLOTS:
454 QCOMPARE(hj->implicitHeight(), 310.);
454 QCOMPARE(hj->implicitHeight(), 310.);
455 }
455 }
456
456
457+ void testNegativeHeight()
458+ {
459+ QQuickItemPrivate::get(hj)->anchors()->resetFill();
460+ hj->setHeight(-8);
461+
462+ QStringList widthList;
463+ widthList << "100" << "50" << "125" << "25" << "50" << "50";
464+ model->setStringList(widthList);
465+
466+ QTRY_COMPARE(hj->m_visibleItems.count(), 0);
467+ QTRY_COMPARE(hj->implicitHeight(), 0.);
468+ }
469+
470+ void testNegativeDelegateCreationRange()
471+ {
472+ hj->setDelegateCreationBegin(0);
473+ hj->setDelegateCreationEnd(-100);
474+
475+ QStringList widthList;
476+ widthList << "100" << "50" << "50" << "30";
477+ model->setStringList(widthList);
478+
479+ QTRY_COMPARE(hj->m_visibleItems.count(), 0);
480+ QTRY_COMPARE(hj->implicitHeight(), 0.);
481+ }
482+
457private:
483private:
458 QQuickView *view;
484 QQuickView *view;
459 HorizontalJournal *hj;
485 HorizontalJournal *hj;
tests/plugins/DashViews/organicgridtest.cppnew file+531
@@ -0,0 +1,531 @@
1+/*
2+ * Copyright (C) 2014 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#include <QQuickView>
18+#include <QtTestGui>
19+#include <QDebug>
20+#include <QGuiApplication>
21+#include <QQuickView>
22+#include <QtQml/qqml.h>
23+#include <QStringListModel>
24+#include <QQmlContext>
25+#include <QQmlEngine>
26+#pragma GCC diagnostic push
27+#pragma GCC diagnostic ignored "-pedantic"
28+#include <private/qquickitem_p.h>
29+#pragma GCC diagnostic pop
30+
31+#include "organicgrid.h"
32+
33+class DummyModel : public QAbstractListModel {
34+public:
35+ DummyModel() : m_count(0) {}
36+
37+ int rowCount(const QModelIndex & /*parent*/) const
38+ {
39+ return m_count;
40+ }
41+
42+ QVariant data(const QModelIndex & /*index*/, int /*role*/) const
43+ {
44+ return QVariant();
45+ }
46+
47+ void setCount(int count)
48+ {
49+ beginResetModel();
50+ m_count = count;
51+ endResetModel();
52+ }
53+
54+ void addItem()
55+ {
56+ beginInsertRows(QModelIndex(), m_count, m_count);
57+ m_count++;
58+ endInsertRows();
59+ }
60+
61+ void removeLast()
62+ {
63+ beginRemoveRows(QModelIndex(), m_count - 1, m_count - 1);
64+ m_count--;
65+ endRemoveRows();
66+ }
67+
68+private:
69+ int m_count;
70+};
71+
72+class OrganicGridTest : public QObject
73+{
74+ Q_OBJECT
75+
76+private:
77+ void verifyItem(const QQuickItem *item, int modelIndex, qreal x, qreal y, bool visible)
78+ {
79+ QTRY_COMPARE(item->x(), x);
80+ QTRY_COMPARE(item->y(), y);
81+ QTRY_COMPARE(QQuickItemPrivate::get(item)->culled, !visible);
82+ const int inModuleIndex = modelIndex % 6;
83+ if (inModuleIndex == 0 || inModuleIndex == 1 || inModuleIndex == 3 || inModuleIndex == 5) {
84+ QTRY_COMPARE(item->height(), grid->smallDelegateSize().height());
85+ QTRY_COMPARE(item->width(), grid->smallDelegateSize().width());
86+ } else {
87+ QTRY_COMPARE(item->height(), grid->bigDelegateSize().height());
88+ QTRY_COMPARE(item->width(), grid->bigDelegateSize().width());
89+ }
90+ }
91+
92+ void checkInitialPositions()
93+ {
94+ QTRY_COMPARE(grid->m_visibleItems.count(), 18);
95+ QTRY_COMPARE(grid->m_firstVisibleIndex, 0);
96+ QTRY_COMPARE(grid->m_numberOfModulesPerRow, 1);
97+ verifyItem(grid->m_visibleItems[ 0], 0, 0, 0, true);
98+ verifyItem(grid->m_visibleItems[ 1], 1, 100, 0, true);
99+ verifyItem(grid->m_visibleItems[ 2], 2, 0, 100, true);
100+ verifyItem(grid->m_visibleItems[ 3], 3, 190, 190, true);
101+ verifyItem(grid->m_visibleItems[ 4], 4, 200, 0, true);
102+ verifyItem(grid->m_visibleItems[ 5], 5, 290, 190, true);
103+ verifyItem(grid->m_visibleItems[ 6], 6, 0, 290, true);
104+ verifyItem(grid->m_visibleItems[ 7], 7, 100, 290, true);
105+ verifyItem(grid->m_visibleItems[ 8], 8, 0, 390, true);
106+ verifyItem(grid->m_visibleItems[ 9], 9, 190, 480, false);
107+ verifyItem(grid->m_visibleItems[10], 10, 200, 290, true);
108+ verifyItem(grid->m_visibleItems[11], 11, 290, 480, false);
109+ verifyItem(grid->m_visibleItems[12], 12, 0, 580, false);
110+ verifyItem(grid->m_visibleItems[13], 13, 100, 580, false);
111+ verifyItem(grid->m_visibleItems[14], 14, 0, 680, false);
112+ verifyItem(grid->m_visibleItems[15], 15, 190, 770, false);
113+ verifyItem(grid->m_visibleItems[16], 16, 200, 580, false);
114+ verifyItem(grid->m_visibleItems[17], 17, 290, 770, false);
115+ checkImplicitHeight(1150);
116+ }
117+
118+ void checkImplicitHeight(qreal implicitHeight)
119+ {
120+ QTRY_COMPARE(grid->m_implicitHeightDirty, false);
121+ QCOMPARE(grid->implicitHeight(), implicitHeight);
122+ }
123+
124+private Q_SLOTS:
125+ void init()
126+ {
127+ view = new QQuickView();
128+ view->setResizeMode(QQuickView::SizeRootObjectToView);
129+ view->engine()->addImportPath(BUILT_PLUGINS_DIR);
130+
131+ model = new DummyModel();
132+ model->setCount(21);
133+
134+ view->setSource(QUrl::fromLocalFile(DASHVIEWSTEST_FOLDER "/organicgridtest.qml"));
135+
136+ view->show();
137+ view->resize(470, 400);
138+ QTest::qWaitForWindowExposed(view);
139+
140+ grid = dynamic_cast<OrganicGrid*>(view->rootObject()->findChild<QObject*>("grid"));
141+ grid->setModel(model);
142+
143+ checkInitialPositions();
144+ }
145+
146+ void cleanup()
147+ {
148+ delete view;
149+ delete model;
150+ }
151+
152+ void testInitialPosition()
153+ {
154+ }
155+
156+ void testWidthResize()
157+ {
158+ view->resize(770, 400);
159+ QTRY_COMPARE(grid->width(), 770.);
160+
161+ QTRY_COMPARE(grid->m_visibleItems.count(), 21);
162+ QTRY_COMPARE(grid->m_firstVisibleIndex, 0);
163+ QTRY_COMPARE(grid->m_numberOfModulesPerRow, 2);
164+ verifyItem(grid->m_visibleItems[ 0], 0, 0, 0, true);
165+ verifyItem(grid->m_visibleItems[ 1], 1, 100, 0, true);
166+ verifyItem(grid->m_visibleItems[ 2], 2, 0, 100, true);
167+ verifyItem(grid->m_visibleItems[ 3], 3, 190, 190, true);
168+ verifyItem(grid->m_visibleItems[ 4], 4, 200, 0, true);
169+ verifyItem(grid->m_visibleItems[ 5], 5, 290, 190, true);
170+
171+ verifyItem(grid->m_visibleItems[ 6], 6, 390, 0, true);
172+ verifyItem(grid->m_visibleItems[ 7], 7, 490, 0, true);
173+ verifyItem(grid->m_visibleItems[ 8], 8, 390, 100, true);
174+ verifyItem(grid->m_visibleItems[ 9], 9, 580, 190, true);
175+ verifyItem(grid->m_visibleItems[10], 10, 590, 0, true);
176+ verifyItem(grid->m_visibleItems[11], 11, 680, 190, true);
177+
178+ verifyItem(grid->m_visibleItems[12], 12, 0, 290, true);
179+ verifyItem(grid->m_visibleItems[13], 13, 100, 290, true);
180+ verifyItem(grid->m_visibleItems[14], 14, 0, 390, true);
181+ verifyItem(grid->m_visibleItems[15], 15, 190, 480, false);
182+ verifyItem(grid->m_visibleItems[16], 16, 200, 290, true);
183+ verifyItem(grid->m_visibleItems[17], 17, 290, 480, false);
184+
185+ verifyItem(grid->m_visibleItems[18], 18, 390, 290, true);
186+ verifyItem(grid->m_visibleItems[19], 19, 490, 290, true);
187+ verifyItem(grid->m_visibleItems[20], 20, 390, 390, true);
188+
189+ checkImplicitHeight(570);
190+
191+ view->resize(769, 400);
192+
193+ // This is exactly the same block as the first again
194+ checkInitialPositions();
195+ }
196+
197+ void testColumnSpacing()
198+ {
199+ grid->setColumnSpacing(11);
200+
201+ QTRY_COMPARE(grid->m_needsRelayout, false);
202+ QTRY_COMPARE(grid->m_visibleItems.count(), 18);
203+ QTRY_COMPARE(grid->m_firstVisibleIndex, 0);
204+ QTRY_COMPARE(grid->m_numberOfModulesPerRow, 1);
205+ verifyItem(grid->m_visibleItems[ 0], 0, 0, 0, true);
206+ verifyItem(grid->m_visibleItems[ 1], 1, 101, 0, true);
207+ verifyItem(grid->m_visibleItems[ 2], 2, 0, 100, true);
208+ verifyItem(grid->m_visibleItems[ 3], 3, 191, 190, true);
209+ verifyItem(grid->m_visibleItems[ 4], 4, 202, 0, true);
210+ verifyItem(grid->m_visibleItems[ 5], 5, 292, 190, true);
211+ verifyItem(grid->m_visibleItems[ 6], 6, 0, 290, true);
212+ verifyItem(grid->m_visibleItems[ 7], 7, 101, 290, true);
213+ verifyItem(grid->m_visibleItems[ 8], 8, 0, 390, true);
214+ verifyItem(grid->m_visibleItems[ 9], 9, 191, 480, false);
215+ verifyItem(grid->m_visibleItems[10], 10, 202, 290, true);
216+ verifyItem(grid->m_visibleItems[11], 11, 292, 480, false);
217+ verifyItem(grid->m_visibleItems[12], 12, 0, 580, false);
218+ verifyItem(grid->m_visibleItems[13], 13, 101, 580, false);
219+ verifyItem(grid->m_visibleItems[14], 14, 0, 680, false);
220+ verifyItem(grid->m_visibleItems[15], 15, 191, 770, false);
221+ verifyItem(grid->m_visibleItems[16], 16, 202, 580, false);
222+ verifyItem(grid->m_visibleItems[17], 17, 292, 770, false);
223+ checkImplicitHeight(1150);
224+
225+ grid->setColumnSpacing(10);
226+ QTRY_COMPARE(grid->m_needsRelayout, false);
227+
228+ // This is exactly the same block as the first again
229+ checkInitialPositions();
230+ }
231+
232+ void testRowSpacing()
233+ {
234+ grid->setRowSpacing(11);
235+
236+ QTRY_COMPARE(grid->m_needsRelayout, false);
237+ QTRY_COMPARE(grid->m_visibleItems.count(), 18);
238+ QTRY_COMPARE(grid->m_firstVisibleIndex, 0);
239+ QTRY_COMPARE(grid->m_numberOfModulesPerRow, 1);
240+ verifyItem(grid->m_visibleItems[ 0], 0, 0, 0, true);
241+ verifyItem(grid->m_visibleItems[ 1], 1, 100, 0, true);
242+ verifyItem(grid->m_visibleItems[ 2], 2, 0, 101, true);
243+ verifyItem(grid->m_visibleItems[ 3], 3, 190, 191, true);
244+ verifyItem(grid->m_visibleItems[ 4], 4, 200, 0, true);
245+ verifyItem(grid->m_visibleItems[ 5], 5, 290, 191, true);
246+ verifyItem(grid->m_visibleItems[ 6], 6, 0, 292, true);
247+ verifyItem(grid->m_visibleItems[ 7], 7, 100, 292, true);
248+ verifyItem(grid->m_visibleItems[ 8], 8, 0, 393, true);
249+ verifyItem(grid->m_visibleItems[ 9], 9, 190, 483, false);
250+ verifyItem(grid->m_visibleItems[10], 10, 200, 292, true);
251+ verifyItem(grid->m_visibleItems[11], 11, 290, 483, false);
252+ verifyItem(grid->m_visibleItems[12], 12, 0, 584, false);
253+ verifyItem(grid->m_visibleItems[13], 13, 100, 584, false);
254+ verifyItem(grid->m_visibleItems[14], 14, 0, 685, false);
255+ verifyItem(grid->m_visibleItems[15], 15, 190, 775, false);
256+ verifyItem(grid->m_visibleItems[16], 16, 200, 584, false);
257+ verifyItem(grid->m_visibleItems[17], 17, 290, 775, false);
258+ checkImplicitHeight(1157);
259+
260+ grid->setRowSpacing(10);
261+ QTRY_COMPARE(grid->m_needsRelayout, false);
262+
263+ // This is exactly the same block as the first again
264+ checkInitialPositions();
265+ }
266+
267+ void testDelegateSizeChange()
268+ {
269+ grid->setSmallDelegateSize(QSizeF(30, 30));
270+ grid->setBigDelegateSize(QSizeF(50, 50));
271+ QTRY_COMPARE(grid->m_firstVisibleIndex, 0);
272+ QTRY_COMPARE(grid->m_visibleItems.count(), 21);
273+ verifyItem(grid->m_visibleItems[ 0], 0, 0, 0, true);
274+ verifyItem(grid->m_visibleItems[ 1], 1, 40, 0, true);
275+ verifyItem(grid->m_visibleItems[ 2], 2, 0, 40, true);
276+ verifyItem(grid->m_visibleItems[ 3], 3, 60, 60, true);
277+ verifyItem(grid->m_visibleItems[ 4], 4, 80, 0, true);
278+ verifyItem(grid->m_visibleItems[ 5], 5, 100, 60, true);
279+
280+ verifyItem(grid->m_visibleItems[ 6], 6, 140, 0, true);
281+ verifyItem(grid->m_visibleItems[ 7], 7, 180, 0, true);
282+ verifyItem(grid->m_visibleItems[ 8], 8, 140, 40, true);
283+ verifyItem(grid->m_visibleItems[ 9], 9, 200, 60, true);
284+ verifyItem(grid->m_visibleItems[10], 10, 220, 0, true);
285+ verifyItem(grid->m_visibleItems[11], 11, 240, 60, true);
286+
287+ verifyItem(grid->m_visibleItems[12], 12, 280, 0, true);
288+ verifyItem(grid->m_visibleItems[13], 13, 320, 0, true);
289+ verifyItem(grid->m_visibleItems[14], 14, 280, 40, true);
290+ verifyItem(grid->m_visibleItems[15], 15, 340, 60, true);
291+ verifyItem(grid->m_visibleItems[16], 16, 360, 0, true);
292+ verifyItem(grid->m_visibleItems[17], 17, 380, 60, true);
293+
294+ verifyItem(grid->m_visibleItems[18], 18, 0, 100, true);
295+ verifyItem(grid->m_visibleItems[19], 19, 40, 100, true);
296+ verifyItem(grid->m_visibleItems[20], 20, 0, 140, true);
297+ checkImplicitHeight(190);
298+
299+ grid->setSmallDelegateSize(QSizeF(90, 90));
300+ grid->setBigDelegateSize(QSizeF(180, 180));
301+
302+ // This is exactly the same block as the first again
303+ checkInitialPositions();
304+ }
305+
306+ void testChangeModel()
307+ {
308+ DummyModel *model2 = new DummyModel();
309+ model2->setCount(6);
310+ grid->setModel(model2);
311+ delete model;
312+ model = model2;
313+
314+ QTRY_COMPARE(grid->m_firstVisibleIndex, 0);
315+ QTRY_COMPARE(grid->m_visibleItems.count(), 6);
316+ verifyItem(grid->m_visibleItems[ 0], 0, 0, 0, true);
317+ verifyItem(grid->m_visibleItems[ 1], 1, 100, 0, true);
318+ verifyItem(grid->m_visibleItems[ 2], 2, 0, 100, true);
319+ verifyItem(grid->m_visibleItems[ 3], 3, 190, 190, true);
320+ verifyItem(grid->m_visibleItems[ 4], 4, 200, 0, true);
321+ verifyItem(grid->m_visibleItems[ 5], 5, 290, 190, true);
322+ checkImplicitHeight(280);
323+ }
324+
325+ void testModelReset()
326+ {
327+ model->setCount(6);
328+
329+ QTRY_COMPARE(grid->m_firstVisibleIndex, 0);
330+ QTRY_COMPARE(grid->m_visibleItems.count(), 6);
331+ verifyItem(grid->m_visibleItems[ 0], 0, 0, 0, true);
332+ verifyItem(grid->m_visibleItems[ 1], 1, 100, 0, true);
333+ verifyItem(grid->m_visibleItems[ 2], 2, 0, 100, true);
334+ verifyItem(grid->m_visibleItems[ 3], 3, 190, 190, true);
335+ verifyItem(grid->m_visibleItems[ 4], 4, 200, 0, true);
336+ verifyItem(grid->m_visibleItems[ 5], 5, 290, 190, true);
337+ checkImplicitHeight(280);
338+ }
339+
340+ void testModelRemoveLastNonVisible()
341+ {
342+ model->removeLast();
343+
344+ // This is the same than checkInitialPositions but
345+ // with a different implicitHeight since there's an item less
346+ // in the model
347+ QTRY_COMPARE(grid->m_visibleItems.count(), 18);
348+ QTRY_COMPARE(grid->m_firstVisibleIndex, 0);
349+ QTRY_COMPARE(grid->m_numberOfModulesPerRow, 1);
350+ verifyItem(grid->m_visibleItems[ 0], 0, 0, 0, true);
351+ verifyItem(grid->m_visibleItems[ 1], 1, 100, 0, true);
352+ verifyItem(grid->m_visibleItems[ 2], 2, 0, 100, true);
353+ verifyItem(grid->m_visibleItems[ 3], 3, 190, 190, true);
354+ verifyItem(grid->m_visibleItems[ 4], 4, 200, 0, true);
355+ verifyItem(grid->m_visibleItems[ 5], 5, 290, 190, true);
356+ verifyItem(grid->m_visibleItems[ 6], 6, 0, 290, true);
357+ verifyItem(grid->m_visibleItems[ 7], 7, 100, 290, true);
358+ verifyItem(grid->m_visibleItems[ 8], 8, 0, 390, true);
359+ verifyItem(grid->m_visibleItems[ 9], 9, 190, 480, false);
360+ verifyItem(grid->m_visibleItems[10], 10, 200, 290, true);
361+ verifyItem(grid->m_visibleItems[11], 11, 290, 480, false);
362+ verifyItem(grid->m_visibleItems[12], 12, 0, 580, false);
363+ verifyItem(grid->m_visibleItems[13], 13, 100, 580, false);
364+ verifyItem(grid->m_visibleItems[14], 14, 0, 680, false);
365+ verifyItem(grid->m_visibleItems[15], 15, 190, 770, false);
366+ verifyItem(grid->m_visibleItems[16], 16, 200, 580, false);
367+ verifyItem(grid->m_visibleItems[17], 17, 290, 770, false);
368+ checkImplicitHeight(960);
369+
370+ model->removeLast();
371+
372+ // Removing this one didn't cause any change since it only
373+ // was the second item of a non visible 6-module
374+ QTRY_COMPARE(grid->m_visibleItems.count(), 18);
375+ QTRY_COMPARE(grid->m_firstVisibleIndex, 0);
376+ QTRY_COMPARE(grid->m_numberOfModulesPerRow, 1);
377+ verifyItem(grid->m_visibleItems[ 0], 0, 0, 0, true);
378+ verifyItem(grid->m_visibleItems[ 1], 1, 100, 0, true);
379+ verifyItem(grid->m_visibleItems[ 2], 2, 0, 100, true);
380+ verifyItem(grid->m_visibleItems[ 3], 3, 190, 190, true);
381+ verifyItem(grid->m_visibleItems[ 4], 4, 200, 0, true);
382+ verifyItem(grid->m_visibleItems[ 5], 5, 290, 190, true);
383+ verifyItem(grid->m_visibleItems[ 6], 6, 0, 290, true);
384+ verifyItem(grid->m_visibleItems[ 7], 7, 100, 290, true);
385+ verifyItem(grid->m_visibleItems[ 8], 8, 0, 390, true);
386+ verifyItem(grid->m_visibleItems[ 9], 9, 190, 480, false);
387+ verifyItem(grid->m_visibleItems[10], 10, 200, 290, true);
388+ verifyItem(grid->m_visibleItems[11], 11, 290, 480, false);
389+ verifyItem(grid->m_visibleItems[12], 12, 0, 580, false);
390+ verifyItem(grid->m_visibleItems[13], 13, 100, 580, false);
391+ verifyItem(grid->m_visibleItems[14], 14, 0, 680, false);
392+ verifyItem(grid->m_visibleItems[15], 15, 190, 770, false);
393+ verifyItem(grid->m_visibleItems[16], 16, 200, 580, false);
394+ verifyItem(grid->m_visibleItems[17], 17, 290, 770, false);
395+ checkImplicitHeight(960);
396+
397+ model->removeLast();
398+
399+ // Removing this one removes the first of a 6-module so
400+ // it does change height again
401+ QTRY_COMPARE(grid->m_visibleItems.count(), 18);
402+ QTRY_COMPARE(grid->m_firstVisibleIndex, 0);
403+ QTRY_COMPARE(grid->m_numberOfModulesPerRow, 1);
404+ verifyItem(grid->m_visibleItems[ 0], 0, 0, 0, true);
405+ verifyItem(grid->m_visibleItems[ 1], 1, 100, 0, true);
406+ verifyItem(grid->m_visibleItems[ 2], 2, 0, 100, true);
407+ verifyItem(grid->m_visibleItems[ 3], 3, 190, 190, true);
408+ verifyItem(grid->m_visibleItems[ 4], 4, 200, 0, true);
409+ verifyItem(grid->m_visibleItems[ 5], 5, 290, 190, true);
410+ verifyItem(grid->m_visibleItems[ 6], 6, 0, 290, true);
411+ verifyItem(grid->m_visibleItems[ 7], 7, 100, 290, true);
412+ verifyItem(grid->m_visibleItems[ 8], 8, 0, 390, true);
413+ verifyItem(grid->m_visibleItems[ 9], 9, 190, 480, false);
414+ verifyItem(grid->m_visibleItems[10], 10, 200, 290, true);
415+ verifyItem(grid->m_visibleItems[11], 11, 290, 480, false);
416+ verifyItem(grid->m_visibleItems[12], 12, 0, 580, false);
417+ verifyItem(grid->m_visibleItems[13], 13, 100, 580, false);
418+ verifyItem(grid->m_visibleItems[14], 14, 0, 680, false);
419+ verifyItem(grid->m_visibleItems[15], 15, 190, 770, false);
420+ verifyItem(grid->m_visibleItems[16], 16, 200, 580, false);
421+ verifyItem(grid->m_visibleItems[17], 17, 290, 770, false);
422+ checkImplicitHeight(860);
423+
424+ }
425+
426+ void testModelAppendRemoveLast()
427+ {
428+ DummyModel *model2 = new DummyModel();
429+ model2->setCount(6);
430+ grid->setModel(model2);
431+ delete model;
432+ model = model2;
433+
434+ QTRY_COMPARE(grid->m_firstVisibleIndex, 0);
435+ QTRY_COMPARE(grid->m_visibleItems.count(), 6);
436+ verifyItem(grid->m_visibleItems[0], 0, 0, 0, true);
437+ verifyItem(grid->m_visibleItems[1], 1, 100, 0, true);
438+ verifyItem(grid->m_visibleItems[2], 2, 0, 100, true);
439+ verifyItem(grid->m_visibleItems[3], 3, 190, 190, true);
440+ verifyItem(grid->m_visibleItems[4], 4, 200, 0, true);
441+ verifyItem(grid->m_visibleItems[5], 5, 290, 190, true);
442+ checkImplicitHeight(280);
443+
444+ model2->addItem();
445+
446+ QTRY_COMPARE(grid->m_firstVisibleIndex, 0);
447+ QTRY_COMPARE(grid->m_visibleItems.count(), 7);
448+ verifyItem(grid->m_visibleItems[0], 0, 0, 0, true);
449+ verifyItem(grid->m_visibleItems[1], 1, 100, 0, true);
450+ verifyItem(grid->m_visibleItems[2], 2, 0, 100, true);
451+ verifyItem(grid->m_visibleItems[3], 3, 190, 190, true);
452+ verifyItem(grid->m_visibleItems[4], 4, 200, 0, true);
453+ verifyItem(grid->m_visibleItems[5], 5, 290, 190, true);
454+ verifyItem(grid->m_visibleItems[6], 6, 0, 290, true);
455+ checkImplicitHeight(380);
456+
457+ model2->addItem();
458+ model2->addItem();
459+
460+ QTRY_COMPARE(grid->m_firstVisibleIndex, 0);
461+ QTRY_COMPARE(grid->m_visibleItems.count(), 9);
462+ verifyItem(grid->m_visibleItems[0], 0, 0, 0, true);
463+ verifyItem(grid->m_visibleItems[1], 1, 100, 0, true);
464+ verifyItem(grid->m_visibleItems[2], 2, 0, 100, true);
465+ verifyItem(grid->m_visibleItems[3], 3, 190, 190, true);
466+ verifyItem(grid->m_visibleItems[4], 4, 200, 0, true);
467+ verifyItem(grid->m_visibleItems[5], 5, 290, 190, true);
468+ verifyItem(grid->m_visibleItems[6], 6, 0, 290, true);
469+ verifyItem(grid->m_visibleItems[7], 7, 100, 290, true);
470+ verifyItem(grid->m_visibleItems[8], 8, 0, 390, true);
471+ checkImplicitHeight(570);
472+
473+ model2->removeLast();
474+
475+ QTRY_COMPARE(grid->m_firstVisibleIndex, 0);
476+ QTRY_COMPARE(grid->m_visibleItems.count(), 8);
477+ verifyItem(grid->m_visibleItems[0], 0, 0, 0, true);
478+ verifyItem(grid->m_visibleItems[1], 1, 100, 0, true);
479+ verifyItem(grid->m_visibleItems[2], 2, 0, 100, true);
480+ verifyItem(grid->m_visibleItems[3], 3, 190, 190, true);
481+ verifyItem(grid->m_visibleItems[4], 4, 200, 0, true);
482+ verifyItem(grid->m_visibleItems[5], 5, 290, 190, true);
483+ verifyItem(grid->m_visibleItems[6], 6, 0, 290, true);
484+ verifyItem(grid->m_visibleItems[7], 7, 100, 290, true);
485+ checkImplicitHeight(380);
486+ }
487+
488+ void testDelegateCreationRanges()
489+ {
490+ grid->setSmallDelegateSize(QSizeF(30, 30));
491+ grid->setBigDelegateSize(QSizeF(50, 50));
492+ model->setCount(400);
493+ checkImplicitHeight(2290);
494+
495+ view->resize(470, 700);
496+ QTRY_COMPARE(grid->height(), 700.);
497+ checkImplicitHeight(2290);
498+ QTRY_COMPARE(grid->m_firstVisibleIndex, 0);
499+ QTRY_COMPARE(grid->m_visibleItems.count(), 198);
500+
501+ grid->setDelegateCreationBegin(300);
502+ grid->setDelegateCreationEnd(400);
503+ checkImplicitHeight(2290);
504+
505+ QTRY_COMPARE(grid->m_firstVisibleIndex, 36);
506+ QTRY_COMPARE(grid->m_visibleItems.count(), 54);
507+ checkImplicitHeight(2290);
508+
509+ grid->resetDelegateCreationBegin();
510+ grid->resetDelegateCreationEnd();
511+
512+ view->resize(470, 470);
513+
514+ grid->setSmallDelegateSize(QSizeF(90, 90));
515+ grid->setBigDelegateSize(QSizeF(180, 180));
516+
517+ model->setCount(21);
518+
519+ // This is exactly the same block as the first again
520+ checkInitialPositions();
521+ }
522+
523+private:
524+ QQuickView *view;
525+ OrganicGrid *grid;
526+ DummyModel *model;
527+};
528+
529+QTEST_MAIN(OrganicGridTest)
530+
531+#include "organicgridtest.moc"
tests/plugins/DashViews/organicgridtest.qmlnew file+43
@@ -0,0 +1,43 @@
1+/*
2+ * Copyright (C) 2014 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.1
18+import DashViews 0.1
19+
20+Item {
21+
22+ OrganicGrid {
23+ id: vj
24+ objectName: "grid"
25+ anchors.fill: parent
26+ columnSpacing: 10
27+ rowSpacing: 10
28+ smallDelegateSize: Qt.size(90, 90)
29+ bigDelegateSize: Qt.size(180, 180)
30+
31+ delegate: Rectangle {
32+ property real randomValue: Math.random()
33+ color: randomValue < 0.3 ? "green" : randomValue < 0.6 ? "blue" : "red";
34+ border.width: 3
35+
36+ Text {
37+ text: index
38+ x: 10
39+ y: 10
40+ }
41+ }
42+ }
43+}
tests/plugins/DashViews/organicgridtry.cppnew file+98
@@ -0,0 +1,98 @@
1+/*
2+ * Copyright (C) 2014 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#include <QQuickView>
18+#include <QDebug>
19+#include <QGuiApplication>
20+#include <QQuickView>
21+#include <QtQml/qqml.h>
22+#include <QStringListModel>
23+#include <QQmlContext>
24+#include <QQmlEngine>
25+#include <QGuiApplication>
26+
27+#include "verticaljournal.h"
28+
29+class DummyModel : public QAbstractListModel {
30+ Q_OBJECT
31+public:
32+ DummyModel() : m_count(0) {}
33+
34+ int rowCount(const QModelIndex & /*parent*/) const
35+ {
36+ return m_count;
37+ }
38+
39+ QVariant data(const QModelIndex & /*index*/, int /*role*/) const
40+ {
41+ return QVariant();
42+ }
43+
44+ void setCount(int count)
45+ {
46+ beginResetModel();
47+ m_count = count;
48+ endResetModel();
49+ }
50+
51+public slots:
52+ void addItem()
53+ {
54+ beginInsertRows(QModelIndex(), m_count, m_count);
55+ m_count++;
56+ endInsertRows();
57+ }
58+
59+ void removeLast()
60+ {
61+ beginRemoveRows(QModelIndex(), m_count - 1, m_count - 1);
62+ m_count--;
63+ endRemoveRows();
64+ }
65+
66+private:
67+ int m_count;
68+};
69+
70+int main(int argc, char *argv[])
71+{
72+ QGuiApplication a(argc, argv);
73+
74+ QQuickView *view = new QQuickView();
75+ view->setResizeMode(QQuickView::SizeRootObjectToView);
76+ view->engine()->addImportPath(BUILT_PLUGINS_DIR);
77+
78+ DummyModel model;
79+ model.setCount(3);
80+
81+ QStringListModel listModel;
82+ listModel.setStringList(QStringList() << QString());
83+
84+ view->rootContext()->setContextProperty("listModel", &listModel);
85+ view->rootContext()->setContextProperty("gridModel", &model);
86+
87+ view->setSource(QUrl::fromLocalFile(DASHVIEWSTEST_FOLDER "/organicgridtry.qml"));
88+
89+ view->show();
90+ view->resize(530, 400);
91+
92+ QObject::connect(view->rootObject(), SIGNAL(add()), &model, SLOT(addItem()));
93+ QObject::connect(view->rootObject(), SIGNAL(remove()), &model, SLOT(removeLast()));
94+
95+ return a.exec();
96+}
97+
98+#include "organicgridtry.moc"
tests/plugins/DashViews/organicgridtry.qmlnew file+94
@@ -0,0 +1,94 @@
1+/*
2+ * Copyright (C) 2014 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.1
18+import DashViews 0.1
19+
20+Item {
21+ id: root
22+ signal add()
23+ signal remove()
24+
25+ ListViewWithPageHeader {
26+ id: lvwph
27+ model: listModel
28+ height: parent.height
29+ width: parent.width - controls.width
30+
31+ delegate: OrganicGrid {
32+ id: grid
33+ model: gridModel
34+ smallDelegateSize: Qt.size(90, 90)
35+ bigDelegateSize: Qt.size(180, 180)
36+ columnSpacing: 10
37+ rowSpacing: 10
38+ width: parent.width
39+ height: implicitHeight > 100 ? implicitHeight : 100
40+ delegateCreationBegin: lvwph.contentY
41+ delegateCreationEnd: lvwph.contentY + lvwph.height
42+
43+ delegate: Rectangle {
44+ width: 100
45+ color: "red";
46+ border.width: 3
47+
48+ Text {
49+ text: index
50+ x: 10
51+ y: 10
52+ }
53+ }
54+ }
55+ }
56+
57+ Rectangle {
58+ id: controls
59+ height: parent.height
60+ width: 100
61+ anchors.right: parent.right
62+ color: "gray"
63+ opacity: 0.4
64+
65+ Rectangle {
66+ id: addButton
67+ height: 50
68+ width: parent.width
69+ color: "blue"
70+ Text {
71+ text: "Add"
72+ anchors.centerIn: parent
73+ }
74+ MouseArea {
75+ anchors.fill: parent
76+ onClicked: root.add()
77+ }
78+ }
79+ Rectangle {
80+ anchors.top: addButton.bottom
81+ height: 50
82+ width: parent.width
83+ color: "red"
84+ Text {
85+ text: "Remove"
86+ anchors.centerIn: parent
87+ }
88+ MouseArea {
89+ anchors.fill: parent
90+ onClicked: root.remove()
91+ }
92+ }
93+ }
94+}
tests/plugins/DashViews/verticaljournaltest.cpp+32
@@ -459,6 +459,38 @@ private Q_SLOTS:
459 verifyItem(vj->m_columnVisibleItems[1][2], 7, 160, 120, true);
459 verifyItem(vj->m_columnVisibleItems[1][2], 7, 160, 120, true);
460 }
460 }
461
461
462+ void testNegativeHeight()
463+ {
464+ QQuickItemPrivate::get(vj)->anchors()->resetFill();
465+ vj->setHeight(-8);
466+
467+ QStringList heightList;
468+ heightList << "100" << "50" << "50" << "30";
469+ model->setStringList(heightList);
470+
471+ QTRY_COMPARE(vj->m_columnVisibleItems.count(), 3);
472+ QTRY_COMPARE(vj->m_columnVisibleItems[0].count(), 0);
473+ QTRY_COMPARE(vj->m_columnVisibleItems[1].count(), 0);
474+ QTRY_COMPARE(vj->m_columnVisibleItems[2].count(), 0);
475+ QTRY_COMPARE(vj->implicitHeight(), 0.);
476+ }
477+
478+ void testNegativeDelegateCreationRange()
479+ {
480+ vj->setDelegateCreationBegin(0);
481+ vj->setDelegateCreationEnd(-100);
482+
483+ QStringList heightList;
484+ heightList << "100" << "50" << "50" << "30";
485+ model->setStringList(heightList);
486+
487+ QTRY_COMPARE(vj->m_columnVisibleItems.count(), 3);
488+ QTRY_COMPARE(vj->m_columnVisibleItems[0].count(), 0);
489+ QTRY_COMPARE(vj->m_columnVisibleItems[1].count(), 0);
490+ QTRY_COMPARE(vj->m_columnVisibleItems[2].count(), 0);
491+ QTRY_COMPARE(vj->implicitHeight(), 0.);
492+ }
493+
462private:
494private:
463 QQuickView *view;
495 QQuickView *view;
464 VerticalJournal *vj;
496 VerticalJournal *vj;
tests/qmltests/tst_Shell.qml+4−4
@@ -69,17 +69,17 @@ Item {
69 var dashContentList = findChild(shell, "dashContentList");
69 var dashContentList = findChild(shell, "dashContentList");
70 waitForRendering(dashContentList);
70 waitForRendering(dashContentList);
71 var homeLoader = findChild(dashContentList, "home.scope loader");
71 var homeLoader = findChild(dashContentList, "home.scope loader");
72− ok = homeLoader !== undefined
72+ ok = homeLoader !== null
73 && homeLoader.item !== undefined;
73 && homeLoader.item !== undefined;
74
74
75 var dashHome = findChild(shell, "DashHome");
75 var dashHome = findChild(shell, "DashHome");
76− ok &= dashHome !== undefined;
76+ ok &= dashHome !== null;
77
77
78 var greeter = findChild(shell, "greeter");
78 var greeter = findChild(shell, "greeter");
79− ok &= greeter !== undefined;
79+ ok &= greeter !== null;
80
80
81 var launcherPanel = findChild(shell, "launcherPanel");
81 var launcherPanel = findChild(shell, "launcherPanel");
82− ok &= launcherPanel !== undefined;
82+ ok &= launcherPanel !== null;
83
83
84 attempts++;
84 attempts++;
85 if (!ok) {
85 if (!ok) {