Warning, file /utilities/kdebugsettings/src/kdebugsettingsdialog.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002     SPDX-FileCopyrightText: 2015-2023 Laurent Montel <montel@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 
0006 */
0007 
0008 #include "kdebugsettingsdialog.h"
0009 #include "categorywarning.h"
0010 #include "customdebugsettingspage.h"
0011 #include "environmentsettingsrulespage.h"
0012 #include "groupmanagementdialog.h"
0013 #include "kdeapplicationdebugsettingpage.h"
0014 #include "kdebugsettings_debug.h"
0015 #include "kdebugsettingsutil.h"
0016 #include "loadgroupmenu.h"
0017 #include "loadtoolbutton.h"
0018 #include "saverulesjob.h"
0019 #include "savetoolbutton.h"
0020 
0021 #include <KConfigGroup>
0022 #include <KLocalizedString>
0023 #include <KMessageBox>
0024 #include <KSharedConfig>
0025 #include <KWindowConfig>
0026 
0027 #include <QDesktopServices>
0028 #include <QDialogButtonBox>
0029 #include <QDir>
0030 #include <QFileDialog>
0031 #include <QInputDialog>
0032 #include <QPushButton>
0033 #include <QTabWidget>
0034 #include <QUrl>
0035 #include <QVBoxLayout>
0036 #include <QWindow>
0037 
0038 #include <KAboutData>
0039 #include <KHelpMenu>
0040 
0041 namespace
0042 {
0043 constexpr char KDebugSettingsDialogGroupName[] = "KDebugSettingsDialog";
0044 }
0045 KDebugSettingsDialog::KDebugSettingsDialog(QWidget *parent)
0046     : QDialog(parent)
0047     , mTabWidget(new QTabWidget(this))
0048     , mKdeApplicationSettingsPage(new KDEApplicationDebugSettingPage(this))
0049     , mCustomSettingsPage(new CustomDebugSettingsPage(this))
0050     , mEnvironmentSettingsRulesPage(new EnvironmentSettingsRulesPage(this))
0051     , mCategoryWarning(new CategoryWarning(this))
0052     , mLoadToolButton(new LoadToolButton(this))
0053 {
0054     auto mainLayout = new QVBoxLayout(this);
0055 
0056     mCategoryWarning->setObjectName(QStringLiteral("categorywarning"));
0057     mainLayout->addWidget(mCategoryWarning);
0058 
0059     mTabWidget->setObjectName(QStringLiteral("tabwidget"));
0060     mainLayout->addWidget(mTabWidget);
0061 
0062     mKdeApplicationSettingsPage->setObjectName(QStringLiteral("kdeapplicationsettingspage"));
0063     mCustomSettingsPage->setObjectName(QStringLiteral("customsettingspage"));
0064     mEnvironmentSettingsRulesPage->setObjectName(QStringLiteral("environmentsettingsrulespage"));
0065     mTabWidget->addTab(mKdeApplicationSettingsPage, i18n("KDE Application"));
0066     mTabWidget->addTab(mCustomSettingsPage, i18n("Custom Rules"));
0067     mTabWidget->addTab(mEnvironmentSettingsRulesPage, i18n("Rules Settings With Environment Variable"));
0068     mTabWidget->setFocusPolicy(Qt::NoFocus);
0069 
0070     auto buttonBox = new QDialogButtonBox(QDialogButtonBox::RestoreDefaults | QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::Help
0071                                               | QDialogButtonBox::Apply,
0072                                           this);
0073     buttonBox->setObjectName(QStringLiteral("buttonbox"));
0074 
0075     auto saveAs = new SaveToolButton(this);
0076     saveAs->setText(i18n("Save As..."));
0077     saveAs->setObjectName(QStringLiteral("saveas_button"));
0078     buttonBox->addButton(saveAs, QDialogButtonBox::ActionRole);
0079     connect(saveAs, &SaveToolButton::saveAsFile, this, &KDebugSettingsDialog::slotSaveAs);
0080     connect(saveAs, &SaveToolButton::saveAsGroup, this, &KDebugSettingsDialog::slotSaveAsGroup);
0081 
0082     mLoadToolButton->setObjectName(QStringLiteral("load_button"));
0083     buttonBox->addButton(mLoadToolButton, QDialogButtonBox::ActionRole);
0084     connect(mLoadToolButton, &LoadToolButton::loadFromFile, this, &KDebugSettingsDialog::slotLoad);
0085     connect(mLoadToolButton, &LoadToolButton::loadGroupRequested, this, &KDebugSettingsDialog::slotLoadGroup);
0086     connect(mLoadToolButton, &LoadToolButton::manageGroupRequested, this, &KDebugSettingsDialog::slotManageGroup);
0087     connect(this, &KDebugSettingsDialog::updateLoadGroupMenu, mLoadToolButton, &LoadToolButton::updateLoadGroupMenu);
0088 
0089     auto insertCategories = new QPushButton(i18n("Insert..."), this);
0090     insertCategories->setObjectName(QStringLiteral("insert_button"));
0091     buttonBox->addButton(insertCategories, QDialogButtonBox::ActionRole);
0092     connect(insertCategories, &QPushButton::clicked, this, &KDebugSettingsDialog::slotInsertCategories);
0093 
0094     connect(buttonBox, &QDialogButtonBox::accepted, this, &KDebugSettingsDialog::slotAccepted);
0095     connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
0096     auto helpMenu = new KHelpMenu(this, KAboutData::applicationData(), false);
0097     buttonBox->button(QDialogButtonBox::Help)->setMenu(helpMenu->menu());
0098 
0099     connect(buttonBox->button(QDialogButtonBox::Apply), &QPushButton::clicked, this, &KDebugSettingsDialog::slotApply);
0100     connect(buttonBox->button(QDialogButtonBox::RestoreDefaults), &QPushButton::clicked, this, &KDebugSettingsDialog::slotRestoreDefault);
0101     mainLayout->addWidget(buttonBox);
0102     readConfig();
0103     readQtLoggingFile();
0104     mKdeApplicationSettingsPage->forceFocus();
0105 }
0106 
0107 KDebugSettingsDialog::~KDebugSettingsDialog()
0108 {
0109     saveConfig();
0110 }
0111 
0112 void KDebugSettingsDialog::readConfig()
0113 {
0114     create(); // ensure a window is created
0115     windowHandle()->resize(QSize(600, 300));
0116     KConfigGroup group(KSharedConfig::openStateConfig(), KDebugSettingsDialogGroupName);
0117     KWindowConfig::restoreWindowSize(windowHandle(), group);
0118     resize(windowHandle()->size()); // workaround for QTBUG-40584
0119 }
0120 
0121 void KDebugSettingsDialog::saveConfig()
0122 {
0123     KConfigGroup group(KSharedConfig::openStateConfig(), QLatin1String(KDebugSettingsDialogGroupName));
0124     KWindowConfig::saveWindowSize(windowHandle(), group);
0125 }
0126 
0127 void KDebugSettingsDialog::slotLoadGroup(const QString &fullPath)
0128 {
0129     if (!fullPath.isEmpty()) {
0130         mLoggings.readCategoriesFiles(fullPath);
0131         updateLoggingCategories();
0132     }
0133 }
0134 
0135 void KDebugSettingsDialog::readQtLoggingFile()
0136 {
0137     mLoggings.readQtLoggingFile();
0138     updateLoggingCategories();
0139 }
0140 
0141 void KDebugSettingsDialog::updateLoggingCategories()
0142 {
0143     if (!mLoggings.environmentrules().isEmpty()) {
0144         mEnvironmentSettingsRulesPage->setRules(mLoggings.environmentrules());
0145     }
0146     const LoggingCategory::List customCategories = mLoggings.customCategories();
0147     const LoggingCategory::List qtKdeCategories = mLoggings.qtKdeCategories();
0148     const bool foundOverrideRule = mLoggings.foundOverrideRule();
0149 
0150     mKdeApplicationSettingsPage->fillList(qtKdeCategories);
0151     mCustomSettingsPage->fillList(customCategories);
0152     if (foundOverrideRule) {
0153         mCategoryWarning->animatedShow();
0154     }
0155     mCategoriesList = mLoggings.categoriesList();
0156 }
0157 
0158 bool KDebugSettingsDialog::saveRules(const QString &path, bool forceSavingAllRules)
0159 {
0160     SaveRulesJob job;
0161     job.setFileName(path);
0162     job.setListCustom(mCustomSettingsPage->rules());
0163     job.setListKde(mKdeApplicationSettingsPage->rules(forceSavingAllRules));
0164     if (!job.start()) {
0165         KMessageBox::error(this, i18n("\'%1\' cannot be opened. Please verify it.", path));
0166         return false;
0167     }
0168     return true;
0169 }
0170 
0171 bool KDebugSettingsDialog::saveInQtLogging()
0172 {
0173     return saveRules(KDebugSettingsUtil::qtFileName());
0174 }
0175 
0176 void KDebugSettingsDialog::slotAccepted()
0177 {
0178     if (saveInQtLogging()) {
0179         accept();
0180     }
0181 }
0182 
0183 void KDebugSettingsDialog::slotApply()
0184 {
0185     saveInQtLogging();
0186 }
0187 
0188 void KDebugSettingsDialog::slotInsertCategories()
0189 {
0190     const QString path =
0191         QFileDialog::getOpenFileName(this, i18n("Insert Categories"), QString(), QStringLiteral("%1 (*.categories)").arg(i18n("Categories Files")));
0192     if (!path.isEmpty()) {
0193         const KdeLoggingCategory::List insertCategoriesList = KDebugSettingsUtil::readLoggingCategoriesForInserting(path, mCategoriesList);
0194         LoggingCategory::List newCategories;
0195         for (const KdeLoggingCategory &cat : std::as_const(insertCategoriesList)) {
0196             LoggingCategory loggingCat;
0197             loggingCat.description = cat.description;
0198             loggingCat.categoryName = cat.categoryName;
0199             loggingCat.defaultSeverityType = KDebugSettingsUtil::convertCategoryTypeFromString(cat.defaultSeverity);
0200             if (loggingCat.isValid()) {
0201                 newCategories.append(loggingCat);
0202             }
0203         }
0204         mKdeApplicationSettingsPage->insertCategories(newCategories);
0205         KMessageBox::information(this, i18n("Categories from file \'%1\' inserted.", path), i18n("Insert Categories"));
0206     }
0207 }
0208 
0209 void KDebugSettingsDialog::slotSaveAsGroup()
0210 {
0211     const QString groupPath = LoadGroupMenu::defaultWritableGroupPath();
0212     bool ok = false;
0213     const QString name = QInputDialog::getText(this, i18n("Group Name"), i18n("Name:"), QLineEdit::Normal, QString(), &ok);
0214     if (ok) {
0215         const QString trimmedName = name.trimmed();
0216         if (!trimmedName.isEmpty()) {
0217             if (mLoadToolButton->groupNames().contains(trimmedName)) {
0218                 KMessageBox::error(this, i18n("<b>\'%1\'</b> is already used as a group name.\nPlease save as another name.", trimmedName));
0219             } else {
0220                 if (!QDir().mkpath(groupPath)) {
0221                     qCWarning(KDEBUGSETTINGS_LOG) << "Unable to create folder: " << groupPath;
0222                 }
0223                 saveRules(groupPath + QLatin1Char('/') + trimmedName, true);
0224                 Q_EMIT updateLoadGroupMenu();
0225             }
0226         } else {
0227             KMessageBox::error(this, i18n("Can not save as empty name. Please use a new one."));
0228         }
0229     }
0230 }
0231 
0232 void KDebugSettingsDialog::slotSaveAs()
0233 {
0234     const QString path = QFileDialog::getSaveFileName(this, i18n("Save As"), QString(), i18n("KDebugSettings File (*.kdebugsettingsrules)"));
0235     if (!path.isEmpty()) {
0236         saveRules(path, true);
0237     }
0238 }
0239 
0240 void KDebugSettingsDialog::slotLoad()
0241 {
0242     const QString path = QFileDialog::getOpenFileName(this, i18n("Load Debug Settings Files"), QString(), i18n("KDebugSettings File (*.kdebugsettingsrules)"));
0243     if (!path.isEmpty()) {
0244         mLoggings.readCategoriesFiles(path);
0245         updateLoggingCategories();
0246     }
0247 }
0248 
0249 void KDebugSettingsDialog::slotRestoreDefault()
0250 {
0251     mKdeApplicationSettingsPage->restoreToDefault();
0252 }
0253 
0254 void KDebugSettingsDialog::slotManageGroup()
0255 {
0256     auto groupManagementDialog = new GroupManagementDialog(this);
0257     connect(groupManagementDialog, &GroupManagementDialog::groupsChanged, this, &KDebugSettingsDialog::updateLoadGroupMenu);
0258     groupManagementDialog->exec();
0259     delete groupManagementDialog;
0260 }