/*************************************************************************** * This file is part of awesome-widgets * * * * awesome-widgets 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 3 of the * * License, or (at your option) any later version. * * * * awesome-widgets 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 awesome-widgets. If not, see http://www.gnu.org/licenses/ * ***************************************************************************/ #include "awactions.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "awdebug.h" #include "version.h" AWActions::AWActions(QObject *parent) : QObject(parent) { qCDebug(LOG_AW); } AWActions::~AWActions() { qCDebug(LOG_AW); } void AWActions::checkUpdates(const bool showAnyway) { qCDebug(LOG_AW); qCDebug(LOG_AW) << "Show anyway" << showAnyway; // showAnyway options requires to show message if no updates found on direct // request. In case of automatic check no message will be shown QNetworkAccessManager *manager = new QNetworkAccessManager(this); connect(manager, &QNetworkAccessManager::finished, [showAnyway, this](QNetworkReply *reply) { return versionReplyRecieved(reply, showAnyway); }); manager->get(QNetworkRequest(QUrl(VERSION_API))); } bool AWActions::dropCache() const { qCDebug(LOG_AW); QString fileName = QString("%1/awesomewidgets.ndx"). arg(QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation)); return QFile(fileName).remove(); } // HACK: since QML could not use QLoggingCategory I need this hack bool AWActions::isDebugEnabled() const { qCDebug(LOG_AW); return LOG_AW().isDebugEnabled(); } bool AWActions::runCmd(const QString cmd) const { qCDebug(LOG_AW); qCDebug(LOG_AW) << "Cmd" << cmd; sendNotification(QString("Info"), i18n("Run %1", cmd)); return QProcess::startDetached(cmd); } // HACK: this method uses variable from version.h void AWActions::showReadme() const { qCDebug(LOG_AW); QDesktopServices::openUrl(QString(HOMEPAGE)); } void AWActions::exportConfiguration(QObject *nativeConfig) const { qCDebug(LOG_AW); // get file path and init settings object QString fileName = QFileDialog::getSaveFileName(nullptr, i18n("Export")); if (fileName.isEmpty()) return; qCInfo(LOG_AW) << "Selected filename" << fileName; QSettings settings(fileName, QSettings::IniFormat); // additional parameters QString baseDir = QString("%1/awesomewidgets"). arg(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)); QStringList dirs = QStringList() << QString("desktops") << QString("quotes") << QString("scripts") << QString("upgrade") << QString("weather"); // plasmoid configuration QQmlPropertyMap *configuration = static_cast(nativeConfig); settings.beginGroup(QString("plasmoid")); foreach(QString key, configuration->keys()) { QVariant value = configuration->value(key); if (!value.isValid()) continue; settings.setValue(key, value); } settings.endGroup(); // extenstions foreach(QString item, dirs) { QStringList items = QDir(QString("%1/%2").arg(baseDir).arg(item)).entryList( QStringList() << QString("*.desktop"), QDir::Files); settings.beginGroup(item); foreach(QString it, items) { qCInfo(LOG_AW) << "Processing file" << it; settings.beginGroup(it); QSettings itemSettings(QString("%1/%2/%3").arg(baseDir).arg(item).arg(it), QSettings::IniFormat); itemSettings.beginGroup(QString("Desktop Entry")); foreach(QString key, itemSettings.childKeys()) settings.setValue(key, itemSettings.value(key)); itemSettings.endGroup(); settings.endGroup(); } settings.endGroup(); } // additional files settings.beginGroup(QString("json")); // script filters QFile filterFile(QString("%1/scripts/awesomewidgets-extscripts-filters.json").arg(baseDir)); if (filterFile.open(QIODevice::ReadOnly | QIODevice::Text)) { QString filterText = filterFile.readAll(); filterFile.close(); settings.setValue(QString("filters"), filterText); } else { qCWarning(LOG_LIB) << "Could not open" << filterFile.fileName(); } // weather icon settings QFile weatherIdFile(QString("%1/weather/awesomewidgets-extweather-ids.json").arg(baseDir)); if (weatherIdFile.open(QIODevice::ReadOnly | QIODevice::Text)) { QString weatherIdText = weatherIdFile.readAll(); weatherIdFile.close(); settings.setValue(QString("weathers"), weatherIdText); } else { qCWarning(LOG_LIB) << "Could not open" << weatherIdFile.fileName(); } settings.endGroup(); // sync settings settings.sync(); } // HACK: this method uses variables from version.h QString AWActions::getAboutText(const QString type) const { qCDebug(LOG_AW); qCDebug(LOG_AW) << "Type" << type; QString text; if (type == QString("header")) { text = QString(NAME); } else if (type == QString("version")) { text = i18n("Version %1 (build date %2)", QString(VERSION), QString(BUILD_DATE)); if (!QString(COMMIT_SHA).isEmpty()) text += QString(" (%1)").arg(QString(COMMIT_SHA)); } else if (type == QString("description")) { text = i18n("A set of minimalistic plasmoid widgets"); } else if (type == QString("links")) { text = i18n("Links:") + QString("
") + QString("%2
").arg(QString(HOMEPAGE)).arg(i18n("Homepage")) + QString("%2
").arg(QString(REPOSITORY)).arg(i18n("Repository")) + QString("%2
").arg(QString(BUGTRACKER)).arg(i18n("Bugtracker")) + QString("%2
").arg(QString(TRANSLATION)).arg(i18n("Translation issue")) + QString("%2
").arg(QString(AUR_PACKAGES)).arg(i18n("AUR packages")) + QString("%2").arg(QString(OPENSUSE_PACKAGES)).arg(i18n("openSUSE packages")); } else if (type == QString("copy")) { text = QString("© %1 %3
"). arg(QString(DATE)).arg(QString(EMAIL)).arg(QString(AUTHOR)) + i18n("This software is licensed under %1", QString(LICENSE)) + QString("
"); } else if (type == QString("translators")) { text = i18n("Translators: %1", QString(TRANSLATORS)); } else if (type == QString("3rdparty")) { QStringList trdPartyList = QString(TRDPARTY_LICENSE).split(QChar(';'), QString::SkipEmptyParts); for (int i=0; i%1 (%2 license)"). arg(trdPartyList.at(i).split(QChar(','))[0]). arg(trdPartyList.at(i).split(QChar(','))[1]). arg(trdPartyList.at(i).split(QChar(','))[2]); text = i18n("This software uses: %1", trdPartyList.join(QString(", "))); } return text; } QVariantMap AWActions::getFont(const QVariantMap defaultFont) const { qCDebug(LOG_AW); qCDebug(LOG_AW) << "Default font is" << defaultFont; QVariantMap fontMap; CFont defaultCFont = CFont(defaultFont[QString("family")].toString(), defaultFont[QString("size")].toInt(), 400, false, defaultFont[QString("color")].toString()); CFont font = CFontDialog::getFont(i18n("Select font"), defaultCFont, false, false); fontMap[QString("color")] = font.color().name(); fontMap[QString("family")] = font.family(); fontMap[QString("size")] = font.pointSize(); return fontMap; } QQmlPropertyMap* AWActions::importConfiguration() const { qCDebug(LOG_AW); QQmlPropertyMap *configuration = new QQmlPropertyMap(); // get file path and init settings object QString fileName = QFileDialog::getOpenFileName(nullptr, i18n("Import")); if (fileName.isEmpty()) return configuration; qCInfo(LOG_AW) << "Selected filename" << fileName; QSettings settings(fileName, QSettings::IniFormat); // additional parameters QString baseDir = QString("%1/awesomewidgets"). arg(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)); QStringList dirs = QStringList() << QString("desktops") << QString("quotes") << QString("scripts") << QString("upgrade") << QString("weather"); // check what should be exported QDialog *dialog = new QDialog(nullptr); QCheckBox *importPlasmoidSettings = new QCheckBox(i18n("Import plasmoid settings"), dialog); QCheckBox *importExtensionsSettings = new QCheckBox(i18n("Import extenstions"), dialog); QCheckBox *importAddsSettings = new QCheckBox(i18n("Import additional files"), dialog); QDialogButtonBox *dialogButtons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, dialog); QVBoxLayout *layout = new QVBoxLayout(dialog); layout->addWidget(importPlasmoidSettings); layout->addWidget(importExtensionsSettings); layout->addWidget(importAddsSettings); layout->addWidget(dialogButtons); connect(dialogButtons, SIGNAL(accepted()), dialog, SLOT(accept())); connect(dialogButtons, SIGNAL(rejected()), dialog, SLOT(reject())); // get parameters bool importPlasmoid = false; bool importExtensions = false; bool importAdds = false; switch(int ret = dialog->exec()) { case QDialog::Accepted: importPlasmoid = importPlasmoidSettings->isChecked(); importExtensions = importExtensionsSettings->isChecked(); importAdds = importAddsSettings->isChecked(); break; case QDialog::Rejected: default: break; } dialog->deleteLater(); // extenstions if (importExtensions) { foreach(QString item, dirs) { settings.beginGroup(item); qDebug() << settings.childGroups(); foreach(QString it, settings.childGroups()) { qCInfo(LOG_AW) << "Processing file" << it; settings.beginGroup(it); QSettings itemSettings(QString("%1/%2/%3").arg(baseDir).arg(item).arg(it), QSettings::IniFormat); itemSettings.beginGroup(QString("Desktop Entry")); foreach(QString key, settings.childKeys()) itemSettings.setValue(key, settings.value(key)); itemSettings.endGroup(); itemSettings.sync(); settings.endGroup(); } settings.endGroup(); } } // additional files if (importAdds) { settings.beginGroup(QString("json")); // script filters if (settings.contains(QString("filters"))) { QFile filterFile(QString("%1/scripts/awesomewidgets-extscripts-filters.json").arg(baseDir)); if (filterFile.open(QIODevice::WriteOnly | QIODevice::Text)) { QDataStream out(&filterFile); out << settings.value(QString("filters")).toString(); filterFile.close(); } else { qCWarning(LOG_LIB) << "Could not open" << filterFile.fileName(); } } // weather icon settings if (settings.contains(QString("weathers"))) { QFile weatherIdFile(QString("%1/weather/awesomewidgets-extweather-ids.json").arg(baseDir)); if (weatherIdFile.open(QIODevice::WriteOnly | QIODevice::Text)) { QDataStream out(&weatherIdFile); out << settings.value(QString("weathers")).toString(); weatherIdFile.close(); } else { qCWarning(LOG_LIB) << "Could not open" << weatherIdFile.fileName(); } } settings.endGroup(); } // plasmoid configuration if (importPlasmoid) { settings.beginGroup(QString("plasmoid")); foreach(QString key, settings.childKeys()) configuration->insert(key, settings.value(key)); configuration->insert(QString("valid"), true); settings.endGroup(); } return configuration; } QVariantMap AWActions::readDataEngineConfiguration() const { qCDebug(LOG_AW); QString fileName = QStandardPaths::locate(QStandardPaths::ConfigLocation, QString("plasma-dataengine-extsysmon.conf")); qCInfo(LOG_AW) << "Configuration file" << fileName; QSettings settings(fileName, QSettings::IniFormat); QVariantMap configuration; settings.beginGroup(QString("Configuration")); configuration[QString("ACPIPATH")] = settings.value(QString("ACPIPATH"), QString("/sys/class/power_supply/")); configuration[QString("GPUDEV")] = settings.value(QString("GPUDEV"), QString("auto")); configuration[QString("HDDDEV")] = settings.value(QString("HDDDEV"), QString("all")); configuration[QString("HDDTEMPCMD")] = settings.value(QString("HDDTEMPCMD"), QString("sudo smartctl -a")); configuration[QString("MPDADDRESS")] = settings.value(QString("MPDADDRESS"), QString("localhost")); configuration[QString("MPDPORT")] = settings.value(QString("MPDPORT"), QString("6600")); configuration[QString("MPRIS")] = settings.value(QString("MPRIS"), QString("auto")); configuration[QString("PLAYER")] = settings.value(QString("PLAYER"), QString("mpris")); configuration[QString("PLAYERSYMBOLS")] = settings.value(QString("PLAYERSYMBOLS"), QString("10")); settings.endGroup(); qCInfo(LOG_AW) << "Configuration" << configuration; return configuration; } void AWActions::writeDataEngineConfiguration(const QVariantMap configuration) const { qCDebug(LOG_AW); QString fileName = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + QString("/plasma-dataengine-extsysmon.conf"); QSettings settings(fileName, QSettings::IniFormat); qCInfo(LOG_AW) << "Configuration file" << settings.fileName(); settings.beginGroup(QString("Configuration")); settings.setValue(QString("ACPIPATH"), configuration[QString("ACPIPATH")]); settings.setValue(QString("GPUDEV"), configuration[QString("GPUDEV")]); settings.setValue(QString("HDDDEV"), configuration[QString("HDDDEV")]); settings.setValue(QString("HDDTEMPCMD"), configuration[QString("HDDTEMPCMD")]); settings.setValue(QString("MPDADDRESS"), configuration[QString("MPDADDRESS")]); settings.setValue(QString("MPDPORT"), configuration[QString("MPDPORT")]); settings.setValue(QString("MPRIS"), configuration[QString("MPRIS")]); settings.setValue(QString("PLAYER"), configuration[QString("PLAYER")]); settings.setValue(QString("PLAYERSYMBOLS"), configuration[QString("PLAYERSYMBOLS")]); settings.endGroup(); settings.sync(); } // to avoid additional object definition this method is static void AWActions::sendNotification(const QString eventId, const QString message) { qCDebug(LOG_AW); qCDebug(LOG_AW) << "Event" << eventId; qCDebug(LOG_AW) << "Message" << message; KNotification *notification = KNotification::event(eventId, QString("Awesome Widget ::: %1").arg(eventId), message); notification->setComponentName(QString("plasma-applet-org.kde.plasma.awesome-widget")); } void AWActions::showInfo(const QString version) const { qCDebug(LOG_AW); qCDebug(LOG_AW) << "Version" << version; QString text = i18n("You are using the actual version %1", version); if (!QString(COMMIT_SHA).isEmpty()) text += QString(" (%1)").arg(QString(COMMIT_SHA)); QMessageBox::information(nullptr, i18n("No new version found"), text); } void AWActions::showUpdates(const QString version) const { qCDebug(LOG_AW); qCDebug(LOG_AW) << "Version" << version; QString text; text += i18n("Current version : %1", QString(VERSION)); text += QString(COMMIT_SHA).isEmpty() ? QString("\n") : QString(" (%1)\n").arg(QString(COMMIT_SHA)); text += i18n("New version : %1", version) + QString("\n\n"); text += i18n("Click \"Ok\" to download"); int select = QMessageBox::information(nullptr, i18n("There are updates"), text, QMessageBox::Ok | QMessageBox::Cancel); switch (select) { case QMessageBox::Ok: QDesktopServices::openUrl(QString(RELEASES) + version); break; case QMessageBox::Cancel: default: break; } } void AWActions::versionReplyRecieved(QNetworkReply *reply, const bool showAnyway) const { qCDebug(LOG_AW); qCDebug(LOG_AW) << "Return code" << reply->error(); qCDebug(LOG_AW) << "Reply error message" << reply->errorString(); qCDebug(LOG_AW) << "Show anyway" << showAnyway; QJsonParseError error; QJsonDocument jsonDoc = QJsonDocument::fromJson(reply->readAll(), &error); reply->deleteLater(); if ((reply->error() != QNetworkReply::NoError) || (error.error != QJsonParseError::NoError)) { qCWarning(LOG_AW) << "Parse error" << error.errorString(); return; } // convert to map QVariantMap firstRelease = jsonDoc.toVariant().toList().first().toMap(); QString version = firstRelease[QString("tag_name")].toString(); version.remove(QString("V.")); qCInfo(LOG_AW) << "Found version" << version; // FIXME: possible there is a better way to check versions int old_major = QString(VERSION).split(QChar('.')).at(0).toInt(); int old_minor = QString(VERSION).split(QChar('.')).at(1).toInt(); int old_patch = QString(VERSION).split(QChar('.')).at(2).toInt(); int new_major = QString(version).split(QChar('.')).at(0).toInt(); int new_minor = QString(version).split(QChar('.')).at(1).toInt(); int new_patch = QString(version).split(QChar('.')).at(2).toInt(); if ((old_major < new_major) || ((old_major == new_major) && (old_minor < new_minor)) || ((old_major == new_major) && (old_minor == new_minor) && (old_patch < new_patch))) return showUpdates(version); else if (showAnyway) return showInfo(version); }