File indexing completed on 2024-05-12 09:55:40
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 layout->addStretch(1); // :-] works correct without autoadd 0340 } 0341 0342 void KateConfigDialog::addSessionPage() 0343 { 0344 KSharedConfig::Ptr config = KSharedConfig::openConfig(); 0345 KConfigGroup cgGeneral = KConfigGroup(config, QStringLiteral("General")); 0346 0347 QWidget *sessionsPage = new QWidget(); 0348 auto item = addScrollablePage(sessionsPage, i18n("Session")); 0349 m_allPages.insert(item); 0350 item->setHeader(i18n("Session Management")); 0351 item->setIcon(QIcon::fromTheme(QStringLiteral("view-history"))); 0352 0353 sessionConfigUi.setupUi(sessionsPage); 0354 0355 // save meta infos 0356 sessionConfigUi.saveMetaInfos->setChecked(KateApp::self()->documentManager()->getSaveMetaInfos()); 0357 connect(sessionConfigUi.saveMetaInfos, &QGroupBox::toggled, this, &KateConfigDialog::slotChanged); 0358 0359 // meta infos days 0360 sessionConfigUi.daysMetaInfos->setMaximum(180); 0361 sessionConfigUi.daysMetaInfos->setSpecialValueText(i18nc("The special case of 'Delete unused meta-information after'", "(never)")); 0362 sessionConfigUi.daysMetaInfos->setSuffix(ki18ncp("The suffix of 'Delete unused meta-information after'", " day", " days")); 0363 sessionConfigUi.daysMetaInfos->setValue(KateApp::self()->documentManager()->getDaysMetaInfos()); 0364 connect(sessionConfigUi.daysMetaInfos, 0365 static_cast<void (KPluralHandlingSpinBox::*)(int)>(&KPluralHandlingSpinBox::valueChanged), 0366 this, 0367 &KateConfigDialog::slotChanged); 0368 0369 // restore view config 0370 sessionConfigUi.restoreVC->setChecked(cgGeneral.readEntry("Restore Window Configuration", true)); 0371 connect(sessionConfigUi.restoreVC, &QCheckBox::toggled, this, &KateConfigDialog::slotChanged); 0372 0373 sessionConfigUi.spinBoxRecentFilesCount->setValue(recentFilesMaxCount()); 0374 connect(sessionConfigUi.spinBoxRecentFilesCount, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &KateConfigDialog::slotChanged); 0375 0376 QString sesStart(cgGeneral.readEntry("Startup Session", "manual")); 0377 if (sesStart == QLatin1String("new")) { 0378 sessionConfigUi.startNewSessionRadioButton->setChecked(true); 0379 } else if (sesStart == QLatin1String("last")) { 0380 sessionConfigUi.loadLastUserSessionRadioButton->setChecked(true); 0381 } else { 0382 sessionConfigUi.manuallyChooseSessionRadioButton->setChecked(true); 0383 } 0384 0385 connect(sessionConfigUi.startNewSessionRadioButton, &QRadioButton::toggled, this, &KateConfigDialog::slotChanged); 0386 connect(sessionConfigUi.loadLastUserSessionRadioButton, &QRadioButton::toggled, this, &KateConfigDialog::slotChanged); 0387 connect(sessionConfigUi.manuallyChooseSessionRadioButton, &QRadioButton::toggled, this, &KateConfigDialog::slotChanged); 0388 0389 // New main windows open always a new document if none there 0390 sessionConfigUi.showWelcomeViewForNewWindow->setChecked(cgGeneral.readEntry("Show welcome view for new window", true)); 0391 connect(sessionConfigUi.showWelcomeViewForNewWindow, &QCheckBox::toggled, this, &KateConfigDialog::slotChanged); 0392 0393 // When a window is closed, close all documents only visible in that window, too 0394 sessionConfigUi.winClosesDocuments->setChecked(cgGeneral.readEntry("Close documents with window", true)); 0395 sessionConfigUi.winClosesDocuments->setToolTip(i18n("When a window is closed the documents opened only in this window are closed as well.")); 0396 connect(sessionConfigUi.winClosesDocuments, &QCheckBox::toggled, this, &KateConfigDialog::slotChanged); 0397 0398 // Closing last file closes Kate 0399 sessionConfigUi.modCloseAfterLast->setChecked(m_mainWindow->modCloseAfterLast()); 0400 connect(sessionConfigUi.modCloseAfterLast, &QCheckBox::toggled, this, &KateConfigDialog::slotChanged); 0401 0402 // stash unsave changes 0403 sessionConfigUi.stashNewUnsavedFiles->setChecked(KateApp::self()->stashManager()->stashNewUnsavedFiles()); 0404 sessionConfigUi.stashUnsavedFilesChanges->setChecked(KateApp::self()->stashManager()->stashUnsavedChanges()); 0405 connect(sessionConfigUi.stashNewUnsavedFiles, &QRadioButton::toggled, this, &KateConfigDialog::slotChanged); 0406 connect(sessionConfigUi.stashUnsavedFilesChanges, &QRadioButton::toggled, this, &KateConfigDialog::slotChanged); 0407 0408 // simplify the session page for KWrite 0409 if (KateApp::isKWrite()) { 0410 sessionConfigUi.gbAppStartup->hide(); 0411 sessionConfigUi.restoreVC->hide(); 0412 sessionConfigUi.label_4->hide(); 0413 sessionConfigUi.stashNewUnsavedFiles->hide(); 0414 sessionConfigUi.stashUnsavedFilesChanges->hide(); 0415 sessionConfigUi.label->hide(); 0416 } 0417 } 0418 0419 void KateConfigDialog::addPluginsPage() 0420 { 0421 QFrame *page = new QFrame(this); 0422 QVBoxLayout *vlayout = new QVBoxLayout(page); 0423 vlayout->setContentsMargins(0, 0, 0, 0); 0424 vlayout->setSpacing(0); 0425 0426 m_configPluginPage = new KateConfigPluginPage(page, this); 0427 vlayout->addWidget(m_configPluginPage); 0428 connect(m_configPluginPage, &KateConfigPluginPage::changed, this, &KateConfigDialog::slotChanged); 0429 0430 auto item = addScrollablePage(page, i18n("Plugins")); 0431 m_allPages.insert(item); 0432 item->setHeader(i18n("Plugin Manager")); 0433 item->setIcon(QIcon::fromTheme(QStringLiteral("preferences-plugin"))); 0434 } 0435 0436 void KateConfigDialog::addFeedbackPage() 0437 { 0438 #ifdef WITH_KUSERFEEDBACK 0439 // KUserFeedback Config 0440 auto page = new QFrame(this); 0441 auto vlayout = new QVBoxLayout(page); 0442 vlayout->setContentsMargins(0, 0, 0, 0); 0443 vlayout->setSpacing(0); 0444 0445 m_userFeedbackWidget = new KUserFeedback::FeedbackConfigWidget(page); 0446 m_userFeedbackWidget->setFeedbackProvider(&KateApp::self()->userFeedbackProvider()); 0447 connect(m_userFeedbackWidget, &KUserFeedback::FeedbackConfigWidget::configurationChanged, this, &KateConfigDialog::slotChanged); 0448 vlayout->addWidget(m_userFeedbackWidget); 0449 0450 auto item = addScrollablePage(page, i18n("User Feedback")); 0451 m_allPages.insert(item); 0452 item->setHeader(i18n("User Feedback")); 0453 item->setIcon(QIcon::fromTheme(QStringLiteral("preferences-desktop-locale"))); 0454 #endif 0455 } 0456 0457 void KateConfigDialog::addPluginPages() 0458 { 0459 const KatePluginList &pluginList(KateApp::self()->pluginManager()->pluginList()); 0460 for (const KatePluginInfo &plugin : pluginList) { 0461 if (plugin.plugin) { 0462 addPluginPage(plugin.plugin); 0463 } 0464 } 0465 } 0466 0467 void KateConfigDialog::addEditorPages() 0468 { 0469 for (int i = 0; i < KTextEditor::Editor::instance()->configPages(); ++i) { 0470 KTextEditor::ConfigPage *page = KTextEditor::Editor::instance()->configPage(i, this); 0471 connect(page, &KTextEditor::ConfigPage::changed, this, &KateConfigDialog::slotChanged); 0472 m_editorPages.push_back(page); 0473 KPageWidgetItem *item = addScrollablePage(page, page->name()); 0474 item->setHeader(page->fullName()); 0475 item->setIcon(page->icon()); 0476 m_allPages.insert(item); 0477 } 0478 } 0479 0480 void KateConfigDialog::addPluginPage(KTextEditor::Plugin *plugin) 0481 { 0482 for (int i = 0; i < plugin->configPages(); i++) { 0483 KTextEditor::ConfigPage *cp = plugin->configPage(i, this); 0484 KPageWidgetItem *item = addScrollablePage(cp, cp->name()); 0485 item->setHeader(cp->fullName()); 0486 item->setIcon(cp->icon()); 0487 0488 PluginPageListItem info; 0489 info.plugin = plugin; 0490 info.pluginPage = cp; 0491 info.idInPlugin = i; 0492 info.pageWidgetItem = item; 0493 connect(info.pluginPage, &KTextEditor::ConfigPage::changed, this, &KateConfigDialog::slotChanged); 0494 m_pluginPages.insert(item, info); 0495 m_allPages.insert(item); 0496 } 0497 } 0498 0499 void KateConfigDialog::removePluginPage(KTextEditor::Plugin *plugin) 0500 { 0501 std::vector<KPageWidgetItem *> remove; 0502 for (QHash<KPageWidgetItem *, PluginPageListItem>::const_iterator it = m_pluginPages.constBegin(); it != m_pluginPages.constEnd(); ++it) { 0503 const PluginPageListItem &pli = it.value(); 0504 0505 if (pli.plugin == plugin) { 0506 remove.push_back(it.key()); 0507 } 0508 } 0509 0510 qCDebug(LOG_KATE) << remove.size(); 0511 while (!remove.empty()) { 0512 KPageWidgetItem *wItem = remove.back(); 0513 remove.pop_back(); 0514 PluginPageListItem item = m_pluginPages.take(wItem); 0515 m_allPages.remove(wItem); 0516 delete item.pluginPage; 0517 removePage(wItem); 0518 } 0519 } 0520 0521 void KateConfigDialog::slotApply() 0522 { 0523 KSharedConfig::Ptr config = KSharedConfig::openConfig(); 0524 0525 // if data changed apply the kate app stuff 0526 if (m_dataChanged) { 0527 // apply plugin load state changes 0528 if (m_configPluginPage) { 0529 m_configPluginPage->slotApply(); 0530 } 0531 0532 KConfigGroup cg(config, QStringLiteral("General")); 0533 0534 cg.writeEntry("SDI Mode", m_sdiMode->isChecked()); 0535 0536 // only there for kate 0537 if (m_syncSectionSizeWithSidebarTabs) { 0538 cg.writeEntry("Sync section size with tab positions", m_syncSectionSizeWithSidebarTabs->isChecked()); 0539 } 0540 if (m_showTextForLeftRightSidebars) { 0541 cg.writeEntry("Show text for left and right sidebar", m_showTextForLeftRightSidebars->isChecked()); 0542 } 0543 if (m_leftRightSidebarsIconSize) { 0544 cg.writeEntry("Icon size for left and right sidebar buttons", m_leftRightSidebarsIconSize->value()); 0545 } 0546 0547 cg.writeEntry("Restore Window Configuration", sessionConfigUi.restoreVC->isChecked()); 0548 0549 cg.writeEntry("Recent File List Entry Count", sessionConfigUi.spinBoxRecentFilesCount->value()); 0550 0551 if (sessionConfigUi.startNewSessionRadioButton->isChecked()) { 0552 cg.writeEntry("Startup Session", "new"); 0553 } else if (sessionConfigUi.loadLastUserSessionRadioButton->isChecked()) { 0554 cg.writeEntry("Startup Session", "last"); 0555 } else { 0556 cg.writeEntry("Startup Session", "manual"); 0557 } 0558 0559 cg.writeEntry("Save Meta Infos", sessionConfigUi.saveMetaInfos->isChecked()); 0560 KateApp::self()->documentManager()->setSaveMetaInfos(sessionConfigUi.saveMetaInfos->isChecked()); 0561 0562 cg.writeEntry("Days Meta Infos", sessionConfigUi.daysMetaInfos->value()); 0563 KateApp::self()->documentManager()->setDaysMetaInfos(sessionConfigUi.daysMetaInfos->value()); 0564 0565 cg.writeEntry("Show welcome view for new window", sessionConfigUi.showWelcomeViewForNewWindow->isChecked()); 0566 0567 cg.writeEntry("Close documents with window", sessionConfigUi.winClosesDocuments->isChecked()); 0568 0569 cg.writeEntry("Close After Last", sessionConfigUi.modCloseAfterLast->isChecked()); 0570 m_mainWindow->setModCloseAfterLast(sessionConfigUi.modCloseAfterLast->isChecked()); 0571 0572 if (m_messageTypes && m_outputHistoryLimit) { 0573 cg.writeEntry("Show output view for message type", m_messageTypes->currentIndex()); 0574 cg.writeEntry("Output History Limit", m_outputHistoryLimit->value()); 0575 } 0576 0577 cg.writeEntry("Mouse back button action", m_mouseBackActions->currentIndex()); 0578 cg.writeEntry("Mouse forward button action", m_mouseForwardActions->currentIndex()); 0579 0580 cg.writeEntry("Stash unsaved file changes", sessionConfigUi.stashUnsavedFilesChanges->isChecked()); 0581 KateApp::self()->stashManager()->setStashUnsavedChanges(sessionConfigUi.stashUnsavedFilesChanges->isChecked()); 0582 cg.writeEntry("Stash new unsaved files", sessionConfigUi.stashNewUnsavedFiles->isChecked()); 0583 KateApp::self()->stashManager()->setStashNewUnsavedFiles(sessionConfigUi.stashNewUnsavedFiles->isChecked()); 0584 0585 cg.writeEntry("Modified Notification", m_modNotifications->isChecked()); 0586 m_mainWindow->setModNotificationEnabled(m_modNotifications->isChecked()); 0587 0588 cg.writeEntry("Tabbar Tab Limit", m_tabLimit->value()); 0589 0590 cg.writeEntry("Auto Hide Tabs", m_autoHideTabs->isChecked()); 0591 0592 cg.writeEntry("Show Tabs Close Button", m_showTabCloseButton->isChecked()); 0593 0594 cg.writeEntry("Expand Tabs", m_expandTabs->isChecked()); 0595 0596 cg.writeEntry("Tab Double Click New Document", m_tabDoubleClickNewDocument->isChecked()); 0597 cg.writeEntry("Tab Middle Click Close Document", m_tabMiddleClickCloseDocument->isChecked()); 0598 0599 cg.writeEntry("Allow Tab Scrolling", m_tabsScrollable->isChecked()); 0600 cg.writeEntry("Elide Tab Text", m_tabsElided->isChecked()); 0601 cg.writeEntry("Open New Tab To The Right Of Current", m_openNewTabInFrontOfCurrent->isChecked()); 0602 0603 cg.writeEntry("Diff Show Style", m_diffStyle->currentIndex()); 0604 0605 cg.writeEntry("Show Symbol In Navigation Bar", m_urlBarShowSymbols->isChecked()); 0606 0607 // patch document modified warn state 0608 const QList<KTextEditor::Document *> &docs = KateApp::self()->documentManager()->documentList(); 0609 for (KTextEditor::Document *doc : docs) { 0610 doc->setModifiedOnDiskWarning(!m_modNotifications->isChecked()); 0611 } 0612 0613 m_mainWindow->saveOptions(); 0614 0615 // save plugin config !! 0616 KateSessionManager *sessionmanager = KateApp::self()->sessionManager(); 0617 KConfig *sessionConfig = sessionmanager->activeSession()->config(); 0618 KateApp::self()->pluginManager()->writeConfig(sessionConfig); 0619 0620 #ifdef WITH_KUSERFEEDBACK 0621 // set current active mode + write back the config for future starts 0622 KateApp::self()->userFeedbackProvider().setTelemetryMode(m_userFeedbackWidget->telemetryMode()); 0623 KateApp::self()->userFeedbackProvider().setSurveyInterval(m_userFeedbackWidget->surveyInterval()); 0624 #endif 0625 } 0626 0627 for (const PluginPageListItem &plugin : qAsConst(m_pluginPages)) { 0628 if (plugin.pluginPage) { 0629 plugin.pluginPage->apply(); 0630 } 0631 } 0632 0633 // apply ktexteditor pages 0634 for (KTextEditor::ConfigPage *page : m_editorPages) { 0635 page->apply(); 0636 } 0637 0638 config->sync(); 0639 0640 // emit config change 0641 if (m_dataChanged) { 0642 KateApp::self()->configurationChanged(); 0643 } 0644 0645 m_dataChanged = false; 0646 buttonBox()->button(QDialogButtonBox::Apply)->setEnabled(false); 0647 } 0648 0649 void KateConfigDialog::slotChanged() 0650 { 0651 m_dataChanged = true; 0652 buttonBox()->button(QDialogButtonBox::Apply)->setEnabled(true); 0653 } 0654 0655 void KateConfigDialog::showAppPluginPage(KTextEditor::Plugin *p, int id) 0656 { 0657 for (const PluginPageListItem &plugin : qAsConst(m_pluginPages)) { 0658 if ((plugin.plugin == p) && (id == plugin.idInPlugin)) { 0659 setCurrentPage(plugin.pageWidgetItem); 0660 break; 0661 } 0662 } 0663 } 0664 0665 void KateConfigDialog::slotHelp() 0666 { 0667 QDesktopServices::openUrl(QUrl(QStringLiteral("help:/"))); 0668 } 0669 0670 int KateConfigDialog::recentFilesMaxCount() 0671 { 0672 int maxItems = KConfigGroup(KSharedConfig::openConfig(), QStringLiteral("General")).readEntry("Recent File List Entry Count", 10); 0673 return maxItems; 0674 } 0675 0676 void KateConfigDialog::closeEvent(QCloseEvent *event) 0677 { 0678 if (!m_dataChanged) { 0679 event->accept(); 0680 return; 0681 } 0682 0683 const auto response = KMessageBox::warningTwoActionsCancel(this, 0684 i18n("You have unsaved changes. Do you want to apply the changes or discard them?"), 0685 i18n("Warning"), 0686 KStandardGuiItem::save(), 0687 KStandardGuiItem::discard(), 0688 KStandardGuiItem::cancel()); 0689 switch (response) { 0690 case KMessageBox::PrimaryAction: 0691 slotApply(); 0692 Q_FALLTHROUGH(); 0693 case KMessageBox::SecondaryAction: 0694 event->accept(); 0695 break; 0696 case KMessageBox::Cancel: 0697 event->ignore(); 0698 break; 0699 default: 0700 break; 0701 } 0702 } 0703 0704 KPageWidgetItem *KateConfigDialog::addScrollablePage(QWidget *page, const QString &itemName) 0705 { 0706 // inspired by KPageWidgetItem *KConfigDialogPrivate::addPageInternal(QWidget *page, const QString &itemName, const QString &pixmapName, const QString 0707 // &header) 0708 QWidget *frame = new QWidget; 0709 QVBoxLayout *boxLayout = new QVBoxLayout(frame); 0710 boxLayout->setContentsMargins(0, 0, 0, 0); 0711 boxLayout->setContentsMargins(0, 0, 0, 0); 0712 0713 QScrollArea *scroll = new QScrollArea; 0714 scroll->setFrameShape(QFrame::NoFrame); 0715 scroll->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); 0716 scroll->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); 0717 scroll->setWidget(page); 0718 scroll->setWidgetResizable(true); 0719 scroll->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); 0720 0721 boxLayout->addWidget(scroll); 0722 return addPage(frame, itemName); 0723 } 0724 0725 #include "moc_kateconfigdialog.cpp"