12#include <QDomDocument>
13#include <QApplication>
36 QWindow *windowHandle = window->windowHandle();
38 geometry.
data = window->saveGeometry();
39 geometry.
stateFlags = windowHandle->windowState();
41 int index = screens.indexOf(windowHandle->screen());
51 QWindow *windowHandle = window->windowHandle();
53 if (screens.indexOf(windowHandle->screen()) !=
screen) {
54 QScreen *qScreen = screens[
screen];
55 windowHandle->setScreen(qScreen);
56 windowHandle->setPosition(qScreen->availableGeometry().topLeft());
64 void save(QDomDocument &doc, QDomElement &elem)
const
67 elem.setAttribute(
"screen",
screen);
71 elem.setAttribute(
"maximized",
"1");
74 QDomElement geometry = doc.createElement(
"geometry");
75 geometry.appendChild(doc.createCDATASection(
data.toBase64()));
76 elem.appendChild(geometry);
82 geometry.
screen = element.attribute(
"screen",
"-1").toInt();
84 if (element.attribute(
"maximized",
"0") !=
"0") {
88 QDomElement dataElement = element.firstChildElement(
"geometry");
89 geometry.
data = QByteArray::fromBase64(dataElement.text().toLatin1());
123 if (mainWindow.isNull()) {
124 mainWindow = kisPart->createMainWindow(window.
windowId);
125 currentWindows.append(mainWindow);
144 windowsToClose.append(mainWindow);
148 if (mainWindow->isVisible()) {
166 Q_FOREACH(
KisMainWindow *mainWindow, kisPart->mainWindows()) {
167 if (!closingWindows.contains(mainWindow)) {
168 migrationTarget = mainWindow;
173 if (!migrationTarget) {
174 qWarning() <<
"Problem: window layout with no windows would leave user with zero main windows.";
175 migrationTarget = closingWindows.takeLast();
176 migrationTarget->show();
180 Q_FOREACH(
KisView *view, kisPart->views()) {
182 if (!closingWindows.contains(window)) {
183 visibleDocuments.append(view->
document());
187 Q_FOREACH(
KisDocument *document, kisPart->documents()) {
188 if (!visibleDocuments.contains(document)) {
189 visibleDocuments.append(document);
190 migrationTarget->
newView(document);
199 std::sort(screens.begin(), screens.end(), [](
const QScreen *a,
const QScreen *b) {
200 QRect aRect = a->geometry();
201 QRect bRect = b->geometry();
203 if (aRect.y() == bRect.y()) return aRect.x() < bRect.x();
204 return (aRect.y() < bRect.y());
232 bool primaryWorkspaceFollowsFocus,
KisMainWindow *primaryWindow
236 resource->setWindows(mainWindows);
237 resource->d->showImageInAllWindows = showImageInAllWindows;
238 resource->d->primaryWorkspaceFollowsFocus = primaryWorkspaceFollowsFocus;
239 resource->d->primaryWindow = primaryWindow->
id();
248 layoutManager->setLastUsedLayout(
this);
252 if (
d->windows.isEmpty()) {
254 if (kisPart->mainwindowCount() == 0) {
255 kisPart->createMainWindow();
257 kisPart->mainWindows().first()->show();
260 d->openNecessaryWindows(currentWindows);
261 d->closeUnneededWindows(currentWindows);
266 QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
268 Q_FOREACH(
const auto &window,
d->windows) {
272 mainWindow->restoreGeometry(window.geometry.data);
273 mainWindow->restoreWorkspaceState(window.windowState);
275 mainWindow->setCanvasDetached(window.canvasDetached);
276 if (window.canvasDetached) {
277 QWidget *canvasWindow = mainWindow->canvasWindow();
278 canvasWindow->restoreGeometry(window.canvasWindowGeometry.data);
282 QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
285 Q_FOREACH(
const auto &window,
d->windows) {
290 if (geometry.
screen >= 0 && geometry.
screen < screens.size()) {
293 if (window.canvasDetached) {
295 if (canvasWindowGeometry.
screen >= 0 && canvasWindowGeometry.
screen < screens.size()) {
301 layoutManager->setShowImageInAllWindowsEnabled(
d->showImageInAllWindows);
302 layoutManager->setPrimaryWorkspaceFollowsFocus(
d->primaryWorkspaceFollowsFocus,
d->primaryWindow);
308 QDomElement root = doc.createElement(
"WindowLayout");
309 root.setAttribute(
"name",
name());
314 doc.appendChild(root);
316 QTextStream textStream(dev);
318 doc.save(textStream, 4);
324 Q_UNUSED(resourcesInterface);
327 if (!doc.setContent(dev)) {
331 QDomElement element = doc.documentElement();
332 setName(element.attribute(
"name"));
344 root.setAttribute(
"showImageInAllWindows", (
int)
d->showImageInAllWindows);
345 root.setAttribute(
"primaryWorkspaceFollowsFocus", (
int)
d->primaryWorkspaceFollowsFocus);
346 root.setAttribute(
"primaryWindow",
d->primaryWindow.toString());
348 Q_FOREACH(
const auto &window,
d->windows) {
349 QDomElement elem = doc.createElement(
"window");
350 elem.setAttribute(
"id", window.windowId.toString());
352 window.geometry.save(doc, elem);
354 if (window.canvasDetached) {
355 QDomElement canvasWindowElement = doc.createElement(
"canvasWindow");
356 window.canvasWindowGeometry.save(doc, canvasWindowElement);
357 elem.appendChild(canvasWindowElement);
360 QDomElement state = doc.createElement(
"windowState");
361 state.appendChild(doc.createCDATASection(window.windowState.toBase64()));
362 elem.appendChild(state);
363 root.appendChild(elem);
369 d->showImageInAllWindows =
KisDomUtils::toInt(element.attribute(
"showImageInAllWindows",
"0"));
370 d->primaryWorkspaceFollowsFocus =
KisDomUtils::toInt(element.attribute(
"primaryWorkspaceFollowsFocus",
"0"));
371 d->primaryWindow = QUuid::fromString(element.attribute(
"primaryWindow"));
374 if (element.firstChildElement(
"window") != element.lastChildElement(
"window")) {
375 QMessageBox::warning(qApp->activeWindow(), i18nc(
"@title:window",
"Krita"),
376 "Workspaces with multiple windows isn't supported on Android");
381 for (
auto windowElement = element.firstChildElement(
"window");
382 !windowElement.isNull();
383 windowElement = windowElement.nextSiblingElement(
"window")) {
387 window.
windowId = QUuid(windowElement.attribute(
"id", QUuid().toString()));
389 window.
windowId = QUuid::createUuid();
394 QDomElement canvasWindowElement = windowElement.firstChildElement(
"canvasWindow");
395 if (!canvasWindowElement.isNull()) {
400 QDomElement state = windowElement.firstChildElement(
"windowState");
401 window.
windowState = QByteArray::fromBase64(state.text().toLatin1());
403 d->windows.append(window);
409 return QString(
".kwl");
418 Q_FOREACH(
auto window, mainWindows) {
419 if (!window->isVisible())
continue;
431 d->windows.append(state);
static const int WINDOW_LAYOUT_VERSION
KisView * newView(QObject *document, QMdiSubWindow *subWindow=0)
static KisPart * instance()
KisMainWindow * mainWindow() const
QPointer< KisDocument > document
static KisWindowLayoutManager * instance()
QString defaultFileExtension() const override
KoResourceSP clone() const override
void setWindows(const QList< QPointer< KisMainWindow > > &mainWindows)
static KisWindowLayoutResourceSP fromCurrentWindows(const QString &filename, const QList< QPointer< KisMainWindow > > &mainWindows, bool showImageInAllWindows, bool primaryWorkspaceFollowsFocus, KisMainWindow *primaryWindow)
virtual void saveXml(QDomDocument &doc, QDomElement &root) const
KisWindowLayoutResource(const QString &filename)
virtual void loadXml(const QDomElement &root) const
bool saveToDevice(QIODevice *dev) const override
QScopedPointer< Private > d
bool loadFromDevice(QIODevice *dev, KisResourcesInterfaceSP resourcesInterface) override
~KisWindowLayoutResource() override
#define KIS_SAFE_ASSERT_RECOVER_BREAK(cond)
QSharedPointer< KoResource > KoResourceSP
int toInt(const QString &str, bool *ok=nullptr)
void setUtf8OnStream(QTextStream &stream)
void save(QDomDocument &doc, QDomElement &elem) const
void forceOntoCorrectScreen(QWidget *window, QList< QScreen * > screens)
static WindowGeometry fromWindow(const QWidget *window, QList< QScreen * > screens)
Qt::WindowStates stateFlags
static WindowGeometry load(const QDomElement &element)
WindowGeometry canvasWindowGeometry
QList< QScreen * > getScreensInConsistentOrder()
bool showImageInAllWindows
bool primaryWorkspaceFollowsFocus
Private(const Private &rhs)=default
Private(QVector< Window > windows)
void openNecessaryWindows(QList< QPointer< KisMainWindow > > ¤tWindows)
QVector< Window > windows
void closeUnneededWindows(QList< QPointer< KisMainWindow > > ¤tWindows)
void migrateViewsFromClosingWindows(QVector< QPointer< KisMainWindow > > &closingWindows) const
void setValid(bool valid)
void setName(const QString &name)