/* SPDX-FileCopyrightText: 2017 Smith AR SPDX-FileCopyrightText: 2019 Michail Vourlakos SPDX-License-Identifier: GPL-2.0-or-later */ #include "manager.h" // local #include "importer.h" #include "syncedlaunchers.h" #include "../infoview.h" #include "../screenpool.h" #include "../data/layoutdata.h" #include "../data/generictable.h" #include "../layout/abstractlayout.h" #include "../layout/centrallayout.h" #include "../settings/universalsettings.h" #include "../templates/templatesmanager.h" #include "../tools/commontools.h" // Qt #include #include #include #include // KDE #include #include #include namespace Latte { namespace Layouts { Manager::Manager(QObject *parent) : QObject(parent), m_importer(new Importer(this)), m_syncedLaunchers(new SyncedLaunchers(this)) { m_corona = qobject_cast(parent); //! needs to be created AFTER corona assignment m_synchronizer = new Synchronizer(this); if (m_corona) { connect(m_synchronizer, &Synchronizer::centralLayoutsChanged, this, &Manager::centralLayoutsChanged); connect(m_synchronizer, &Synchronizer::currentLayoutIsSwitching, this, &Manager::currentLayoutIsSwitching); } } Manager::~Manager() { m_importer->deleteLater(); m_syncedLaunchers->deleteLater(); //! no needed because Latte:Corona is calling it at better place // unload(); m_synchronizer->deleteLater(); } void Manager::init() { QDir layoutsDir(Layouts::Importer::layoutUserDir()); bool firstRun = !layoutsDir.exists(); int configVer = m_corona->universalSettings()->version(); qDebug() << "Universal Settings version : " << configVer; if (firstRun) { m_corona->universalSettings()->setVersion(2); m_corona->universalSettings()->setSingleModeLayoutName(i18n("My Layout")); //startup create what is necessary.... if (!layoutsDir.exists()) { QDir(Latte::configPath()).mkdir("latte"); } QString defpath = m_corona->templatesManager()->newLayout(i18n("My Layout"), i18n(Templates::DEFAULTLAYOUTTEMPLATENAME)); setOnAllActivities(Layout::AbstractLayout::layoutName(defpath)); m_corona->templatesManager()->importSystemLayouts(); } else if (configVer < 2 && !firstRun) { m_corona->universalSettings()->setVersion(2); bool isOlderVersion = m_importer->updateOldConfiguration(); if (isOlderVersion) { qDebug() << "Latte is updating its older configuration..."; m_corona->templatesManager()->importSystemLayouts(); } else { m_corona->universalSettings()->setSingleModeLayoutName(i18n("My Layout")); } } //! Custom Templates path creation QDir localTemplatesDir(Latte::configPath() + "/latte/templates"); if (!localTemplatesDir.exists()) { QDir(Latte::configPath() + "/latte").mkdir("templates"); } //! Check if the multiple-layouts hidden file is present, add it if it isnt if (!QFile(Layouts::Importer::layoutUserFilePath(Layout::MULTIPLELAYOUTSHIDDENNAME)).exists()) { m_corona->templatesManager()->newLayout("", Layout::MULTIPLELAYOUTSHIDDENNAME); } qDebug() << "Latte is loading its layouts..."; m_synchronizer->initLayouts(); } void Manager::unload() { m_synchronizer->unloadLayouts(); } Latte::Corona *Manager::corona() { return m_corona; } Importer *Manager::importer() { return m_importer; } SyncedLaunchers *Manager::syncedLaunchers() const { return m_syncedLaunchers; } Synchronizer *Manager::synchronizer() const { return m_synchronizer; } MemoryUsage::LayoutsMemory Manager::memoryUsage() const { return m_corona->universalSettings()->layoutsMemoryUsage(); } void Manager::setMemoryUsage(MemoryUsage::LayoutsMemory memoryUsage) { m_corona->universalSettings()->setLayoutsMemoryUsage(memoryUsage); } QStringList Manager::centralLayoutsNames() { return m_synchronizer->centralLayoutsNames(); } QStringList Manager::currentLayoutsNames() const { return m_synchronizer->currentLayoutsNames(); } QStringList Manager::viewTemplateNames() const { Latte::Data::GenericTable viewtemplates = m_corona->templatesManager()->viewTemplates(); QStringList names; for(int i=0; i viewtemplates = m_corona->templatesManager()->viewTemplates(); QStringList ids; for(int i=0; idata(storedLayoutName); return iconForLayout(l); } Latte::Data::LayoutIcon Manager::iconForLayout(const Data::Layout &layout) const { Latte::Data::LayoutIcon _icon; if (!layout.icon.isEmpty()) { //! if there is specific icon set from the user for this layout we draw only that icon _icon.name = layout.icon; _icon.isBackgroundFile = false; return _icon; } //! fallback icon: background image if (_icon.isEmpty()) { QString colorPath = m_corona->kPackage().path() + "../../shells/org.kde.latte.shell/contents/images/canvas/"; if (layout.backgroundStyle == Layout::PatternBackgroundStyle && layout.background.isEmpty()) { colorPath += "defaultcustomprint.jpg"; } else { colorPath = layout.background.startsWith("/") ? layout.background : colorPath + layout.color + "print.jpg"; } if (QFileInfo(colorPath).exists()) { _icon.isBackgroundFile = true; _icon.name = colorPath; return _icon; } } return Latte::Data::LayoutIcon(); } QList Manager::currentLayouts() const { return m_synchronizer->currentLayouts(); } bool Manager::switchToLayout(QString layoutName, MemoryUsage::LayoutsMemory newMemoryUsage) { return m_synchronizer->switchToLayout(layoutName, newMemoryUsage); } void Manager::loadLayoutOnStartup(QString layoutName) { QStringList layouts = m_importer->checkRepairMultipleLayoutsLinkedFile(); //! Latte didn't close correctly, maybe a crash if (layouts.size() > 0) { QDialog* dialog = new QDialog(nullptr); dialog->setWindowTitle(i18n("Multiple Layouts Startup Warning")); dialog->setObjectName("sorry"); dialog->setAttribute(Qt::WA_DeleteOnClose); auto buttonbox = new QDialogButtonBox(QDialogButtonBox::Ok); KMessageBox::createKMessageBox(dialog, buttonbox, QMessageBox::Warning, i18np("Multiple Layouts based on Activities mode did not close properly during the last session.

