| 1 | /* |
| 2 | This file is part of the KDE libraries |
| 3 | SPDX-FileCopyrightText: 2002, 2003 Anders Lund <anders.lund@lund.tdcadsl.dk> |
| 4 | SPDX-FileCopyrightText: 2003 Christoph Cullmann <cullmann@kde.org> |
| 5 | SPDX-FileCopyrightText: 2001 Joseph Wenninger <jowenn@kde.org> |
| 6 | SPDX-FileCopyrightText: 2006 Dominik Haumann <dhdev@gmx.de> |
| 7 | SPDX-FileCopyrightText: 2007 Mirko Stocker <me@misto.ch> |
| 8 | SPDX-FileCopyrightText: 2009 Michel Ludwig <michel.ludwig@kdemail.net> |
| 9 | SPDX-FileCopyrightText: 2009 Erlend Hamberg <ehamberg@gmail.com> |
| 10 | |
| 11 | Based on work of: |
| 12 | SPDX-FileCopyrightText: 1999 Jochen Wilhelmy <digisnap@cs.tu-berlin.de> |
| 13 | |
| 14 | SPDX-License-Identifier: LGPL-2.0-only |
| 15 | */ |
| 16 | |
| 17 | // BEGIN Includes |
| 18 | #include "katedialogs.h" |
| 19 | |
| 20 | #include <ktexteditor/message.h> |
| 21 | #include <ktexteditor_version.h> |
| 22 | |
| 23 | #include "kateautoindent.h" |
| 24 | #include "katebuffer.h" |
| 25 | #include "kateconfig.h" |
| 26 | #include "katedocument.h" |
| 27 | #include "kateglobal.h" |
| 28 | #include "katemodeconfigpage.h" |
| 29 | #include "kateview.h" |
| 30 | #include "spellcheck/spellcheck.h" |
| 31 | |
| 32 | // auto generated ui files |
| 33 | #include "ui_bordersappearanceconfigwidget.h" |
| 34 | #include "ui_completionconfigtab.h" |
| 35 | #include "ui_editconfigwidget.h" |
| 36 | #include "ui_indentationconfigwidget.h" |
| 37 | #include "ui_navigationconfigwidget.h" |
| 38 | #include "ui_opensaveconfigadvwidget.h" |
| 39 | #include "ui_opensaveconfigwidget.h" |
| 40 | #include "ui_spellcheckconfigwidget.h" |
| 41 | #include "ui_statusbarconfigwidget.h" |
| 42 | #include "ui_textareaappearanceconfigwidget.h" |
| 43 | |
| 44 | #include <KIO/Job> |
| 45 | #include <KIO/JobUiDelegateFactory> |
| 46 | #include <KIO/OpenUrlJob> |
| 47 | |
| 48 | #include "kateabstractinputmodefactory.h" |
| 49 | #include "katepartdebug.h" |
| 50 | #include <KActionCollection> |
| 51 | #include <KCharsets> |
| 52 | #include <KColorCombo> |
| 53 | #include <KEncodingProber> |
| 54 | #include <KFontRequester> |
| 55 | #include <KLocalization> |
| 56 | #include <KMessageBox> |
| 57 | #include <KProcess> |
| 58 | #include <KSeparator> |
| 59 | |
| 60 | #include <QCheckBox> |
| 61 | #include <QClipboard> |
| 62 | #include <QComboBox> |
| 63 | #include <QDomDocument> |
| 64 | #include <QFile> |
| 65 | #include <QFileDialog> |
| 66 | #include <QFontDatabase> |
| 67 | #include <QGroupBox> |
| 68 | #include <QKeyEvent> |
| 69 | #include <QLabel> |
| 70 | #include <QLayout> |
| 71 | #include <QPainter> |
| 72 | #include <QRadioButton> |
| 73 | #include <QSettings> |
| 74 | #include <QSlider> |
| 75 | #include <QSpinBox> |
| 76 | #include <QStringList> |
| 77 | #include <QTabBar> |
| 78 | #include <QTemporaryFile> |
| 79 | #include <QTextStream> |
| 80 | #include <QToolButton> |
| 81 | #include <QWhatsThis> |
| 82 | |
| 83 | // END |
| 84 | |
| 85 | // BEGIN KateIndentConfigTab |
| 86 | KateIndentConfigTab::KateIndentConfigTab(QWidget *parent) |
| 87 | : KateConfigPage(parent) |
| 88 | { |
| 89 | // This will let us have more separation between this page and |
| 90 | // the QTabWidget edge (ereslibre) |
| 91 | QVBoxLayout *layout = new QVBoxLayout(this); |
| 92 | QWidget *newWidget = new QWidget(this); |
| 93 | |
| 94 | ui = new Ui::IndentationConfigWidget(); |
| 95 | ui->setupUi(newWidget); |
| 96 | |
| 97 | ui->cmbMode->addItems(texts: KateAutoIndent::listModes()); |
| 98 | |
| 99 | // FIXME Give ui->label a more descriptive name, it's these "More..." info about tab key action |
| 100 | ui->label->setTextInteractionFlags(Qt::LinksAccessibleByMouse | Qt::LinksAccessibleByKeyboard); |
| 101 | connect(sender: ui->label, signal: &QLabel::linkActivated, context: this, slot: &KateIndentConfigTab::showWhatsThis); |
| 102 | |
| 103 | // "What's This?" help can be found in the ui file |
| 104 | |
| 105 | reload(); |
| 106 | |
| 107 | observeChanges(button: ui->chkAutoDetectIndent); |
| 108 | observeChanges(button: ui->chkBackspaceUnindents); |
| 109 | observeChanges(button: ui->chkIndentPaste); |
| 110 | observeChanges(button: ui->chkKeepExtraSpaces); |
| 111 | observeChanges(comboBox: ui->cmbMode); |
| 112 | observeChanges(button: ui->rbIndentMixed); |
| 113 | observeChanges(button: ui->rbIndentWithSpaces); |
| 114 | observeChanges(button: ui->rbIndentWithTabs); |
| 115 | connect(sender: ui->rbIndentWithTabs, signal: &QAbstractButton::toggled, context: ui->sbIndentWidth, slot: &QWidget::setDisabled); |
| 116 | connect(sender: ui->rbIndentWithTabs, signal: &QAbstractButton::toggled, context: this, slot: &KateIndentConfigTab::slotChanged); // FIXME See slot below |
| 117 | observeChanges(button: ui->rbTabAdvances); |
| 118 | observeChanges(button: ui->rbTabIndents); |
| 119 | observeChanges(button: ui->rbTabSmart); |
| 120 | observeChanges(spinBox: ui->sbIndentWidth); |
| 121 | observeChanges(spinBox: ui->sbTabWidth); |
| 122 | |
| 123 | layout->addWidget(newWidget); |
| 124 | } |
| 125 | |
| 126 | KateIndentConfigTab::~KateIndentConfigTab() |
| 127 | { |
| 128 | delete ui; |
| 129 | } |
| 130 | |
| 131 | void KateIndentConfigTab::slotChanged() |
| 132 | { |
| 133 | // FIXME Make it working without this quirk |
| 134 | // When the value is not copied it will silently set back to "Tabs & Spaces" |
| 135 | if (ui->rbIndentWithTabs->isChecked()) { |
| 136 | ui->sbIndentWidth->setValue(ui->sbTabWidth->value()); |
| 137 | } |
| 138 | } |
| 139 | |
| 140 | // NOTE Should we have more use of such info stuff, consider to make it part |
| 141 | // of KateConfigPage and add a similar function like observeChanges(..) |
| 142 | void KateIndentConfigTab::showWhatsThis(const QString &text) |
| 143 | { |
| 144 | QWhatsThis::showText(pos: QCursor::pos(), text); |
| 145 | } |
| 146 | |
| 147 | void KateIndentConfigTab::apply() |
| 148 | { |
| 149 | // nothing changed, no need to apply stuff |
| 150 | if (!hasChanged()) { |
| 151 | return; |
| 152 | } |
| 153 | m_changed = false; |
| 154 | |
| 155 | KateDocumentConfig::global()->configStart(); |
| 156 | |
| 157 | KateDocumentConfig::global()->setBackspaceIndents(ui->chkBackspaceUnindents->isChecked()); |
| 158 | KateDocumentConfig::global()->setIndentPastedText(ui->chkIndentPaste->isChecked()); |
| 159 | KateDocumentConfig::global()->setIndentationMode(KateAutoIndent::modeName(mode: ui->cmbMode->currentIndex())); |
| 160 | KateDocumentConfig::global()->setIndentationWidth(ui->sbIndentWidth->value()); |
| 161 | KateDocumentConfig::global()->setKeepExtraSpaces(ui->chkKeepExtraSpaces->isChecked()); |
| 162 | KateDocumentConfig::global()->setReplaceTabsDyn(ui->rbIndentWithSpaces->isChecked()); |
| 163 | KateDocumentConfig::global()->setTabWidth(ui->sbTabWidth->value()); |
| 164 | KateDocumentConfig::global()->setAutoDetectIndent(ui->chkAutoDetectIndent->isChecked()); |
| 165 | |
| 166 | if (ui->rbTabAdvances->isChecked()) { |
| 167 | KateDocumentConfig::global()->setTabHandling(KateDocumentConfig::tabInsertsTab); |
| 168 | } else if (ui->rbTabIndents->isChecked()) { |
| 169 | KateDocumentConfig::global()->setTabHandling(KateDocumentConfig::tabIndents); |
| 170 | } else { |
| 171 | KateDocumentConfig::global()->setTabHandling(KateDocumentConfig::tabSmart); |
| 172 | } |
| 173 | |
| 174 | KateDocumentConfig::global()->configEnd(); |
| 175 | } |
| 176 | |
| 177 | void KateIndentConfigTab::reload() |
| 178 | { |
| 179 | ui->chkBackspaceUnindents->setChecked(KateDocumentConfig::global()->backspaceIndents()); |
| 180 | ui->chkIndentPaste->setChecked(KateDocumentConfig::global()->indentPastedText()); |
| 181 | ui->chkKeepExtraSpaces->setChecked(KateDocumentConfig::global()->keepExtraSpaces()); |
| 182 | |
| 183 | ui->chkAutoDetectIndent->setChecked(KateDocumentConfig::global()->autoDetectIndent()); |
| 184 | KLocalization::setupSpinBoxFormatString(spinBox: ui->sbIndentWidth, ki18np("%v character" , "%v characters" )); |
| 185 | ui->sbIndentWidth->setValue(KateDocumentConfig::global()->indentationWidth()); |
| 186 | KLocalization::setupSpinBoxFormatString(spinBox: ui->sbTabWidth, ki18np("%v character" , "%v characters" )); |
| 187 | ui->sbTabWidth->setValue(KateDocumentConfig::global()->tabWidth()); |
| 188 | |
| 189 | ui->rbTabAdvances->setChecked(KateDocumentConfig::global()->tabHandling() == KateDocumentConfig::tabInsertsTab); |
| 190 | ui->rbTabIndents->setChecked(KateDocumentConfig::global()->tabHandling() == KateDocumentConfig::tabIndents); |
| 191 | ui->rbTabSmart->setChecked(KateDocumentConfig::global()->tabHandling() == KateDocumentConfig::tabSmart); |
| 192 | |
| 193 | ui->cmbMode->setCurrentIndex(KateAutoIndent::modeNumber(name: KateDocumentConfig::global()->indentationMode())); |
| 194 | |
| 195 | if (KateDocumentConfig::global()->replaceTabsDyn()) { |
| 196 | ui->rbIndentWithSpaces->setChecked(true); |
| 197 | } else { |
| 198 | if (KateDocumentConfig::global()->indentationWidth() == KateDocumentConfig::global()->tabWidth()) { |
| 199 | ui->rbIndentWithTabs->setChecked(true); |
| 200 | } else { |
| 201 | ui->rbIndentMixed->setChecked(true); |
| 202 | } |
| 203 | } |
| 204 | |
| 205 | ui->sbIndentWidth->setEnabled(!ui->rbIndentWithTabs->isChecked()); |
| 206 | } |
| 207 | |
| 208 | QString KateIndentConfigTab::name() const |
| 209 | { |
| 210 | return i18n("Indentation" ); |
| 211 | } |
| 212 | |
| 213 | // END KateIndentConfigTab |
| 214 | |
| 215 | // BEGIN KateCompletionConfigTab |
| 216 | KateCompletionConfigTab::KateCompletionConfigTab(QWidget *parent) |
| 217 | : KateConfigPage(parent) |
| 218 | { |
| 219 | // This will let us have more separation between this page and |
| 220 | // the QTabWidget edge (ereslibre) |
| 221 | QVBoxLayout *layout = new QVBoxLayout(this); |
| 222 | QWidget *newWidget = new QWidget(this); |
| 223 | |
| 224 | ui = new Ui::CompletionConfigTab(); |
| 225 | ui->setupUi(newWidget); |
| 226 | |
| 227 | // "What's This?" help can be found in the ui file |
| 228 | |
| 229 | reload(); |
| 230 | |
| 231 | observeChanges(button: ui->chkAutoCompletionEnabled); |
| 232 | observeChanges(button: ui->chkAutoSelectFirstEntry); |
| 233 | observeChanges(button: ui->chkTabCompletion); |
| 234 | observeChanges(button: ui->chkEnterCompletion); |
| 235 | observeChanges(groupBox: ui->gbKeywordCompletion); |
| 236 | observeChanges(groupBox: ui->gbShowDoc); |
| 237 | observeChanges(groupBox: ui->gbWordCompletion); |
| 238 | observeChanges(spinBox: ui->minimalWordLength); |
| 239 | observeChanges(button: ui->removeTail); |
| 240 | |
| 241 | layout->addWidget(newWidget); |
| 242 | } |
| 243 | |
| 244 | KateCompletionConfigTab::~KateCompletionConfigTab() |
| 245 | { |
| 246 | delete ui; |
| 247 | } |
| 248 | |
| 249 | void KateCompletionConfigTab::showWhatsThis(const QString &text) // NOTE Not used atm, remove? See also KateIndentConfigTab::showWhatsThis |
| 250 | { |
| 251 | QWhatsThis::showText(pos: QCursor::pos(), text); |
| 252 | } |
| 253 | |
| 254 | void KateCompletionConfigTab::apply() |
| 255 | { |
| 256 | // nothing changed, no need to apply stuff |
| 257 | if (!hasChanged()) { |
| 258 | return; |
| 259 | } |
| 260 | m_changed = false; |
| 261 | |
| 262 | KateViewConfig::global()->configStart(); |
| 263 | |
| 264 | KateViewConfig::global()->setValue(key: KateViewConfig::AutomaticCompletionInvocation, value: ui->chkAutoCompletionEnabled->isChecked()); |
| 265 | KateViewConfig::global()->setValue(key: KateViewConfig::AutomaticCompletionPreselectFirst, value: ui->chkAutoSelectFirstEntry->isChecked()); |
| 266 | KateViewConfig::global()->setValue(key: KateViewConfig::TabCompletion, value: ui->chkTabCompletion->isChecked()); |
| 267 | KateViewConfig::global()->setValue(key: KateViewConfig::EnterToInsertCompletion, value: ui->chkEnterCompletion->isChecked()); |
| 268 | KateViewConfig::global()->setValue(key: KateViewConfig::KeywordCompletion, value: ui->gbKeywordCompletion->isChecked()); |
| 269 | KateViewConfig::global()->setValue(key: KateViewConfig::WordCompletion, value: ui->gbWordCompletion->isChecked()); |
| 270 | KateViewConfig::global()->setValue(key: KateViewConfig::WordCompletionMinimalWordLength, value: ui->minimalWordLength->value()); |
| 271 | KateViewConfig::global()->setValue(key: KateViewConfig::WordCompletionRemoveTail, value: ui->removeTail->isChecked()); |
| 272 | KateViewConfig::global()->setValue(key: KateViewConfig::ShowDocWithCompletion, value: ui->gbShowDoc->isChecked()); |
| 273 | |
| 274 | KateViewConfig::global()->configEnd(); |
| 275 | } |
| 276 | |
| 277 | void KateCompletionConfigTab::reload() |
| 278 | { |
| 279 | ui->chkAutoCompletionEnabled->setChecked(KateViewConfig::global()->automaticCompletionInvocation()); |
| 280 | ui->chkAutoSelectFirstEntry->setChecked(KateViewConfig::global()->automaticCompletionPreselectFirst()); |
| 281 | ui->chkTabCompletion->setChecked(KateViewConfig::global()->tabCompletion()); |
| 282 | ui->chkEnterCompletion->setChecked(KateViewConfig::global()->value(key: KateViewConfig::EnterToInsertCompletion).toBool()); |
| 283 | |
| 284 | ui->gbKeywordCompletion->setChecked(KateViewConfig::global()->keywordCompletion()); |
| 285 | ui->gbWordCompletion->setChecked(KateViewConfig::global()->wordCompletion()); |
| 286 | ui->gbShowDoc->setChecked(KateViewConfig::global()->showDocWithCompletion()); |
| 287 | |
| 288 | ui->minimalWordLength->setValue(KateViewConfig::global()->wordCompletionMinimalWordLength()); |
| 289 | ui->removeTail->setChecked(KateViewConfig::global()->wordCompletionRemoveTail()); |
| 290 | } |
| 291 | |
| 292 | QString KateCompletionConfigTab::name() const |
| 293 | { |
| 294 | return i18n("Auto Completion" ); |
| 295 | } |
| 296 | |
| 297 | // END KateCompletionConfigTab |
| 298 | |
| 299 | // BEGIN KateSpellCheckConfigTab |
| 300 | KateSpellCheckConfigTab::KateSpellCheckConfigTab(QWidget *parent) |
| 301 | : KateConfigPage(parent) |
| 302 | { |
| 303 | // This will let us have more separation between this page and |
| 304 | // the QTabWidget edge (ereslibre) |
| 305 | QVBoxLayout *layout = new QVBoxLayout(this); |
| 306 | QWidget *newWidget = new QWidget(this); |
| 307 | |
| 308 | ui = new Ui::SpellCheckConfigWidget(); |
| 309 | ui->setupUi(newWidget); |
| 310 | |
| 311 | // "What's This?" help can be found in the ui file |
| 312 | |
| 313 | reload(); |
| 314 | |
| 315 | m_sonnetConfigWidget = new Sonnet::ConfigWidget(this); |
| 316 | connect(sender: m_sonnetConfigWidget, signal: &Sonnet::ConfigWidget::configChanged, context: this, slot: &KateSpellCheckConfigTab::slotChanged); |
| 317 | layout->addWidget(m_sonnetConfigWidget); |
| 318 | |
| 319 | layout->addWidget(newWidget); |
| 320 | } |
| 321 | |
| 322 | KateSpellCheckConfigTab::~KateSpellCheckConfigTab() |
| 323 | { |
| 324 | delete ui; |
| 325 | } |
| 326 | |
| 327 | void KateSpellCheckConfigTab::showWhatsThis(const QString &text) // NOTE Not used atm, remove? See also KateIndentConfigTab::showWhatsThis |
| 328 | { |
| 329 | QWhatsThis::showText(pos: QCursor::pos(), text); |
| 330 | } |
| 331 | |
| 332 | void KateSpellCheckConfigTab::apply() |
| 333 | { |
| 334 | if (!hasChanged()) { |
| 335 | // nothing changed, no need to apply stuff |
| 336 | return; |
| 337 | } |
| 338 | m_changed = false; |
| 339 | |
| 340 | // WARNING: this is slightly hackish, but it's currently the only way to |
| 341 | // do it, see also the KTextEdit class |
| 342 | KateDocumentConfig::global()->configStart(); |
| 343 | m_sonnetConfigWidget->save(); |
| 344 | QSettings settings(QStringLiteral("KDE" ), QStringLiteral("Sonnet" )); |
| 345 | KateDocumentConfig::global()->setOnTheFlySpellCheck(settings.value(QStringLiteral("checkerEnabledByDefault" ), defaultValue: false).toBool()); |
| 346 | KateDocumentConfig::global()->configEnd(); |
| 347 | |
| 348 | const auto docs = KTextEditor::EditorPrivate::self()->documents(); |
| 349 | for (KTextEditor::Document *doc : docs) { |
| 350 | static_cast<KTextEditor::DocumentPrivate *>(doc)->refreshOnTheFlyCheck(); |
| 351 | } |
| 352 | } |
| 353 | |
| 354 | void KateSpellCheckConfigTab::reload() |
| 355 | { |
| 356 | // does nothing |
| 357 | } |
| 358 | |
| 359 | QString KateSpellCheckConfigTab::name() const |
| 360 | { |
| 361 | return i18n("Spellcheck" ); |
| 362 | } |
| 363 | |
| 364 | // END KateSpellCheckConfigTab |
| 365 | |
| 366 | // BEGIN KateNavigationConfigTab |
| 367 | KateNavigationConfigTab::KateNavigationConfigTab(QWidget *parent) |
| 368 | : KateConfigPage(parent) |
| 369 | { |
| 370 | // This will let us having more separation between this page and |
| 371 | // the QTabWidget edge (ereslibre) |
| 372 | QVBoxLayout *layout = new QVBoxLayout(this); |
| 373 | QWidget *newWidget = new QWidget(this); |
| 374 | |
| 375 | ui = new Ui::NavigationConfigWidget(); |
| 376 | ui->setupUi(newWidget); |
| 377 | |
| 378 | initMulticursorModifierComboBox(); |
| 379 | |
| 380 | // "What's This?" help can be found in the ui file |
| 381 | |
| 382 | reload(); |
| 383 | |
| 384 | observeChanges(comboBox: ui->cbTextSelectionMode); |
| 385 | observeChanges(button: ui->chkBackspaceRemoveComposed); |
| 386 | observeChanges(button: ui->chkPagingMovesCursor); |
| 387 | observeChanges(button: ui->chkScrollPastEnd); |
| 388 | observeChanges(button: ui->chkSmartHome); |
| 389 | observeChanges(spinBox: ui->sbAutoCenterCursor); |
| 390 | observeChanges(button: ui->chkCamelCursor); |
| 391 | observeChanges(comboBox: ui->cmbMultiCursorModifier); |
| 392 | observeChanges(button: ui->cbCycleBookmarks); |
| 393 | |
| 394 | layout->addWidget(newWidget); |
| 395 | } |
| 396 | |
| 397 | KateNavigationConfigTab::~KateNavigationConfigTab() |
| 398 | { |
| 399 | delete ui; |
| 400 | } |
| 401 | |
| 402 | void KateNavigationConfigTab::initMulticursorModifierComboBox() |
| 403 | { |
| 404 | // On macOS, the ControlModifier value corresponds to the Command keys on the |
| 405 | // keyboard, and the MetaModifier value corresponds to the Control keys. |
| 406 | auto *c = ui->cmbMultiCursorModifier; |
| 407 | |
| 408 | #ifndef Q_OS_DARWIN |
| 409 | c->insertItem(aindex: 0, i18n("Alt" ), auserData: (int)Qt::ALT); |
| 410 | c->insertItem(aindex: 1, i18n("Ctrl" ), auserData: (int)Qt::CTRL); |
| 411 | c->insertItem(aindex: 2, i18n("Meta" ), auserData: (int)Qt::META); |
| 412 | c->insertItem(aindex: 3, i18n("Ctrl + Alt" ), auserData: (int)(Qt::CTRL | Qt::ALT)); |
| 413 | c->insertItem(aindex: 4, i18n("Meta + Alt" ), auserData: (int)(Qt::META | Qt::ALT)); |
| 414 | c->insertItem(aindex: 5, i18n("Ctrl + Meta" ), auserData: (int)(Qt::CTRL | Qt::META)); |
| 415 | #else |
| 416 | c->insertItem(0, i18n("Alt" ), (int)Qt::ALT); |
| 417 | c->insertItem(1, i18n("Cmd" ), (int)Qt::CTRL); |
| 418 | c->insertItem(2, i18n("Ctrl" ), (int)Qt::META); |
| 419 | c->insertItem(3, i18n("Cmd + Alt" ), (int)(Qt::CTRL | Qt::ALT)); |
| 420 | c->insertItem(4, i18n("Ctrl + Alt" ), (int)(Qt::META | Qt::ALT)); |
| 421 | c->insertItem(5, i18n("Cmd + Ctrl" ), (int)(Qt::CTRL | Qt::META)); |
| 422 | #endif |
| 423 | } |
| 424 | |
| 425 | void KateNavigationConfigTab::apply() |
| 426 | { |
| 427 | // nothing changed, no need to apply stuff |
| 428 | if (!hasChanged()) { |
| 429 | return; |
| 430 | } |
| 431 | m_changed = false; |
| 432 | |
| 433 | KateViewConfig::global()->configStart(); |
| 434 | KateDocumentConfig::global()->configStart(); |
| 435 | |
| 436 | KateDocumentConfig::global()->setPageUpDownMovesCursor(ui->chkPagingMovesCursor->isChecked()); |
| 437 | KateDocumentConfig::global()->setSmartHome(ui->chkSmartHome->isChecked()); |
| 438 | KateDocumentConfig::global()->setCamelCursor(ui->chkCamelCursor->isChecked()); |
| 439 | |
| 440 | KateViewConfig::global()->setValue(key: KateViewConfig::AutoCenterLines, value: ui->sbAutoCenterCursor->value()); |
| 441 | KateViewConfig::global()->setValue(key: KateViewConfig::BackspaceRemoveComposedCharacters, value: ui->chkBackspaceRemoveComposed->isChecked()); |
| 442 | KateViewConfig::global()->setValue(key: KateViewConfig::PersistentSelection, value: ui->cbTextSelectionMode->currentIndex() == 1); |
| 443 | KateViewConfig::global()->setValue(key: KateViewConfig::ScrollPastEnd, value: ui->chkScrollPastEnd->isChecked()); |
| 444 | KateViewConfig::global()->setValue(key: KateViewConfig::CycleThroughBookmarks, value: ui->cbCycleBookmarks->isChecked()); |
| 445 | |
| 446 | const int modifers = ui->cmbMultiCursorModifier->currentData().toInt(); |
| 447 | KateViewConfig::global()->setMultiCursorModifiers(Qt::KeyboardModifiers(modifers)); |
| 448 | |
| 449 | KateDocumentConfig::global()->configEnd(); |
| 450 | KateViewConfig::global()->configEnd(); |
| 451 | } |
| 452 | |
| 453 | void KateNavigationConfigTab::reload() |
| 454 | { |
| 455 | ui->cbTextSelectionMode->setCurrentIndex(KateViewConfig::global()->persistentSelection() ? 1 : 0); |
| 456 | |
| 457 | ui->chkBackspaceRemoveComposed->setChecked(KateViewConfig::global()->backspaceRemoveComposed()); |
| 458 | ui->chkPagingMovesCursor->setChecked(KateDocumentConfig::global()->pageUpDownMovesCursor()); |
| 459 | ui->chkScrollPastEnd->setChecked(KateViewConfig::global()->scrollPastEnd()); |
| 460 | ui->chkSmartHome->setChecked(KateDocumentConfig::global()->smartHome()); |
| 461 | ui->chkCamelCursor->setChecked(KateDocumentConfig::global()->camelCursor()); |
| 462 | |
| 463 | ui->sbAutoCenterCursor->setValue(KateViewConfig::global()->autoCenterLines()); |
| 464 | ui->cbCycleBookmarks->setChecked(KateViewConfig::global()->value(key: KateViewConfig::CycleThroughBookmarks).toBool()); |
| 465 | |
| 466 | const int mods = KateViewConfig::global()->multiCursorModifiers(); |
| 467 | const auto count = ui->cmbMultiCursorModifier->count(); |
| 468 | for (int i = 0; i < count; ++i) { |
| 469 | int idxMods = ui->cmbMultiCursorModifier->itemData(index: i).toInt(); |
| 470 | if (idxMods == mods) { |
| 471 | ui->cmbMultiCursorModifier->setCurrentIndex(i); |
| 472 | break; |
| 473 | } |
| 474 | } |
| 475 | } |
| 476 | |
| 477 | QString KateNavigationConfigTab::name() const |
| 478 | { |
| 479 | return i18n("Text Navigation" ); |
| 480 | } |
| 481 | |
| 482 | // END KateNavigationConfigTab |
| 483 | |
| 484 | // BEGIN KateEditGeneralConfigTab |
| 485 | KateEditGeneralConfigTab::KateEditGeneralConfigTab(QWidget *parent) |
| 486 | : KateConfigPage(parent) |
| 487 | { |
| 488 | QVBoxLayout *layout = new QVBoxLayout(this); |
| 489 | QWidget *newWidget = new QWidget(this); |
| 490 | ui = new Ui::EditConfigWidget(); |
| 491 | ui->setupUi(newWidget); |
| 492 | |
| 493 | for (const auto &fact : KTextEditor::EditorPrivate::self()->inputModeFactories()) { |
| 494 | ui->cmbInputMode->addItem(atext: fact->name(), auserData: static_cast<int>(fact->inputMode())); |
| 495 | } |
| 496 | |
| 497 | // "What's This?" Help is in the ui-files |
| 498 | |
| 499 | reload(); |
| 500 | |
| 501 | observeChanges(button: ui->chkAutoBrackets); |
| 502 | observeChanges(button: ui->chkMousePasteAtCursorPosition); |
| 503 | observeChanges(button: ui->chkShowStaticWordWrapMarker); |
| 504 | observeChanges(button: ui->chkTextDragAndDrop); |
| 505 | observeChanges(button: ui->chkSmartCopyCut); |
| 506 | observeChanges(spinBox: ui->sbClipboardHistoryEntries); |
| 507 | observeChanges(button: ui->chkStaticWordWrap); |
| 508 | observeChanges(comboBox: ui->cmbEncloseSelection); |
| 509 | ui->lblBracketHelp->setFont(QFontDatabase::systemFont(type: QFontDatabase::SmallestReadableFont)); |
| 510 | connect(sender: ui->cmbEncloseSelection->lineEdit(), signal: &QLineEdit::editingFinished, slot: [this] { |
| 511 | const int index = ui->cmbEncloseSelection->currentIndex(); |
| 512 | const QString text = ui->cmbEncloseSelection->currentText(); |
| 513 | // Text removed? Remove item, but don't remove default data! |
| 514 | if (index >= UserData && text.isEmpty()) { |
| 515 | ui->cmbEncloseSelection->removeItem(index); |
| 516 | slotChanged(); |
| 517 | |
| 518 | // Not already there? Add new item! For whatever reason it isn't done automatically |
| 519 | } else if (ui->cmbEncloseSelection->findText(text) < 0) { |
| 520 | ui->cmbEncloseSelection->addItem(atext: text); |
| 521 | slotChanged(); |
| 522 | } |
| 523 | ui->cmbEncloseSelection->setCurrentIndex(ui->cmbEncloseSelection->findText(text)); |
| 524 | }); |
| 525 | observeChanges(comboBox: ui->cmbInputMode); |
| 526 | observeChanges(spinBox: ui->sbWordWrap); |
| 527 | observeChanges(button: ui->chkAccessibility); |
| 528 | |
| 529 | layout->addWidget(newWidget); |
| 530 | } |
| 531 | |
| 532 | KateEditGeneralConfigTab::~KateEditGeneralConfigTab() |
| 533 | { |
| 534 | delete ui; |
| 535 | } |
| 536 | |
| 537 | void KateEditGeneralConfigTab::apply() |
| 538 | { |
| 539 | // nothing changed, no need to apply stuff |
| 540 | if (!hasChanged()) { |
| 541 | return; |
| 542 | } |
| 543 | m_changed = false; |
| 544 | |
| 545 | KateViewConfig::global()->configStart(); |
| 546 | KateDocumentConfig::global()->configStart(); |
| 547 | |
| 548 | KateDocumentConfig::global()->setWordWrap(ui->chkStaticWordWrap->isChecked()); |
| 549 | KateDocumentConfig::global()->setWordWrapAt(ui->sbWordWrap->value()); |
| 550 | |
| 551 | KateRendererConfig::global()->setWordWrapMarker(ui->chkShowStaticWordWrapMarker->isChecked()); |
| 552 | |
| 553 | KateViewConfig::global()->setValue(key: KateViewConfig::AutoBrackets, value: ui->chkAutoBrackets->isChecked()); |
| 554 | KateViewConfig::global()->setValue(key: KateViewConfig::CharsToEncloseSelection, value: ui->cmbEncloseSelection->currentText()); |
| 555 | QStringList userLetters; |
| 556 | for (int i = UserData; i < ui->cmbEncloseSelection->count(); ++i) { |
| 557 | userLetters.append(t: ui->cmbEncloseSelection->itemText(index: i)); |
| 558 | } |
| 559 | KateViewConfig::global()->setValue(key: KateViewConfig::UserSetsOfCharsToEncloseSelection, value: userLetters); |
| 560 | KateViewConfig::global()->setValue(key: KateViewConfig::InputMode, value: ui->cmbInputMode->currentData().toInt()); |
| 561 | KateViewConfig::global()->setValue(key: KateViewConfig::MousePasteAtCursorPosition, value: ui->chkMousePasteAtCursorPosition->isChecked()); |
| 562 | KateViewConfig::global()->setValue(key: KateViewConfig::TextDragAndDrop, value: ui->chkTextDragAndDrop->isChecked()); |
| 563 | KateViewConfig::global()->setValue(key: KateViewConfig::SmartCopyCut, value: ui->chkSmartCopyCut->isChecked()); |
| 564 | KateViewConfig::global()->setValue(key: KateViewConfig::ClipboardHistoryEntries, value: ui->sbClipboardHistoryEntries->value()); |
| 565 | KateViewConfig::global()->setValue(key: KateViewConfig::EnableAccessibility, value: ui->chkAccessibility->isChecked()); |
| 566 | |
| 567 | KateDocumentConfig::global()->configEnd(); |
| 568 | KateViewConfig::global()->configEnd(); |
| 569 | } |
| 570 | |
| 571 | void KateEditGeneralConfigTab::reload() |
| 572 | { |
| 573 | ui->chkAutoBrackets->setChecked(KateViewConfig::global()->autoBrackets()); |
| 574 | ui->chkMousePasteAtCursorPosition->setChecked(KateViewConfig::global()->mousePasteAtCursorPosition()); |
| 575 | ui->chkShowStaticWordWrapMarker->setChecked(KateRendererConfig::global()->wordWrapMarker()); |
| 576 | ui->chkTextDragAndDrop->setChecked(KateViewConfig::global()->textDragAndDrop()); |
| 577 | ui->chkSmartCopyCut->setChecked(KateViewConfig::global()->smartCopyCut()); |
| 578 | ui->chkStaticWordWrap->setChecked(KateDocumentConfig::global()->wordWrap()); |
| 579 | ui->sbClipboardHistoryEntries->setValue(KateViewConfig::global()->clipboardHistoryEntries()); |
| 580 | |
| 581 | KLocalization::setupSpinBoxFormatString(spinBox: ui->sbWordWrap, ki18ncp("Wrap words at (value is at 20 or larger)" , "%v character" , "%v characters" )); |
| 582 | ui->sbWordWrap->setValue(KateDocumentConfig::global()->wordWrapAt()); |
| 583 | |
| 584 | ui->cmbEncloseSelection->clear(); |
| 585 | ui->cmbEncloseSelection->lineEdit()->setClearButtonEnabled(true); |
| 586 | ui->cmbEncloseSelection->lineEdit()->setPlaceholderText(i18n("Feature is not active" )); |
| 587 | ui->cmbEncloseSelection->addItem(atext: QString(), auserData: None); |
| 588 | ui->cmbEncloseSelection->setItemData(index: 0, i18n("Disable Feature" ), role: Qt::ToolTipRole); |
| 589 | ui->cmbEncloseSelection->addItem(QStringLiteral("`*_~" ), auserData: MarkDown); |
| 590 | ui->cmbEncloseSelection->setItemData(index: 1, i18n("May be handy with Markdown" ), role: Qt::ToolTipRole); |
| 591 | ui->cmbEncloseSelection->addItem(QStringLiteral("<>(){}[]'\"" ), auserData: MirrorChar); |
| 592 | ui->cmbEncloseSelection->setItemData(index: 2, i18n("Mirror characters, similar but not exactly like auto brackets" ), role: Qt::ToolTipRole); |
| 593 | ui->cmbEncloseSelection->addItem(QStringLiteral("´`_.:|#@~*!?$%/=,;-+^°§&" ), auserData: NonLetters); |
| 594 | ui->cmbEncloseSelection->setItemData(index: 3, i18n("Non letter character" ), role: Qt::ToolTipRole); |
| 595 | const QStringList userLetters = KateViewConfig::global()->value(key: KateViewConfig::UserSetsOfCharsToEncloseSelection).toStringList(); |
| 596 | for (int i = 0; i < userLetters.size(); ++i) { |
| 597 | ui->cmbEncloseSelection->addItem(atext: userLetters.at(i), auserData: UserData + i); |
| 598 | } |
| 599 | ui->cmbEncloseSelection->setCurrentIndex(ui->cmbEncloseSelection->findText(text: KateViewConfig::global()->charsToEncloseSelection())); |
| 600 | |
| 601 | const int id = static_cast<int>(KateViewConfig::global()->inputMode()); |
| 602 | ui->cmbInputMode->setCurrentIndex(ui->cmbInputMode->findData(data: id)); |
| 603 | ui->chkAccessibility->setChecked(KateViewConfig::global()->value(key: KateViewConfig::EnableAccessibility).toBool()); |
| 604 | } |
| 605 | |
| 606 | QString KateEditGeneralConfigTab::name() const |
| 607 | { |
| 608 | return i18n("General" ); |
| 609 | } |
| 610 | |
| 611 | // END KateEditGeneralConfigTab |
| 612 | |
| 613 | // BEGIN KateEditConfigTab |
| 614 | KateEditConfigTab::KateEditConfigTab(QWidget *parent) |
| 615 | : KateConfigPage(parent) |
| 616 | , editConfigTab(new KateEditGeneralConfigTab(this)) |
| 617 | , navigationConfigTab(new KateNavigationConfigTab(this)) |
| 618 | , indentConfigTab(new KateIndentConfigTab(this)) |
| 619 | , completionConfigTab(new KateCompletionConfigTab(this)) |
| 620 | , spellCheckConfigTab(new KateSpellCheckConfigTab(this)) |
| 621 | { |
| 622 | QVBoxLayout *layout = new QVBoxLayout(this); |
| 623 | layout->setContentsMargins(left: 0, top: 0, right: 0, bottom: 0); |
| 624 | QTabWidget *tabWidget = new QTabWidget(this); |
| 625 | tabWidget->setDocumentMode(true); |
| 626 | |
| 627 | // add all tabs |
| 628 | tabWidget->insertTab(index: 0, widget: editConfigTab, editConfigTab->name()); |
| 629 | tabWidget->insertTab(index: 1, widget: navigationConfigTab, navigationConfigTab->name()); |
| 630 | tabWidget->insertTab(index: 2, widget: indentConfigTab, indentConfigTab->name()); |
| 631 | tabWidget->insertTab(index: 3, widget: completionConfigTab, completionConfigTab->name()); |
| 632 | tabWidget->insertTab(index: 4, widget: spellCheckConfigTab, spellCheckConfigTab->name()); |
| 633 | |
| 634 | observeChanges(page: editConfigTab); |
| 635 | observeChanges(page: navigationConfigTab); |
| 636 | observeChanges(page: indentConfigTab); |
| 637 | observeChanges(page: completionConfigTab); |
| 638 | observeChanges(page: spellCheckConfigTab); |
| 639 | |
| 640 | int i = tabWidget->count(); |
| 641 | for (const auto &factory : KTextEditor::EditorPrivate::self()->inputModeFactories()) { |
| 642 | KateConfigPage *tab = factory->createConfigPage(this); |
| 643 | if (tab) { |
| 644 | m_inputModeConfigTabs.push_back(x: tab); |
| 645 | tabWidget->insertTab(index: i, widget: tab, tab->name()); |
| 646 | observeChanges(page: tab); |
| 647 | i++; |
| 648 | } |
| 649 | } |
| 650 | |
| 651 | layout->addWidget(tabWidget); |
| 652 | } |
| 653 | |
| 654 | KateEditConfigTab::~KateEditConfigTab() |
| 655 | { |
| 656 | qDeleteAll(c: m_inputModeConfigTabs); |
| 657 | } |
| 658 | |
| 659 | void KateEditConfigTab::apply() |
| 660 | { |
| 661 | // try to update the rest of tabs |
| 662 | editConfigTab->apply(); |
| 663 | navigationConfigTab->apply(); |
| 664 | indentConfigTab->apply(); |
| 665 | completionConfigTab->apply(); |
| 666 | spellCheckConfigTab->apply(); |
| 667 | for (KateConfigPage *tab : m_inputModeConfigTabs) { |
| 668 | tab->apply(); |
| 669 | } |
| 670 | } |
| 671 | |
| 672 | void KateEditConfigTab::reload() |
| 673 | { |
| 674 | editConfigTab->reload(); |
| 675 | navigationConfigTab->reload(); |
| 676 | indentConfigTab->reload(); |
| 677 | completionConfigTab->reload(); |
| 678 | spellCheckConfigTab->reload(); |
| 679 | for (KateConfigPage *tab : m_inputModeConfigTabs) { |
| 680 | tab->reload(); |
| 681 | } |
| 682 | } |
| 683 | |
| 684 | void KateEditConfigTab::reset() |
| 685 | { |
| 686 | editConfigTab->reset(); |
| 687 | navigationConfigTab->reset(); |
| 688 | indentConfigTab->reset(); |
| 689 | completionConfigTab->reset(); |
| 690 | spellCheckConfigTab->reset(); |
| 691 | for (KateConfigPage *tab : m_inputModeConfigTabs) { |
| 692 | tab->reset(); |
| 693 | } |
| 694 | } |
| 695 | |
| 696 | void KateEditConfigTab::defaults() |
| 697 | { |
| 698 | editConfigTab->defaults(); |
| 699 | navigationConfigTab->defaults(); |
| 700 | indentConfigTab->defaults(); |
| 701 | completionConfigTab->defaults(); |
| 702 | spellCheckConfigTab->defaults(); |
| 703 | for (KateConfigPage *tab : m_inputModeConfigTabs) { |
| 704 | tab->defaults(); |
| 705 | } |
| 706 | } |
| 707 | |
| 708 | QString KateEditConfigTab::name() const |
| 709 | { |
| 710 | return i18n("Editing" ); |
| 711 | } |
| 712 | |
| 713 | QString KateEditConfigTab::fullName() const |
| 714 | { |
| 715 | return i18n("Editing Options" ); |
| 716 | } |
| 717 | |
| 718 | QIcon KateEditConfigTab::icon() const |
| 719 | { |
| 720 | return QIcon::fromTheme(QStringLiteral("accessories-text-editor" )); |
| 721 | } |
| 722 | |
| 723 | // END KateEditConfigTab |
| 724 | |
| 725 | // BEGIN KateViewDefaultsConfig |
| 726 | KateViewDefaultsConfig::KateViewDefaultsConfig(QWidget *parent) |
| 727 | : KateConfigPage(parent) |
| 728 | , textareaUi(new Ui::TextareaAppearanceConfigWidget()) |
| 729 | , bordersUi(new Ui::BordersAppearanceConfigWidget()) |
| 730 | , statusBarUi(new Ui::StatusbarConfigWidget()) |
| 731 | { |
| 732 | QLayout *layout = new QVBoxLayout(this); |
| 733 | QTabWidget *tabWidget = new QTabWidget(this); |
| 734 | tabWidget->setDocumentMode(true); |
| 735 | layout->addWidget(w: tabWidget); |
| 736 | layout->setContentsMargins(left: 0, top: 0, right: 0, bottom: 0); |
| 737 | |
| 738 | QWidget *textareaTab = new QWidget(tabWidget); |
| 739 | textareaUi->setupUi(textareaTab); |
| 740 | tabWidget->addTab(widget: textareaTab, i18n("General" )); |
| 741 | |
| 742 | QWidget *bordersTab = new QWidget(tabWidget); |
| 743 | bordersUi->setupUi(bordersTab); |
| 744 | tabWidget->addTab(widget: bordersTab, i18n("Borders" )); |
| 745 | |
| 746 | QWidget *statusbarTab = new QWidget(tabWidget); |
| 747 | statusBarUi->setupUi(statusbarTab); |
| 748 | tabWidget->addTab(widget: statusbarTab, i18n("Statusbar" )); |
| 749 | |
| 750 | textareaUi->cmbDynamicWordWrapIndicator->addItem(i18n("Off" )); |
| 751 | textareaUi->cmbDynamicWordWrapIndicator->addItem(i18n("Follow Line Numbers" )); |
| 752 | textareaUi->cmbDynamicWordWrapIndicator->addItem(i18n("Always On" )); |
| 753 | |
| 754 | // "What's This?" help is in the ui-file |
| 755 | |
| 756 | reload(); |
| 757 | |
| 758 | observeChanges(chooser: textareaUi->kfontrequester); |
| 759 | |
| 760 | observeChanges(button: textareaUi->chkAnimateBracketMatching); |
| 761 | observeChanges(button: textareaUi->chkDynWrapAnywhere); |
| 762 | observeChanges(button: textareaUi->chkDynWrapAtStaticMarker); |
| 763 | observeChanges(button: textareaUi->chkFoldFirstLine); |
| 764 | observeChanges(button: textareaUi->chkShowBracketMatchPreview); |
| 765 | observeChanges(button: textareaUi->chkShowIndentationLines); |
| 766 | observeChanges(button: textareaUi->chkShowLineCount); |
| 767 | observeChanges(button: textareaUi->chkShowTabs); |
| 768 | observeChanges(button: textareaUi->chkShowWholeBracketExpression); |
| 769 | observeChanges(button: textareaUi->chkShowWordCount); |
| 770 | observeChanges(comboBox: textareaUi->cmbDynamicWordWrapIndicator); |
| 771 | observeChanges(button: textareaUi->cbxWordWrap); |
| 772 | observeChanges(spinBox: textareaUi->spbLineHeightMultiplier); |
| 773 | auto a = [ui = textareaUi, cbx = textareaUi->cbxWordWrap]() { |
| 774 | ui->chkDynWrapAtStaticMarker->setEnabled(cbx->isChecked()); |
| 775 | ui->chkDynWrapAnywhere->setEnabled(cbx->isChecked()); |
| 776 | ui->cmbDynamicWordWrapIndicator->setEnabled(cbx->isChecked()); |
| 777 | ui->sbDynamicWordWrapDepth->setEnabled(cbx->isChecked()); |
| 778 | }; |
| 779 | connect(sender: textareaUi->cbxWordWrap, signal: &QCheckBox::checkStateChanged, context: this, slot&: a); |
| 780 | a(); |
| 781 | auto b = [cbx = textareaUi->cbxIndentWrappedLines, sb = textareaUi->sbDynamicWordWrapDepth]() { |
| 782 | sb->setEnabled(cbx->isChecked()); |
| 783 | }; |
| 784 | b(); |
| 785 | connect(sender: textareaUi->cbxIndentWrappedLines, signal: &QCheckBox::checkStateChanged, context: this, slot&: b); |
| 786 | observeChanges(button: textareaUi->cbxIndentWrappedLines); |
| 787 | observeChanges(spinBox: textareaUi->sbDynamicWordWrapDepth); |
| 788 | observeChanges(slider: textareaUi->sliSetMarkerSize); |
| 789 | observeChanges(comboBox: textareaUi->spacesComboBox); |
| 790 | |
| 791 | observeChanges(button: bordersUi->chkIconBorder); |
| 792 | observeChanges(button: bordersUi->chkLineNumbers); |
| 793 | observeChanges(button: bordersUi->chkScrollbarMarks); |
| 794 | observeChanges(button: bordersUi->chkScrollbarMiniMap); |
| 795 | observeChanges(button: bordersUi->chkScrollbarMiniMapAll); |
| 796 | bordersUi->chkScrollbarMiniMapAll->hide(); // this is temporary until the feature is done |
| 797 | observeChanges(button: bordersUi->chkScrollbarPreview); |
| 798 | observeChanges(button: bordersUi->chkShowFoldingMarkers); |
| 799 | observeChanges(button: bordersUi->chkShowFoldingPreview); |
| 800 | observeChanges(button: bordersUi->chkShowLineModification); |
| 801 | observeChanges(comboBox: bordersUi->cmbShowScrollbars); |
| 802 | observeChanges(button: bordersUi->rbSortBookmarksByCreation); |
| 803 | observeChanges(button: bordersUi->rbSortBookmarksByPosition); |
| 804 | observeChanges(spinBox: bordersUi->spBoxMiniMapWidth); |
| 805 | observeChanges(comboBox: bordersUi->cmbFoldingArrowVisiblity); |
| 806 | |
| 807 | // statusBarUi |
| 808 | observeChanges(button: statusBarUi->cbShowActiveDictionary); |
| 809 | observeChanges(button: statusBarUi->cbShowHighlightingMode); |
| 810 | observeChanges(button: statusBarUi->cbShowInputMode); |
| 811 | observeChanges(button: statusBarUi->cbShowLineColumn); |
| 812 | observeChanges(button: statusBarUi->cbShowTabSetting); |
| 813 | observeChanges(button: statusBarUi->cbShowEncoding); |
| 814 | observeChanges(button: statusBarUi->cbShowEOL); |
| 815 | } |
| 816 | |
| 817 | KateViewDefaultsConfig::~KateViewDefaultsConfig() |
| 818 | { |
| 819 | delete bordersUi; |
| 820 | delete textareaUi; |
| 821 | delete statusBarUi; |
| 822 | } |
| 823 | |
| 824 | void KateViewDefaultsConfig::apply() |
| 825 | { |
| 826 | // nothing changed, no need to apply stuff |
| 827 | if (!hasChanged()) { |
| 828 | return; |
| 829 | } |
| 830 | m_changed = false; |
| 831 | |
| 832 | KateViewConfig::global()->configStart(); |
| 833 | KateRendererConfig::global()->configStart(); |
| 834 | |
| 835 | KateDocumentConfig::global()->setMarkerSize(textareaUi->sliSetMarkerSize->value()); |
| 836 | KateDocumentConfig::global()->setShowSpaces(KateDocumentConfig::WhitespaceRendering(textareaUi->spacesComboBox->currentIndex())); |
| 837 | KateDocumentConfig::global()->setShowTabs(textareaUi->chkShowTabs->isChecked()); |
| 838 | |
| 839 | KateRendererConfig::global()->setFont(textareaUi->kfontrequester->font()); |
| 840 | KateRendererConfig::global()->setAnimateBracketMatching(textareaUi->chkAnimateBracketMatching->isChecked()); |
| 841 | KateRendererConfig::global()->setShowIndentationLines(textareaUi->chkShowIndentationLines->isChecked()); |
| 842 | KateRendererConfig::global()->setShowWholeBracketExpression(textareaUi->chkShowWholeBracketExpression->isChecked()); |
| 843 | KateRendererConfig::global()->setLineHeightMultiplier(textareaUi->spbLineHeightMultiplier->value()); |
| 844 | |
| 845 | KateViewConfig::global()->setDynWordWrap(textareaUi->cbxWordWrap->isChecked()); |
| 846 | KateViewConfig::global()->setShowWordCount(textareaUi->chkShowWordCount->isChecked()); |
| 847 | KateViewConfig::global()->setValue(key: KateViewConfig::BookmarkSorting, value: bordersUi->rbSortBookmarksByPosition->isChecked() ? 0 : 1); |
| 848 | if (!textareaUi->cbxIndentWrappedLines->isChecked()) { |
| 849 | KateViewConfig::global()->setValue(key: KateViewConfig::DynWordWrapAlignIndent, value: 0); |
| 850 | } else { |
| 851 | KateViewConfig::global()->setValue(key: KateViewConfig::DynWordWrapAlignIndent, value: textareaUi->sbDynamicWordWrapDepth->value()); |
| 852 | } |
| 853 | KateViewConfig::global()->setValue(key: KateViewConfig::DynWordWrapIndicators, value: textareaUi->cmbDynamicWordWrapIndicator->currentIndex()); |
| 854 | KateViewConfig::global()->setValue(key: KateViewConfig::DynWrapAnywhere, value: textareaUi->chkDynWrapAnywhere->isChecked()); |
| 855 | KateViewConfig::global()->setValue(key: KateViewConfig::DynWrapAtStaticMarker, value: textareaUi->chkDynWrapAtStaticMarker->isChecked()); |
| 856 | KateViewConfig::global()->setValue(key: KateViewConfig::FoldFirstLine, value: textareaUi->chkFoldFirstLine->isChecked()); |
| 857 | KateViewConfig::global()->setValue(key: KateViewConfig::ScrollBarMiniMapWidth, value: bordersUi->spBoxMiniMapWidth->value()); |
| 858 | KateViewConfig::global()->setValue(key: KateViewConfig::ShowBracketMatchPreview, value: textareaUi->chkShowBracketMatchPreview->isChecked()); |
| 859 | KateViewConfig::global()->setValue(key: KateViewConfig::ShowFoldingBar, value: bordersUi->chkShowFoldingMarkers->isChecked()); |
| 860 | KateViewConfig::global()->setValue(key: KateViewConfig::ShowFoldingPreview, value: bordersUi->chkShowFoldingPreview->isChecked()); |
| 861 | KateViewConfig::global()->setValue(key: KateViewConfig::ShowIconBar, value: bordersUi->chkIconBorder->isChecked()); |
| 862 | KateViewConfig::global()->setValue(key: KateViewConfig::ShowLineCount, value: textareaUi->chkShowLineCount->isChecked()); |
| 863 | KateViewConfig::global()->setValue(key: KateViewConfig::ShowLineModification, value: bordersUi->chkShowLineModification->isChecked()); |
| 864 | KateViewConfig::global()->setValue(key: KateViewConfig::ShowLineNumbers, value: bordersUi->chkLineNumbers->isChecked()); |
| 865 | KateViewConfig::global()->setValue(key: KateViewConfig::ShowScrollBarMarks, value: bordersUi->chkScrollbarMarks->isChecked()); |
| 866 | KateViewConfig::global()->setValue(key: KateViewConfig::ShowScrollBarMiniMap, value: bordersUi->chkScrollbarMiniMap->isChecked()); |
| 867 | KateViewConfig::global()->setValue(key: KateViewConfig::ShowScrollBarMiniMapAll, value: bordersUi->chkScrollbarMiniMapAll->isChecked()); |
| 868 | KateViewConfig::global()->setValue(key: KateViewConfig::ShowScrollBarPreview, value: bordersUi->chkScrollbarPreview->isChecked()); |
| 869 | KateViewConfig::global()->setValue(key: KateViewConfig::ShowScrollbars, value: bordersUi->cmbShowScrollbars->currentIndex()); |
| 870 | bool showOnHoverOnly = bordersUi->cmbFoldingArrowVisiblity->currentIndex() == 0; |
| 871 | KateViewConfig::global()->setValue(key: KateViewConfig::ShowFoldingOnHoverOnly, value: showOnHoverOnly); |
| 872 | |
| 873 | // Statusbar stuff |
| 874 | KateViewConfig::global()->setValue(key: KateViewConfig::ShowStatusbarDictionary, value: statusBarUi->cbShowActiveDictionary->isChecked()); |
| 875 | KateViewConfig::global()->setValue(key: KateViewConfig::ShowStatusbarHighlightingMode, value: statusBarUi->cbShowHighlightingMode->isChecked()); |
| 876 | KateViewConfig::global()->setValue(key: KateViewConfig::ShowStatusbarInputMode, value: statusBarUi->cbShowInputMode->isChecked()); |
| 877 | KateViewConfig::global()->setValue(key: KateViewConfig::ShowStatusbarLineColumn, value: statusBarUi->cbShowLineColumn->isChecked()); |
| 878 | KateViewConfig::global()->setValue(key: KateViewConfig::ShowStatusbarTabSettings, value: statusBarUi->cbShowTabSetting->isChecked()); |
| 879 | KateViewConfig::global()->setValue(key: KateViewConfig::ShowStatusbarFileEncoding, value: statusBarUi->cbShowEncoding->isChecked()); |
| 880 | KateViewConfig::global()->setValue(key: KateViewConfig::ShowStatusbarEOL, value: statusBarUi->cbShowEOL->isChecked()); |
| 881 | |
| 882 | KateRendererConfig::global()->configEnd(); |
| 883 | KateViewConfig::global()->configEnd(); |
| 884 | } |
| 885 | |
| 886 | void KateViewDefaultsConfig::reload() |
| 887 | { |
| 888 | bordersUi->chkIconBorder->setChecked(KateViewConfig::global()->iconBar()); |
| 889 | bordersUi->chkLineNumbers->setChecked(KateViewConfig::global()->lineNumbers()); |
| 890 | bordersUi->chkScrollbarMarks->setChecked(KateViewConfig::global()->scrollBarMarks()); |
| 891 | bordersUi->chkScrollbarMiniMap->setChecked(KateViewConfig::global()->scrollBarMiniMap()); |
| 892 | bordersUi->chkScrollbarMiniMapAll->setChecked(KateViewConfig::global()->scrollBarMiniMapAll()); |
| 893 | bordersUi->chkScrollbarPreview->setChecked(KateViewConfig::global()->scrollBarPreview()); |
| 894 | bordersUi->chkShowFoldingMarkers->setChecked(KateViewConfig::global()->foldingBar()); |
| 895 | bordersUi->chkShowFoldingPreview->setChecked(KateViewConfig::global()->foldingPreview()); |
| 896 | bordersUi->chkShowLineModification->setChecked(KateViewConfig::global()->lineModification()); |
| 897 | bordersUi->cmbShowScrollbars->setCurrentIndex(KateViewConfig::global()->showScrollbars()); |
| 898 | bordersUi->rbSortBookmarksByCreation->setChecked(KateViewConfig::global()->bookmarkSort() == 1); |
| 899 | bordersUi->rbSortBookmarksByPosition->setChecked(KateViewConfig::global()->bookmarkSort() == 0); |
| 900 | bordersUi->spBoxMiniMapWidth->setValue(KateViewConfig::global()->scrollBarMiniMapWidth()); |
| 901 | bordersUi->cmbFoldingArrowVisiblity->setCurrentIndex(KateViewConfig::global()->showFoldingOnHoverOnly() ? 0 : 1); |
| 902 | |
| 903 | textareaUi->kfontrequester->setFont(font: KateRendererConfig::global()->baseFont()); |
| 904 | |
| 905 | textareaUi->chkAnimateBracketMatching->setChecked(KateRendererConfig::global()->animateBracketMatching()); |
| 906 | textareaUi->chkDynWrapAnywhere->setChecked(KateViewConfig::global()->dynWrapAnywhere()); |
| 907 | textareaUi->chkDynWrapAtStaticMarker->setChecked(KateViewConfig::global()->dynWrapAtStaticMarker()); |
| 908 | textareaUi->chkFoldFirstLine->setChecked(KateViewConfig::global()->foldFirstLine()); |
| 909 | textareaUi->chkShowBracketMatchPreview->setChecked(KateViewConfig::global()->value(key: KateViewConfig::ShowBracketMatchPreview).toBool()); |
| 910 | textareaUi->chkShowIndentationLines->setChecked(KateRendererConfig::global()->showIndentationLines()); |
| 911 | textareaUi->chkShowLineCount->setChecked(KateViewConfig::global()->showLineCount()); |
| 912 | textareaUi->chkShowTabs->setChecked(KateDocumentConfig::global()->showTabs()); |
| 913 | textareaUi->chkShowWholeBracketExpression->setChecked(KateRendererConfig::global()->showWholeBracketExpression()); |
| 914 | textareaUi->chkShowWordCount->setChecked(KateViewConfig::global()->showWordCount()); |
| 915 | textareaUi->cmbDynamicWordWrapIndicator->setCurrentIndex(KateViewConfig::global()->dynWordWrapIndicators()); |
| 916 | textareaUi->cbxWordWrap->setChecked(KateViewConfig::global()->dynWordWrap()); |
| 917 | textareaUi->cbxIndentWrappedLines->setChecked(KateViewConfig::global()->dynWordWrapAlignIndent() != 0); |
| 918 | textareaUi->sbDynamicWordWrapDepth->setValue(KateViewConfig::global()->dynWordWrapAlignIndent()); |
| 919 | textareaUi->sliSetMarkerSize->setValue(KateDocumentConfig::global()->markerSize()); |
| 920 | textareaUi->spacesComboBox->setCurrentIndex(KateDocumentConfig::global()->showSpaces()); |
| 921 | textareaUi->spbLineHeightMultiplier->setValue(KateRendererConfig::global()->lineHeightMultiplier()); |
| 922 | |
| 923 | statusBarUi->cbShowLineColumn->setChecked(KateViewConfig::global()->value(key: KateViewConfig::ShowStatusbarLineColumn).toBool()); |
| 924 | statusBarUi->cbShowActiveDictionary->setChecked(KateViewConfig::global()->value(key: KateViewConfig::ShowStatusbarDictionary).toBool()); |
| 925 | statusBarUi->cbShowTabSetting->setChecked(KateViewConfig::global()->value(key: KateViewConfig::ShowStatusbarTabSettings).toBool()); |
| 926 | statusBarUi->cbShowHighlightingMode->setChecked(KateViewConfig::global()->value(key: KateViewConfig::ShowStatusbarHighlightingMode).toBool()); |
| 927 | statusBarUi->cbShowInputMode->setChecked(KateViewConfig::global()->value(key: KateViewConfig::ShowStatusbarInputMode).toBool()); |
| 928 | statusBarUi->cbShowEncoding->setChecked(KateViewConfig::global()->value(key: KateViewConfig::ShowStatusbarFileEncoding).toBool()); |
| 929 | statusBarUi->cbShowEOL->setChecked(KateViewConfig::global()->value(key: KateViewConfig::ShowStatusbarEOL).toBool()); |
| 930 | } |
| 931 | |
| 932 | void KateViewDefaultsConfig::reset() |
| 933 | { |
| 934 | } |
| 935 | |
| 936 | void KateViewDefaultsConfig::defaults() |
| 937 | { |
| 938 | } |
| 939 | |
| 940 | QString KateViewDefaultsConfig::name() const |
| 941 | { |
| 942 | return i18n("Appearance" ); |
| 943 | } |
| 944 | |
| 945 | QString KateViewDefaultsConfig::fullName() const |
| 946 | { |
| 947 | return i18n("Appearance" ); |
| 948 | } |
| 949 | |
| 950 | QIcon KateViewDefaultsConfig::icon() const |
| 951 | { |
| 952 | return QIcon::fromTheme(QStringLiteral("preferences-desktop-theme" )); |
| 953 | } |
| 954 | |
| 955 | // END KateViewDefaultsConfig |
| 956 | |
| 957 | // BEGIN KateSaveConfigTab |
| 958 | KateSaveConfigTab::KateSaveConfigTab(QWidget *parent) |
| 959 | : KateConfigPage(parent) |
| 960 | , modeConfigPage(new ModeConfigPage(this)) |
| 961 | { |
| 962 | // FIXME: Is really needed to move all this code below to another class, |
| 963 | // since it is another tab itself on the config dialog. This means we should |
| 964 | // initialize, add and work with as we do with modeConfigPage (ereslibre) |
| 965 | QVBoxLayout *layout = new QVBoxLayout(this); |
| 966 | layout->setContentsMargins(left: 0, top: 0, right: 0, bottom: 0); |
| 967 | QTabWidget *tabWidget = new QTabWidget(this); |
| 968 | tabWidget->setDocumentMode(true); |
| 969 | |
| 970 | QWidget *tmpWidget = new QWidget(tabWidget); |
| 971 | QVBoxLayout *internalLayout = new QVBoxLayout(tmpWidget); |
| 972 | QWidget *newWidget = new QWidget(tabWidget); |
| 973 | ui = new Ui::OpenSaveConfigWidget(); |
| 974 | ui->setupUi(newWidget); |
| 975 | |
| 976 | QWidget *tmpWidget2 = new QWidget(tabWidget); |
| 977 | QVBoxLayout *internalLayout2 = new QVBoxLayout(tmpWidget2); |
| 978 | QWidget *newWidget2 = new QWidget(tabWidget); |
| 979 | uiadv = new Ui::OpenSaveConfigAdvWidget(); |
| 980 | uiadv->setupUi(newWidget2); |
| 981 | uiadv->lblExplanatory->setText( |
| 982 | i18n("%1 backs up unsaved files to \"swap files.\" Swap files allow %1 to recover your work in the case of a system crash. Disabling swap files may " |
| 983 | "cause data loss in case of a system crash." , |
| 984 | QCoreApplication::applicationName())); |
| 985 | |
| 986 | // "What's This?" help can be found in the ui file |
| 987 | |
| 988 | reload(); |
| 989 | |
| 990 | observeChanges(comboBox: ui->cbRemoveTrailingSpaces); |
| 991 | observeChanges(button: ui->chkDetectEOL); |
| 992 | observeChanges(button: ui->chkEnableBOM); |
| 993 | observeChanges(button: ui->chkNewLineAtEof); |
| 994 | observeChanges(comboBox: ui->cmbEOL); |
| 995 | observeChanges(comboBox: ui->cmbEncoding); |
| 996 | observeChanges(comboBox: ui->cmbEncodingDetection); |
| 997 | observeChanges(comboBox: ui->cmbEncodingFallback); |
| 998 | observeChanges(spinBox: ui->lineLengthLimit); |
| 999 | observeChanges(groupBox: ui->gbAutoSave); |
| 1000 | observeChanges(button: ui->cbAutoSaveOnFocus); |
| 1001 | observeChanges(spinBox: ui->spbAutoSaveInterval); |
| 1002 | |
| 1003 | observeChanges(button: uiadv->chkAutoReloadVersionControl); |
| 1004 | observeChanges(button: uiadv->chkAutoReloadOnExternalChanges); |
| 1005 | |
| 1006 | observeChanges(button: uiadv->chkBackupLocalFiles); |
| 1007 | observeChanges(button: uiadv->chkBackupRemoteFiles); |
| 1008 | observeChanges(comboBox: uiadv->cmbSwapFileMode); |
| 1009 | connect(sender: uiadv->cmbSwapFileMode, signal: &QComboBox::currentIndexChanged, context: this, slot: &KateSaveConfigTab::swapFileModeChanged); |
| 1010 | |
| 1011 | observeChanges(lineEdit: uiadv->edtBackupPrefix); |
| 1012 | observeChanges(lineEdit: uiadv->edtBackupSuffix); |
| 1013 | observeChanges(requester: uiadv->kurlSwapDirectory); |
| 1014 | observeChanges(spinBox: uiadv->spbSwapFileSync); |
| 1015 | observeChanges(button: uiadv->chkEditorConfig); |
| 1016 | |
| 1017 | internalLayout->addWidget(newWidget); |
| 1018 | internalLayout2->addWidget(newWidget2); |
| 1019 | |
| 1020 | // add all tabs |
| 1021 | tabWidget->insertTab(index: 0, widget: tmpWidget, i18n("General" )); |
| 1022 | tabWidget->insertTab(index: 1, widget: tmpWidget2, i18n("Advanced" )); |
| 1023 | tabWidget->insertTab(index: 2, widget: modeConfigPage, modeConfigPage->name()); |
| 1024 | |
| 1025 | observeChanges(page: modeConfigPage); |
| 1026 | |
| 1027 | layout->addWidget(tabWidget); |
| 1028 | |
| 1029 | // support variable expansion in backup prefix/suffix |
| 1030 | KTextEditor::Editor::instance()->addVariableExpansion(widgets: {uiadv->edtBackupPrefix, uiadv->edtBackupSuffix}, |
| 1031 | variables: {QStringLiteral("Date:Locale" ), |
| 1032 | QStringLiteral("Date:ISO" ), |
| 1033 | QStringLiteral("Date:" ), |
| 1034 | QStringLiteral("Time:Locale" ), |
| 1035 | QStringLiteral("Time:ISO" ), |
| 1036 | QStringLiteral("Time:" ), |
| 1037 | QStringLiteral("ENV:" ), |
| 1038 | QStringLiteral("JS:" ), |
| 1039 | QStringLiteral("UUID" )}); |
| 1040 | } |
| 1041 | |
| 1042 | KateSaveConfigTab::~KateSaveConfigTab() |
| 1043 | { |
| 1044 | delete uiadv; |
| 1045 | delete ui; |
| 1046 | } |
| 1047 | |
| 1048 | void KateSaveConfigTab::swapFileModeChanged(int idx) |
| 1049 | { |
| 1050 | const KateDocumentConfig::SwapFileMode mode = static_cast<KateDocumentConfig::SwapFileMode>(idx); |
| 1051 | switch (mode) { |
| 1052 | case KateDocumentConfig::DisableSwapFile: |
| 1053 | uiadv->lblSwapDirectory->setEnabled(false); |
| 1054 | uiadv->kurlSwapDirectory->setEnabled(false); |
| 1055 | uiadv->lblSwapFileSync->setEnabled(false); |
| 1056 | uiadv->spbSwapFileSync->setEnabled(false); |
| 1057 | break; |
| 1058 | case KateDocumentConfig::EnableSwapFile: |
| 1059 | uiadv->lblSwapDirectory->setEnabled(false); |
| 1060 | uiadv->kurlSwapDirectory->setEnabled(false); |
| 1061 | uiadv->lblSwapFileSync->setEnabled(true); |
| 1062 | uiadv->spbSwapFileSync->setEnabled(true); |
| 1063 | break; |
| 1064 | case KateDocumentConfig::SwapFilePresetDirectory: |
| 1065 | uiadv->lblSwapDirectory->setEnabled(true); |
| 1066 | uiadv->kurlSwapDirectory->setEnabled(true); |
| 1067 | uiadv->lblSwapFileSync->setEnabled(true); |
| 1068 | uiadv->spbSwapFileSync->setEnabled(true); |
| 1069 | break; |
| 1070 | } |
| 1071 | } |
| 1072 | |
| 1073 | void KateSaveConfigTab::apply() |
| 1074 | { |
| 1075 | modeConfigPage->apply(); |
| 1076 | |
| 1077 | // nothing changed, no need to apply stuff |
| 1078 | if (!hasChanged()) { |
| 1079 | return; |
| 1080 | } |
| 1081 | m_changed = false; |
| 1082 | |
| 1083 | KateGlobalConfig::global()->configStart(); |
| 1084 | KateDocumentConfig::global()->configStart(); |
| 1085 | |
| 1086 | if (uiadv->edtBackupSuffix->text().isEmpty() && uiadv->edtBackupPrefix->text().isEmpty()) { |
| 1087 | KMessageBox::information(parent: this, i18n("You did not provide a backup suffix or prefix. Using default suffix: '~'" ), i18n("No Backup Suffix or Prefix" )); |
| 1088 | uiadv->edtBackupSuffix->setText(QStringLiteral("~" )); |
| 1089 | } |
| 1090 | |
| 1091 | KateDocumentConfig::global()->setBackupOnSaveLocal(uiadv->chkBackupLocalFiles->isChecked()); |
| 1092 | KateDocumentConfig::global()->setBackupOnSaveRemote(uiadv->chkBackupRemoteFiles->isChecked()); |
| 1093 | KateDocumentConfig::global()->setBackupPrefix(uiadv->edtBackupPrefix->text()); |
| 1094 | KateDocumentConfig::global()->setBackupSuffix(uiadv->edtBackupSuffix->text()); |
| 1095 | |
| 1096 | KateDocumentConfig::global()->setSwapFileMode(uiadv->cmbSwapFileMode->currentIndex()); |
| 1097 | KateDocumentConfig::global()->setSwapDirectory(uiadv->kurlSwapDirectory->url().toLocalFile()); |
| 1098 | KateDocumentConfig::global()->setSwapSyncInterval(uiadv->spbSwapFileSync->value()); |
| 1099 | |
| 1100 | KateDocumentConfig::global()->setRemoveSpaces(ui->cbRemoveTrailingSpaces->currentIndex()); |
| 1101 | |
| 1102 | KateDocumentConfig::global()->setNewLineAtEof(ui->chkNewLineAtEof->isChecked()); |
| 1103 | |
| 1104 | // set both standard and fallback encoding |
| 1105 | KateDocumentConfig::global()->setEncoding(KCharsets::charsets()->encodingForName(descriptiveName: ui->cmbEncoding->currentText())); |
| 1106 | |
| 1107 | KateGlobalConfig::global()->setValue(key: KateGlobalConfig::EncodingProberType, value: (KEncodingProber::ProberType)ui->cmbEncodingDetection->currentIndex()); |
| 1108 | KateGlobalConfig::global()->setFallbackEncoding(KCharsets::charsets()->encodingForName(descriptiveName: ui->cmbEncodingFallback->currentText())); |
| 1109 | |
| 1110 | KateDocumentConfig::global()->setEol(ui->cmbEOL->currentIndex()); |
| 1111 | KateDocumentConfig::global()->setAllowEolDetection(ui->chkDetectEOL->isChecked()); |
| 1112 | KateDocumentConfig::global()->setBom(ui->chkEnableBOM->isChecked()); |
| 1113 | |
| 1114 | KateDocumentConfig::global()->setLineLengthLimit(ui->lineLengthLimit->value()); |
| 1115 | |
| 1116 | KateDocumentConfig::global()->setValue(key: KateDocumentConfig::AutoSave, value: ui->gbAutoSave->isChecked()); |
| 1117 | KateDocumentConfig::global()->setValue(key: KateDocumentConfig::AutoSaveOnFocusOut, value: ui->cbAutoSaveOnFocus->isChecked()); |
| 1118 | KateDocumentConfig::global()->setValue(key: KateDocumentConfig::AutoSaveInteral, value: ui->spbAutoSaveInterval->value()); |
| 1119 | |
| 1120 | KateDocumentConfig::global()->setValue(key: KateDocumentConfig::AutoReloadIfStateIsInVersionControl, value: uiadv->chkAutoReloadVersionControl->isChecked()); |
| 1121 | KateDocumentConfig::global()->setValue(key: KateDocumentConfig::AutoReloadOnExternalChanges, value: uiadv->chkAutoReloadOnExternalChanges->isChecked()); |
| 1122 | KateDocumentConfig::global()->setValue(key: KateDocumentConfig::UseEditorConfig, value: uiadv->chkEditorConfig->isChecked()); |
| 1123 | |
| 1124 | KateDocumentConfig::global()->configEnd(); |
| 1125 | KateGlobalConfig::global()->configEnd(); |
| 1126 | } |
| 1127 | |
| 1128 | void KateSaveConfigTab::reload() |
| 1129 | { |
| 1130 | modeConfigPage->reload(); |
| 1131 | |
| 1132 | // encodings |
| 1133 | ui->cmbEncoding->clear(); |
| 1134 | ui->cmbEncodingFallback->clear(); |
| 1135 | QStringList encodings(KCharsets::charsets()->descriptiveEncodingNames()); |
| 1136 | for (int i = 0; i < encodings.count(); i++) { |
| 1137 | const auto encodingName = KCharsets::charsets()->encodingForName(descriptiveName: encodings[i]); |
| 1138 | |
| 1139 | ui->cmbEncoding->addItem(atext: encodings[i]); |
| 1140 | ui->cmbEncodingFallback->addItem(atext: encodings[i]); |
| 1141 | |
| 1142 | if (encodingName == KateDocumentConfig::global()->encoding()) { |
| 1143 | ui->cmbEncoding->setCurrentIndex(i); |
| 1144 | } |
| 1145 | |
| 1146 | if (encodingName == KateGlobalConfig::global()->fallbackEncoding()) { |
| 1147 | // adjust index for fallback config, has no default! |
| 1148 | ui->cmbEncodingFallback->setCurrentIndex(i); |
| 1149 | } |
| 1150 | } |
| 1151 | |
| 1152 | // encoding detection |
| 1153 | ui->cmbEncodingDetection->clear(); |
| 1154 | bool found = false; |
| 1155 | const auto proberType = (KEncodingProber::ProberType)KateGlobalConfig::global()->value(key: KateGlobalConfig::EncodingProberType).toInt(); |
| 1156 | for (int i = 0; !KEncodingProber::nameForProberType(proberType: (KEncodingProber::ProberType)i).isEmpty(); ++i) { |
| 1157 | ui->cmbEncodingDetection->addItem(atext: KEncodingProber::nameForProberType(proberType: (KEncodingProber::ProberType)i)); |
| 1158 | if (i == proberType) { |
| 1159 | ui->cmbEncodingDetection->setCurrentIndex(ui->cmbEncodingDetection->count() - 1); |
| 1160 | found = true; |
| 1161 | } |
| 1162 | } |
| 1163 | if (!found) { |
| 1164 | ui->cmbEncodingDetection->setCurrentIndex(KEncodingProber::Universal); |
| 1165 | } |
| 1166 | |
| 1167 | // eol |
| 1168 | ui->cmbEOL->setCurrentIndex(KateDocumentConfig::global()->eol()); |
| 1169 | ui->chkDetectEOL->setChecked(KateDocumentConfig::global()->allowEolDetection()); |
| 1170 | ui->chkEnableBOM->setChecked(KateDocumentConfig::global()->bom()); |
| 1171 | ui->lineLengthLimit->setValue(KateDocumentConfig::global()->lineLengthLimit()); |
| 1172 | |
| 1173 | ui->cbRemoveTrailingSpaces->setCurrentIndex(KateDocumentConfig::global()->removeSpaces()); |
| 1174 | ui->chkNewLineAtEof->setChecked(KateDocumentConfig::global()->newLineAtEof()); |
| 1175 | |
| 1176 | // other stuff |
| 1177 | uiadv->chkBackupLocalFiles->setChecked(KateDocumentConfig::global()->backupOnSaveLocal()); |
| 1178 | uiadv->chkBackupRemoteFiles->setChecked(KateDocumentConfig::global()->backupOnSaveRemote()); |
| 1179 | uiadv->edtBackupPrefix->setText(KateDocumentConfig::global()->backupPrefix()); |
| 1180 | uiadv->edtBackupSuffix->setText(KateDocumentConfig::global()->backupSuffix()); |
| 1181 | |
| 1182 | uiadv->cmbSwapFileMode->setCurrentIndex(KateDocumentConfig::global()->swapFileMode()); |
| 1183 | uiadv->kurlSwapDirectory->setUrl(QUrl::fromLocalFile(localfile: KateDocumentConfig::global()->swapDirectory())); |
| 1184 | uiadv->spbSwapFileSync->setValue(KateDocumentConfig::global()->swapSyncInterval()); |
| 1185 | swapFileModeChanged(idx: KateDocumentConfig::global()->swapFileMode()); |
| 1186 | |
| 1187 | ui->gbAutoSave->setChecked(KateDocumentConfig::global()->autoSave()); |
| 1188 | ui->cbAutoSaveOnFocus->setChecked(KateDocumentConfig::global()->autoSaveOnFocusOut()); |
| 1189 | ui->spbAutoSaveInterval->setValue(KateDocumentConfig::global()->autoSaveInterval()); |
| 1190 | |
| 1191 | uiadv->chkAutoReloadVersionControl->setChecked(KateDocumentConfig::global()->value(key: KateDocumentConfig::AutoReloadIfStateIsInVersionControl).toBool()); |
| 1192 | uiadv->chkAutoReloadOnExternalChanges->setChecked(KateDocumentConfig::global()->value(key: KateDocumentConfig::AutoReloadOnExternalChanges).toBool()); |
| 1193 | uiadv->chkEditorConfig->setChecked(KateDocumentConfig::global()->value(key: KateDocumentConfig::UseEditorConfig).toBool()); |
| 1194 | } |
| 1195 | |
| 1196 | void KateSaveConfigTab::reset() |
| 1197 | { |
| 1198 | modeConfigPage->reset(); |
| 1199 | } |
| 1200 | |
| 1201 | void KateSaveConfigTab::defaults() |
| 1202 | { |
| 1203 | modeConfigPage->defaults(); |
| 1204 | |
| 1205 | ui->cbRemoveTrailingSpaces->setCurrentIndex(0); |
| 1206 | |
| 1207 | uiadv->chkBackupLocalFiles->setChecked(true); |
| 1208 | uiadv->chkBackupRemoteFiles->setChecked(false); |
| 1209 | uiadv->edtBackupPrefix->setText(QString()); |
| 1210 | uiadv->edtBackupSuffix->setText(QStringLiteral("~" )); |
| 1211 | |
| 1212 | uiadv->cmbSwapFileMode->setCurrentIndex(1); |
| 1213 | uiadv->kurlSwapDirectory->setDisabled(true); |
| 1214 | uiadv->lblSwapDirectory->setDisabled(true); |
| 1215 | uiadv->spbSwapFileSync->setValue(15); |
| 1216 | } |
| 1217 | |
| 1218 | QString KateSaveConfigTab::name() const |
| 1219 | { |
| 1220 | return i18n("Open/Save" ); |
| 1221 | } |
| 1222 | |
| 1223 | QString KateSaveConfigTab::fullName() const |
| 1224 | { |
| 1225 | return i18n("File Opening & Saving" ); |
| 1226 | } |
| 1227 | |
| 1228 | QIcon KateSaveConfigTab::icon() const |
| 1229 | { |
| 1230 | return QIcon::fromTheme(QStringLiteral("document-save" )); |
| 1231 | } |
| 1232 | |
| 1233 | // END KateSaveConfigTab |
| 1234 | |
| 1235 | // BEGIN KateGotoBar |
| 1236 | KateGotoBar::KateGotoBar(KTextEditor::View *view, QWidget *parent) |
| 1237 | : KateViewBarWidget(true, parent) |
| 1238 | , m_view(view) |
| 1239 | { |
| 1240 | Q_ASSERT(m_view != nullptr); // this bar widget is pointless w/o a view |
| 1241 | |
| 1242 | QHBoxLayout *topLayout = new QHBoxLayout(centralWidget()); |
| 1243 | topLayout->setContentsMargins(left: 0, top: 0, right: 0, bottom: 0); |
| 1244 | |
| 1245 | QToolButton *btn = new QToolButton(this); |
| 1246 | btn->setAutoRaise(true); |
| 1247 | btn->setMinimumSize(QSize(1, btn->minimumSizeHint().height())); |
| 1248 | btn->setText(i18n("&Line:" )); |
| 1249 | btn->setToolTip(i18n("Go to line number from clipboard" )); |
| 1250 | connect(sender: btn, signal: &QToolButton::clicked, context: this, slot: &KateGotoBar::gotoClipboard); |
| 1251 | topLayout->addWidget(btn); |
| 1252 | |
| 1253 | m_gotoRange = new QSpinBox(this); |
| 1254 | topLayout->addWidget(m_gotoRange, stretch: 1); |
| 1255 | topLayout->setStretchFactor(w: m_gotoRange, stretch: 0); |
| 1256 | |
| 1257 | btn = new QToolButton(this); |
| 1258 | btn->setAutoRaise(true); |
| 1259 | btn->setMinimumSize(QSize(1, btn->minimumSizeHint().height())); |
| 1260 | btn->setText(i18n("Go to" )); |
| 1261 | btn->setIcon(QIcon::fromTheme(QStringLiteral("go-jump" ))); |
| 1262 | btn->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); |
| 1263 | connect(sender: btn, signal: &QToolButton::clicked, context: this, slot: &KateGotoBar::gotoLine); |
| 1264 | topLayout->addWidget(btn); |
| 1265 | |
| 1266 | btn = m_modifiedUp = new QToolButton(this); |
| 1267 | btn->setAutoRaise(true); |
| 1268 | btn->setMinimumSize(QSize(1, btn->minimumSizeHint().height())); |
| 1269 | btn->setDefaultAction(m_view->action(QStringLiteral("modified_line_up" ))); |
| 1270 | btn->setIcon(QIcon::fromTheme(QStringLiteral("go-up-search" ))); |
| 1271 | btn->setText(QString()); |
| 1272 | btn->installEventFilter(filterObj: this); |
| 1273 | topLayout->addWidget(btn); |
| 1274 | |
| 1275 | btn = m_modifiedDown = new QToolButton(this); |
| 1276 | btn->setAutoRaise(true); |
| 1277 | btn->setMinimumSize(QSize(1, btn->minimumSizeHint().height())); |
| 1278 | btn->setDefaultAction(m_view->action(QStringLiteral("modified_line_down" ))); |
| 1279 | btn->setIcon(QIcon::fromTheme(QStringLiteral("go-down-search" ))); |
| 1280 | btn->setText(QString()); |
| 1281 | btn->installEventFilter(filterObj: this); |
| 1282 | topLayout->addWidget(btn); |
| 1283 | |
| 1284 | topLayout->addStretch(); |
| 1285 | |
| 1286 | setFocusProxy(m_gotoRange); |
| 1287 | } |
| 1288 | |
| 1289 | void KateGotoBar::showEvent(QShowEvent *event) |
| 1290 | { |
| 1291 | Q_UNUSED(event) |
| 1292 | // Catch rare cases where the bar is visible while document is edited |
| 1293 | connect(sender: m_view->document(), signal: &KTextEditor::Document::textChanged, context: this, slot: &KateGotoBar::updateData); |
| 1294 | } |
| 1295 | |
| 1296 | void KateGotoBar::closed() |
| 1297 | { |
| 1298 | disconnect(sender: m_view->document(), signal: &KTextEditor::Document::textChanged, receiver: this, slot: &KateGotoBar::updateData); |
| 1299 | } |
| 1300 | |
| 1301 | bool KateGotoBar::eventFilter(QObject *object, QEvent *event) |
| 1302 | { |
| 1303 | if (object == m_modifiedUp || object == m_modifiedDown) { |
| 1304 | if (event->type() != QEvent::Wheel) { |
| 1305 | return false; |
| 1306 | } |
| 1307 | |
| 1308 | int delta = static_cast<QWheelEvent *>(event)->angleDelta().y(); |
| 1309 | // Reset m_wheelDelta when scroll direction change |
| 1310 | if (m_wheelDelta != 0 && (m_wheelDelta < 0) != (delta < 0)) { |
| 1311 | m_wheelDelta = 0; |
| 1312 | } |
| 1313 | |
| 1314 | m_wheelDelta += delta; |
| 1315 | |
| 1316 | if (m_wheelDelta >= 120) { |
| 1317 | m_wheelDelta = 0; |
| 1318 | m_modifiedUp->click(); |
| 1319 | } else if (m_wheelDelta <= -120) { |
| 1320 | m_wheelDelta = 0; |
| 1321 | m_modifiedDown->click(); |
| 1322 | } |
| 1323 | } |
| 1324 | |
| 1325 | return false; |
| 1326 | } |
| 1327 | |
| 1328 | void KateGotoBar::gotoClipboard() |
| 1329 | { |
| 1330 | static const QRegularExpression rx(QStringLiteral("-?\\d+" )); |
| 1331 | bool ok = false; |
| 1332 | const int lineNo = rx.match(subject: QApplication::clipboard()->text(mode: QClipboard::Selection)).captured().toInt(ok: &ok); |
| 1333 | if (!ok) { |
| 1334 | return; |
| 1335 | } |
| 1336 | if (lineNo >= m_gotoRange->minimum() && lineNo <= m_gotoRange->maximum()) { |
| 1337 | m_gotoRange->setValue(lineNo); |
| 1338 | gotoLine(); |
| 1339 | } else { |
| 1340 | QPointer<KTextEditor::Message> message = new KTextEditor::Message(i18n("No valid line number found in clipboard" )); |
| 1341 | message->setWordWrap(true); |
| 1342 | message->setAutoHide(2000); |
| 1343 | message->setPosition(KTextEditor::Message::BottomInView); |
| 1344 | message->setView(m_view), m_view->document()->postMessage(message); |
| 1345 | } |
| 1346 | } |
| 1347 | |
| 1348 | void KateGotoBar::updateData() |
| 1349 | { |
| 1350 | int lines = m_view->document()->lines(); |
| 1351 | m_gotoRange->setMinimum(-lines); |
| 1352 | m_gotoRange->setMaximum(lines); |
| 1353 | if (!isVisible()) { |
| 1354 | m_gotoRange->setValue(m_view->cursorPosition().line() + 1); |
| 1355 | m_gotoRange->adjustSize(); // ### does not respect the range :-( |
| 1356 | } |
| 1357 | |
| 1358 | m_gotoRange->selectAll(); |
| 1359 | } |
| 1360 | |
| 1361 | void KateGotoBar::keyPressEvent(QKeyEvent *event) |
| 1362 | { |
| 1363 | int key = event->key(); |
| 1364 | if (key == Qt::Key_Return || key == Qt::Key_Enter) { |
| 1365 | gotoLine(); |
| 1366 | return; |
| 1367 | } |
| 1368 | KateViewBarWidget::keyPressEvent(event); |
| 1369 | } |
| 1370 | |
| 1371 | void KateGotoBar::gotoLine() |
| 1372 | { |
| 1373 | KTextEditor::ViewPrivate *kv = qobject_cast<KTextEditor::ViewPrivate *>(object: m_view); |
| 1374 | if (kv && kv->selection() && !kv->config()->persistentSelection()) { |
| 1375 | kv->clearSelection(); |
| 1376 | } |
| 1377 | |
| 1378 | int gotoValue = m_gotoRange->value(); |
| 1379 | if (gotoValue < 0) { |
| 1380 | gotoValue += m_view->document()->lines(); |
| 1381 | } else if (gotoValue > 0) { |
| 1382 | gotoValue -= 1; |
| 1383 | } |
| 1384 | |
| 1385 | m_view->setCursorPosition(KTextEditor::Cursor(gotoValue, 0)); |
| 1386 | m_view->setFocus(); |
| 1387 | Q_EMIT hideMe(); |
| 1388 | } |
| 1389 | // END KateGotoBar |
| 1390 | |
| 1391 | // BEGIN KateDictionaryBar |
| 1392 | KateDictionaryBar::KateDictionaryBar(KTextEditor::ViewPrivate *view, QWidget *parent) |
| 1393 | : KateViewBarWidget(true, parent) |
| 1394 | , m_view(view) |
| 1395 | { |
| 1396 | Q_ASSERT(m_view != nullptr); // this bar widget is pointless w/o a view |
| 1397 | |
| 1398 | QHBoxLayout *topLayout = new QHBoxLayout(centralWidget()); |
| 1399 | topLayout->setContentsMargins(left: 0, top: 0, right: 0, bottom: 0); |
| 1400 | // topLayout->setSpacing(spacingHint()); |
| 1401 | m_dictionaryComboBox = new Sonnet::DictionaryComboBox(centralWidget()); |
| 1402 | connect(sender: m_dictionaryComboBox, signal: &Sonnet::DictionaryComboBox::dictionaryChanged, context: this, slot: &KateDictionaryBar::dictionaryChanged); |
| 1403 | connect(sender: view->doc(), signal: &KTextEditor::DocumentPrivate::defaultDictionaryChanged, context: this, slot: &KateDictionaryBar::updateData); |
| 1404 | QLabel *label = new QLabel(i18n("Dictionary:" ), centralWidget()); |
| 1405 | label->setBuddy(m_dictionaryComboBox); |
| 1406 | |
| 1407 | topLayout->addWidget(label); |
| 1408 | topLayout->addWidget(m_dictionaryComboBox, stretch: 1); |
| 1409 | topLayout->setStretchFactor(w: m_dictionaryComboBox, stretch: 0); |
| 1410 | topLayout->addStretch(); |
| 1411 | } |
| 1412 | |
| 1413 | KateDictionaryBar::~KateDictionaryBar() |
| 1414 | { |
| 1415 | } |
| 1416 | |
| 1417 | void KateDictionaryBar::updateData() |
| 1418 | { |
| 1419 | KTextEditor::DocumentPrivate *document = m_view->doc(); |
| 1420 | QString dictionary = document->defaultDictionary(); |
| 1421 | if (dictionary.isEmpty()) { |
| 1422 | dictionary = Sonnet::Speller().defaultLanguage(); |
| 1423 | } |
| 1424 | m_dictionaryComboBox->setCurrentByDictionary(dictionary); |
| 1425 | } |
| 1426 | |
| 1427 | void KateDictionaryBar::dictionaryChanged(const QString &dictionary) |
| 1428 | { |
| 1429 | const KTextEditor::Range selection = m_view->selectionRange(); |
| 1430 | if (selection.isValid() && !selection.isEmpty()) { |
| 1431 | const bool blockmode = m_view->blockSelection(); |
| 1432 | m_view->doc()->setDictionary(dict: dictionary, range: selection, blockmode); |
| 1433 | } else { |
| 1434 | m_view->doc()->setDefaultDictionary(dictionary); |
| 1435 | } |
| 1436 | } |
| 1437 | |
| 1438 | // END KateGotoBar |
| 1439 | |
| 1440 | // BEGIN KateModOnHdPrompt |
| 1441 | KateModOnHdPrompt::KateModOnHdPrompt(KTextEditor::DocumentPrivate *doc, KTextEditor::Document::ModifiedOnDiskReason modtype, const QString &reason) |
| 1442 | : QObject(doc) |
| 1443 | , m_doc(doc) |
| 1444 | , m_message(new KTextEditor::Message(reason, KTextEditor::Message::Information)) |
| 1445 | , m_fullDiffPath(QStandardPaths::findExecutable(QStringLiteral("diff" ))) |
| 1446 | , m_proc(nullptr) |
| 1447 | , m_diffFile(nullptr) |
| 1448 | , m_diffAction(nullptr) |
| 1449 | { |
| 1450 | m_message->setPosition(KTextEditor::Message::AboveView); |
| 1451 | m_message->setWordWrap(true); |
| 1452 | |
| 1453 | // If the file isn't deleted, present a diff button |
| 1454 | const bool onDiskDeleted = modtype == KTextEditor::Document::OnDiskDeleted; |
| 1455 | if (!onDiskDeleted) { |
| 1456 | QAction *aAutoReload = new QAction(i18n("Enable Auto Reload" ), this); |
| 1457 | aAutoReload->setIcon(QIcon::fromTheme(QStringLiteral("view-refresh" ))); |
| 1458 | aAutoReload->setToolTip( |
| 1459 | i18n("Reloads and will automatically reload without warning about disk changes from now until you close either the tab or window." )); |
| 1460 | m_message->addAction(action: aAutoReload, closeOnTrigger: false); |
| 1461 | connect(sender: aAutoReload, signal: &QAction::triggered, context: this, slot: &KateModOnHdPrompt::autoReloadTriggered); |
| 1462 | |
| 1463 | if (!m_fullDiffPath.isEmpty()) { |
| 1464 | m_diffAction = new QAction(i18n("View &Difference" ), this); |
| 1465 | m_diffAction->setIcon(QIcon::fromTheme(QStringLiteral("document-multiple" ))); |
| 1466 | m_diffAction->setToolTip(i18n("Shows a diff of the changes." )); |
| 1467 | m_message->addAction(action: m_diffAction, closeOnTrigger: false); |
| 1468 | connect(sender: m_diffAction, signal: &QAction::triggered, context: this, slot: &KateModOnHdPrompt::slotDiff); |
| 1469 | } |
| 1470 | |
| 1471 | QAction *aReload = new QAction(i18n("&Reload" ), this); |
| 1472 | aReload->setIcon(QIcon::fromTheme(QStringLiteral("view-refresh" ))); |
| 1473 | aReload->setToolTip(i18n("Reloads the file from disk. Unsaved changes will be lost." )); |
| 1474 | m_message->addAction(action: aReload); |
| 1475 | connect(sender: aReload, signal: &QAction::triggered, context: this, slot: &KateModOnHdPrompt::reloadTriggered); |
| 1476 | } else { |
| 1477 | QAction *closeFile = new QAction(i18nc("@action:button closes the opened file" , "&Close File" ), this); |
| 1478 | closeFile->setIcon(QIcon::fromTheme(QStringLiteral("document-close" ))); |
| 1479 | closeFile->setToolTip(i18n("Closes the file, discarding its content." )); |
| 1480 | m_message->addAction(action: closeFile, closeOnTrigger: false); |
| 1481 | connect(sender: closeFile, signal: &QAction::triggered, context: this, slot: &KateModOnHdPrompt::closeTriggered); |
| 1482 | |
| 1483 | auto *aSaveAs = new QAction(i18nc("@action" , "&Save As…" ), this); |
| 1484 | aSaveAs->setIcon(QIcon::fromTheme(QStringLiteral("document-save-as" ))); |
| 1485 | aSaveAs->setToolTip(i18n("Lets you select a location and save the file again." )); |
| 1486 | m_message->addAction(action: aSaveAs, closeOnTrigger: false); |
| 1487 | connect(sender: aSaveAs, signal: &QAction::triggered, context: this, slot: &KateModOnHdPrompt::saveAsTriggered); |
| 1488 | } |
| 1489 | |
| 1490 | QAction *aIgnore = new QAction(i18n("&Ignore" ), this); |
| 1491 | aIgnore->setToolTip(i18n("Ignores the changes on disk without any action." )); |
| 1492 | aIgnore->setIcon(QIcon::fromTheme(QStringLiteral("dialog-cancel" ))); |
| 1493 | m_message->addAction(action: aIgnore); |
| 1494 | connect(sender: aIgnore, signal: &QAction::triggered, context: this, slot: &KateModOnHdPrompt::ignoreTriggered); |
| 1495 | |
| 1496 | m_doc->postMessage(message: m_message); |
| 1497 | } |
| 1498 | |
| 1499 | KateModOnHdPrompt::~KateModOnHdPrompt() |
| 1500 | { |
| 1501 | delete m_proc; |
| 1502 | m_proc = nullptr; |
| 1503 | if (m_diffFile) { |
| 1504 | m_diffFile->setAutoRemove(true); |
| 1505 | delete m_diffFile; |
| 1506 | m_diffFile = nullptr; |
| 1507 | } |
| 1508 | delete m_message; |
| 1509 | } |
| 1510 | |
| 1511 | void KateModOnHdPrompt::slotDiff() |
| 1512 | { |
| 1513 | if (m_diffFile) { |
| 1514 | return; |
| 1515 | } |
| 1516 | |
| 1517 | m_diffFile = new QTemporaryFile(QDir::temp().filePath(fileName: QLatin1String("XXXXXX.diff" ))); |
| 1518 | m_diffFile->open(); |
| 1519 | |
| 1520 | // Start a KProcess that creates a diff |
| 1521 | m_proc = new KProcess(this); |
| 1522 | m_proc->setOutputChannelMode(KProcess::MergedChannels); |
| 1523 | *m_proc << m_fullDiffPath << QStringLiteral("-u" ) << QStringLiteral("-" ) << m_doc->url().toLocalFile(); |
| 1524 | connect(sender: m_proc, signal: &KProcess::readyRead, context: this, slot: &KateModOnHdPrompt::slotDataAvailable); |
| 1525 | connect(sender: m_proc, signal: &KProcess::finished, context: this, slot: &KateModOnHdPrompt::slotPDone); |
| 1526 | |
| 1527 | // disable the diff button, to hinder the user to run it twice. |
| 1528 | m_diffAction->setEnabled(false); |
| 1529 | |
| 1530 | m_proc->start(); |
| 1531 | |
| 1532 | QTextStream ts(m_proc); |
| 1533 | int lastln = m_doc->lines() - 1; |
| 1534 | for (int l = 0; l < lastln; ++l) { |
| 1535 | ts << m_doc->line(line: l) << '\n'; |
| 1536 | } |
| 1537 | ts << m_doc->line(line: lastln); |
| 1538 | ts.flush(); |
| 1539 | m_proc->closeWriteChannel(); |
| 1540 | } |
| 1541 | |
| 1542 | void KateModOnHdPrompt::slotDataAvailable() |
| 1543 | { |
| 1544 | m_diffFile->write(data: m_proc->readAll()); |
| 1545 | } |
| 1546 | |
| 1547 | void KateModOnHdPrompt::slotPDone() |
| 1548 | { |
| 1549 | m_diffAction->setEnabled(true); |
| 1550 | |
| 1551 | const QProcess::ExitStatus es = m_proc->exitStatus(); |
| 1552 | delete m_proc; |
| 1553 | m_proc = nullptr; |
| 1554 | |
| 1555 | if (es != QProcess::NormalExit) { |
| 1556 | KMessageBox::error(parent: m_doc->activeView(), |
| 1557 | i18n("The diff command failed. Please make sure that " |
| 1558 | "diff(1) is installed and in your PATH." ), |
| 1559 | i18n("Error Creating Diff" )); |
| 1560 | delete m_diffFile; |
| 1561 | m_diffFile = nullptr; |
| 1562 | return; |
| 1563 | } |
| 1564 | |
| 1565 | if (m_diffFile->size() == 0) { |
| 1566 | KMessageBox::information(parent: m_doc->activeView(), i18n("The files are identical." ), i18n("Diff Output" )); |
| 1567 | delete m_diffFile; |
| 1568 | m_diffFile = nullptr; |
| 1569 | return; |
| 1570 | } |
| 1571 | |
| 1572 | m_diffFile->setAutoRemove(false); |
| 1573 | QUrl url = QUrl::fromLocalFile(localfile: m_diffFile->fileName()); |
| 1574 | delete m_diffFile; |
| 1575 | m_diffFile = nullptr; |
| 1576 | |
| 1577 | KIO::OpenUrlJob *job = new KIO::OpenUrlJob(url, QStringLiteral("text/x-patch" )); |
| 1578 | job->setUiDelegate(KIO::createDefaultJobUiDelegate(flags: KJobUiDelegate::AutoHandlingEnabled, window: m_doc->activeView())); |
| 1579 | job->setDeleteTemporaryFile(true); // delete the file, once the client exits |
| 1580 | job->start(); |
| 1581 | } |
| 1582 | |
| 1583 | // END KateModOnHdPrompt |
| 1584 | |
| 1585 | #include "moc_katedialogs.cpp" |
| 1586 | |