Changeset View
Changeset View
Standalone View
Standalone View
Modules/about-distro/src/Module.cpp
Show All 17 Lines | 1 | /* | |||
---|---|---|---|---|---|
18 | along with this program. If not, see <http://www.gnu.org/licenses/>. | 18 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
19 | */ | 19 | */ | ||
20 | 20 | | |||
21 | #include "Module.h" | 21 | #include "Module.h" | ||
22 | #include "ui_Module.h" | 22 | #include "ui_Module.h" | ||
23 | 23 | | |||
24 | #include <QClipboard> | 24 | #include <QClipboard> | ||
25 | #include <QIcon> | 25 | #include <QIcon> | ||
26 | #include <QLocale> | ||||
26 | #include <QStandardPaths> | 27 | #include <QStandardPaths> | ||
27 | 28 | | |||
28 | #include <KAboutData> | 29 | #include <KAboutData> | ||
29 | #include <KCoreAddons> | 30 | #include <KCoreAddons> | ||
30 | #include <KConfig> | 31 | #include <KConfig> | ||
31 | #include <KConfigGroup> | 32 | #include <KConfigGroup> | ||
32 | #include <KDesktopFile> | 33 | #include <KDesktopFile> | ||
33 | #include <KFormat> | 34 | #include <KFormat> | ||
▲ Show 20 Lines • Show All 66 Lines • ▼ Show 20 Line(s) | 76 | { | |||
100 | 101 | | |||
101 | ui->urlLabel->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::LinksAccessibleByMouse); | 102 | ui->urlLabel->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::LinksAccessibleByMouse); | ||
102 | 103 | | |||
103 | // We have no help so remove the button from the buttons. | 104 | // We have no help so remove the button from the buttons. | ||
104 | setButtons(buttons() ^ KCModule::Help ^ KCModule::Default ^ KCModule::Apply); | 105 | setButtons(buttons() ^ KCModule::Help ^ KCModule::Default ^ KCModule::Apply); | ||
105 | 106 | | |||
106 | // Setup Copy to Clipboard button | 107 | // Setup Copy to Clipboard button | ||
107 | connect(ui->pushButtonCopyInfo, &QPushButton::clicked, this, &Module::copyToClipboard); | 108 | connect(ui->pushButtonCopyInfo, &QPushButton::clicked, this, &Module::copyToClipboard); | ||
109 | connect(ui->pushButtonCopyInfoInEnglish, &QPushButton::clicked, this, &Module::copyToClipboardInEnglish); | ||||
110 | if (QLocale::system().language() == QLocale::English) { | ||||
111 | ui->pushButtonCopyInfoInEnglish->hide(); | ||||
112 | } | ||||
108 | ui->pushButtonCopyInfo->setShortcut(QKeySequence::Copy); | 113 | ui->pushButtonCopyInfo->setShortcut(QKeySequence::Copy); | ||
109 | 114 | | |||
110 | // https://bugs.kde.org/show_bug.cgi?id=366158 | 115 | // https://bugs.kde.org/show_bug.cgi?id=366158 | ||
111 | // When a KCM loads fast enough do a blocking load via the constructor. | 116 | // When a KCM loads fast enough do a blocking load via the constructor. | ||
112 | // Otherwise there is a notciable rendering gap where dummy/no data is | 117 | // Otherwise there is a notciable rendering gap where dummy/no data is | ||
113 | // shown. Makes it look bad. | 118 | // shown. Makes it look bad. | ||
114 | load(); | 119 | load(); | ||
115 | } | 120 | } | ||
116 | 121 | | |||
117 | Module::~Module() | 122 | Module::~Module() | ||
118 | { | 123 | { | ||
119 | delete ui; | 124 | delete ui; | ||
120 | } | 125 | } | ||
121 | 126 | | |||
122 | void Module::load() | 127 | void Module::load() | ||
123 | { | 128 | { | ||
124 | labelsForClipboard.clear(); | 129 | labelsForClipboard.clear(); | ||
130 | englishTextForClipboard = QStringLiteral(""); | ||||
125 | loadSoftware(); | 131 | loadSoftware(); | ||
126 | loadHardware(); | 132 | loadHardware(); | ||
127 | } | 133 | } | ||
128 | 134 | | |||
129 | void Module::save() | 135 | void Module::save() | ||
130 | { | 136 | { | ||
131 | } | 137 | } | ||
132 | 138 | | |||
Show All 19 Lines | 144 | { | |||
152 | ui->logoLabel->setPixmap(logo); | 158 | ui->logoLabel->setPixmap(logo); | ||
153 | 159 | | |||
154 | OSRelease os; | 160 | OSRelease os; | ||
155 | // We allow overriding of the OS name for branding purposes. | 161 | // We allow overriding of the OS name for branding purposes. | ||
156 | // For example OS Ubuntu may be rebranded as Kubuntu. Also Kubuntu Active | 162 | // For example OS Ubuntu may be rebranded as Kubuntu. Also Kubuntu Active | ||
157 | // as a product brand is different from Kubuntu. | 163 | // as a product brand is different from Kubuntu. | ||
158 | const QString distroName = cg.readEntry("Name", os.name); | 164 | const QString distroName = cg.readEntry("Name", os.name); | ||
159 | const QString versionId = cg.readEntry("Version", os.versionId); | 165 | const QString versionId = cg.readEntry("Version", os.versionId); | ||
160 | ui->nameVersionLabel->setText(QStringLiteral("%1 %2").arg(distroName, versionId)); | 166 | const QString distroNameVersion = QStringLiteral("%1 %2").arg(distroName, versionId); | ||
167 | ui->nameVersionLabel->setText(distroNameVersion); | ||||
161 | 168 | | |||
162 | const auto dummyDistroDescriptionLabel = new QLabel(i18nc("@title:row", "Operating System:"), this); | 169 | const auto dummyDistroDescriptionLabel = new QLabel(i18nc("@title:row", "Operating System:"), this); | ||
163 | dummyDistroDescriptionLabel->hide(); | 170 | dummyDistroDescriptionLabel->hide(); | ||
164 | labelsForClipboard << qMakePair(dummyDistroDescriptionLabel, ui->nameVersionLabel); | 171 | labelsForClipboard << qMakePair(dummyDistroDescriptionLabel, ui->nameVersionLabel); | ||
172 | englishTextForClipboard += QStringLiteral("Operating System: %1\n").arg(distroNameVersion); | ||||
165 | 173 | | |||
166 | const QString variant = cg.readEntry("Variant", QString()); | 174 | const QString variant = cg.readEntry("Variant", QString()); | ||
167 | if (variant.isEmpty()) { | 175 | if (variant.isEmpty()) { | ||
168 | ui->variantLabel->hide(); | 176 | ui->variantLabel->hide(); | ||
169 | } else { | 177 | } else { | ||
170 | ui->variantLabel->setText(variant); | 178 | ui->variantLabel->setText(variant); | ||
171 | } | 179 | } | ||
172 | 180 | | |||
173 | const QString url = cg.readEntry("Website", os.homeUrl); | 181 | const QString url = cg.readEntry("Website", os.homeUrl); | ||
174 | if (url.isEmpty()) { | 182 | if (url.isEmpty()) { | ||
175 | ui->urlLabel->hide(); | 183 | ui->urlLabel->hide(); | ||
176 | } else { | 184 | } else { | ||
177 | ui->urlLabel->setText(QStringLiteral("<a href='%1'>%1</a>").arg(url)); | 185 | ui->urlLabel->setText(QStringLiteral("<a href='%1'>%1</a>").arg(url)); | ||
178 | } | 186 | } | ||
179 | 187 | | |||
180 | // Since Plasma version detection isn't based on a library query it can fail | 188 | // Since Plasma version detection isn't based on a library query it can fail | ||
181 | // in weird cases; instead of admitting defeat we simply hide everything :P | 189 | // in weird cases; instead of admitting defeat we simply hide everything :P | ||
182 | const QString plasma = plasmaVersion(); | 190 | const QString plasma = plasmaVersion(); | ||
183 | if (plasma.isEmpty()) { | 191 | if (plasma.isEmpty()) { | ||
184 | ui->plasma->hide(); | 192 | ui->plasma->hide(); | ||
185 | ui->plasmaLabel->hide(); | 193 | ui->plasmaLabel->hide(); | ||
186 | } else { | 194 | } else { | ||
187 | ui->plasmaLabel->setText(plasma); | 195 | ui->plasmaLabel->setText(plasma); | ||
188 | labelsForClipboard << qMakePair(ui->plasma, ui->plasmaLabel); | 196 | labelsForClipboard << qMakePair(ui->plasma, ui->plasmaLabel); | ||
197 | englishTextForClipboard += QStringLiteral("KDE Plasma Version: %1\n").arg(plasma); | ||||
189 | } | 198 | } | ||
190 | 199 | | |||
191 | const QString frameworksVersion = KCoreAddons::versionString(); | 200 | const QString frameworksVersion = KCoreAddons::versionString(); | ||
192 | ui->frameworksLabel->setText(frameworksVersion); | 201 | ui->frameworksLabel->setText(frameworksVersion); | ||
193 | labelsForClipboard << qMakePair(ui->frameworksLabelKey, ui->frameworksLabel); | 202 | labelsForClipboard << qMakePair(ui->frameworksLabelKey, ui->frameworksLabel); | ||
203 | englishTextForClipboard += QStringLiteral("KDE Frameworks Version: %1\n").arg(frameworksVersion); | ||||
194 | 204 | | |||
195 | const QString qversion = QString::fromLatin1(qVersion()); | 205 | const QString qversion = QString::fromLatin1(qVersion()); | ||
196 | ui->qtLabel->setText(qversion); | 206 | ui->qtLabel->setText(qversion); | ||
197 | labelsForClipboard << qMakePair(ui->qt, ui->qtLabel); | 207 | labelsForClipboard << qMakePair(ui->qt, ui->qtLabel); | ||
208 | englishTextForClipboard += QStringLiteral("Qt Version: %1\n").arg(qversion); | ||||
198 | } | 209 | } | ||
199 | 210 | | |||
200 | void Module::loadHardware() | 211 | void Module::loadHardware() | ||
201 | { | 212 | { | ||
202 | struct utsname utsName; | 213 | struct utsname utsName; | ||
203 | if(uname(&utsName) != 0) { | 214 | if(uname(&utsName) != 0) { | ||
204 | ui->kernel->hide(); | 215 | ui->kernel->hide(); | ||
205 | ui->kernelLabel->hide(); | 216 | ui->kernelLabel->hide(); | ||
206 | } else { | 217 | } else { | ||
207 | ui->kernelLabel->setText(QString::fromLatin1(utsName.release)); | 218 | QString kernelVersion = QString::fromLatin1(utsName.release); | ||
219 | ui->kernelLabel->setText(kernelVersion); | ||||
208 | labelsForClipboard << qMakePair(ui->kernel, ui->kernelLabel); | 220 | labelsForClipboard << qMakePair(ui->kernel, ui->kernelLabel); | ||
221 | englishTextForClipboard += QStringLiteral("Kernel Version: %1\n").arg(kernelVersion); | ||||
209 | } | 222 | } | ||
210 | 223 | | |||
211 | const int bits = QT_POINTER_SIZE == 8 ? 64 : 32; | 224 | const int bits = QT_POINTER_SIZE == 8 ? 64 : 32; | ||
212 | const QString bitsStr = QString::number(bits); | 225 | const QString bitsStr = QString::number(bits); | ||
213 | ui->bitsLabel->setText(i18nc("@label %1 is the CPU bit width (e.g. 32 or 64)", | 226 | ui->bitsLabel->setText(i18nc("@label %1 is the CPU bit width (e.g. 32 or 64)", | ||
214 | "%1-bit", bitsStr)); | 227 | "%1-bit", bitsStr)); | ||
215 | labelsForClipboard << qMakePair(ui->bitsKey, ui->bitsLabel); | 228 | labelsForClipboard << qMakePair(ui->bitsKey, ui->bitsLabel); | ||
229 | englishTextForClipboard += QStringLiteral("OS Type: %1-bit\n").arg(bitsStr); | ||||
216 | 230 | | |||
217 | const QList<Solid::Device> list = Solid::Device::listFromType(Solid::DeviceInterface::Processor); | 231 | const QList<Solid::Device> list = Solid::Device::listFromType(Solid::DeviceInterface::Processor); | ||
218 | ui->processor->setText(i18np("Processor:", "Processors:", list.count())); | 232 | ui->processor->setText(i18np("Processor:", "Processors:", list.count())); | ||
219 | // Format processor string | 233 | // Format processor string | ||
220 | // Group by processor name | 234 | // Group by processor name | ||
221 | QMap<QString, int> processorMap; | 235 | QMap<QString, int> processorMap; | ||
222 | Q_FOREACH(const Solid::Device &device, list) { | 236 | Q_FOREACH(const Solid::Device &device, list) { | ||
223 | const QString name = device.product(); | 237 | const QString name = device.product(); | ||
Show All 18 Lines | |||||
242 | 256 | | |||
243 | const QString processorLabel = names.join(QStringLiteral(", ")); | 257 | const QString processorLabel = names.join(QStringLiteral(", ")); | ||
244 | ui->processorLabel->setText(processorLabel); | 258 | ui->processorLabel->setText(processorLabel); | ||
245 | if (ui->processorLabel->text().isEmpty()) { | 259 | if (ui->processorLabel->text().isEmpty()) { | ||
246 | ui->processor->setHidden(true); | 260 | ui->processor->setHidden(true); | ||
247 | ui->processorLabel->setHidden(true); | 261 | ui->processorLabel->setHidden(true); | ||
248 | } else { | 262 | } else { | ||
249 | labelsForClipboard << qMakePair(ui->processor, ui->processorLabel); | 263 | labelsForClipboard << qMakePair(ui->processor, ui->processorLabel); | ||
264 | englishTextForClipboard += QStringLiteral("Processors: %1\n").arg(processorLabel); | ||||
250 | } | 265 | } | ||
251 | 266 | | |||
252 | const qlonglong totalRam = calculateTotalRam(); | 267 | const qlonglong totalRam = calculateTotalRam(); | ||
253 | const QString memoryLabel = totalRam > 0 | 268 | const QString memoryLabel = totalRam > 0 | ||
254 | ? i18nc("@label %1 is the formatted amount of system memory (e.g. 7,7 GiB)", | 269 | ? i18nc("@label %1 is the formatted amount of system memory (e.g. 7,7 GiB)", | ||
255 | "%1 of RAM", KFormat().formatByteSize(totalRam)) | 270 | "%1 of RAM", KFormat().formatByteSize(totalRam)) | ||
256 | : i18nc("Unknown amount of RAM", "Unknown"); | 271 | : i18nc("Unknown amount of RAM", "Unknown"); | ||
257 | ui->memoryLabel->setText(memoryLabel); | 272 | ui->memoryLabel->setText(memoryLabel); | ||
258 | labelsForClipboard << qMakePair(ui->memory, ui->memoryLabel); | 273 | labelsForClipboard << qMakePair(ui->memory, ui->memoryLabel); | ||
274 | englishTextForClipboard += QStringLiteral("Memory: %1\n").arg(KFormat().formatByteSize(totalRam)); | ||||
259 | } | 275 | } | ||
260 | 276 | | |||
261 | void Module::copyToClipboard() | 277 | void Module::copyToClipboard() | ||
262 | { | 278 | { | ||
263 | QString text; | 279 | QString text; | ||
264 | // note that this loop does not necessarily represent the same order as in the GUI | 280 | // note that this loop does not necessarily represent the same order as in the GUI | ||
265 | for (auto labelPair : qAsConst(labelsForClipboard)) { | 281 | for (auto labelPair : qAsConst(labelsForClipboard)) { | ||
266 | const auto valueLabel = labelPair.second; | 282 | const auto valueLabel = labelPair.second; | ||
267 | if (!valueLabel->isHidden()) { | 283 | if (!valueLabel->isHidden()) { | ||
268 | const auto descriptionLabelText = labelPair.first->text(); | 284 | const auto descriptionLabelText = labelPair.first->text(); | ||
269 | const auto valueLabelText = valueLabel->text(); | 285 | const auto valueLabelText = valueLabel->text(); | ||
270 | text += i18nc("%1 is a label already including a colon, %2 is the corresponding value", "%1 %2", descriptionLabelText, valueLabelText) + QStringLiteral("\n"); | 286 | text += i18nc("%1 is a label already including a colon, %2 is the corresponding value", "%1 %2", descriptionLabelText, valueLabelText) + QStringLiteral("\n"); | ||
271 | } | 287 | } | ||
272 | } | 288 | } | ||
273 | 289 | | |||
274 | QGuiApplication::clipboard()->setText(text); | 290 | QGuiApplication::clipboard()->setText(text); | ||
275 | } | 291 | } | ||
276 | 292 | | |||
293 | void Module::copyToClipboardInEnglish() | ||||
294 | { | ||||
295 | QGuiApplication::clipboard()->setText(englishTextForClipboard); | ||||
296 | } | ||||
297 | | ||||
277 | QString Module::plasmaVersion() const | 298 | QString Module::plasmaVersion() const | ||
278 | { | 299 | { | ||
279 | const QStringList &filePaths = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, | 300 | const QStringList &filePaths = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, | ||
280 | QStringLiteral("xsessions/plasma.desktop")); | 301 | QStringLiteral("xsessions/plasma.desktop")); | ||
281 | 302 | | |||
282 | if (filePaths.length() < 1) { | 303 | if (filePaths.length() < 1) { | ||
283 | return QString(); | 304 | return QString(); | ||
284 | } | 305 | } | ||
285 | 306 | | |||
286 | // Despite the fact that there can be multiple desktop files we simply take | 307 | // Despite the fact that there can be multiple desktop files we simply take | ||
287 | // the first one as users usually don't have xsessions/ in their $HOME | 308 | // the first one as users usually don't have xsessions/ in their $HOME | ||
288 | // data location, so the first match should (usually) be the only one and | 309 | // data location, so the first match should (usually) be the only one and | ||
289 | // reflect the plasma session run. | 310 | // reflect the plasma session run. | ||
290 | KDesktopFile desktopFile(filePaths.first()); | 311 | KDesktopFile desktopFile(filePaths.first()); | ||
291 | return desktopFile.desktopGroup().readEntry("X-KDE-PluginInfo-Version", QString()); | 312 | return desktopFile.desktopGroup().readEntry("X-KDE-PluginInfo-Version", QString()); | ||
292 | } | 313 | } |