diff --git a/.gitmodules b/.gitmodules index 425dd6e..052080f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,9 +1,3 @@ -[submodule "sources/3rdparty/task"] - path = sources/3rdparty/task - url = https://github.com/arcan1s/qtadds-taskadds-qprocess.git -[submodule "sources/3rdparty/tasks"] - path = sources/3rdparty/tasks - url = https://github.com/mhogomchungu/tasks.git [submodule "sources/3rdparty/fontdialog"] path = sources/3rdparty/fontdialog url = https://github.com/arcan1s/qtadds-fontdialog.git diff --git a/CHANGELOG b/CHANGELOG index 8370635..59f3563 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,24 @@ +Ver.3.1.0: ++ implement templates support (#71) ++ implement special functions (#71) ++ special directory for configs (#72) ++ custom bar images (#80) ++ custom bar values (#80) ++ show changelog after updates ++ add Polish translation (thanks to Mariusz Kocoń) ++ use Qt-5.6 features +- fix invalid tooltip resize in desktop panel (#74) +- fix graphical items blinking (#81) +- drop tasks and move to native QProcess to avoid crash (#83) +- the newest Qt (5.6) fixes +- the newest Plasma fixes +* move from OWM to Yahoo! Weather (#73) +* improve performance by using optimized subscriptions (#75) +* improve performance by storing QVariant instead of frequent casting (#75) +* change bar names semantic to the simplest one (#80, breaking changes) +* high memory usage notifications have been changed from 90 to 80 perc +* a large part of refactoring + Ver.3.0.1: + add patches for old Qt versions - drop `nullptr` checking diff --git a/CHANGELOG-RU b/CHANGELOG-RU index c1fcbd5..7b604a6 100644 --- a/CHANGELOG-RU +++ b/CHANGELOG-RU @@ -1,3 +1,24 @@ +Вер.3.1.0: ++ добавлена поддержка шаблонов (#71) ++ добавлена поддержка специальных функций (#71) ++ добавлена отдельная директория для настроек (#72) ++ произвольные картинки для баров (#80) ++ произвольные значения для баров (#80) ++ показывать ченджлог после обновления ++ добавлен польский перевод (спасибо Mariusz Kocoń) ++ использование Qt-5.6 плюшек +- исправлено неправильное обновление размера тултипа в desktop panel (#74) +- исправлено мигание баров (#81) +- убрано использование tasks в пользу QProcess, чтобы избежать падения (#83) +- исправления, вызванные новым Qt (5.6) +- исправления, вызванные новой Plasma +* вместо OWM теперь используется Yahoo! Weather (#73) +* улучшена производительность путем оптимизированной подписки (#75) +* улучшена производительность путем хранения QVariant вместо частых кастов (#75) +* изменен принцип наименования баров (#80, ломает совместимость) +* уведомление о большом использовании памяти изменено с 90 на 80 процентов +* много рефакторинга + Вер.3.0.1: + добавлены патчи для старых версий Qt - убрана проверка на nullptr diff --git a/README.md b/README.md index d290084..63614c6 100644 --- a/README.md +++ b/README.md @@ -66,9 +66,9 @@ See [milestones](https://github.com/arcan1s/awesome-widgets/milestones) for more Links ----- -* [Homepage](http://arcanis.name/projects/awesome-widgets/) -* [Migration to 2.*](http://arcanis.name/en/2014/09/04/migration-to-v2/) -* [Scripts and bars](http://arcanis.name/en/2014/12/19/aw-v21-bells-and-whistles/) +* [Homepage](https://arcanis.me/projects/awesome-widgets/) +* [Migration to 2.*](https://arcanis.me/en/2014/09/04/migration-to-v2/) +* [Scripts and bars](https://arcanis.me/en/2014/12/19/aw-v21-bells-and-whistles/) * Plasmoid on [kde-look](http://kde-look.org/content/show.php/Awesome+Widgets?content=157124) * DataEngine on [kde-look](http://kde-look.org/content/show.php/Extended+Systemmonitor+DataEngine?content=158773) * Archlinux [AUR](https://aur.archlinux.org/packages/plasma5-applet-awesome-widgets/) package diff --git a/create_archive.sh b/create_archive.sh index 4211d32..a7e686e 100755 --- a/create_archive.sh +++ b/create_archive.sh @@ -11,8 +11,8 @@ git submodule update --init --recursive # build widget ARCHIVE="awesome-widgets" -FILES="AUTHORS CHANGELOG CHANGELOG-RU COPYING patches" -IGNORELIST="build usr .kdev4 *.kdev4 .idea" +FILES="AUTHORS CHANGELOG CHANGELOG-RU COPYING packages patches" +IGNORELIST="build usr .kdev4 *.kdev4 .idea packages/*src.tar.xz" # create archive [[ -e ${ARCHIVE}-${VERSION}-src.tar.xz ]] && rm -f "${ARCHIVE}-${VERSION}-src.tar.xz" [[ -d ${ARCHIVE} ]] && rm -rf "${ARCHIVE}" diff --git a/packages/PKGBUILD b/packages/PKGBUILD index 07e3615..3d876df 100644 --- a/packages/PKGBUILD +++ b/packages/PKGBUILD @@ -2,11 +2,11 @@ pkgname=plasma5-applet-awesome-widgets _pkgname=awesome-widgets -pkgver=3.0.1 +pkgver=3.1.0 pkgrel=1 pkgdesc="Collection of minimalistic Plasmoids which look like Awesome WM widgets (ex-PyTextMonitor)" arch=('i686' 'x86_64') -url="http://arcanis.name/projects/awesome-widgets" +url="https://arcanis.me/projects/awesome-widgets" license=('GPL3') depends=('plasma-framework') optdepends=("catalyst: for GPU monitor" @@ -17,7 +17,7 @@ optdepends=("catalyst: for GPU monitor" makedepends=('cmake' 'extra-cmake-modules') source=(https://github.com/arcan1s/awesome-widgets/releases/download/V.${pkgver}/${_pkgname}-${pkgver}-src.tar.xz) install=${pkgname}.install -md5sums=('6e17215102a4965b0167c5de0c9a5222') +md5sums=('08d1c0b3995ae6003a5b552a7ae7b93d') backup=('etc/xdg/plasma-dataengine-extsysmon.conf') prepare() { diff --git a/packages/PKGBUILD-git b/packages/PKGBUILD-git index 3567242..a4835a5 100644 --- a/packages/PKGBUILD-git +++ b/packages/PKGBUILD-git @@ -6,7 +6,7 @@ pkgver=2.2.1.r15.g78931b3 pkgrel=1 pkgdesc="Collection of minimalistic Plasmoids which look like Awesome WM widgets (ex-PyTextMonitor). Git version" arch=('i686' 'x86_64') -url="http://arcanis.name/projects/awesome-widgets" +url="https://arcanis.me/projects/awesome-widgets" license=('GPL3') depends=('plasma-framework') optdepends=("amarok: for music player monitor" diff --git a/patches/qt5.3-qtconcurrent-and-qlogging-category.patch b/patches/qt5.3-qtconcurrent-and-qlogging-category.patch index 04ccff4..a2e8e7f 100644 --- a/patches/qt5.3-qtconcurrent-and-qlogging-category.patch +++ b/patches/qt5.3-qtconcurrent-and-qlogging-category.patch @@ -24,24 +24,12 @@ diff --git a/sources/awesome-widget/plugin/awkeys.cpp b/sources/awesome-widget/p index e5b9861..eb73073 100644 --- a/sources/awesome-widget/plugin/awkeys.cpp +++ b/sources/awesome-widget/plugin/awkeys.cpp -@@ -439,7 +439,7 @@ void AWKeys::dataUpdated(const QString &sourceName, +@@ -439,4 +439,4 @@ void AWKeys::dataUpdated(const QString &sourceName, - #ifdef BUILD_FUTURE // run concurrent data update - QtConcurrent::run(m_threadPool, this, &AWKeys::setDataBySource, sourceName, + QtConcurrent::run(this, &AWKeys::setDataBySource, sourceName, data); - #else /* BUILD_FUTURE */ - return setDataBySource(sourceName, data); -@@ -564,7 +564,7 @@ void AWKeys::reinitKeys() - void AWKeys::updateTextData() - { - #ifdef BUILD_FUTURE -- QFuture text = QtConcurrent::run(m_threadPool, [this]() { -+ QFuture text = QtConcurrent::run([this]() { - calculateValues(); - return parsePattern(m_pattern); - }); diff --git a/sources/libraries.cmake b/sources/libraries.cmake index 33192f7..46e2b1e 100644 --- a/sources/libraries.cmake diff --git a/patches/qt5.4-replace-qml-dialogs.patch b/patches/qt5.4-replace-qml-dialogs.patch index 641730d..8bde1d3 100644 --- a/patches/qt5.4-replace-qml-dialogs.patch +++ b/patches/qt5.4-replace-qml-dialogs.patch @@ -10,7 +10,7 @@ index 01bcd58..1ec7ba6 100644 import org.kde.plasma.private.awesomewidget 1.0 -@@ -372,31 +371,7 @@ Item { +@@ -372,32 +371,7 @@ Item { QtControls.Button { width: parent.width * 3 / 5 text: i18n("Export configuration") @@ -21,6 +21,7 @@ index 01bcd58..1ec7ba6 100644 - id: saveConfigAs - selectExisting: false - title: i18n("Export") +- folder: awConfig.configurationDirectory() - onAccepted: { - var status = awConfig.exportConfiguration( - plasmoid.configuration, @@ -43,7 +44,7 @@ index 01bcd58..1ec7ba6 100644 } } -@@ -410,41 +385,9 @@ Item { +@@ -410,42 +385,9 @@ Item { QtControls.Button { width: parent.width * 3 / 5 text: i18n("Import configuration") @@ -53,6 +54,7 @@ index 01bcd58..1ec7ba6 100644 - QtDialogs.FileDialog { - id: openConfig - title: i18n("Import") +- folder: awConfig.configurationDirectory() - onAccepted: importSelection.open() - } - @@ -219,9 +221,9 @@ index 6263b30..5f61d2a 100644 // extensions - if (importExtensions) { + if (selection[QString("extensions")]) { - foreach (QString item, m_dirs) { + for (auto item : m_dirs) { settings.beginGroup(item); - foreach (QString it, settings.childGroups()) + for (auto it : settings.childGroups()) @@ -121,7 +139,7 @@ QVariantMap AWConfigHelper::importConfiguration(const QString fileName, } @@ -238,7 +240,7 @@ index 6263b30..5f61d2a 100644 - if (importPlasmoid) { + if (selection[QString("plasmoid")]) { settings.beginGroup(QString("plasmoid")); - foreach (QString key, settings.childKeys()) + for (auto key : settings.childKeys()) configuration[key] = settings.value(key); @@ -261,6 +279,50 @@ void AWConfigHelper::readFile(QSettings &settings, const QString key, } @@ -295,9 +297,10 @@ diff --git a/sources/awesome-widget/plugin/awconfighelper.h b/sources/awesome-wi index 912ac3d..dc51dfb 100644 --- a/sources/awesome-widget/plugin/awconfighelper.h +++ b/sources/awesome-widget/plugin/awconfighelper.h -@@ -33,12 +33,8 @@ public: +@@ -33,13 +33,9 @@ public: explicit AWConfigHelper(QObject *parent = nullptr); virtual ~AWConfigHelper(); + Q_INVOKABLE QString configurationDirectory() const; Q_INVOKABLE bool dropCache() const; - Q_INVOKABLE bool exportConfiguration(QObject *nativeConfig, - const QString fileName) const; @@ -322,10 +325,11 @@ diff --git a/sources/awesome-widget/plugin/awkeys.cpp b/sources/awesome-widget/p index e5b9861..039d24e 100644 --- a/sources/awesome-widget/plugin/awkeys.cpp +++ b/sources/awesome-widget/plugin/awkeys.cpp -@@ -324,6 +324,13 @@ QStringList AWKeys::getHddDevices() const +@@ -324,6 +324,14 @@ QStringList AWKeys::getHddDevices() const } ++#include +QString AWKeys::graphicalKey() const +{ + return QInputDialog::getItem(nullptr, i18n("Select tag"), QString(), @@ -335,7 +339,7 @@ index e5b9861..039d24e 100644 + QString AWKeys::infoByKey(QString key) const { - qCDebug(LOG_AW) << "Requested key" << key; + qCDebug(LOG_AW) << "Requested info for key" << key; diff --git a/sources/awesome-widget/plugin/awkeys.h b/sources/awesome-widget/plugin/awkeys.h index a8300f1..8edc3bd 100644 --- a/sources/awesome-widget/plugin/awkeys.h diff --git a/patches/qt5.5-qstringlist-and-qinfo.patch b/patches/qt5.5-qstringlist-and-qinfo.patch index 626e498..ff7845b 100644 --- a/patches/qt5.5-qstringlist-and-qinfo.patch +++ b/patches/qt5.5-qstringlist-and-qinfo.patch @@ -11,19 +11,21 @@ index f808d03..a056b3f 100644 #include "version.h" diff --git a/sources/awdebug.h b/sources/awdebug.h -index 48dc580..530c0d6 100644 +index 43944ce..c679281 100644 --- a/sources/awdebug.h +++ b/sources/awdebug.h -@@ -23,9 +23,9 @@ +@@ -21,9 +21,13 @@ + #include + ++#ifndef qCInfo ++#define qCInfo qCDebug ++#endif ++ #ifndef LOG_FORMAT #define LOG_FORMAT \ - "[%{time process}][%{if-debug}DD%{endif}%{if-info}II%{endif}%{if-" \ -- "warning}WW%{endif}%{if-critical}CC%{endif}%{if-fatal}FF%{endif}][%{" \ -- "category}][%{function}] %{message}" -+ "[%{time process}][%{if-debug}DD%{endif}%{if-warning}WW%{endif}%{if-" \ -+ "critical}CC%{endif}%{if-fatal}FF%{endif}][%{category}][%{function}] " \ -+ "%{message}" ++ "[%{time process}][%{if-debug}DD%{endif}%{if-" \ + "warning}WW%{endif}%{if-critical}CC%{endif}%{if-fatal}FF%{endif}][%{" \ + "category}][%{function}] %{message}" #endif /* LOG_FORMAT */ - - // redefine info because it doesn't log properly diff --git a/patches/qt5.6-qversionnumber.patch b/patches/qt5.6-qversionnumber.patch new file mode 100644 index 0000000..3520369 --- /dev/null +++ b/patches/qt5.6-qversionnumber.patch @@ -0,0 +1,134 @@ +diff --git a/sources/awesome-widget/plugin/awupdatehelper.cpp b/sources/awesome-widget/plugin/awupdatehelper.cpp +index 3698602..42871c8 100644 +--- a/sources/awesome-widget/plugin/awupdatehelper.cpp ++++ b/sources/awesome-widget/plugin/awupdatehelper.cpp +@@ -37,7 +37,7 @@ AWUpdateHelper::AWUpdateHelper(QObject *parent) + { + qCDebug(LOG_AW) << __PRETTY_FUNCTION__; + +- m_foundVersion = QVersionNumber::fromString(VERSION); ++ m_foundVersion = QString(VERSION); + m_genericConfig = QString("%1/awesomewidgets/general.ini") + .arg(QStandardPaths::writableLocation( + QStandardPaths::GenericDataLocation)); +@@ -69,14 +69,14 @@ void AWUpdateHelper::checkUpdates(const bool showAnyway) + bool AWUpdateHelper::checkVersion() + { + QSettings settings(m_genericConfig, QSettings::IniFormat); +- QVersionNumber version = QVersionNumber::fromString( +- settings.value(QString("Version"), QString(VERSION)).toString()); ++ QString version ++ = settings.value(QString("Version"), QString(VERSION)).toString(); + // update version + settings.setValue(QString("Version"), QString(VERSION)); + settings.sync(); + + qCInfo(LOG_AW) << "Found version" << version << "actual one is" << VERSION; +- if (version != QVersionNumber::fromString(VERSION)) { ++ if (version != QString(VERSION)) { + genMessageBox(i18n("Changelog of %1", QString(VERSION)), + QString(CHANGELOG).replace(QChar('@'), QChar('\n')), + QMessageBox::Ok) +@@ -90,12 +90,11 @@ bool AWUpdateHelper::checkVersion() + } + + +-void AWUpdateHelper::showInfo(const QVersionNumber version) ++void AWUpdateHelper::showInfo(const QString version) + { + qCDebug(LOG_AW) << "Version" << version; + +- QString text +- = i18n("You are using the actual version %1", version.toString()); ++ QString text = i18n("You are using the actual version %1", version); + if (!QString(COMMIT_SHA).isEmpty()) + text += QString(" (%1)").arg(QString(COMMIT_SHA)); + return genMessageBox(i18n("No new version found"), text, QMessageBox::Ok) +@@ -103,7 +102,7 @@ void AWUpdateHelper::showInfo(const QVersionNumber version) + } + + +-void AWUpdateHelper::showUpdates(const QVersionNumber version) ++void AWUpdateHelper::showUpdates(const QString version) + { + qCDebug(LOG_AW) << "Version" << version; + +@@ -112,7 +111,7 @@ void AWUpdateHelper::showUpdates(const QVersionNumber version) + text += QString(COMMIT_SHA).isEmpty() + ? QString("\n") + : QString(" (%1)\n").arg(QString(COMMIT_SHA)); +- text += i18n("New version : %1", version.toString()) + QString("\n\n"); ++ text += i18n("New version : %1", version) + QString("\n\n"); + text += i18n("Click \"Ok\" to download"); + + genMessageBox(i18n("There are updates"), text, +@@ -128,8 +127,7 @@ void AWUpdateHelper::userReplyOnUpdates(QAbstractButton *button) + + switch (ret) { + case QMessageBox::Ok: +- QDesktopServices::openUrl(QString(RELEASES) +- + m_foundVersion.toString()); ++ QDesktopServices::openUrl(QString(RELEASES) + m_foundVersion); + break; + case QMessageBox::Cancel: + default: +@@ -157,14 +155,23 @@ void AWUpdateHelper::versionReplyRecieved(QNetworkReply *reply, + QVariantMap firstRelease = jsonDoc.toVariant().toList().first().toMap(); + QString version = firstRelease[QString("tag_name")].toString(); + version.remove(QString("V.")); +- m_foundVersion = QVersionNumber::fromString(version); ++ m_foundVersion = version; + qCInfo(LOG_AW) << "Update found version to" << m_foundVersion; + +- QVersionNumber oldVersion = QVersionNumber::fromString(VERSION); +- if (oldVersion < m_foundVersion) +- return showUpdates(m_foundVersion); ++ // 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 = version.split(QChar('.')).at(0).toInt(); ++ int new_minor = version.split(QChar('.')).at(1).toInt(); ++ int new_patch = 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(m_foundVersion); ++ return showInfo(version); + } + + +diff --git a/sources/awesome-widget/plugin/awupdatehelper.h b/sources/awesome-widget/plugin/awupdatehelper.h +index 359cdb2..9c6a42d 100644 +--- a/sources/awesome-widget/plugin/awupdatehelper.h ++++ b/sources/awesome-widget/plugin/awupdatehelper.h +@@ -21,7 +21,6 @@ + + #include + #include +-#include + + + class QNetworkReply; +@@ -37,15 +36,15 @@ public: + bool checkVersion(); + + private slots: +- void showInfo(const QVersionNumber version); +- void showUpdates(const QVersionNumber version); ++ void showInfo(const QString version); ++ void showUpdates(const QString version); + void userReplyOnUpdates(QAbstractButton *button); + void versionReplyRecieved(QNetworkReply *reply, const bool showAnyway); + + private: + QMessageBox *genMessageBox(const QString title, const QString body, + const QMessageBox::StandardButtons buttons); +- QVersionNumber m_foundVersion; ++ QString m_foundVersion; + QString m_genericConfig; + }; + diff --git a/sources/3rdparty/task b/sources/3rdparty/task deleted file mode 160000 index d279820..0000000 --- a/sources/3rdparty/task +++ /dev/null @@ -1 +0,0 @@ -Subproject commit d2798204a1a84a23a9510aeda73d5b9b75d2c8eb diff --git a/sources/3rdparty/tasks b/sources/3rdparty/tasks deleted file mode 160000 index 230bdec..0000000 --- a/sources/3rdparty/tasks +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 230bdecd2c18ee2ec5350d94778a51158565c119 diff --git a/sources/CMakeLists.txt b/sources/CMakeLists.txt index 1ff1734..eae5b11 100644 --- a/sources/CMakeLists.txt +++ b/sources/CMakeLists.txt @@ -14,8 +14,8 @@ set(PROJECT_AUTHOR "Evgeniy Alekseev") set(PROJECT_CONTACT "esalexeev@gmail.com") set(PROJECT_LICENSE "GPL3") set(PROJECT_VERSION_MAJOR "3") -set(PROJECT_VERSION_MINOR "0") -set(PROJECT_VERSION_PATCH "1") +set(PROJECT_VERSION_MINOR "1") +set(PROJECT_VERSION_PATCH "0") set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}") # append git version if any set(PROJECT_COMMIT_SHA "Commit hash" CACHE INTERNAL "") @@ -39,6 +39,10 @@ option(BUILD_TESTING "Build with additional test abilities" OFF) set(CLANGFORMAT_EXECUTABLE "/usr/bin/clang-format" CACHE STRING "Path to clang-format executable") set(CPPCHECK_EXECUTABLE "/usr/bin/cppcheck" CACHE STRING "Path to cppcheck executable") +# generate changelog +set(PROJECT_CHANGELOG "Changelog" CACHE INTERNAL "") +include(changelog.cmake) + # flags if (CMAKE_COMPILER_IS_GNUCXX) set(CMAKE_CXX_FLAGS "-Wall -Wno-cpp -std=c++14") diff --git a/sources/awdebug.cpp b/sources/awdebug.cpp index eee61e1..40a8d5f 100644 --- a/sources/awdebug.cpp +++ b/sources/awdebug.cpp @@ -78,7 +78,7 @@ const QStringList getBuildData() metadata.append( QString(" CPPCHECK_EXECUTABLE: %1").arg(CPPCHECK_EXECUTABLE)); metadata.append(QString(" PROP_FUTURE: %1").arg(PROP_FUTURE)); - metadata.append(QString(" PROP_FUTURE: %1").arg(PROP_FUTURE)); + metadata.append(QString(" PROP_TEST: %1").arg(PROP_TEST)); return metadata; } diff --git a/sources/awesome-widget/metadata.desktop b/sources/awesome-widget/metadata.desktop index e87c445..52f21e6 100644 --- a/sources/awesome-widget/metadata.desktop +++ b/sources/awesome-widget/metadata.desktop @@ -21,7 +21,7 @@ X-KDE-PluginInfo-Author=Evgeniy Alekseev aka arcanis X-KDE-PluginInfo-Email=esalexeev@gmail.com X-KDE-PluginInfo-Name=org.kde.plasma.awesomewidget X-KDE-PluginInfo-Version=@PROJECT_VERSION@ -X-KDE-PluginInfo-Website=http://arcanis.name/projects/awesome-widgets/ +X-KDE-PluginInfo-Website=https://arcanis.me/projects/awesome-widgets/ X-KDE-PluginInfo-Category=System Information X-KDE-PluginInfo-Depends= X-KDE-PluginInfo-License=GPLv3 diff --git a/sources/awesome-widget/package/contents/config/main.xml b/sources/awesome-widget/package/contents/config/main.xml index 05fc242..23d14c7 100644 --- a/sources/awesome-widget/package/contents/config/main.xml +++ b/sources/awesome-widget/package/contents/config/main.xml @@ -32,6 +32,9 @@ true + + true + 0 @@ -95,13 +98,13 @@ #ffff00 - + true - + #00ffff - + #ff00ff diff --git a/sources/awesome-widget/package/contents/ui/advanced.qml b/sources/awesome-widget/package/contents/ui/advanced.qml index 01bcd58..d3e2549 100644 --- a/sources/awesome-widget/package/contents/ui/advanced.qml +++ b/sources/awesome-widget/package/contents/ui/advanced.qml @@ -45,6 +45,7 @@ Item { property alias cfg_wrapText: wordWrap.checked property alias cfg_notify: notify.checked property alias cfg_checkUpdates: updates.checked + property alias cfg_optimize: optimize.checked property alias cfg_height: widgetHeight.value property alias cfg_width: widgetWidth.value property alias cfg_interval: update.value @@ -143,6 +144,20 @@ Item { } } + Row { + height: implicitHeight + width: parent.width + QtControls.Label { + height: parent.heigth + width: parent.width * 2 / 5 + } + QtControls.CheckBox { + id: optimize + width: parent.width * 3 / 5 + text: i18n("Optimize subscription") + } + } + Row { height: implicitHeight width: parent.width @@ -379,6 +394,7 @@ Item { id: saveConfigAs selectExisting: false title: i18n("Export") + folder: awConfig.configurationDirectory() onAccepted: { var status = awConfig.exportConfiguration( plasmoid.configuration, @@ -416,6 +432,7 @@ Item { QtDialogs.FileDialog { id: openConfig title: i18n("Import") + folder: awConfig.configurationDirectory() onAccepted: importSelection.open() } diff --git a/sources/awesome-widget/package/contents/ui/main.qml b/sources/awesome-widget/package/contents/ui/main.qml index 23e9690..0e20bc9 100644 --- a/sources/awesome-widget/package/contents/ui/main.qml +++ b/sources/awesome-widget/package/contents/ui/main.qml @@ -46,15 +46,15 @@ Item { "cpuclTooltip": plasmoid.configuration.cpuclTooltip, "memTooltip": plasmoid.configuration.memTooltip, "swapTooltip": plasmoid.configuration.swapTooltip, - "downTooltip": plasmoid.configuration.downTooltip, - "upTooltip": plasmoid.configuration.downTooltip, + "downkbTooltip": plasmoid.configuration.downkbTooltip, + "upkbTooltip": plasmoid.configuration.downkbTooltip, "batTooltip": plasmoid.configuration.batTooltip, "cpuTooltipColor": plasmoid.configuration.cpuTooltipColor, "cpuclTooltipColor": plasmoid.configuration.cpuclTooltipColor, "memTooltipColor": plasmoid.configuration.memTooltipColor, "swapTooltipColor": plasmoid.configuration.swapTooltipColor, - "downTooltipColor": plasmoid.configuration.downTooltipColor, - "upTooltipColor": plasmoid.configuration.upTooltipColor, + "downkbTooltipColor": plasmoid.configuration.downkbTooltipColor, + "upkbTooltipColor": plasmoid.configuration.upkbTooltipColor, "batTooltipColor": plasmoid.configuration.batTooltipColor, "batInTooltipColor": plasmoid.configuration.batInTooltipColor, // additional field to parse AC status @@ -136,7 +136,9 @@ Item { if (debug) console.debug() // actions - plasmoid.setAction("requestKey", i18n("Request key"), "utilities-system-monitor") + // it makes no sense to use this field with optimization enable + if (!plasmoid.configuration.optimize) + plasmoid.setAction("requestKey", i18n("Request key"), "utilities-system-monitor") plasmoid.setAction("showReadme", i18n("Show README"), "text-x-readme") plasmoid.setAction("checkUpdates", i18n("Check updates"), "system-software-update") // init submodule @@ -187,9 +189,9 @@ Item { if (debug) console.debug() // init submodule - awKeys.initKeys(plasmoid.configuration.text, plasmoid.configuration.interval, - plasmoid.configuration.queueLimit) awKeys.initDataAggregator(tooltipSettings) + awKeys.initKeys(plasmoid.configuration.text, plasmoid.configuration.interval, + plasmoid.configuration.queueLimit, plasmoid.configuration.optimize) awKeys.setWrapNewLines(plasmoid.configuration.wrapNewLines) // configure aggregator awKeys.setAggregatorProperty("acOffline", plasmoid.configuration.acOffline) diff --git a/sources/awesome-widget/package/contents/ui/tooltip.qml b/sources/awesome-widget/package/contents/ui/tooltip.qml index 15b68f4..64eba9a 100644 --- a/sources/awesome-widget/package/contents/ui/tooltip.qml +++ b/sources/awesome-widget/package/contents/ui/tooltip.qml @@ -48,9 +48,9 @@ Item { property alias cfg_memTooltipColor: memTooltipColor.text property alias cfg_swapTooltip: swapTooltip.checked property alias cfg_swapTooltipColor: swapTooltipColor.text - property alias cfg_downTooltip: downTooltip.checked - property alias cfg_downTooltipColor: downTooltipColor.text - property alias cfg_upTooltipColor: upTooltipColor.text + property alias cfg_downkbTooltip: downkbTooltip.checked + property alias cfg_downkbTooltipColor: downkbTooltipColor.text + property alias cfg_upkbTooltipColor: upkbTooltipColor.text property alias cfg_batTooltip: batTooltip.checked property alias cfg_batTooltipColor: batTooltipColor.text property alias cfg_batInTooltipColor: batInTooltipColor.text @@ -273,7 +273,7 @@ Item { } QtControls.GroupBox { - id: downTooltip + id: downkbTooltip height: implicitHeight width: parent.width checkable: true @@ -292,22 +292,22 @@ Item { text: i18n("Download speed color") } QtControls.Button { - id: downTooltipColor + id: downkbTooltipColor width: parent.width * 3 / 5 style: QtStyles.ButtonStyle { background: Rectangle { - color: plasmoid.configuration.downTooltipColor + color: plasmoid.configuration.downkbTooltipColor } } - text: plasmoid.configuration.downTooltipColor - onClicked: downTooltipColorDialog.visible = true + text: plasmoid.configuration.downkbTooltipColor + onClicked: downkbTooltipColorDialog.visible = true } QtDialogs.ColorDialog { - id: downTooltipColorDialog + id: downkbTooltipColorDialog title: i18n("Select a color") - color: downTooltipColor.text - onAccepted: downTooltipColor.text = downTooltipColorDialog.color + color: downkbTooltipColor.text + onAccepted: downkbTooltipColor.text = downkbTooltipColorDialog.color } } Row { @@ -321,22 +321,22 @@ Item { text: i18n("Upload speed color") } QtControls.Button { - id: upTooltipColor + id: upkbTooltipColor width: parent.width * 3 / 5 style: QtStyles.ButtonStyle { background: Rectangle { - color: plasmoid.configuration.upTooltipColor + color: plasmoid.configuration.upkbTooltipColor } } - text: plasmoid.configuration.upTooltipColor - onClicked: upTooltipColorDialog.visible = true + text: plasmoid.configuration.upkbTooltipColor + onClicked: upkbTooltipColorDialog.visible = true } QtDialogs.ColorDialog { - id: upTooltipColorDialog + id: upkbTooltipColorDialog title: i18n("Select a color") - color: upTooltipColor.text - onAccepted: upTooltipColor.text = upTooltipColorDialog.color + color: upkbTooltipColor.text + onAccepted: upkbTooltipColor.text = upkbTooltipColorDialog.color } } } diff --git a/sources/awesome-widget/package/contents/ui/widget.qml b/sources/awesome-widget/package/contents/ui/widget.qml index 4c7c508..640617e 100644 --- a/sources/awesome-widget/package/contents/ui/widget.qml +++ b/sources/awesome-widget/package/contents/ui/widget.qml @@ -53,7 +53,7 @@ Item { horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter wrapMode: Text.WordWrap - text: i18n("Detailed information may be found on project homepage") + text: i18n("Detailed information may be found on project homepage") onLinkActivated: Qt.openUrlExternally(link); } @@ -262,8 +262,8 @@ Item { if (debug) console.debug() if (model[currentIndex]["regexp"] == "functions") tags.model = ["{{\n\n}}", "template{{\n\n}}", - "aw_all<>()", "aw_count<>()", "aw_keys<>()", - "aw_names<>()"] + "aw_all<>{{}}", "aw_count<>{{}}", "aw_keys<>{{}}", + "aw_names<>{{}}"] else tags.model = awKeys.dictKeys(true, model[currentIndex]["regexp"]) if (debug) console.info("Init model", tags.model, "for", model[currentIndex]["label"]) @@ -318,7 +318,7 @@ Item { onClicked: { lock = false awKeys.initKeys(textPattern.text, plasmoid.configuration.interval, - plasmoid.configuration.queueLimit) + plasmoid.configuration.queueLimit, false) awKeys.needToBeUpdated() } } @@ -346,7 +346,7 @@ Item { awKeys.needTextToBeUpdated.connect(needTextUpdate) // init submodule awKeys.initKeys(plasmoid.configuration.text, plasmoid.configuration.interval, - plasmoid.configuration.queueLimit) + plasmoid.configuration.queueLimit, false) awKeys.setAggregatorProperty("acOffline", plasmoid.configuration.acOffline) awKeys.setAggregatorProperty("acOnline", plasmoid.configuration.acOnline) awKeys.setAggregatorProperty("customTime", plasmoid.configuration.customTime) diff --git a/sources/awesome-widget/package/metadata.desktop b/sources/awesome-widget/package/metadata.desktop index 8983e48..8e057c0 100644 --- a/sources/awesome-widget/package/metadata.desktop +++ b/sources/awesome-widget/package/metadata.desktop @@ -21,7 +21,7 @@ X-KDE-PluginInfo-Author=Evgeniy Alekseev aka arcanis X-KDE-PluginInfo-Email=esalexeev@gmail.com X-KDE-PluginInfo-Name=org.kde.plasma.awesomewidget X-KDE-PluginInfo-Version=3.0.1 -X-KDE-PluginInfo-Website=http://arcanis.name/projects/awesome-widgets/ +X-KDE-PluginInfo-Website=https://arcanis.me/projects/awesome-widgets/ X-KDE-PluginInfo-Category=System Information X-KDE-PluginInfo-Depends= X-KDE-PluginInfo-License=GPLv3 diff --git a/sources/awesome-widget/plugin/awactions.cpp b/sources/awesome-widget/plugin/awactions.cpp index f519632..93efb56 100644 --- a/sources/awesome-widget/plugin/awactions.cpp +++ b/sources/awesome-widget/plugin/awactions.cpp @@ -21,19 +21,13 @@ #include #include -#include -#include -#include -#include -#include -#include #include -#include -#include +#include #include #include "awdebug.h" +#include "awupdatehelper.h" #include "version.h" @@ -41,12 +35,16 @@ AWActions::AWActions(QObject *parent) : QObject(parent) { qCDebug(LOG_AW) << __PRETTY_FUNCTION__; + + m_updateHelper = new AWUpdateHelper(this); } AWActions::~AWActions() { qCDebug(LOG_AW) << __PRETTY_FUNCTION__; + + delete m_updateHelper; } @@ -54,15 +52,8 @@ void AWActions::checkUpdates(const bool showAnyway) { 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(nullptr); - connect(manager, &QNetworkAccessManager::finished, - [showAnyway, this](QNetworkReply *reply) { - return versionReplyRecieved(reply, showAnyway); - }); - - manager->get(QNetworkRequest(QUrl(VERSION_API))); + if (!m_updateHelper->checkVersion()) + m_updateHelper->checkUpdates(showAnyway); } @@ -86,7 +77,7 @@ bool AWActions::runCmd(const QString cmd) const // HACK: this method uses variable from version.h void AWActions::showReadme() const { - QDesktopServices::openUrl(QString(HOMEPAGE)); + QDesktopServices::openUrl(QUrl(HOMEPAGE)); } @@ -186,78 +177,3 @@ void AWActions::sendNotification(const QString eventId, const QString message) notification->setComponentName( QString("plasma-applet-org.kde.plasma.awesome-widget")); } - - -void AWActions::showInfo(const QString version) const -{ - 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) << "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) << "Return code" << reply->error() << "with message" - << reply->errorString() << "and show anyway" << showAnyway; - - QJsonParseError error; - QJsonDocument jsonDoc = QJsonDocument::fromJson(reply->readAll(), &error); - if ((reply->error() != QNetworkReply::NoError) - || (error.error != QJsonParseError::NoError)) { - qCWarning(LOG_AW) << "Parse error" << error.errorString(); - return; - } - reply->deleteLater(); - - // 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 = version.split(QChar('.')).at(0).toInt(); - int new_minor = version.split(QChar('.')).at(1).toInt(); - int new_patch = 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); -} diff --git a/sources/awesome-widget/plugin/awactions.h b/sources/awesome-widget/plugin/awactions.h index af1374a..2f14650 100644 --- a/sources/awesome-widget/plugin/awactions.h +++ b/sources/awesome-widget/plugin/awactions.h @@ -22,7 +22,7 @@ #include -class QNetworkReply; +class AWUpdateHelper; class AWActions : public QObject { @@ -44,11 +44,8 @@ public slots: Q_INVOKABLE static void sendNotification(const QString eventId, const QString message); -private slots: - void showInfo(const QString version) const; - void showUpdates(const QString version) const; - void versionReplyRecieved(QNetworkReply *reply, - const bool showAnyway) const; +private: + AWUpdateHelper *m_updateHelper = nullptr; }; diff --git a/sources/awesome-widget/plugin/awconfighelper.cpp b/sources/awesome-widget/plugin/awconfighelper.cpp index 2dd0259..a7b26be 100644 --- a/sources/awesome-widget/plugin/awconfighelper.cpp +++ b/sources/awesome-widget/plugin/awconfighelper.cpp @@ -40,6 +40,25 @@ AWConfigHelper::~AWConfigHelper() } +QString AWConfigHelper::configurationDirectory() const +{ + // get readable directory + QString localDir = QString("%1/awesomewidgets/configs") + .arg(QStandardPaths::writableLocation( + QStandardPaths::GenericDataLocation)); + + // create directory and copy files from default settings + QDir localDirectory; + if ((!localDirectory.exists(localDir)) + && (localDirectory.mkpath(localDir))) { + qCInfo(LOG_AW) << "Created directory" << localDir; + copyConfigs(localDir); + } + + return localDir; +} + + bool AWConfigHelper::dropCache() const { QString fileName = QString("%1/awesomewidgets.ndx") @@ -212,6 +231,28 @@ void AWConfigHelper::writeDataEngineConfiguration( } +void AWConfigHelper::copyConfigs(const QString localDir) const +{ + qCDebug(LOG_AW) << "Local directory" << localDir; + + QStringList dirs = QStandardPaths::locateAll( + QStandardPaths::GenericDataLocation, QString("awesomewidgets/configs"), + QStandardPaths::LocateDirectory); + for (auto dir : dirs) { + if (dir == localDir) + continue; + QStringList files = QDir(dir).entryList(QDir::Files); + for (auto source : files) { + QString destination = QString("%1/%2").arg(localDir).arg(source); + bool status = QFile::copy(QString("%1/%2").arg(dir).arg(source), + destination); + qCInfo(LOG_AW) << "File" << source << "has been copied to" + << destination << "with status" << status; + } + } +} + + void AWConfigHelper::copyExtensions(const QString item, const QString type, QSettings &settings, const bool inverse) const diff --git a/sources/awesome-widget/plugin/awconfighelper.h b/sources/awesome-widget/plugin/awconfighelper.h index 912ac3d..d16e297 100644 --- a/sources/awesome-widget/plugin/awconfighelper.h +++ b/sources/awesome-widget/plugin/awconfighelper.h @@ -32,6 +32,7 @@ class AWConfigHelper : public QObject public: explicit AWConfigHelper(QObject *parent = nullptr); virtual ~AWConfigHelper(); + Q_INVOKABLE QString configurationDirectory() const; Q_INVOKABLE bool dropCache() const; Q_INVOKABLE bool exportConfiguration(QObject *nativeConfig, const QString fileName) const; @@ -46,6 +47,7 @@ public: private: // methods + void copyConfigs(const QString localDir) const; void copyExtensions(const QString item, const QString type, QSettings &settings, const bool inverse) const; void copySettings(QSettings &from, QSettings &to) const; diff --git a/sources/awesome-widget/plugin/awdataaggregator.cpp b/sources/awesome-widget/plugin/awdataaggregator.cpp index 01b358c..7bfa9bd 100644 --- a/sources/awesome-widget/plugin/awdataaggregator.cpp +++ b/sources/awesome-widget/plugin/awdataaggregator.cpp @@ -25,7 +25,7 @@ #include #include -#include +#include #include "awactions.h" #include "awdebug.h" @@ -35,12 +35,18 @@ AWDataAggregator::AWDataAggregator(QObject *parent) : QObject(parent) { qCDebug(LOG_AW) << __PRETTY_FUNCTION__; - // required by signals - qRegisterMetaType>("QHash"); + + boundaries[QString("cpuTooltip")] = 100.0; + boundaries[QString("cpuclTooltip")] = 4000.0; + boundaries[QString("memTooltip")] = 100.0; + boundaries[QString("swapTooltip")] = 100.0; + boundaries[QString("downkbTooltip")] = 1.0; + boundaries[QString("upkbTooltip")] = 1.0; + boundaries[QString("batTooltip")] = 100.0; initScene(); - connect(this, SIGNAL(updateData(const QHash &)), this, - SLOT(dataUpdate(const QHash &))); + connect(this, SIGNAL(updateData(const QVariantHash &)), this, + SLOT(dataUpdate(const QVariantHash &))); } @@ -87,19 +93,11 @@ void AWDataAggregator::setParameters(QVariantMap settings) counts += configuration[QString("cpuclTooltip")].toInt(); counts += configuration[QString("memTooltip")].toInt(); counts += configuration[QString("swapTooltip")].toInt(); - counts += configuration[QString("downTooltip")].toInt(); + counts += configuration[QString("downkbTooltip")].toInt(); counts += configuration[QString("batTooltip")].toInt(); // resize tooltip image toolTipView->resize(100 * counts, 105); - boundaries[QString("cpuTooltip")] = 100.0; - boundaries[QString("cpuclTooltip")] = 4000.0; - boundaries[QString("memTooltip")] = 100.0; - boundaries[QString("swapTooltip")] = 100.0; - boundaries[QString("downTooltip")] = 1.0; - boundaries[QString("upTooltip")] = 1.0; - boundaries[QString("batTooltip")] = 100.0; - requiredKeys.clear(); if (configuration[QString("cpuTooltip")].toBool()) requiredKeys.append(QString("cpuTooltip")); @@ -109,10 +107,10 @@ void AWDataAggregator::setParameters(QVariantMap settings) requiredKeys.append(QString("memTooltip")); if (configuration[QString("swapTooltip")].toBool()) requiredKeys.append(QString("swapTooltip")); - if (configuration[QString("downTooltip")].toBool()) - requiredKeys.append(QString("downTooltip")); - if (configuration[QString("upTooltip")].toBool()) - requiredKeys.append(QString("upTooltip")); + if (configuration[QString("downkbTooltip")].toBool()) + requiredKeys.append(QString("downkbTooltip")); + if (configuration[QString("upkbTooltip")].toBool()) + requiredKeys.append(QString("upkbTooltip")); if (configuration[QString("batTooltip")].toBool()) requiredKeys.append(QString("batTooltip")); @@ -133,9 +131,9 @@ QPixmap AWDataAggregator::tooltipImage() bool down = false; for (auto key : requiredKeys) { // create frame - float normX = 100.0 / static_cast(data[key].count()); - float normY = 100.0 / (1.5 * boundaries[key]); - float shift = requiredKeys.indexOf(key) * 100.0; + float normX = 100.0f / static_cast(data[key].count()); + float normY = 100.0f / (1.5f * boundaries[key]); + float shift = requiredKeys.indexOf(key) * 100.0f; if (down) shift -= 100.0; // apply pen color @@ -146,9 +144,9 @@ QPixmap AWDataAggregator::tooltipImage() for (int j = 0; j < data[key].count() - 1; j++) { // some magic here float x1 = j * normX + shift; - float y1 = -fabs(data[key].at(j)) * normY + 5.0; + float y1 = -fabs(data[key].at(j)) * normY + 5.0f; float x2 = (j + 1) * normX + shift; - float y2 = -fabs(data[key].at(j + 1)) * normY + 5.0; + float y2 = -fabs(data[key].at(j + 1)) * normY + 5.0f; if (key == QString("batTooltip")) { if (data[key].at(j + 1) > 0) pen.setColor(QColor( @@ -160,7 +158,7 @@ QPixmap AWDataAggregator::tooltipImage() } toolTipScene->addLine(x1, y1, x2, y2, pen); } - if (key == QString("downTooltip")) + if (key == QString("downkbTooltip")) down = true; } @@ -168,7 +166,7 @@ QPixmap AWDataAggregator::tooltipImage() } -void AWDataAggregator::dataUpdate(const QHash &values) +void AWDataAggregator::dataUpdate(const QVariantHash &values) { // do not log these arguments setData(values); @@ -254,24 +252,25 @@ QString AWDataAggregator::notificationText(const QString source, } -void AWDataAggregator::setData(const QHash &values) +void AWDataAggregator::setData(const QVariantHash &values) { // do not log these arguments // battery update requires info is AC online or not - setData(values[QString("ac")] == configuration[QString("acOnline")], + setData(values[QString("ac")].toString() + == configuration[QString("acOnline")], QString("batTooltip"), values[QString("bat")].toFloat()); // usual case setData(QString("cpuTooltip"), values[QString("cpu")].toFloat(), 90.0); setData(QString("cpuclTooltip"), values[QString("cpucl")].toFloat()); - setData(QString("memTooltip"), values[QString("mem")].toFloat(), 90.0); + setData(QString("memTooltip"), values[QString("mem")].toFloat(), 80.0); setData(QString("swapTooltip"), values[QString("swap")].toFloat(), 0.0); - setData(QString("downTooltip"), values[QString("downkb")].toFloat()); - setData(QString("upTooltip"), values[QString("upkb")].toFloat()); + setData(QString("downkbTooltip"), values[QString("downkb")].toFloat()); + setData(QString("upkbTooltip"), values[QString("upkb")].toFloat()); // additional check for network device [this](const QString value) { checkValue(QString("netdev"), currentNetworkDevice, value); currentNetworkDevice = value; - }(values[QString("netdev")]); + }(values[QString("netdev")].toString()); // additional check for GPU load [this](const float value) { checkValue(QString("gpu"), value, 90.0); @@ -298,12 +297,15 @@ void AWDataAggregator::setData(const QString &source, float value, checkValue(source, value, extremum); data[source].append(value); - if (source == QString("downTooltip")) { + if (source == QString("downkbTooltip")) { QList netValues - = data[QString("downTooltip")] + data[QString("upTooltip")]; - boundaries[QString("downTooltip")] - = 1.2 * *std::max_element(netValues.cbegin(), netValues.cend()); - boundaries[QString("upTooltip")] = boundaries[QString("downTooltip")]; + = data[QString("downkbTooltip")] + data[QString("upkbTooltip")]; + // to avoid inf value of normY + netValues << 1.0; + boundaries[QString("downkbTooltip")] + = 1.2f * *std::max_element(netValues.cbegin(), netValues.cend()); + boundaries[QString("upkbTooltip")] + = boundaries[QString("downkbTooltip")]; } } diff --git a/sources/awesome-widget/plugin/awdataaggregator.h b/sources/awesome-widget/plugin/awdataaggregator.h index 6abcddb..a5da613 100644 --- a/sources/awesome-widget/plugin/awdataaggregator.h +++ b/sources/awesome-widget/plugin/awdataaggregator.h @@ -41,11 +41,11 @@ public: QPixmap tooltipImage(); signals: - void updateData(const QHash &values); + void updateData(const QVariantHash &values); void toolTipPainted(const QString image) const; -public slots: - void dataUpdate(const QHash &values); +private slots: + void dataUpdate(const QVariantHash &values); private: // ui @@ -59,9 +59,9 @@ private: QString notificationText(const QString source, const float value) const; QString notificationText(const QString source, const QString value) const; // main method - void setData(const QHash &values); + void setData(const QVariantHash &values); void setData(const QString &source, float value, - const float extremum = -1.0); + const float extremum = -1.0f); // different signature for battery device void setData(const bool dontInvert, const QString &source, float value); // variables diff --git a/sources/awesome-widget/plugin/awdataengineaggregator.cpp b/sources/awesome-widget/plugin/awdataengineaggregator.cpp index 7ff6642..a8b7d96 100644 --- a/sources/awesome-widget/plugin/awdataengineaggregator.cpp +++ b/sources/awesome-widget/plugin/awdataengineaggregator.cpp @@ -21,14 +21,10 @@ #include "awkeys.h" -AWDataEngineAggregator::AWDataEngineAggregator(QObject *parent, - const int interval) +AWDataEngineAggregator::AWDataEngineAggregator(QObject *parent) : QObject(parent) { qCDebug(LOG_AW) << __PRETTY_FUNCTION__; - - setInterval(interval); - initDataEngines(); } @@ -36,10 +32,17 @@ AWDataEngineAggregator::~AWDataEngineAggregator() { qCDebug(LOG_AW) << __PRETTY_FUNCTION__; + clear(); +} + + +void AWDataEngineAggregator::clear() +{ // disconnect sources first disconnectSources(); m_dataEngines.clear(); delete m_consumer; + m_consumer = nullptr; } @@ -51,11 +54,27 @@ void AWDataEngineAggregator::disconnectSources() } -void AWDataEngineAggregator::setInterval(const int _interval) +void AWDataEngineAggregator::initDataEngines(const int interval) { - qCDebug(LOG_AW) << "Interval" << _interval; + qCDebug(LOG_AW) << "Init dataengines with interval" << interval; - m_interval = _interval; + m_consumer = new Plasma::DataEngineConsumer(); + m_dataEngines[QString("systemmonitor")] + = m_consumer->dataEngine(QString("systemmonitor")); + m_dataEngines[QString("extsysmon")] + = m_consumer->dataEngine(QString("extsysmon")); + m_dataEngines[QString("time")] = m_consumer->dataEngine(QString("time")); + + // additional method required by systemmonitor structure + connect(m_dataEngines[QString("systemmonitor")], + &Plasma::DataEngine::sourceAdded, + [this, interval](const QString source) { + emit(deviceAdded(source)); + m_dataEngines[QString("systemmonitor")]->connectSource( + source, parent(), interval); + }); + + return reconnectSources(interval); } @@ -67,34 +86,17 @@ void AWDataEngineAggregator::dropSource(const QString source) // connected we will try to disconnect it from systemmonitor and extsysmon m_dataEngines[QString("systemmonitor")]->disconnectSource(source, parent()); m_dataEngines[QString("extsysmon")]->disconnectSource(source, parent()); + m_dataEngines[QString("time")]->disconnectSource(source, parent()); } -void AWDataEngineAggregator::reconnectSources() +void AWDataEngineAggregator::reconnectSources(const int interval) { + qCDebug(LOG_AW) << "Reconnect sources with interval" << interval; + m_dataEngines[QString("systemmonitor")]->connectAllSources(parent(), - m_interval); - m_dataEngines[QString("extsysmon")]->connectAllSources(parent(), - m_interval); + interval); + m_dataEngines[QString("extsysmon")]->connectAllSources(parent(), interval); m_dataEngines[QString("time")]->connectSource(QString("Local"), parent(), 1000); } - - -void AWDataEngineAggregator::initDataEngines() -{ - m_consumer = new Plasma::DataEngineConsumer(); - m_dataEngines[QString("systemmonitor")] - = m_consumer->dataEngine(QString("systemmonitor")); - m_dataEngines[QString("extsysmon")] - = m_consumer->dataEngine(QString("extsysmon")); - m_dataEngines[QString("time")] = m_consumer->dataEngine(QString("time")); - - // additional method required by systemmonitor structure - connect(m_dataEngines[QString("systemmonitor")], - &Plasma::DataEngine::sourceAdded, [this](const QString source) { - emit(deviceAdded(source)); - m_dataEngines[QString("systemmonitor")]->connectSource( - source, parent(), m_interval); - }); -} diff --git a/sources/awesome-widget/plugin/awdataengineaggregator.h b/sources/awesome-widget/plugin/awdataengineaggregator.h index 229fce1..11afab3 100644 --- a/sources/awesome-widget/plugin/awdataengineaggregator.h +++ b/sources/awesome-widget/plugin/awdataengineaggregator.h @@ -28,28 +28,24 @@ class AWDataEngineAggregator : public QObject { Q_OBJECT - Q_PROPERTY(int interval MEMBER m_interval WRITE setInterval); public: - explicit AWDataEngineAggregator(QObject *parent = nullptr, - const int interval = 1000); + explicit AWDataEngineAggregator(QObject *parent = nullptr); virtual ~AWDataEngineAggregator(); + void clear(); void disconnectSources(); - // properties - void setInterval(const int _interval); + void initDataEngines(const int interval); signals: void deviceAdded(const QString &source); public slots: void dropSource(const QString source); - void reconnectSources(); + void reconnectSources(const int interval); private: - void initDataEngines(); Plasma::DataEngineConsumer *m_consumer = nullptr; QHash m_dataEngines; - int m_interval; }; diff --git a/sources/awesome-widget/plugin/awkeycache.cpp b/sources/awesome-widget/plugin/awkeycache.cpp index 4002f7d..cf2347b 100644 --- a/sources/awesome-widget/plugin/awkeycache.cpp +++ b/sources/awesome-widget/plugin/awkeycache.cpp @@ -81,6 +81,89 @@ bool AWKeyCache::addKeyToCache(const QString type, const QString key) } +QStringList AWKeyCache::getRequiredKeys(const QStringList &keys, + const QStringList &bars, + const QVariantMap &tooltip, + const QStringList &allKeys) +{ + qCDebug(LOG_AW) << "Looking for required keys in" << keys << bars + << "using tooltip settings" << tooltip; + + // initial copy + QSet used = QSet::fromList(keys); + used.unite(QSet::fromList(bars)); + // insert keys from tooltip + for (auto key : tooltip.keys()) { + if ((key.endsWith(QString("Tooltip"))) && (tooltip[key].toBool())) { + key.remove(QString("Tooltip")); + used << key; + } + } + + // insert depending keys, refer to AWKeys::calculateValues() + // hddtotmb* + for (auto key : allKeys.filter(QRegExp(QString("^hddtotmb")))) { + if (!used.contains(key)) + continue; + key.remove(QString("hddtotmb")); + int index = key.toInt(); + used << QString("hddfreemb%1").arg(index) + << QString("hddmb%1").arg(index); + } + // hddtotgb* + for (auto key : allKeys.filter(QRegExp(QString("^hddtotgb")))) { + if (!used.contains(key)) + continue; + key.remove(QString("hddtotgb")); + int index = key.toInt(); + used << QString("hddfreegb%1").arg(index) + << QString("hddgb%1").arg(index); + } + // mem + if (used.contains(QString("mem"))) + used << QString("memmb") << QString("memtotmb"); + // memtotmb + if (used.contains(QString("memtotmb"))) + used << QString("memusedmb") << QString("memfreemb"); + // memtotgb + if (used.contains(QString("memtotgb"))) + used << QString("memusedgb") << QString("memfreegb"); + // swap + if (used.contains(QString("swap"))) + used << QString("swapmb") << QString("swaptotmb"); + // swaptotmb + if (used.contains(QString("swaptotmb"))) + used << QString("swapmb") << QString("swapfreemb"); + // memtotgb + if (used.contains(QString("swaptotgb"))) + used << QString("swapgb") << QString("swapfreegb"); + // network keys + QStringList netKeys(QStringList() << QString("up") << QString("upkb") + << QString("upunits") << QString("down") + << QString("downkb") + << QString("downunits")); + for (auto key : netKeys) { + if (!used.contains(key)) + continue; + QStringList filt + = allKeys.filter(QRegExp(QString("^%1[0-9]{1,}").arg(key))); + for (auto filtered : filt) + used << filtered; + } + // netdev key + if (std::any_of(netKeys.cbegin(), netKeys.cend(), + [&used](const QString &key) { return used.contains(key); })) + used << QString("netdev"); + + // HACK append dummy if there are no other keys. This hack is required + // because empty list leads to the same behaviour as skip checking + if (used.isEmpty()) + used << QString("dummy"); + + return used.toList(); +} + + QHash AWKeyCache::loadKeysFromCache() { QString fileName = QString("%1/awesomewidgets.ndx") diff --git a/sources/awesome-widget/plugin/awkeycache.h b/sources/awesome-widget/plugin/awkeycache.h index 806e61d..9685122 100644 --- a/sources/awesome-widget/plugin/awkeycache.h +++ b/sources/awesome-widget/plugin/awkeycache.h @@ -21,11 +21,15 @@ #include #include +#include namespace AWKeyCache { bool addKeyToCache(const QString type, const QString key = QString("")); +QStringList getRequiredKeys(const QStringList &keys, const QStringList &bars, + const QVariantMap &tooltip, + const QStringList &allKeys); QHash loadKeysFromCache(); }; diff --git a/sources/awesome-widget/plugin/awkeyoperations.cpp b/sources/awesome-widget/plugin/awkeyoperations.cpp index 135d6f2..e9e0d4c 100644 --- a/sources/awesome-widget/plugin/awkeyoperations.cpp +++ b/sources/awesome-widget/plugin/awkeyoperations.cpp @@ -94,47 +94,14 @@ QStringList AWKeyOperations::dictKeys() const allKeys.append( extWeather->activeItems().at(i)->tag(QString("timestamp"))); } - // time - allKeys.append(QString("time")); - allKeys.append(QString("isotime")); - allKeys.append(QString("shorttime")); - allKeys.append(QString("longtime")); - allKeys.append(QString("ctime")); - // uptime - allKeys.append(QString("uptime")); - allKeys.append(QString("cuptime")); // cpuclock & cpu for (int i = QThread::idealThreadCount() - 1; i >= 0; i--) { allKeys.append(QString("cpucl%1").arg(i)); allKeys.append(QString("cpu%1").arg(i)); } - allKeys.append(QString("cpucl")); - allKeys.append(QString("cpu")); // temperature for (int i = m_devices[QString("temp")].count() - 1; i >= 0; i--) allKeys.append(QString("temp%1").arg(i)); - // gputemp - allKeys.append(QString("gputemp")); - // gpu - allKeys.append(QString("gpu")); - // memory - allKeys.append(QString("memmb")); - allKeys.append(QString("memgb")); - allKeys.append(QString("memfreemb")); - allKeys.append(QString("memfreegb")); - allKeys.append(QString("memtotmb")); - allKeys.append(QString("memtotgb")); - allKeys.append(QString("memusedmb")); - allKeys.append(QString("memusedgb")); - allKeys.append(QString("mem")); - // swap - allKeys.append(QString("swapmb")); - allKeys.append(QString("swapgb")); - allKeys.append(QString("swapfreemb")); - allKeys.append(QString("swapfreegb")); - allKeys.append(QString("swaptotmb")); - allKeys.append(QString("swaptotgb")); - allKeys.append(QString("swap")); // hdd for (int i = m_devices[QString("mount")].count() - 1; i >= 0; i--) { allKeys.append(QString("hddmb%1").arg(i)); @@ -162,38 +129,13 @@ QStringList AWKeyOperations::dictKeys() const allKeys.append(QString("upkb%1").arg(i)); allKeys.append(QString("up%1").arg(i)); } - allKeys.append(QString("downunits")); - allKeys.append(QString("upunits")); - allKeys.append(QString("downkb")); - allKeys.append(QString("down")); - allKeys.append(QString("upkb")); - allKeys.append(QString("up")); - allKeys.append(QString("netdev")); // battery - allKeys.append(QString("ac")); QStringList allBatteryDevices = QDir(QString("/sys/class/power_supply")) .entryList(QStringList() << QString("BAT*"), QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name); for (int i = allBatteryDevices.count() - 1; i >= 0; i--) allKeys.append(QString("bat%1").arg(i)); - allKeys.append(QString("bat")); - // player - allKeys.append(QString("album")); - allKeys.append(QString("artist")); - allKeys.append(QString("duration")); - allKeys.append(QString("progress")); - allKeys.append(QString("title")); - allKeys.append(QString("dalbum")); - allKeys.append(QString("dartist")); - allKeys.append(QString("dtitle")); - allKeys.append(QString("salbum")); - allKeys.append(QString("sartist")); - allKeys.append(QString("stitle")); - // ps - allKeys.append(QString("pscount")); - allKeys.append(QString("pstotal")); - allKeys.append(QString("ps")); // package manager for (int i = extUpgrade->activeItems().count() - 1; i >= 0; i--) allKeys.append( @@ -217,21 +159,14 @@ QStringList AWKeyOperations::dictKeys() const // custom for (int i = extScripts->activeItems().count() - 1; i >= 0; i--) allKeys.append(extScripts->activeItems().at(i)->tag(QString("custom"))); - // desktop - allKeys.append(QString("desktop")); - allKeys.append(QString("ndesktop")); - allKeys.append(QString("tdesktops")); - // load average - allKeys.append(QString("la15")); - allKeys.append(QString("la5")); - allKeys.append(QString("la1")); // bars - QStringList graphicalItemsKeys; - for (auto item : graphicalItems->items()) - graphicalItemsKeys.append(item->tag()); - graphicalItemsKeys.sort(); - for (int i = graphicalItemsKeys.count() - 1; i >= 0; i--) - allKeys.append(graphicalItemsKeys.at(i)); + for (int i = graphicalItems->activeItems().count() - 1; i >= 0; i--) + allKeys.append( + graphicalItems->activeItems().at(i)->tag(QString("bar"))); + // static keys + QStringList staticKeys = QString(STATIC_KEYS).split(QChar(',')); + std::for_each(staticKeys.cbegin(), staticKeys.cend(), + [&allKeys](const QString &key) { allKeys.append(key); }); return allKeys; } @@ -243,7 +178,7 @@ GraphicalItem *AWKeyOperations::giByKey(const QString key) const { qCDebug(LOG_AW) << "Looking for item" << key; - return graphicalItems->itemByTag(key); + return graphicalItems->itemByTag(key, QString("bar")); } @@ -251,11 +186,10 @@ QString AWKeyOperations::infoByKey(QString key) const { qCDebug(LOG_AW) << "Requested key" << key; - key.remove(QRegExp(QString("^bar[0-9]{1,}"))); - if (key.startsWith(QString("custom"))) - return extScripts->itemByTagNumber( - key.remove(QString("custom")).toInt()) - ->uniq(); + if (key.startsWith(QString("bar"))) + return graphicalItems->itemByTag(key, QString("bar"))->uniq(); + else if (key.startsWith(QString("custom"))) + return extScripts->itemByTag(key, QString("custom"))->uniq(); else if (key.contains(QRegExp(QString("^hdd[rw]")))) return QString("%1").arg(m_devices[QString( "disk")][key.remove(QRegExp(QString("hdd[rw]"))).toInt()]); @@ -273,24 +207,12 @@ QString AWKeyOperations::infoByKey(QString key) const return QString("%1").arg(m_devices[QString( "net")][key.remove(QRegExp(QString("^(down|up)"))).toInt()]); else if (key.startsWith(QString("pkgcount"))) - return extUpgrade->itemByTagNumber( - key.remove(QString("pkgcount")).toInt()) - ->uniq(); + return extUpgrade->itemByTag(key, QString("pkgcount"))->uniq(); else if (key.contains(QRegExp(QString("(^|perc)(ask|bid|price)(chg|)")))) - return extQuotes->itemByTagNumber( - key.remove(QRegExp(QString( - "(^|perc)(ask|bid|price)(chg|)"))) - .toInt()) - ->uniq(); + return extQuotes->itemByTag(key, QString("ask"))->uniq(); else if (key.contains(QRegExp( QString("(weather|weatherId|humidity|pressure|temperature)")))) - return extWeather - ->itemByTagNumber( - key - .remove(QRegExp(QString( - "(weather|weatherId|humidity|pressure|temperature)"))) - .toInt()) - ->uniq(); + return extWeather->itemByTag(key, QString("weather"))->uniq(); else if (key.startsWith(QString("temp"))) return QString("%1").arg( m_devices[QString("temp")][key.remove(QString("temp")).toInt()]); diff --git a/sources/awesome-widget/plugin/awkeys.cpp b/sources/awesome-widget/plugin/awkeys.cpp index 23ccd90..71b4e6e 100644 --- a/sources/awesome-widget/plugin/awkeys.cpp +++ b/sources/awesome-widget/plugin/awkeys.cpp @@ -25,6 +25,7 @@ #include "awdataaggregator.h" #include "awdataengineaggregator.h" #include "awdebug.h" +#include "awkeycache.h" #include "awkeyoperations.h" #include "awkeysaggregator.h" #include "awpatternfunctions.h" @@ -45,7 +46,9 @@ AWKeys::AWKeys(QObject *parent) aggregator = new AWKeysAggregator(this); dataAggregator = new AWDataAggregator(this); + dataEngineAggregator = new AWDataEngineAggregator(this); keyOperator = new AWKeyOperations(this); + // update key data if required connect(keyOperator, SIGNAL(updateKeys(QStringList)), this, SLOT(reinitKeys(QStringList))); @@ -53,6 +56,11 @@ AWKeys::AWKeys(QObject *parent) connect(dataAggregator, SIGNAL(toolTipPainted(const QString)), this, SIGNAL(needToolTipToBeUpdated(const QString))); connect(this, SIGNAL(needToBeUpdated()), this, SLOT(updateTextData())); + connect(this, SIGNAL(dropSourceFromDataengine(QString)), + dataEngineAggregator, SLOT(dropSource(QString))); + // transfer signal from dataengine to update source list + connect(dataEngineAggregator, SIGNAL(deviceAdded(const QString &)), + keyOperator, SLOT(addDevice(const QString &))); } @@ -73,32 +81,29 @@ void AWKeys::initDataAggregator(const QVariantMap tooltipParams) { qCDebug(LOG_AW) << "Tooltip parameters" << tooltipParams; - dataAggregator->setParameters(tooltipParams); + // store parameters to generate m_requiredKeys + m_tooltipParams = tooltipParams; + dataAggregator->setParameters(m_tooltipParams); } void AWKeys::initKeys(const QString currentPattern, const int interval, - const int limit) + const int limit, const bool optimize) { qCDebug(LOG_AW) << "Pattern" << currentPattern << "with interval" - << interval << "and queue limit" << limit; + << interval << "and queue limit" << limit + << "with optimization" << optimize; // init - keyOperator->setPattern(currentPattern); - if (dataEngineAggregator == nullptr) { - dataEngineAggregator = new AWDataEngineAggregator(this, interval); - connect(this, SIGNAL(dropSourceFromDataengine(QString)), - dataEngineAggregator, SLOT(dropSource(QString))); - // transfer signal from dataengine to update source list - connect(dataEngineAggregator, SIGNAL(deviceAdded(const QString &)), - keyOperator, SLOT(addDevice(const QString &))); - } else - dataEngineAggregator->setInterval(interval); + m_optimize = optimize; m_threadPool->setMaxThreadCount(limit == 0 ? QThread::idealThreadCount() : limit); + // child objects + keyOperator->setPattern(currentPattern); keyOperator->updateCache(); + dataEngineAggregator->clear(); - return dataEngineAggregator->reconnectSources(); + return dataEngineAggregator->initDataEngines(interval); } @@ -162,8 +167,8 @@ QString AWKeys::valueByKey(QString key) const { qCDebug(LOG_AW) << "Requested value for key" << key; - return values.value(key.remove(QRegExp(QString("^bar[0-9]{1,}"))), - QString("")); + key.remove(QRegExp(QString("^bar[0-9]{1,}"))); + return aggregator->formater(values[key], key); } @@ -200,6 +205,22 @@ void AWKeys::reinitKeys(const QStringList currentKeys) m_foundKeys = AWPatternFunctions::findKeys(keyOperator->pattern(), currentKeys); m_foundLambdas = AWPatternFunctions::findLambdas(keyOperator->pattern()); + // generate list of required keys for bars + QStringList barKeys; + for (auto bar : m_foundBars) { + GraphicalItem *item = keyOperator->giByKey(bar); + if (item->isCustom()) + item->setUsedKeys( + AWPatternFunctions::findKeys(item->bar(), currentKeys)); + else + item->setUsedKeys(QStringList() << item->bar()); + barKeys.append(item->usedKeys()); + } + // get required keys + m_requiredKeys + = m_optimize ? AWKeyCache::getRequiredKeys(m_foundKeys, barKeys, + m_tooltipParams, currentKeys) + : QStringList(); // set key data to aggregator aggregator->setDevices(keyOperator->devices()); @@ -208,10 +229,9 @@ void AWKeys::reinitKeys(const QStringList currentKeys) void AWKeys::updateTextData() { - QFuture text = QtConcurrent::run(m_threadPool, [this]() { - calculateValues(); - return parsePattern(keyOperator->pattern()); - }); + // do not do it in parallel to avoid race condition + calculateValues(); + QString text = parsePattern(keyOperator->pattern()); emit(needTextToBeUpdated(text)); emit(dataAggregator->updateData(values)); @@ -226,34 +246,26 @@ void AWKeys::calculateValues() QStringList mountDevices = keyOperator->devices(QString("mount")); for (auto device : mountDevices) { int index = mountDevices.indexOf(device); - values[QString("hddtotmb%1").arg(index)] = QString("%1").arg( - values[QString("hddfreemb%1").arg(index)].toFloat() - + values[QString("hddmb%1").arg(index)].toFloat(), - 5, 'f', 0); - values[QString("hddtotgb%1").arg(index)] = QString("%1").arg( - values[QString("hddfreegb%1").arg(index)].toFloat() - + values[QString("hddgb%1").arg(index)].toFloat(), - 5, 'f', 1); + values[QString("hddtotmb%1").arg(index)] + = values[QString("hddfreemb%1").arg(index)].toFloat() + + values[QString("hddmb%1").arg(index)].toFloat(); + values[QString("hddtotgb%1").arg(index)] + = values[QString("hddfreegb%1").arg(index)].toFloat() + + values[QString("hddgb%1").arg(index)].toFloat(); } // memtot* - values[QString("memtotmb")] - = QString("%1").arg(values[QString("memusedmb")].toInt() - + values[QString("memfreemb")].toInt(), - 5); - values[QString("memtotgb")] - = QString("%1").arg(values[QString("memusedgb")].toFloat() - + values[QString("memfreegb")].toFloat(), - 5, 'f', 1); + values[QString("memtotmb")] = values[QString("memusedmb")].toInt() + + values[QString("memfreemb")].toInt(); + values[QString("memtotgb")] = values[QString("memusedgb")].toFloat() + + values[QString("memfreegb")].toFloat(); // mem - values[QString("mem")] - = QString("%1").arg(100.0 * values[QString("memmb")].toFloat() - / values[QString("memtotmb")].toFloat(), - 5, 'f', 1); + values[QString("mem")] = 100.0f * values[QString("memmb")].toFloat() + / values[QString("memtotmb")].toFloat(); // up, down, upkb, downkb, upunits, downunits int netIndex = keyOperator->devices(QString("net")) - .indexOf(values[QString("netdev")]); + .indexOf(values[QString("netdev")].toString()); values[QString("down")] = values[QString("down%1").arg(netIndex)]; values[QString("downkb")] = values[QString("downkb%1").arg(netIndex)]; values[QString("downunits")] = values[QString("downunits%1").arg(netIndex)]; @@ -262,39 +274,18 @@ void AWKeys::calculateValues() values[QString("upunits")] = values[QString("upunits%1").arg(netIndex)]; // swaptot* - values[QString("swaptotmb")] - = QString("%1").arg(values[QString("swapmb")].toInt() - + values[QString("swapfreemb")].toInt(), - 5); - values[QString("swaptotgb")] - = QString("%1").arg(values[QString("swapgb")].toFloat() - + values[QString("swapfreegb")].toFloat(), - 5, 'f', 1); + values[QString("swaptotmb")] = values[QString("swapmb")].toInt() + + values[QString("swapfreemb")].toInt(); + values[QString("swaptotgb")] = values[QString("swapgb")].toFloat() + + values[QString("swapfreegb")].toFloat(); // swap - values[QString("swap")] - = QString("%1").arg(100.0 * values[QString("swapmb")].toFloat() - / values[QString("swaptotmb")].toFloat(), - 5, 'f', 1); + values[QString("swap")] = 100.0f * values[QString("swapmb")].toFloat() + / values[QString("swaptotmb")].toFloat(); // lambdas for (auto key : m_foundLambdas) - values[key] = [this](QString key) { - QJSEngine engine; - // apply $this values - key.replace(QString("$this"), values[key]); - for (auto lambdaKey : m_foundKeys) - key.replace(QString("$%1").arg(lambdaKey), values[lambdaKey]); - qCInfo(LOG_AW) << "Expression" << key; - QJSValue result = engine.evaluate(key); - if (result.isError()) { - qCWarning(LOG_AW) << "Uncaught exception at line" - << result.property("lineNumber").toInt() - << ":" << result.toString(); - return QString(); - } else { - return result.toString(); - } - }(key); + values[key] = AWPatternFunctions::expandLambdas(key, aggregator, values, + m_foundKeys); } @@ -305,30 +296,30 @@ QString AWKeys::parsePattern(QString pattern) const // lambdas for (auto key : m_foundLambdas) - pattern.replace(QString("${{%1}}").arg(key), values[key]); + pattern.replace(QString("${{%1}}").arg(key), values[key].toString()); // main keys for (auto key : m_foundKeys) - pattern.replace(QString("$%1").arg(key), - [](QString key, QString value) { - if ((!key.startsWith(QString("custom"))) - && (!key.startsWith(QString("weather")))) - value.replace(QString(" "), QString(" ")); - return value; - }(key, values[key])); + pattern.replace(QString("$%1").arg(key), [this](const QString &tag, + const QVariant &value) { + QString strValue = aggregator->formater(value, tag); + if ((!tag.startsWith(QString("custom"))) + && (!tag.startsWith(QString("weather")))) + strValue.replace(QString(" "), QString(" ")); + return strValue; + }(key, values[key])); // bars for (auto bar : m_foundBars) { GraphicalItem *item = keyOperator->giByKey(bar); - QString key = bar; - key.remove(QRegExp(QString("^bar[0-9]{1,}"))); - if (item->type() == GraphicalItem::Graph) - pattern.replace(QString("$%1").arg(bar), - item->image([](const QList data) { - return QVariant::fromValue>(data); - }(dataAggregator->getData(key)))); + if (item->isCustom()) + pattern.replace( + QString("$%1").arg(bar), + item->image(AWPatternFunctions::expandLambdas( + item->bar(), aggregator, values, item->usedKeys()))); else - pattern.replace(QString("$%1").arg(bar), item->image(values[key])); + pattern.replace(QString("$%1").arg(bar), + item->image(values[item->bar()])); } // prepare strings @@ -347,8 +338,8 @@ void AWKeys::setDataBySource(const QString &sourceName, const QVariantMap &data) // first list init QStringList tags = aggregator->keysFromSource(sourceName); if (tags.isEmpty()) - tags = aggregator->registerSource(sourceName, - data[QString("units")].toString()); + tags = aggregator->registerSource( + sourceName, data[QString("units")].toString(), m_requiredKeys); // update data or drop source if there are no matches and exit if (tags.isEmpty()) { @@ -358,10 +349,11 @@ void AWKeys::setDataBySource(const QString &sourceName, const QVariantMap &data) m_mutex.lock(); // HACK workaround for time values which are stored in the different path - QVariant value = sourceName == QString("Local") ? data[QString("DateTime")] - : data[QString("value")]; - std::for_each(tags.cbegin(), tags.cend(), [this, value](const QString tag) { - values[tag] = aggregator->formater(value, tag); - }); + std::for_each(tags.cbegin(), tags.cend(), + [this, &data, &sourceName](const QString &tag) { + values[tag] = sourceName == QString("Local") + ? data[QString("DateTime")] + : data[QString("value")]; + }); m_mutex.unlock(); } diff --git a/sources/awesome-widget/plugin/awkeys.h b/sources/awesome-widget/plugin/awkeys.h index c3c0ff9..ace101f 100644 --- a/sources/awesome-widget/plugin/awkeys.h +++ b/sources/awesome-widget/plugin/awkeys.h @@ -40,7 +40,7 @@ public: virtual ~AWKeys(); Q_INVOKABLE void initDataAggregator(const QVariantMap tooltipParams); Q_INVOKABLE void initKeys(const QString currentPattern, const int interval, - const int limit); + const int limit, const bool optimize); Q_INVOKABLE void setAggregatorProperty(const QString key, const QVariant value); Q_INVOKABLE void setWrapNewLines(const bool wrap = false); @@ -84,8 +84,10 @@ private: AWKeysAggregator *aggregator = nullptr; AWKeyOperations *keyOperator = nullptr; // variables - QStringList m_foundBars, m_foundKeys, m_foundLambdas; - QHash values; + QVariantMap m_tooltipParams; + QStringList m_foundBars, m_foundKeys, m_foundLambdas, m_requiredKeys; + QVariantHash values; + bool m_optimize = false; bool m_wrapNewLines = false; // multithread features QThreadPool *m_threadPool = nullptr; diff --git a/sources/awesome-widget/plugin/awkeysaggregator.cpp b/sources/awesome-widget/plugin/awkeysaggregator.cpp index f846b72..7a1887b 100644 --- a/sources/awesome-widget/plugin/awkeysaggregator.cpp +++ b/sources/awesome-widget/plugin/awkeysaggregator.cpp @@ -30,6 +30,23 @@ AWKeysAggregator::AWKeysAggregator(QObject *parent) : QObject(parent) { qCDebug(LOG_AW) << __PRETTY_FUNCTION__; + + // default formaters + // memory + m_formater[QString("mem")] = Float; + m_formater[QString("memtotmb")] = IntegerFive; + m_formater[QString("memtotgb")] = Float; + // network + m_formater[QString("down")] = NetSmartFormat; + m_formater[QString("downkb")] = Integer; + m_formater[QString("downunits")] = NetSmartUnits; + m_formater[QString("up")] = NetSmartFormat; + m_formater[QString("upkb")] = Integer; + m_formater[QString("upunits")] = NetSmartUnits; + // swap + m_formater[QString("swap")] = Float; + m_formater[QString("swaptotmb")] = IntegerFive; + m_formater[QString("swaptotgb")] = Float; } @@ -57,6 +74,9 @@ QString AWKeysAggregator::formater(const QVariant &data, case Integer: output = QString("%1").arg(data.toFloat(), 4, 'f', 0); break; + case IntegerFive: + output = QString("%1").arg(data.toFloat(), 5, 'f', 0); + break; case IntegerThree: output = QString("%1").arg(data.toFloat(), 3, 'f', 0); break; @@ -137,9 +157,11 @@ QString AWKeysAggregator::formater(const QVariant &data, static_cast(data.toFloat())); break; case NoFormat: - default: output = data.toString(); break; + default: + output = QString(); + break; } return output; @@ -154,15 +176,6 @@ QStringList AWKeysAggregator::keysFromSource(const QString &source) const } -QStringList -AWKeysAggregator::requiredByKeysFromSource(const QString &source) const -{ - qCDebug(LOG_AW) << "Search for source" << source; - - return m_requiredByMap.values(source); -} - - void AWKeysAggregator::setAcOffline(const QString inactive) { qCDebug(LOG_AW) << "Inactive AC string" << inactive; @@ -222,7 +235,8 @@ void AWKeysAggregator::setTranslate(const bool translate) // HACK units required to define should the value be calculated as temperature // or fan data QStringList AWKeysAggregator::registerSource(const QString &source, - const QString &units) + const QString &units, + const QStringList &keys) { qCDebug(LOG_AW) << "Source" << source << "with units" << units; @@ -323,6 +337,9 @@ QStringList AWKeysAggregator::registerSource(const QString &source, QString key = QString("hdd%1").arg(index); m_map[source] = key; m_formater[key] = Float; + // additional keys + m_formater[QString("hddtotmb%1").arg(index)] = IntegerFive; + m_formater[QString("hddtotgb%1").arg(index)] = Float; } } else if (source.contains(mountFreeRegExp)) { // free space @@ -338,11 +355,6 @@ QStringList AWKeysAggregator::registerSource(const QString &source, key = QString("hddfreegb%1").arg(index); m_map.insertMulti(source, key); m_formater[key] = MemGBFormat; - // fill required by list - m_requiredByMap.insertMulti(source, - QString("hddtotmb%1").arg(index)); - m_requiredByMap.insertMulti(source, - QString("hddtotgb%1").arg(index)); } } else if (source.contains(mountUsedRegExp)) { // used @@ -358,11 +370,6 @@ QStringList AWKeysAggregator::registerSource(const QString &source, key = QString("hddgb%1").arg(index); m_map.insertMulti(source, key); m_formater[key] = MemGBFormat; - // fill required by list - m_requiredByMap.insertMulti(source, - QString("hddtotmb%1").arg(index)); - m_requiredByMap.insertMulti(source, - QString("hddtotgb%1").arg(index)); } } else if (source.startsWith(QString("hdd/temperature"))) { // hdd temperature @@ -389,8 +396,6 @@ QStringList AWKeysAggregator::registerSource(const QString &source, // gb m_map.insertMulti(source, QString("memgb")); m_formater[QString("memgb")] = MemGBFormat; - // fill required by list - m_requiredByMap.insertMulti(source, QString("mem")); } else if (source == QString("mem/physical/free")) { // free memory // mb @@ -399,10 +404,6 @@ QStringList AWKeysAggregator::registerSource(const QString &source, // gb m_map.insertMulti(source, QString("memfreegb")); m_formater[QString("memfreegb")] = MemGBFormat; - // fill required by list - m_requiredByMap.insertMulti(source, QString("memtotmb")); - m_requiredByMap.insertMulti(source, QString("memtotgb")); - m_requiredByMap.insertMulti(source, QString("mem")); } else if (source == QString("mem/physical/used")) { // used memory // mb @@ -411,21 +412,10 @@ QStringList AWKeysAggregator::registerSource(const QString &source, // gb m_map.insertMulti(source, QString("memusedgb")); m_formater[QString("memusedgb")] = MemGBFormat; - // fill required by list - m_requiredByMap.insertMulti(source, QString("memtotmb")); - m_requiredByMap.insertMulti(source, QString("memtotgb")); - m_requiredByMap.insertMulti(source, QString("mem")); } else if (source == QString("network/current/name")) { // network device m_map[source] = QString("netdev"); m_formater[QString("netdev")] = NoFormat; - // fill required by list - m_requiredByMap.insertMulti(source, QString("down")); - m_requiredByMap.insertMulti(source, QString("downkb")); - m_requiredByMap.insertMulti(source, QString("downunits")); - m_requiredByMap.insertMulti(source, QString("up")); - m_requiredByMap.insertMulti(source, QString("upkb")); - m_requiredByMap.insertMulti(source, QString("upunits")); } else if (source.contains(netRegExp)) { // network speed QString type = source.contains(QString("receiver")) ? QString("down") @@ -446,13 +436,6 @@ QStringList AWKeysAggregator::registerSource(const QString &source, m_map.insertMulti(source, key); m_formater[key] = NetSmartUnits; } - // fill required by list - m_requiredByMap.insertMulti(source, QString("%1").arg(type)); - m_requiredByMap.insertMulti(source, QString("%1kb").arg(type)); - m_requiredByMap.insertMulti(source, QString("%1units").arg(type)); - m_requiredByMap.insertMulti(source, QString("%1").arg(type)); - m_requiredByMap.insertMulti(source, QString("%1kb").arg(type)); - m_requiredByMap.insertMulti(source, QString("%1units").arg(type)); } else if (source.startsWith(QString("upgrade"))) { // package manager QString key = source; @@ -491,10 +474,6 @@ QStringList AWKeysAggregator::registerSource(const QString &source, // gb m_map.insertMulti(source, QString("swapfreegb")); m_formater[QString("swapfreegb")] = MemGBFormat; - // fill required by list - m_requiredByMap.insertMulti(source, QString("swaptotmb")); - m_requiredByMap.insertMulti(source, QString("swaptotgb")); - m_requiredByMap.insertMulti(source, QString("swap")); } else if (source == QString("mem/swap/used")) { // used swap // mb @@ -503,10 +482,6 @@ QStringList AWKeysAggregator::registerSource(const QString &source, // gb m_map.insertMulti(source, QString("swapgb")); m_formater[QString("swapgb")] = MemGBFormat; - // fill required by list - m_requiredByMap.insertMulti(source, QString("swaptotmb")); - m_requiredByMap.insertMulti(source, QString("swaptotgb")); - m_requiredByMap.insertMulti(source, QString("swap")); } else if (source.startsWith(QString("lmsensors/"))) { // temperature int index = m_devices[QString("temp")].indexOf(source); @@ -561,6 +536,19 @@ QStringList AWKeysAggregator::registerSource(const QString &source, m_formater[key] = Temperature; } + // drop key from dictionary if no one user requested key required it + QStringList foundKeys = keysFromSource(source); + qCInfo(LOG_AW) << "Looking for keys" << foundKeys << "in" << keys; + // this source is required if list is empty (which means skip checking) + // or if key in required key list + bool required + = keys.isEmpty() || std::any_of(foundKeys.cbegin(), foundKeys.cend(), + [&keys](const QString &key) { + return keys.contains(key); + }); + if (!required) + m_map.remove(source); + return keysFromSource(source); } @@ -572,17 +560,17 @@ float AWKeysAggregator::temperature(const float temp) const float converted = temp; if (m_tempUnits == QString("Celsius")) { } else if (m_tempUnits == QString("Fahrenheit")) { - converted = temp * 9.0 / 5.0 + 32.0; + converted = temp * 9.0f / 5.0f + 32.0f; } else if (m_tempUnits == QString("Kelvin")) { - converted = temp + 273.15; + converted = temp + 273.15f; } else if (m_tempUnits == QString("Reaumur")) { - converted = temp * 0.8; + converted = temp * 0.8f; } else if (m_tempUnits == QString("cm^-1")) { - converted = (temp + 273.15) * 0.695; + converted = (temp + 273.15f) * 0.695f; } else if (m_tempUnits == QString("kJ/mol")) { - converted = (temp + 273.15) * 8.31; + converted = (temp + 273.15f) * 8.31f; } else if (m_tempUnits == QString("kcal/mol")) { - converted = (temp + 273.15) * 1.98; + converted = (temp + 273.15f) * 1.98f; } else { qCWarning(LOG_AW) << "Invalid units" << m_tempUnits; } diff --git a/sources/awesome-widget/plugin/awkeysaggregator.h b/sources/awesome-widget/plugin/awkeysaggregator.h index 37bfc77..1e2ef6c 100644 --- a/sources/awesome-widget/plugin/awkeysaggregator.h +++ b/sources/awesome-widget/plugin/awkeysaggregator.h @@ -42,6 +42,7 @@ class AWKeysAggregator : public QObject Float, FloatTwoSymbols, Integer, + IntegerFive, IntegerThree, List, // unit specific formaters @@ -67,7 +68,6 @@ public: // get methods QString formater(const QVariant &data, const QString &key) const; QStringList keysFromSource(const QString &source) const; - QStringList requiredByKeysFromSource(const QString &source) const; // set methods void setAcOffline(const QString inactive); void setAcOnline(const QString active); @@ -78,7 +78,8 @@ public: void setTranslate(const bool translate); public slots: - QStringList registerSource(const QString &source, const QString &units); + QStringList registerSource(const QString &source, const QString &units, + const QStringList &keys); private: float temperature(const float temp) const; @@ -91,7 +92,6 @@ private: QHash m_devices; QHash m_formater; QHash m_map; - QHash m_requiredByMap; QString m_tempUnits; bool m_translate = false; }; diff --git a/sources/awesome-widget/plugin/awpatternfunctions.cpp b/sources/awesome-widget/plugin/awpatternfunctions.cpp index 60e9b30..a1843ec 100644 --- a/sources/awesome-widget/plugin/awpatternfunctions.cpp +++ b/sources/awesome-widget/plugin/awpatternfunctions.cpp @@ -21,6 +21,69 @@ #include #include "awdebug.h" +#include "awkeysaggregator.h" + + +QString AWPatternFunctions::expandLambdas(QString code, + AWKeysAggregator *aggregator, + const QVariantHash &metadata, + const QStringList &usedKeys) +{ + qCDebug(LOG_AW) << "Expand lamdas in" << code; + + QJSEngine engine; + // apply $this values + code.replace(QString("$this"), metadata[code].toString()); + // parsed values + for (auto lambdaKey : usedKeys) + code.replace(QString("$%1").arg(lambdaKey), + aggregator->formater(metadata[lambdaKey], lambdaKey)); + qCInfo(LOG_AW) << "Expression" << code; + QJSValue result = engine.evaluate(code); + if (result.isError()) { + qCWarning(LOG_AW) << "Uncaught exception at line" + << result.property("lineNumber").toInt() << ":" + << result.toString(); + return QString(); + } else { + return result.toString(); + } +} + + +QString AWPatternFunctions::expandTemplates(QString code) +{ + qCDebug(LOG_AW) << "Expand templates in" << code; + + // match the following construction $template{{some code here}} + QRegularExpression templatesRegexp( + QString("\\$template\\{\\{(?.*?)\\}\\}")); + templatesRegexp.setPatternOptions( + QRegularExpression::DotMatchesEverythingOption); + + QRegularExpressionMatchIterator it = templatesRegexp.globalMatch(code); + while (it.hasNext()) { + QRegularExpressionMatch match = it.next(); + QString body = match.captured(QString("body")); + + QJSEngine engine; + qCInfo(LOG_AW) << "Expression" << body; + QJSValue result = engine.evaluate(body); + QString templateResult = QString(""); + if (result.isError()) { + qCWarning(LOG_AW) << "Uncaught exception at line" + << result.property("lineNumber").toInt() << ":" + << result.toString(); + } else { + templateResult = result.toString(); + } + + // replace template + code.replace(match.captured(), templateResult); + } + + return code; +} QVariantList AWPatternFunctions::findFunctionCalls(const QString function, @@ -68,41 +131,6 @@ QVariantList AWPatternFunctions::findFunctionCalls(const QString function, } -QString AWPatternFunctions::expandTemplates(QString code) -{ - qCDebug(LOG_AW) << "Expand templates in" << code; - - // match the following construction $template{{some code here}} - QRegularExpression templatesRegexp( - QString("\\$template\\{\\{(?.*?)\\}\\}")); - templatesRegexp.setPatternOptions( - QRegularExpression::DotMatchesEverythingOption); - - QRegularExpressionMatchIterator it = templatesRegexp.globalMatch(code); - while (it.hasNext()) { - QRegularExpressionMatch match = it.next(); - QString body = match.captured(QString("body")); - - QJSEngine engine; - qCInfo(LOG_AW) << "Expression" << body; - QJSValue result = engine.evaluate(body); - QString templateResult = QString(""); - if (result.isError()) { - qCWarning(LOG_AW) << "Uncaught exception at line" - << result.property("lineNumber").toInt() << ":" - << result.toString(); - } else { - templateResult = result.toString(); - } - - // replace template - code.replace(match.captured(), templateResult); - } - - return code; -} - - QString AWPatternFunctions::insertAllKeys(QString code, const QStringList keys) { qCDebug(LOG_AW) << "Looking for keys in code" << code << "using list" diff --git a/sources/awesome-widget/plugin/awpatternfunctions.h b/sources/awesome-widget/plugin/awpatternfunctions.h index d5d362f..1c8cc3c 100644 --- a/sources/awesome-widget/plugin/awpatternfunctions.h +++ b/sources/awesome-widget/plugin/awpatternfunctions.h @@ -23,9 +23,14 @@ #include +class AWKeysAggregator; + namespace AWPatternFunctions { // insert methods +QString expandLambdas(QString code, AWKeysAggregator *aggregator, + const QVariantHash &metadata, + const QStringList &usedKeys); QString expandTemplates(QString code); QVariantList findFunctionCalls(const QString function, const QString code); QString insertAllKeys(QString code, const QStringList keys); diff --git a/sources/awesome-widget/plugin/awupdatehelper.cpp b/sources/awesome-widget/plugin/awupdatehelper.cpp new file mode 100644 index 0000000..3698602 --- /dev/null +++ b/sources/awesome-widget/plugin/awupdatehelper.cpp @@ -0,0 +1,188 @@ +/*************************************************************************** + * 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 "awupdatehelper.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "awdebug.h" +#include "version.h" + + +AWUpdateHelper::AWUpdateHelper(QObject *parent) + : QObject(parent) +{ + qCDebug(LOG_AW) << __PRETTY_FUNCTION__; + + m_foundVersion = QVersionNumber::fromString(VERSION); + m_genericConfig = QString("%1/awesomewidgets/general.ini") + .arg(QStandardPaths::writableLocation( + QStandardPaths::GenericDataLocation)); +} + + +AWUpdateHelper::~AWUpdateHelper() +{ + qCDebug(LOG_AW) << __PRETTY_FUNCTION__; +} + + +void AWUpdateHelper::checkUpdates(const bool showAnyway) +{ + 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(nullptr); + connect(manager, &QNetworkAccessManager::finished, + [showAnyway, this](QNetworkReply *reply) { + return versionReplyRecieved(reply, showAnyway); + }); + + manager->get(QNetworkRequest(QUrl(VERSION_API))); +} + + +bool AWUpdateHelper::checkVersion() +{ + QSettings settings(m_genericConfig, QSettings::IniFormat); + QVersionNumber version = QVersionNumber::fromString( + settings.value(QString("Version"), QString(VERSION)).toString()); + // update version + settings.setValue(QString("Version"), QString(VERSION)); + settings.sync(); + + qCInfo(LOG_AW) << "Found version" << version << "actual one is" << VERSION; + if (version != QVersionNumber::fromString(VERSION)) { + genMessageBox(i18n("Changelog of %1", QString(VERSION)), + QString(CHANGELOG).replace(QChar('@'), QChar('\n')), + QMessageBox::Ok) + ->open(); + return true; + } else { + qCInfo(LOG_AW) << "No need to update version"; + } + + return false; +} + + +void AWUpdateHelper::showInfo(const QVersionNumber version) +{ + qCDebug(LOG_AW) << "Version" << version; + + QString text + = i18n("You are using the actual version %1", version.toString()); + if (!QString(COMMIT_SHA).isEmpty()) + text += QString(" (%1)").arg(QString(COMMIT_SHA)); + return genMessageBox(i18n("No new version found"), text, QMessageBox::Ok) + ->open(); +} + + +void AWUpdateHelper::showUpdates(const QVersionNumber version) +{ + 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.toString()) + QString("\n\n"); + text += i18n("Click \"Ok\" to download"); + + genMessageBox(i18n("There are updates"), text, + QMessageBox::Ok | QMessageBox::Cancel) + ->open(this, SLOT(userReplyOnUpdates(QAbstractButton *))); +} + + +void AWUpdateHelper::userReplyOnUpdates(QAbstractButton *button) +{ + int ret = static_cast(sender())->buttonRole(button); + qCInfo(LOG_AW) << "User select" << ret; + + switch (ret) { + case QMessageBox::Ok: + QDesktopServices::openUrl(QString(RELEASES) + + m_foundVersion.toString()); + break; + case QMessageBox::Cancel: + default: + break; + } +} + + +void AWUpdateHelper::versionReplyRecieved(QNetworkReply *reply, + const bool showAnyway) +{ + qCDebug(LOG_AW) << "Return code" << reply->error() << "with message" + << reply->errorString() << "and show anyway" << showAnyway; + + QJsonParseError error; + QJsonDocument jsonDoc = QJsonDocument::fromJson(reply->readAll(), &error); + if ((reply->error() != QNetworkReply::NoError) + || (error.error != QJsonParseError::NoError)) { + qCWarning(LOG_AW) << "Parse error" << error.errorString(); + return; + } + reply->deleteLater(); + + // convert to map + QVariantMap firstRelease = jsonDoc.toVariant().toList().first().toMap(); + QString version = firstRelease[QString("tag_name")].toString(); + version.remove(QString("V.")); + m_foundVersion = QVersionNumber::fromString(version); + qCInfo(LOG_AW) << "Update found version to" << m_foundVersion; + + QVersionNumber oldVersion = QVersionNumber::fromString(VERSION); + if (oldVersion < m_foundVersion) + return showUpdates(m_foundVersion); + else if (showAnyway) + return showInfo(m_foundVersion); +} + + +// additional method which is used to show message box which does not block UI +QMessageBox * +AWUpdateHelper::genMessageBox(const QString title, const QString body, + const QMessageBox::StandardButtons buttons) +{ + qCDebug(LOG_AW) << "Construct message box with title" << title << "and body" + << body; + + QMessageBox *msgBox = new QMessageBox(nullptr); + msgBox->setAttribute(Qt::WA_DeleteOnClose); + msgBox->setModal(false); + msgBox->setWindowTitle(title); + msgBox->setText(body); + msgBox->setStandardButtons(buttons); + msgBox->setIcon(QMessageBox::Information); + + return msgBox; +} diff --git a/sources/awesome-widget/plugin/awupdatehelper.h b/sources/awesome-widget/plugin/awupdatehelper.h new file mode 100644 index 0000000..359cdb2 --- /dev/null +++ b/sources/awesome-widget/plugin/awupdatehelper.h @@ -0,0 +1,53 @@ +/*************************************************************************** + * 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/ * + ***************************************************************************/ + + +#ifndef AWUPDATEHELPER_H +#define AWUPDATEHELPER_H + +#include +#include +#include + + +class QNetworkReply; + +class AWUpdateHelper : public QObject +{ + Q_OBJECT + +public: + explicit AWUpdateHelper(QObject *parent = nullptr); + virtual ~AWUpdateHelper(); + void checkUpdates(const bool showAnyway = false); + bool checkVersion(); + +private slots: + void showInfo(const QVersionNumber version); + void showUpdates(const QVersionNumber version); + void userReplyOnUpdates(QAbstractButton *button); + void versionReplyRecieved(QNetworkReply *reply, const bool showAnyway); + +private: + QMessageBox *genMessageBox(const QString title, const QString body, + const QMessageBox::StandardButtons buttons); + QVersionNumber m_foundVersion; + QString m_genericConfig; +}; + + +#endif /* AWUPDATEHELPER_H */ diff --git a/sources/awesomewidgets/CMakeLists.txt b/sources/awesomewidgets/CMakeLists.txt index fe9dfc0..f0ff53f 100644 --- a/sources/awesomewidgets/CMakeLists.txt +++ b/sources/awesomewidgets/CMakeLists.txt @@ -13,6 +13,8 @@ include_directories( file(GLOB SUBPROJECT_SOURCE *.cpp ${PROJECT_TRDPARTY_DIR}/qreplytimeout/*.cpp ${CMAKE_SOURCE_DIR}/*.cpp) file(GLOB SUBPROJECT_HEADER *.h ${PROJECT_TRDPARTY_DIR}/qreplytimeout/*.h) file(GLOB SUBPROJECT_UI *.ui) +file(GLOB SUBPROJECT_INI *.ini) +set(SUBPROJECT_CONFIGS ${CMAKE_CURRENT_SOURCE_DIR}/configs) set(SUBPROJECT_GRAPHITEMS ${CMAKE_CURRENT_SOURCE_DIR}/desktops) set(SUBPROJECT_QUOTES ${CMAKE_CURRENT_SOURCE_DIR}/quotes) set(SUBPROJECT_SCRIPTS ${CMAKE_CURRENT_SOURCE_DIR}/scripts) @@ -29,9 +31,11 @@ add_library(${SUBPROJECT} STATIC ${SUBPROJECT_SOURCE} ${SUBPROJECT_HEADER} ${SUB target_link_libraries(${SUBPROJECT} ${Qt_LIBRARIES} ${Kf5_LIBRARIES}) # install +install(DIRECTORY ${SUBPROJECT_CONFIGS} DESTINATION ${DATA_INSTALL_DIR}/${PROJECT_NAME}) install(DIRECTORY ${SUBPROJECT_GRAPHITEMS} DESTINATION ${DATA_INSTALL_DIR}/${PROJECT_NAME}) install(DIRECTORY ${SUBPROJECT_QUOTES} DESTINATION ${DATA_INSTALL_DIR}/${PROJECT_NAME}) install(DIRECTORY ${SUBPROJECT_SCRIPTS} DESTINATION ${DATA_INSTALL_DIR}/${PROJECT_NAME}) install(DIRECTORY ${SUBPROJECT_UPGRADE} DESTINATION ${DATA_INSTALL_DIR}/${PROJECT_NAME}) install(DIRECTORY ${SUBPROJECT_WEATHER} DESTINATION ${DATA_INSTALL_DIR}/${PROJECT_NAME}) +install(FILES ${SUBPROJECT_INI} DESTINATION ${CONFIG_INSTALL_DIR}) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${SUBPROJECT_WEATHER_JSON} DESTINATION ${DATA_INSTALL_DIR}/${PROJECT_NAME}/weather) diff --git a/sources/awesomewidgets/abstractextitem.cpp b/sources/awesomewidgets/abstractextitem.cpp index 6691f10..b66f7ca 100644 --- a/sources/awesomewidgets/abstractextitem.cpp +++ b/sources/awesomewidgets/abstractextitem.cpp @@ -24,6 +24,7 @@ #include "awdebug.h" #include "version.h" +#include "abstractextitemaggregator.h" AbstractExtItem::AbstractExtItem(QWidget *parent, const QString desktopName, @@ -47,10 +48,13 @@ AbstractExtItem::~AbstractExtItem() } -template T *AbstractExtItem::copy(const QString, const int) +void AbstractExtItem::copyDefaults(AbstractExtItem *_other) const { - // an analog of pure virtual method - return new T(); + _other->setActive(m_active); + _other->setApiVersion(m_apiVersion); + _other->setComment(m_comment); + _other->setInterval(m_interval); + _other->setName(m_name); } diff --git a/sources/awesomewidgets/abstractextitem.h b/sources/awesomewidgets/abstractextitem.h index 60d0729..e2ec0b8 100644 --- a/sources/awesomewidgets/abstractextitem.h +++ b/sources/awesomewidgets/abstractextitem.h @@ -40,7 +40,9 @@ public: const QString desktopName = QString(), const QStringList directories = QStringList()); virtual ~AbstractExtItem(); - template T *copy(const QString, const int); + virtual AbstractExtItem *copy(const QString _fileName, const int _number) + = 0; + void copyDefaults(AbstractExtItem *_other) const; // get methods int apiVersion() const; QString comment() const; diff --git a/sources/extsysmon/awesome-widgets-logging.ini b/sources/awesomewidgets/awesome-widgets-logging.ini similarity index 100% rename from sources/extsysmon/awesome-widgets-logging.ini rename to sources/awesomewidgets/awesome-widgets-logging.ini diff --git a/sources/awesomewidgets/configs/aw-example-statusbarrc b/sources/awesomewidgets/configs/aw-example-statusbarrc new file mode 100644 index 0000000..d6b2e33 --- /dev/null +++ b/sources/awesomewidgets/configs/aw-example-statusbarrc @@ -0,0 +1,41 @@ +[plasmoid] +acOffline=( ) +acOnline=(*) +background=true +batInTooltipColor=#880000 +batTooltip=true +batTooltipColor=#008800 +checkUpdates=true +cpuTooltip=true +cpuTooltipColor=#ff0000 +cpuclTooltip=true +cpuclTooltipColor=#00ff00 +customTime=$hh:$mm +customUptime="$dd,$hh,$mm" +downkbTooltip=true +downkbTooltipColor=#00ffff +fontColor=#000000 +fontFamily=Terminus +fontSize=12 +fontStyle=normal +fontWeight=normal +height=0 +interval=1000 +memTooltip=true +memTooltipColor=#0000ff +notify=true +optimize=true +queueLimit=0 +swapTooltip=true +swapTooltipColor=#ffff00 +tempUnits=Celsius +text=[cpu: $cpu%] [mem: $mem%] [swap: $swap%] [$netdev: $down/$upKB/s] +textAlign=center +tooltipBackground=#ffffff +tooltipNumber=100 +translateStrings=true +upkbTooltipColor=#ff00ff +useTooltipBackground=true +width=0 +wrapNewLines=false +wrapText=false diff --git a/sources/awesomewidgets/desktops/aw-bat-bar.desktop b/sources/awesomewidgets/desktops/aw-bat-bar.desktop index 9aa9df0..5dac5d4 100644 --- a/sources/awesomewidgets/desktops/aw-bat-bar.desktop +++ b/sources/awesomewidgets/desktops/aw-bat-bar.desktop @@ -3,11 +3,14 @@ Encoding=UTF-8 Name=bar3 Comment=Simple bat bar X-AW-Value=bat +X-AW-Custom=false +X-AW-Max=100.0 +X-AW-Min=0.0 X-AW-ActiveColor="0,0,0,255" X-AW-InactiveColor="255,255,255,255" X-AW-Type=Horizontal X-AW-Direction=LeftToRight X-AW-Height=25 X-AW-Width=100 -X-AW-ApiVersion=3 +X-AW-ApiVersion=4 X-AW-Number=3 diff --git a/sources/awesomewidgets/desktops/aw-cpu-bar.desktop b/sources/awesomewidgets/desktops/aw-cpu-bar.desktop index 0c328a8..224f58b 100644 --- a/sources/awesomewidgets/desktops/aw-cpu-bar.desktop +++ b/sources/awesomewidgets/desktops/aw-cpu-bar.desktop @@ -3,11 +3,14 @@ Encoding=UTF-8 Name=bar0 Comment=Simple cpu bar X-AW-Value=cpu +X-AW-Custom=false +X-AW-Max=100.0 +X-AW-Min=0.0 X-AW-ActiveColor="0,0,0,255" X-AW-InactiveColor="255,255,255,255" X-AW-Type=Horizontal X-AW-Direction=LeftToRight X-AW-Height=25 X-AW-Width=100 -X-AW-ApiVersion=3 +X-AW-ApiVersion=4 X-AW-Number=0 diff --git a/sources/awesomewidgets/desktops/aw-mem-bar.desktop b/sources/awesomewidgets/desktops/aw-mem-bar.desktop index 4f4f92a..d76fa22 100644 --- a/sources/awesomewidgets/desktops/aw-mem-bar.desktop +++ b/sources/awesomewidgets/desktops/aw-mem-bar.desktop @@ -3,11 +3,14 @@ Encoding=UTF-8 Name=bar1 Comment=Simple mem bar X-AW-Value=mem +X-AW-Custom=false +X-AW-Max=100.0 +X-AW-Min=0.0 X-AW-ActiveColor="0,0,0,255" X-AW-InactiveColor="255,255,255,255" X-AW-Type=Horizontal X-AW-Direction=LeftToRight X-AW-Height=25 X-AW-Width=100 -X-AW-ApiVersion=3 +X-AW-ApiVersion=4 X-AW-Number=1 diff --git a/sources/awesomewidgets/desktops/aw-swap-bar.desktop b/sources/awesomewidgets/desktops/aw-swap-bar.desktop index 95f3b9a..ee957ee 100644 --- a/sources/awesomewidgets/desktops/aw-swap-bar.desktop +++ b/sources/awesomewidgets/desktops/aw-swap-bar.desktop @@ -3,11 +3,14 @@ Encoding=UTF-8 Name=bar2 Comment=Simple swap bar X-AW-Value=swap +X-AW-Custom=false +X-AW-Max=100.0 +X-AW-Min=0.0 X-AW-ActiveColor="0,0,0,255" X-AW-InactiveColor="255,255,255,255" X-AW-Type=Horizontal X-AW-Direction=LeftToRight X-AW-Height=25 X-AW-Width=100 -X-AW-ApiVersion=3 +X-AW-ApiVersion=4 X-AW-Number=2 diff --git a/sources/awesomewidgets/extitemaggregator.h b/sources/awesomewidgets/extitemaggregator.h index 5e0b9ea..df92a16 100644 --- a/sources/awesomewidgets/extitemaggregator.h +++ b/sources/awesomewidgets/extitemaggregator.h @@ -62,13 +62,13 @@ public: qCInfo(LOG_LIB) << "Dialog returns" << ret; }; - T *itemByTag(const QString _tag) const + T *itemByTag(const QString _tag, const QString _type) const { - qCDebug(LOG_LIB) << "Tag" << _tag; + qCDebug(LOG_LIB) << "Tag" << _tag << "with used type" << _type; T *found = nullptr; for (auto item : m_items) { - if (item->tag() != _tag) + if (item->tag(_type) != _tag) continue; found = item; break; @@ -211,7 +211,7 @@ private: return; } - T *newItem = source->copy(fileName, number); + T *newItem = static_cast(source->copy(fileName, number)); if (newItem->showConfiguration(configArgs()) == 1) { initItems(); repaint(); diff --git a/sources/awesomewidgets/extquotes.cpp b/sources/awesomewidgets/extquotes.cpp index 49e9725..cbb4ed5 100644 --- a/sources/awesomewidgets/extquotes.cpp +++ b/sources/awesomewidgets/extquotes.cpp @@ -81,11 +81,7 @@ ExtQuotes *ExtQuotes::copy(const QString _fileName, const int _number) ExtQuotes *item = new ExtQuotes(static_cast(parent()), _fileName, directories()); - item->setActive(isActive()); - item->setApiVersion(apiVersion()); - item->setComment(comment()); - item->setInterval(interval()); - item->setName(name()); + copyDefaults(item); item->setNumber(_number); item->setTicker(ticker()); diff --git a/sources/awesomewidgets/extscript.cpp b/sources/awesomewidgets/extscript.cpp index 6c114a0..90c61d1 100644 --- a/sources/awesomewidgets/extscript.cpp +++ b/sources/awesomewidgets/extscript.cpp @@ -68,12 +68,8 @@ ExtScript *ExtScript::copy(const QString _fileName, const int _number) ExtScript *item = new ExtScript(static_cast(parent()), _fileName, directories()); - item->setActive(isActive()); - item->setApiVersion(apiVersion()); - item->setComment(comment()); + copyDefaults(item); item->setExecutable(executable()); - item->setInterval(interval()); - item->setName(name()); item->setNumber(_number); item->setPrefix(prefix()); item->setRedirect(redirect()); diff --git a/sources/awesomewidgets/extscript.h b/sources/awesomewidgets/extscript.h index 3aa899b..511c032 100644 --- a/sources/awesomewidgets/extscript.h +++ b/sources/awesomewidgets/extscript.h @@ -82,7 +82,6 @@ private: QString m_prefix = QString(""); Redirect m_redirect = nothing; // internal properties - Q_PID childProcess = 0; QVariantMap jsonFilters = QVariantMap(); int times = 0; QVariantHash value; diff --git a/sources/awesomewidgets/extupgrade.cpp b/sources/awesomewidgets/extupgrade.cpp index 2fe6a4f..33d79df 100644 --- a/sources/awesomewidgets/extupgrade.cpp +++ b/sources/awesomewidgets/extupgrade.cpp @@ -64,13 +64,9 @@ ExtUpgrade *ExtUpgrade::copy(const QString _fileName, const int _number) ExtUpgrade *item = new ExtUpgrade(static_cast(parent()), _fileName, directories()); - item->setActive(isActive()); - item->setApiVersion(apiVersion()); - item->setComment(comment()); + copyDefaults(item); item->setExecutable(executable()); item->setFilter(filter()); - item->setInterval(interval()); - item->setName(name()); item->setNumber(_number); item->setNull(null()); diff --git a/sources/awesomewidgets/extweather.cpp b/sources/awesomewidgets/extweather.cpp index 8e865d5..3333836 100644 --- a/sources/awesomewidgets/extweather.cpp +++ b/sources/awesomewidgets/extweather.cpp @@ -78,14 +78,10 @@ ExtWeather *ExtWeather::copy(const QString _fileName, const int _number) ExtWeather *item = new ExtWeather(static_cast(parent()), _fileName, directories()); - item->setActive(isActive()); - item->setApiVersion(apiVersion()); + copyDefaults(item); item->setCity(city()); - item->setComment(comment()); item->setCountry(country()); - item->setInterval(interval()); item->setImage(image()); - item->setName(name()); item->setNumber(_number); item->setTs(ts()); @@ -303,8 +299,8 @@ void ExtWeather::writeConfiguration() const void ExtWeather::weatherReplyReceived(QNetworkReply *reply) { - qCDebug(LOG_LIB) << "Return code" << reply->error() << "with messa"; - qCDebug(LOG_LIB) << "Reply error message" << reply->errorString(); + qCDebug(LOG_LIB) << "Return code" << reply->error() << "with message" + << reply->errorString(); isRunning = false; QJsonParseError error; diff --git a/sources/awesomewidgets/extweather.h b/sources/awesomewidgets/extweather.h index eafac3e..e0f1863 100644 --- a/sources/awesomewidgets/extweather.h +++ b/sources/awesomewidgets/extweather.h @@ -23,9 +23,9 @@ #include "abstractextitem.h" #define YAHOO_WEATHER_URL \ - "https://query.yahooapis.com/v1/public/yql?format=json&q=select * from " \ - "weather.forecast where u='c' and woeid in (select woeid from " \ - "geo.places(1) where text='%1, %2')" + "https://query.yahooapis.com/v1/public/yql?format=json&env=store://" \ + "datatables.org/alltableswithkeys&q=select * from weather.forecast where " \ + "u='c' and woeid in (select woeid from geo.places(1) where text='%1, %2')" namespace Ui diff --git a/sources/awesomewidgets/graphicalitem.cpp b/sources/awesomewidgets/graphicalitem.cpp index 843da2b..b24e284 100644 --- a/sources/awesomewidgets/graphicalitem.cpp +++ b/sources/awesomewidgets/graphicalitem.cpp @@ -23,14 +23,13 @@ #include #include #include -#include +#include #include #include #include -#include - #include "awdebug.h" +#include "graphicalitemhelper.h" #include "version.h" @@ -47,10 +46,22 @@ GraphicalItem::GraphicalItem(QWidget *parent, const QString desktopName, initScene(); + connect(ui->checkBox_custom, SIGNAL(stateChanged(int)), this, + SLOT(changeValue(int))); + connect(ui->checkBox_activeCheck, SIGNAL(stateChanged(int)), this, + SLOT(changeColorState(int))); + connect(ui->checkBox_inactiveCheck, SIGNAL(stateChanged(int)), this, + SLOT(changeColorState(int))); + connect(ui->comboBox_type, SIGNAL(currentIndexChanged(int)), this, + SLOT(changeCountState(int))); connect(ui->pushButton_activeColor, SIGNAL(clicked()), this, SLOT(changeColor())); connect(ui->pushButton_inactiveColor, SIGNAL(clicked()), this, SLOT(changeColor())); + connect(ui->pushButton_activeImage, SIGNAL(clicked()), this, + SLOT(changeImage())); + connect(ui->pushButton_inactiveImage, SIGNAL(clicked()), this, + SLOT(changeImage())); } @@ -60,6 +71,7 @@ GraphicalItem::~GraphicalItem() delete m_scene; delete ui; + delete m_helper; } @@ -69,52 +81,52 @@ GraphicalItem *GraphicalItem::copy(const QString _fileName, const int _number) GraphicalItem *item = new GraphicalItem(static_cast(parent()), _fileName, directories()); - item->setActive(isActive()); - item->setActiveColor(activeColor()); - item->setApiVersion(apiVersion()); - item->setBar(bar()); - item->setComment(comment()); - item->setDirection(direction()); - item->setHeight(height()); - item->setInactiveColor(inactiveColor()); - item->setInterval(interval()); - item->setName(QString("bar%1").arg(_number)); + copyDefaults(item); + item->setActiveColor(m_activeColor); + item->setBar(m_bar); + item->setCount(m_count); + item->setCustom(m_custom); + item->setDirection(m_direction); + item->setHeight(m_height); + item->setInactiveColor(m_inactiveColor); + item->setMaxValue(m_maxValue); + item->setMinValue(m_minValue); item->setNumber(_number); - item->setType(type()); - item->setWidth(width()); + item->setType(m_type); + item->setWidth(m_width); return item; } -QString GraphicalItem::image(const QVariant value) +QString GraphicalItem::image(const QVariant &value) { qCDebug(LOG_LIB) << "Value" << value; - if (m_bar == QString("none")) - return QString(""); m_scene->clear(); int scale[2] = {1, 1}; + float converted + = m_helper->getPercents(value.toFloat(), m_minValue, m_maxValue); // paint switch (m_type) { case Vertical: - paintVertical(value.toFloat()); + m_helper->paintVertical(converted); // scale scale[1] = -2 * static_cast(m_direction) + 1; break; case Circle: - paintCircle(value.toFloat()); + m_helper->paintCircle(converted); // scale scale[0] = -2 * static_cast(m_direction) + 1; break; case Graph: - paintGraph(value.value>()); + m_helper->paintGraph(converted); // direction option is not recognized by this GI type break; case Horizontal: default: - paintHorizontal(value.toFloat()); + m_helper->paintHorizontal(converted); // scale scale[0] = -2 * static_cast(m_direction) + 1; break; @@ -151,9 +163,27 @@ QString GraphicalItem::inactiveColor() const } -QString GraphicalItem::tag() const +int GraphicalItem::count() const { - return QString("bar%1%2").arg(number()).arg(m_bar); + return m_count; +} + + +bool GraphicalItem::isCustom() const +{ + return m_custom; +} + + +float GraphicalItem::maxValue() const +{ + return m_maxValue; +} + + +float GraphicalItem::minValue() const +{ + return m_minValue; } @@ -215,6 +245,12 @@ int GraphicalItem::height() const } +QStringList GraphicalItem::usedKeys() const +{ + return m_usedKeys; +} + + int GraphicalItem::width() const { return m_width; @@ -231,13 +267,7 @@ void GraphicalItem::setBar(const QString _bar) { qCDebug(LOG_LIB) << "Bar" << _bar; - if (!_bar.contains(QRegExp( - QString("^(cpu(?!cl).*|gpu$|mem$|swap$|hdd[0-9].*|bat.*)")))) { - qCWarning(LOG_LIB) << "Unsupported bar type" << _bar; - m_bar = QString("none"); - } else { - m_bar = _bar; - } + m_bar = _bar; } @@ -249,6 +279,24 @@ void GraphicalItem::setActiveColor(const QString _color) } +void GraphicalItem::setCount(const int _count) +{ + qCDebug(LOG_LIB) << "Count" << _count; + if (_count <= 1) + return; + + m_count = _count; +} + + +void GraphicalItem::setCustom(const bool _custom) +{ + qCDebug(LOG_LIB) << "Use custom tag" << _custom; + + m_custom = _custom; +} + + void GraphicalItem::setInactiveColor(const QString _color) { qCDebug(LOG_LIB) << "Color" << _color; @@ -257,6 +305,22 @@ void GraphicalItem::setInactiveColor(const QString _color) } +void GraphicalItem::setMaxValue(const float _value) +{ + qCDebug(LOG_LIB) << "Max value" << _value; + + m_maxValue = _value; +} + + +void GraphicalItem::setMinValue(const float _value) +{ + qCDebug(LOG_LIB) << "Min value" << _value; + + m_minValue = _value; +} + + void GraphicalItem::setType(const Type _type) { qCDebug(LOG_LIB) << "Type" << _type; @@ -309,6 +373,15 @@ void GraphicalItem::setHeight(const int _height) } +void GraphicalItem::setUsedKeys(const QStringList _usedKeys) +{ + qCDebug(LOG_LIB) << "Used keys" << _usedKeys; + + // remove dubs + m_usedKeys = QSet::fromList(_usedKeys).toList(); +} + + void GraphicalItem::setWidth(const int _width) { qCDebug(LOG_LIB) << "Width" << _width; @@ -333,7 +406,11 @@ void GraphicalItem::readConfiguration() QSettings::IniFormat); settings.beginGroup(QString("Desktop Entry")); + setCount(settings.value(QString("X-AW-Count"), m_count).toInt()); + setCustom(settings.value(QString("X-AW-Custom"), m_custom).toBool()); setBar(settings.value(QString("X-AW-Value"), m_bar).toString()); + setMaxValue(settings.value(QString("X-AW-Max"), m_maxValue).toFloat()); + setMinValue(settings.value(QString("X-AW-Min"), m_minValue).toFloat()); setActiveColor( settings.value(QString("X-AW-ActiveColor"), m_activeColor) .toString()); @@ -362,23 +439,24 @@ void GraphicalItem::readConfiguration() } -QVariantHash GraphicalItem::run() -{ - // required by abstract class - return QVariantHash(); -} - - int GraphicalItem::showConfiguration(const QVariant args) { qCDebug(LOG_LIB) << "Combobox arguments" << args; QStringList tags = args.toStringList(); - ui->label_nameValue->setText(name()); + ui->lineEdit_name->setText(name()); ui->lineEdit_comment->setText(comment()); + ui->checkBox_custom->setChecked(m_custom); ui->comboBox_value->addItems(tags); - ui->comboBox_value->addItem(m_bar); - ui->comboBox_value->setCurrentIndex(ui->comboBox_value->count() - 1); + if (m_custom) { + ui->lineEdit_customValue->setText(m_bar); + } else { + ui->comboBox_value->addItem(m_bar); + ui->comboBox_value->setCurrentIndex(ui->comboBox_value->count() - 1); + } + ui->doubleSpinBox_max->setValue(m_maxValue); + ui->doubleSpinBox_min->setValue(m_minValue); + ui->spinBox_count->setValue(m_count); ui->pushButton_activeColor->setText(m_activeColor); ui->pushButton_inactiveColor->setText(m_inactiveColor); ui->comboBox_type->setCurrentIndex(static_cast(m_type)); @@ -386,13 +464,22 @@ int GraphicalItem::showConfiguration(const QVariant args) ui->spinBox_height->setValue(m_height); ui->spinBox_width->setValue(m_width); + // update UI + changeCountState(ui->comboBox_type->currentIndex()); + changeValue(ui->checkBox_custom->checkState()); + int ret = exec(); if (ret != 1) return ret; - setName(ui->label_nameValue->text()); + setName(ui->lineEdit_name->text()); setComment(ui->lineEdit_comment->text()); setApiVersion(AWGIAPI); - setBar(ui->comboBox_value->currentText()); + setCount(ui->spinBox_count->value()); + setCustom(ui->checkBox_custom->isChecked()); + setBar(m_custom ? ui->lineEdit_customValue->text() + : ui->comboBox_value->currentText()); + setMaxValue(ui->doubleSpinBox_max->value()); + setMinValue(ui->doubleSpinBox_min->value()); setActiveColor(ui->pushButton_activeColor->text().remove(QChar('&'))); setInactiveColor(ui->pushButton_inactiveColor->text().remove(QChar('&'))); setStrType(ui->comboBox_type->currentText()); @@ -416,6 +503,10 @@ void GraphicalItem::writeConfiguration() const settings.beginGroup(QString("Desktop Entry")); settings.setValue(QString("X-AW-Value"), m_bar); + settings.setValue(QString("X-AW-Count"), m_count); + settings.setValue(QString("X-AW-Custom"), m_custom); + settings.setValue(QString("X-AW-Max"), m_maxValue); + settings.setValue(QString("X-AW-Min"), m_minValue); settings.setValue(QString("X-AW-ActiveColor"), m_activeColor); settings.setValue(QString("X-AW-InactiveColor"), m_inactiveColor); settings.setValue(QString("X-AW-Type"), strType()); @@ -430,8 +521,8 @@ void GraphicalItem::writeConfiguration() const void GraphicalItem::changeColor() { - QColor color - = stringToColor((static_cast(sender()))->text()); + QColor color = m_helper->stringToColor( + (static_cast(sender()))->text()); QColor newColor = QColorDialog::getColor(color, this, tr("Select color"), QColorDialog::ShowAlphaChannel); if (!newColor.isValid()) @@ -449,14 +540,59 @@ void GraphicalItem::changeColor() } +void GraphicalItem::changeColorState(const int state) +{ + qCDebug(LOG_LIB) << "Current color state is" << state; + + if (sender() == ui->checkBox_activeCheck) { + qCInfo(LOG_LIB) << "Change active color state"; + ui->widget_activeColor->setHidden(state == Qt::Unchecked); + ui->widget_activeImage->setHidden(state != Qt::Unchecked); + } else if (sender() == ui->checkBox_inactiveCheck) { + qCInfo(LOG_LIB) << "Change inactive color state"; + ui->widget_inactiveColor->setHidden(state == Qt::Unchecked); + ui->widget_inactiveImage->setHidden(state != Qt::Unchecked); + } +} + + +void GraphicalItem::changeCountState(const int state) +{ + qCDebug(LOG_LIB) << "Current state is" << state; + + // 3 is magic number. Actually 3 is Graph mode + ui->widget_count->setHidden(state != 3); +} + + +void GraphicalItem::changeImage() +{ + QString path = static_cast(sender())->text(); + QString directory = QFileInfo(path).absolutePath(); + QString newPath = QFileDialog::getOpenFileName( + this, tr("Select path"), directory, + tr("Images (*.png *.bpm *.jpg);;All files (*.*)")); + + qCInfo(LOG_LIB) << "Selected path" << newPath; + + return static_cast(sender())->setText(newPath); +} + + +void GraphicalItem::changeValue(const int state) +{ + qCDebug(LOG_LIB) << "Current state is" << state; + + ui->widget_value->setHidden(state != Qt::Unchecked); + ui->widget_customValue->setHidden(state == Qt::Unchecked); +} + + void GraphicalItem::initScene() { // init scene m_scene = new QGraphicsScene(); - if (m_type == Graph) - m_scene->setBackgroundBrush(stringToColor(m_inactiveColor)); - else - m_scene->setBackgroundBrush(QBrush(Qt::NoBrush)); + m_scene->setBackgroundBrush(QBrush(Qt::NoBrush)); // init view m_view = new QGraphicsView(m_scene); m_view->setStyleSheet(QString("background: transparent")); @@ -464,104 +600,12 @@ void GraphicalItem::initScene() m_view->setFrameShape(QFrame::NoFrame); m_view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); m_view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - m_view->resize(m_width + 5.0, m_height + 5.0); -} + m_view->resize(m_width + 5, m_height + 5); - -void GraphicalItem::paintCircle(const float value) -{ - QPen pen; - pen.setWidth(1.0); - float percent = value / 100.0; - QGraphicsEllipseItem *circle; - - QColor inactive = stringToColor(m_inactiveColor); - QColor active = stringToColor(m_activeColor); - - // inactive - pen.setColor(inactive); - circle = m_scene->addEllipse(0.0, 0.0, m_width, m_height, pen, - QBrush(inactive, Qt::SolidPattern)); - circle->setSpanAngle(-(1.0 - percent) * 360.0 * 16.0); - circle->setStartAngle(90.0 * 16.0 - percent * 360.0 * 16.0); - // active - pen.setColor(active); - circle = m_scene->addEllipse(0.0, 0.0, m_width, m_height, pen, - QBrush(active, Qt::SolidPattern)); - circle->setSpanAngle(-percent * 360.0 * 16.0); - circle->setStartAngle(90.0 * 16.0); -} - - -void GraphicalItem::paintGraph(const QList value) -{ - QPen pen; - pen.setColor(stringToColor(m_activeColor)); - - // default norms - float normX - = static_cast(m_width) / static_cast(value.count()); - float normY = static_cast(m_height) / (1.5 * 100.0); - // paint graph - for (int i = 0; i < value.count() - 1; i++) { - // some magic here - float x1 = i * normX; - float y1 = -fabs(value.at(i)) * normY + 5.0; - float x2 = (i + 1) * normX; - float y2 = -fabs(value.at(i + 1)) * normY + 5.0; - m_scene->addLine(x1, y1, x2, y2, pen); - } -} - - -void GraphicalItem::paintHorizontal(const float value) -{ - QPen pen; - float percent = value / 100.0; - - pen.setWidth(m_height); - // inactive - pen.setColor(stringToColor(m_inactiveColor)); - m_scene->addLine(percent * m_width + 0.5 * m_height, 0.5 * m_height, - m_width + 0.5 * m_height, 0.5 * m_height, pen); - // active - pen.setColor(stringToColor(m_activeColor)); - m_scene->addLine(-0.5 * m_height, 0.5 * m_height, - percent * m_width - 0.5 * m_height, 0.5 * m_height, pen); -} - - -void GraphicalItem::paintVertical(const float value) -{ - QPen pen; - float percent = value / 100.0; - - pen.setWidth(m_width); - // inactive - pen.setColor(stringToColor(m_inactiveColor)); - m_scene->addLine(0.5 * m_width, -0.5 * m_width, 0.5 * m_width, - (1.0 - percent) * m_height - 0.5 * m_width, pen); - // active - pen.setColor(stringToColor(m_activeColor)); - m_scene->addLine(0.5 * m_width, (1.0 - percent) * m_height + 0.5 * m_width, - 0.5 * m_width, m_height + 0.5 * m_width, pen); -} - - -QColor GraphicalItem::stringToColor(const QString _color) const -{ - qCDebug(LOG_LIB) << "Color" << _color; - - QColor qcolor; - QStringList listColor = _color.split(QChar(',')); - while (listColor.count() < 4) - listColor.append(QString("0")); - qcolor.setRed(listColor.at(0).toInt()); - qcolor.setGreen(listColor.at(1).toInt()); - qcolor.setBlue(listColor.at(2).toInt()); - qcolor.setAlpha(listColor.at(3).toInt()); - - return qcolor; + // init helper + m_helper = new GraphicalItemHelper(this, m_scene); + m_helper->setParameters(m_activeColor, m_inactiveColor, m_width, m_height, + m_count); } @@ -569,9 +613,18 @@ void GraphicalItem::translate() { ui->label_name->setText(i18n("Name")); ui->label_comment->setText(i18n("Comment")); + ui->label_count->setText(i18n("Points count")); + ui->checkBox_custom->setText(i18n("Use custom formula")); ui->label_value->setText(i18n("Value")); + ui->label_customValue->setText(i18n("Value")); + ui->label_max->setText(i18n("Max value")); + ui->label_min->setText(i18n("Min value")); + ui->checkBox_activeCheck->setText(i18n("Use image for active")); ui->label_activeColor->setText(i18n("Active color")); + ui->label_activeImage->setText(i18n("Active image")); + ui->checkBox_inactiveCheck->setText(i18n("Use image for inactive")); ui->label_inactiveColor->setText(i18n("Inactive color")); + ui->label_inactiveImage->setText(i18n("Inactive image")); ui->label_type->setText(i18n("Type")); ui->label_direction->setText(i18n("Direction")); ui->label_height->setText(i18n("Height")); diff --git a/sources/awesomewidgets/graphicalitem.h b/sources/awesomewidgets/graphicalitem.h index eb0ef78..117237c 100644 --- a/sources/awesomewidgets/graphicalitem.h +++ b/sources/awesomewidgets/graphicalitem.h @@ -23,6 +23,7 @@ #include "abstractextitem.h" +class GraphicalItemHelper; class QGraphicsScene; class QGraphicsView; @@ -36,10 +37,15 @@ class GraphicalItem : public AbstractExtItem Q_OBJECT Q_PROPERTY(QString bar READ bar WRITE setBar) Q_PROPERTY(QString activeColor READ activeColor WRITE setActiveColor) + Q_PROPERTY(int count READ count WRITE setCount) + Q_PROPERTY(bool custom READ isCustom WRITE setCustom) Q_PROPERTY(QString inactiveColor READ inactiveColor WRITE setInactiveColor) Q_PROPERTY(Type type READ type WRITE setType) Q_PROPERTY(Direction direction READ direction WRITE setDirection) Q_PROPERTY(int height READ height WRITE setHeight) + Q_PROPERTY(float maxValue READ maxValue WRITE setMaxValue) + Q_PROPERTY(float minValue READ minValue WRITE setMinValue) + Q_PROPERTY(QStringList usedKeys READ usedKeys WRITE setUsedKeys) Q_PROPERTY(int width READ width WRITE setWidth) public: @@ -51,61 +57,71 @@ public: const QStringList directories = QStringList()); virtual ~GraphicalItem(); GraphicalItem *copy(const QString _fileName, const int _number); - QString image(const QVariant value); + QString image(const QVariant &value); // get methods QString bar() const; QString activeColor() const; QString inactiveColor() const; - QString tag() const; + int count() const; + bool isCustom() const; + float minValue() const; + float maxValue() const; Type type() const; QString strType() const; Direction direction() const; QString strDirection() const; int height() const; + QStringList usedKeys() const; int width() const; QString uniq() const; // set methods void setBar(const QString _bar = QString("cpu")); void setActiveColor(const QString _color = QString("0,0,0,130")); + void setCount(const int _count = 100); + void setCustom(const bool _custom = false); void setInactiveColor(const QString _color = QString("255,255,255,130")); + void setMinValue(const float _value = 0.0); + void setMaxValue(const float _value = 100.0); void setType(const Type _type = Horizontal); void setStrType(const QString _type = QString("Horizontal")); void setDirection(const Direction _direction = LeftToRight); void setStrDirection(const QString _direction = QString("LeftToRight")); void setHeight(const int _height = 100); + void setUsedKeys(const QStringList _usedKeys = QStringList()); void setWidth(const int _width = 100); public slots: void readConfiguration(); - QVariantHash run(); + QVariantHash run() { return QVariantHash(); }; int showConfiguration(const QVariant args = QVariant()); void writeConfiguration() const; private slots: void changeColor(); + void changeColorState(const int state); + void changeCountState(const int state); + void changeImage(); + void changeValue(const int state); private: - QString m_fileName; - QStringList m_dirs; + GraphicalItemHelper *m_helper = nullptr; QGraphicsScene *m_scene = nullptr; QGraphicsView *m_view = nullptr; Ui::GraphicalItem *ui; void initScene(); - // paint methods - void paintCircle(const float value); - void paintGraph(const QList value); - void paintHorizontal(const float value); - void paintVertical(const float value); - // additional method - QColor stringToColor(const QString _color) const; void translate(); // properties QString m_bar = QString("cpu"); - QString m_activeColor = QString("0,0,0,130"); - QString m_inactiveColor = QString("255,255,255,130"); + int m_count = 100; + bool m_custom = false; + QString m_activeColor; + QString m_inactiveColor; + float m_minValue = 0.0f; + float m_maxValue = 100.0f; Type m_type = Horizontal; Direction m_direction = LeftToRight; int m_height = 100; + QStringList m_usedKeys; int m_width = 100; }; diff --git a/sources/awesomewidgets/graphicalitem.ui b/sources/awesomewidgets/graphicalitem.ui index a2fb703..5a5e2ae 100644 --- a/sources/awesomewidgets/graphicalitem.ui +++ b/sources/awesomewidgets/graphicalitem.ui @@ -7,7 +7,7 @@ 0 0 416 - 325 + 606 @@ -18,8 +18,14 @@ + + + 0 + 0 + + - Name + &Name Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -27,11 +33,7 @@ - - - - - + @@ -46,7 +48,7 @@ - Comment + &Comment Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -59,32 +61,120 @@ - + + + Qt::Horizontal + + + + + - - - Value + + + Qt::Horizontal - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 40 + 20 + - + - - - false + + + + 0 + 0 + + + + Use custom formula - + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + &Value + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + false + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + Va&lue + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + - + - Active color + &Max value Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -92,20 +182,20 @@ - - - + + + 9999.989999999999782 - + - + - Inactive color + Min val&ue Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -113,20 +203,265 @@ - - - + + + 9999.989999999999782 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + &Points count + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + 2000 + + + 25 + + + + + + + + + + Qt::Horizontal + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + Use image for active + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Activ&e color + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + &Active image + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + Use image for inactive + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + &Inactive color + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Inactive image + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + + - Type + &Type Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -164,7 +499,7 @@ - Direction + &Direction Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -192,7 +527,7 @@ - Height + &Height Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -216,7 +551,7 @@ - Width + &Width Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter diff --git a/sources/awesomewidgets/graphicalitemhelper.cpp b/sources/awesomewidgets/graphicalitemhelper.cpp new file mode 100644 index 0000000..a08f8cb --- /dev/null +++ b/sources/awesomewidgets/graphicalitemhelper.cpp @@ -0,0 +1,201 @@ +/*************************************************************************** + * 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 "graphicalitemhelper.h" + +#include +#include +#include + +#include + +#include "awdebug.h" + + +GraphicalItemHelper::GraphicalItemHelper(QObject *parent, QGraphicsScene *scene) + : QObject(parent) + , m_scene(scene) +{ + qCDebug(LOG_LIB) << __PRETTY_FUNCTION__; +} + + +GraphicalItemHelper::~GraphicalItemHelper() +{ + qCDebug(LOG_LIB) << __PRETTY_FUNCTION__; +} + + +void GraphicalItemHelper::setParameters(const QString active, + const QString inactive, const int width, + const int height, const int count) +{ + qCDebug(LOG_LIB) << "Use active color" << active << ", inactive" << inactive + << ", width" << width << ", height" << height << ", count" + << count; + + // put images to pens if any otherwise set pen colors + // Images resize to content here as well + if (active.startsWith(QString("/"))) { + qCInfo(LOG_LIB) << "Found path, trying to load Pixmap from" << active; + QPixmap pixmap = QPixmap(active); + if (pixmap.isNull()) { + qCInfo(LOG_LIB) << "Invalid pixmap found" << active; + m_activePen.setColor(QColor(0, 0, 0, 130)); + } else { + m_activePen.setBrush(QBrush(pixmap.scaled(width, height))); + } + } else { + m_activePen.setColor(stringToColor(active)); + } + if (inactive.startsWith(QString("/"))) { + qCInfo(LOG_LIB) << "Found path, trying to load Pixmap from" << inactive; + QPixmap pixmap = QPixmap(inactive); + if (pixmap.isNull()) { + qCInfo(LOG_LIB) << "Invalid pixmap found" << inactive; + m_inactivePen.setColor(QColor(255, 255, 255, 130)); + } else { + m_inactivePen.setBrush(QBrush(pixmap.scaled(width, height))); + } + } else { + m_inactivePen.setColor(stringToColor(inactive)); + } + m_width = width; + m_height = height; + m_count = count; +} + + +void GraphicalItemHelper::paintCircle(const float &percent) +{ + qCDebug(LOG_LIB) << "Paint with percent" << percent; + + m_activePen.setWidth(1); + m_inactivePen.setWidth(1); + QGraphicsEllipseItem *circle; + // 16 is because of qt. From Qt documentation: + // Returns the start angle for an ellipse segment in 16ths of a degree + + // inactive + circle = m_scene->addEllipse(0.0, 0.0, m_width, m_height, m_inactivePen, + m_inactivePen.brush()); + circle->setSpanAngle(-(1.0f - percent) * 360.0f * 16.0f); + circle->setStartAngle(90.0f * 16.0f - percent * 360.0f * 16.0f); + // active + circle = m_scene->addEllipse(0.0, 0.0, m_width, m_height, m_activePen, + m_activePen.brush()); + circle->setSpanAngle(-percent * 360.0f * 16.0f); + circle->setStartAngle(90 * 16); +} + + +void GraphicalItemHelper::paintGraph(const float &value) +{ + qCDebug(LOG_LIB) << "Paint with value" << value; + + // refresh background image + m_scene->setBackgroundBrush(m_inactivePen.brush()); + + storeValue(value); + + // default norms + float normX + = static_cast(m_width) / static_cast(m_values.count()); + float normY = static_cast(m_height - 1); + // paint graph + for (int i = 0; i < m_values.count() - 1; i++) { + // some magic here + float x1 = i * normX; + float y1 = -fabs(m_values.at(i)) * normY + 0.5f; + float x2 = (i + 1) * normX; + float y2 = -fabs(m_values.at(i + 1)) * normY + 0.5f; + m_scene->addLine(x1, y1, x2, y2, m_activePen); + } +} + + +void GraphicalItemHelper::paintHorizontal(const float &percent) +{ + qCDebug(LOG_LIB) << "Paint with percent" << percent; + + m_activePen.setWidth(m_height); + m_inactivePen.setWidth(m_height); + // inactive + m_scene->addLine(percent * m_width + 0.5 * m_height, 0.5 * m_height, + m_width + 0.5 * m_height, 0.5 * m_height, m_inactivePen); + // active + m_scene->addLine(-0.5 * m_height, 0.5 * m_height, + percent * m_width - 0.5 * m_height, 0.5 * m_height, + m_activePen); +} + + +void GraphicalItemHelper::paintVertical(const float &percent) +{ + qCDebug(LOG_LIB) << "Paint with percent" << percent; + + m_activePen.setWidth(m_height); + m_inactivePen.setWidth(m_height); + // inactive + m_scene->addLine(0.5 * m_width, -0.5 * m_width, 0.5 * m_width, + (1.0 - percent) * m_height - 0.5 * m_width, m_inactivePen); + // active + m_scene->addLine(0.5 * m_width, (1.0 - percent) * m_height + 0.5 * m_width, + 0.5 * m_width, m_height + 0.5 * m_width, m_activePen); +} + + +float GraphicalItemHelper::getPercents(const float &value, const float &min, + const float &max) +{ + qCDebug(LOG_LIB) << "Get percent value from" << value; + // newest Qt crashes here if value is nan + if (isnan(value)) + return 0.0; + + return (value - min) / (max - min); +} + + +QColor GraphicalItemHelper::stringToColor(const QString &color) +{ + qCDebug(LOG_LIB) << "Color" << color; + + QColor qColor; + QStringList listColor = color.split(QChar(',')); + while (listColor.count() < 4) + listColor.append(QString("0")); + qColor.setRed(listColor.at(0).toInt()); + qColor.setGreen(listColor.at(1).toInt()); + qColor.setBlue(listColor.at(2).toInt()); + qColor.setAlpha(listColor.at(3).toInt()); + + return qColor; +} + + +void GraphicalItemHelper::storeValue(const float &value) +{ + qCDebug(LOG_LIB) << "Save value to array" << value; + + if (m_values.count() == 0) + m_values.append(1.0); + else if (m_values.count() > m_count) + m_values.removeFirst(); + + m_values.append(value); +} diff --git a/sources/awesomewidgets/graphicalitemhelper.h b/sources/awesomewidgets/graphicalitemhelper.h new file mode 100644 index 0000000..96ac999 --- /dev/null +++ b/sources/awesomewidgets/graphicalitemhelper.h @@ -0,0 +1,59 @@ +/*************************************************************************** + * 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/ * + ***************************************************************************/ + +#ifndef GRAPHICALITEMHELPER_H +#define GRAPHICALITEMHELPER_H + +#include +#include +#include + + +class QGraphicsScene; + +class GraphicalItemHelper : public QObject +{ +public: + explicit GraphicalItemHelper(QObject *parent = nullptr, + QGraphicsScene *scene = nullptr); + virtual ~GraphicalItemHelper(); + // parameters + void setParameters(const QString active, const QString inactive, + const int width, const int height, const int count); + // paint methods + void paintCircle(const float &percent); + void paintGraph(const float &value); + void paintHorizontal(const float &percent); + void paintVertical(const float &percent); + // additional conversion methods + float getPercents(const float &value, const float &min, const float &max); + QColor stringToColor(const QString &color); + +private: + void storeValue(const float &value); + QGraphicsScene *m_scene = nullptr; + int m_count = 100; + QPen m_activePen; + QPen m_inactivePen; + int m_width = 100; + int m_height = 100; + // list of values which will be used to store data for graph type only + QList m_values; +}; + + +#endif /* GRAPHICALITEMHELPER_H */ diff --git a/sources/changelog.cmake b/sources/changelog.cmake new file mode 100644 index 0000000..abc78e7 --- /dev/null +++ b/sources/changelog.cmake @@ -0,0 +1,5 @@ +exec_program( + "sed -n '1,/^Ver/ p' CHANGELOG | grep -v '^Ver' | tr '\n' '@'" + ${CMAKE_CURRENT_SOURCE_DIR}/.. + OUTPUT_VARIABLE PROJECT_CHANGELOG +) diff --git a/sources/clang-format.cmake b/sources/clang-format.cmake index 3c9f08e..8484fba 100644 --- a/sources/clang-format.cmake +++ b/sources/clang-format.cmake @@ -1,7 +1,7 @@ # additional target to perform clang-format run, requires clang-format # get all project files -file(GLOB_RECURSE ALL_SOURCE_FILES *.cpp *.h) +file(GLOB_RECURSE ALL_SOURCE_FILES *.cpp *.h *.h.in) foreach (SOURCE_FILE ${ALL_SOURCE_FILES}) string(FIND ${SOURCE_FILE} ${PROJECT_TRDPARTY_DIR} PROJECT_TRDPARTY_DIR_FOUND) if (NOT ${PROJECT_TRDPARTY_DIR_FOUND} EQUAL -1) diff --git a/sources/desktop-panel/metadata.desktop b/sources/desktop-panel/metadata.desktop index 87fa8fa..f18af63 100644 --- a/sources/desktop-panel/metadata.desktop +++ b/sources/desktop-panel/metadata.desktop @@ -21,7 +21,7 @@ X-KDE-PluginInfo-Author=Evgeniy Alekseev aka arcanis X-KDE-PluginInfo-Email=esalexeev@gmail.com X-KDE-PluginInfo-Name=org.kde.plasma.desktoppanel X-KDE-PluginInfo-Version=@PROJECT_VERSION@ -X-KDE-PluginInfo-Website=http://arcanis.name/projects/awesome-widgets/ +X-KDE-PluginInfo-Website=https://arcanis.me/projects/awesome-widgets/ X-KDE-PluginInfo-Category=System Information X-KDE-PluginInfo-Depends= X-KDE-PluginInfo-License=GPLv3 diff --git a/sources/desktop-panel/package/contents/ui/widget.qml b/sources/desktop-panel/package/contents/ui/widget.qml index 99b30a6..cafccbf 100644 --- a/sources/desktop-panel/package/contents/ui/widget.qml +++ b/sources/desktop-panel/package/contents/ui/widget.qml @@ -46,7 +46,7 @@ Item { horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter wrapMode: Text.WordWrap - text: i18n("Detailed information may be found on project homepage") + text: i18n("Detailed information may be found on project homepage") onLinkActivated: Qt.openUrlExternally(link); } diff --git a/sources/desktop-panel/package/metadata.desktop b/sources/desktop-panel/package/metadata.desktop index 3f82376..574ff8d 100644 --- a/sources/desktop-panel/package/metadata.desktop +++ b/sources/desktop-panel/package/metadata.desktop @@ -21,7 +21,7 @@ X-KDE-PluginInfo-Author=Evgeniy Alekseev aka arcanis X-KDE-PluginInfo-Email=esalexeev@gmail.com X-KDE-PluginInfo-Name=org.kde.plasma.desktoppanel X-KDE-PluginInfo-Version=3.0.1 -X-KDE-PluginInfo-Website=http://arcanis.name/projects/awesome-widgets/ +X-KDE-PluginInfo-Website=https://arcanis.me/projects/awesome-widgets/ X-KDE-PluginInfo-Category=System Information X-KDE-PluginInfo-Depends= X-KDE-PluginInfo-License=GPLv3 diff --git a/sources/extsysmon/CMakeLists.txt b/sources/extsysmon/CMakeLists.txt index f7ca636..7e9857a 100644 --- a/sources/extsysmon/CMakeLists.txt +++ b/sources/extsysmon/CMakeLists.txt @@ -13,22 +13,19 @@ include_directories( file(GLOB SUBPROJECT_DESKTOP_IN *.desktop) file(RELATIVE_PATH SUBPROJECT_DESKTOP ${CMAKE_SOURCE_DIR} ${SUBPROJECT_DESKTOP_IN}) -file(GLOB SUBPROJECT_SOURCE *.cpp sources/*.cpp ${PROJECT_TRDPARTY_DIR}/task/*.cpp ${CMAKE_SOURCE_DIR}/*.cpp) -set(TASK_HEADER ${PROJECT_TRDPARTY_DIR}/task/task.h) +file(GLOB SUBPROJECT_SOURCE *.cpp sources/*.cpp ${CMAKE_SOURCE_DIR}/*.cpp) file(GLOB SUBPROJECT_CONF *.conf) -file(GLOB SUBPROJECT_INI *.ini) # prepare configure_file(${SUBPROJECT_DESKTOP_IN} ${CMAKE_CURRENT_BINARY_DIR}/${SUBPROJECT_DESKTOP}) # make -qt5_wrap_cpp(TASK_MOC_SOURCE ${TASK_HEADER}) -add_library(${SUBPROJECT} MODULE ${SUBPROJECT_SOURCE} ${TASK_MOC_SOURCE}) +add_library(${SUBPROJECT} MODULE ${SUBPROJECT_SOURCE}) target_link_libraries(${SUBPROJECT} ${PROJECT_LIBRARY} ${Qt_LIBRARIES} ${Kf5_LIBRARIES}) -kcoreaddons_desktop_to_json(${SUBPROJECT} ${CMAKE_CURRENT_BINARY_DIR}/${SUBPROJECT_DESKTOP}) +kcoreaddons_desktop_to_json(${SUBPROJECT} ${CMAKE_CURRENT_BINARY_DIR}/${SUBPROJECT_DESKTOP} + SERVICE_TYPES plasma-dataengine.desktop) # install install(TARGETS ${SUBPROJECT} DESTINATION ${PLUGIN_INSTALL_DIR}/plasma/dataengine) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${SUBPROJECT_DESKTOP} DESTINATION ${SERVICES_INSTALL_DIR}) install(FILES ${SUBPROJECT_CONF} DESTINATION ${CONFIG_INSTALL_DIR}) -install(FILES ${SUBPROJECT_INI} DESTINATION ${CONFIG_INSTALL_DIR}) diff --git a/sources/extsysmon/extsysmonaggregator.cpp b/sources/extsysmon/extsysmonaggregator.cpp index 44f33cd..7a43d7e 100644 --- a/sources/extsysmon/extsysmonaggregator.cpp +++ b/sources/extsysmon/extsysmonaggregator.cpp @@ -57,12 +57,14 @@ QVariant ExtSysMonAggregator::data(const QString source) const { qCDebug(LOG_ESM) << "Source" << source; - return hasSource(source) ? m_map[source]->data(source) : QVariant(); + return m_map[source]->data(source); } bool ExtSysMonAggregator::hasSource(const QString source) const { + qCDebug(LOG_ESM) << "Source" << source; + return m_map.contains(source); } @@ -78,9 +80,7 @@ QVariantMap ExtSysMonAggregator::initialData(const QString source) const QStringList ExtSysMonAggregator::sources() const { - QStringList sorted = m_map.keys(); - sorted.sort(); - return sorted; + return m_map.keys(); } diff --git a/sources/extsysmon/plasma-dataengine-extsysmon.desktop b/sources/extsysmon/plasma-dataengine-extsysmon.desktop index 9e570fa..8481949 100644 --- a/sources/extsysmon/plasma-dataengine-extsysmon.desktop +++ b/sources/extsysmon/plasma-dataengine-extsysmon.desktop @@ -6,9 +6,7 @@ ServiceTypes=Plasma/DataEngine Type=Service Icon=utilities-system-monitor -X-KDE-ServiceTypes=Plasma/DataEngine X-KDE-Library=plasma_dataengine_extsysmon -X-Plasma-EngineName=extsysmon X-KDE-PluginInfo-Author=Evgeniy Alekseev aka arcanis X-KDE-PluginInfo-Email=esalexeev@gmail.com @@ -17,4 +15,3 @@ X-KDE-PluginInfo-Version=@PROJECT_VERSION@ X-KDE-PluginInfo-Category=System Information X-KDE-PluginInfo-Depends= X-KDE-PluginInfo-License=GPL3 -X-KDE-PluginInfo-EnabledByDefault=true diff --git a/sources/extsysmon/sources/batterysource.cpp b/sources/extsysmon/sources/batterysource.cpp index 70ee6e2..96dfae2 100644 --- a/sources/extsysmon/sources/batterysource.cpp +++ b/sources/extsysmon/sources/batterysource.cpp @@ -44,9 +44,10 @@ QVariant BatterySource::data(QString source) { qCDebug(LOG_ESM) << "Source" << source; - if (source == QString("battery/ac")) + if (!m_values.contains(source)) run(); - return values[source]; + QVariant value = m_values.take(source); + return value; } @@ -84,11 +85,11 @@ void BatterySource::run() // adaptor QFile acFile(QString("%1/AC/online").arg(m_acpiPath)); if (acFile.open(QIODevice::ReadOnly)) - values[QString("battery/ac")] + m_values[QString("battery/ac")] = (QString(acFile.readLine()).trimmed().toInt() == 1); acFile.close(); - // batterites + // batteries float currentLevel = 0.0; float fullLevel = 0.0; for (int i = 0; i < m_batteriesCount; i++) { @@ -102,7 +103,7 @@ void BatterySource::run() = QString(currentLevelFile.readLine()).trimmed().toFloat(); float batFull = QString(fullLevelFile.readLine()).trimmed().toFloat(); - values[QString("battery/bat%1").arg(i)] + m_values[QString("battery/bat%1").arg(i)] = static_cast(100 * batCurrent / batFull); currentLevel += batCurrent; fullLevel += batFull; @@ -110,7 +111,7 @@ void BatterySource::run() currentLevelFile.close(); fullLevelFile.close(); } - values[QString("battery/bat")] + m_values[QString("battery/bat")] = static_cast(100 * currentLevel / fullLevel); } diff --git a/sources/extsysmon/sources/batterysource.h b/sources/extsysmon/sources/batterysource.h index 8a1fe3f..09403c7 100644 --- a/sources/extsysmon/sources/batterysource.h +++ b/sources/extsysmon/sources/batterysource.h @@ -39,7 +39,7 @@ private: int m_batteriesCount = 0; QString m_acpiPath; QStringList m_sources; - QVariantHash values; + QVariantHash m_values; }; diff --git a/sources/extsysmon/sources/gpuloadsource.cpp b/sources/extsysmon/sources/gpuloadsource.cpp index 6150bda..c7d1396 100644 --- a/sources/extsysmon/sources/gpuloadsource.cpp +++ b/sources/extsysmon/sources/gpuloadsource.cpp @@ -18,10 +18,9 @@ #include "gpuloadsource.h" +#include #include -#include - #include "awdebug.h" @@ -32,12 +31,23 @@ GPULoadSource::GPULoadSource(QObject *parent, const QStringList args) qCDebug(LOG_ESM) << __PRETTY_FUNCTION__; m_device = args.at(0); + + m_process = new QProcess(nullptr); + // fucking magic from http://doc.qt.io/qt-5/qprocess.html#finished + connect(m_process, + static_cast( + &QProcess::finished), + [this](int, QProcess::ExitStatus) { return updateValue(); }); + m_process->waitForFinished(0); } GPULoadSource::~GPULoadSource() { qCDebug(LOG_ESM) << __PRETTY_FUNCTION__; + + m_process->kill(); + m_process->deleteLater(); } @@ -45,49 +55,10 @@ QVariant GPULoadSource::data(QString source) { qCDebug(LOG_ESM) << "Source" << source; - if (source == QString("gpu/load")) { - float value = 0.0; - if ((m_device != QString("nvidia")) && (m_device != QString("ati"))) - return value; - // build cmd - QString cmd = m_device == QString("nvidia") - ? QString("nvidia-smi -q -x") - : QString("aticonfig --od-getclocks"); - qCInfo(LOG_ESM) << "cmd" << cmd; - TaskResult process = runTask(cmd); - qCInfo(LOG_ESM) << "Cmd returns" << process.exitCode; - qCInfo(LOG_ESM) << "Error" << process.error; - // parse - QString qoutput - = QTextCodec::codecForMib(106)->toUnicode(process.output).trimmed(); - if (m_device == QString("nvidia")) { - for (auto str : - qoutput.split(QChar('\n'), QString::SkipEmptyParts)) { - if (!str.contains(QString(""))) - continue; - QString load = str.remove(QString("")) - .remove(QString("")) - .remove(QChar('%')); - value = load.toFloat(); - break; - } - } else if (m_device == QString("ati")) { - for (auto str : - qoutput.split(QChar('\n'), QString::SkipEmptyParts)) { - if (!str.contains(QString("load"))) - continue; - QString load - = str.split(QChar(' '), QString::SkipEmptyParts)[3].remove( - QChar('%')); - value = load.toFloat(); - break; - } - } - // return - return value; - } + if (source == QString("gpu/load")) + run(); - return QVariant(); + return m_value; } @@ -108,6 +79,20 @@ QVariantMap GPULoadSource::initialData(QString source) const } +void GPULoadSource::run() +{ + if ((m_device != QString("nvidia")) && (m_device != QString("ati"))) + return; + // build cmd + QString cmd = m_device == QString("nvidia") + ? QString("nvidia-smi -q -x") + : QString("aticonfig --od-getclocks"); + qCInfo(LOG_ESM) << "cmd" << cmd; + + m_process->start(cmd); +} + + QStringList GPULoadSource::sources() const { QStringList sources; @@ -115,3 +100,39 @@ QStringList GPULoadSource::sources() const return sources; } + + +void GPULoadSource::updateValue() +{ + qCInfo(LOG_LIB) << "Cmd returns" << m_process->exitCode(); + QString qdebug = QTextCodec::codecForMib(106) + ->toUnicode(m_process->readAllStandardError()) + .trimmed(); + qCInfo(LOG_LIB) << "Error" << qdebug; + QString qoutput = QTextCodec::codecForMib(106) + ->toUnicode(m_process->readAllStandardOutput()) + .trimmed(); + qCInfo(LOG_LIB) << "Output" << qoutput; + + if (m_device == QString("nvidia")) { + for (auto str : qoutput.split(QChar('\n'), QString::SkipEmptyParts)) { + if (!str.contains(QString(""))) + continue; + QString load = str.remove(QString("")) + .remove(QString("")) + .remove(QChar('%')); + m_value = load.toFloat(); + break; + } + } else if (m_device == QString("ati")) { + for (auto str : qoutput.split(QChar('\n'), QString::SkipEmptyParts)) { + if (!str.contains(QString("load"))) + continue; + QString load + = str.split(QChar(' '), QString::SkipEmptyParts)[3].remove( + QChar('%')); + m_value = load.toFloat(); + break; + } + } +} diff --git a/sources/extsysmon/sources/gpuloadsource.h b/sources/extsysmon/sources/gpuloadsource.h index 3ddff3b..38e611b 100644 --- a/sources/extsysmon/sources/gpuloadsource.h +++ b/sources/extsysmon/sources/gpuloadsource.h @@ -23,6 +23,8 @@ #include "abstractextsysmonsource.h" +class QProcess; + class GPULoadSource : public AbstractExtSysMonSource { public: @@ -30,12 +32,17 @@ public: virtual ~GPULoadSource(); QVariant data(QString source); QVariantMap initialData(QString source) const; - void run(){}; + void run(); QStringList sources() const; +private slots: + void updateValue(); + private: // configuration and values QString m_device; + QProcess *m_process = nullptr; + QVariant m_value; }; diff --git a/sources/extsysmon/sources/gputempsource.cpp b/sources/extsysmon/sources/gputempsource.cpp index 3c83258..45cdc4b 100644 --- a/sources/extsysmon/sources/gputempsource.cpp +++ b/sources/extsysmon/sources/gputempsource.cpp @@ -18,10 +18,9 @@ #include "gputempsource.h" +#include #include -#include - #include "awdebug.h" @@ -33,12 +32,23 @@ GPUTemperatureSource::GPUTemperatureSource(QObject *parent, qCDebug(LOG_ESM) << __PRETTY_FUNCTION__; m_device = args.at(0); + + m_process = new QProcess(nullptr); + // fucking magic from http://doc.qt.io/qt-5/qprocess.html#finished + connect(m_process, + static_cast( + &QProcess::finished), + [this](int, QProcess::ExitStatus) { return updateValue(); }); + m_process->waitForFinished(0); } GPUTemperatureSource::~GPUTemperatureSource() { qCDebug(LOG_ESM) << __PRETTY_FUNCTION__; + + m_process->kill(); + m_process->deleteLater(); } @@ -46,47 +56,10 @@ QVariant GPUTemperatureSource::data(QString source) { qCDebug(LOG_ESM) << "Source" << source; - if (source == QString("gpu/temperature")) { - float value = 0.0; - if ((m_device != QString("nvidia")) && (m_device != QString("ati"))) - return value; - // build cmd - QString cmd = m_device == QString("nvidia") - ? QString("nvidia-smi -q -x") - : QString("aticonfig --od-gettemperature"); - qCInfo(LOG_ESM) << "cmd" << cmd; - TaskResult process = runTask(cmd); - qCInfo(LOG_ESM) << "Cmd returns" << process.exitCode; - qCInfo(LOG_ESM) << "Error" << process.error; - // parse - QString qoutput - = QTextCodec::codecForMib(106)->toUnicode(process.output).trimmed(); - if (m_device == QString("nvidia")) { - for (auto str : - qoutput.split(QChar('\n'), QString::SkipEmptyParts)) { - if (!str.contains(QString(""))) - continue; - QString temp = str.remove(QString("")) - .remove(QString("C")); - value = temp.toFloat(); - break; - } - } else if (m_device == QString("ati")) { - for (auto str : - qoutput.split(QChar('\n'), QString::SkipEmptyParts)) { - if (!str.contains(QString("Temperature"))) - continue; - QString temp - = str.split(QChar(' '), QString::SkipEmptyParts).at(4); - value = temp.toFloat(); - break; - } - } - // return - return value; - } + if (source == QString("gpu/temperature")) + run(); - return QVariant(); + return m_value; } @@ -107,6 +80,20 @@ QVariantMap GPUTemperatureSource::initialData(QString source) const } +void GPUTemperatureSource::run() +{ + if ((m_device != QString("nvidia")) && (m_device != QString("ati"))) + return; + // build cmd + QString cmd = m_device == QString("nvidia") + ? QString("nvidia-smi -q -x") + : QString("aticonfig --od-gettemperature"); + qCInfo(LOG_ESM) << "cmd" << cmd; + + m_process->start(cmd); +} + + QStringList GPUTemperatureSource::sources() const { QStringList sources; @@ -114,3 +101,36 @@ QStringList GPUTemperatureSource::sources() const return sources; } + + +void GPUTemperatureSource::updateValue() +{ + qCInfo(LOG_LIB) << "Cmd returns" << m_process->exitCode(); + QString qdebug = QTextCodec::codecForMib(106) + ->toUnicode(m_process->readAllStandardError()) + .trimmed(); + qCInfo(LOG_LIB) << "Error" << qdebug; + QString qoutput = QTextCodec::codecForMib(106) + ->toUnicode(m_process->readAllStandardOutput()) + .trimmed(); + qCInfo(LOG_LIB) << "Output" << qoutput; + + if (m_device == QString("nvidia")) { + for (auto str : qoutput.split(QChar('\n'), QString::SkipEmptyParts)) { + if (!str.contains(QString(""))) + continue; + QString temp = str.remove(QString("")) + .remove(QString("C")); + m_value = temp.toFloat(); + break; + } + } else if (m_device == QString("ati")) { + for (auto str : qoutput.split(QChar('\n'), QString::SkipEmptyParts)) { + if (!str.contains(QString("Temperature"))) + continue; + QString temp = str.split(QChar(' '), QString::SkipEmptyParts).at(4); + m_value = temp.toFloat(); + break; + } + } +} diff --git a/sources/extsysmon/sources/gputempsource.h b/sources/extsysmon/sources/gputempsource.h index 3e62bad..fc2d7a0 100644 --- a/sources/extsysmon/sources/gputempsource.h +++ b/sources/extsysmon/sources/gputempsource.h @@ -23,6 +23,8 @@ #include "abstractextsysmonsource.h" +class QProcess; + class GPUTemperatureSource : public AbstractExtSysMonSource { public: @@ -30,12 +32,17 @@ public: virtual ~GPUTemperatureSource(); QVariant data(QString source); QVariantMap initialData(QString source) const; - void run(){}; + void run(); QStringList sources() const; +private slots: + void updateValue(); + private: // configuration and values QString m_device; + QProcess *m_process = nullptr; + QVariant m_value; }; diff --git a/sources/extsysmon/sources/hddtempsource.cpp b/sources/extsysmon/sources/hddtempsource.cpp index 92b9b22..b0774e1 100644 --- a/sources/extsysmon/sources/hddtempsource.cpp +++ b/sources/extsysmon/sources/hddtempsource.cpp @@ -18,10 +18,9 @@ #include "hddtempsource.h" +#include #include -#include - #include "awdebug.h" @@ -37,12 +36,29 @@ HDDTemperatureSource::HDDTemperatureSource(QObject *parent, m_smartctl = m_cmd.contains(QString("smartctl")); qCInfo(LOG_ESM) << "Parse as smartctl" << m_smartctl; + + for (auto device : m_devices) { + m_processes[device] = new QProcess(nullptr); + // fucking magic from http://doc.qt.io/qt-5/qprocess.html#finished + connect(m_processes[device], + static_cast( + &QProcess::finished), + [this, device](int, QProcess::ExitStatus) { + return updateValue(device); + }); + m_processes[device]->waitForFinished(0); + } } HDDTemperatureSource::~HDDTemperatureSource() { qCDebug(LOG_ESM) << __PRETTY_FUNCTION__; + + for (auto device : m_devices) { + m_processes[device]->kill(); + m_processes[device]->deleteLater(); + } } @@ -51,36 +67,11 @@ QVariant HDDTemperatureSource::data(QString source) qCDebug(LOG_ESM) << "Source" << source; QString device = source.remove(QString("hdd/temperature")); - float value = 0.0; // run cmd - TaskResult process = runTask(QString("%1 %2").arg(m_cmd).arg(device)); - qCInfo(LOG_ESM) << "Cmd returns" << process.exitCode; - qCInfo(LOG_ESM) << "Error" << process.error; + if (m_processes[device]->state() == QProcess::NotRunning) + m_processes[device]->start(QString("%1 %2").arg(m_cmd).arg(device)); - // parse - QString qoutput - = QTextCodec::codecForMib(106)->toUnicode(process.output).trimmed(); - if (m_smartctl) { - for (auto str : qoutput.split(QChar('\n'), QString::SkipEmptyParts)) { - if (!str.startsWith(QString("194"))) - continue; - if (str.split(QChar(' '), QString::SkipEmptyParts).count() < 9) - break; - value = str.split(QChar(' '), QString::SkipEmptyParts) - .at(9) - .toFloat(); - break; - } - } else { - if (qoutput.split(QChar(':'), QString::SkipEmptyParts).count() >= 3) { - QString temp - = qoutput.split(QChar(':'), QString::SkipEmptyParts).at(2); - temp.remove(QChar(0260)).remove(QChar('C')); - value = temp.toFloat(); - } - } - - return value; + return m_values[device]; } @@ -108,3 +99,42 @@ QStringList HDDTemperatureSource::sources() const return sources; } + + +void HDDTemperatureSource::updateValue(const QString &device) +{ + qCDebug(LOG_LIB) << "Called with device" << device; + + qCInfo(LOG_LIB) << "Cmd returns" << m_processes[device]->exitCode(); + QString qdebug + = QTextCodec::codecForMib(106) + ->toUnicode(m_processes[device]->readAllStandardError()) + .trimmed(); + qCInfo(LOG_LIB) << "Error" << qdebug; + QString qoutput + = QTextCodec::codecForMib(106) + ->toUnicode(m_processes[device]->readAllStandardOutput()) + .trimmed(); + qCInfo(LOG_LIB) << "Output" << qoutput; + + // parse + if (m_smartctl) { + for (auto str : qoutput.split(QChar('\n'), QString::SkipEmptyParts)) { + if (!str.startsWith(QString("194"))) + continue; + if (str.split(QChar(' '), QString::SkipEmptyParts).count() < 9) + continue; + m_values[device] = str.split(QChar(' '), QString::SkipEmptyParts) + .at(9) + .toFloat(); + break; + } + } else { + if (qoutput.split(QChar(':'), QString::SkipEmptyParts).count() >= 3) { + QString temp + = qoutput.split(QChar(':'), QString::SkipEmptyParts).at(2); + temp.remove(QChar(0260)).remove(QChar('C')); + m_values[device] = temp.toFloat(); + } + } +} diff --git a/sources/extsysmon/sources/hddtempsource.h b/sources/extsysmon/sources/hddtempsource.h index 0da6f31..ffc37b4 100644 --- a/sources/extsysmon/sources/hddtempsource.h +++ b/sources/extsysmon/sources/hddtempsource.h @@ -23,6 +23,8 @@ #include "abstractextsysmonsource.h" +class QProcess; + class HDDTemperatureSource : public AbstractExtSysMonSource { public: @@ -33,11 +35,17 @@ public: void run(){}; QStringList sources() const; +private slots: + void updateValue(const QString &device); + private: + // properties + QHash m_processes; // configuration and values QString m_cmd; QStringList m_devices; bool m_smartctl; + QHash m_values; }; diff --git a/sources/extsysmon/sources/playersource.cpp b/sources/extsysmon/sources/playersource.cpp index c580a2d..df832e1 100644 --- a/sources/extsysmon/sources/playersource.cpp +++ b/sources/extsysmon/sources/playersource.cpp @@ -22,10 +22,9 @@ #include #include #include +#include #include -#include - #include "awdebug.h" @@ -39,12 +38,24 @@ PlayerSource::PlayerSource(QObject *parent, const QStringList args) m_mpdAddress = QString("%1:%2").arg(args.at(1)).arg(args.at(2)); m_mpris = args.at(3); m_symbols = args.at(4).toInt(); + + m_mpdProcess = new QProcess(nullptr); + // fucking magic from http://doc.qt.io/qt-5/qprocess.html#finished + connect(m_mpdProcess, + static_cast( + &QProcess::finished), + [this](int, QProcess::ExitStatus) { return updateValue(); }); + m_mpdProcess->waitForFinished(0); + m_mpdCached = defaultInfo(); } PlayerSource::~PlayerSource() { qCDebug(LOG_ESM) << __PRETTY_FUNCTION__; + + m_mpdProcess->kill(); + m_mpdProcess->deleteLater(); } @@ -52,9 +63,10 @@ QVariant PlayerSource::data(QString source) { qCDebug(LOG_ESM) << "Source" << source; - if (source == QString("player/title")) + if (!m_values.contains(source)) run(); - return values[source]; + QVariant value = m_values.take(source); + return value; } @@ -151,33 +163,33 @@ void PlayerSource::run() // mpd QHash data = getPlayerMpdInfo(m_mpdAddress); for (auto key : data.keys()) - values[key] = data[key]; + m_values[key] = data[key]; } else if (m_player == QString("mpris")) { // players which supports mpris QString mpris = m_mpris == QString("auto") ? getAutoMpris() : m_mpris; QHash data = getPlayerMprisInfo(mpris); for (auto key : data.keys()) - values[key] = data[key]; + m_values[key] = data[key]; } // dymanic properties // solid - values[QString("player/salbum")] - = stripString(values[QString("player/album")].toString(), m_symbols); - values[QString("player/sartist")] - = stripString(values[QString("player/artist")].toString(), m_symbols); - values[QString("player/stitle")] - = stripString(values[QString("player/title")].toString(), m_symbols); + m_values[QString("player/salbum")] + = stripString(m_values[QString("player/album")].toString(), m_symbols); + m_values[QString("player/sartist")] + = stripString(m_values[QString("player/artist")].toString(), m_symbols); + m_values[QString("player/stitle")] + = stripString(m_values[QString("player/title")].toString(), m_symbols); // dynamic - values[QString("player/dalbum")] - = buildString(values[QString("player/dalbum")].toString(), - values[QString("player/album")].toString(), m_symbols); - values[QString("player/dartist")] - = buildString(values[QString("player/dartist")].toString(), - values[QString("player/artist")].toString(), m_symbols); - values[QString("player/dtitle")] - = buildString(values[QString("player/dtitle")].toString(), - values[QString("player/title")].toString(), m_symbols); + m_values[QString("player/dalbum")] + = buildString(m_values[QString("player/dalbum")].toString(), + m_values[QString("player/album")].toString(), m_symbols); + m_values[QString("player/dartist")] + = buildString(m_values[QString("player/dartist")].toString(), + m_values[QString("player/artist")].toString(), m_symbols); + m_values[QString("player/dtitle")] + = buildString(m_values[QString("player/dtitle")].toString(), + m_values[QString("player/title")].toString(), m_symbols); } @@ -200,6 +212,40 @@ QStringList PlayerSource::sources() const } +void PlayerSource::updateValue() +{ + qCInfo(LOG_LIB) << "Cmd returns" << m_mpdProcess->exitCode(); + QString qdebug = QTextCodec::codecForMib(106) + ->toUnicode(m_mpdProcess->readAllStandardError()) + .trimmed(); + qCInfo(LOG_LIB) << "Error" << qdebug; + QString qoutput = QTextCodec::codecForMib(106) + ->toUnicode(m_mpdProcess->readAllStandardOutput()) + .trimmed(); + qCInfo(LOG_LIB) << "Output" << qoutput; + + for (auto str : qoutput.split(QChar('\n'), QString::SkipEmptyParts)) { + if (str.split(QString(": "), QString::SkipEmptyParts).count() == 2) { + // "Metadata: data" + QString metadata = str.split(QString(": "), QString::SkipEmptyParts) + .first() + .toLower(); + QString data = str.split(QString(": "), QString::SkipEmptyParts) + .last() + .trimmed(); + // there are one more time... + if ((metadata == QString("time")) && (data.contains(QChar(':')))) { + QStringList times = data.split(QString(":")); + m_mpdCached[QString("player/duration")] = times.at(0).toInt(); + m_mpdCached[QString("player/progress")] = times.at(1).toInt(); + } else if (m_metadata.contains(metadata)) { + m_mpdCached[QString("player/%1").arg(metadata)] = data; + } + } + } +} + + QVariantHash PlayerSource::defaultInfo() const { QVariantHash info; @@ -238,40 +284,14 @@ QVariantHash PlayerSource::getPlayerMpdInfo(const QString mpdAddress) const { qCDebug(LOG_ESM) << "MPD" << mpdAddress; - QVariantHash info = defaultInfo(); - // build cmd QString cmd = QString("bash -c \"echo 'currentsong\nstatus\nclose' | curl " "--connect-timeout 1 -fsm 3 telnet://%1\"") .arg(mpdAddress); qCInfo(LOG_ESM) << "cmd" << cmd; - TaskResult process = runTask(cmd); - qCInfo(LOG_ESM) << "Cmd returns" << process.exitCode; - qCInfo(LOG_ESM) << "Error" << process.error; + m_mpdProcess->start(cmd); - QString qoutput - = QTextCodec::codecForMib(106)->toUnicode(process.output).trimmed(); - for (auto str : qoutput.split(QChar('\n'), QString::SkipEmptyParts)) { - if (str.split(QString(": "), QString::SkipEmptyParts).count() == 2) { - // "Metadata: data" - QString metadata = str.split(QString(": "), QString::SkipEmptyParts) - .first() - .toLower(); - QString data = str.split(QString(": "), QString::SkipEmptyParts) - .last() - .trimmed(); - // there are one more time... - if ((metadata == QString("time")) && (data.contains(QChar(':')))) { - QStringList times = data.split(QString(":")); - info[QString("player/duration")] = times.at(0).toInt(); - info[QString("player/progress")] = times.at(1).toInt(); - } else if (m_metadata.contains(metadata)) { - info[QString("player/%1").arg(metadata)] = data; - } - } - } - - return info; + return m_mpdCached; } @@ -350,11 +370,10 @@ QString PlayerSource::buildString(const QString current, const QString value, << "will be stripped after" << s; int index = value.indexOf(current); - if ((current.isEmpty()) || ((index + s + 1) > value.count())) { + if ((current.isEmpty()) || ((index + s + 1) > value.count())) return QString("%1").arg(value.left(s), s, QLatin1Char(' ')); - } else { + else return QString("%1").arg(value.mid(index + 1, s), s, QLatin1Char(' ')); - } } diff --git a/sources/extsysmon/sources/playersource.h b/sources/extsysmon/sources/playersource.h index 14904bd..0d8bbfc 100644 --- a/sources/extsysmon/sources/playersource.h +++ b/sources/extsysmon/sources/playersource.h @@ -23,6 +23,8 @@ #include "abstractextsysmonsource.h" +class QProcess; + class PlayerSource : public AbstractExtSysMonSource { public: @@ -33,6 +35,9 @@ public: void run(); QStringList sources() const; +private slots: + void updateValue(); + private: inline QVariantHash defaultInfo() const; QString getAutoMpris() const; @@ -44,13 +49,15 @@ private: QString stripString(const QString value, const int s) const; // configuration and values QString m_mpdAddress; + QVariantHash m_mpdCached; + QProcess *m_mpdProcess = nullptr; QString m_mpris; QString m_player; int m_symbols; QStringList m_metadata = QStringList() << QString("album") << QString("artist") << QString("title"); - QVariantHash values; + QVariantHash m_values; }; diff --git a/sources/extsysmon/sources/processessource.cpp b/sources/extsysmon/sources/processessource.cpp index 4f41cb9..6054909 100644 --- a/sources/extsysmon/sources/processessource.cpp +++ b/sources/extsysmon/sources/processessource.cpp @@ -41,9 +41,10 @@ QVariant ProcessesSource::data(QString source) { qCDebug(LOG_ESM) << "Source" << source; - if (source == QString("ps/running/count")) + if (!m_values.contains(source)) run(); - return values[source]; + QVariant value = m_values.take(source); + return value; } @@ -97,9 +98,9 @@ void ProcessesSource::run() running.append(cmdFile.readAll()); } - values[QString("ps/running/count")] = running.count(); - values[QString("ps/running/list")] = running; - values[QString("ps/total/count")] = directories.count(); + m_values[QString("ps/running/count")] = running.count(); + m_values[QString("ps/running/list")] = running; + m_values[QString("ps/total/count")] = directories.count(); } diff --git a/sources/extsysmon/sources/processessource.h b/sources/extsysmon/sources/processessource.h index e9e12df..3d7c3a3 100644 --- a/sources/extsysmon/sources/processessource.h +++ b/sources/extsysmon/sources/processessource.h @@ -35,7 +35,7 @@ public: private: // configuration and values - QVariantHash values; + QVariantHash m_values; }; diff --git a/sources/extsysmon/sources/quotessource.cpp b/sources/extsysmon/sources/quotessource.cpp index a9d8129..4a44b09 100644 --- a/sources/extsysmon/sources/quotessource.cpp +++ b/sources/extsysmon/sources/quotessource.cpp @@ -45,13 +45,15 @@ QVariant QuotesSource::data(QString source) { qCDebug(LOG_ESM) << "Source" << source; - if (source.startsWith(QString("quotes/percpricechg"))) { - QVariantHash data = extQuotes->itemByTagNumber(index(source))->run(); + int ind = index(source); + source.remove(QString("quotes/")); + if (!m_values.contains(source)) { + QVariantHash data = extQuotes->itemByTagNumber(ind)->run(); for (auto key : data.keys()) - values[key] = data[key]; + m_values[key] = data[key]; } - QString key = QString(source).remove(QString("quotes/")); - return values[key]; + QVariant value = m_values.take(source); + return value; } diff --git a/sources/extsysmon/sources/quotessource.h b/sources/extsysmon/sources/quotessource.h index 2dbc4c5..ae09f0b 100644 --- a/sources/extsysmon/sources/quotessource.h +++ b/sources/extsysmon/sources/quotessource.h @@ -41,7 +41,7 @@ private: // configuration and values ExtItemAggregator *extQuotes; QStringList m_sources; - QVariantHash values; + QVariantHash m_values; }; diff --git a/sources/extsysmon/sources/weathersource.cpp b/sources/extsysmon/sources/weathersource.cpp index 9a57851..910ad31 100644 --- a/sources/extsysmon/sources/weathersource.cpp +++ b/sources/extsysmon/sources/weathersource.cpp @@ -45,13 +45,15 @@ QVariant WeatherSource::data(QString source) { qCDebug(LOG_ESM) << "Source" << source; - if (source.startsWith(QString("weather/weatherId"))) { - QVariantHash data = extWeather->itemByTagNumber(index(source))->run(); + int ind = index(source); + source.remove(QString("weather/")); + if (!m_values.contains(source)) { + QVariantHash data = extWeather->itemByTagNumber(ind)->run(); for (auto key : data.keys()) - values[key] = data[key]; + m_values[key] = data[key]; } - QString key = QString(source).remove(QString("weather/")); - return values[key]; + QVariant value = m_values.take(source); + return value; } diff --git a/sources/extsysmon/sources/weathersource.h b/sources/extsysmon/sources/weathersource.h index 5132fff..50b9f83 100644 --- a/sources/extsysmon/sources/weathersource.h +++ b/sources/extsysmon/sources/weathersource.h @@ -41,7 +41,7 @@ private: // configuration and values ExtItemAggregator *extWeather; QStringList m_sources; - QVariantHash values; + QVariantHash m_values; }; diff --git a/sources/packages-recipe.cmake b/sources/packages-recipe.cmake index ba4e857..f133247 100644 --- a/sources/packages-recipe.cmake +++ b/sources/packages-recipe.cmake @@ -21,7 +21,7 @@ set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${CP set(CPACK_DEBIAN_PACKAGE_DEPENDS "plasma-framework") set(CPACK_DEBIAN_PACKAGE_DESCRIPTION "Collection of minimalistic Plasmoids which look like Awesome WM widgets (ex-PyTextMonitor)") set(CPACK_DEBIAN_PACKAGE_ENHANCES "mpd, smartmontools") -set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "https://arcanis.name/projects/awesome-widgets") +set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "https://arcanis.me/projects/awesome-widgets") set(CPACK_DEBIAN_PACKAGE_SECTION "KDE") # rpm specific @@ -30,7 +30,7 @@ set(CPACK_RPM_PACKAGE_GROUP "User Interface/Desktops") set(CPACK_RPM_PACKAGE_LICENSE "${PROJECT_LICENSE}") set(CPACK_RPM_PACKAGE_REQUIRES "plasma-framework") set(CPACK_RPM_PACKAGE_SUGGESTS "mpd, smartmontools") -set(CPACK_RPM_PACKAGE_URL "https://arcanis.name/projects/awesome-widgets") +set(CPACK_RPM_PACKAGE_URL "https://arcanis.me/projects/awesome-widgets") if (BUILD_DEB_PACKAGE OR BUILD_RPM_PACKAGE) include(CPack) diff --git a/sources/translations/awesome-widgets.pot b/sources/translations/awesome-widgets.pot index 437a528..699e068 100644 --- a/sources/translations/awesome-widgets.pot +++ b/sources/translations/awesome-widgets.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: https://github.com/arcan1s/awesome-widgets/issues\n" -"POT-Creation-Date: 2016-01-26 21:48+0300\n" +"POT-Creation-Date: 2016-02-15 11:43+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -56,6 +56,9 @@ msgstr "" msgid "Check updates on startup" msgstr "" +msgid "Optimize subscription" +msgstr "" + msgid "Widget height, px" msgstr "" @@ -323,7 +326,7 @@ msgid "Battery inactive color" msgstr "" msgid "" -"Detailed information may be found on project homepage" msgstr "" @@ -351,15 +354,15 @@ msgstr "" msgid "Weathers" msgstr "" +msgid "Functions" +msgstr "" + msgid "Add" msgstr "" msgid "Show value" msgstr "" -msgid "Add lambda" -msgstr "" - msgid "Edit bars" msgstr "" @@ -411,24 +414,6 @@ msgstr "" msgid "Select font" msgstr "" -msgid "You are using the actual version %1" -msgstr "" - -msgid "No new version found" -msgstr "" - -msgid "Current version : %1" -msgstr "" - -msgid "New version : %1" -msgstr "" - -msgid "Click \"Ok\" to download" -msgstr "" - -msgid "There are updates" -msgstr "" - msgid "AC online" msgstr "" @@ -456,6 +441,27 @@ msgstr "" msgid "KB/s" msgstr "" +msgid "Changelog of %1" +msgstr "" + +msgid "You are using the actual version %1" +msgstr "" + +msgid "No new version found" +msgstr "" + +msgid "Current version : %1" +msgstr "" + +msgid "New version : %1" +msgstr "" + +msgid "Click \"Ok\" to download" +msgstr "" + +msgid "There are updates" +msgstr "" + msgid "Copy" msgstr "" @@ -541,9 +547,18 @@ msgstr "" msgid "Use images" msgstr "" +msgid "Use custom formula" +msgstr "" + msgid "Value" msgstr "" +msgid "Max value" +msgstr "" + +msgid "Min value" +msgstr "" + msgid "Active color" msgstr "" diff --git a/sources/translations/en.po b/sources/translations/en.po index c40d104..f0cca3e 100644 --- a/sources/translations/en.po +++ b/sources/translations/en.po @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: https://github.com/arcan1s/awesome-widgets/issues\n" -"POT-Creation-Date: 2016-01-26 21:48+0300\n" -"PO-Revision-Date: 2016-01-26 21:48+0300\n" +"POT-Creation-Date: 2016-02-15 11:43+0300\n" +"PO-Revision-Date: 2016-02-15 11:43+0300\n" "Last-Translator: Evgeniy Alekseev \n" "Language-Team: English \n" "Language: ru\n" @@ -57,6 +57,9 @@ msgstr "Enable notifications" msgid "Check updates on startup" msgstr "Check updates on startup" +msgid "Optimize subscription" +msgstr "Optimize subscription" + msgid "Widget height, px" msgstr "Widget height, px" @@ -326,10 +329,10 @@ msgid "Battery inactive color" msgstr "Battery inactive color" msgid "" -"Detailed information may be found on project homepage" msgstr "" -"Detailed information may be found on project homepage" msgid "AC" @@ -356,15 +359,15 @@ msgstr "Upgrades" msgid "Weathers" msgstr "Weathers" +msgid "Functions" +msgstr "Functions" + msgid "Add" msgstr "Add" msgid "Show value" msgstr "Show value" -msgid "Add lambda" -msgstr "Add lambda" - msgid "Edit bars" msgstr "Edit bars" @@ -416,24 +419,6 @@ msgstr "Special thanks to %1" msgid "Select font" msgstr "Select font" -msgid "You are using the actual version %1" -msgstr "You are using the actual version %1" - -msgid "No new version found" -msgstr "No new version found" - -msgid "Current version : %1" -msgstr "Current version : %1" - -msgid "New version : %1" -msgstr "New version : %1" - -msgid "Click \"Ok\" to download" -msgstr "Click \"Ok\" to download" - -msgid "There are updates" -msgstr "There are updates" - msgid "AC online" msgstr "AC online" @@ -461,6 +446,27 @@ msgstr "MB/s" msgid "KB/s" msgstr "KB/s" +msgid "Changelog of %1" +msgstr "Changelog of %1" + +msgid "You are using the actual version %1" +msgstr "You are using the actual version %1" + +msgid "No new version found" +msgstr "No new version found" + +msgid "Current version : %1" +msgstr "Current version : %1" + +msgid "New version : %1" +msgstr "New version : %1" + +msgid "Click \"Ok\" to download" +msgstr "Click \"Ok\" to download" + +msgid "There are updates" +msgstr "There are updates" + msgid "Copy" msgstr "Copy" @@ -550,9 +556,18 @@ msgstr "Timestamp" msgid "Use images" msgstr "Use images" +msgid "Use custom formula" +msgstr "Use custom formula" + msgid "Value" msgstr "Value" +msgid "Max value" +msgstr "Max value" + +msgid "Min value" +msgstr "Min value" + msgid "Active color" msgstr "Active color" @@ -612,6 +627,9 @@ msgctxt "EMAIL OF TRANSLATORS" msgid "Your emails" msgstr "esalexeev@gmail.com" +#~ msgid "Add lambda" +#~ msgstr "Add lambda" + #~ msgid "Free space on %1 less than 10%" #~ msgstr "Free space on %1 less than 10%" diff --git a/sources/translations/es.po b/sources/translations/es.po index b1b6c63..c767368 100644 --- a/sources/translations/es.po +++ b/sources/translations/es.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: Awesome widgets\n" "Report-Msgid-Bugs-To: https://github.com/arcan1s/awesome-widgets/issues\n" -"POT-Creation-Date: 2016-01-26 21:48+0300\n" +"POT-Creation-Date: 2016-02-15 11:43+0300\n" "PO-Revision-Date: 2015-09-26 22:07+0000\n" "Last-Translator: Ernesto Avilés Vázquez \n" "Language-Team: Spanish (http://www.transifex.com/arcanis/awesome-widgets/" @@ -59,6 +59,9 @@ msgstr "Habilitar notificaciones" msgid "Check updates on startup" msgstr "Comprobar actualizaciones al inicio" +msgid "Optimize subscription" +msgstr "" + msgid "Widget height, px" msgstr "Alto del widget, px" @@ -331,10 +334,10 @@ msgid "Battery inactive color" msgstr "Color de la batería inactiva" msgid "" -"Detailed information may be found on project homepage" msgstr "" -"Puedes encontrar información detallada en el sitio del proyecto" msgid "AC" @@ -361,15 +364,15 @@ msgstr "Actualizaciones" msgid "Weathers" msgstr "Tiempo" +msgid "Functions" +msgstr "" + msgid "Add" msgstr "Añadir" msgid "Show value" msgstr "Mostrar valor" -msgid "Add lambda" -msgstr "Añadir lambda" - msgid "Edit bars" msgstr "Editar barras" @@ -421,24 +424,6 @@ msgstr "" msgid "Select font" msgstr "Elegir tipo de letra" -msgid "You are using the actual version %1" -msgstr "Estás usando al versión actual %1" - -msgid "No new version found" -msgstr "No se encontraron nuevas versiones" - -msgid "Current version : %1" -msgstr "Versión actual: %1" - -msgid "New version : %1" -msgstr "Nueva versión: %1" - -msgid "Click \"Ok\" to download" -msgstr "Haz clic en «Ok» para descargar" - -msgid "There are updates" -msgstr "Hay actualizaciones disponibles" - msgid "AC online" msgstr "Alimentación conectada" @@ -466,6 +451,27 @@ msgstr "MB/s" msgid "KB/s" msgstr "KB/s" +msgid "Changelog of %1" +msgstr "" + +msgid "You are using the actual version %1" +msgstr "Estás usando al versión actual %1" + +msgid "No new version found" +msgstr "No se encontraron nuevas versiones" + +msgid "Current version : %1" +msgstr "Versión actual: %1" + +msgid "New version : %1" +msgstr "Nueva versión: %1" + +msgid "Click \"Ok\" to download" +msgstr "Haz clic en «Ok» para descargar" + +msgid "There are updates" +msgstr "Hay actualizaciones disponibles" + msgid "Copy" msgstr "Copiar" @@ -555,9 +561,21 @@ msgstr "Marca de tiempo" msgid "Use images" msgstr "Usar imágenes" +#, fuzzy +msgid "Use custom formula" +msgstr "Formato personalizado de hora" + msgid "Value" msgstr "Valor" +#, fuzzy +msgid "Max value" +msgstr "Mostrar valor" + +#, fuzzy +msgid "Min value" +msgstr "Mostrar valor" + msgid "Active color" msgstr "Color de activo" @@ -616,3 +634,6 @@ msgstr "Tu nombre" msgctxt "EMAIL OF TRANSLATORS" msgid "Your emails" msgstr "Tu correo electrónico" + +#~ msgid "Add lambda" +#~ msgstr "Añadir lambda" diff --git a/sources/translations/fr.po b/sources/translations/fr.po index 34ddcf5..9232c36 100644 --- a/sources/translations/fr.po +++ b/sources/translations/fr.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: https://github.com/arcan1s/awesome-widgets/issues\n" -"POT-Creation-Date: 2016-01-26 21:48+0300\n" +"POT-Creation-Date: 2016-02-15 11:43+0300\n" "PO-Revision-Date: 2015-07-31 22:16+0300\n" "Last-Translator: Evgeniy Alekseev \n" "Language-Team: French \n" @@ -61,6 +61,9 @@ msgstr "Activer les notifications" msgid "Check updates on startup" msgstr "Vérifier les mises à jour" +msgid "Optimize subscription" +msgstr "" + msgid "Widget height, px" msgstr "Paramètres du composant" @@ -337,10 +340,10 @@ msgid "Battery inactive color" msgstr "Couleur batterie inactive" msgid "" -"Detailed information may be found on project homepage" msgstr "" -"D'avantage d'informations se trouvent sur la page du projet" msgid "AC" @@ -371,15 +374,15 @@ msgstr "" msgid "Weathers" msgstr "Modifier les tickers" +msgid "Functions" +msgstr "" + msgid "Add" msgstr "Ajouter" msgid "Show value" msgstr "Afficher la valeur" -msgid "Add lambda" -msgstr "" - msgid "Edit bars" msgstr "Modifier les barres" @@ -431,27 +434,6 @@ msgstr "" msgid "Select font" msgstr "Sélectionner une couleur" -msgid "You are using the actual version %1" -msgstr "" - -#, fuzzy -msgid "No new version found" -msgstr "Nouvelle version" - -#, fuzzy -msgid "Current version : %1" -msgstr "Version actuelle" - -#, fuzzy -msgid "New version : %1" -msgstr "Nouvelle version" - -msgid "Click \"Ok\" to download" -msgstr "Cliquer sur \"Valider\" pour télécharger" - -msgid "There are updates" -msgstr "Des mises à jour sont disponibles" - msgid "AC online" msgstr "Alimentation branchée" @@ -479,6 +461,30 @@ msgstr "" msgid "KB/s" msgstr "" +msgid "Changelog of %1" +msgstr "" + +msgid "You are using the actual version %1" +msgstr "" + +#, fuzzy +msgid "No new version found" +msgstr "Nouvelle version" + +#, fuzzy +msgid "Current version : %1" +msgstr "Version actuelle" + +#, fuzzy +msgid "New version : %1" +msgstr "Nouvelle version" + +msgid "Click \"Ok\" to download" +msgstr "Cliquer sur \"Valider\" pour télécharger" + +msgid "There are updates" +msgstr "Des mises à jour sont disponibles" + msgid "Copy" msgstr "Copier" @@ -573,10 +579,22 @@ msgstr "Durée" msgid "Use images" msgstr "" +#, fuzzy +msgid "Use custom formula" +msgstr "Format de l'heure personnalisé" + #, fuzzy msgid "Value" msgstr "Valeur: %1" +#, fuzzy +msgid "Max value" +msgstr "Afficher la valeur" + +#, fuzzy +msgid "Min value" +msgstr "Afficher la valeur" + #, fuzzy msgid "Active color" msgstr "Batterie" diff --git a/sources/translations/nl.po b/sources/translations/nl.po index 9c4a562..930424b 100644 --- a/sources/translations/nl.po +++ b/sources/translations/nl.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Awesome widgets\n" "Report-Msgid-Bugs-To: https://github.com/arcan1s/awesome-widgets/issues\n" -"POT-Creation-Date: 2016-01-26 21:48+0300\n" +"POT-Creation-Date: 2016-02-15 11:43+0300\n" "PO-Revision-Date: 2015-08-20 22:52+0300\n" "Last-Translator: Evgeniy Alekseev \n" "Language-Team: Dutch \n" @@ -61,6 +61,9 @@ msgstr "" msgid "Check updates on startup" msgstr "Controleren op updates" +msgid "Optimize subscription" +msgstr "" + msgid "Widget height, px" msgstr "" @@ -341,7 +344,7 @@ msgid "Battery inactive color" msgstr "Kleur van inactieve accu" msgid "" -"Detailed information may be found on project homepage" msgstr "" "Gedetailleerde informatie kan worden gevonden op de , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: https://github.com/arcan1s/awesome-widgets/issues\n" +"POT-Creation-Date: 2016-01-26 21:48+0300\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "Widget" +msgstr "Widżet" + +msgid "Advanced" +msgstr "Zaawansowany" + +msgid "Tooltip" +msgstr "Podpowiedź" + +msgid "Appearance" +msgstr "Wygląd" + +msgid "DataEngine" +msgstr "Silnik danych" + +msgid "About" +msgstr "O..." + +msgid "Acknowledgment" +msgstr "Potwierdzenie" + +msgid "Enable background" +msgstr "Włącz tło" + +msgid "Translate strings" +msgstr "Tłumacz napisy" + +msgid "Wrap new lines" +msgstr "Zawijaj nowe linie" + +msgid "Enable word wrap" +msgstr "Włącz zawijanie linii" + +msgid "Enable notifications" +msgstr "Włącz powiadomienia" + +msgid "Check updates on startup" +msgstr "Sprawdź aktualizacje przy uruchomieniu" + +msgid "Widget height, px" +msgstr "Wysokość widżetu, px" + +msgid "Widget width, px" +msgstr "Szerokość widżetu, px" + +msgid "Time interval" +msgstr "Przedział czasowy" + +msgid "Messages queue limit" +msgstr "Limit kolejki wiadomości" + +msgid "Temperature units" +msgstr "Jednostki temperatury" + +msgid "Celsius" +msgstr "Celsius" + +msgid "Fahrenheit" +msgstr "Fahrenheit" + +msgid "Kelvin" +msgstr "Kelvin" + +msgid "Reaumur" +msgstr "Reaumur" + +msgid "cm^-1" +msgstr "cm^-1" + +msgid "kJ/mol" +msgstr "kJ/mol" + +msgid "kcal/mol" +msgstr "kcal/mol" + +msgid "Custom time format" +msgstr "Twój format czasu" + +msgid "Custom uptime format" +msgstr "Twój format czasu działania" + +msgid "AC online tag" +msgstr "Znacznik właczonego zasilania" + +msgid "AC offline tag" +msgstr "Znacznik wyłączonego zasilania" + +msgid "Drop key cache" +msgstr "Wyczyść cache klawiatury" + +msgid "Export configuration" +msgstr "Zapisz konfigurację" + +msgid "Export" +msgstr "Eksport" + +msgid "Success" +msgstr "Sukces" + +msgid "Please note that binary files were not copied" +msgstr "Zapamiętaj sobie że te binarne pliki skopiowanie nie zostały" + +msgid "Ooops..." +msgstr "Pizło..." + +msgid "Could not save configuration file" +msgstr "Nie mogę zapisać pliku konfiguracji" + +msgid "Import configuration" +msgstr "Załaduj konfigurację" + +msgid "Import" +msgstr "Import" + +msgid "Import plasmoid settings" +msgstr "Załaduj ustawnienai plasmoidu" + +msgid "Import extensions" +msgstr "Załaduj rozszerzenia" + +msgid "Import additional files" +msgstr "Załaduj pliki dodatkowe" + +msgid "Font" +msgstr "Czcionka" + +msgid "Font size" +msgstr "Rozmiar czcionki" + +msgid "Font weight" +msgstr "Ciężar czcionki" + +msgid "light" +msgstr "lekka" + +msgid "normal" +msgstr "normalna" + +msgid "demi bold" +msgstr "pogrubiona" + +msgid "bold" +msgstr "gruba" + +msgid "black" +msgstr "opasła" + +msgid "Font style" +msgstr "Styl czcionki" + +msgid "italic" +msgstr "pochylona" + +msgid "Font color" +msgstr "Kolor czcionki" + +msgid "Select a color" +msgstr "Wybierz kolor" + +msgid "Select a font" +msgstr "Wybierz czcionkę" + +msgid "ACPI" +msgstr "ACPI" + +msgid "ACPI path" +msgstr "Ścieżka ACPI" + +msgid "GPU" +msgstr "GPU" + +msgid "GPU device" +msgstr "Urządzenie GPU" + +msgid "HDD temperature" +msgstr "Temperatura twardego dysku" + +msgid "HDD" +msgstr "Twardy dysk" + +msgid "hddtemp cmd" +msgstr "hddtemp cmd" + +msgid "Player" +msgstr "Odtwarzacz" + +msgid "Player data symbols" +msgstr "Symbole odtwarzacza" + +msgid "Music player" +msgstr "Odtwarzacz muzyczny" + +msgid "MPRIS player name" +msgstr "Nazwa odtwarzacza MPRIS" + +msgid "MPD address" +msgstr "Adres MPD" + +msgid "MPD port" +msgstr "Port MPD" + +msgid "Extensions" +msgstr "Rozszerzenia" + +msgid "Custom scripts" +msgstr "Skrypty własne" + +msgid "Edit scripts" +msgstr "Edytuj skrypty" + +msgid "Quotes monitor" +msgstr "Monitor wielkości zapisu" + +msgid "Edit tickers" +msgstr "Eytuj znaczniki" + +msgid "Package manager" +msgstr "Zarządca pakietów" + +msgid "Edit command" +msgstr "Polecenie edycji" + +msgid "Weather" +msgstr "Pogoda" + +msgid "Edit weather" +msgstr "Edytuj pogodę" + +msgid "Select tag" +msgstr "Wybierz znacznik" + +msgid "Tag: %1" +msgstr "Znacznik: %1" + +msgid "Value: %1" +msgstr "Wartość: %1" + +msgid "Info: %1" +msgstr "Info: %1" + +msgid "Request key" +msgstr "Zarządaj klawisza" + +msgid "Show README" +msgstr "Pokaż README" + +msgid "Check updates" +msgstr "Sprawdź aktualizacje" + +msgid "" +"CPU, CPU clock, memory, swap and network labels support graphical tooltip. " +"To enable them just make needed checkbox checked." +msgstr "CPU, zegar CPU, pamięć, opisy swap i sieci obsługują podpowiedź graficzną." +"Aby je włączyć po prostu zaznacz odpowiednią opcję." + +msgid "Number of values for tooltips" +msgstr "Ilość wartości dla podpowiedzi" + +msgid "Background" +msgstr "Tło" + +msgid "Background color" +msgstr "Kolor tła" + +msgid "CPU" +msgstr "Procesor" + +msgid "CPU color" +msgstr "Kolor procesora" + +msgid "CPU clock" +msgstr "Zegar procesora" + +msgid "CPU clock color" +msgstr "KOlor zegara procesora" + +msgid "Memory" +msgstr "Pamięć" + +msgid "Memory color" +msgstr "Kolor pamięci" + +msgid "Swap" +msgstr "Swap" + +msgid "Swap color" +msgstr "Kolor pamięci swap" + +msgid "Network" +msgstr "Sieć" + +msgid "Download speed color" +msgstr "Kolor prędkości pobierania" + +msgid "Upload speed color" +msgstr "Kolor prędkości wysyłania" + +msgid "Battery" +msgstr "Bateria" + +msgid "Battery active color" +msgstr "Kolor baterii aktywnej" + +msgid "Battery inactive color" +msgstr "Kolor baterii nie aktywnej" + +msgid "" +"Detailed information may be found on project homepage" +msgstr "Szczegóły znajdziesz na stronie projektu" + +msgid "AC" +msgstr "Zasialnie zewnętrzne" + +msgid "Bars" +msgstr "Paski postępu" + +msgid "Desktops" +msgstr "Pulpity" + +msgid "Scripts" +msgstr "Skrypty" + +msgid "Time" +msgstr "Czas" + +msgid "Quotes" +msgstr "Ograniczenia" + +msgid "Upgrades" +msgstr "Aktualizacje" + +msgid "Weathers" +msgstr "Pogoda" + +msgid "Add" +msgstr "Dodaj" + +msgid "Show value" +msgstr "Pokaż wartość" + +msgid "Add lambda" +msgstr "Dodaj różnicę" + +msgid "Edit bars" +msgstr "Edytuj paski postępu" + +msgid "Preview" +msgstr "Przegląd" + +msgid "Run %1" +msgstr "Wykonać %1" + +msgid "Version %1 (build date %2)" +msgstr "Wersja %1 (data budowy %2)" + +msgid "A set of minimalistic plasmoid widgets" +msgstr "Zestaw minimalistycznych widżetów plasmy" + +msgid "Links:" +msgstr "Links: " + +msgid "Homepage" +msgstr "Strona domowa" + +msgid "Repository" +msgstr "Repozytorium" + +msgid "Bugtracker" +msgstr "Zgłasanie błędów" + +msgid "Translation issue" +msgstr "Tłumaczenie" + +msgid "AUR packages" +msgstr "Pakiety AUR" + +msgid "openSUSE packages" +msgstr "Pakiety openSUSE" + +msgid "This software is licensed under %1" +msgstr "To oprogramowanie jest licencjonowane według %1" + +msgid "Translators: %1" +msgstr "Tłumacze: %1" + +msgid "This software uses: %1" +msgstr "Używa tego: %1" + +msgid "Special thanks to %1" +msgstr "Specjalnie podziękowania dla %1" + +msgid "Select font" +msgstr "Wybierz czcionkę" + +msgid "You are using the actual version %1" +msgstr "Używasz wersji %1" + +msgid "No new version found" +msgstr "Nie znalazłem nowszej wersji" + +msgid "Current version : %1" +msgstr "Aktualna wersja: %1" + +msgid "New version : %1" +msgstr "Nowa wersja: %$1" + +msgid "Click \"Ok\" to download" +msgstr "Kliknij \"Ok\" aby pobrać" + +msgid "There are updates" +msgstr "Aktualizacje są" + +msgid "AC online" +msgstr "Zasilanie zewnętrzne podłączone" + +msgid "AC offline" +msgstr "Zasilanie zewnętrzne odłaczone" + +msgid "High CPU load" +msgstr "Wysokie obciążenie procesora" + +msgid "High memory usage" +msgstr "Wyskoie zużycie pamięci" + +msgid "Swap is used" +msgstr "Swap w użyciu" + +msgid "High GPU load" +msgstr "Wysokie obciążenie procesora graficznego" + +msgid "Network device has been changed to %1" +msgstr "Urządznie sieciowe zamienione na %1" + +msgid "MB/s" +msgstr "MB/s" + +msgid "KB/s" +msgstr "KB/s" + +msgid "Copy" +msgstr "Kopiuj" + +msgid "Create" +msgstr "Twórz" + +msgid "Remove" +msgstr "Usuń" + +msgid "Enter file name" +msgstr "Wpisz nazwę pliku" + +msgid "File name" +msgstr "Nazwa pliku" + +msgid "Name: %1" +msgstr "Nazwa: %1" + +msgid "Comment: %1" +msgstr "Komentarz: %1" + +msgid "Identity: %1" +msgstr "Tożsamość: %1" + +msgid "Name" +msgstr "Nazwa" + +msgid "Comment" +msgstr "Komentarz" + +msgid "Tag" +msgstr "Znacznik" + +msgid "" +"

