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);
142 windowsToMigrate.append(mainWindow);
146 if (mainWindow->isVisible()) {
178 Q_FOREACH(
KisMainWindow *mainWindow, kisPart->mainWindows()) {
179 if (!closingWindows.contains(mainWindow)) {
180 migrationTarget = mainWindow;
185 if (!migrationTarget) {
186 qWarning() <<
"Problem: window layout with no windows would leave user with zero main windows.";
187 migrationTarget = closingWindows.takeLast();
188 migrationTarget->show();
192 Q_FOREACH(
KisView *view, kisPart->views()) {
194 if (!closingWindows.contains(window)) {
195 visibleDocuments.append(view->
document());
199 Q_FOREACH(
KisDocument *document, kisPart->documents()) {
200 if (!visibleDocuments.contains(document)) {
201 visibleDocuments.append(document);
202 migrationTarget->
newView(document);
211 std::sort(screens.begin(), screens.end(), [](
const QScreen *a,
const QScreen *b) {
212 QRect aRect = a->geometry();
213 QRect bRect = b->geometry();
215 if (aRect.y() == bRect.y()) return aRect.x() < bRect.x();
216 return (aRect.y() < bRect.y());
244 bool primaryWorkspaceFollowsFocus,
KisMainWindow *primaryWindow
248 resource->setWindows(mainWindows);
249 resource->d->showImageInAllWindows = showImageInAllWindows;
250 resource->d->primaryWorkspaceFollowsFocus = primaryWorkspaceFollowsFocus;
251 resource->d->primaryWindow = primaryWindow->
id();
260 layoutManager->setLastUsedLayout(
this);
263 bool createWindows =
d->windows.isEmpty();
267 if (kisPart->mainwindowCount() == 0) {
268 kisPart->createMainWindow();
270 kisPart->mainWindows().first()->show();
273 d->openNecessaryWindows(currentWindows);
278 QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
280 Q_FOREACH(
const auto &window,
d->windows) {
284 mainWindow->restoreGeometry(window.geometry.data);
285 mainWindow->restoreWorkspaceState(window.windowState);
287 mainWindow->setCanvasDetached(window.canvasDetached);
288 if (window.canvasDetached) {
289 QWidget *canvasWindow = mainWindow->canvasWindow();
290 canvasWindow->restoreGeometry(window.canvasWindowGeometry.data);
294 QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
297 Q_FOREACH(
const auto &window,
d->windows) {
302 if (geometry.
screen >= 0 && geometry.
screen < screens.size()) {
305 if (window.canvasDetached) {
307 if (canvasWindowGeometry.
screen >= 0 && canvasWindowGeometry.
screen < screens.size()) {
313 layoutManager->setShowImageInAllWindowsEnabled(
d->showImageInAllWindows);
314 layoutManager->setPrimaryWorkspaceFollowsFocus(
d->primaryWorkspaceFollowsFocus,
d->primaryWindow);
315 if (!createWindows) {
316 d->closeUnneededWindows(currentWindows);
323 QDomElement root = doc.createElement(
"WindowLayout");
324 root.setAttribute(
"name",
name());
329 doc.appendChild(root);
331 QTextStream textStream(dev);
333 doc.save(textStream, 4);
339 Q_UNUSED(resourcesInterface);
342 if (!doc.setContent(dev)) {
346 QDomElement element = doc.documentElement();
347 setName(element.attribute(
"name"));
359 root.setAttribute(
"showImageInAllWindows", (
int)
d->showImageInAllWindows);
360 root.setAttribute(
"primaryWorkspaceFollowsFocus", (
int)
d->primaryWorkspaceFollowsFocus);
361 root.setAttribute(
"primaryWindow",
d->primaryWindow.toString());
363 Q_FOREACH(
const auto &window,
d->windows) {
364 QDomElement elem = doc.createElement(
"window");
365 elem.setAttribute(
"id", window.windowId.toString());
367 window.geometry.save(doc, elem);
369 if (window.canvasDetached) {
370 QDomElement canvasWindowElement = doc.createElement(
"canvasWindow");
371 window.canvasWindowGeometry.save(doc, canvasWindowElement);
372 elem.appendChild(canvasWindowElement);
375 QDomElement state = doc.createElement(
"windowState");
376 state.appendChild(doc.createCDATASection(window.windowState.toBase64()));
377 elem.appendChild(state);
378 root.appendChild(elem);
384 d->showImageInAllWindows =
KisDomUtils::toInt(element.attribute(
"showImageInAllWindows",
"0"));
385 d->primaryWorkspaceFollowsFocus =
KisDomUtils::toInt(element.attribute(
"primaryWorkspaceFollowsFocus",
"0"));
386 d->primaryWindow = QUuid::fromString(element.attribute(
"primaryWindow"));
389 if (element.firstChildElement(
"window") != element.lastChildElement(
"window")) {
390 QMessageBox::warning(qApp->activeWindow(), i18nc(
"@title:window",
"Krita"),
391 "Workspaces with multiple windows isn't supported on Android");
396 for (
auto windowElement = element.firstChildElement(
"window");
397 !windowElement.isNull();
398 windowElement = windowElement.nextSiblingElement(
"window")) {
402 window.
windowId = QUuid(windowElement.attribute(
"id", QUuid().toString()));
404 window.
windowId = QUuid::createUuid();
409 QDomElement canvasWindowElement = windowElement.firstChildElement(
"canvasWindow");
410 if (!canvasWindowElement.isNull()) {
415 QDomElement state = windowElement.firstChildElement(
"windowState");
416 window.
windowState = QByteArray::fromBase64(state.text().toLatin1());
418 d->windows.append(window);
424 return QString(
".kwl");
433 Q_FOREACH(
auto window, mainWindows) {
434 if (!window->isVisible())
continue;
446 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)