File indexing completed on 2024-05-19 04:29:19
0001 /* 0002 * SPDX-FileCopyrightText: 2018 Jouni Pentikäinen <joupent@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 #include "KisSessionResource.h" 0007 0008 #include <QDomElement> 0009 0010 #include <KisPart.h> 0011 #include <kis_properties_configuration.h> 0012 #include <KisDocument.h> 0013 0014 #include <ksharedconfig.h> 0015 #include <KisViewManager.h> 0016 #include <KisMainWindow.h> 0017 0018 0019 struct KisSessionResource::Private 0020 { 0021 struct View 0022 { 0023 QUuid windowId; 0024 // NOTE: path of the file without scheme 0025 QString file; 0026 KisPropertiesConfiguration viewConfig; 0027 0028 KisMainWindow *getWindow() const { 0029 Q_FOREACH(KisMainWindow *window, KisPart::instance()->mainWindows()) { 0030 if (window->id() == this->windowId) return window; 0031 } 0032 0033 return nullptr; 0034 } 0035 }; 0036 QString profileName; 0037 QVector<View> views; 0038 }; 0039 0040 KisSessionResource::KisSessionResource(const QString &filename) 0041 : KisWindowLayoutResource(filename) 0042 , d(new Private) 0043 {} 0044 0045 KisSessionResource::~KisSessionResource() 0046 {} 0047 0048 KisSessionResource::KisSessionResource(const KisSessionResource &rhs) 0049 : KisWindowLayoutResource(rhs) 0050 , d(new Private(*rhs.d)) 0051 { 0052 } 0053 0054 KoResourceSP KisSessionResource::clone() const 0055 { 0056 return KoResourceSP(new KisSessionResource(*this)); 0057 } 0058 0059 void KisSessionResource::restore() 0060 { 0061 auto *kisPart = KisPart::instance(); 0062 0063 applyLayout(); 0064 0065 QMap<QString, KisDocument *> documents; 0066 0067 // Find documents which are already open so we don't need to reload them 0068 QList<QPointer<KisView>> oldViews = kisPart->views(); 0069 Q_FOREACH(const QPointer<KisView> view, oldViews) { 0070 KisDocument *document = view->document(); 0071 const QString path = document->path(); 0072 documents.insert(path, document); 0073 } 0074 0075 Q_FOREACH(auto &viewData, d->views) { 0076 QString path = viewData.file; 0077 0078 KisMainWindow *window = viewData.getWindow(); 0079 0080 if (!window) { 0081 qDebug() << "Warning: session file contains inconsistent data."; 0082 } else { 0083 KisDocument *document = documents.value(path); 0084 0085 if (!document) { 0086 document = kisPart->createDocument(); 0087 0088 bool ok = document->openPath(path); 0089 if (!ok) { 0090 delete document; 0091 continue; 0092 } 0093 0094 kisPart->addDocument(document); 0095 documents.insert(path, document); 0096 } 0097 //update profile 0098 QString profileName; 0099 profileName = d->profileName; 0100 window->viewManager()->changeAuthorProfile(profileName); 0101 window->viewManager()->slotUpdateAuthorProfileActions(); 0102 0103 0104 KisView *view = window->newView(document); 0105 view->restoreViewState(viewData.viewConfig); 0106 } 0107 } 0108 0109 Q_FOREACH(QPointer<KisView> view, oldViews) { 0110 view->closeView(); 0111 } 0112 0113 } 0114 0115 0116 QString KisSessionResource::defaultFileExtension() const 0117 { 0118 return ".ksn"; 0119 } 0120 0121 void KisSessionResource::storeCurrentWindows() 0122 { 0123 KisPart *kisPart = KisPart::instance(); 0124 const auto &windows = kisPart->mainWindows(); 0125 setWindows(windows); 0126 0127 d->views.clear(); 0128 Q_FOREACH(const KisView *view, kisPart->views()) { 0129 if (view->document()->path().isEmpty()) continue; 0130 0131 auto viewData = Private::View(); 0132 viewData.windowId = view->mainWindow()->id(); 0133 viewData.file = view->document()->path(); 0134 view->saveViewState(viewData.viewConfig); 0135 d->views.append(viewData); 0136 } 0137 0138 setValid(true); 0139 } 0140 0141 void KisSessionResource::saveXml(QDomDocument &doc, QDomElement &root) const 0142 { 0143 KisWindowLayoutResource::saveXml(doc, root); 0144 0145 Q_FOREACH(const auto view, d->views) { 0146 QDomElement elem = doc.createElement("view"); 0147 0148 elem.setAttribute("window", view.windowId.toString()); 0149 // we convert to QUrl to maintain compatibility with Krita 4.4 0150 elem.setAttribute("src", QUrl::fromLocalFile(view.file).toString()); 0151 view.viewConfig.toXML(doc, elem); 0152 0153 root.appendChild(elem); 0154 0155 // Save profile 0156 KConfigGroup appAuthorGroup(KSharedConfig::openConfig(), "Author"); 0157 QString profileName = appAuthorGroup.readEntry("active-profile", ""); 0158 0159 QDomElement session = doc.createElement("session"); 0160 session.setAttribute("profile", profileName); 0161 root.appendChild(session); 0162 0163 } 0164 0165 } 0166 0167 void KisSessionResource::loadXml(const QDomElement &root) const 0168 { 0169 KisWindowLayoutResource::loadXml(root); 0170 0171 d->views.clear(); 0172 for (auto viewElement = root.firstChildElement("view"); 0173 !viewElement.isNull(); 0174 viewElement = viewElement.nextSiblingElement("view")) { 0175 Private::View view; 0176 0177 view.file = QUrl(viewElement.attribute("src")).toLocalFile(); 0178 view.windowId = QUuid(viewElement.attribute("window")); 0179 view.viewConfig.fromXML(viewElement); 0180 0181 d->views.append(view); 0182 } 0183 //Load session 0184 d->profileName.clear(); 0185 auto sessionElement = root.firstChildElement("session"); 0186 d->profileName = QString(sessionElement.attribute("profile")); 0187 0188 }