File indexing completed on 2024-05-12 05:52:36

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