mirror of
https://github.com/KDE/latte-dock.git
synced 2024-12-28 19:21:50 +03:00
2526ab7e17
--easier to read in the code as that type provides: MemoryUsage::SingleLayout MemoryUsage::MultipleLayouts
475 lines
14 KiB
C++
475 lines
14 KiB
C++
/*
|
|
* Copyright 2017 Smith AR <audoban@openmailbox.org>
|
|
* Michail Vourlakos <mvourlakos@gmail.com>
|
|
*
|
|
* 2019 Michail Vourlakos <mvourlakos@gmail.com>
|
|
*
|
|
* This file is part of Latte-Dock
|
|
*
|
|
* Latte-Dock is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License as
|
|
* published by the Free Software Foundation; either version 2 of
|
|
* the License, or (at your option) any later version.
|
|
*
|
|
* Latte-Dock is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "manager.h"
|
|
|
|
// local
|
|
#include "importer.h"
|
|
#include "launcherssignals.h"
|
|
#include "../infoview.h"
|
|
#include "../screenpool.h"
|
|
#include "../layout/abstractlayout.h"
|
|
#include "../layout/centrallayout.h"
|
|
#include "../settings/dialogs/settingsdialog.h"
|
|
#include "../settings/universalsettings.h"
|
|
|
|
// Qt
|
|
#include <QDir>
|
|
#include <QFile>
|
|
#include <QMessageBox>
|
|
|
|
// KDE
|
|
#include <KLocalizedString>
|
|
#include <KNotification>
|
|
|
|
namespace Latte {
|
|
namespace Layouts {
|
|
|
|
const int MultipleLayoutsPresetId = 10;
|
|
|
|
Manager::Manager(QObject *parent)
|
|
: QObject(parent),
|
|
m_importer(new Importer(this)),
|
|
m_launchersSignals(new LaunchersSignals(this))
|
|
{
|
|
m_corona = qobject_cast<Latte::Corona *>(parent);
|
|
//! needs to be created AFTER corona assignment
|
|
m_synchronizer = new Synchronizer(this);
|
|
|
|
if (m_corona) {
|
|
connect(m_corona->universalSettings(), &UniversalSettings::currentLayoutNameChanged, this, &Manager::currentLayoutNameChanged);
|
|
|
|
connect(m_synchronizer, &Synchronizer::centralLayoutsChanged, this, &Manager::centralLayoutsChanged);
|
|
connect(m_synchronizer, &Synchronizer::currentLayoutNameChanged, this, &Manager::currentLayoutNameChanged);
|
|
connect(m_synchronizer, &Synchronizer::currentLayoutIsSwitching, this, &Manager::currentLayoutIsSwitching);
|
|
connect(m_synchronizer, &Synchronizer::layoutsChanged, this, &Manager::layoutsChanged);
|
|
connect(m_synchronizer, &Synchronizer::menuLayoutsChanged, this, &Manager::menuLayoutsChanged);
|
|
}
|
|
}
|
|
|
|
Manager::~Manager()
|
|
{
|
|
m_importer->deleteLater();
|
|
m_launchersSignals->deleteLater();
|
|
|
|
//! no needed because Latte:Corona is calling it at better place
|
|
// unload();
|
|
|
|
m_synchronizer->deleteLater();
|
|
}
|
|
|
|
void Manager::load()
|
|
{
|
|
m_presetsPaths.clear();
|
|
|
|
QDir layoutsDir(QDir::homePath() + "/.config/latte");
|
|
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()->setCurrentLayoutName(i18n("My Layout"));
|
|
|
|
//startup create what is necessary....
|
|
if (!layoutsDir.exists()) {
|
|
QDir(QDir::homePath() + "/.config").mkdir("latte");
|
|
}
|
|
|
|
newLayout(i18n("My Layout"));
|
|
importPresets(false);
|
|
} else if (configVer < 2 && !firstRun) {
|
|
m_corona->universalSettings()->setVersion(2);
|
|
|
|
bool isOlderVersion = m_importer->updateOldConfiguration();
|
|
if (isOlderVersion) {
|
|
qDebug() << "Latte is updating its older configuration...";
|
|
importPresets(false);
|
|
} else {
|
|
m_corona->universalSettings()->setCurrentLayoutName(i18n("My Layout"));
|
|
}
|
|
}
|
|
|
|
//! Check if the multiple-layouts hidden file is present, add it if it isnt
|
|
if (!QFile(QDir::homePath() + "/.config/latte/" + Layout::AbstractLayout::MultipleLayoutsName + ".layout.latte").exists()) {
|
|
importPreset(MultipleLayoutsPresetId, false);
|
|
}
|
|
|
|
qDebug() << "Latte is loading its layouts...";
|
|
|
|
m_presetsPaths.append(m_corona->kPackage().filePath("preset1"));
|
|
m_presetsPaths.append(m_corona->kPackage().filePath("preset2"));
|
|
m_presetsPaths.append(m_corona->kPackage().filePath("preset3"));
|
|
m_presetsPaths.append(m_corona->kPackage().filePath("preset4"));
|
|
|
|
m_synchronizer->loadLayouts();
|
|
}
|
|
|
|
void Manager::unload()
|
|
{
|
|
m_synchronizer->unloadLayouts();
|
|
|
|
//! Remove no-needed temp files
|
|
QString temp1File = QDir::homePath() + "/.config/lattedock.copy1.bak";
|
|
QString temp2File = QDir::homePath() + "/.config/lattedock.copy2.bak";
|
|
|
|
QFile file1(temp1File);
|
|
QFile file2(temp2File);
|
|
|
|
if (file1.exists()) {
|
|
file1.remove();
|
|
}
|
|
|
|
if (file2.exists()) {
|
|
file2.remove();
|
|
}
|
|
}
|
|
|
|
Latte::Corona *Manager::corona()
|
|
{
|
|
return m_corona;
|
|
}
|
|
|
|
Importer *Manager::importer()
|
|
{
|
|
return m_importer;
|
|
}
|
|
|
|
LaunchersSignals *Manager::launchersSignals() const
|
|
{
|
|
return m_launchersSignals;
|
|
}
|
|
|
|
Synchronizer *Manager::synchronizer() const
|
|
{
|
|
return m_synchronizer;
|
|
}
|
|
|
|
QString Manager::currentLayoutName() const
|
|
{
|
|
return m_synchronizer->currentLayoutName();
|
|
}
|
|
|
|
QString Manager::defaultLayoutName() const
|
|
{
|
|
QByteArray presetNameOrig = QString("preset" + QString::number(1)).toUtf8();
|
|
QString presetPath = m_corona->kPackage().filePath(presetNameOrig);
|
|
QString presetName = CentralLayout::layoutName(presetPath);
|
|
QByteArray presetNameChars = presetName.toUtf8();
|
|
presetName = i18n(presetNameChars);
|
|
|
|
return presetName;
|
|
}
|
|
|
|
QStringList Manager::layouts() const
|
|
{
|
|
return m_synchronizer->layouts();
|
|
}
|
|
|
|
QStringList Manager::menuLayouts() const
|
|
{
|
|
return m_synchronizer->menuLayouts();
|
|
}
|
|
|
|
void Manager::setMenuLayouts(QStringList layouts)
|
|
{
|
|
m_synchronizer->setMenuLayouts(layouts);
|
|
}
|
|
|
|
QStringList Manager::presetsPaths() const
|
|
{
|
|
return m_presetsPaths;
|
|
}
|
|
|
|
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::sharedLayoutsNames()
|
|
{
|
|
return m_synchronizer->sharedLayoutsNames();
|
|
}
|
|
|
|
QStringList Manager::storedSharedLayouts() const
|
|
{
|
|
return m_synchronizer->storedSharedLayouts();
|
|
}
|
|
|
|
CentralLayout *Manager::currentLayout() const
|
|
{
|
|
return m_synchronizer->currentLayout();
|
|
}
|
|
|
|
bool Manager::switchToLayout(QString layoutName, int previousMemoryUsage)
|
|
{
|
|
return m_synchronizer->switchToLayout(layoutName, previousMemoryUsage);
|
|
}
|
|
|
|
void Manager::loadLayoutOnStartup(QString layoutName)
|
|
{
|
|
QStringList layouts = m_importer->checkRepairMultipleLayoutsLinkedFile();
|
|
|
|
//! Latte didn't 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("Multiple Layouts Warning"));
|
|
msg->setText(i18n("Latte did not close properly in the previous session. The following layout(s) <b>[%0]</b> were updated for consistency!!!").arg(layouts.join(",")));
|
|
msg->setStandardButtons(QMessageBox::Ok);
|
|
|
|
msg->open();
|
|
}
|
|
|
|
m_synchronizer->switchToLayout(layoutName);
|
|
}
|
|
|
|
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::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 == "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 == "org.kde.desktopcontainment") { //!must remove ghost containments first
|
|
removeContaimentsList << cId;
|
|
}
|
|
}
|
|
|
|
for (const auto &cId : removeContaimentsList) {
|
|
containmentGroups.group(cId).deleteGroup();
|
|
}
|
|
|
|
|
|
actionGroups.sync();
|
|
containmentGroups.sync();
|
|
}
|
|
|
|
|
|
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();
|
|
}
|
|
|
|
containments.sync();
|
|
}
|
|
|
|
QString Manager::newLayout(QString layoutName, QString preset)
|
|
{
|
|
QDir layoutDir(QDir::homePath() + "/.config/latte");
|
|
QStringList filter;
|
|
filter.append(QString(layoutName + "*.layout.latte"));
|
|
QStringList files = layoutDir.entryList(filter, QDir::Files | QDir::NoSymLinks);
|
|
|
|
//! if the newLayout already exists provide a newName that doesn't
|
|
if (files.count() >= 1) {
|
|
int newCounter = files.count() + 1;
|
|
|
|
layoutName = layoutName + "-" + QString::number(newCounter);
|
|
}
|
|
|
|
QString newLayoutPath = layoutDir.absolutePath() + "/" + layoutName + ".layout.latte";
|
|
|
|
qDebug() << "adding layout : " << layoutName << " based on preset:" << preset;
|
|
|
|
if (preset == i18n("Default") && !QFile(newLayoutPath).exists()) {
|
|
qDebug() << "adding layout : succeed";
|
|
QFile(m_corona->kPackage().filePath("preset1")).copy(newLayoutPath);
|
|
}
|
|
|
|
return newLayoutPath;
|
|
}
|
|
|
|
void Manager::importDefaultLayout(bool newInstanceIfPresent)
|
|
{
|
|
importPreset(1, newInstanceIfPresent);
|
|
|
|
if (newInstanceIfPresent) {
|
|
m_synchronizer->loadLayouts();
|
|
}
|
|
}
|
|
|
|
void Manager::importPresets(bool includeDefault)
|
|
{
|
|
int start = 1;
|
|
|
|
if (!includeDefault) {
|
|
start = 2;
|
|
}
|
|
|
|
for (int i = start; i <= 4; ++i) {
|
|
importPreset(i, false);
|
|
}
|
|
}
|
|
|
|
void Manager::importPreset(int presetNo, bool newInstanceIfPresent)
|
|
{
|
|
QDir configDir(QDir::homePath() + "/.config");
|
|
|
|
if (!QDir(configDir.absolutePath() + "/latte").exists()) {
|
|
configDir.mkdir("latte");
|
|
}
|
|
|
|
QByteArray presetNameOrig = QString("preset" + QString::number(presetNo)).toUtf8();
|
|
QString presetPath = m_corona->kPackage().filePath(presetNameOrig);
|
|
QString presetName = Layout::AbstractLayout::layoutName(presetPath);
|
|
QByteArray presetNameChars = presetName.toUtf8();
|
|
presetName = i18n(presetNameChars);
|
|
|
|
//! hide the multiple layouts layout file from user
|
|
presetName = (presetNo == MultipleLayoutsPresetId) ? "." + presetName : presetName;
|
|
|
|
QString newLayoutFile = "";
|
|
|
|
if (newInstanceIfPresent) {
|
|
newLayoutFile = QDir::homePath() + "/.config/latte/" + m_importer->uniqueLayoutName(presetName) + ".layout.latte";
|
|
} else {
|
|
newLayoutFile = QDir::homePath() + "/.config/latte/" + presetName + ".layout.latte";
|
|
}
|
|
|
|
if (!QFile(newLayoutFile).exists()) {
|
|
QFile(presetPath).copy(newLayoutFile);
|
|
QFileInfo newFileInfo(newLayoutFile);
|
|
|
|
if (newFileInfo.exists() && !newFileInfo.isWritable()) {
|
|
QFile(newLayoutFile).setPermissions(QFileDevice::ReadUser | QFileDevice::WriteUser | QFileDevice::ReadGroup | QFileDevice::ReadOther);
|
|
}
|
|
}
|
|
}
|
|
|
|
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();
|
|
});
|
|
}
|
|
}
|
|
|
|
//! it is used just in order to provide translations for the presets
|
|
void Manager::ghostForTranslatedPresets()
|
|
{
|
|
QString preset1 = i18n("Default");
|
|
QString preset2 = i18n("Plasma");
|
|
QString preset3 = i18n("Unity");
|
|
QString preset4 = i18n("Extended");
|
|
}
|
|
|
|
}
|
|
}
|