File indexing completed on 2024-04-28 05:49:28
0001 /* This file is part of the KDE project 0002 SPDX-FileCopyrightText: 2001 Christoph Cullmann <cullmann@kde.org> 0003 SPDX-FileCopyrightText: 2002 Joseph Wenninger <jowenn@kde.org> 0004 SPDX-FileCopyrightText: 2007 Mirko Stocker <me@misto.ch> 0005 0006 For the addScrollablePage original 0007 SPDX-FileCopyrightText: 2003 Benjamin C Meyer <ben+kdelibs at meyerhome dot net> 0008 SPDX-FileCopyrightText: 2003 Waldo Bastian <bastian@kde.org> 0009 SPDX-FileCopyrightText: 2004 Michael Brade <brade@kde.org> 0010 SPDX-FileCopyrightText: 2021 Ahmad Samir <a.samirh78@gmail.com> 0011 0012 SPDX-License-Identifier: LGPL-2.0-only 0013 */ 0014 0015 #include "kateconfigdialog.h" 0016 0017 #include "kateapp.h" 0018 #include "kateconfigplugindialogpage.h" 0019 #include "katedebug.h" 0020 #include "katedocmanager.h" 0021 #include "katemainwindow.h" 0022 #include "katepluginmanager.h" 0023 #include "katequickopenmodel.h" 0024 #include "katesessionmanager.h" 0025 #include "kateviewmanager.h" 0026 0027 #include <KConfigGroup> 0028 #include <KLocalizedString> 0029 #include <KMessageBox> 0030 #include <KPluralHandlingSpinBox> 0031 #include <KSharedConfig> 0032 #include <kwidgetsaddons_version.h> 0033 0034 #include <QCheckBox> 0035 #include <QComboBox> 0036 #include <QDesktopServices> 0037 #include <QDialogButtonBox> 0038 #include <QFrame> 0039 #include <QGroupBox> 0040 #include <QLabel> 0041 #include <QLineEdit> 0042 #include <QListView> 0043 #include <QPainter> 0044 #include <QScreen> 0045 #include <QScrollArea> 0046 #include <QScrollBar> 0047 #include <QTimer> 0048 #include <QVBoxLayout> 0049 0050 KateConfigDialog::KateConfigDialog(KateMainWindow *parent) 0051 : KPageDialog(parent) 0052 , m_mainWindow(parent) 0053 { 0054 setWindowTitle(i18n("Configure")); 0055 setWindowIcon(QIcon::fromTheme(QStringLiteral("configure"))); 0056 setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Apply | QDialogButtonBox::Cancel | QDialogButtonBox::Help); 0057 0058 // we may have a lot of pages on Kate, we want small icons for the list 0059 if (KateApp::isKate()) { 0060 setFaceType(KPageDialog::FlatList); 0061 } else { 0062 setFaceType(KPageDialog::List); 0063 } 0064 0065 const auto listViews = findChildren<QListView *>(); 0066 for (auto *lv : listViews) { 0067 if (qstrcmp(lv->metaObject()->className(), "KDEPrivate::KPageListView") == 0) { 0068 m_sideBar = lv; 0069 break; 0070 } 0071 } 0072 if (!m_sideBar) { 0073 qWarning() << "Unable to find config dialog sidebar listview!!"; 0074 } 0075 0076 // first: add the KTextEditor config pages 0077 // rational: most people want to alter e.g. the fonts, the colors or some other editor stuff first 0078 addEditorPages(); 0079 0080 // second: add out own config pages 0081 // this includes all plugin config pages, added to the bottom 0082 addBehaviorPage(); 0083 addSessionPage(); 0084 addFeedbackPage(); 0085 0086 // no plugins for KWrite 0087 if (KateApp::isKate()) { 0088 addPluginsPage(); 0089 addPluginPages(); 0090 } 0091 0092 // ensure no stray signals already set this! 0093 m_dataChanged = false; 0094 buttonBox()->button(QDialogButtonBox::Apply)->setEnabled(false); 0095 0096 // handle dialog actions 0097 connect(this, &KateConfigDialog::accepted, this, &KateConfigDialog::slotApply); 0098 connect(buttonBox()->button(QDialogButtonBox::Apply), &QPushButton::clicked, this, &KateConfigDialog::slotApply); 0099 connect(buttonBox()->button(QDialogButtonBox::Help), &QPushButton::clicked, this, &KateConfigDialog::slotHelp); 0100 } 0101 0102 QSize KateConfigDialog::sizeHint() const 0103 { 0104 // start with a bit enlarged default size hint to minimize changes of useless scrollbars 0105 QSize size = KPageDialog::sizeHint() * 1.3; 0106 0107 // enlarge it to half of the main window size, if that is larger 0108 size = size.expandedTo(m_mainWindow->size() * 0.5); 0109 0110 // return bounded size to available real screen space 0111 return size.boundedTo(screen()->availableSize() * 0.9); 0112 } 0113 0114 void KateConfigDialog::addBehaviorPage() 0115 { 0116 KSharedConfig::Ptr config = KSharedConfig::openConfig(); 0117 KConfigGroup cgGeneral = KConfigGroup(config, QStringLiteral("General")); 0118 0119 QFrame *generalFrame = new QFrame; 0120 KPageWidgetItem *item = addScrollablePage(generalFrame, i18n("Behavior")); 0121 m_allPages.insert(item); 0122 item->setHeader(i18n("Behavior Options")); 0123 item->setIcon(QIcon::fromTheme(QStringLiteral("preferences-system-windows-behavior"))); 0124 0125 QVBoxLayout *layout = new QVBoxLayout(generalFrame); 0126 0127 // GROUP with the one below: "Behavior" 0128 QGroupBox *buttonGroup = new QGroupBox(i18n("&Behavior"), generalFrame); 0129 QVBoxLayout *vbox = new QVBoxLayout; 0130 layout->addWidget(buttonGroup); 0131 0132 // shall we try to behave like some SDI application 0133 m_sdiMode = new QCheckBox(i18n("Open each document in its own window"), buttonGroup); 0134 m_sdiMode->setChecked(cgGeneral.readEntry("SDI Mode", false)); 0135 m_sdiMode->setToolTip( 0136 i18n("If enabled, each document will be opened in its own window. " 0137 "If not enabled, each document will be opened in a new tab in the current window.")); 0138 connect(m_sdiMode, &QCheckBox::toggled, this, &KateConfigDialog::slotChanged); 0139 vbox->addWidget(m_sdiMode); 0140 0141 QHBoxLayout *hlayout = nullptr; 0142 QLabel *label = nullptr; 0143 0144 if (KateApp::isKate()) { 0145 hlayout = new QHBoxLayout; 0146 label = new QLabel(i18n("&Switch to output view upon message type:"), buttonGroup); 0147 hlayout->addWidget(label); 0148 m_messageTypes = new QComboBox(buttonGroup); 0149 hlayout->addWidget(m_messageTypes); 0150 label->setBuddy(m_messageTypes); 0151 m_messageTypes->addItems({i18n("Never"), i18n("Error"), i18n("Warning"), i18n("Info"), i18n("Log")}); 0152 m_messageTypes->setCurrentIndex(cgGeneral.readEntry("Show output view for message type", 1)); 0153 connect(m_messageTypes, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &KateConfigDialog::slotChanged); 0154 vbox->addLayout(hlayout); 0155 0156 hlayout = new QHBoxLayout; 0157 label = new QLabel(i18n("&Limit output view history:"), buttonGroup); 0158 hlayout->addWidget(label); 0159 m_outputHistoryLimit = new QSpinBox(buttonGroup); 0160 hlayout->addWidget(m_outputHistoryLimit); 0161 label->setBuddy(m_outputHistoryLimit); 0162 m_outputHistoryLimit->setRange(-1, 10000); 0163 m_outputHistoryLimit->setSpecialValueText(i18n("Unlimited")); 0164 m_outputHistoryLimit->setValue(cgGeneral.readEntry("Output History Limit", 100)); 0165 connect(m_outputHistoryLimit, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &KateConfigDialog::slotChanged); 0166 vbox->addLayout(hlayout); 0167 } 0168 0169 // modified files notification 0170 m_modNotifications = new QCheckBox(i18n("Use a separate &dialog for handling externally modified files"), buttonGroup); 0171 m_modNotifications->setChecked(m_mainWindow->modNotificationEnabled()); 0172 m_modNotifications->setToolTip( 0173 i18n("If enabled, a modal dialog will be used to show all of the modified files. " 0174 "If not enabled, you will be individually asked what to do for each modified file " 0175 "only when that file's view receives focus.")); 0176 connect(m_modNotifications, &QCheckBox::toggled, this, &KateConfigDialog::slotChanged); 0177 0178 vbox->addWidget(m_modNotifications); 0179 buttonGroup->setLayout(vbox); 0180 0181 if (KateApp::isKate()) { 0182 QGroupBox *buttonGroup = new QGroupBox(i18n("&Sidebars"), generalFrame); 0183 layout->addWidget(buttonGroup); 0184 QVBoxLayout *vbox = new QVBoxLayout; 0185 m_syncSectionSizeWithSidebarTabs = new QCheckBox(i18n("Sync section size with tab positions"), buttonGroup); 0186 m_syncSectionSizeWithSidebarTabs->setChecked(cgGeneral.readEntry("Sync section size with tab positions", false)); 0187 m_syncSectionSizeWithSidebarTabs->setToolTip( 0188 i18n("When enabled the section size will be determined by the position of the tabs.\n" 0189 "This option does not affect the bottom sidebar.")); 0190 connect(m_syncSectionSizeWithSidebarTabs, &QCheckBox::toggled, this, &KateConfigDialog::slotChanged); 0191 vbox->addWidget(m_syncSectionSizeWithSidebarTabs); 0192 0193 m_showTextForLeftRightSidebars = new QCheckBox(i18n("Show text for left and right sidebar buttons"), buttonGroup); 0194 m_showTextForLeftRightSidebars->setChecked(cgGeneral.readEntry("Show text for left and right sidebar", false)); 0195 connect(m_showTextForLeftRightSidebars, &QCheckBox::toggled, this, &KateConfigDialog::slotChanged); 0196 vbox->addWidget(m_showTextForLeftRightSidebars); 0197 0198 label = new QLabel(i18n("Icon size for left and right sidebar buttons"), buttonGroup); 0199 m_leftRightSidebarsIconSize = new QSpinBox(buttonGroup); 0200 m_leftRightSidebarsIconSize->setMinimum(16); 0201 m_leftRightSidebarsIconSize->setMaximum(48); 0202 m_leftRightSidebarsIconSize->setValue(cgGeneral.readEntry("Icon size for left and right sidebar buttons", 32)); 0203 connect(m_leftRightSidebarsIconSize, &QSpinBox::textChanged, this, &KateConfigDialog::slotChanged); 0204 hlayout = new QHBoxLayout; 0205 hlayout->addWidget(label); 0206 hlayout->addWidget(m_leftRightSidebarsIconSize); 0207 vbox->addLayout(hlayout); 0208 0209 connect(m_showTextForLeftRightSidebars, &QCheckBox::toggled, this, [l = QPointer(label), this](bool v) { 0210 m_leftRightSidebarsIconSize->setEnabled(!v); 0211 l->setEnabled(!v); 0212 }); 0213 buttonGroup->setLayout(vbox); 0214 } 0215 0216 // tabbar => we allow to configure some limit on number of tabs to show 0217 buttonGroup = new QGroupBox(i18n("&Tabs"), generalFrame); 0218 vbox = new QVBoxLayout; 0219 buttonGroup->setLayout(vbox); 0220 hlayout = new QHBoxLayout; 0221 label = new QLabel(i18n("&Limit number of tabs:"), buttonGroup); 0222 hlayout->addWidget(label); 0223 m_tabLimit = new QSpinBox(buttonGroup); 0224 hlayout->addWidget(m_tabLimit); 0225 label->setBuddy(m_tabLimit); 0226 m_tabLimit->setRange(0, 256); 0227 m_tabLimit->setSpecialValueText(i18n("Unlimited")); 0228 m_tabLimit->setValue(cgGeneral.readEntry("Tabbar Tab Limit", 0)); 0229 connect(m_tabLimit, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &KateConfigDialog::slotChanged); 0230 vbox->addLayout(hlayout); 0231 label = 0232 new QLabel(i18n("A high limit can increase the window size, please enable 'Allow tab scrolling' to prevent it. Unlimited tabs are always scrollable.")); 0233 label->setWordWrap(true); 0234 vbox->addWidget(label); 0235 0236 m_autoHideTabs = new QCheckBox(i18n("&Auto hide tabs"), buttonGroup); 0237 m_autoHideTabs->setChecked(cgGeneral.readEntry("Auto Hide Tabs", KateApp::isKWrite())); 0238 m_autoHideTabs->setToolTip(i18n("When checked tabs will be hidden if only one document is open.")); 0239 connect(m_autoHideTabs, &QCheckBox::toggled, this, &KateConfigDialog::slotChanged); 0240 vbox->addWidget(m_autoHideTabs); 0241 0242 m_showTabCloseButton = new QCheckBox(i18n("&Show close button"), buttonGroup); 0243 m_showTabCloseButton->setChecked(cgGeneral.readEntry("Show Tabs Close Button", true)); 0244 m_showTabCloseButton->setToolTip(i18n("When checked each tab will display a close button.")); 0245 connect(m_showTabCloseButton, &QCheckBox::toggled, this, &KateConfigDialog::slotChanged); 0246 vbox->addWidget(m_showTabCloseButton); 0247 0248 m_expandTabs = new QCheckBox(i18n("&Expand tabs"), buttonGroup); 0249 m_expandTabs->setChecked(cgGeneral.readEntry("Expand Tabs", false)); 0250 m_expandTabs->setToolTip(i18n("When checked tabs take as much size as possible.")); 0251 connect(m_expandTabs, &QCheckBox::toggled, this, &KateConfigDialog::slotChanged); 0252 vbox->addWidget(m_expandTabs); 0253 0254 m_tabDoubleClickNewDocument = new QCheckBox(i18n("&Double click opens a new document"), buttonGroup); 0255 m_tabDoubleClickNewDocument->setChecked(cgGeneral.readEntry("Tab Double Click New Document", true)); 0256 m_tabDoubleClickNewDocument->setToolTip(i18n("When checked double click opens a new document.")); 0257 connect(m_tabDoubleClickNewDocument, &QCheckBox::toggled, this, &KateConfigDialog::slotChanged); 0258 vbox->addWidget(m_tabDoubleClickNewDocument); 0259 0260 m_tabMiddleClickCloseDocument = new QCheckBox(i18n("&Middle click closes a document"), buttonGroup); 0261 m_tabMiddleClickCloseDocument->setChecked(cgGeneral.readEntry("Tab Middle Click Close Document", true)); 0262 m_tabMiddleClickCloseDocument->setToolTip(i18n("When checked middle click closes a document.")); 0263 connect(m_tabMiddleClickCloseDocument, &QCheckBox::toggled, this, &KateConfigDialog::slotChanged); 0264 vbox->addWidget(m_tabMiddleClickCloseDocument); 0265 0266 m_tabsScrollable = new QCheckBox(i18n("Allow tab scrolling"), this); 0267 m_tabsScrollable->setChecked(cgGeneral.readEntry("Allow Tab Scrolling", true)); 0268 m_tabsScrollable->setToolTip(i18n("When checked this will allow scrolling in tab bar when number of tabs is large.")); 0269 connect(m_tabsScrollable, &QCheckBox::toggled, this, &KateConfigDialog::slotChanged); 0270 vbox->addWidget(m_tabsScrollable); 0271 0272 m_tabsElided = new QCheckBox(i18n("Elide tab text"), this); 0273 m_tabsElided->setChecked(cgGeneral.readEntry("Elide Tab Text", false)); 0274 m_tabsElided->setToolTip(i18n("When checked tab text might be elided if its too long.")); 0275 connect(m_tabsElided, &QCheckBox::toggled, this, &KateConfigDialog::slotChanged); 0276 vbox->addWidget(m_tabsElided); 0277 0278 m_openNewTabInFrontOfCurrent = new QCheckBox(i18n("Open new tab to the right of current tab."), this); 0279 m_openNewTabInFrontOfCurrent->setChecked(cgGeneral.readEntry("Open New Tab To The Right Of Current", false)); 0280 m_openNewTabInFrontOfCurrent->setToolTip(i18n("If unchecked the new tab will open at the end.")); 0281 connect(m_openNewTabInFrontOfCurrent, &QCheckBox::toggled, this, &KateConfigDialog::slotChanged); 0282 vbox->addWidget(m_openNewTabInFrontOfCurrent); 0283 0284 layout->addWidget(buttonGroup); 0285 0286 buttonGroup = new QGroupBox(i18n("&Mouse"), generalFrame); 0287 vbox = new QVBoxLayout; 0288 layout->addWidget(buttonGroup); 0289 0290 hlayout = new QHBoxLayout; 0291 label = new QLabel(i18n("&Backward button pressed:"), buttonGroup); 0292 hlayout->addWidget(label); 0293 m_mouseBackActions = new QComboBox(buttonGroup); 0294 hlayout->addWidget(m_mouseBackActions); 0295 label->setBuddy(m_mouseBackActions); 0296 m_mouseBackActions->addItems({i18n("Previous tab"), i18n("History back")}); 0297 m_mouseBackActions->setCurrentIndex(cgGeneral.readEntry("Mouse back button action", 0)); 0298 connect(m_mouseBackActions, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &KateConfigDialog::slotChanged); 0299 vbox->addLayout(hlayout); 0300 0301 hlayout = new QHBoxLayout; 0302 label = new QLabel(i18n("&Forward button pressed:"), buttonGroup); 0303 hlayout->addWidget(label); 0304 m_mouseForwardActions = new QComboBox(buttonGroup); 0305 hlayout->addWidget(m_mouseForwardActions); 0306 label->setBuddy(m_mouseForwardActions); 0307 m_mouseForwardActions->addItems({i18n("Next tab"), i18n("History forward")}); 0308 m_mouseForwardActions->setCurrentIndex(cgGeneral.readEntry("Mouse forward button action", 0)); 0309 connect(m_mouseForwardActions, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &KateConfigDialog::slotChanged); 0310 vbox->addLayout(hlayout); 0311 0312 buttonGroup->setLayout(vbox); 0313 0314 /** DIFF **/ 0315 buttonGroup = new QGroupBox(i18n("Diff"), generalFrame); 0316 vbox = new QVBoxLayout(buttonGroup); 0317 hlayout = new QHBoxLayout; 0318 vbox->addLayout(hlayout); 0319 layout->addWidget(buttonGroup); 0320 m_diffStyle = new QComboBox; 0321 m_diffStyle->addItem(i18n("Side By Side")); 0322 m_diffStyle->addItem(i18n("Unified")); 0323 m_diffStyle->addItem(i18n("Raw")); 0324 hlayout->addWidget(new QLabel(i18n("Diff Style:"))); 0325 hlayout->addWidget(m_diffStyle); 0326 m_diffStyle->setCurrentIndex(cgGeneral.readEntry("Diff Show Style", 0)); 0327 connect(m_diffStyle, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &KateConfigDialog::slotChanged); 0328 0329 buttonGroup = new QGroupBox(i18n("Navigation Bar"), generalFrame); 0330 vbox = new QVBoxLayout(buttonGroup); 0331 hlayout = new QHBoxLayout; 0332 vbox->addLayout(hlayout); 0333 layout->addWidget(buttonGroup); 0334 m_urlBarShowSymbols = new QCheckBox(i18n("Show current symbol in navigation bar")); 0335 hlayout->addWidget(m_urlBarShowSymbols); 0336 m_urlBarShowSymbols->setChecked(cgGeneral.readEntry("Show Symbol In Navigation Bar", true)); 0337 connect(m_urlBarShowSymbols, &QCheckBox::toggled, this, &KateConfigDialog::slotChanged); 0338 0339 buttonGroup = new QGroupBox(i18n("Diagnostics"), generalFrame); 0340 vbox = new QVBoxLayout(buttonGroup); 0341 hlayout = new QHBoxLayout; 0342 vbox->addLayout(hlayout); 0343 layout->addWidget(buttonGroup); 0344 label = new QLabel(i18n("Diagnostics limit:"), buttonGroup); 0345 m_diagnosticsLimit = new QSpinBox(buttonGroup); 0346 m_diagnosticsLimit->setRange(-1, 50000); 0347 m_diagnosticsLimit->setSpecialValueText(i18n("Unlimited")); 0348 m_diagnosticsLimit->setValue(cgGeneral.readEntry("Diagnostics Limit", 12000)); 0349 m_diagnosticsLimit->setToolTip(i18n("Max number of diagnostics allowed in the Diagnostics toolview.")); 0350 label->setBuddy(m_diagnosticsLimit); 0351 hlayout->addWidget(label); 0352 hlayout->addWidget(m_diagnosticsLimit); 0353 connect(m_diagnosticsLimit, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &KateConfigDialog::slotChanged); 0354 0355 layout->addStretch(1); // :-] works correct without autoadd 0356 } 0357 0358 void KateConfigDialog::addSessionPage() 0359 { 0360 KSharedConfig::Ptr config = KSharedConfig::openConfig(); 0361 KConfigGroup cgGeneral = KConfigGroup(config, QStringLiteral("General")); 0362 0363 QWidget *sessionsPage = new QWidget(); 0364 auto item = addScrollablePage(sessionsPage, i18n("Session")); 0365 m_allPages.insert(item); 0366 item->setHeader(i18n("Session Management")); 0367 item->setIcon(QIcon::fromTheme(QStringLiteral("view-history"))); 0368 0369 sessionConfigUi.setupUi(sessionsPage); 0370 0371 // save meta infos 0372 sessionConfigUi.saveMetaInfos->setChecked(KateApp::self()->documentManager()->getSaveMetaInfos()); 0373 connect(sessionConfigUi.saveMetaInfos, &QGroupBox::toggled, this, &KateConfigDialog::slotChanged); 0374 0375 // meta infos days 0376 sessionConfigUi.daysMetaInfos->setMaximum(180); 0377 sessionConfigUi.daysMetaInfos->setSpecialValueText(i18nc("The special case of 'Delete unused meta-information after'", "(never)")); 0378 sessionConfigUi.daysMetaInfos->setSuffix(ki18ncp("The suffix of 'Delete unused meta-information after'", " day", " days")); 0379 sessionConfigUi.daysMetaInfos->setValue(KateApp::self()->documentManager()->getDaysMetaInfos()); 0380 connect(sessionConfigUi.daysMetaInfos, 0381 static_cast<void (KPluralHandlingSpinBox::*)(int)>(&KPluralHandlingSpinBox::valueChanged), 0382 this, 0383 &KateConfigDialog::slotChanged); 0384 0385 // restore view config 0386 sessionConfigUi.restoreVC->setChecked(cgGeneral.readEntry("Restore Window Configuration", true)); 0387 connect(sessionConfigUi.restoreVC, &QCheckBox::toggled, this, &KateConfigDialog::slotChanged); 0388 0389 sessionConfigUi.spinBoxRecentFilesCount->setValue(recentFilesMaxCount()); 0390 connect(sessionConfigUi.spinBoxRecentFilesCount, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &KateConfigDialog::slotChanged); 0391 0392 QString sesStart(cgGeneral.readEntry("Startup Session", "manual")); 0393 if (sesStart == QLatin1String("new")) { 0394 sessionConfigUi.startNewSessionRadioButton->setChecked(true); 0395 } else if (sesStart == QLatin1String("last")) { 0396 sessionConfigUi.loadLastUserSessionRadioButton->setChecked(true); 0397 } else { 0398 sessionConfigUi.manuallyChooseSessionRadioButton->setChecked(true); 0399 } 0400 0401 connect(sessionConfigUi.startNewSessionRadioButton, &QRadioButton::toggled, this, &KateConfigDialog::slotChanged); 0402 connect(sessionConfigUi.loadLastUserSessionRadioButton, &QRadioButton::toggled, this, &KateConfigDialog::slotChanged); 0403 connect(sessionConfigUi.manuallyChooseSessionRadioButton, &QRadioButton::toggled, this, &KateConfigDialog::slotChanged); 0404 0405 // New main windows open always a new document if none there 0406 sessionConfigUi.showWelcomeViewForNewWindow->setChecked(cgGeneral.readEntry("Show welcome view for new window", true)); 0407 connect(sessionConfigUi.showWelcomeViewForNewWindow, &QCheckBox::toggled, this, &KateConfigDialog::slotChanged); 0408 0409 // When a window is closed, close all documents only visible in that window, too 0410 sessionConfigUi.winClosesDocuments->setChecked(cgGeneral.readEntry("Close documents with window", true)); 0411 sessionConfigUi.winClosesDocuments->setToolTip(i18n("When a window is closed the documents opened only in this window are closed as well.")); 0412 connect(sessionConfigUi.winClosesDocuments, &QCheckBox::toggled, this, &KateConfigDialog::slotChanged); 0413 0414 // Closing last file closes Kate 0415 sessionConfigUi.modCloseAfterLast->setChecked(m_mainWindow->modCloseAfterLast()); 0416 connect(sessionConfigUi.modCloseAfterLast, &QCheckBox::toggled, this, &KateConfigDialog::slotChanged); 0417 0418 // stash unsave changes 0419 sessionConfigUi.stashNewUnsavedFiles->setChecked(KateApp::self()->stashManager()->stashNewUnsavedFiles()); 0420 sessionConfigUi.stashUnsavedFilesChanges->setChecked(KateApp::self()->stashManager()->stashUnsavedChanges()); 0421 connect(sessionConfigUi.stashNewUnsavedFiles, &QRadioButton::toggled, this, &KateConfigDialog::slotChanged); 0422 connect(sessionConfigUi.stashUnsavedFilesChanges, &QRadioButton::toggled, this, &KateConfigDialog::slotChanged); 0423 0424 // simplify the session page for KWrite 0425 if (KateApp::isKWrite()) { 0426 sessionConfigUi.gbAppStartup->hide(); 0427 sessionConfigUi.restoreVC->hide(); 0428 sessionConfigUi.label_4->hide(); 0429 sessionConfigUi.stashNewUnsavedFiles->hide(); 0430 sessionConfigUi.stashUnsavedFilesChanges->hide(); 0431 sessionConfigUi.label->hide(); 0432 } 0433 } 0434 0435 void KateConfigDialog::addPluginsPage() 0436 { 0437 QFrame *page = new QFrame(this); 0438 QVBoxLayout *vlayout = new QVBoxLayout(page); 0439 vlayout->setContentsMargins(0, 0, 0, 0); 0440 vlayout->setSpacing(0); 0441 0442 m_configPluginPage = new KateConfigPluginPage(page, this); 0443 vlayout->addWidget(m_configPluginPage); 0444 connect(m_configPluginPage, &KateConfigPluginPage::changed, this, &KateConfigDialog::slotChanged); 0445 0446 auto item = addScrollablePage(page, i18n("Plugins")); 0447 m_allPages.insert(item); 0448 item->setHeader(i18n("Plugin Manager")); 0449 item->setIcon(QIcon::fromTheme(QStringLiteral("preferences-plugin"))); 0450 } 0451 0452 void KateConfigDialog::addFeedbackPage() 0453 { 0454 #ifdef WITH_KUSERFEEDBACK 0455 // KUserFeedback Config 0456 auto page = new QFrame(this); 0457 auto vlayout = new QVBoxLayout(page); 0458 vlayout->setContentsMargins(0, 0, 0, 0); 0459 vlayout->setSpacing(0); 0460 0461 m_userFeedbackWidget = new KUserFeedback::FeedbackConfigWidget(page); 0462 m_userFeedbackWidget->setFeedbackProvider(&KateApp::self()->userFeedbackProvider()); 0463 connect(m_userFeedbackWidget, &KUserFeedback::FeedbackConfigWidget::configurationChanged, this, &KateConfigDialog::slotChanged); 0464 vlayout->addWidget(m_userFeedbackWidget); 0465 0466 auto item = addScrollablePage(page, i18n("User Feedback")); 0467 m_allPages.insert(item); 0468 item->setHeader(i18n("User Feedback")); 0469 item->setIcon(QIcon::fromTheme(QStringLiteral("preferences-desktop-locale"))); 0470 #endif 0471 } 0472 0473 void KateConfigDialog::addPluginPages() 0474 { 0475 const KatePluginList &pluginList(KateApp::self()->pluginManager()->pluginList()); 0476 for (const KatePluginInfo &plugin : pluginList) { 0477 if (plugin.plugin) { 0478 addPluginPage(plugin.plugin); 0479 } 0480 } 0481 } 0482 0483 void KateConfigDialog::addEditorPages() 0484 { 0485 for (int i = 0; i < KTextEditor::Editor::instance()->configPages(); ++i) { 0486 KTextEditor::ConfigPage *page = KTextEditor::Editor::instance()->configPage(i, this); 0487 connect(page, &KTextEditor::ConfigPage::changed, this, &KateConfigDialog::slotChanged); 0488 m_editorPages.push_back(page); 0489 KPageWidgetItem *item = addScrollablePage(page, page->name()); 0490 item->setHeader(page->fullName()); 0491 item->setIcon(page->icon()); 0492 m_allPages.insert(item); 0493 } 0494 } 0495 0496 void KateConfigDialog::addPluginPage(KTextEditor::Plugin *plugin) 0497 { 0498 for (int i = 0; i < plugin->configPages(); i++) { 0499 KTextEditor::ConfigPage *cp = plugin->configPage(i, this); 0500 KPageWidgetItem *item = addScrollablePage(cp, cp->name()); 0501 item->setHeader(cp->fullName()); 0502 item->setIcon(cp->icon()); 0503 0504 PluginPageListItem info; 0505 info.plugin = plugin; 0506 info.pluginPage = cp; 0507 info.idInPlugin = i; 0508 info.pageWidgetItem = item; 0509 connect(info.pluginPage, &KTextEditor::ConfigPage::changed, this, &KateConfigDialog::slotChanged); 0510 m_pluginPages.insert(item, info); 0511 m_allPages.insert(item); 0512 } 0513 } 0514 0515 void KateConfigDialog::removePluginPage(KTextEditor::Plugin *plugin) 0516 { 0517 std::vector<KPageWidgetItem *> remove; 0518 for (QHash<KPageWidgetItem *, PluginPageListItem>::const_iterator it = m_pluginPages.constBegin(); it != m_pluginPages.constEnd(); ++it) { 0519 const PluginPageListItem &pli = it.value(); 0520 0521 if (pli.plugin == plugin) { 0522 remove.push_back(it.key()); 0523 } 0524 } 0525 0526 qCDebug(LOG_KATE) << remove.size(); 0527 while (!remove.empty()) { 0528 KPageWidgetItem *wItem = remove.back(); 0529 remove.pop_back(); 0530 PluginPageListItem item = m_pluginPages.take(wItem); 0531 m_allPages.remove(wItem); 0532 delete item.pluginPage; 0533 removePage(wItem); 0534 } 0535 } 0536 0537 void KateConfigDialog::slotApply() 0538 { 0539 KSharedConfig::Ptr config = KSharedConfig::openConfig(); 0540 0541 // if data changed apply the kate app stuff 0542 if (m_dataChanged) { 0543 // apply plugin load state changes 0544 if (m_configPluginPage) { 0545 m_configPluginPage->slotApply(); 0546 } 0547 0548 KConfigGroup cg(config, QStringLiteral("General")); 0549 0550 cg.writeEntry("SDI Mode", m_sdiMode->isChecked()); 0551 0552 // only there for kate 0553 if (m_syncSectionSizeWithSidebarTabs) { 0554 cg.writeEntry("Sync section size with tab positions", m_syncSectionSizeWithSidebarTabs->isChecked()); 0555 } 0556 if (m_showTextForLeftRightSidebars) { 0557 cg.writeEntry("Show text for left and right sidebar", m_showTextForLeftRightSidebars->isChecked()); 0558 } 0559 if (m_leftRightSidebarsIconSize) { 0560 cg.writeEntry("Icon size for left and right sidebar buttons", m_leftRightSidebarsIconSize->value()); 0561 } 0562 0563 cg.writeEntry("Restore Window Configuration", sessionConfigUi.restoreVC->isChecked()); 0564 0565 cg.writeEntry("Recent File List Entry Count", sessionConfigUi.spinBoxRecentFilesCount->value()); 0566 0567 if (sessionConfigUi.startNewSessionRadioButton->isChecked()) { 0568 cg.writeEntry("Startup Session", "new"); 0569 } else if (sessionConfigUi.loadLastUserSessionRadioButton->isChecked()) { 0570 cg.writeEntry("Startup Session", "last"); 0571 } else { 0572 cg.writeEntry("Startup Session", "manual"); 0573 } 0574 0575 cg.writeEntry("Save Meta Infos", sessionConfigUi.saveMetaInfos->isChecked()); 0576 KateApp::self()->documentManager()->setSaveMetaInfos(sessionConfigUi.saveMetaInfos->isChecked()); 0577 0578 cg.writeEntry("Days Meta Infos", sessionConfigUi.daysMetaInfos->value()); 0579 KateApp::self()->documentManager()->setDaysMetaInfos(sessionConfigUi.daysMetaInfos->value()); 0580 0581 cg.writeEntry("Show welcome view for new window", sessionConfigUi.showWelcomeViewForNewWindow->isChecked()); 0582 0583 cg.writeEntry("Close documents with window", sessionConfigUi.winClosesDocuments->isChecked()); 0584 0585 cg.writeEntry("Close After Last", sessionConfigUi.modCloseAfterLast->isChecked()); 0586 m_mainWindow->setModCloseAfterLast(sessionConfigUi.modCloseAfterLast->isChecked()); 0587 0588 if (m_messageTypes && m_outputHistoryLimit) { 0589 cg.writeEntry("Show output view for message type", m_messageTypes->currentIndex()); 0590 cg.writeEntry("Output History Limit", m_outputHistoryLimit->value()); 0591 } 0592 0593 cg.writeEntry("Mouse back button action", m_mouseBackActions->currentIndex()); 0594 cg.writeEntry("Mouse forward button action", m_mouseForwardActions->currentIndex()); 0595 0596 cg.writeEntry("Stash unsaved file changes", sessionConfigUi.stashUnsavedFilesChanges->isChecked()); 0597 KateApp::self()->stashManager()->setStashUnsavedChanges(sessionConfigUi.stashUnsavedFilesChanges->isChecked()); 0598 cg.writeEntry("Stash new unsaved files", sessionConfigUi.stashNewUnsavedFiles->isChecked()); 0599 KateApp::self()->stashManager()->setStashNewUnsavedFiles(sessionConfigUi.stashNewUnsavedFiles->isChecked()); 0600 0601 cg.writeEntry("Modified Notification", m_modNotifications->isChecked()); 0602 m_mainWindow->setModNotificationEnabled(m_modNotifications->isChecked()); 0603 0604 cg.writeEntry("Tabbar Tab Limit", m_tabLimit->value()); 0605 0606 cg.writeEntry("Auto Hide Tabs", m_autoHideTabs->isChecked()); 0607 0608 cg.writeEntry("Show Tabs Close Button", m_showTabCloseButton->isChecked()); 0609 0610 cg.writeEntry("Expand Tabs", m_expandTabs->isChecked()); 0611 0612 cg.writeEntry("Tab Double Click New Document", m_tabDoubleClickNewDocument->isChecked()); 0613 cg.writeEntry("Tab Middle Click Close Document", m_tabMiddleClickCloseDocument->isChecked()); 0614 0615 cg.writeEntry("Allow Tab Scrolling", m_tabsScrollable->isChecked()); 0616 cg.writeEntry("Elide Tab Text", m_tabsElided->isChecked()); 0617 cg.writeEntry("Open New Tab To The Right Of Current", m_openNewTabInFrontOfCurrent->isChecked()); 0618 0619 cg.writeEntry("Diff Show Style", m_diffStyle->currentIndex()); 0620 0621 cg.writeEntry("Show Symbol In Navigation Bar", m_urlBarShowSymbols->isChecked()); 0622 0623 cg.writeEntry("Diagnostics Limit", m_diagnosticsLimit->value()); 0624 0625 // patch document modified warn state 0626 const QList<KTextEditor::Document *> &docs = KateApp::self()->documentManager()->documentList(); 0627 for (KTextEditor::Document *doc : docs) { 0628 doc->setModifiedOnDiskWarning(!m_modNotifications->isChecked()); 0629 } 0630 0631 m_mainWindow->saveOptions(); 0632 0633 // save plugin config !! 0634 KateSessionManager *sessionmanager = KateApp::self()->sessionManager(); 0635 KConfig *sessionConfig = sessionmanager->activeSession()->config(); 0636 KateApp::self()->pluginManager()->writeConfig(sessionConfig); 0637 0638 #ifdef WITH_KUSERFEEDBACK 0639 // set current active mode + write back the config for future starts 0640 KateApp::self()->userFeedbackProvider().setTelemetryMode(m_userFeedbackWidget->telemetryMode()); 0641 KateApp::self()->userFeedbackProvider().setSurveyInterval(m_userFeedbackWidget->surveyInterval()); 0642 #endif 0643 } 0644 0645 for (const PluginPageListItem &plugin : qAsConst(m_pluginPages)) { 0646 if (plugin.pluginPage) { 0647 plugin.pluginPage->apply(); 0648 } 0649 } 0650 0651 // apply ktexteditor pages 0652 for (KTextEditor::ConfigPage *page : m_editorPages) { 0653 page->apply(); 0654 } 0655 0656 config->sync(); 0657 0658 // emit config change 0659 if (m_dataChanged) { 0660 KateApp::self()->configurationChanged(); 0661 } 0662 0663 m_dataChanged = false; 0664 buttonBox()->button(QDialogButtonBox::Apply)->setEnabled(false); 0665 } 0666 0667 void KateConfigDialog::slotChanged() 0668 { 0669 m_dataChanged = true; 0670 buttonBox()->button(QDialogButtonBox::Apply)->setEnabled(true); 0671 } 0672 0673 void KateConfigDialog::showAppPluginPage(KTextEditor::Plugin *p, int id) 0674 { 0675 for (const PluginPageListItem &plugin : qAsConst(m_pluginPages)) { 0676 if ((plugin.plugin == p) && (id == plugin.idInPlugin)) { 0677 setCurrentPage(plugin.pageWidgetItem); 0678 break; 0679 } 0680 } 0681 } 0682 0683 void KateConfigDialog::slotHelp() 0684 { 0685 QDesktopServices::openUrl(QUrl(QStringLiteral("help:/"))); 0686 } 0687 0688 int KateConfigDialog::recentFilesMaxCount() 0689 { 0690 int maxItems = KConfigGroup(KSharedConfig::openConfig(), QStringLiteral("General")).readEntry("Recent File List Entry Count", 10); 0691 return maxItems; 0692 } 0693 0694 void KateConfigDialog::closeEvent(QCloseEvent *event) 0695 { 0696 if (!m_dataChanged) { 0697 event->accept(); 0698 return; 0699 } 0700 0701 const auto response = KMessageBox::warningTwoActionsCancel(this, 0702 i18n("You have unsaved changes. Do you want to apply the changes or discard them?"), 0703 i18n("Warning"), 0704 KStandardGuiItem::save(), 0705 KStandardGuiItem::discard(), 0706 KStandardGuiItem::cancel()); 0707 switch (response) { 0708 case KMessageBox::PrimaryAction: 0709 slotApply(); 0710 Q_FALLTHROUGH(); 0711 case KMessageBox::SecondaryAction: 0712 event->accept(); 0713 break; 0714 case KMessageBox::Cancel: 0715 event->ignore(); 0716 break; 0717 default: 0718 break; 0719 } 0720 } 0721 0722 KPageWidgetItem *KateConfigDialog::addScrollablePage(QWidget *page, const QString &itemName) 0723 { 0724 // inspired by KPageWidgetItem *KConfigDialogPrivate::addPageInternal(QWidget *page, const QString &itemName, const QString &pixmapName, const QString 0725 // &header) 0726 QWidget *frame = new QWidget; 0727 QVBoxLayout *boxLayout = new QVBoxLayout(frame); 0728 boxLayout->setContentsMargins(0, 0, 0, 0); 0729 boxLayout->setContentsMargins(0, 0, 0, 0); 0730 0731 QScrollArea *scroll = new QScrollArea; 0732 scroll->setFrameShape(QFrame::NoFrame); 0733 scroll->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); 0734 scroll->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); 0735 scroll->setWidget(page); 0736 scroll->setWidgetResizable(true); 0737 scroll->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); 0738 0739 boxLayout->addWidget(scroll); 0740 return addPage(frame, itemName); 0741 } 0742 0743 #include "moc_kateconfigdialog.cpp"