on b3c03fa help sign in
unity8/plugins/WindowManager/WorkspaceModel.cpp
187 lines 5.2 kB history raw
1/*
2 * Copyright (C) 2017 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 */
17#include "WorkspaceModel.h"
18#include "WorkspaceManager.h"
19#include "Workspace.h"
21Q_LOGGING_CATEGORY(WORKSPACES, "Workspaces", QtInfoMsg)
23#define DEBUG_MSG qCDebug(WORKSPACES).nospace().noquote() << __func__
24#define INFO_MSG qCInfo(WORKSPACES).nospace().noquote() << __func__
26WorkspaceModel::WorkspaceModel(QObject *parent)
27 : QAbstractListModel(parent)
31void WorkspaceModel::append(Workspace *workspace)
33 insert(m_workspaces.count(), workspace);
36void WorkspaceModel::insert(int index, Workspace *workspace)
38 beginInsertRows(QModelIndex(), index, index);
40 m_workspaces.insert(index, workspace);
42 endInsertRows();
44 Q_EMIT workspaceAdded(workspace);
45 Q_EMIT countChanged();
48void WorkspaceModel::remove(Workspace *workspace)
50 int index = m_workspaces.indexOf(workspace);
51 if (index < 0) return;
53 beginRemoveRows(QModelIndex(), index, index);
55 m_workspaces.removeAt(index);
57 endRemoveRows();
59 Q_EMIT workspaceRemoved(workspace);
60 Q_EMIT countChanged();
63void WorkspaceModel::move(int from, int to)
65 if (from == to) return;
66 DEBUG_MSG << " from=" << from << " to=" << to;
68 if (from >= 0 && from < m_workspaces.size() && to >= 0 && to < m_workspaces.size()) {
69 QModelIndex parent;
71 beginMoveRows(parent, from, from, parent, to + (to > from ? 1 : 0));
72#if QT_VERSION < QT_VERSION_CHECK(5, 6, 0)
73 const auto &window = m_windowModel.takeAt(from);
74 m_workspaces.insert(to, window);
75#else
76 m_workspaces.move(from, to);
77#endif
78 endMoveRows();
79 Q_EMIT countChanged();
80 }
83int WorkspaceModel::indexOf(Workspace *workspace) const
85 return m_workspaces.indexOf(workspace);
88Workspace *WorkspaceModel::get(int index) const
90 if (index < 0 || index >= rowCount()) return nullptr;
91 return m_workspaces.at(index);
94int WorkspaceModel::rowCount(const QModelIndex &) const
96 return m_workspaces.count();
99QVariant WorkspaceModel::data(const QModelIndex &index, int role) const
101 if (index.row() < 0 || index.row() >= m_workspaces.size())
102 return QVariant();
104 if (role == WorkspaceRole) {
105 Workspace *workspace = m_workspaces.at(index.row());
106 return QVariant::fromValue(workspace);
107 } else {
108 return QVariant();
109 }
112void WorkspaceModel::sync(WorkspaceModel *proxy)
114 if (!proxy) return;
115 const auto& proxyList = proxy->list();
117 // check for removals
118 int removedIndexWhichWasActive = -1;
119 QVector<Workspace*> dpCpy(this->list());
120 Q_FOREACH(auto workspace, dpCpy) {
122 bool found = false;
123 Q_FOREACH(auto p, proxyList) {
124 auto workspaceProxy = static_cast<WorkspaceProxy*>(p);
125 if (workspaceProxy->proxyObject() == workspace) {
126 found = true;
127 break;
128 }
129 }
130 if (!found) {
131 if (workspace->isActive()) {
132 removedIndexWhichWasActive = indexOf(workspace);
133 }
134 workspace->unassign();
135 }
136 }
138 // existing
139 QSet<Workspace*> newWorkspaces;
140 for (int i = 0; i < proxyList.count(); i++) {
141 auto workspaceProxy = static_cast<WorkspaceProxy*>(proxyList[i]);
142 auto workspace = workspaceProxy->proxyObject();
144 int oldIndex = this->indexOf(workspace);
146 if (oldIndex < 0) {
147 workspace->assign(this, QVariant(i));
148 } else if (oldIndex != i) {
149 this->move(oldIndex, i);
150 }
151 newWorkspaces.insert(workspace);
152 }
154 // Make sure we have at least one workspace in the model.
155 if (rowCount() == 0) {
156 Workspace* workspace = WorkspaceManager::instance()->createWorkspace();
157 workspace->assign(this);
158 (new WorkspaceProxy(workspace))->assign(proxy);
159 }
161 if (removedIndexWhichWasActive != -1) {
162 int newActiveIndex = qMin(removedIndexWhichWasActive, this->rowCount()-1);
163 Workspace* newActiveWorkspace = newActiveIndex >= 0 ? this->get(newActiveIndex) : nullptr;
165 WorkspaceManager::instance()->setActiveWorkspace(newActiveWorkspace);
166 }
170WorkspaceModelProxy::WorkspaceModelProxy(WorkspaceModel * const model)
171 : m_original(model)
173 Q_FOREACH(auto workspace, model->list()) {
174 (new WorkspaceProxy(workspace))->assign(this);
175 }
178WorkspaceModelProxy::~WorkspaceModelProxy()
180 qDeleteAll(m_workspaces.toList()); // make a copy so the list doesnt edit itself during delete.
181 m_workspaces.clear();
184void WorkspaceModelProxy::move(int from, int to)
186 WorkspaceModel::move(from, to);