From 94914ee578b2da1f954d2f98ccaf3b6c6c4c4913 Mon Sep 17 00:00:00 2001 From: Michail Vourlakos Date: Mon, 15 Jan 2018 14:09:41 +0200 Subject: [PATCH] warning message for broken MultipleLayouts startup --if the app crashed and the user trys to reopen Latte then the Containments must first return to their Original Layouts. This code provides that and informs also the user during the startup. --- app/dockcorona.cpp | 2 +- app/importer.cpp | 60 ++++++++++++++++++++++++++++++++++++++++++- app/importer.h | 8 ++++++ app/layoutmanager.cpp | 22 ++++++++++++++++ app/layoutmanager.h | 1 + 5 files changed, 91 insertions(+), 2 deletions(-) diff --git a/app/dockcorona.cpp b/app/dockcorona.cpp index 46235ad6e..158976529 100644 --- a/app/dockcorona.cpp +++ b/app/dockcorona.cpp @@ -163,7 +163,7 @@ void DockCorona::load() loadLayoutName = m_layoutNameOnStartUp; } - m_layoutManager->switchToLayout(loadLayoutName); + m_layoutManager->loadLayoutOnStartup(loadLayoutName); } } diff --git a/app/importer.cpp b/app/importer.cpp index 6cc0e300e..39cae4b9d 100644 --- a/app/importer.cpp +++ b/app/importer.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -498,7 +499,13 @@ QString Importer::nameOfConfigFile(const QString &fileName) bool Importer::layoutExists(QString layoutName) { - return QFile::exists(QDir::homePath() + "/.config/latte/" + layoutName + ".layout.latte"); + return QFile::exists(layoutFilePath(layoutName)); +} + + +QString Importer::layoutFilePath(QString layoutName) +{ + return QString(QDir::homePath() + "/.config/latte/" + layoutName + ".layout.latte"); } QString Importer::uniqueLayoutName(QString name) @@ -521,4 +528,55 @@ QString Importer::uniqueLayoutName(QString name) return name; } +QStringList Importer::checkRepairMultipleLayoutsLinkedFile() +{ + QString linkedFilePath = QDir::homePath() + "/.config/latte/" + Layout::MultipleLayoutsName + ".layout.latte"; + KSharedConfigPtr filePtr = KSharedConfig::openConfig(linkedFilePath); + KConfigGroup linkedContainments = KConfigGroup(filePtr, "Containments"); + + //! layoutName and its Containments + QHash linkedLayoutContainmentGroups; + + foreach (auto cId, linkedContainments.groupList()) { + QString layoutName = linkedContainments.group(cId).readEntry("layoutId", QString()); + + if (!layoutName.isEmpty()) { + qDebug() << layoutName; + linkedLayoutContainmentGroups[layoutName].append(cId); + linkedContainments.group(cId).writeEntry("layoutId", QString()); + } + } + + QStringList updatedLayouts; + + foreach (auto layoutName, linkedLayoutContainmentGroups.uniqueKeys()) { + if (layoutName != Layout::MultipleLayoutsName && layoutExists(layoutName)) { + updatedLayouts << layoutName; + KSharedConfigPtr layoutFilePtr = KSharedConfig::openConfig(layoutFilePath(layoutName)); + KConfigGroup origLayoutContainments = KConfigGroup(layoutFilePtr, "Containments"); + + //Clear old containments + origLayoutContainments.deleteGroup(); + + //Update containments + foreach (auto cId, linkedLayoutContainmentGroups[layoutName]) { + KConfigGroup newContainment = origLayoutContainments.group(cId); + linkedContainments.group(cId).copyTo(&newContainment); + linkedContainments.group(cId).deleteGroup(); + } + + origLayoutContainments.sync(); + } + } + + //! clear all remaining ghost containments + foreach (auto cId, linkedContainments.groupList()) { + linkedContainments.group(cId).deleteGroup(); + } + + linkedContainments.sync(); + + return updatedLayouts; +} + } diff --git a/app/importer.h b/app/importer.h index a295e30bf..55f6ce898 100644 --- a/app/importer.h +++ b/app/importer.h @@ -73,9 +73,17 @@ public: //! if the function didnt succeed return an empty string static QString importLayoutHelper(QString fileName); + //! return the file path of a layout either existing or not + static QString layoutFilePath(QString layoutName); static QString nameOfConfigFile(const QString &fileName); static QString uniqueLayoutName(QString name); + static QStringList availableLayouts(); + //! it checks the linked file if there are Containments in it that belong + //! to Original Layouts and moves them accordingly. This is used mainly on + //! startup and if such state occurs, it basically means that the app didnt + //! close correctly, e.g. there was a crash. + static QStringList checkRepairMultipleLayoutsLinkedFile(); private: //! checks if this old layout can be imported. If it can it returns diff --git a/app/layoutmanager.cpp b/app/layoutmanager.cpp index 59c31195c..4eae2098c 100644 --- a/app/layoutmanager.cpp +++ b/app/layoutmanager.cpp @@ -24,6 +24,7 @@ #include #include +#include #include #include @@ -490,6 +491,27 @@ void LayoutManager::loadLayouts() emit menuLayoutsChanged(); } +void LayoutManager::loadLayoutOnStartup(QString layoutName) +{ + if (memoryUsage() == Dock::MultipleLayouts) { + QStringList layouts = m_importer->checkRepairMultipleLayoutsLinkedFile(); + + //! Latte didnt close correctly, maybe a crash + if (layouts.size() > 0) { + QMessageBox *msg = new QMessageBox(); + msg->setAttribute(Qt::WA_DeleteOnClose); + msg->setIcon(QMessageBox::Warning); + msg->setWindowTitle(i18n("Mutliple Layouts Warning")); + msg->setText(i18n("Latte did not close properly in the previous session.The following layout(s) [%0] were updated for consistency !!!").arg(layouts.join(","))); + msg->setStandardButtons(QMessageBox::Ok); + + msg->open(); + } + } + + switchToLayout(layoutName); +} + void LayoutManager::loadLatteLayout(QString layoutPath) { qDebug() << " -------------------------------------------------------------------- "; diff --git a/app/layoutmanager.h b/app/layoutmanager.h index 11722ad6d..80ed7c039 100644 --- a/app/layoutmanager.h +++ b/app/layoutmanager.h @@ -61,6 +61,7 @@ public: Importer *importer(); void load(); + void loadLayoutOnStartup(QString layoutName); void unload(); void addDock(Plasma::Containment *containment, bool forceLoading = false, int expDockScreen = -1); void recreateDock(Plasma::Containment *containment);