diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 60d79780..3741e547 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -1,124 +1,125 @@ set(lattedock-app_SRCS alternativeshelper.cpp infoview.cpp lattecorona.cpp screenpool.cpp + types.cpp main.cpp ) add_subdirectory(indicator) add_subdirectory(layout) add_subdirectory(layouts) add_subdirectory(package) add_subdirectory(plasma/extended) add_subdirectory(settings) add_subdirectory(settings/controllers) add_subdirectory(settings/data) add_subdirectory(settings/delegates) add_subdirectory(settings/dialogs) add_subdirectory(settings/handlers) add_subdirectory(settings/models) add_subdirectory(settings/tools) add_subdirectory(settings/views) add_subdirectory(settings/widgets) add_subdirectory(shortcuts) add_subdirectory(tools) add_subdirectory(view) add_subdirectory(view/helpers) add_subdirectory(view/indicator) add_subdirectory(view/settings) add_subdirectory(view/windowstracker) add_subdirectory(wm) add_subdirectory(wm/tracker) set(latte_dbusXML dbus/org.kde.LatteDock.xml) qt5_add_dbus_adaptor(lattedock-app_SRCS ${latte_dbusXML} lattecorona.h Latte::Corona lattedockadaptor) ki18n_wrap_ui(lattedock-app_SRCS settings/dialogs/detailsdialog.ui) ki18n_wrap_ui(lattedock-app_SRCS settings/dialogs/settingsdialog.ui) add_executable(latte-dock ${lattedock-app_SRCS}) include(FakeTarget.cmake) if(${KF5_VERSION_MINOR} LESS "62") target_link_libraries(latte-dock Qt5::DBus Qt5::Quick Qt5::Qml KF5::Activities KF5::Archive KF5::CoreAddons KF5::Crash KF5::DBusAddons KF5::Declarative KF5::GuiAddons KF5::GlobalAccel KF5::I18n KF5::IconThemes KF5::KIOWidgets KF5::Notifications KF5::NewStuff KF5::QuickAddons KF5::Plasma KF5::PlasmaQuick KF5::ProcessCore KF5::WaylandClient KF5::XmlGui Latte ) else() target_link_libraries(latte-dock Qt5::DBus Qt5::Quick Qt5::Qml KF5::Activities KF5::Archive KF5::CoreAddons KF5::Crash KF5::DBusAddons KF5::Declarative KF5::GuiAddons KF5::GlobalAccel KF5::I18n KF5::IconThemes KF5::KIOWidgets KF5::Notifications KF5::NewStuff KF5::QuickAddons KF5::Plasma KF5::PlasmaQuick KF5::WaylandClient KF5::XmlGui Latte ) endif() if(HAVE_X11) target_link_libraries(latte-dock Qt5::X11Extras KF5::WindowSystem ${X11_LIBRARIES} ${XCB_LIBRARIES} ) endif() configure_file(org.kde.latte-dock.desktop.cmake org.kde.latte-dock.desktop) configure_file(org.kde.latte-dock.appdata.xml.cmake org.kde.latte-dock.appdata.xml) install(TARGETS latte-dock ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/org.kde.latte-dock.desktop DESTINATION ${KDE_INSTALL_APPDIR}) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/org.kde.latte-dock.appdata.xml DESTINATION ${KDE_INSTALL_METAINFODIR}) install(FILES dbus/org.kde.LatteDock.xml DESTINATION ${KDE_INSTALL_DBUSINTERFACEDIR}) install(FILES lattedock.notifyrc DESTINATION ${KNOTIFYRC_INSTALL_DIR}) if(${KF5_VERSION_MINOR} LESS "57") install(FILES latte-layouts.knsrc DESTINATION ${CONFIG_INSTALL_DIR}) install(FILES latte-indicators.knsrc DESTINATION ${CONFIG_INSTALL_DIR}) else() install(FILES latte-layouts.knsrc DESTINATION ${KDE_INSTALL_KNSRCDIR}) install(FILES latte-indicators.knsrc DESTINATION ${KDE_INSTALL_KNSRCDIR}) endif() add_subdirectory(packageplugins) diff --git a/app/indicator/factory.cpp b/app/indicator/factory.cpp index 7616b680..e43f7035 100644 --- a/app/indicator/factory.cpp +++ b/app/indicator/factory.cpp @@ -1,380 +1,380 @@ /* * Copyright 2019 Michail Vourlakos * * 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 . */ #include "factory.h" // local #include "../layouts/importer.h" // Qt #include #include #include #include #include #include #include // KDE #include #include #include #include #include #include #include #include #include namespace Latte { namespace Indicator { Factory::Factory(QObject *parent) : QObject(parent) { m_parentWidget = new QWidget(); m_mainPaths = Latte::Layouts::Importer::standardPaths(); for(int i=0; iaddDir(dir); } connect(KDirWatch::self(), &KDirWatch::dirty, this, [ & ](const QString & path) { if (m_indicatorsPaths.contains(path)) { //! indicator updated reload(path); } else if (m_mainPaths.contains(path)){ //! consider indicator addition discoverNewIndicators(path); } }); connect(KDirWatch::self(), &KDirWatch::deleted, this, [ & ](const QString & path) { if (m_indicatorsPaths.contains(path)) { //! indicator removed removeIndicatorRecords(path); } }); qDebug() << m_plugins["org.kde.latte.default"].name(); } Factory::~Factory() { m_parentWidget->deleteLater(); } bool Factory::pluginExists(QString id) const { return m_plugins.contains(id); } int Factory::customPluginsCount() { return m_customPluginIds.count(); } QStringList Factory::customPluginIds() { return m_customPluginIds; } QStringList Factory::customPluginNames() { return m_customPluginNames; } QStringList Factory::customLocalPluginIds() { return m_customLocalPluginIds; } KPluginMetaData Factory::metadata(QString pluginId) { if (m_plugins.contains(pluginId)) { return m_plugins[pluginId]; } return KPluginMetaData(); } void Factory::reload(const QString &indicatorPath) { QString pluginChangedId; if (!indicatorPath.isEmpty() && indicatorPath != "." && indicatorPath != "..") { QString metadataFile = indicatorPath + "/metadata.desktop"; if(QFileInfo(metadataFile).exists()) { KPluginMetaData metadata = KPluginMetaData::fromDesktopFile(metadataFile); if (metadataAreValid(metadata)) { pluginChangedId = metadata.pluginId(); QString uiFile = indicatorPath + "/package/" + metadata.value("X-Latte-MainScript"); if (!m_plugins.contains(metadata.pluginId())) { m_plugins[metadata.pluginId()] = metadata; } if (QFileInfo(uiFile).exists()) { m_pluginUiPaths[metadata.pluginId()] = QFileInfo(uiFile).absolutePath(); } if ((metadata.pluginId() != "org.kde.latte.default") && (metadata.pluginId() != "org.kde.latte.plasma") && (metadata.pluginId() != "org.kde.latte.plasmatabstyle")) { if (!m_customPluginIds.contains(metadata.pluginId())) { m_customPluginIds << metadata.pluginId(); } if (!m_customPluginNames.contains(metadata.name())) { m_customPluginNames << metadata.name(); } } if (indicatorPath.startsWith(QDir::homePath())) { m_customLocalPluginIds << metadata.pluginId(); } } qDebug() << " Indicator Package Loaded ::: " << metadata.name() << " [" << metadata.pluginId() << "]" << " - [" << indicatorPath <<"]"; /*qDebug() << " Indicator value ::: " << metadata.pluginId(); qDebug() << " Indicator value ::: " << metadata.fileName(); qDebug() << " Indicator value ::: " << metadata.value("X-Latte-MainScript"); qDebug() << " Indicator value ::: " << metadata.value("X-Latte-ConfigUi"); qDebug() << " Indicator value ::: " << metadata.value("X-Latte-ConfigXml");*/ } } if (!pluginChangedId.isEmpty()) { emit indicatorChanged(pluginChangedId); } } void Factory::discoverNewIndicators(const QString &main) { if (!m_mainPaths.contains(main)) { return; } QDirIterator indicatorsDirs(main, QDir::Dirs | QDir::NoSymLinks | QDir::NoDotAndDotDot, QDirIterator::NoIteratorFlags); while(indicatorsDirs.hasNext()){ indicatorsDirs.next(); QString iPath = indicatorsDirs.filePath(); if (!m_indicatorsPaths.contains(iPath)) { m_indicatorsPaths << iPath; KDirWatch::self()->addDir(iPath); reload(iPath); } } } void Factory::removeIndicatorRecords(const QString &path) { if (m_indicatorsPaths.contains(path)) { QString pluginId = path.section('/',-1); m_plugins.remove(pluginId); m_pluginUiPaths.remove(pluginId); int pos = m_customPluginIds.indexOf(pluginId); m_customPluginIds.removeAt(pos); m_customPluginNames.removeAt(pos); m_customLocalPluginIds.removeAll(pluginId); m_indicatorsPaths.removeAll(path); KDirWatch::self()->removeDir(path); //! delay informing the removal in case it is just an update QTimer::singleShot(1000, [this, pluginId]() { emit indicatorRemoved(pluginId); }); } } bool Factory::isCustomType(const QString &id) const { return ((id != "org.kde.latte.default") && (id != "org.kde.latte.plasma") && (id != "org.kde.latte.plasmatabstyle")); } bool Factory::metadataAreValid(KPluginMetaData &metadata) { return metadata.isValid() && metadata.category() == "Latte Indicator" && !metadata.value("X-Latte-MainScript").isEmpty(); } bool Factory::metadataAreValid(QString &file) { if (QFileInfo(file).exists()) { KPluginMetaData metadata = KPluginMetaData::fromDesktopFile(file); return metadata.isValid(); } return false; } QString Factory::uiPath(QString pluginName) const { if (!m_pluginUiPaths.contains(pluginName)) { return ""; } return m_pluginUiPaths[pluginName]; } -Latte::Types::ImportExportState Factory::importIndicatorFile(QString compressedFile) +Latte::ImportExport::State Factory::importIndicatorFile(QString compressedFile) { auto showNotificationError = []() { auto notification = new KNotification("import-fail", KNotification::CloseOnTimeout); notification->setText(i18n("Failed to import indicator")); notification->sendEvent(); }; auto showNotificationSucceed = [](QString name, bool updated) { auto notification = new KNotification("import-done", KNotification::CloseOnTimeout); notification->setText(updated ? i18nc("indicator_name, imported updated","%0 indicator updated successfully").arg(name) : i18nc("indicator_name, imported success","%0 indicator installed successfully").arg(name)); notification->sendEvent(); }; KArchive *archive; KZip *zipArchive = new KZip(compressedFile); zipArchive->open(QIODevice::ReadOnly); //! if the file isnt a zip archive if (!zipArchive->isOpen()) { delete zipArchive; KTar *tarArchive = new KTar(compressedFile, QStringLiteral("application/x-tar")); tarArchive->open(QIODevice::ReadOnly); if (!tarArchive->isOpen()) { delete tarArchive; showNotificationError(); - return Latte::Types::Failed; + return Latte::ImportExport::FailedState; } else { archive = tarArchive; } } else { archive = zipArchive; } QTemporaryDir archiveTempDir; archive->directory()->copyTo(archiveTempDir.path()); //metadata file QString packagePath = archiveTempDir.path(); QString metadataFile = archiveTempDir.path() + "/metadata.desktop"; if (!QFileInfo(metadataFile).exists()){ QDirIterator iter(archiveTempDir.path(), QDir::Dirs | QDir::NoDotAndDotDot); while(iter.hasNext() ) { QString currentPath = iter.next(); QString tempMetadata = currentPath + "/metadata.desktop"; if (QFileInfo(tempMetadata).exists()) { metadataFile = tempMetadata; packagePath = currentPath; } } } KPluginMetaData metadata = KPluginMetaData::fromDesktopFile(metadataFile); if (metadataAreValid(metadata)) { QStringList standardPaths = Latte::Layouts::Importer::standardPaths(); QString installPath = standardPaths[0] + "/latte/indicators/" + metadata.pluginId(); bool updated{QDir(installPath).exists()}; if (QDir(installPath).exists()) { QDir(installPath).removeRecursively(); } QProcess process; process.start(QString("mv " +packagePath + " " + installPath)); process.waitForFinished(); QString output(process.readAllStandardOutput()); showNotificationSucceed(metadata.name(), updated); - return Latte::Types::Installed; + return Latte::ImportExport::InstalledState; } showNotificationError(); - return Latte::Types::Failed; + return Latte::ImportExport::FailedState; } void Factory::removeIndicator(QString id) { if (m_plugins.contains(id)) { QString pluginName = m_plugins[id].name(); auto msg = new QMessageBox(m_parentWidget); msg->setIcon(QMessageBox::Warning); msg->setWindowTitle(i18n("Remove Indicator")); msg->setText( i18n("Do you want to remove %0 indicator from your system?").arg(pluginName)); msg->setStandardButtons(QMessageBox::Yes | QMessageBox::No); msg->setDefaultButton(QMessageBox::No); connect(msg, &QMessageBox::finished, this, [ &, msg, id, pluginName](int result) { auto showRemovedSucceed = [](QString name) { auto notification = new KNotification("remove-done", KNotification::CloseOnTimeout); notification->setText(i18nc("indicator_name, removed success","%0 indicator removed successfully").arg(name)); notification->sendEvent(); }; if (result == QMessageBox::Yes) { qDebug() << "Trying to remove indicator :: " << id; QProcess process; process.start(QString("kpackagetool5 -r " +id + " -t Latte/Indicator")); process.waitForFinished(); showRemovedSucceed(pluginName); } }); msg->open(); } } void Factory::downloadIndicator() { KNS3::DownloadDialog dialog(QStringLiteral("latte-indicators.knsrc"), m_parentWidget); dialog.exec(); } } } diff --git a/app/indicator/factory.h b/app/indicator/factory.h index f119c3d3..d20ac37c 100644 --- a/app/indicator/factory.h +++ b/app/indicator/factory.h @@ -1,94 +1,94 @@ /* * Copyright 2019 Michail Vourlakos * * 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 . */ #ifndef INDICATORFACTORY_H #define INDICATORFACTORY_H +// local +#include "../types.h" + // Qt #include #include #include -// Latte -#include - class KPluginMetaData; namespace Latte { namespace Indicator { class Factory : public QObject { Q_OBJECT public: Factory(QObject *parent); ~Factory() override; int customPluginsCount(); QStringList customPluginIds(); QStringList customPluginNames(); QStringList customLocalPluginIds(); KPluginMetaData metadata(QString pluginId); void downloadIndicator(); void removeIndicator(QString id); bool pluginExists(QString id) const; bool isCustomType(const QString &id) const; QString uiPath(QString pluginName) const; //! metadata record static bool metadataAreValid(KPluginMetaData &metadata); //! metadata file static bool metadataAreValid(QString &file); //! imports an indicator compressed file - static Latte::Types::ImportExportState importIndicatorFile(QString compressedFile); + static Latte::ImportExport::State importIndicatorFile(QString compressedFile); signals: void indicatorChanged(const QString &indicatorId); void indicatorRemoved(const QString &indicatorId); private: void reload(const QString &indicatorPath); void removeIndicatorRecords(const QString &path); void discoverNewIndicators(const QString &main); private: QHash m_plugins; QHash m_pluginUiPaths; QStringList m_customPluginIds; QStringList m_customPluginNames; QStringList m_customLocalPluginIds; //! plugins paths QStringList m_mainPaths; QStringList m_indicatorsPaths; QWidget *m_parentWidget; }; } } #endif diff --git a/app/types.cpp b/app/types.cpp new file mode 100644 index 00000000..36496aff --- /dev/null +++ b/app/types.cpp @@ -0,0 +1,21 @@ +/* +* Copyright 2020 Michail Vourlakos +* +* +* 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 . +*/ + +#include "types.h" diff --git a/app/types.h b/app/types.h new file mode 100644 index 00000000..dea6ea81 --- /dev/null +++ b/app/types.h @@ -0,0 +1,42 @@ +/* +* Copyright 2020 Michail Vourlakos +* +* +* 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 . +*/ + +#ifndef LATTEAPPLOCALTYPES_H +#define LATTEAPPLOCALTYPES_H + +// Qt +#include + +namespace Latte { +namespace ImportExport { +Q_NAMESPACE + +enum State +{ + FailedState = 0, + UpdatedState = 2, + InstalledState = 4 +}; +Q_ENUM_NS(State); + +} +} + +#endif