diff --git a/Modules/about-distro/src/BitEntry.h b/Modules/about-distro/src/BitEntry.h new file mode 100644 --- /dev/null +++ b/Modules/about-distro/src/BitEntry.h @@ -0,0 +1,35 @@ +/* + Copyright (C) 2012-2020 Harald Sitter + + 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 . +*/ + +#ifndef BITENTRY_H +#define BITENTRY_H + +#include "Entry.h" + +#include + +class BitEntry : public Entry +{ +public: + BitEntry(); + static QString bitString(); +}; + +#endif // BITENTRY_H diff --git a/Modules/about-distro/src/BitEntry.cpp b/Modules/about-distro/src/BitEntry.cpp new file mode 100644 --- /dev/null +++ b/Modules/about-distro/src/BitEntry.cpp @@ -0,0 +1,34 @@ +/* + Copyright (C) 2012-2020 Harald Sitter + + 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 "BitEntry.h" + + +BitEntry::BitEntry() + : Entry(ki18n("OS Type:"), bitString()) +{ +} + +QString BitEntry::bitString() +{ + const int bits = QT_POINTER_SIZE == 8 ? 64 : 32; + return i18nc("@label %1 is the CPU bit width (e.g. 32 or 64)", + "%1-bit", QString::number(bits)); +} diff --git a/Modules/about-distro/src/CMakeLists.txt b/Modules/about-distro/src/CMakeLists.txt --- a/Modules/about-distro/src/CMakeLists.txt +++ b/Modules/about-distro/src/CMakeLists.txt @@ -4,6 +4,13 @@ set(kcm_SRCS main.cpp Module.cpp + Entry.cpp + PlasmaEntry.cpp + KernelEntry.cpp + SectionLabel.cpp + BitEntry.cpp + MemoryEntry.cpp + CPUEntry.cpp ) ki18n_wrap_ui(kcm_SRCS Module.ui) diff --git a/Modules/about-distro/src/CPUEntry.h b/Modules/about-distro/src/CPUEntry.h new file mode 100644 --- /dev/null +++ b/Modules/about-distro/src/CPUEntry.h @@ -0,0 +1,32 @@ +/* + Copyright (C) 2012-2020 Harald Sitter + + 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 . +*/ + +#ifndef CPUENTRY_H +#define CPUENTRY_H + +#include "Entry.h" + +class CPUEntry : public Entry +{ +public: + CPUEntry(); +}; + +#endif // CPUENTRY_H diff --git a/Modules/about-distro/src/CPUEntry.cpp b/Modules/about-distro/src/CPUEntry.cpp new file mode 100644 --- /dev/null +++ b/Modules/about-distro/src/CPUEntry.cpp @@ -0,0 +1,60 @@ +/* + Copyright (C) 2012-2020 Harald Sitter + + 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 "CPUEntry.h" + +#include + +#include +#include + +CPUEntry::CPUEntry() + : Entry(KLocalizedString(), QString()) +{ + const QList list = Solid::Device::listFromType(Solid::DeviceInterface::Processor); + + label = ki18np("Processor:", "Processors:").subs(list.count()); + + // Format processor string + // Group by processor name + QMap processorMap; + for (const Solid::Device &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)); + } + + value = names.join(QLatin1String(", ")); +} diff --git a/Modules/about-distro/src/Entry.h b/Modules/about-distro/src/Entry.h new file mode 100644 --- /dev/null +++ b/Modules/about-distro/src/Entry.h @@ -0,0 +1,59 @@ +/* + Copyright (C) 2012-2020 Harald Sitter + + 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 . +*/ + +#ifndef ENTRY_H +#define ENTRY_H + +#include +#include + +// Generic dumpable info entry. +// This encapsulates a table entry so that it may be put into the UI +// and also serialized into textual form for copy to clipboard. +// All entries that are meant to be serializable should derive from this! +// This class may either be subclassed or used as-is if label/value are trivial +// to obtain. +class Entry +{ +public: + enum class Language { + System, + English + }; + + Entry(const KLocalizedString &label_, const QString &value_); + virtual ~Entry(); + + // When false this entry is garbage (e.g. incomplete data) and shouldn't be rendered. + bool isValid() const; + + // Returns textual representation of entry. + QString diagnosticLine(Language language = Language::System) const; + + // Descriptive label + KLocalizedString label; + // Value of the entry (e.g. the version of plasma) + QString value; + +private: + QString localizedLabel(Language language) const; +}; + +#endif // ENTRY_H diff --git a/Modules/about-distro/src/Entry.cpp b/Modules/about-distro/src/Entry.cpp new file mode 100644 --- /dev/null +++ b/Modules/about-distro/src/Entry.cpp @@ -0,0 +1,63 @@ +/* + Copyright (C) 2012-2020 Harald Sitter + + 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 "Entry.h" + +Entry::Entry(const KLocalizedString &label_, const QString &value_) + : label(label_) + , value(value_) +{ + Q_ASSERT(label.isEmpty() || localizedLabel(Language::English).endsWith(':')); +} + +Entry::~Entry() = default; + +// When false this entry is garbage (e.g. incomplete data) and shouldn't be rendered. +bool Entry::isValid() const +{ + return !label.toString().isEmpty() && !value.isEmpty(); +} + +// Returns textual representation of entry. +QString Entry::diagnosticLine(Language language) const +{ + // FIXME: This isn't really working for right-to-left + // The answer probably is in uncide control characters, but + // didn't work when tried. + // Essentially what needs to happen is that the label should be RTL + // that is to say the colon should be on the left, BUT englishy words + // within that should be LTR, everything besides the label should be LTR + // because we do not localize the values I don't think? + return localizedLabel(language) + ' ' + value + '\n'; +} + +QString Entry::localizedLabel(Language language) const +{ + switch (language) { + case Language::System: + return label.toString(); + case Language::English: + // https://bugs.kde.org/show_bug.cgi?id=416247 + return label.toString(QStringList { QStringLiteral("en_US") }); + } + Q_UNREACHABLE(); + return QStringLiteral("Unknown Label Language %1 (bug in KInfocenter!):").arg( + QString::number(static_cast(language))); +} diff --git a/Modules/about-distro/src/KernelEntry.h b/Modules/about-distro/src/KernelEntry.h new file mode 100644 --- /dev/null +++ b/Modules/about-distro/src/KernelEntry.h @@ -0,0 +1,33 @@ +/* + Copyright (C) 2012-2020 Harald Sitter + + 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 . +*/ + +#ifndef KERNELENTRY_H +#define KERNELENTRY_H + +#include "Entry.h" + +class KernelEntry : public Entry +{ +public: + KernelEntry(); + static QString kernelVersion(); +}; + +#endif // KERNELENTRY_H diff --git a/Modules/about-distro/src/KernelEntry.cpp b/Modules/about-distro/src/KernelEntry.cpp new file mode 100644 --- /dev/null +++ b/Modules/about-distro/src/KernelEntry.cpp @@ -0,0 +1,37 @@ +/* + Copyright (C) 2012-2020 Harald Sitter + + 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 "KernelEntry.h" + +#include + +KernelEntry::KernelEntry() + : Entry(ki18n("Kernel Version:"), kernelVersion()) +{ +} + +QString KernelEntry::kernelVersion() +{ + struct utsname utsName; + if (uname(&utsName) == 0) { + return QString::fromLatin1(utsName.release); + } + return QString(); +} diff --git a/Modules/about-distro/src/MemoryEntry.h b/Modules/about-distro/src/MemoryEntry.h new file mode 100644 --- /dev/null +++ b/Modules/about-distro/src/MemoryEntry.h @@ -0,0 +1,34 @@ +/* + Copyright (C) 2012-2020 Harald Sitter + + 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 . +*/ + +#ifndef MEMORYENTRY_H +#define MEMORYENTRY_H + +#include "Entry.h" + +class MemoryEntry : public Entry +{ +public: + MemoryEntry(); + static qlonglong calculateTotalRam(); + static QString text(); +}; + +#endif // MEMORYENTRY_H diff --git a/Modules/about-distro/src/MemoryEntry.cpp b/Modules/about-distro/src/MemoryEntry.cpp new file mode 100644 --- /dev/null +++ b/Modules/about-distro/src/MemoryEntry.cpp @@ -0,0 +1,65 @@ +/* + Copyright (C) 2012-2020 Harald Sitter + + 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 "MemoryEntry.h" + +#include + +#ifdef Q_OS_LINUX +#include +#elif defined(Q_OS_FREEBSD) +#include +#include +#endif + +MemoryEntry::MemoryEntry() : Entry(ki18n("Memory:"), text()) +{ +} + +qlonglong MemoryEntry::calculateTotalRam() +{ + qlonglong ret = -1; +#ifdef Q_OS_LINUX + struct sysinfo info; + if (sysinfo(&info) == 0) + // manpage "sizes are given as multiples of mem_unit bytes" + ret = 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); + + ret = memory; +#endif + return ret; +} + +QString MemoryEntry::text() +{ + const qlonglong totalRam = calculateTotalRam(); + if (totalRam > 0) { + return i18nc("@label %1 is the formatted amount of system memory (e.g. 7,7 GiB)", + "%1 of RAM", KFormat().formatByteSize(totalRam)); + } + return i18nc("Unknown amount of RAM", "Unknown"); +} diff --git a/Modules/about-distro/src/Module.h b/Modules/about-distro/src/Module.h --- a/Modules/about-distro/src/Module.h +++ b/Modules/about-distro/src/Module.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 Harald Sitter + Copyright (C) 2012-2020 Harald Sitter This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -27,7 +27,7 @@ class Module; } -class QLabel; +class Entry; class Module : public KCModule { @@ -62,25 +62,24 @@ void defaults() override; private: - void loadSoftware(); - void loadHardware(); + // Load os-release data into UI. + void loadOSData(); + // Load generic entries into UI. + void loadEntries(); - /** - * Copies the software and hardware information to clipboard. - */ + // Copy data dump to clipboard void copyToClipboard(); + // Same as copyToClipboard but in en_US when the system language + // is something else void copyToClipboardInEnglish(); - QVector > labelsForClipboard; - QString englishTextForClipboard; - /** * UI */ Ui::Module *ui = nullptr; - /** \returns Version of plasmashell or an empty string when none was found */ - QString plasmaVersion() const; + /*** Description entries for dumping into textual form. Already excludes invalids. */ + std::vector m_entries; }; #endif // MODULE_H diff --git a/Modules/about-distro/src/Module.cpp b/Modules/about-distro/src/Module.cpp --- a/Modules/about-distro/src/Module.cpp +++ b/Modules/about-distro/src/Module.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2014 Harald Sitter + Copyright (C) 2012-2020 Harald Sitter This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -24,66 +24,37 @@ #include #include #include -#include #include #include #include #include -#include -#include #include #include #include -#include -#include - -#ifdef Q_OS_LINUX -#include -#elif defined(Q_OS_FREEBSD) -#include -#include -#endif -#include - +#include "CPUEntry.h" +#include "BitEntry.h" +#include "KernelEntry.h" +#include "MemoryEntry.h" +#include "PlasmaEntry.h" +#include "SectionLabel.h" #include "Version.h" -static qlonglong calculateTotalRam() -{ - qlonglong ret = -1; -#ifdef Q_OS_LINUX - struct sysinfo info; - if (sysinfo(&info) == 0) - // manpage "sizes are given as multiples of mem_unit bytes" - ret = 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); - - ret = memory; -#endif - return ret; -} - Module::Module(QWidget *parent, const QVariantList &args) : KCModule(parent, args), ui(new Ui::Module) { KAboutData *aboutData = new KAboutData(QStringLiteral("kcm-about-distro"), - i18nc("@title", "About Distribution"), + i18nc("@title", "About System"), QString::fromLatin1(global_s_versionStringFull), QString(), KAboutLicense::LicenseKey::GPL_V3, - i18nc("@info:credit", "Copyright 2012-2014 Harald Sitter")); + i18nc("@info:credit", "Copyright 2012-2020 Harald Sitter")); aboutData->addAuthor(i18nc("@info:credit", "Harald Sitter"), i18nc("@info:credit", "Author"), - QStringLiteral("apachelogger@kubuntu.org")); + QStringLiteral("sitter@kde.org")); setAboutData(aboutData); @@ -122,14 +93,20 @@ Module::~Module() { delete ui; + qDeleteAll(m_entries); } void Module::load() { - labelsForClipboard.clear(); - englishTextForClipboard = QStringLiteral(""); - loadSoftware(); - loadHardware(); + // load is called lazly, but also from the ctor -> prevent double init. + static bool initd = false; + if (initd) { + return; + } + initd = true; + + loadOSData(); + loadEntries(); } void Module::save() @@ -140,7 +117,7 @@ { } -void Module::loadSoftware() +void Module::loadOSData() { // NOTE: do not include globals, otherwise kdeglobals could provide values // even though we only explicitly want them from our own config. @@ -168,10 +145,8 @@ const QString distroNameVersion = QStringLiteral("%1 %2").arg(distroName, versionId); ui->nameVersionLabel->setText(distroNameVersion); - const auto dummyDistroDescriptionLabel = new QLabel(i18nc("@title:row", "Operating System:"), this); - dummyDistroDescriptionLabel->hide(); - labelsForClipboard << qMakePair(dummyDistroDescriptionLabel, ui->nameVersionLabel); - englishTextForClipboard += QStringLiteral("Operating System: %1\n").arg(distroNameVersion); + // Insert a dummy entry for debug info dumps. + m_entries.push_back(new Entry(ki18n("Operating System:"), distroNameVersion)); const QString variant = cg.readEntry("Variant", os.variant()); if (variant.isEmpty()) { @@ -186,130 +161,67 @@ } else { ui->urlLabel->setText(QStringLiteral("%1").arg(url)); } - - // Since Plasma version detection isn't based on a library query it can fail - // in weird cases; instead of admitting defeat we simply hide everything :P - const QString plasma = plasmaVersion(); - if (plasma.isEmpty()) { - ui->plasma->hide(); - ui->plasmaLabel->hide(); - } else { - ui->plasmaLabel->setText(plasma); - labelsForClipboard << qMakePair(ui->plasma, ui->plasmaLabel); - englishTextForClipboard += QStringLiteral("KDE Plasma Version: %1\n").arg(plasma); - } - - const QString frameworksVersion = KCoreAddons::versionString(); - ui->frameworksLabel->setText(frameworksVersion); - labelsForClipboard << qMakePair(ui->frameworksLabelKey, ui->frameworksLabel); - englishTextForClipboard += QStringLiteral("KDE Frameworks Version: %1\n").arg(frameworksVersion); - - const QString qversion = QString::fromLatin1(qVersion()); - ui->qtLabel->setText(qversion); - labelsForClipboard << qMakePair(ui->qt, ui->qtLabel); - englishTextForClipboard += QStringLiteral("Qt Version: %1\n").arg(qversion); } -void Module::loadHardware() +void Module::loadEntries() { - struct utsname utsName; - if(uname(&utsName) != 0) { - ui->kernel->hide(); - ui->kernelLabel->hide(); - } else { - QString kernelVersion = QString::fromLatin1(utsName.release); - ui->kernelLabel->setText(kernelVersion); - labelsForClipboard << qMakePair(ui->kernel, ui->kernelLabel); - englishTextForClipboard += QStringLiteral("Kernel Version: %1\n").arg(kernelVersion); - } - - const int bits = QT_POINTER_SIZE == 8 ? 64 : 32; - const QString bitsStr = QString::number(bits); - ui->bitsLabel->setText(i18nc("@label %1 is the CPU bit width (e.g. 32 or 64)", - "%1-bit", bitsStr)); - labelsForClipboard << qMakePair(ui->bitsKey, ui->bitsLabel); - englishTextForClipboard += QStringLiteral("OS Type: %1-bit\n").arg(bitsStr); - - const QList list = Solid::Device::listFromType(Solid::DeviceInterface::Processor); - ui->processor->setText(i18np("Processor:", "Processors:", list.count())); - // Format processor string - // Group by processor name - QMap processorMap; - Q_FOREACH(const Solid::Device &device, list) { - const QString name = device.product(); - auto it = processorMap.find(name); - if (it == processorMap.end()) { - processorMap.insert(name, 1); - } else { - ++it.value(); + auto addSectionHeader = [this](const QString &text) + { + int row = ui->infoGrid->rowCount(); + // Random sizes stolen from original UI file values :S + ui->infoGrid->addItem(new QSpacerItem(17, 21, QSizePolicy::Minimum, QSizePolicy::Fixed), row, 1, 1, 1); + ++row; + ui->infoGrid->addWidget(new SectionLabel(text), row, 1, Qt::AlignLeft); + ++row; + }; + + auto addEntriesToGrid = [this](std::vector entries) + { + int row = ui->infoGrid->rowCount(); + for (auto entry : entries) { + if (!entry->isValid()) { + delete entry; // since we do not keep it around + continue; + } + ui->infoGrid->addWidget(new QLabel(entry->label.toString()), row, 0, Qt::AlignRight); + ui->infoGrid->addWidget(new QLabel(entry->value), row, 1, Qt::AlignLeft); + m_entries.push_back(entry); + ++row; } - } - // 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(", ")); - ui->processorLabel->setText(processorLabel); - if (ui->processorLabel->text().isEmpty()) { - ui->processor->setHidden(true); - ui->processorLabel->setHidden(true); - } else { - labelsForClipboard << qMakePair(ui->processor, ui->processorLabel); - englishTextForClipboard += QStringLiteral("Processors: %1\n").arg(processorLabel); - } - - const qlonglong totalRam = calculateTotalRam(); - const QString memoryLabel = totalRam > 0 - ? i18nc("@label %1 is the formatted amount of system memory (e.g. 7,7 GiB)", - "%1 of RAM", KFormat().formatByteSize(totalRam)) - : i18nc("Unknown amount of RAM", "Unknown"); - ui->memoryLabel->setText(memoryLabel); - labelsForClipboard << qMakePair(ui->memory, ui->memoryLabel); - englishTextForClipboard += QStringLiteral("Memory: %1\n").arg(KFormat().formatByteSize(totalRam)); + }; + + // software + addSectionHeader(i18nc("@title:group", "Software")); + addEntriesToGrid({ + new PlasmaEntry(), + new Entry(ki18n("KDE Frameworks Version:"), KCoreAddons::versionString()), + new Entry(ki18n("Qt Version:"), QString::fromLatin1(qVersion())), + new KernelEntry(), + new BitEntry() + }); + + // hardware + addSectionHeader(i18nc("@title:group", "Hardware")); + addEntriesToGrid({ + new CPUEntry(), + new MemoryEntry() + }); } void Module::copyToClipboard() { QString text; - // note that this loop does not necessarily represent the same order as in the GUI - for (auto labelPair : qAsConst(labelsForClipboard)) { - const auto valueLabel = labelPair.second; - if (!valueLabel->isHidden()) { - const auto descriptionLabelText = labelPair.first->text(); - const auto valueLabelText = valueLabel->text(); - text += i18nc("%1 is a label already including a colon, %2 is the corresponding value", "%1 %2", descriptionLabelText, valueLabelText) + QStringLiteral("\n"); - } + for (auto entry : m_entries) { + text += entry->diagnosticLine(Entry::Language::System); } - QGuiApplication::clipboard()->setText(text); } void Module::copyToClipboardInEnglish() { - QGuiApplication::clipboard()->setText(englishTextForClipboard); -} - -QString Module::plasmaVersion() const -{ - const QStringList &filePaths = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, - QStringLiteral("xsessions/plasma.desktop")); - - if (filePaths.length() < 1) { - return QString(); + QString text; + for (auto entry : m_entries) { + text += entry->diagnosticLine(Entry::Language::English); } - - // 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()); + QGuiApplication::clipboard()->setText(text); } diff --git a/Modules/about-distro/src/Module.ui b/Modules/about-distro/src/Module.ui --- a/Modules/about-distro/src/Module.ui +++ b/Modules/about-distro/src/Module.ui @@ -46,7 +46,7 @@ - + @@ -137,189 +137,6 @@ - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 17 - 21 - - - - - - - - - 75 - true - - - - Software - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - KDE Plasma Version: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - {KDEVersion} - - - - - - - KDE Frameworks Version: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - {FrameworksVersion} - - - - - - - Qt Version: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - {QtVersion} - - - - - - - Kernel Version: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - {KernelName} - - - - - - - OS Type: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - {QtArchitecutre} - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 17 - 21 - - - - - - - - - 75 - true - - - - Hardware - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - Processor: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - {PrcoessorName} - - - - - - - Memory: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - {MemoryAmount} - - - @@ -367,18 +184,18 @@ - - - Copy software and hardware information to clipboard in English - - - Copy to Clipboard in English - - - - .. - - + + + Copy software and hardware information to clipboard in English + + + Copy to Clipboard in English + + + + .. + + diff --git a/Modules/about-distro/src/PlasmaEntry.h b/Modules/about-distro/src/PlasmaEntry.h new file mode 100644 --- /dev/null +++ b/Modules/about-distro/src/PlasmaEntry.h @@ -0,0 +1,33 @@ +/* + Copyright (C) 2012-2020 Harald Sitter + + 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 . +*/ + +#ifndef PLASMAENTRY_H +#define PLASMAENTRY_H + +#include "Entry.h" + +class PlasmaEntry : public Entry +{ +public: + PlasmaEntry(); + static QString plasmaVersion(); +}; + +#endif // PLASMAENTRY_H diff --git a/Modules/about-distro/src/PlasmaEntry.cpp b/Modules/about-distro/src/PlasmaEntry.cpp new file mode 100644 --- /dev/null +++ b/Modules/about-distro/src/PlasmaEntry.cpp @@ -0,0 +1,52 @@ +/* + Copyright (C) 2012-2020 Harald Sitter + + 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 "PlasmaEntry.h" + +#include +#include +#include + +PlasmaEntry::PlasmaEntry() + : Entry(ki18n("KDE Plasma Version:"), plasmaVersion()) +{ + // Since Plasma version detection isn't based on a library query it can fail + // in weird cases; instead of admitting defeat we simply hide everything :P + if (value.isEmpty()) { + return; + } +} + +QString PlasmaEntry::plasmaVersion() +{ + 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()); +} diff --git a/Modules/about-distro/src/SectionLabel.h b/Modules/about-distro/src/SectionLabel.h new file mode 100644 --- /dev/null +++ b/Modules/about-distro/src/SectionLabel.h @@ -0,0 +1,33 @@ +/* + Copyright (C) 2020 Harald Sitter + + 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 . +*/ + +#ifndef SECTIONLABEL_H +#define SECTIONLABEL_H + +#include + +// Label with font styling for section heading such as 'Software' +class SectionLabel : public QLabel +{ +public: + explicit SectionLabel(const QString &text, QWidget *parent = nullptr); +}; + +#endif // SECTIONLABEL_H diff --git a/Modules/about-distro/src/SectionLabel.cpp b/Modules/about-distro/src/SectionLabel.cpp new file mode 100644 --- /dev/null +++ b/Modules/about-distro/src/SectionLabel.cpp @@ -0,0 +1,30 @@ +/* + Copyright (C) 2020 Harald Sitter + + 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 "SectionLabel.h" + +SectionLabel::SectionLabel(const QString &text, QWidget *parent) + : QLabel(text, parent) +{ + QFont font; + font.setBold(true); + font.setWeight(75); + setFont(font); +}