on xenial help sign in
Update mock ApplicationManager APIs to use that defined in unity-api
febd475Gerry Boland
tests/mocks/Unity/Application/ApplicationInfo.cpp+15−2
@@ -21,11 +21,24 @@
21#include <QQuickView>
21#include <QQuickView>
22#include <QQmlComponent>
22#include <QQmlComponent>
23
23
24+ApplicationInfo::ApplicationInfo(const QString &appId, QObject *parent)
25+ : ApplicationInfoInterface(appId, parent)
26+ ,m_appId(appId)
27+ ,m_stage(MainStage)
28+ ,m_state(Starting)
29+ ,m_focused(false)
30+ ,m_fullscreen(false)
31+ ,m_windowItem(0)
32+ ,m_windowComponent(0)
33+ ,m_parentItem(0)
34+{
35+}
36+
24ApplicationInfo::ApplicationInfo(QObject *parent)
37ApplicationInfo::ApplicationInfo(QObject *parent)
25− : QObject(parent)
38+ : ApplicationInfoInterface(QString(), parent)
26− ,m_handle(0)
27 ,m_stage(MainStage)
39 ,m_stage(MainStage)
28 ,m_state(Starting)
40 ,m_state(Starting)
41+ ,m_focused(false)
29 ,m_fullscreen(false)
42 ,m_fullscreen(false)
30 ,m_windowItem(0)
43 ,m_windowItem(0)
31 ,m_windowComponent(0)
44 ,m_windowComponent(0)
tests/mocks/Unity/Application/ApplicationInfo.h+12−18
@@ -22,21 +22,18 @@
22
22
23class QQuickItem;
23class QQuickItem;
24
24
25+// unity-api
26+#include <unity/shell/application/ApplicationInfoInterface.h>
27+
25// A pretty dumb file. Just a container for properties.
28// A pretty dumb file. Just a container for properties.
26// Implemented in C++ instead of QML just because of the enumerations
29// Implemented in C++ instead of QML just because of the enumerations
27// See QTBUG-14861
30// See QTBUG-14861
31+
32+using namespace unity::shell::application;
33+
28−class ApplicationInfo : public QObject {
34+class ApplicationInfo : public ApplicationInfoInterface {
29 Q_OBJECT
35 Q_OBJECT
30− Q_ENUMS(Stage)
36+
31− Q_ENUMS(State)
32− Q_PROPERTY(QString desktopFile READ desktopFile WRITE setDesktopFile NOTIFY desktopFileChanged)
33− Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
34− Q_PROPERTY(QString comment READ comment WRITE setComment NOTIFY commentChanged)
35− Q_PROPERTY(QString icon READ icon WRITE setIcon NOTIFY iconChanged)
36− Q_PROPERTY(QString exec READ exec WRITE setExec NOTIFY execChanged)
37− Q_PROPERTY(qint64 handle READ handle WRITE setHandle NOTIFY handleChanged)
38− Q_PROPERTY(Stage stage READ stage WRITE setStage NOTIFY stageChanged)
39− Q_PROPERTY(State state READ state WRITE setState NOTIFY stateChanged)
40 Q_PROPERTY(bool fullscreen READ fullscreen WRITE setFullscreen NOTIFY fullscreenChanged)
37 Q_PROPERTY(bool fullscreen READ fullscreen WRITE setFullscreen NOTIFY fullscreenChanged)
41
38
42 // Only exists in this fake implementation
39 // Only exists in this fake implementation
@@ -48,10 +45,8 @@ class ApplicationInfo : public QObject {
48 Q_PROPERTY(QString windowQml READ windowQml WRITE setWindowQml NOTIFY windowQmlChanged)
45 Q_PROPERTY(QString windowQml READ windowQml WRITE setWindowQml NOTIFY windowQmlChanged)
49
46
50 public:
47 public:
51− enum Stage { MainStage, SideStage };
52− enum State { Starting, Running };
53−
54 ApplicationInfo(QObject *parent = NULL);
48 ApplicationInfo(QObject *parent = NULL);
49+ ApplicationInfo(const QString &appId, QObject *parent = NULL);
55
50
56 #define IMPLEMENT_PROPERTY(name, Name, type) \
51 #define IMPLEMENT_PROPERTY(name, Name, type) \
57 public: \
52 public: \
@@ -68,14 +63,13 @@ class ApplicationInfo : public QObject {
68 private: \
63 private: \
69 type m_##name;
64 type m_##name;
70
65
71− IMPLEMENT_PROPERTY(desktopFile, DesktopFile, QString)
66+ IMPLEMENT_PROPERTY(appId, AppId, QString)
72 IMPLEMENT_PROPERTY(name, Name, QString)
67 IMPLEMENT_PROPERTY(name, Name, QString)
73 IMPLEMENT_PROPERTY(comment, Comment, QString)
68 IMPLEMENT_PROPERTY(comment, Comment, QString)
74− IMPLEMENT_PROPERTY(icon, Icon, QString)
69+ IMPLEMENT_PROPERTY(icon, Icon, QUrl)
75− IMPLEMENT_PROPERTY(exec, Exec, QString)
76− IMPLEMENT_PROPERTY(handle, Handle, qint64)
77 IMPLEMENT_PROPERTY(stage, Stage, Stage)
70 IMPLEMENT_PROPERTY(stage, Stage, Stage)
78 IMPLEMENT_PROPERTY(state, State, State)
71 IMPLEMENT_PROPERTY(state, State, State)
72+ IMPLEMENT_PROPERTY(focused, Focused, bool)
79 IMPLEMENT_PROPERTY(fullscreen, Fullscreen, bool)
73 IMPLEMENT_PROPERTY(fullscreen, Fullscreen, bool)
80 IMPLEMENT_PROPERTY(imageQml, ImageQml, QString)
74 IMPLEMENT_PROPERTY(imageQml, ImageQml, QString)
81 IMPLEMENT_PROPERTY(windowQml, WindowQml, QString)
75 IMPLEMENT_PROPERTY(windowQml, WindowQml, QString)
tests/mocks/Unity/Application/ApplicationListModel.cppdeleted−144
@@ -1,144 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−
17−#include "ApplicationListModel.h"
18−#include "ApplicationInfo.h"
19−
20−ApplicationListModel::ApplicationListModel(QObject* parent)
21− : QAbstractListModel(parent), m_applications()
22−{
23− m_roleNames.insert(0, "application");
24−}
25−
26−ApplicationListModel::~ApplicationListModel()
27−{
28− const int kSize = m_applications.size();
29− for (int i = 0; i < kSize; i++)
30− delete m_applications.at(i);
31− m_applications.clear();
32−}
33−
34−int ApplicationListModel::rowCount(const QModelIndex& parent) const
35−{
36− return !parent.isValid() ? m_applications.size() : 0;
37−}
38−
39−QVariant ApplicationListModel::data(const QModelIndex& index, int role) const
40−{
41− if (index.row() >= 0 && index.row() < m_applications.size() && role == 0)
42− return QVariant::fromValue(m_applications.at(index.row()));
43− else
44− return QVariant();
45−}
46−
47−QVariant ApplicationListModel::get(int row) const
48−{
49− return data(index(row), 0);
50−}
51−
52−void ApplicationListModel::move(int from, int to)
53−{
54− if (from >= 0 && from < m_applications.size() && to >= 0 && to < m_applications.size()) {
55− QModelIndex parent;
56− /* When moving an item down, the destination index needs to be incremented
57− by one, as explained in the documentation:
58− http://qt-project.org/doc/qt-5.0/qtcore/qabstractitemmodel.html#beginMoveRows */
59− beginMoveRows(parent, from, from, parent, to + (to > from ? 1 : 0));
60− m_applications.move(from, to);
61− endMoveRows();
62− }
63−}
64−
65−void ApplicationListModel::add(ApplicationInfo* application)
66−{
67− beginInsertRows(QModelIndex(), m_applications.size(), m_applications.size());
68− m_applications.append(application);
69− endInsertRows();
70− Q_EMIT countChanged();
71−}
72−
73−void ApplicationListModel::remove(ApplicationInfo* application)
74−{
75− int i = m_applications.indexOf(application);
76− if (i != -1) {
77− beginRemoveRows(QModelIndex(), i, i);
78− m_applications.removeAt(i);
79− endRemoveRows();
80− Q_EMIT countChanged();
81− }
82−}
83−
84−bool ApplicationListModel::contains(ApplicationInfo* application) const {
85− return m_applications.contains(application);
86−}
87−
88−void ApplicationListModel::clear()
89−{
90− beginRemoveRows(QModelIndex(), 0, m_applications.size()-1);
91− m_applications.clear();
92− endRemoveRows();
93− Q_EMIT countChanged();
94−}
95−
96−QQmlListProperty<ApplicationInfo> ApplicationListModel::applications()
97−{
98− return QQmlListProperty<ApplicationInfo>(this, 0,
99− &ApplicationListModel::appendApplication,
100− &ApplicationListModel::countApplications,
101− &ApplicationListModel::atApplication,
102− &ApplicationListModel::clearApplications);
103−}
104−
105−void ApplicationListModel::appendApplication(QQmlListProperty<ApplicationInfo> *list,
106− ApplicationInfo *application)
107−{
108− ApplicationListModel *self = qobject_cast<ApplicationListModel *>(list->object);
109− if (self) {
110− application->setParent(self);
111− self->add(application);
112− }
113−}
114−
115−int ApplicationListModel::countApplications(QQmlListProperty<ApplicationInfo> *list)
116−{
117− ApplicationListModel *self = qobject_cast<ApplicationListModel *>(list->object);
118− if (self) {
119− return self->m_applications.size();
120− } else {
121− return 0;
122− }
123−}
124−
125−ApplicationInfo* ApplicationListModel::atApplication(QQmlListProperty<ApplicationInfo> *list,
126− int index)
127−{
128− ApplicationListModel *self = qobject_cast<ApplicationListModel *>(list->object);
129− if (!self) { return 0; }
130−
131− if (index >= 0 && index < self->m_applications.size()) {
132− return self->m_applications.at(index);
133− } else {
134− return 0;
135− }
136−}
137−
138−void ApplicationListModel::clearApplications(QQmlListProperty<ApplicationInfo> *list)
139−{
140− ApplicationListModel *self = qobject_cast<ApplicationListModel *>(list->object);
141− if (self) {
142− self->clear();
143− }
144−}
tests/mocks/Unity/Application/ApplicationListModel.hdeleted−71
@@ -1,71 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−
17−#ifndef APPLICATION_LIST_MODEL_H
18−#define APPLICATION_LIST_MODEL_H
19−
20−#include <QAbstractListModel>
21−#include <QQmlListProperty>
22−#include "ApplicationInfo.h"
23−
24−class ApplicationManager;
25−
26−class ApplicationListModel : public QAbstractListModel {
27− Q_OBJECT
28−
29− Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
30− Q_PROPERTY(QQmlListProperty<ApplicationInfo> applications READ applications)
31− Q_CLASSINFO("DefaultProperty", "applications")
32−
33− public:
34− explicit ApplicationListModel(QObject* parent = 0);
35− virtual ~ApplicationListModel();
36−
37− // QAbstractItemModel methods.
38− int rowCount(const QModelIndex& parent = QModelIndex()) const;
39− QVariant data(const QModelIndex& index, int role) const;
40− QHash<int,QByteArray> roleNames() const { return m_roleNames; }
41− Q_INVOKABLE QVariant get(int index) const;
42− Q_INVOKABLE void move(int from, int to);
43−
44− QQmlListProperty<ApplicationInfo> applications();
45−
46− Q_INVOKABLE void add(ApplicationInfo* application);
47− Q_INVOKABLE void remove(ApplicationInfo* application);
48− Q_INVOKABLE bool contains(ApplicationInfo* application) const;
49− Q_INVOKABLE void clear();
50−
51− Q_SIGNALS:
52− void countChanged();
53−
54− private:
55− Q_DISABLE_COPY(ApplicationListModel)
56−
57− static void appendApplication(QQmlListProperty<ApplicationInfo> *list,
58− ApplicationInfo *application);
59− static int countApplications(QQmlListProperty<ApplicationInfo> *list);
60− static ApplicationInfo* atApplication(QQmlListProperty<ApplicationInfo> *list, int index);
61− static void clearApplications(QQmlListProperty<ApplicationInfo> *list);
62−
63− QHash<int,QByteArray> m_roleNames;
64− QList<ApplicationInfo*> m_applications;
65−
66− friend class ApplicationManager;
67−};
68−
69−Q_DECLARE_METATYPE(ApplicationListModel*)
70−
71−#endif // APPLICATION_LIST_MODEL_H
tests/mocks/Unity/Application/ApplicationManager.cpp+164−154
@@ -16,7 +16,6 @@
16
16
17#include "ApplicationManager.h"
17#include "ApplicationManager.h"
18#include "ApplicationInfo.h"
18#include "ApplicationInfo.h"
19−#include "ApplicationListModel.h"
20#include "paths.h"
19#include "paths.h"
21
20
22#include <QDir>
21#include <QDir>
@@ -26,11 +25,7 @@
26#include <QQmlComponent>
25#include <QQmlComponent>
27
26
28ApplicationManager::ApplicationManager(QObject *parent)
27ApplicationManager::ApplicationManager(QObject *parent)
29− : QObject(parent)
28+ : ApplicationManagerInterface(parent)
30− , m_mainStageApplications(new ApplicationListModel())
31− , m_sideStageApplications(new ApplicationListModel())
32− , m_mainStageFocusedApplication(0)
33− , m_sideStageFocusedApplication(0)
34 , m_mainStageComponent(0)
29 , m_mainStageComponent(0)
35 , m_mainStage(0)
30 , m_mainStage(0)
36 , m_sideStageComponent(0)
31 , m_sideStageComponent(0)
@@ -41,8 +36,65 @@ ApplicationManager::ApplicationManager(QObject *parent)
41
36
42ApplicationManager::~ApplicationManager()
37ApplicationManager::~ApplicationManager()
43{
38{
44− delete m_mainStageApplications;
39+}
45− delete m_sideStageApplications;
40+
41+int ApplicationManager::rowCount(const QModelIndex& parent) const {
42+ return !parent.isValid() ? m_runningApplications.size() : 0;
43+}
44+
45+QVariant ApplicationManager::data(const QModelIndex& index, int role) const {
46+ if (index.row() < 0 || index.row() >= m_runningApplications.size())
47+ return QVariant();
48+
49+ auto app = m_runningApplications.at(index.row());
50+ switch(role) {
51+ case RoleAppId:
52+ return app->appId();
53+ case RoleName:
54+ return app->name();
55+ case RoleComment:
56+ return app->comment();
57+ case RoleIcon:
58+ return app->icon();
59+ case RoleStage:
60+ return app->stage();
61+ case RoleState:
62+ return app->state();
63+ case RoleFocused:
64+ return app->focused();
65+ default:
66+ return QVariant();
67+ }
68+}
69+
70+ApplicationInfo *ApplicationManager::get(int row) const {
71+ if (row < 0 || row >= m_runningApplications.size())
72+ return nullptr;
73+
74+ return m_runningApplications.at(row);
75+}
76+
77+ApplicationInfo *ApplicationManager::findApplication(const QString &appId) const {
78+ for (ApplicationInfo *app : m_runningApplications) {
79+ if (app->appId() == appId) {
80+ return app;
81+ }
82+ }
83+ return nullptr;
84+}
85+
86+void ApplicationManager::move(int from, int to) {
87+ if (from == to) return;
88+
89+ if (from >= 0 && from < m_runningApplications.size() && to >= 0 && to < m_runningApplications.size()) {
90+ QModelIndex parent;
91+ /* When moving an item down, the destination index needs to be incremented
92+ * by one, as explained in the documentation:
93+ * http://qt-project.org/doc/qt-5.0/qtcore/qabstractitemmodel.html#beginMoveRows */
94+ beginMoveRows(parent, from, from, parent, to + (to > from ? 1 : 0));
95+ m_runningApplications.move(from, to);
96+ endMoveRows();
97+ }
46}
98}
47
99
48int ApplicationManager::keyboardHeight() const
100int ApplicationManager::keyboardHeight() const
@@ -70,36 +122,22 @@ ApplicationManager::FormFactorHint ApplicationManager::formFactorHint() const
70 return PhoneFormFactor;
122 return PhoneFormFactor;
71}
123}
72
124
73−ApplicationListModel* ApplicationManager::mainStageApplications() const
125+ApplicationInfo* ApplicationManager::startApplication(const QString &appId,
74−{
126+ const QStringList &arguments)
75− return m_mainStageApplications;
76−}
77−
78−ApplicationListModel* ApplicationManager::sideStageApplications() const
79{
127{
80− return m_sideStageApplications;
128+ return this->startApplication(appId, NoFlag, arguments);
81}
129}
82
130
83−ApplicationInfo* ApplicationManager::mainStageFocusedApplication() const
131+ApplicationInfo* ApplicationManager::startApplication(const QString &appId,
84−{
85− return m_mainStageFocusedApplication;
86−}
87−
88−ApplicationInfo* ApplicationManager::sideStageFocusedApplication() const
89−{
90− return m_sideStageFocusedApplication;
91−}
92−
93−ApplicationInfo* ApplicationManager::startProcess(QString desktopFile,
94 ExecFlags flags,
132 ExecFlags flags,
95− QStringList arguments)
133+ const QStringList &arguments)
96{
134{
97 Q_UNUSED(arguments)
135 Q_UNUSED(arguments)
98 ApplicationInfo *application = 0;
136 ApplicationInfo *application = 0;
99
137
100 for (int i = 0; i < m_availableApplications.count(); ++i) {
138 for (int i = 0; i < m_availableApplications.count(); ++i) {
101 ApplicationInfo *availableApp = m_availableApplications[i];
139 ApplicationInfo *availableApp = m_availableApplications[i];
102− if (availableApp->desktopFile() == desktopFile) {
140+ if (availableApp->appId() == appId) {
103 application = availableApp;
141 application = availableApp;
104 break;
142 break;
105 }
143 }
@@ -108,87 +146,88 @@ ApplicationInfo* ApplicationManager::startProcess(QString desktopFile,
108 if (!application)
146 if (!application)
109 return 0;
147 return 0;
110
148
149+ m_runningApplications.append(application);
111 if (flags.testFlag(ApplicationManager::ForceMainStage)
150 if (flags.testFlag(ApplicationManager::ForceMainStage)
112− || application->stage() == ApplicationInfo::MainStage) {
151+ && application->stage() == ApplicationInfo::SideStage) {
113− m_mainStageApplications->add(application);
152+ application->setStage(ApplicationInfo::MainStage);
114− } else {
115− m_sideStageApplications->add(application);
116 }
153 }
117
154
155+ application->setFocused(true);
156+ Q_EMIT focusedApplicationIdChanged();
118 return application;
157 return application;
119}
158}
120
159
121−void ApplicationManager::stopProcess(ApplicationInfo* application)
160+bool ApplicationManager::stopApplication(const QString &appId)
122{
161{
123− if (m_mainStageApplications->contains(application)) {
162+ ApplicationInfo *application = this->findApplication(appId);
124− m_mainStageApplications->remove(application);
163+ if (application == nullptr)
125−
164+ return false;
126− if (m_mainStageFocusedApplication == application) {
165+
127− m_mainStageFocusedApplication = 0;
166+ application->setFocused(false);
128− Q_EMIT mainStageFocusedApplicationChanged();
167+ m_runningApplications.removeAll(application);
129− }
168+ Q_EMIT focusedApplicationIdChanged();
130− } else if (m_sideStageApplications->contains(application)){
169+ return true;
131− m_sideStageApplications->remove(application);
170+}
132
171
133− if (m_sideStageFocusedApplication == application) {
172+QString ApplicationManager::focusedApplicationId() const {
134− m_sideStageFocusedApplication = 0;
173+ for (ApplicationInfo *app : m_runningApplications) {
135− Q_EMIT sideStageFocusedApplicationChanged();
174+ if (app->focused())
136− }
175+ return app->appId();
137 }
176 }
177+ return QString();
138}
178}
139
179
140−void ApplicationManager::focusApplication(int handle)
180+bool ApplicationManager::focusApplication(const QString &appId)
141{
181{
142− for (int i = 0; i < m_mainStageApplications->m_applications.count(); ++i) {
143− ApplicationInfo *application = m_mainStageApplications->m_applications[i];
182+ ApplicationInfo *application = this->findApplication(appId);
144− if (application->handle() == handle) {
145− if (m_mainStageFocusedApplication)
146− m_mainStageFocusedApplication->hideWindow();
147− m_mainStageFocusedApplication = application;
148− if (!m_mainStage)
149− createMainStage();
150− application->showWindow(m_mainStage);
183+ if (application == nullptr)
151− m_mainStage->setZ(-1000);
152− if (m_sideStage)
153− m_sideStage->setZ(-2000);
154− Q_EMIT mainStageFocusedApplicationChanged();
155− return;
184+ return false;
185+
186+ if (application->stage() == ApplicationInfo::MainStage) {
187+ // unfocus currently focused mainstage app
188+ for (ApplicationInfo *app : m_runningApplications) {
189+ if (app->focused() && app->stage() == ApplicationInfo::MainStage)
190+ app->setFocused(false);
156 }
191 }
157− }
158
192
159− for (int i = 0; i < m_sideStageApplications->m_applications.count(); ++i) {
193+ // focus this app
160− ApplicationInfo *application = m_sideStageApplications->m_applications[i];
161− if (application->handle() == handle) {
194+ application->setFocused(true);
162− if (m_sideStageFocusedApplication)
195+ if (!m_mainStage)
163− m_sideStageFocusedApplication->hideWindow();
196+ createMainStage();
164− m_sideStageFocusedApplication = application;
165− if (!m_sideStage)
166− createSideStage();
167− application->showWindow(m_sideStage);
197+ application->showWindow(m_mainStage);
168− m_sideStage->setZ(-1000);
198+ m_mainStage->setZ(-1000);
169− if (m_mainStage)
199+ if (m_sideStage)
170− m_mainStage->setZ(-2000);
200+ m_sideStage->setZ(-2000);
171− Q_EMIT sideStageFocusedApplicationChanged();
201+ } else if (application->stage() == ApplicationInfo::SideStage) {
172− return;
202+ // unfocus currently focused sidestage app
203+ for (ApplicationInfo *app : m_runningApplications) {
204+ if (app->focused() && app->stage() == ApplicationInfo::SideStage)
205+ app->setFocused(false);
173 }
206 }
207+
208+ // focus this app
209+ application->setFocused(true);
210+ if (!m_sideStage)
211+ createSideStage();
212+ application->showWindow(m_sideStage);
213+ m_sideStage->setZ(-1000);
214+ if (m_mainStage)
215+ m_mainStage->setZ(-2000);
174 }
216 }
217+
218+ // move app to top of stack
219+ this->move(m_runningApplications.indexOf(application), 0);
220+ Q_EMIT focusedApplicationIdChanged();
221+ return true;
175}
222}
176
223
177−void ApplicationManager::unfocusCurrentApplication(StageHint stageHint)
224+void ApplicationManager::unfocusCurrentApplication()
178{
225{
179− if (stageHint == SideStage) {
226+ for (ApplicationInfo *app : m_runningApplications) {
180− if (m_sideStageFocusedApplication) {
227+ if (app->focused())
181− m_sideStageFocusedApplication->hideWindow();
228+ app->setFocused(false);
182− m_sideStageFocusedApplication = 0;
183− Q_EMIT sideStageFocusedApplicationChanged();
184− }
185− } else {
186− if (m_mainStageFocusedApplication) {
187− m_mainStageFocusedApplication->hideWindow();
188− m_mainStageFocusedApplication = 0;
189− Q_EMIT mainStageFocusedApplicationChanged();
190− }
191 }
229 }
230+ Q_EMIT focusedApplicationIdChanged();
192}
231}
193
232
194void ApplicationManager::generateQmlStrings(ApplicationInfo *application)
233void ApplicationManager::generateQmlStrings(ApplicationInfo *application)
@@ -213,7 +252,7 @@ void ApplicationManager::generateQmlStrings(ApplicationInfo *application)
213 " fillMode: Image.PreserveAspectCrop\n"
252 " fillMode: Image.PreserveAspectCrop\n"
214 "}").arg(topMargin)
253 "}").arg(topMargin)
215 .arg(shellAppDirectory())
254 .arg(shellAppDirectory())
216− .arg(application->icon());
255+ .arg(application->icon().toString());
217 application->setWindowQml(windowQml);
256 application->setWindowQml(windowQml);
218
257
219 QString imageQml = QString(
258 QString imageQml = QString(
@@ -224,159 +263,130 @@ void ApplicationManager::generateQmlStrings(ApplicationInfo *application)
224 " smooth: true\n"
263 " smooth: true\n"
225 " fillMode: Image.PreserveAspectCrop\n"
264 " fillMode: Image.PreserveAspectCrop\n"
226 "}").arg(shellAppDirectory())
265 "}").arg(shellAppDirectory())
227− .arg(application->icon());
266+ .arg(application->icon().toString());
228 application->setImageQml(imageQml);
267 application->setImageQml(imageQml);
229}
268}
230
269
231void ApplicationManager::buildListOfAvailableApplications()
270void ApplicationManager::buildListOfAvailableApplications()
232{
271{
233 ApplicationInfo *application;
272 ApplicationInfo *application;
234− qint64 nextHandle = 1;
235
273
236 application = new ApplicationInfo(this);
274 application = new ApplicationInfo(this);
237− application->setDesktopFile("/usr/share/applications/phone-app.desktop");
275+ application->setAppId("phone-app");
238 application->setName("Phone");
276 application->setName("Phone");
239− application->setIcon("phone");
277+ application->setIcon(QUrl("phone"));
240− application->setExec("/usr/bin/phone-app");
241 application->setStage(ApplicationInfo::SideStage);
278 application->setStage(ApplicationInfo::SideStage);
242− application->setHandle(nextHandle++);
243 generateQmlStrings(application);
279 generateQmlStrings(application);
244 m_availableApplications.append(application);
280 m_availableApplications.append(application);
245
281
246 application = new ApplicationInfo(this);
282 application = new ApplicationInfo(this);
247− application->setDesktopFile("/usr/share/applications/camera-app.desktop");
283+ application->setAppId("camera-app");
248 application->setName("Camera");
284 application->setName("Camera");
249− application->setIcon("camera");
285+ application->setIcon(QUrl("camera"));
250 application->setFullscreen(true);
286 application->setFullscreen(true);
251− application->setExec("/usr/bin/camera-app --fullscreen");
252− application->setHandle(nextHandle++);
253 generateQmlStrings(application);
287 generateQmlStrings(application);
254 m_availableApplications.append(application);
288 m_availableApplications.append(application);
255
289
256 application = new ApplicationInfo(this);
290 application = new ApplicationInfo(this);
257− application->setDesktopFile("/usr/share/applications/gallery-app.desktop");
291+ application->setAppId("gallery-app");
258 application->setName("Gallery");
292 application->setName("Gallery");
259− application->setIcon("gallery");
293+ application->setIcon(QUrl("gallery"));
260− application->setExec("/usr/bin/gallery-app");
261− application->setHandle(nextHandle++);
262 generateQmlStrings(application);
294 generateQmlStrings(application);
263 m_availableApplications.append(application);
295 m_availableApplications.append(application);
264
296
265 application = new ApplicationInfo(this);
297 application = new ApplicationInfo(this);
266− application->setDesktopFile("/usr/share/applications/facebook-webapp.desktop");
298+ application->setAppId("facebook-webapp");
267 application->setName("Facebook");
299 application->setName("Facebook");
268− application->setIcon("facebook");
300+ application->setIcon(QUrl("facebook"));
269− application->setExec("/usr/bin/webbrowser-app --chromeless http://m.facebook.com");
270 application->setStage(ApplicationInfo::SideStage);
301 application->setStage(ApplicationInfo::SideStage);
271− application->setHandle(nextHandle++);
272 generateQmlStrings(application);
302 generateQmlStrings(application);
273 m_availableApplications.append(application);
303 m_availableApplications.append(application);
274
304
275 application = new ApplicationInfo(this);
305 application = new ApplicationInfo(this);
276− application->setDesktopFile("/usr/share/applications/webbrowser-app.desktop");
306+ application->setAppId("webbrowser-app");
277 application->setName("Browser");
307 application->setName("Browser");
278− application->setIcon("browser");
308+ application->setIcon(QUrl("browser"));
279− application->setExec("/usr/bin/webbrowser-app");
280− application->setHandle(nextHandle++);
281 generateQmlStrings(application);
309 generateQmlStrings(application);
282 m_availableApplications.append(application);
310 m_availableApplications.append(application);
283
311
284 application = new ApplicationInfo(this);
312 application = new ApplicationInfo(this);
285− application->setDesktopFile("/usr/share/applications/twitter-webapp.desktop");
313+ application->setAppId("twitter-webapp");
286 application->setName("Twitter");
314 application->setName("Twitter");
287− application->setIcon("twitter");
315+ application->setIcon(QUrl("twitter"));
288− application->setExec("/usr/bin/webbrowser-app --chromeless http://www.twitter.com");
289 application->setStage(ApplicationInfo::SideStage);
316 application->setStage(ApplicationInfo::SideStage);
290− application->setHandle(nextHandle++);
291 generateQmlStrings(application);
317 generateQmlStrings(application);
292 m_availableApplications.append(application);
318 m_availableApplications.append(application);
293
319
294 application = new ApplicationInfo(this);
320 application = new ApplicationInfo(this);
295− application->setDesktopFile("/usr/share/applications/gmail-webapp.desktop");
321+ application->setAppId("gmail-webapp");
296 application->setName("GMail");
322 application->setName("GMail");
297− application->setIcon("gmail");
323+ application->setIcon(QUrl("gmail"));
298− application->setExec("/usr/bin/webbrowser-app --chromeless http://m.gmail.com");
299− application->setHandle(nextHandle++);
300 m_availableApplications.append(application);
324 m_availableApplications.append(application);
301
325
302 application = new ApplicationInfo(this);
326 application = new ApplicationInfo(this);
303− application->setDesktopFile("/usr/share/applications/ubuntu-weather-app.desktop");
327+ application->setAppId("ubuntu-weather-app");
304 application->setName("Weather");
328 application->setName("Weather");
305− application->setIcon("weather");
329+ application->setIcon(QUrl("weather"));
306− application->setExec("/usr/bin/qmlscene /usr/share/ubuntu-weather-app/ubuntu-weather-app.qml");
307 application->setStage(ApplicationInfo::SideStage);
330 application->setStage(ApplicationInfo::SideStage);
308− application->setHandle(nextHandle++);
309 generateQmlStrings(application);
331 generateQmlStrings(application);
310 m_availableApplications.append(application);
332 m_availableApplications.append(application);
311
333
312 application = new ApplicationInfo(this);
334 application = new ApplicationInfo(this);
313− application->setDesktopFile("/usr/share/applications/notes-app.desktop");
335+ application->setAppId("notes-app");
314 application->setName("Notepad");
336 application->setName("Notepad");
315− application->setIcon("notepad");
337+ application->setIcon(QUrl("notepad"));
316− application->setExec("/usr/bin/qmlscene /usr/share/notes-app/NotesApp.qml");
317 application->setStage(ApplicationInfo::SideStage);
338 application->setStage(ApplicationInfo::SideStage);
318− application->setHandle(nextHandle++);
319 m_availableApplications.append(application);
339 m_availableApplications.append(application);
320
340
321 application = new ApplicationInfo(this);
341 application = new ApplicationInfo(this);
322− application->setDesktopFile("/usr/share/applications/calendar-app.desktop");
342+ application->setAppId("calendar-app");
323 application->setName("Calendar");
343 application->setName("Calendar");
324− application->setIcon("calendar");
344+ application->setIcon(QUrl("calendar"));
325− application->setExec("/usr/bin/qmlscene /usr/share/calendar-app/calendar.qml");
326 application->setStage(ApplicationInfo::SideStage);
345 application->setStage(ApplicationInfo::SideStage);
327− application->setHandle(nextHandle++);
328 m_availableApplications.append(application);
346 m_availableApplications.append(application);
329
347
330 application = new ApplicationInfo(this);
348 application = new ApplicationInfo(this);
331− application->setDesktopFile("/usr/share/applications/mediaplayer-app.desktop");
349+ application->setAppId("mediaplayer-app");
332 application->setName("Media Player");
350 application->setName("Media Player");
333− application->setIcon("mediaplayer-app");
351+ application->setIcon(QUrl("mediaplayer-app"));
334 application->setFullscreen(true);
352 application->setFullscreen(true);
335− application->setExec("/usr/bin/mediaplayer-app");
336− application->setHandle(nextHandle++);
337 m_availableApplications.append(application);
353 m_availableApplications.append(application);
338
354
339 application = new ApplicationInfo(this);
355 application = new ApplicationInfo(this);
340− application->setDesktopFile("/usr/share/applications/evernote.desktop");
356+ application->setAppId("evernote");
341 application->setName("Evernote");
357 application->setName("Evernote");
342− application->setIcon("evernote");
358+ application->setIcon(QUrl("evernote"));
343− application->setHandle(nextHandle++);
344 m_availableApplications.append(application);
359 m_availableApplications.append(application);
345
360
346 application = new ApplicationInfo(this);
361 application = new ApplicationInfo(this);
347− application->setDesktopFile("/usr/share/applications/map.desktop");
362+ application->setAppId("map");
348 application->setName("Map");
363 application->setName("Map");
349− application->setIcon("map");
364+ application->setIcon(QUrl("map"));
350− application->setHandle(nextHandle++);
351 generateQmlStrings(application);
365 generateQmlStrings(application);
352 m_availableApplications.append(application);
366 m_availableApplications.append(application);
353
367
354 application = new ApplicationInfo(this);
368 application = new ApplicationInfo(this);
355− application->setDesktopFile("/usr/share/applications/pinterest.desktop");
369+ application->setAppId("pinterest");
356 application->setName("Pinterest");
370 application->setName("Pinterest");
357− application->setIcon("pinterest");
371+ application->setIcon(QUrl("pinterest"));
358− application->setHandle(nextHandle++);
359 m_availableApplications.append(application);
372 m_availableApplications.append(application);
360
373
361 application = new ApplicationInfo(this);
374 application = new ApplicationInfo(this);
362− application->setDesktopFile("/usr/share/applications/soundcloud.desktop");
375+ application->setAppId("soundcloud");
363 application->setName("SoundCloud");
376 application->setName("SoundCloud");
364− application->setIcon("soundcloud");
377+ application->setIcon(QUrl("soundcloud"));
365− application->setHandle(nextHandle++);
366 m_availableApplications.append(application);
378 m_availableApplications.append(application);
367
379
368 application = new ApplicationInfo(this);
380 application = new ApplicationInfo(this);
369− application->setDesktopFile("/usr/share/applications/wikipedia.desktop");
381+ application->setAppId("wikipedia");
370 application->setName("Wikipedia");
382 application->setName("Wikipedia");
371− application->setIcon("wikipedia");
383+ application->setIcon(QUrl("wikipedia"));
372− application->setHandle(nextHandle++);
373 m_availableApplications.append(application);
384 m_availableApplications.append(application);
374
385
375 application = new ApplicationInfo(this);
386 application = new ApplicationInfo(this);
376− application->setDesktopFile("/usr/share/applications/youtube.desktop");
387+ application->setAppId("youtube");
377 application->setName("YouTube");
388 application->setName("YouTube");
378− application->setIcon("youtube");
389+ application->setIcon(QUrl("youtube"));
379− application->setHandle(nextHandle++);
380 m_availableApplications.append(application);
390 m_availableApplications.append(application);
381}
391}
382
392
tests/mocks/Unity/Application/ApplicationManager.h+34−26
@@ -20,14 +20,18 @@
20#include <QObject>
20#include <QObject>
21#include <QList>
21#include <QList>
22#include <QStringList>
22#include <QStringList>
23−#include "ApplicationListModel.h"
24#include "ApplicationInfo.h"
23#include "ApplicationInfo.h"
25
24
25+// unity-api
26+#include <unity/shell/application/ApplicationManagerInterface.h>
27+
26class QQuickItem;
28class QQuickItem;
29+using namespace unity::shell::application;
27
30
28−class ApplicationManager : public QObject {
31+class ApplicationManager : public ApplicationManagerInterface {
29 Q_OBJECT
32 Q_OBJECT
30 Q_ENUMS(Role)
33 Q_ENUMS(Role)
34+ Q_ENUMS(Roles) //inherited, but want to expose to QML
31 Q_ENUMS(StageHint)
35 Q_ENUMS(StageHint)
32 Q_ENUMS(FormFactorHint)
36 Q_ENUMS(FormFactorHint)
33 Q_ENUMS(FavoriteApplication)
37 Q_ENUMS(FavoriteApplication)
@@ -39,12 +43,6 @@ class ApplicationManager : public QObject {
39 Q_PROPERTY(int sideStageWidth READ sideStageWidth)
43 Q_PROPERTY(int sideStageWidth READ sideStageWidth)
40 Q_PROPERTY(StageHint stageHint READ stageHint)
44 Q_PROPERTY(StageHint stageHint READ stageHint)
41 Q_PROPERTY(FormFactorHint formFactorHint READ formFactorHint)
45 Q_PROPERTY(FormFactorHint formFactorHint READ formFactorHint)
42− Q_PROPERTY(ApplicationListModel* mainStageApplications READ mainStageApplications)
43− Q_PROPERTY(ApplicationListModel* sideStageApplications READ sideStageApplications)
44− Q_PROPERTY(ApplicationInfo* mainStageFocusedApplication READ mainStageFocusedApplication
45− NOTIFY mainStageFocusedApplicationChanged)
46− Q_PROPERTY(ApplicationInfo* sideStageFocusedApplication READ sideStageFocusedApplication
47− NOTIFY sideStageFocusedApplicationChanged)
48
46
49 Q_PROPERTY(bool fake READ fake CONSTANT)
47 Q_PROPERTY(bool fake READ fake CONSTANT)
50
48
@@ -64,39 +62,52 @@ class ApplicationManager : public QObject {
64 DesktopFormFactor, PhoneFormFactor, TabletFormFactor
62 DesktopFormFactor, PhoneFormFactor, TabletFormFactor
65 };
63 };
66 enum FavoriteApplication {
64 enum FavoriteApplication {
67− CameraApplication, GalleryApplication, BrowserApplication, ShareApplication
65+ CameraApplication, GalleryApplication, BrowserApplication, ShareApplication,
66+ PhoneApplication, DialerApplication, MessagingApplication, AddressbookApplication
68 };
67 };
69 enum Flag {
68 enum Flag {
70 NoFlag = 0x0,
69 NoFlag = 0x0,
71 ForceMainStage = 0x1,
70 ForceMainStage = 0x1,
72 };
71 };
73 Q_DECLARE_FLAGS(ExecFlags, Flag)
72 Q_DECLARE_FLAGS(ExecFlags, Flag)
73+ enum Roles { // Q_ENUM of inherited Roles doesn't work?!?!?!
74+ RoleAppId = Qt::UserRole,
75+ RoleName,
76+ RoleComment,
77+ RoleIcon,
78+ RoleStage,
79+ RoleState,
80+ RoleFocused,
81+ };
74
82
75 int keyboardHeight() const;
83 int keyboardHeight() const;
76 bool keyboardVisible() const;
84 bool keyboardVisible() const;
77 int sideStageWidth() const;
85 int sideStageWidth() const;
78 StageHint stageHint() const;
86 StageHint stageHint() const;
79 FormFactorHint formFactorHint() const;
87 FormFactorHint formFactorHint() const;
80− ApplicationListModel* mainStageApplications() const;
81− ApplicationListModel* sideStageApplications() const;
82− ApplicationInfo* mainStageFocusedApplication() const;
83− ApplicationInfo* sideStageFocusedApplication() const;
84
88
85 bool fake() { return true; }
89 bool fake() { return true; }
86
90
87− Q_INVOKABLE void focusApplication(int handle);
91+ // QAbstractItemModel methods.
92+ int rowCount(const QModelIndex& parent = QModelIndex()) const override;
93+ QVariant data(const QModelIndex& index, int role) const override;
94+ Q_INVOKABLE ApplicationInfo *get(int index) const override;
95+ Q_INVOKABLE ApplicationInfo *findApplication(const QString &appId) const override;
96+
97+ Q_INVOKABLE void move(int from, int to);
98+
99+ // Application control methods
100+ Q_INVOKABLE bool focusApplication(const QString &appId) override;
88− Q_INVOKABLE void unfocusCurrentApplication(StageHint stageHint);
101+ Q_INVOKABLE void unfocusCurrentApplication() override;
89− Q_INVOKABLE ApplicationInfo* startProcess(QString desktopFile,
102+ Q_INVOKABLE ApplicationInfo *startApplication(const QString &appId, const QStringList &arguments = QStringList()) override;
90− ExecFlags flags,
91− QStringList arguments = QStringList());
103+ Q_INVOKABLE ApplicationInfo *startApplication(const QString &appId, ExecFlags flags, const QStringList &arguments = QStringList());
92− Q_INVOKABLE void stopProcess(ApplicationInfo* application);
104+ Q_INVOKABLE bool stopApplication(const QString &appId) override;
93− Q_INVOKABLE void startWatcher() {}
105+
106+ QString focusedApplicationId() const override;
94
107
95 Q_SIGNALS:
108 Q_SIGNALS:
96 void keyboardHeightChanged();
109 void keyboardHeightChanged();
97 void keyboardVisibleChanged();
110 void keyboardVisibleChanged();
98− void mainStageFocusedApplicationChanged();
99− void sideStageFocusedApplicationChanged();
100 void focusRequested(FavoriteApplication favoriteApplication);
111 void focusRequested(FavoriteApplication favoriteApplication);
101
112
102 private:
113 private:
@@ -109,10 +120,7 @@ class ApplicationManager : public QObject {
109 void createSideStage();
120 void createSideStage();
110 int m_keyboardHeight;
121 int m_keyboardHeight;
111 bool m_keyboardVisible;
122 bool m_keyboardVisible;
112− ApplicationListModel* m_mainStageApplications;
123+ QList<ApplicationInfo*> m_runningApplications;
113− ApplicationListModel* m_sideStageApplications;
114− ApplicationInfo* m_mainStageFocusedApplication;
115− ApplicationInfo* m_sideStageFocusedApplication;
116 QList<ApplicationInfo*> m_availableApplications;
124 QList<ApplicationInfo*> m_availableApplications;
117 QQmlComponent *m_mainStageComponent;
125 QQmlComponent *m_mainStageComponent;
118 QQuickItem *m_mainStage;
126 QQuickItem *m_mainStage;
tests/mocks/Unity/Application/CMakeLists.txt+5−1
@@ -1,9 +1,13 @@
1+include(FindPkgConfig)
2+pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application)
3+
1set(FakeUnityApplicationQml_SOURCES
4set(FakeUnityApplicationQml_SOURCES
2 plugin.cpp
5 plugin.cpp
3 ApplicationInfo.cpp
6 ApplicationInfo.cpp
4 ApplicationImage.cpp
7 ApplicationImage.cpp
5− ApplicationListModel.cpp
6 ApplicationManager.cpp
8 ApplicationManager.cpp
9+ ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationInfoInterface.h
10+ ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationManagerInterface.h
7)
11)
8
12
9add_library(FakeUnityApplicationQml MODULE ${FakeUnityApplicationQml_SOURCES})
13add_library(FakeUnityApplicationQml MODULE ${FakeUnityApplicationQml_SOURCES})
tests/mocks/Unity/Application/plugin.cpp−2
@@ -17,7 +17,6 @@
17#include "plugin.h"
17#include "plugin.h"
18#include "ApplicationInfo.h"
18#include "ApplicationInfo.h"
19#include "ApplicationImage.h"
19#include "ApplicationImage.h"
20−#include "ApplicationListModel.h"
21#include "ApplicationManager.h"
20#include "ApplicationManager.h"
22
21
23#include <qqml.h>
22#include <qqml.h>
@@ -34,5 +33,4 @@ void FakeUnityApplicationQmlPlugin::registerTypes(const char *uri)
34 uri, 0, 1, "ApplicationManager", applicationManagerSingleton);
33 uri, 0, 1, "ApplicationManager", applicationManagerSingleton);
35 qmlRegisterType<ApplicationInfo>(uri, 0, 1, "ApplicationInfo");
34 qmlRegisterType<ApplicationInfo>(uri, 0, 1, "ApplicationInfo");
36 qmlRegisterType<ApplicationImage>(uri, 0, 1, "ApplicationImage");
35 qmlRegisterType<ApplicationImage>(uri, 0, 1, "ApplicationImage");
37− qmlRegisterType<ApplicationListModel>(uri, 0, 1, "ApplicationListModel");
38}
36}