File indexing completed on 2024-06-16 04:16:26

0001 /*
0002  * SPDX-FileCopyrightText: 2017 Boudewijn Rempt <boud@valdyas.org>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #include "dlg_buginfo.h"
0008 
0009 #include <klocalizedstring.h>
0010 #include <kis_debug.h>
0011 #include <opengl/kis_opengl.h>
0012 #include <KritaVersionWrapper.h>
0013 #include <QSysInfo>
0014 #include <kis_image_config.h>
0015 #include <QDesktopWidget>
0016 #include <QClipboard>
0017 #include <QThread>
0018 #include <QFile>
0019 #include <QFileInfo>
0020 #include <QSettings>
0021 #include <QStandardPaths>
0022 #include <KoFileDialog.h>
0023 #include <QMessageBox>
0024 
0025 #include <QScreen>
0026 
0027 #ifdef Q_OS_ANDROID
0028 #include <QtAndroid>
0029 #endif
0030 
0031 DlgBugInfo::DlgBugInfo(QWidget *parent, KoDialog::ButtonCodes customButtons)
0032     : KoDialog(parent)
0033     , m_page(new WdgBugInfo(this))
0034 {
0035     setCaption(i18n("Please paste this information in your bug report"));
0036 
0037     setButtons(User1 | User2 | Ok | customButtons);
0038     setButtonText(User1, i18n("Copy to clipboard"));
0039     setButtonText(User2, i18n("Save to file"));
0040     setDefaultButton(Ok);
0041 
0042     Q_CHECK_PTR(m_page);
0043 
0044     setMainWidget(m_page);
0045 
0046     connect(this, &KoDialog::user1Clicked, this, [this](){
0047         QGuiApplication::clipboard()->setText(m_page->txtBugInfo->toPlainText());
0048         m_page->txtBugInfo->selectAll(); // feedback
0049     });
0050 
0051     connect(this, &KoDialog::user2Clicked, this, &DlgBugInfo::saveToFile);
0052 
0053 }
0054 
0055 void DlgBugInfo::initialize()
0056 {
0057     initializeText();
0058     setCaption(captionText());
0059 }
0060 
0061 void DlgBugInfo::initializeText()
0062 {
0063     const QString configPath = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation);
0064     QSettings kritarc(configPath + QStringLiteral("/kritadisplayrc"), QSettings::IniFormat);
0065 
0066     QString info = infoText(kritarc);
0067 
0068     m_page->txtBugInfo->setText(info);
0069 }
0070 
0071 void DlgBugInfo::saveToFile()
0072 {
0073     KoFileDialog dlg(this, KoFileDialog::SaveFile, i18n("Save to file"));
0074     dlg.setDefaultDir(QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation) + "/" + defaultNewFileName());
0075     dlg.setMimeTypeFilters(QStringList("text/plain"), "text/plain");
0076     QString filename = dlg.filename();
0077 
0078     if (filename.isEmpty()) {
0079         return;
0080     } else {
0081 
0082         QFile file(filename);
0083         if (!file.open(QIODevice::WriteOnly)) {
0084             QMessageBox::information(this, i18n("Unable to open file"),
0085                 file.errorString());
0086             return;
0087         }
0088 
0089         QTextStream out(&file);
0090         out.setCodec("UTF-8");
0091         QString originalLogFileName = originalFileName();
0092         if (originalLogFileName.isEmpty() && QFileInfo(originalLogFileName).exists()) {
0093             QFile src(originalLogFileName);
0094             out << src.readAll();
0095             src.close();
0096         } else {
0097             out << m_page->txtBugInfo->toPlainText();
0098         }
0099         file.close();
0100     }
0101 }
0102 
0103 QString DlgBugInfo::basicSystemInformationReplacementText()
0104 {
0105     QString info;
0106 
0107     // Krita version info
0108     info.append("Krita");
0109     info.append("\n  Version: ").append(KritaVersionWrapper::versionString(true));
0110     info.append("\n\n");
0111 
0112     info.append("Qt");
0113     info.append("\n  Version (compiled): ").append(QT_VERSION_STR);
0114     info.append("\n  Version (loaded): ").append(qVersion());
0115     info.append("\n\n");
0116 
0117     // OS information
0118     info.append("OS Information");
0119     info.append("\n  Build ABI: ").append(QSysInfo::buildAbi());
0120     info.append("\n  Build CPU: ").append(QSysInfo::buildCpuArchitecture());
0121     info.append("\n  CPU: ").append(QSysInfo::currentCpuArchitecture());
0122     info.append("\n  Kernel Type: ").append(QSysInfo::kernelType());
0123     info.append("\n  Kernel Version: ").append(QSysInfo::kernelVersion());
0124     info.append("\n  Pretty Productname: ").append(QSysInfo::prettyProductName());
0125     info.append("\n  Product Type: ").append(QSysInfo::productType());
0126     info.append("\n  Product Version: ").append(QSysInfo::productVersion());
0127 #ifdef Q_OS_ANDROID
0128     QString manufacturer =
0129         QAndroidJniObject::getStaticObjectField("android/os/Build", "MANUFACTURER", "Ljava/lang/String;").toString();
0130     const QString model =
0131         QAndroidJniObject::getStaticObjectField("android/os/Build", "MODEL", "Ljava/lang/String;").toString();
0132     manufacturer[0] = manufacturer[0].toUpper();
0133     info.append("\n  Product Model: ").append(manufacturer + " " + model);
0134 #endif
0135     info.append("\n\n");
0136 
0137     // OpenGL information
0138     info.append("\n").append(KisOpenGL::getDebugText());
0139     info.append("\n\n");
0140     // Hardware information
0141     info.append("Hardware Information");
0142     info.append(QString("\n Memory: %1").arg(KisImageConfig(true).totalRAM() / 1024)).append(" Gb");
0143     info.append(QString("\n Cores: %1").arg(QThread::idealThreadCount()));
0144     info.append("\n Swap: ").append(KisImageConfig(true).swapDir());
0145 
0146     return info;
0147 }
0148 
0149 QString DlgBugInfo::infoText(QSettings& kritarc)
0150 {
0151     QString info;
0152 
0153     if (!kritarc.value("LogUsage", true).toBool() || !QFileInfo(originalFileName()).exists()) {
0154 
0155         // NOTE: This is intentionally not translated!
0156 
0157         info.append(replacementWarningText());
0158         info.append("File name and location: " + originalFileName());
0159         info.append("------------------------------------");
0160         info.append("\n\n");
0161 
0162         info.append(basicSystemInformationReplacementText());
0163     }
0164     else {
0165 
0166         QFile log(originalFileName());
0167         log.open(QFile::ReadOnly | QFile::Text);
0168         info += QString::fromUtf8(log.readAll());
0169         log.close();
0170     }
0171 
0172     return info;
0173 
0174 }
0175 
0176 DlgBugInfo::~DlgBugInfo()
0177 {
0178     delete m_page;
0179 }