Use YAHOO! finance ticker to get quotes for the " +"instrument. Refer to http://finance.yahoo.com/

" +msgstr "" +"

Użyj usług finansowych YAHOO!" +"Przjdź na http://finance.yahoo.com/

" + +msgid "Ticker" +msgstr "Znacznik czasowy" + +msgid "Active" +msgstr "Aktywny" + +msgid "Interval" +msgstr "Przedział" + +msgid "Command" +msgstr "Polecenie" + +msgid "Prefix" +msgstr "Prefiks" + +msgid "Redirect" +msgstr "Przenieś" + +msgid "Additional filters" +msgstr "Dodatkowe filtry" + +msgid "Wrap colors" +msgstr "Kolory oblewania" + +msgid "Wrap spaces" +msgstr "Oblewanie tekstu" + +msgid "Filter" +msgstr "Filtr" + +msgid "Null" +msgstr "Null" + +msgid "City" +msgstr "Miasto" + +msgid "Country" +msgstr "Kraj" + +msgid "Timestamp" +msgstr "Znacznik czasu" + +msgid "Use images" +msgstr "Użyj obrazków" + +msgid "Value" +msgstr "Wartość" + +msgid "Active color" +msgstr "Kolor aktywnego" + +msgid "Inactive color" +msgstr "Kolor nieaktywnego" + +msgid "Type" +msgstr "Typ" + +msgid "Direction" +msgstr "Kierunek" + +msgid "Height" +msgstr "Wysokość" + +msgid "Width" +msgstr "Szerokość" + +msgid "Active desktop" +msgstr "AKtywny pulpit" + +msgid "Inactive desktop" +msgstr "Nie aktywny pulpit" + +msgid "Vertical layout" +msgstr "Ułożenie pionowe" + +msgid "Mark" +msgstr "Znak" + +msgid "Tooltip type" +msgstr "Rodzaj podpowiedzi" + +msgid "contours" +msgstr "kontury" + +msgid "windows" +msgstr "okienka" + +msgid "clean desktop" +msgstr "czysty pulpit" + +msgid "names" +msgstr "nazwy" + +msgid "none" +msgstr "nie" + +msgid "Tooltip width" +msgstr "Szerokość podpowiedzi" + +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Terminus" + +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "terminus@linux.pl" diff --git a/sources/translations/pt_BR.po b/sources/translations/pt_BR.po index 9cb71f1..f25123e 100644 --- a/sources/translations/pt_BR.po +++ b/sources/translations/pt_BR.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: https://github.com/arcan1s/awesome-widgets/issues\n" -"POT-Creation-Date: 2016-01-26 21:48+0300\n" +"POT-Creation-Date: 2016-02-15 11:43+0300\n" "PO-Revision-Date: 2015-07-31 22:21+0300\n" "Last-Translator: Evgeniy Alekseev \n" "Language-Team: Russian \n" @@ -60,6 +60,9 @@ msgstr "Ativar notificações" msgid "Check updates on startup" msgstr "Checar por atualizações" +msgid "Optimize subscription" +msgstr "" + msgid "Widget height, px" msgstr "Altura do widget, px" @@ -338,7 +341,7 @@ msgid "Battery inactive color" msgstr "Cor da bateria inativa" msgid "" -"Detailed information may be found on project homepage" msgstr "" "Informações detalhadas podem ser encontradas na \n" "Language-Team: Russian \n" "Language: ru\n" @@ -57,6 +57,9 @@ msgstr "Включить уведомления " msgid "Check updates on startup" msgstr "Проверять обновления при запуске" +msgid "Optimize subscription" +msgstr "Оптимизировать подписку" + msgid "Widget height, px" msgstr "Высота виджета, пиксели" @@ -326,10 +329,10 @@ msgid "Battery inactive color" msgstr "Цвет разряжаемой батареи" msgid "" -"Detailed information may be found on project homepage" msgstr "" -"Подробная информация может быть найдена на домашней странице проекта" msgid "AC" @@ -356,15 +359,15 @@ msgstr "Обновления" msgid "Weathers" msgstr "Погода" +msgid "Functions" +msgstr "Функции" + msgid "Add" msgstr "Добавить" msgid "Show value" msgstr "Показать значение" -msgid "Add lambda" -msgstr "Добавить лямбду" - msgid "Edit bars" msgstr "Редактировать бары" @@ -411,29 +414,11 @@ msgid "This software uses: %1" msgstr "Данное приложение использует: %1" msgid "Special thanks to %1" -msgstr "Отдельно спасибо %1" +msgstr "Отдельное спасибо %1" msgid "Select font" msgstr "Выберете шрифт" -msgid "You are using the actual version %1" -msgstr "Вы используете актуальную версию %1" - -msgid "No new version found" -msgstr "Обновления не найдены" - -msgid "Current version : %1" -msgstr "Текущая версия : %1" - -msgid "New version : %1" -msgstr "Новая версия : %1" - -msgid "Click \"Ok\" to download" -msgstr "Нажмите \"Ok\" для загрузки" - -msgid "There are updates" -msgstr "Найдены обновления" - msgid "AC online" msgstr "AC подключен" @@ -461,6 +446,27 @@ msgstr "МБ/с" msgid "KB/s" msgstr "КБ/с" +msgid "Changelog of %1" +msgstr "Список изменений %1" + +msgid "You are using the actual version %1" +msgstr "Вы используете актуальную версию %1" + +msgid "No new version found" +msgstr "Обновления не найдены" + +msgid "Current version : %1" +msgstr "Текущая версия : %1" + +msgid "New version : %1" +msgstr "Новая версия : %1" + +msgid "Click \"Ok\" to download" +msgstr "Нажмите \"Ok\" для загрузки" + +msgid "There are updates" +msgstr "Найдены обновления" + msgid "Copy" msgstr "Копировать" @@ -550,9 +556,18 @@ msgstr "Таймштамп" msgid "Use images" msgstr "Использовать изображения" +msgid "Use custom formula" +msgstr "Использовать свою формулу" + msgid "Value" msgstr "Значение" +msgid "Max value" +msgstr "Максимальное значение" + +msgid "Min value" +msgstr "Минимальное значение" + msgid "Active color" msgstr "Активный цвет" @@ -612,6 +627,9 @@ msgctxt "EMAIL OF TRANSLATORS" msgid "Your emails" msgstr "esalexeev@gmail.com" +#~ msgid "Add lambda" +#~ msgstr "Добавить лямбду" + #~ msgid "Free space on %1 less than 10%" #~ msgstr "Свободное место на диске %1 меньше 10%" diff --git a/sources/translations/uk.po b/sources/translations/uk.po index 330f72e..db3932a 100644 --- a/sources/translations/uk.po +++ b/sources/translations/uk.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: https://github.com/arcan1s/awesome-widgets/issues\n" -"POT-Creation-Date: 2016-01-26 21:48+0300\n" +"POT-Creation-Date: 2016-02-15 11:43+0300\n" "PO-Revision-Date: 2015-09-27 12:37+0300\n" "Last-Translator: Evgeniy Alekseev \n" "Language-Team: Ukrainian \n" @@ -59,6 +59,9 @@ msgstr "Включити повідомлення" msgid "Check updates on startup" msgstr "Перевіряти оновлення при запуску" +msgid "Optimize subscription" +msgstr "" + msgid "Widget height, px" msgstr "Висота віджету, пікселі" @@ -340,10 +343,10 @@ msgid "Battery inactive color" msgstr "Колір батарєї, що розряджається" msgid "" -"Detailed information may be found on project homepage" msgstr "" -"Детальна інформація може бути знайдена на домашній сторінці проекту" msgid "AC" @@ -374,15 +377,15 @@ msgstr "Оновлення" msgid "Weathers" msgstr "Погода" +msgid "Functions" +msgstr "" + msgid "Add" msgstr "Додати" msgid "Show value" msgstr "Показати значення" -msgid "Add lambda" -msgstr "Додати лямбду" - msgid "Edit bars" msgstr "Редагувати бари" @@ -434,25 +437,6 @@ msgstr "" msgid "Select font" msgstr "Оберіть шрифт" -msgid "You are using the actual version %1" -msgstr "Ви використовуєте актуальну версію %1" - -#, fuzzy -msgid "No new version found" -msgstr "Оновлень не знайдено" - -msgid "Current version : %1" -msgstr "Поточна версія : %1" - -msgid "New version : %1" -msgstr "Нова версія : %1" - -msgid "Click \"Ok\" to download" -msgstr "Натисніть \"Ok\" для завантаження" - -msgid "There are updates" -msgstr "Знайдені оновлення" - msgid "AC online" msgstr "AC підключений" @@ -480,6 +464,28 @@ msgstr "МБ/с" msgid "KB/s" msgstr "КБ/с" +msgid "Changelog of %1" +msgstr "" + +msgid "You are using the actual version %1" +msgstr "Ви використовуєте актуальну версію %1" + +#, fuzzy +msgid "No new version found" +msgstr "Оновлень не знайдено" + +msgid "Current version : %1" +msgstr "Поточна версія : %1" + +msgid "New version : %1" +msgstr "Нова версія : %1" + +msgid "Click \"Ok\" to download" +msgstr "Натисніть \"Ok\" для завантаження" + +msgid "There are updates" +msgstr "Знайдені оновлення" + msgid "Copy" msgstr "Копіювати" @@ -576,9 +582,21 @@ msgstr "Відмітка часу" msgid "Use images" msgstr "Використовувати зображення" +#, fuzzy +msgid "Use custom formula" +msgstr "Свій формат часу" + msgid "Value" msgstr "Значення" +#, fuzzy +msgid "Max value" +msgstr "Показати значення" + +#, fuzzy +msgid "Min value" +msgstr "Показати значення" + #, fuzzy msgid "Active color" msgstr "Активний колір" @@ -640,6 +658,9 @@ msgctxt "EMAIL OF TRANSLATORS" msgid "Your emails" msgstr "sarumyan@i.ua" +#~ msgid "Add lambda" +#~ msgstr "Додати лямбду" + #~ msgid "Free space on %1 less than 10%" #~ msgstr "Вільний простір на диску %1 меньше ніж 10%" diff --git a/sources/version.h.in b/sources/version.h.in index b9fdfb6..97bd9c7 100644 --- a/sources/version.h.in +++ b/sources/version.h.in @@ -7,15 +7,24 @@ #define VERSION "@PROJECT_VERSION@" #define COMMIT_SHA "@PROJECT_COMMIT_SHA@" #define AUTHOR "@PROJECT_AUTHOR@" -#define TRANSLATORS "Ernesto Aviles Vzqz (Spanish), Mermouy (French), underr (Brazillian Portuguese), Viktor Slobodyan (Ukrainian), Lemueler (Chinese), Heimen Stoffels (Dutch)" +#define TRANSLATORS \ + "Ernesto Aviles Vzqz (Spanish), Mermouy (French), underr (Brazillian " \ + "Portuguese), Viktor Slobodyan (Ukrainian), Lemueler (Chinese), Heimen " \ + "Stoffels (Dutch)" #define EMAIL "@PROJECT_CONTACT@" #define LICENSE "@PROJECT_LICENSE@" -#define TRDPARTY_LICENSE "tasks,BSD,https://github.com/mhogomchungu/tasks;QReplyTimeout wrapper,no,http://codereview.stackexchange.com/questions/30031/qnetworkreply-network-reply-timeout-helper" -#define SPECIAL_THANKS "Yahoo! Finance,https://finance.yahoo.com/;Yahoo! Weather,https://weather.yahoo.com/;JetBrains,https://www.jetbrains.com/" +#define TRDPARTY_LICENSE \ + "QReplyTimeout " \ + "wrapper,no,http://codereview.stackexchange.com/questions/30031/" \ + "qnetworkreply-network-reply-timeout-helper" +#define SPECIAL_THANKS \ + "Yahoo! Finance,https://finance.yahoo.com/;Yahoo! " \ + "Weather,https://weather.yahoo.com/;JetBrains,https://www.jetbrains.com/" +#define CHANGELOG "@PROJECT_CHANGELOG@" // configuraion // graphical items api version -#define AWGIAPI 3 +#define AWGIAPI 4 // extquotes api version #define AWEQAPI 3 // extscript api version @@ -27,18 +36,29 @@ // network requests timeout, ms #define REQUEST_TIMEOUT 5000 // available time keys -#define TIME_KEYS "dddd,ddd,dd,d,MMMM,MMM,MM,M,yyyy,yy,hh,h,HH,H,mm,m,ss,s,t,ap,a,AP,A" +#define TIME_KEYS \ + "dddd,ddd,dd,d,MMMM,MMM,MM,M,yyyy,yy,hh,h,HH,H,mm,m,ss,s,t,ap,a,AP,A" +// static keys +#define STATIC_KEYS \ + "time,isotime,shorttime,longtime,ctime,uptime,cuptime,cpucl,cpu,gputemp," \ + "gpu,memmb,memgb,memfreemb,memfreegb,memtotmb,memtotgb,memusedmb," \ + "memusedgb,mem,swapmb,swapgb,swapfreemb,swapfreegb,swaptotmb,swaptotgb," \ + "swap,downunits,upunits,downkb,down,upkb,up,netdev,ac,bat,album,artist," \ + "duration,progress,title,dalbum,dartist,dtitle,salbum,sartist,stitle," \ + "pscount,pstotal,ps,desktop,ndesktop,tdesktops,la15,la5,la1" #cmakedefine BUILD_FUTURE #cmakedefine BUILD_TESTING // links -#define HOMEPAGE "https://arcanis.name/projects/awesome-widgets/" +#define HOMEPAGE "https://arcanis.me/projects/awesome-widgets/" #define REPOSITORY "https://github.com/arcan1s/awesome-widgets" #define RELEASES "https://github.com/arcan1s/awesome-widgets/releases/tag/V." -#define VERSION_API "https://api.github.com/repos/arcan1s/awesome-widgets/releases" +#define VERSION_API \ + "https://api.github.com/repos/arcan1s/awesome-widgets/releases" #define BUGTRACKER "https://github.com/arcan1s/awesome-widgets/issues" #define TRANSLATION "https://github.com/arcan1s/awesome-widgets/issues/14" -#define AUR_PACKAGES "https://aur.archlinux.org/packages/plasma5-applet-awesome-widgets/" +#define AUR_PACKAGES \ + "https://aur.archlinux.org/packages/plasma5-applet-awesome-widgets/" #define OPENSUSE_PACKAGES "http://software.opensuse.org/package/awesome-widgets" // build information