on xenial help sign in
add missing files
commit9f6934ddd8f92978391a8e93205b9fb107191f3f authorMichael Zanetti <michael.zanetti@canonical.com> dateThu 3 Nov 2016, 13:38 (10 years ago) parentca5c299
12 files changed+732
plugins/Unity/Launcher/appdrawermodel.cpp+39 plugins/Unity/Launcher/appdrawermodel.h+17 plugins/Unity/Launcher/ualwrapper.cpp+48 plugins/Unity/Launcher/ualwrapper.h+18 plugins/Utils/appdrawerproxymodel.cpp+128 plugins/Utils/appdrawerproxymodel.h+58 qml/Launcher/BackgroundBlur.qml+68 qml/Launcher/Drawer.qml+213 qml/Launcher/DrawerGridView.qml+31 qml/Launcher/MoreAppsHeader.qml+41 tests/mocks/Unity/Launcher/MockAppDrawerModel.cpp+54 tests/mocks/Unity/Launcher/MockAppDrawerModel.h+17
plugins/Unity/Launcher/appdrawermodel.cppnew file+39
@@ -0,0 +1,39 @@
1+#include "appdrawermodel.h"
2+#include "ualwrapper.h"
3+
4+#include <QDebug>
5+
6+#include <ubuntu-app-launch/registry.h>
7+
8+AppDrawerModel::AppDrawerModel(QObject *parent):
9+ AppDrawerModelInterface(parent)
10+{
11+ Q_FOREACH (const QString &appId, UalWrapper::installedApps()) {
12+ UalWrapper::AppInfo info = UalWrapper::getApplicationInfo(appId);
13+ if (!info.valid) {
14+ qWarning() << "Failed to get app info for app" << appId;
15+ continue;
16+ }
17+ m_list.append(new LauncherItem(appId, info.name, info.icon, this));
18+ qDebug() << "added" << appId;
19+ }
20+}
21+
22+int AppDrawerModel::rowCount(const QModelIndex &parent) const
23+{
24+ return m_list.count();
25+}
26+
27+QVariant AppDrawerModel::data(const QModelIndex &index, int role) const
28+{
29+ switch (role) {
30+ case RoleAppId:
31+ return m_list.at(index.row())->appId();
32+ case RoleName:
33+ return m_list.at(index.row())->name();
34+ case RoleIcon:
35+ return m_list.at(index.row())->icon();
36+ }
37+
38+ return QVariant();
39+}
plugins/Unity/Launcher/appdrawermodel.hnew file+17
@@ -0,0 +1,17 @@
1+
2+#include <unity/shell/launcher/AppDrawerModelInterface.h>
3+
4+#include "launcheritem.h"
5+
6+class AppDrawerModel: public AppDrawerModelInterface
7+{
8+ Q_OBJECT
9+public:
10+ AppDrawerModel(QObject* parent = nullptr);
11+
12+ int rowCount(const QModelIndex &parent) const override;
13+ QVariant data(const QModelIndex &index, int role) const override;
14+
15+private:
16+ QList<LauncherItem*> m_list;
17+};
plugins/Unity/Launcher/ualwrapper.cppnew file+48
@@ -0,0 +1,48 @@
1+#include <QDebug>
2+
3+#include "ualwrapper.h"
4+
5+#include <ubuntu-app-launch/registry.h>
6+using namespace ubuntu::app_launch;
7+
8+UalWrapper::UalWrapper(QObject *parent):
9+ QObject(parent)
10+{
11+
12+}
13+
14+QStringList UalWrapper::installedApps()
15+{
16+ QStringList appIds;
17+ Registry::installedApps();
18+ for (std::shared_ptr<Application> app : Registry::installedApps()) {
19+ appIds << QString::fromStdString(app->appId().package) + "_" + QString::fromStdString(app->appId().appname);
20+ }
21+ return appIds;
22+}
23+
24+UalWrapper::AppInfo UalWrapper::getApplicationInfo(const QString &appId)
25+{
26+ AppInfo info;
27+
28+ AppID ualAppId = AppID::find(Registry::getDefault(), appId.toStdString());
29+ if (ualAppId.empty()) {
30+ return info;
31+ }
32+
33+ std::shared_ptr<Application> ualApp;
34+ try
35+ {
36+ ualApp = Application::create(ualAppId, Registry::getDefault());
37+ }
38+ catch (std::runtime_error &e)
39+ {
40+ qWarning() << "Couldn't find application info for" << appId << "-" << e.what();
41+ return info;
42+ }
43+
44+ info.valid = true;
45+ info.name = QString::fromStdString(ualApp->info()->name());
46+ info.icon = QString::fromStdString(ualApp->info()->iconPath());
47+ return info;
48+}
plugins/Unity/Launcher/ualwrapper.hnew file+18
@@ -0,0 +1,18 @@
1+#include <QObject>
2+
3+class UalWrapper: public QObject
4+{
5+ Q_OBJECT
6+public:
7+ struct AppInfo {
8+ bool valid = false;
9+ QString name;
10+ QString icon;
11+ };
12+
13+ UalWrapper(QObject* parent = nullptr);
14+
15+ static QStringList installedApps();
16+ static AppInfo getApplicationInfo(const QString &appId);
17+
18+};
plugins/Utils/appdrawerproxymodel.cppnew file+128
@@ -0,0 +1,128 @@
1+#include "appdrawerproxymodel.h"
2+
3+#include <QDebug>
4+
5+AppDrawerProxyModel::AppDrawerProxyModel(QObject *parent):
6+ QSortFilterProxyModel(parent)
7+{
8+ setSortRole(AppDrawerModelInterface::RoleName);
9+
10+ connect(this, &QAbstractListModel::rowsInserted, this, &AppDrawerProxyModel::countChanged);
11+ connect(this, &QAbstractListModel::rowsRemoved, this, &AppDrawerProxyModel::countChanged);
12+ connect(this, &QAbstractListModel::layoutChanged, this, &AppDrawerProxyModel::countChanged);
13+}
14+
15+QAbstractItemModel *AppDrawerProxyModel::source() const
16+{
17+ return m_source;
18+}
19+
20+void AppDrawerProxyModel::setSource(QAbstractItemModel *source)
21+{
22+ if (m_source != source) {
23+ m_source = source;
24+ setSourceModel(m_source);
25+ sort(0);
26+ connect(m_source, &QAbstractItemModel::rowsRemoved, this, &AppDrawerProxyModel::invalidateFilter);
27+ connect(m_source, &QAbstractItemModel::rowsInserted, this, &AppDrawerProxyModel::invalidateFilter);
28+ Q_EMIT sourceChanged();
29+ }
30+}
31+
32+AppDrawerProxyModel::GroupBy AppDrawerProxyModel::group() const
33+{
34+ return m_group;
35+}
36+
37+void AppDrawerProxyModel::setGroup(AppDrawerProxyModel::GroupBy group)
38+{
39+ if (m_group != group) {
40+ m_group = group;
41+ Q_EMIT groupChanged();
42+ invalidateFilter();
43+ }
44+}
45+
46+QString AppDrawerProxyModel::filterLetter() const
47+{
48+ return m_filterLetter;
49+}
50+
51+void AppDrawerProxyModel::setFilterLetter(const QString &filterLetter)
52+{
53+ if (m_filterLetter != filterLetter) {
54+ m_filterLetter = filterLetter;
55+ Q_EMIT filterLetterChanged();
56+ invalidateFilter();
57+ }
58+}
59+
60+QString AppDrawerProxyModel::filterString() const
61+{
62+ return m_filterString;
63+}
64+
65+void AppDrawerProxyModel::setFilterString(const QString &filterString)
66+{
67+ if (m_filterString != filterString) {
68+ m_filterString = filterString;
69+ Q_EMIT filterStringChanged();
70+ invalidateFilter();
71+ }
72+}
73+
74+int AppDrawerProxyModel::count() const
75+{
76+ return rowCount();
77+}
78+
79+QVariant AppDrawerProxyModel::data(const QModelIndex &index, int role) const
80+{
81+ QModelIndex idx = mapToSource(index);
82+ if (role == Qt::UserRole) {
83+ QString name = m_source->data(idx, AppDrawerModelInterface::RoleName).toString();
84+ return name.length() > 0 ? QString(name.at(0)) : QChar();
85+ }
86+ return m_source->data(idx, role);
87+}
88+
89+QHash<int, QByteArray> AppDrawerProxyModel::roleNames() const
90+{
91+ if (m_source) {
92+ QHash<int, QByteArray> roles = m_source->roleNames();
93+ roles.insert(Qt::UserRole, "letter");
94+ return roles;
95+ }
96+ return QHash<int, QByteArray>();
97+}
98+
99+bool AppDrawerProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
100+{
101+ Q_UNUSED(source_parent)
102+
103+ if (m_group == GroupByAToZ && source_row > 0) {
104+ QString currentName = m_source->data(m_source->index(source_row, 0), AppDrawerModelInterface::RoleName).toString();
105+ QChar currentLetter = currentName.length() > 0 ? currentName.at(0) : QChar();
106+ QString previousName = m_source->data(m_source->index(source_row - 1,0 ), AppDrawerModelInterface::RoleName).toString();
107+ QChar previousLetter = previousName.length() > 0 ? previousName.at(0) : QChar();
108+ if (currentLetter == previousLetter) {
109+ return false;
110+ }
111+ } else if(m_group == GroupByAll && source_row > 0) {
112+ return false;
113+ }
114+ if (!m_filterLetter.isEmpty()) {
115+ QString currentName = m_source->data(m_source->index(source_row, 0), AppDrawerModelInterface::RoleName).toString();
116+ QString currentLetter = currentName.length() > 0 ? QString(currentName.at(0)) : QString();
117+ if (currentLetter != m_filterLetter) {
118+ return false;
119+ }
120+ }
121+ if (!m_filterString.isEmpty()) {
122+ QString currentLabel = m_source->data(m_source->index(source_row, 0), AppDrawerModelInterface::RoleName).toString().toLower();
123+ if (!currentLabel.startsWith(m_filterString.toLower())) {
124+ return false;
125+ }
126+ }
127+ return true;
128+}
plugins/Utils/appdrawerproxymodel.hnew file+58
@@ -0,0 +1,58 @@
1+#include <QSortFilterProxyModel>
2+
3+#include <unity/shell/launcher/AppDrawerModelInterface.h>
4+
5+using namespace unity::shell::launcher;
6+
7+class AppDrawerProxyModel: public QSortFilterProxyModel
8+{
9+ Q_OBJECT
10+ Q_ENUMS(GroupBy)
11+ Q_PROPERTY(QAbstractItemModel* source READ source WRITE setSource NOTIFY sourceChanged)
12+ Q_PROPERTY(GroupBy group READ group WRITE setGroup NOTIFY groupChanged)
13+ Q_PROPERTY(QString filterLetter READ filterLetter WRITE setFilterLetter NOTIFY filterLetterChanged)
14+ Q_PROPERTY(QString filterString READ filterString WRITE setFilterString NOTIFY filterStringChanged)
15+ Q_PROPERTY(int count READ count NOTIFY countChanged)
16+
17+public:
18+ enum GroupBy {
19+ GroupByNone,
20+ GroupByAll,
21+ GroupByAToZ
22+ };
23+
24+ AppDrawerProxyModel(QObject* parent = nullptr);
25+
26+ QAbstractItemModel* source() const;
27+ void setSource(QAbstractItemModel* source);
28+
29+ GroupBy group() const;
30+ void setGroup(GroupBy group);
31+
32+ QString filterLetter() const;
33+ void setFilterLetter(const QString &filterLetter);
34+
35+ QString filterString() const;
36+ void setFilterString(const QString &filterString);
37+
38+ int count() const;
39+
40+ QVariant data(const QModelIndex &index, int role) const override;
41+ QHash<int, QByteArray> roleNames() const override;
42+
43+protected:
44+ bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override;
45+
46+Q_SIGNALS:
47+ void sourceChanged();
48+ void groupChanged();
49+ void filterLetterChanged();
50+ void filterStringChanged();
51+ void countChanged();
52+
53+private:
54+ QAbstractItemModel* m_source = nullptr;
55+ GroupBy m_group = GroupByNone;
56+ QString m_filterLetter;
57+ QString m_filterString;
58+};
qml/Launcher/BackgroundBlur.qmlnew file+68
@@ -0,0 +1,68 @@
1+import QtQuick 2.4
2+import Ubuntu.Components 1.3
3+import QtGraphicalEffects 1.0
4+
5+Item {
6+ id: root
7+
8+ property int blurAmount: 32
9+ property Item sourceItem
10+ property rect blurRect: Qt.rect(0,0,0,0)
11+ property alias cached: fastBlur.cached
12+
13+ Item {
14+ anchors.fill: parent
15+ Rectangle {
16+ id: blurMask
17+ color: "yellow"
18+ x: blurRect.x
19+ y: blurRect.y
20+ width: blurRect.width
21+ height: blurRect.height
22+ }
23+ }
24+
25+ ShaderEffect {
26+ id: maskedBlurEffect
27+ x: blurRect.x
28+ y: blurRect.y
29+ width: blurRect.width
30+ height: blurRect.height
31+
32+ property variant source: ShaderEffectSource {
33+ id: shaderEffectSource
34+ sourceItem: root.sourceItem
35+ hideSource: false
36+ sourceRect: root.blurRect
37+ }
38+
39+ property var mask: ShaderEffectSource {
40+ sourceItem: blurMask
41+ hideSource: true
42+ }
43+
44+ fragmentShader: "
45+ varying highp vec2 qt_TexCoord0;
46+ uniform sampler2D source;
47+ uniform sampler2D mask;
48+ void main(void)
49+ {
50+ highp vec4 sourceColor = texture2D(source, qt_TexCoord0);
51+ highp vec4 maskColor = texture2D(mask, qt_TexCoord0);
52+
53+ sourceColor *= maskColor.a;
54+
55+ gl_FragColor = sourceColor;
56+ }"
57+ }
58+
59+ FastBlur {
60+ id: fastBlur
61+ x: blurRect.x
62+ y: blurRect.y
63+ width: blurRect.width
64+ height: blurRect.height
65+ source: maskedBlurEffect
66+ radius: Math.min(blurAmount, 128)
67+ }
68+ }
qml/Launcher/Drawer.qmlnew file+213
@@ -0,0 +1,213 @@
1+import QtQuick 2.4
2+import Ubuntu.Components 1.3
3+import Unity.Launcher 0.1
4+import Utils 0.1
5+import "../Components"
6+
7+Rectangle {
8+ id: root
9+ color: "#BF000000"
10+
11+ property int panelWidth: 0
12+ readonly property bool moving: listLoader.item && listLoader.item.moving
13+
14+ signal applicationSelected(string appId)
15+
16+ AppDrawerModel {
17+ id: appDrawerModel
18+ }
19+
20+ AppDrawerProxyModel {
21+ id: sortProxyModel
22+ source: appDrawerModel
23+ filterString: searchField.text
24+ }
25+
26+ Item {
27+ id: contentContainer
28+ anchors.fill: parent
29+ anchors.leftMargin: root.panelWidth
30+
31+ TextField {
32+ id: searchField
33+ anchors { left: parent.left; top: parent.top; right: parent.right; margins: units.gu(1) }
34+ placeholderText: i18n.tr("Search...")
35+ }
36+
37+ Item {
38+ id: sectionsContainer
39+ anchors { left: parent.left; top: searchField.bottom; right: parent.right; }
40+ height: sections.height
41+ clip: true
42+ z: 2
43+
44+ Sections {
45+ id: sections
46+ width: parent.width
47+ actions: [
48+ Action {
49+ text: "A-Z"
50+ },
51+ Action {
52+ text: "Most used"
53+ }
54+ ]
55+
56+ Rectangle {
57+ anchors.bottom: parent.bottom
58+ height: units.dp(1)
59+ color: 'gray'
60+ width: contentContainer.width
61+ }
62+ }
63+ }
64+
65+ Loader {
66+ id: listLoader
67+ anchors { left: parent.left; top: sectionsContainer.bottom; right: parent.right; bottom: parent.bottom; leftMargin: units.gu(1); rightMargin: units.gu(1) }
68+ sourceComponent: sections.selectedIndex == 0 ? aToZComponent : mostUsedComponent
69+ }
70+
71+ Component {
72+ id: mostUsedComponent
73+ ListView {
74+ anchors.fill: parent
75+ topMargin: units.gu(1)
76+ bottomMargin: units.gu(1)
77+ spacing: units.gu(1)
78+ clip: true
79+
80+ header: MoreAppsHeader {
81+ width: parent.width
82+ height: units.gu(6)
83+ }
84+
85+ model: AppDrawerProxyModel {
86+ source: sortProxyModel
87+ group: AppDrawerProxyModel.GroupByAll
88+ }
89+
90+ delegate: UbuntuShape {
91+ width: parent.width
92+ color: "#20ffffff"
93+ aspect: UbuntuShape.Flat
94+ // NOTE: Cannot use gridView.rows here as it would evaluate to 0 at first and only update later,
95+ // which messes up the ListView.
96+ height: (Math.ceil(mostUsedGridView.model.count / mostUsedGridView.columns) * mostUsedGridView.delegateHeight) + units.gu(2)
97+
98+ DrawerGridView {
99+ id: mostUsedGridView
100+ anchors.fill: parent
101+ topMargin: units.gu(1)
102+ bottomMargin: units.gu(1)
103+ clip: true
104+
105+ model: sortProxyModel
106+
107+
108+ delegateWidth: units.gu(8)
109+ delegateHeight: units.gu(10)
110+ delegate: drawerDelegateComponent
111+ }
112+ }
113+ }
114+ }
115+
116+ Component {
117+ id: aToZComponent
118+ ListView {
119+ anchors.fill: parent
120+ topMargin: units.gu(1)
121+ bottomMargin: units.gu(1)
122+ spacing: units.gu(1)
123+ clip: true
124+
125+ header: MoreAppsHeader {
126+ width: parent.width
127+ height: units.gu(6)
128+ }
129+
130+ model: AppDrawerProxyModel {
131+ source: sortProxyModel
132+ group: AppDrawerProxyModel.GroupByAToZ
133+ }
134+
135+ delegate: UbuntuShape {
136+ width: parent.width
137+ color: "#20ffffff"
138+ aspect: UbuntuShape.Flat
139+
140+ // NOTE: Cannot use gridView.rows here as it would evaluate to 0 at first and only update later,
141+ // which messes up the ListView.
142+ height: (Math.ceil(gridView.model.count / gridView.columns) * gridView.delegateHeight) +
143+ categoryNameLabel.implicitHeight + units.gu(2)
144+
145+ Label {
146+ id: categoryNameLabel
147+ anchors { left: parent.left; top: parent.top; right: parent.right; margins: units.gu(1) }
148+ text: model.letter
149+ }
150+
151+ DrawerGridView {
152+ id: gridView
153+ anchors { left: parent.left; top: categoryNameLabel.bottom; right: parent.right; topMargin: units.gu(1) }
154+ height: rows * delegateHeight
155+
156+ interactive: false
157+
158+ model: AppDrawerProxyModel {
159+ id: categoryModel
160+ source: sortProxyModel
161+ filterLetter: model.letter
162+ }
163+ delegateWidth: units.gu(8)
164+ delegateHeight: units.gu(10)
165+ delegate: drawerDelegateComponent
166+ }
167+ }
168+ }
169+ }
170+ }
171+
172+ Component {
173+ id: drawerDelegateComponent
174+ AbstractButton {
175+ width: GridView.view.cellWidth
176+ height: units.gu(10)
177+
178+ onClicked: root.applicationSelected(model.appId)
179+
180+ Column {
181+ width: units.gu(8)
182+ anchors.horizontalCenter: parent.horizontalCenter
183+ height: childrenRect.height
184+ spacing: units.gu(1)
185+
186+ UbuntuShape {
187+ id: appIcon
188+ width: units.gu(6)
189+ height: 7.5 / 8 * width
190+ anchors.horizontalCenter: parent.horizontalCenter
191+ backgroundMode: UbuntuShape.SolidColor
192+ backgroundColor: UbuntuColors.lightGrey
193+ radius: "medium"
194+ borderSource: 'undefined'
195+ source: Image {
196+ id: sourceImage
197+ sourceSize.width: appIcon.width
198+ source: model.icon
199+ }
200+ sourceFillMode: UbuntuShape.PreserveAspectCrop
201+ }
202+
203+ Label {
204+ text: model.name
205+ width: parent.width
206+ horizontalAlignment: Text.AlignHCenter
207+ fontSize: "small"
208+ elide: Text.ElideRight
209+ }
210+ }
211+ }
212+ }
213+}
qml/Launcher/DrawerGridView.qmlnew file+31
@@ -0,0 +1,31 @@
1+import QtQuick 2.4
2+
3+Item {
4+ id: root
5+
6+ property int delegateWidth: units.gu(10)
7+ property int delegateHeight: units.gu(10)
8+ property alias delegate: gridView.delegate
9+ property alias model: gridView.model
10+ property alias interactive: gridView.interactive
11+
12+ property alias header: gridView.header
13+ property alias topMargin: gridView.topMargin
14+ property alias bottomMargin: gridView.bottomMargin
15+
16+ readonly property int columns: width / delegateWidth
17+ readonly property int rows: Math.ceil(gridView.model.count / root.columns)
18+
19+ GridView {
20+ id: gridView
21+ anchors.fill: parent
22+ leftMargin: spacing
23+
24+ readonly property int overflow: width - (root.columns * root.delegateWidth)
25+ readonly property real spacing: overflow / (root.columns)
26+
27+ cellWidth: root.delegateWidth + spacing
28+ cellHeight: root.delegateHeight
29+ }
30+}
31+
qml/Launcher/MoreAppsHeader.qmlnew file+41
@@ -0,0 +1,41 @@
1+import QtQuick 2.4
2+import Ubuntu.Components 1.3
3+
4+Item {
5+ id: root
6+
7+ UbuntuShape {
8+ width: parent.width
9+ height: parent.height - units.gu(1)
10+ color: "#20ffffff"
11+ aspect: UbuntuShape.Flat
12+
13+ Row {
14+ anchors.fill: parent
15+ anchors.margins: units.gu(1)
16+ spacing: units.gu(1)
17+
18+ Icon {
19+ height: units.gu(2.2)
20+ width: height
21+ name: "stock_application"
22+ anchors.verticalCenter: parent.verticalCenter
23+ color: "white"
24+ }
25+
26+ Label {
27+ text: i18n.tr("More apps in the store")
28+ anchors.verticalCenter: parent.verticalCenter
29+ fontSize: "small"
30+ }
31+
32+ Icon {
33+ height: units.gu(2.5)
34+ width: height
35+ anchors.verticalCenter: parent.verticalCenter
36+ name: "go-next"
37+ color: "white"
38+ }
39+ }
40+ }
41+}
tests/mocks/Unity/Launcher/MockAppDrawerModel.cppnew file+54
@@ -0,0 +1,54 @@
1+#include "MockAppDrawerModel.h"
2+
3+#include <QDebug>
4+
5+MockAppDrawerModel::MockAppDrawerModel(QObject *parent):
6+ AppDrawerModelInterface(parent)
7+{
8+ MockLauncherItem *item = new MockLauncherItem("dialer-app", "/usr/share/applications/dialer-app.desktop", "Dialer", "dialer-app", this);
9+ m_list.append(item);
10+ item = new MockLauncherItem("camera-app", "/usr/share/applications/camera-app.desktop", "Camera", "camera", this);
11+ m_list.append(item);
12+ item = new MockLauncherItem("camera-app2", "/usr/share/applications/camera-app2.desktop", "Camera2", "camera", this);
13+ m_list.append(item);
14+ item = new MockLauncherItem("gallery-app", "/usr/share/applications/gallery-app.desktop", "Gallery", "gallery", this);
15+ m_list.append(item);
16+ item = new MockLauncherItem("music-app", "/usr/share/applications/music-app.desktop", "Music", "soundcloud", this);
17+ m_list.append(item);
18+ item = new MockLauncherItem("facebook-webapp", "/usr/share/applications/facebook-webapp.desktop", "Facebook", "facebook", this);
19+ m_list.append(item);
20+ item = new MockLauncherItem("webbrowser-app", "/usr/share/applications/webbrowser-app.desktop", "Browser", "browser", this);
21+ m_list.append(item);
22+ item = new MockLauncherItem("twitter-webapp", "/usr/share/applications/twitter-webapp.desktop", "Twitter", "twitter", this);
23+ m_list.append(item);
24+ item = new MockLauncherItem("gmail-webapp", "/usr/share/applications/gmail-webapp.desktop", "GMail", "gmail", this);
25+ m_list.append(item);
26+ item = new MockLauncherItem("ubuntu-weather-app", "/usr/share/applications/ubuntu-weather-app.desktop", "Weather", "weather", this);
27+ m_list.append(item);
28+ item = new MockLauncherItem("notes-app", "/usr/share/applications/notes-app.desktop", "Notepad", "notepad", this);
29+ m_list.append(item);
30+ item = new MockLauncherItem("calendar-app", "/usr/share/applications/calendar-app.desktop","Calendar", "calendar", this);
31+ m_list.append(item);
32+ item = new MockLauncherItem("libreoffice", "/usr/share/applications/libreoffice.desktop","Libre Office", "libreoffice", this);
33+ m_list.append(item);
34+ qDebug() << "mock model created";
35+}
36+
37+int MockAppDrawerModel::rowCount(const QModelIndex &parent) const
38+{
39+ return m_list.count();
40+}
41+
42+QVariant MockAppDrawerModel::data(const QModelIndex &index, int role) const
43+{
44+ switch (role) {
45+ case RoleAppId:
46+ return m_list.at(index.row())->appId();
47+ case RoleName:
48+ return m_list.at(index.row())->name();
49+ case RoleIcon:
50+ return m_list.at(index.row())->icon();
51+ }
52+
53+ return QVariant();
54+}
tests/mocks/Unity/Launcher/MockAppDrawerModel.hnew file+17
@@ -0,0 +1,17 @@
1+
2+#include <unity/shell/launcher/AppDrawerModelInterface.h>
3+
4+#include "MockLauncherItem.h"
5+
6+class MockAppDrawerModel: public AppDrawerModelInterface
7+{
8+ Q_OBJECT
9+public:
10+ MockAppDrawerModel(QObject* parent = nullptr);
11+
12+ int rowCount(const QModelIndex &parent) const override;
13+ QVariant data(const QModelIndex &index, int role) const override;
14+
15+private:
16+ QList<MockLauncherItem*> m_list;
17+};