diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt index 1d88cbf..4572f27 100644 --- a/modules/CMakeLists.txt +++ b/modules/CMakeLists.txt @@ -1,10 +1,12 @@ # Install the packages, also make it known to the system add_subdirectory(theme) if (${KF5KDELibs4Support_FOUND}) add_subdirectory(time) endif() # Power add_subdirectory(powermanagement) +# Info +add_subdirectory(info) diff --git a/modules/info/CMakeLists.txt b/modules/info/CMakeLists.txt new file mode 100644 index 0000000..2310c01 --- /dev/null +++ b/modules/info/CMakeLists.txt @@ -0,0 +1,25 @@ +set(info_SRCS # Specify source files for the library + info.cpp + distroinfo.cpp + softwareinfo.cpp + hardwareinfo.cpp +) + +add_library(kcm_mobile_info MODULE ${info_SRCS}) + +target_link_libraries(kcm_mobile_info + Qt5::Core + KF5::CoreAddons + KF5::I18n + KF5::QuickAddons + KF5::ConfigCore + KF5::Solid +) + +kcoreaddons_desktop_to_json(kcm_mobile_info "info.desktop") # Convert our desktop file to json + +install(TARGETS kcm_mobile_info DESTINATION ${KDE_INSTALL_PLUGINDIR}/kcms) # Install the library to the kcm location + +install(FILES info.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR}) # Install the desktop file +kpackage_install_package(package kcm_mobile_info kcms) # Finally install our QML kpackage. + diff --git a/modules/info/distroinfo.cpp b/modules/info/distroinfo.cpp new file mode 100644 index 0000000..4352241 --- /dev/null +++ b/modules/info/distroinfo.cpp @@ -0,0 +1,25 @@ +/* + * Copyright 2019 Jonah Brüchert + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License or (at your option) version 3 or any later version + * accepted by the membership of KDE e.V. (or its successor approved + * by the membership of KDE e.V.), which shall act as a proxy + * defined in Section 14 of version 3 of the license. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include "distroinfo.h" + +DistroInfo::DistroInfo() += default; diff --git a/modules/info/distroinfo.h b/modules/info/distroinfo.h new file mode 100644 index 0000000..a85b350 --- /dev/null +++ b/modules/info/distroinfo.h @@ -0,0 +1,96 @@ +/* + * Copyright 2019 Jonah Brüchert + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License or (at your option) version 3 or any later version + * accepted by the membership of KDE e.V. (or its successor approved + * by the membership of KDE e.V.), which shall act as a proxy + * defined in Section 14 of version 3 of the license. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include + +#define PROPERTY(type, name) \ + type name() const { return m_osrelease.name(); }\ + +#ifndef DISTROINFO_H +#define DISTROINFO_H + +class DistroInfo : public QObject +{ + Q_OBJECT + + Q_PROPERTY(QString name READ name CONSTANT) + PROPERTY(QString, name) + + Q_PROPERTY(QString version READ version CONSTANT) + PROPERTY(QString, version) + + Q_PROPERTY(QString id READ id CONSTANT) + PROPERTY(QString, id) + + Q_PROPERTY(QStringList idLike READ idLike CONSTANT) + PROPERTY(QStringList, idLike) + + Q_PROPERTY(QString versionCodename READ versionCodename CONSTANT) + PROPERTY(QString, versionCodename) + + Q_PROPERTY(QString versionId READ versionId CONSTANT) + PROPERTY(QString, versionId) + + Q_PROPERTY(QString prettyName READ prettyName CONSTANT) + PROPERTY(QString, prettyName) + + Q_PROPERTY(QString ansiColor READ ansiColor CONSTANT) + PROPERTY(QString, ansiColor) + + Q_PROPERTY(QString cpeName READ cpeName CONSTANT) + PROPERTY(QString, cpeName) + + Q_PROPERTY(QString homeUrl READ homeUrl CONSTANT) + PROPERTY(QString, homeUrl) + + Q_PROPERTY(QString documentationUrl READ documentationUrl CONSTANT) + PROPERTY(QString, documentationUrl) + + Q_PROPERTY(QString supportUrl READ supportUrl CONSTANT) + PROPERTY(QString, supportUrl) + + Q_PROPERTY(QString bugReportUrl READ bugReportUrl CONSTANT) + PROPERTY(QString, bugReportUrl) + + Q_PROPERTY(QString privacyPolicyUrl READ privacyPolicyUrl CONSTANT) + PROPERTY(QString, privacyPolicyUrl) + + Q_PROPERTY(QString buildId READ buildId CONSTANT) + PROPERTY(QString, buildId) + + Q_PROPERTY(QString variant READ variant CONSTANT) + PROPERTY(QString, variant) + + Q_PROPERTY(QString variantId READ variantId CONSTANT) + PROPERTY(QString, variantId) + + Q_PROPERTY(QString logo READ logo CONSTANT) + PROPERTY(QString, logo) + +public: + DistroInfo(); + +private: + KOSRelease m_osrelease; + +}; + +#endif // DISTROINFO_H diff --git a/modules/info/hardwareinfo.cpp b/modules/info/hardwareinfo.cpp new file mode 100644 index 0000000..1d648d5 --- /dev/null +++ b/modules/info/hardwareinfo.cpp @@ -0,0 +1,98 @@ +/* + * Copyright 2019 Jonah Brüchert + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License or (at your option) version 3 or any later version + * accepted by the membership of KDE e.V. (or its successor approved + * by the membership of KDE e.V.), which shall act as a proxy + * defined in Section 14 of version 3 of the license. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include "hardwareinfo.h" + +#include +#include + +#include +#include + +#include + +#ifdef Q_OS_LINUX +#include +#elif defined(Q_OS_FREEBSD) +#include +#include +#endif + +HardwareInfo::HardwareInfo() += default; + +int HardwareInfo::processorCount() const { + return Solid::Device::listFromType(Solid::DeviceInterface::Processor).count(); +} + +QString HardwareInfo::processors() const { + const auto list = Solid::Device::listFromType(Solid::DeviceInterface::Processor); + + // Format processor string + // Group by processor name + QMap processorMap; + for (const auto &device : list) { + const QString name = device.product(); + auto it = processorMap.find(name); + if (it == processorMap.end()) { + processorMap.insert(name, 1); + } else { + ++it.value(); + } + } + // Create a formatted list of grouped processors + QStringList names; + names.reserve(processorMap.count()); + for (auto it = processorMap.constBegin(); it != processorMap.constEnd(); ++it) { + const int count = it.value(); + QString name = it.key(); + name.replace(QStringLiteral("(TM)"), QChar(8482)); + name.replace(QStringLiteral("(R)"), QChar(174)); + name = name.simplified(); + names.append(QStringLiteral("%1 × %2").arg(count).arg(name)); + } + + const QString processorLabel = names.join(QLatin1String(", ")); + + return processorLabel; +} + +QString HardwareInfo::memory() const +{ + qlonglong totalRam = -1; +#ifdef Q_OS_LINUX + struct sysinfo info; + if (sysinfo(&info) == 0) + // manpage "sizes are given as multiples of mem_unit bytes" + totalRam = qlonglong(info.totalram) * info.mem_unit; +#elif defined(Q_OS_FREEBSD) + /* Stuff for sysctl */ + size_t len; + + unsigned long memory; + len = sizeof(memory); + sysctlbyname("hw.physmem", &memory, &len, NULL, 0); + + totalRam = memory; +#endif + + return KFormat().formatByteSize(totalRam); +} diff --git a/modules/info/hardwareinfo.h b/modules/info/hardwareinfo.h new file mode 100644 index 0000000..76699f8 --- /dev/null +++ b/modules/info/hardwareinfo.h @@ -0,0 +1,43 @@ +/* + * Copyright 2019 Jonah Brüchert + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License or (at your option) version 3 or any later version + * accepted by the membership of KDE e.V. (or its successor approved + * by the membership of KDE e.V.), which shall act as a proxy + * defined in Section 14 of version 3 of the license. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#ifndef HARDWAREINFO_H +#define HARDWAREINFO_H + +class HardwareInfo : public QObject +{ + Q_OBJECT + + Q_PROPERTY(QString processors READ processors CONSTANT) + QString processors() const; + + Q_PROPERTY(QString processorCount READ processorCount CONSTANT) + int processorCount() const; + + Q_PROPERTY(QString memory READ memory CONSTANT) + QString memory() const; + +public: + HardwareInfo(); +}; + +#endif // HARDWAREINFO_H diff --git a/modules/info/info.cpp b/modules/info/info.cpp new file mode 100644 index 0000000..7fba042 --- /dev/null +++ b/modules/info/info.cpp @@ -0,0 +1,68 @@ +/* + * Copyright 2019 Jonah Brüchert + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License or (at your option) version 3 or any later version + * accepted by the membership of KDE e.V. (or its successor approved + * by the membership of KDE e.V.), which shall act as a proxy + * defined in Section 14 of version 3 of the license. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "info.h" + +#include +#include +#include +#include +#include + + +K_PLUGIN_CLASS_WITH_JSON(Info, "info.json") + +Info::Info(QObject *parent, const QVariantList &args) + : KQuickAddons::ConfigModule(parent, args), + m_distroInfo(new DistroInfo), + m_softwareInfo(new SoftwareInfo), + m_hardwareInfo(new HardwareInfo) +{ + KAboutData* about = new KAboutData("kcm_mobile_info", i18n("Info"), + "1.0", QString(), KAboutLicense::LGPL); + about->addAuthor(i18n("Jonah Brüchert"), QString(), "jbb@kaidan.im"); + setAboutData(about); + setButtons(Apply | Default); + + qDebug() << "Info module loaded."; + +} + +void Info::copyToClipboard(const QString text) const +{ + QGuiApplication::clipboard()->setText(text); +} + +DistroInfo* Info::distroInfo() const +{ + return m_distroInfo; +} + +SoftwareInfo* Info::softwareInfo() const +{ + return m_softwareInfo; +} + +HardwareInfo* Info::hardwareInfo() const +{ + return m_hardwareInfo; +} + +#include "info.moc" diff --git a/modules/info/info.desktop b/modules/info/info.desktop new file mode 100644 index 0000000..f5231b5 --- /dev/null +++ b/modules/info/info.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Name=Info +Comment=About System +Type=Service +X-KDE-ServiceTypes=KCModule +X-KDE-Library=kcm_mobile_info +X-KDE-FormFactors=handset,tablet,mediacenter +Categories=Qt;KDE;X-KDE-settings-system; +X-KDE-Keywords=info, distro, system +X-KDE-ParentApp=kcontrol +Exec=plasma-settings -m kcm_mobile_info diff --git a/modules/info/info.h b/modules/info/info.h new file mode 100644 index 0000000..325f07a --- /dev/null +++ b/modules/info/info.h @@ -0,0 +1,56 @@ +/* + * Copyright 2019 Jonah Brüchert + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License or (at your option) version 3 or any later version + * accepted by the membership of KDE e.V. (or its successor approved + * by the membership of KDE e.V.), which shall act as a proxy + * defined in Section 14 of version 3 of the license. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include +#include "distroinfo.h" +#include "softwareinfo.h" +#include "hardwareinfo.h" + +#ifndef INFO_H +#define INFO_H + +class Info : public KQuickAddons::ConfigModule { + Q_OBJECT + + Q_PROPERTY(DistroInfo* distroInfo READ distroInfo NOTIFY distroInfoChanged) + Q_PROPERTY(SoftwareInfo* softwareInfo READ softwareInfo NOTIFY softwareInfoChanged) + Q_PROPERTY(HardwareInfo* hardwareInfo READ hardwareInfo NOTIFY hardwareInfoChanged) + DistroInfo* distroInfo() const; + SoftwareInfo* softwareInfo() const; + HardwareInfo* hardwareInfo() const; + +public: + Info(QObject* parent, const QVariantList& args); + + Q_INVOKABLE void copyToClipboard(const QString text) const; + +Q_SIGNALS: + void distroInfoChanged(); + void softwareInfoChanged(); + void hardwareInfoChanged(); + +private: + DistroInfo* m_distroInfo; + SoftwareInfo* m_softwareInfo; + HardwareInfo* m_hardwareInfo; +}; + +#endif // INFO_H diff --git a/modules/info/package/contents/ui/main.qml b/modules/info/package/contents/ui/main.qml new file mode 100644 index 0000000..0cb4fd6 --- /dev/null +++ b/modules/info/package/contents/ui/main.qml @@ -0,0 +1,125 @@ +import org.kde.kcm 1.2 as KCM +import QtQuick.Layouts 1.2 +import QtQuick 2.7 +import QtQuick.Controls 2.2 as Controls +import org.kde.kirigami 2.10 as Kirigami + +KCM.SimpleKCM { + title: i18n("Information About This System") + + Kirigami.Theme.colorSet: Kirigami.Theme.Window + + // This only works in plasma-settings + actions.contextualActions: [ + Kirigami.Action { + text: i18n("Copy to clipboard") + icon.name: "edit-copy" + onTriggered: copyInfoToClipboard() + } + ] + + function copyInfoToClipboard() { + var clipboardText = "" + + clipboardText += "Operating System " + kcm.distroInfo.name + "\n" + + clipboardText += "KDE Plasma Version: " + kcm.softwareInfo.plasmaVersion + "\n" + clipboardText += "KDE Frameworks Version: " + kcm.softwareInfo.frameworksVersion + "\n" + clipboardText += "Qt Version: " + kcm.softwareInfo.qtVersion + "\n" + clipboardText += "Kernel Version: " + kcm.softwareInfo.kernelRelease + "\n" + clipboardText += "OS-Type: " + kcm.softwareInfo.osType + "-bit\n" + + clipboardText += "Processor: " + kcm.hardwareInfo.processors + "\n" + clipboardText += "Memory: " + kcm.hardwareInfo.memory + "\n" + + kcm.copyToClipboard(clipboardText) + } + + ColumnLayout { + width: parent.width + spacing: Kirigami.Units.largeSpacing + + Kirigami.Icon { + Layout.alignment: Qt.AlignHCenter + width: Kirigami.Units.iconSizes.huge + height: width + source: kcm.distroInfo.logo ? kcm.distroInfo.logo : "kde" + } + Kirigami.Heading { + Layout.alignment: Qt.AlignHCenter + text: kcm.distroInfo.name + } + + Kirigami.UrlButton { + Layout.alignment: Qt.AlignHCenter + text: kcm.distroInfo.homeUrl + } + + Kirigami.Heading { + level: 2 + Layout.alignment: Qt.AlignHCenter + text: i18n("Software") + } + Kirigami.FormLayout { + id: softwareLayout + + Controls.Label { + Kirigami.FormData.label: i18n("KDE Plasma Version:") + text: kcm.softwareInfo.plasmaVersion + visible: kcm.softwareInfo.plasmaVersion + } + Controls.Label { + Kirigami.FormData.label: i18n("KDE Frameworks Version:") + text: kcm.softwareInfo.frameworksVersion + } + Controls.Label { + Kirigami.FormData.label: i18n("Qt Version:") + text: kcm.softwareInfo.qtVersion + visible: kcm.softwareInfo.qtVersion + } + Controls.Label { + Kirigami.FormData.label: i18n("Kernel Version:") + text: kcm.softwareInfo.kernelRelease + visible: kcm.softwareInfo.kernelRelease + } + Controls.Label { + Kirigami.FormData.label: i18n("OS Type:") + text: i18nc("@label %1 is the CPU bit width (e.g. 32 or 64)", "%1-bit", kcm.softwareInfo.osType) + visible: kcm.softwareInfo.osType + } + } + Kirigami.Heading { + level: 2 + Layout.alignment: Qt.AlignHCenter + text: i18n("Hardware") + } + Kirigami.FormLayout { + id: hardwareLayout + + Controls.Label { + Kirigami.FormData.label: i18np("Processor:", "Processors:", kcm.hardwareInfo.processorCount); + text: kcm.hardwareInfo.processors + } + Controls.Label { + Kirigami.FormData.label: i18n("Memory:") + text: { + if (kcm.hardwareInfo.memory !== "0 B") { + return i18nc("@label %1 is the formatted amount of system memory (e.g. 7,7 GiB)", + "%1 of RAM", kcm.hardwareInfo.memory) + } else { + return i18nc("Unknown amount of RAM", "Unknown") + } + } + } + } + } + // Only display when we can't use Kirigami Actions + footer: Controls.Button { + visible: !Kirigami.Settings.isMobile + Layout.alignment: Qt.AlignLeft | Qt.AlignBottom + + text: i18n("Copy to clipboard") + icon.name: "edit-copy" + onClicked: copyInfoToClipboard() + } +} diff --git a/modules/info/package/metadata.desktop b/modules/info/package/metadata.desktop new file mode 100644 index 0000000..ccbc813 --- /dev/null +++ b/modules/info/package/metadata.desktop @@ -0,0 +1,14 @@ +[Desktop Entry] +Name=About System +Comment=Software versions +Encoding=UTF-8 +Type=Service +Icon=documentinfo +X-KDE-ServiceTypes=SettingsModule +X-KDE-PluginInfo-Author=Jonah Brüchert +X-KDE-PluginInfo-Email=jbb@kaidan.im +X-KDE-PluginInfo-Name=kcm_mobile_info +X-KDE-PluginInfo-Version=1.0 +X-KDE-PluginInfo-Website=http://plasma-mobile.org +X-KDE-PluginInfo-License=GPL +X-Plasma-MainScript=ui/main.qml diff --git a/modules/info/softwareinfo.cpp b/modules/info/softwareinfo.cpp new file mode 100644 index 0000000..e2ae822 --- /dev/null +++ b/modules/info/softwareinfo.cpp @@ -0,0 +1,74 @@ +/* + * Copyright 2019 Jonah Brüchert + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License or (at your option) version 3 or any later version + * accepted by the membership of KDE e.V. (or its successor approved + * by the membership of KDE e.V.), which shall act as a proxy + * defined in Section 14 of version 3 of the license. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include "softwareinfo.h" +#include + +#include +#include +#include +#include +#include +#include + +SoftwareInfo::SoftwareInfo() += default; + +QString SoftwareInfo::kernelRelease() const +{ + struct utsname utsName; + uname(&utsName); + return QString::fromLatin1(utsName.release); +} + +QString SoftwareInfo::frameworksVersion() const +{ + return KCoreAddons::versionString(); +} + +QString SoftwareInfo::qtVersion() const +{ + return QString::fromLatin1(qVersion()); +} + +QString SoftwareInfo::plasmaVersion() const +{ + const QStringList &filePaths = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, + QStringLiteral("xsessions/plasma.desktop")); + + if (filePaths.length() < 1) { + return QString(); + } + + // Despite the fact that there can be multiple desktop files we simply take + // the first one as users usually don't have xsessions/ in their $HOME + // data location, so the first match should (usually) be the only one and + // reflect the plasma session run. + KDesktopFile desktopFile(filePaths.first()); + return desktopFile.desktopGroup().readEntry("X-KDE-PluginInfo-Version", QString()); +} + +QString SoftwareInfo::osType() const +{ + const int bits = QT_POINTER_SIZE == 8 ? 64 : 32; + + return QString::number(bits); +} diff --git a/modules/info/softwareinfo.h b/modules/info/softwareinfo.h new file mode 100644 index 0000000..d9b4700 --- /dev/null +++ b/modules/info/softwareinfo.h @@ -0,0 +1,49 @@ +/* + * Copyright 2019 Jonah Brüchert + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License or (at your option) version 3 or any later version + * accepted by the membership of KDE e.V. (or its successor approved + * by the membership of KDE e.V.), which shall act as a proxy + * defined in Section 14 of version 3 of the license. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#ifndef SOFTWAREINFO_H +#define SOFTWAREINFO_H + +class SoftwareInfo : public QObject +{ + Q_OBJECT + + Q_PROPERTY(QString kernelRelease READ kernelRelease CONSTANT) + QString kernelRelease() const; + + Q_PROPERTY(QString frameworksVersion READ frameworksVersion CONSTANT) + QString frameworksVersion() const; + + Q_PROPERTY(QString qtVersion READ qtVersion CONSTANT) + QString qtVersion() const; + + Q_PROPERTY(QString plasmaVersion READ plasmaVersion CONSTANT) + QString plasmaVersion() const; + + Q_PROPERTY(QString osType READ osType CONSTANT) + QString osType() const; + +public: + SoftwareInfo(); +}; + +#endif // SOFTWAREINFO_H