Commit c0f28efd authored by Gregor Mi's avatar Gregor Mi
Browse files

Add "Copy Info" button to the About System KCM

Summary:
Adds a new button with a "Copy to Clipboard" action to the "About" System module. The action copies the visible information to the clipboard. It can be used for quickly retrieving information for a bug report.

This is an example of how the copied text looks like:

Distro: openSUSE Tumbleweed 20180404
KDE Frameworks Version: 5.46.0
Qt Version: 5.10.0
Kernel Version: 4.15.13-2-default
OS Type: 64-bit
Processors: 4 × Intel® Core™ i3 CPU M 370 @ 2.40GHz
Memory: 7,7 GiB of RAM

(Note that in this example 'KDE Plasma Version' is missing here because it is hidden in the development version)

Screenshot:

{F5691627}

BUG: 366266

Also note, that the layout in Modules/about-distro/src/Module.ui had to be reworked in order to properly integrate the new button (see screenshots below). As a nice side effect is that the behavior of horizontal resizing is now better than before. The content is now always centered instead of shifted to the right.

Reviewers: ngraham, dhaumann, rkflx

Reviewed By: ngraham, dhaumann

Subscribers: rkflx, dhaumann, ltoscano, sebas, elvisangelaccio, cfeck, plasma-devel

Tags: #plasma

