on xenial help sign in
Need to expand capability of QSortFilterProxyModelQML to explicitly emit signal on any row manipulations. With this can fix much behaviours in shell. The main & side stage focused apps are now working
commitd835e2a0f600f6f96935d4aadc2284c7982784fd authorGerry Boland <gerry.boland@canonical.com> dateWed 4 Sep 2013, 19:35 (13 years ago) parent527a6ca
8 files changed+109−42
Components/ApplicationManagerWrapper.qml+26−33 Components/ApplicationScreenshot.qml+1−1 Components/ApplicationsModelStageFiltered.qml+54 Components/Stage.qml+3−3 Dash/Apps/RunningApplicationTile.qml+1−1 Dash/Apps/RunningApplicationsGrid.qml+4−4 plugins/Utils/qsortfilterproxymodelqml.cpp+18 plugins/Utils/qsortfilterproxymodelqml.h+2
Components/ApplicationManagerWrapper.qml+26−33
@@ -16,15 +16,14 @@
1616
1717import QtQuick 2.0
1818import Unity.Application 0.1
19−import Utils 0.1
2019
2120Item {
2221 id: applicationManager
2322
24− property var mainStageApplications: mainStageModel
25− property var sideStageApplications: sideStageModel
26− property var mainStageFocusedApplication: null
27− property var sideStageFocusedApplication: null
23+ property alias mainStageApplications: mainStageModel
24+ property alias sideStageApplications: sideStageModel
25+ property alias mainStageFocusedApplication: mainStageModel.focusedApplication
26+ property alias sideStageFocusedApplication: sideStageModel.focusedApplication
2827 property bool sideStageEnabled: true
2928 signal focusRequested(string desktopFile)
3029 property bool keyboardVisible: ApplicationManager.keyboardVisible
@@ -32,39 +31,21 @@ Item {
3231
3332 property bool fake: ApplicationManager.fake ? ApplicationManager.fake : false
3433
35− SortFilterProxyModel {
34+ ApplicationsModelStageFiltered {
3635 id: mainStageModel
37− model: ApplicationManager
38− dynamicSortFilter: true
39− filterRole: ApplicationManager.RoleStage
40− filterRegExp: RegExp(ApplicationInfo.MainStage)
41−
42− onCountChanged: { print("MODEL Main:", count, ApplicationManager.RoleStage, ApplicationManager.RoleFocused)
43− mainStageFocusedApplication = ApplicationManager.get(mainStageModel.findFirst(ApplicationManager.RoleFocused, true));
44− print("MS", mainStageFocusedApplication)
45− }
46− onLayoutChanged: print("LAYOUT")
47− onDataChanged: print("DATA")
36+ stage: ApplicationInfo.MainStage
4837 }
4938
50− SortFilterProxyModel {
39+ ApplicationsModelStageFiltered {
5140 id: sideStageModel
52− model: ApplicationManager
53− dynamicSortFilter: true
54− filterRole: ApplicationManager.RoleStage
55− filterRegExp: RegExp(ApplicationInfo.SideStage)
56−
57− onDataChanged: { print("MODEL Side", count)
58− sideStageFocusedApplication = ApplicationManager.get(sideStageModel.findFirst(ApplicationManager.RoleFocused, true));
59− print("SS", sideStageFocusedApplication)
60− }
41+ stage: ApplicationInfo.SideStage
6142 }
6243
6344 function activateApplication(desktopFile, argument) {
6445 var appId;
6546
6647 // HACK: might be called with appId, but mostly with desktopFile
67− if (desktopFile.indexOf(".desktop") = -1) {
48+ if (desktopFile.indexOf(".desktop") >= 0) {
6849 appId = desktopFileToAppId(desktopFile);
6950 } else {
7051 appId = desktopFile;
@@ -97,7 +78,7 @@ Item {
9778 ApplicationManager.stopProcess(appId);
9879 }
9980
100− function focusApplication(application) {
81+ function focusApplication(application) {print("focusApplication", application.appId)
10182 if (application == null || application == undefined) {
10283 return;
10384 }
@@ -109,13 +90,25 @@ Item {
10990 ApplicationManager.unfocusCurrentApplication();
11091 }
11192
112− function moveRunningApplicationStackPosition(from, to, stage) { //FIXME: stage unused!
113− if (from !== to && from >= 0 && to >= 0) ApplicationManager.move(from, to);
93+ function moveRunningApplicationStackPosition(from, to, stage) { print("moveRunningApplicationStackPosition", from, to, stage)
94+ if (from == to || from < 0 || to < 0) return;
95+
96+ if (stage == ApplicationInfo.SideStage) {
97+ sideStageModel.move(from, to);
98+ } else {
99+ mainStageModel.move(from, to);
100+ }
114101 }
115102
116103 function getApplicationFromDesktopFile(desktopFile, stage) {
117− var foundSideStageApp, foundMainStageApp;
118− var appId = desktopFileToAppId(desktopFile);
104+ var appId;
105+
106+ // HACK: might be called with appId, but mostly with desktopFile
107+ if (desktopFile.indexOf(".desktop") >= 0) {
108+ appId = desktopFileToAppId(desktopFile);
109+ } else {
110+ appId = desktopFile;
111+ }
119112
120113 for (var i = 0, len = ApplicationManager.count; i < len; i++ ) {
121114 var app = ApplicationManager.get(i);
Components/ApplicationScreenshot.qml+1−1
@@ -25,7 +25,7 @@ Item {
2525 property bool withBackground: false
2626 property bool ready: applicationImage.ready || withBackground
2727
28− function setApplication(application) {
28+ function setApplication(application) { print("SET APP", application, (application) ? application.appId : "")
2929 applicationScreenshot.application = application
3030 }
3131
Components/ApplicationsModelStageFiltered.qmlnew file+54
@@ -0,0 +1,54 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Utils 0.1
19+import Unity.Application 0.1
20+
21+SortFilterProxyModel {
22+ id: root
23+ property int stage
24+ property variant focusedApplication: null
25+
26+ function get(index) {
27+ print("GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG get", index)
28+ return ApplicationManager.get(mapRowToSource(index));
29+ }
30+
31+ function move(from, to) {
32+ var realFrom = mapRowToSource(from);
33+ if (realFrom == -1) {
34+ console.log("ERROR; invalid from=" + from + " index in move operation");
35+ return;
36+ }
37+ var realTo = mapRowToSource(to);
38+ if (realTo == -1) {
39+ // assuming wanting to move to end of list
40+ realTo = ApplicationManager.count;
41+ }
42+ ApplicationManager.move(realFrom, realTo);
43+ }
44+
45+ model: ApplicationManager
46+ dynamicSortFilter: true
47+ filterRole: ApplicationManager.RoleStage
48+ filterRegExp: RegExp(stage)
49+
50+ onLayoutChanged: {
51+ focusedApplication = get(0);
52+ print("LAYOUT CHANGED", focusedApplication.appId)
53+ }
54+}
Components/Stage.qml+3−3
@@ -142,7 +142,7 @@ Showable {
142142 oldApplicationScreenshot.visible = false;
143143 }
144144
145− function __focusApplication(application) {
145+ function __focusApplication(application) { print("__focusApplication", application)
146146 if (!application) return
147147 if (shouldUseScreenshots) {
148148 stage.__focusApplicationUsingScreenshots(application);
@@ -267,7 +267,7 @@ Showable {
267267 SequentialAnimation {
268268 id: showStartingApplicationAnimation
269269
270− function prepare(newApplication) {
270+ function prepare(newApplication) { print("showStartingApplicationAnimation::prepare", newApplication)
271271 var oldApplication = stage.focusedApplication;
272272 newApplicationScreenshot.setApplication(newApplication);
273273 newApplicationScreenshot.updateFromCache();
@@ -336,7 +336,7 @@ Showable {
336336 SequentialAnimation {
337337 id: switchToApplicationAnimation
338338
339− function prepare(newApplication) {
339+ function prepare(newApplication) { print("switchToApplicationAnimation::prepare", newApplication)
340340 var oldApplication = stage.focusedApplication;
341341 newApplicationScreenshot.setApplication(newApplication);
342342 newApplicationScreenshot.updateFromCache();
Dash/Apps/RunningApplicationTile.qml+1−1
@@ -76,7 +76,7 @@ AbstractButton {
7676
7777 ApplicationImage {
7878 id: applicationImage
79− source: application
79+ source: ApplicationManager.findApplication((application) ? application.appId : "")
8080 width: shapedApplicationImage.width
8181 height: shapedApplicationImage.height
8282 fillMode: ApplicationImage.PreserveAspectCrop
Dash/Apps/RunningApplicationsGrid.qml+4−4
@@ -52,22 +52,22 @@ ResponsiveFlowView {
5252
5353 RunningApplicationTile {
5454 id: runningAppTile
55− objectName: "runningAppTile " + model.application.name
55+ objectName: "runningAppTile " + model.name
5656 anchors {
5757 top: parent.top
5858 horizontalCenter: parent.horizontalCenter
5959 }
60− application: model.application
60+ application: model
6161 onRequestedActivationMode: { root.terminationModeEnabled = false }
6262 onRequestedTerminationMode: {
6363 if (canEnableTerminationMode)
6464 root.terminationModeEnabled = true
6565 }
6666 onRequestedApplicationTermination: {
67− shell.applicationManager.stopProcess(application)
67+ shell.applicationManager.stopApplication(model.appId)
6868 }
6969 onRequestedApplicationActivation: {
70− shell.activateApplication(application.desktopFile)
70+ shell.activateApplication(model.appId)
7171 }
7272
7373 terminationModeEnabled: root.terminationModeEnabled
plugins/Utils/qsortfilterproxymodelqml.cpp+18
@@ -29,6 +29,17 @@ QSortFilterProxyModelQML::QSortFilterProxyModelQML(QObject *parent)
2929 connect(this, SIGNAL(rowsRemoved(QModelIndex,int,int)), SIGNAL(countChanged()));
3030}
3131
32+/*
33+ * Enter row index of filtered/sorted model, returns row index of source model
34+ */
35+int QSortFilterProxyModelQML::mapRowToSource(int row)
36+{
37+ if (sourceModel() == NULL)
38+ return -1;
39+
40+ return QSortFilterProxyModel::mapToSource(index(row, 0)).row();
41+}
42+
3243QHash<int, QByteArray> QSortFilterProxyModelQML::roleNames() const
3344{
3445 return sourceModel() ? sourceModel()->roleNames() : QHash<int, QByteArray>();
@@ -51,7 +62,14 @@ QSortFilterProxyModelQML::setModel(QAbstractItemModel *itemModel)
5162 connect(itemModel, SIGNAL(modelReset()), SIGNAL(totalCountChanged()));
5263 connect(itemModel, SIGNAL(rowsInserted(QModelIndex,int,int)), SIGNAL(totalCountChanged()));
5364 connect(itemModel, SIGNAL(rowsRemoved(QModelIndex,int,int)), SIGNAL(totalCountChanged()));
65+
66+ connect(itemModel, SIGNAL(modelReset()), SIGNAL(layoutChanged()));
67+ connect(itemModel, SIGNAL(rowsInserted(QModelIndex,int,int)), SIGNAL(layoutChanged()));
68+ connect(itemModel, SIGNAL(rowsRemoved(QModelIndex,int,int)), SIGNAL(layoutChanged()));
69+ connect(itemModel, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)), SIGNAL(layoutChanged()));
70+
5471 Q_EMIT totalCountChanged();
72+ Q_EMIT layoutChanged();
5573 Q_EMIT modelChanged();
5674 }
5775}
plugins/Utils/qsortfilterproxymodelqml.h+2
@@ -34,6 +34,7 @@ public:
3434 Q_INVOKABLE QVariant data(int row, int role);
3535 Q_INVOKABLE int count();
3636 Q_INVOKABLE int findFirst(int role, const QVariant& value) const;
37+ Q_INVOKABLE int mapRowToSource(int row);
3738 virtual bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
3839
3940 /* getters */
@@ -50,6 +51,7 @@ Q_SIGNALS:
5051 void countChanged();
5152 void invertMatchChanged(bool);
5253 void modelChanged();
54+ void layoutChanged();
5355
5456private:
5557 bool m_invertMatch;