QtCanpool 3.3.0
载入中...
搜索中...
未找到
qxworkspacemanager.cpp
浏览该文件的文档.
1
7
8#include "qxappshell.h"
9
10#include "qxdock/dockwindow.h"
11
12#include <QtCore/QDebug>
13
16
18
19namespace
20{
21
27const char *const kGroup = "ui";
28const char *const kNamesKey = "workspaceNames";
29const char *const kCurrentKey = "currentWorkspace";
31const char *const kWorkspaceGroup = "workspace";
32const char *const kDockStateKey = "dockState";
33const char *const kPageKey = "currentPage";
34
35} // namespace
36
37QxWorkspaceManagerPrivate::QxWorkspaceManagerPrivate() = default;
38
39QX_CORE_PREPEND_NAMESPACE(QxSettings) * QxWorkspaceManagerPrivate::settings() const
40{
41 // The shell creates its settings object on first use and owns it, so this
42 // is never a borrowed pointer that has to be kept alive here.
43 return m_shell ? m_shell->settings() : Q_NULLPTR;
44}
45
46QStringList QxWorkspaceManagerPrivate::names() const
47{
48 QX_CORE_PREPEND_NAMESPACE(QxSettings) *settings = this->settings();
49 if (!settings) {
50 return QStringList();
51 }
52
53 settings->beginGroup(QString::fromLatin1(kGroup));
54 const QStringList list = settings->stringListValue(QString::fromLatin1(kNamesKey));
55 settings->endGroup();
56 return list;
57}
58
59void QxWorkspaceManagerPrivate::setNames(const QStringList &list)
60{
61 QX_CORE_PREPEND_NAMESPACE(QxSettings) *settings = this->settings();
62 if (!settings) {
63 return;
64 }
65
66 settings->beginGroup(QString::fromLatin1(kGroup));
67 if (list.isEmpty()) {
68 // An empty list is a key no reader has to special-case.
69 settings->remove(QString::fromLatin1(kNamesKey));
70 } else {
71 settings->setValue(QString::fromLatin1(kNamesKey), list);
72 }
73 settings->endGroup();
74}
75
76QString QxWorkspaceManagerPrivate::normalize(const QString &name)
77{
78 return name.trimmed();
79}
80
81QString QxWorkspaceManagerPrivate::current() const
82{
83 QX_CORE_PREPEND_NAMESPACE(QxSettings) *settings = this->settings();
84 if (!settings) {
85 return QString();
86 }
87
88 settings->beginGroup(QString::fromLatin1(kGroup));
89 const QString name = settings->stringValue(QString::fromLatin1(kCurrentKey));
90 settings->endGroup();
91 return name;
92}
93
94void QxWorkspaceManagerPrivate::setCurrent(const QString &name)
95{
97
98 QX_CORE_PREPEND_NAMESPACE(QxSettings) *settings = this->settings();
99 if (!settings) {
100 return;
101 }
102
103 const QString previous = current();
104 if (previous == name) {
105 return;
106 }
107
108 settings->beginGroup(QString::fromLatin1(kGroup));
109 if (name.isEmpty()) {
110 settings->remove(QString::fromLatin1(kCurrentKey));
111 } else {
112 settings->setValue(QString::fromLatin1(kCurrentKey), name);
113 }
114 settings->endGroup();
115 settings->sync();
116
117 Q_EMIT q->currentWorkspaceChanged(name);
118}
119
120QxWorkspaceManager::QxWorkspaceManager(QxAppShell *shell, QObject *parent)
121 : QObject(parent)
122 , d_ptr(new QxWorkspaceManagerPrivate())
123{
124 d_ptr->setPublic(this);
125 d_ptr->m_shell = shell;
126}
127
132
134{
135 Q_D(const QxWorkspaceManager);
136 return d->m_shell;
137}
138
140{
141 Q_D(const QxWorkspaceManager);
142 return d->settings();
143}
144
146{
147 Q_D(const QxWorkspaceManager);
148 return d->names().count();
149}
150
152{
153 Q_D(const QxWorkspaceManager);
154 return d->names();
155}
156
157bool QxWorkspaceManager::contains(const QString &name) const
158{
159 Q_D(const QxWorkspaceManager);
160 return d->names().contains(QxWorkspaceManagerPrivate::normalize(name));
161}
162
164{
165 Q_D(const QxWorkspaceManager);
166 return d->current();
167}
168
170{
172 if (!d->m_shell) {
173 qWarning("QxWorkspaceManager: there is no shell to save a layout of");
174 return false;
175 }
176
177 const QString key = QxWorkspaceManagerPrivate::normalize(name);
178 if (key.isEmpty()) {
179 qWarning("QxWorkspaceManager: a workspace needs a name");
180 return false;
181 }
182
184
185 QStringList list = d->names();
186 if (!list.contains(key)) {
187 list.append(key);
188 }
189 d->setNames(list);
190
191 settings->beginGroup(QString::fromLatin1(kGroup));
192 settings->beginGroup(QString::fromLatin1(kWorkspaceGroup));
193 settings->beginGroup(key);
194 settings->setValue(QString::fromLatin1(kDockStateKey), d->m_shell->dockWindow()->saveState());
195 settings->setValue(QString::fromLatin1(kPageKey), d->m_shell->currentPageId());
199 settings->sync();
200
201 // Saving is also picking: the panels on screen are what the name now means.
202 d->setCurrent(key);
203 Q_EMIT workspaceSaved(key);
204 return true;
205}
206
208{
210 if (!d->m_shell) {
211 qWarning("QxWorkspaceManager: there is no shell to apply a layout to");
212 return false;
213 }
214
215 const QString key = QxWorkspaceManagerPrivate::normalize(name);
216 if (!d->names().contains(key)) {
217 qWarning("QxWorkspaceManager: there is no workspace called \"%s\"", qPrintable(key));
218 return false;
219 }
220
222 settings->beginGroup(QString::fromLatin1(kGroup));
223 settings->beginGroup(QString::fromLatin1(kWorkspaceGroup));
224 settings->beginGroup(key);
225 const QByteArray dockState = settings->value(QString::fromLatin1(kDockStateKey)).toByteArray();
226 const QString pageId = settings->stringValue(QString::fromLatin1(kPageKey));
230
231 if (dockState.isEmpty()) {
232 qWarning("QxWorkspaceManager: the workspace \"%s\" has no layout stored", qPrintable(key));
233 return false;
234 }
235 if (!d->m_shell->dockWindow()->restoreState(dockState)) {
236 // The usual reason is a dock of the arrangement that no longer exists.
237 // There is nothing to fall back to: a half-applied arrangement is worse
238 // than the one on screen.
239 qWarning("QxWorkspaceManager: the layout of \"%s\" does not fit this shell", qPrintable(key));
240 return false;
241 }
242
243 d->m_shell->setCurrentPage(pageId);
244 d->setCurrent(key);
245 Q_EMIT workspaceApplied(key);
246 return true;
247}
248
250{
252
253 const QString key = QxWorkspaceManagerPrivate::normalize(name);
254 QStringList list = d->names();
255 if (!list.removeOne(key)) {
256 return false;
257 }
258 d->setNames(list);
259
261 if (settings) {
262 settings->beginGroup(QString::fromLatin1(kGroup));
263 settings->beginGroup(QString::fromLatin1(kWorkspaceGroup));
264 // Removes the key and everything below it, which is the whole workspace.
265 settings->remove(key);
268 settings->sync();
269 }
270
271 if (d->current() == key) {
272 d->setCurrent(QString());
273 }
274 Q_EMIT workspaceRemoved(key);
275 return true;
276}
277
278bool QxWorkspaceManager::renameWorkspace(const QString &from, const QString &to)
279{
281
282 const QString oldKey = QxWorkspaceManagerPrivate::normalize(from);
283 const QString newKey = QxWorkspaceManagerPrivate::normalize(to);
284 if (oldKey.isEmpty() || newKey.isEmpty()) {
285 qWarning("QxWorkspaceManager: a workspace needs a name");
286 return false;
287 }
288
289 QStringList list = d->names();
290 const int index = list.indexOf(oldKey);
291 if (index < 0) {
292 return false;
293 }
294 if (oldKey == newKey) {
295 return true;
296 }
297 if (list.contains(newKey)) {
298 qWarning("QxWorkspaceManager: \"%s\" is already taken", qPrintable(newKey));
299 return false;
300 }
301
303 if (settings) {
304 settings->beginGroup(QString::fromLatin1(kGroup));
305 settings->beginGroup(QString::fromLatin1(kWorkspaceGroup));
306
307 settings->beginGroup(oldKey);
308 const QVariant dockState = settings->value(QString::fromLatin1(kDockStateKey));
309 const QString pageId = settings->stringValue(QString::fromLatin1(kPageKey));
311
312 settings->remove(oldKey);
313 settings->beginGroup(newKey);
314 settings->setValue(QString::fromLatin1(kDockStateKey), dockState);
315 settings->setValue(QString::fromLatin1(kPageKey), pageId);
317
320 }
321
322 list.replace(index, newKey);
323 d->setNames(list);
324 if (settings) {
325 settings->sync();
326 }
327
328 if (d->current() == oldKey) {
329 d->setCurrent(newKey);
330 }
331 // A rename is a removal and a save, told with the two signals every
332 // consumer already handles; a signal of its own would make each of them
333 // write a third branch for the same outcome.
334 Q_EMIT workspaceRemoved(oldKey);
335 Q_EMIT workspaceSaved(newKey);
336 return true;
337}
338
340{
342
343 const QStringList list = d->names();
344 if (list.isEmpty()) {
345 return;
346 }
347
349 if (settings) {
350 settings->beginGroup(QString::fromLatin1(kGroup));
351 settings->beginGroup(QString::fromLatin1(kWorkspaceGroup));
352 for (const QString &name : list) {
354 }
357 }
358
359 d->setNames(QStringList());
360 d->setCurrent(QString());
361 if (settings) {
362 settings->sync();
363 }
364
365 for (const QString &name : list) {
366 Q_EMIT workspaceRemoved(name);
367 }
368}
369
The window skeleton of a ribbon application.
Definition qxappshell.h:70
The state behind QxWorkspaceManager: the shell it belongs to and the paths the workspaces are written...
static QString normalize(const QString &name)
The name as it is stored and looked up: without surrounding space.
The named layouts of one shell.
QxCore::QxSettings * settings() const
The settings object the workspaces are stored in - the one the shell uses, so there is a single confi...
void workspaceRemoved(const QString &name)
A workspace was forgotten - also emitted once per name by clearWorkspaces().
int count() const
How many workspaces are stored.
bool applyWorkspace(const QString &name)
Brings back the layout stored under name: the dock state is restored and the page that was in front c...
void workspaceSaved(const QString &name)
A workspace was stored, first time or overwriting.
QStringList workspaceNames() const
Their names, in the order they were saved - the order a menu wants.
QString currentWorkspace() const
The workspace applied or saved last, empty when there is none.
bool contains(const QString &name) const
Whether a workspace called name is stored.
void clearWorkspaces()
Forgets every workspace.
QxAppShell * shell() const
The shell whose layout this manages; null only for a default-built one.
bool removeWorkspace(const QString &name)
Forgets the workspace called name.
bool saveWorkspace(const QString &name)
Stores the dock layout and the visible page under name, which becomes the current workspace.
void workspaceApplied(const QString &name)
A workspace was brought back on screen.
bool renameWorkspace(const QString &from, const QString &to)
Moves everything stored under from to to, keeping its place in the order.
Thin wrapper around QSettings that keeps call sites free of the usual boilerplate: typed accessors wi...
Definition qxsettings.h:32
QSettings * settings() const
The underlying QSettings instance, never null.
QVariant value(const QString &key, const QVariant &defaultValue=QVariant()) const
QString stringValue(const QString &key, const QString &defaultValue=QString()) const
void beginGroup(const QString &prefix)
void remove(const QString &key)
void setValue(const QString &key, const QVariant &value)
#define QX_APP_END_NAMESPACE
#define Q_NULLPTR
Copyleft (C) 2025 maminjie canpool@163.com SPDX-License-Identifier: MulanPSL-2.0
#define QX_APP_BEGIN_NAMESPACE
#define QX_FINI_PRIVATE()
#define QX_CORE_USE_NAMESPACE
#define QX_CORE_PREPEND_NAMESPACE(name)
#define QX_DOCK_USE_NAMESPACE
QtMessageHandler previous
Definition qxlogger.cpp:28
const char * name
Definition qxtheme.cpp:25