Differential Revision: https://phabricator.kde.org/D7087
parent 5d81ddbf
......@@ -21,6 +21,7 @@
#include "Module.h"
#include "ui_Module.h"
#include <QClipboard>
#include <QIcon>
#include <QStandardPaths>
......@@ -102,6 +103,10 @@ Module::Module(QWidget *parent, const QVariantList &args) :
// We have no help so remove the button from the buttons.
setButtons(buttons() ^ KCModule::Help ^ KCModule::Default ^ KCModule::Apply);
// Setup Copy to Clipboard button
connect(ui->pushButtonCopyInfo, &QPushButton::clicked, this, &Module::copyToClipboard);
ui->pushButtonCopyInfo->setShortcut(QKeySequence::Copy);
// https://bugs.kde.org/show_bug.cgi?id=366158
// When a KCM loads fast enough do a blocking load via the constructor.
// Otherwise there is a notciable rendering gap where dummy/no data is
......@@ -116,6 +121,7 @@ Module::~Module()
void Module::load()
{
labelsForClipboard.clear();
loadSoftware();
loadHardware();
}
......@@ -153,6 +159,10 @@ void Module::loadSoftware()
const QString versionId = cg.readEntry("Version", os.versionId);
ui->nameVersionLabel->setText(QStringLiteral("%1 %2").arg(distroName, versionId));
const auto dummyDistroDescriptionLabel = new QLabel(i18nc("@title:row", "Operating System:"), this);
dummyDistroDescriptionLabel->hide();
labelsForClipboard << qMakePair(dummyDistroDescriptionLabel, ui->nameVersionLabel);
const QString variant = cg.readEntry("Variant", QString());
if (variant.isEmpty()) {
ui->variantLabel->hide();
......@@ -175,11 +185,16 @@ void Module::loadSoftware()
ui->plasmaLabel->hide();
} else {
ui->plasmaLabel->setText(plasma);
labelsForClipboard << qMakePair(ui->plasma, ui->plasmaLabel);
}
ui->qtLabel->setText(QString::fromLatin1(qVersion()));
const QString qversion = QString::fromLatin1(qVersion());
ui->qtLabel->setText(qversion);
labelsForClipboard << qMakePair(ui->qt, ui->qtLabel);
ui->frameworksLabel->setText(KCoreAddons::versionString());
const QString frameworksVersion = KCoreAddons::versionString();
ui->frameworksLabel->setText(frameworksVersion);
labelsForClipboard << qMakePair(ui->frameworksLabelKey, ui->frameworksLabel);
}
void Module::loadHardware()
......@@ -190,11 +205,14 @@ void Module::loadHardware()
ui->kernelLabel->hide();
} else {
ui->kernelLabel->setText(QString::fromLatin1(utsName.release));
labelsForClipboard << qMakePair(ui->kernel, ui->kernelLabel);
}
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", QString::number(bits)));
"%1-bit", bitsStr));
labelsForClipboard << qMakePair(ui->bitsKey, ui->bitsLabel);
const QList<Solid::Device> list = Solid::Device::listFromType(Solid::DeviceInterface::Processor);
ui->processor->setText(i18np("Processor:", "Processors:", list.count()));
......@@ -221,17 +239,39 @@ void Module::loadHardware()
name = name.simplified();
names.append(QStringLiteral("%1 × %2").arg(count).arg(name));
}
ui->processorLabel->setText(names.join(QStringLiteral(", ")));
const QString processorLabel = names.join(QStringLiteral(", "));
ui->processorLabel->setText(processorLabel);
if (ui->processorLabel->text().isEmpty()) {
ui->processor->setHidden(true);
ui->processorLabel->setHidden(true);
} else {
labelsForClipboard << qMakePair(ui->processor, ui->processorLabel);
}
const qlonglong totalRam = calculateTotalRam();
ui->memoryLabel->setText(totalRam > 0
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"));
: i18nc("Unknown amount of RAM", "Unknown");
ui->memoryLabel->setText(memoryLabel);
labelsForClipboard << qMakePair(ui->memory, ui->memoryLabel);
}
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");
}
}
QGuiApplication::clipboard()->setText(text);
}
QString Module::plasmaVersion() const
......
......@@ -27,6 +27,8 @@ namespace Ui {
class Module;
}
class QLabel;
class Module : public KCModule
{
Q_OBJECT
......@@ -63,6 +65,13 @@ private:
void loadSoftware();
void loadHardware();
/**
* Copies the software and hardware information to clipboard.
*/
void copyToClipboard();
QVector<QPair<QLabel*, QLabel*> > labelsForClipboard;
/**
* UI
*/
......
......@@ -10,147 +10,334 @@
<height>586</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="3" colspan="2">
<layout class="QVBoxLayout" name="verticalLayout">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Maximum</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>17</width>
<height>21</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QHBoxLayout" name="hLayout">
<item>
<spacer name="verticalSpacer_6">
<spacer name="hSpacerLeft">
<property name="orientation">
<enum>Qt::Vertical</enum>
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="nameVersionLabel">
<property name="text">
<string notr="true">{NameVersionLabel}</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="variantLabel">
<property name="text">
<string notr="true">{variantLabel}</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="urlLabel">
<property name="text">
<string notr="true">{UrlLabel}</string>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="logoLabel">
<property name="text">
<string notr="true">{LogoLabel}</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>10</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="0" column="1">
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="0">
<widget class="QLabel" name="nameVersionLabel">
<property name="text">
<string notr="true">{NameVersionLabel}</string>
</property>
</widget>
</item>
<item row="4" column="0">
<spacer name="verticalSpacer_5">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="0">
<spacer name="verticalSpacer_6">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="3" column="0">
<widget class="QLabel" name="urlLabel">
<property name="text">
<string notr="true">{UrlLabel}</string>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="variantLabel">
<property name="text">
<string notr="true">{variantLabel}</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="1">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>17</width>
<height>21</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="1">
<widget class="QLabel" name="label_2">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Software</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="plasma">
<property name="text">
<string>KDE Plasma Version:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLabel" name="plasmaLabel">
<property name="text">
<string notr="true">{KDEVersion}</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="frameworksLabelKey">
<property name="text">
<string>KDE Frameworks Version:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLabel" name="frameworksLabel">
<property name="text">
<string notr="true">{FrameworksVersion}</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="qt">
<property name="text">
<string>Qt Version:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLabel" name="qtLabel">
<property name="text">
<string notr="true">{QtVersion}</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="kernel">
<property name="text">
<string>Kernel Version:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QLabel" name="kernelLabel">
<property name="text">
<string notr="true">{KernelName}</string>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="bitsKey">
<property name="text">
<string>OS Type:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QLabel" name="bitsLabel">
<property name="text">
<string notr="true">{QtArchitecutre}</string>
</property>
</widget>
</item>
<item row="8" column="1">
<spacer name="verticalSpacer_4">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>17</width>
<height>21</height>
</size>
</property>
</spacer>
</item>
<item row="9" column="1">
<widget class="QLabel" name="label">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Hardware</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="10" column="0">
<widget class="QLabel" name="processor">
<property name="text">
<string notr="true">Processor:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="10" column="1">
<widget class="QLabel" name="processorLabel">
<property name="text">
<string notr="true">{PrcoessorName}</string>
</property>
</widget>
</item>
<item row="11" column="0">
<widget class="QLabel" name="memory">
<property name="text">
<string>Memory:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="11" column="1">
<widget class="QLabel" name="memoryLabel">
<property name="text">
<string notr="true">{MemoryAmount}</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer_5">
<spacer name="hSpacerRight">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="5" column="1">
<widget class="QLabel" name="plasma">
<property name="text">
<string>KDE Plasma Version:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="8" column="4">
<spacer name="horizontalSpacer_7">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>215</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="1">
<widget class="QWidget" name="widget" native="true">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="logoLabel">
<property name="text">
<string notr="true">{LogoLabel}</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>4</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item row="13" column="3">
<widget class="QLabel" name="memoryLabel">
<property name="text">
<string notr="true">{MemoryAmount}</string>
</property>
</widget>
</item>
<item row="5" column="3">
<widget class="QLabel" name="plasmaLabel">
<property name="text">
<string notr="true">{KDEVersion}</string>
</property>
</widget>
</item>
<item row="13" column="1">
<widget class="QLabel" name="memory">
<property name="text">
<string>Memory:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="14" column="3">
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
......@@ -163,183 +350,36 @@
</property>
</spacer>
</item>
<item row="12" column="1">
<widget class="QLabel" name="processor">
<property name="text">
<string notr="true">Processor:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="3" column="3">
<widget class="QLabel" name="label_2">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Software</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>