The following layout [ %2 ] had to be updated for consistency!", "Multiple Layouts based on Activities mode did not close properly during the last session.

The following layouts [ %2 ] had to be updated for consistency!", layouts.count(), layouts.join(", ")), QStringList(), QString(), 0, KMessageBox::NoExec, QString()); dialog->show(); } m_synchronizer->switchToLayout(layoutName); } void Manager::moveView(QString originLayoutName, uint originViewId, QString destinationLayoutName) { if (memoryUsage() != Latte::MemoryUsage::MultipleLayouts || originLayoutName.isEmpty() || destinationLayoutName.isEmpty() || originViewId <= 0 || originLayoutName == destinationLayoutName) { return; } auto originlayout = m_synchronizer->layout(originLayoutName); auto destinationlayout = m_synchronizer->layout(destinationLayoutName); if (!originlayout || !destinationlayout || originlayout == destinationlayout) { return; } Plasma::Containment *originviewcontainment = originlayout->containmentForId(originViewId); Latte::View *originview = originlayout->viewForContainment(originViewId); if (!originviewcontainment) { return; } QList origincontainments = originlayout->unassignFromLayout(originviewcontainment); if (origincontainments.size() > 0) { destinationlayout->assignToLayout(originview, origincontainments); } } void Manager::loadLatteLayout(QString layoutPath) { qDebug() << " -------------------------------------------------------------------- "; qDebug() << " -------------------------------------------------------------------- "; if (m_corona->containments().size() > 0) { qDebug() << "LOAD LATTE LAYOUT ::: There are still containments present !!!! :: " << m_corona->containments().size(); } if (!layoutPath.isEmpty() && m_corona->containments().size() == 0) { cleanupOnStartup(layoutPath); qDebug() << "LOADING CORONA LAYOUT:" << layoutPath; m_corona->loadLayout(layoutPath); } } void Manager::setOnAllActivities(QString layoutName) { CentralLayout *central = m_synchronizer->centralLayout(layoutName); if (central) { central->setActivities(QStringList(Data::Layout::ALLACTIVITIESID)); } else if (m_importer->layoutExists(layoutName)) { CentralLayout storage(this, m_importer->layoutUserFilePath(layoutName)); storage.setActivities(QStringList(Data::Layout::ALLACTIVITIESID)); } } void Manager::setOnActivities(QString layoutName, QStringList activities) { CentralLayout *central = m_synchronizer->centralLayout(layoutName); if (central) { central->setActivities(activities); } else if (m_importer->layoutExists(layoutName)) { CentralLayout storage(this, m_importer->layoutUserFilePath(layoutName)); storage.setActivities(activities); } } void Manager::cleanupOnStartup(QString path) { KSharedConfigPtr filePtr = KSharedConfig::openConfig(path); KConfigGroup actionGroups = KConfigGroup(filePtr, "ActionPlugins"); QStringList deprecatedActionGroup; for (const auto &actId : actionGroups.groupList()) { QString pluginId = actionGroups.group(actId).readEntry("RightButton;NoModifier", ""); if (pluginId == QStringLiteral("org.kde.contextmenu")) { deprecatedActionGroup << actId; } } for (const auto &pId : deprecatedActionGroup) { qDebug() << "!!!!!!!!!!!!!!!! !!!!!!!!!!!! !!!!!!! REMOVING :::: " << pId; actionGroups.group(pId).deleteGroup(); } KConfigGroup containmentGroups = KConfigGroup(filePtr, "Containments"); QStringList removeContaimentsList; for (const auto &cId : containmentGroups.groupList()) { QString pluginId = containmentGroups.group(cId).readEntry("plugin", ""); if (pluginId == QStringLiteral("org.kde.desktopcontainment")) { //!must remove ghost containments first removeContaimentsList << cId; } } for (const auto &cId : removeContaimentsList) { containmentGroups.group(cId).deleteGroup(); } } void Manager::showAboutDialog() { m_corona->aboutApplication(); } void Manager::clearUnloadedContainmentsFromLinkedFile(QStringList containmentsIds, bool bypassChecks) { if (!m_corona || (memoryUsage() == MemoryUsage::SingleLayout && !bypassChecks)) { return; } auto containments = m_corona->config()->group("Containments"); for (const auto &conId : containmentsIds) { qDebug() << "unloads ::: " << conId; KConfigGroup containment = containments.group(conId); containment.deleteGroup(); containment.sync(); } containments.sync(); } void Manager::showLatteSettingsDialog(int firstPage, bool toggleCurrentPage) { if (!m_latteSettingsDialog) { m_latteSettingsDialog = new Latte::Settings::Dialog::SettingsDialog(nullptr, m_corona); } m_latteSettingsDialog->show(); if (m_latteSettingsDialog->isMinimized()) { m_latteSettingsDialog->showNormal(); } if (toggleCurrentPage) { m_latteSettingsDialog->toggleCurrentPage(); } else { m_latteSettingsDialog->setCurrentPage(firstPage); } m_latteSettingsDialog->activateWindow(); } void Manager::hideLatteSettingsDialog() { if (m_latteSettingsDialog) { m_latteSettingsDialog->deleteLater(); m_latteSettingsDialog = nullptr; } } void Manager::showInfoWindow(QString info, int duration, QStringList activities) { for (const auto screen : qGuiApp->screens()) { InfoView *infoView = new InfoView(m_corona, info, screen); infoView->show(); infoView->setOnActivities(activities); QTimer::singleShot(duration, [this, infoView]() { infoView->deleteLater(); }); } } } }