KTextEditor

katestatusbar.cpp
1/*
2 SPDX-FileCopyrightText: 2013 Dominik Haumann <dhaumann@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.0-or-later
5*/
6
7#include "katestatusbar.h"
8
9#include "kateabstractinputmode.h"
10#include "kateconfig.h"
11#include "katedocument.h"
12#include "kateglobal.h"
13#include "katemodemanager.h"
14#include "katemodemenulist.h"
15#include "katerenderer.h"
16#include "kateview.h"
17#include "wordcounter.h"
18
19#include <KAcceleratorManager>
20#include <KActionCollection>
21#include <KIconUtils>
22#include <Sonnet/Speller>
23
24#include <QActionGroup>
25#include <QHBoxLayout>
26#include <QInputDialog>
27#include <QStylePainter>
28
29// BEGIN menu
30KateStatusBarOpenUpMenu::KateStatusBarOpenUpMenu(QWidget *parent)
31 : QMenu(parent)
32{
33}
34
35void KateStatusBarOpenUpMenu::setVisible(bool visibility)
36{
37 if (visibility) {
38 QRect geo = geometry();
40 geo.moveTopLeft(QPoint(pos.x(), pos.y() - geo.height()));
41 if (geo.top() < 0) {
42 geo.moveTop(0);
43 }
44 setGeometry(geo);
45 }
46
47 QMenu::setVisible(visibility);
48}
49// END menu
50
51// BEGIN StatusBarButton
52StatusBarButton::StatusBarButton(KateStatusBar *parent, const QString &text /*= QString()*/)
53 : QPushButton(text, parent)
54{
55 setFlat(true);
56 setFocusProxy(parent->m_view);
57 setMinimumSize(QSize(1, minimumSizeHint().height()));
58}
59
60void StatusBarButton::paintEvent(QPaintEvent *)
61{
62 QStylePainter p(this);
64 initStyleOption(&opt);
65 opt.features &= (~QStyleOptionButton::HasMenu);
66 p.drawControl(QStyle::CE_PushButton, opt);
67}
68
69QSize StatusBarButton::sizeHint() const
70{
71 return minimumSizeHint();
72}
73
74QSize StatusBarButton::minimumSizeHint() const
75{
76 const auto fm = QFontMetrics(font());
77 const int h = fm.lineSpacing();
79 const int vMmargin = style()->pixelMetric(QStyle::PM_FocusFrameVMargin) * 2;
80 size.setHeight(h + vMmargin);
81
82 const int w = fm.horizontalAdvance(text());
83 const int bm = style()->pixelMetric(QStyle::PM_ButtonMargin) * 2;
84 const int hMargin = style()->pixelMetric(QStyle::PM_FocusFrameHMargin) * 2;
85 size.setWidth(w + bm + hMargin);
86
87 return size;
88}
89
90// END StatusBarButton
91
92KateStatusBar::KateStatusBar(KTextEditor::ViewPrivate *view)
93 : KateViewBarWidget(false)
94 , m_view(view)
95 , m_selectionMode(-1)
96 , m_wordCounter(nullptr)
97{
99 setFocusProxy(m_view);
100
101 // just add our status bar to central widget, full sized
102 QHBoxLayout *topLayout = new QHBoxLayout(centralWidget());
103 topLayout->setContentsMargins(0, 0, 0, 0);
104 topLayout->setSpacing(0);
105
106 // ensure all elements of the status bar are right aligned
107 // for Kate this is nice, as on the left side are the tool view buttons
108 // for KWrite this makes it more consistent with Kate
109 topLayout->addStretch(1);
110
111 // show Line XXX, Column XXX
112 m_cursorPosition = new StatusBarButton(this);
113 topLayout->addWidget(m_cursorPosition);
114 m_cursorPosition->setWhatsThis(i18n("Current cursor position. Click to go to a specific line."));
115 connect(m_cursorPosition, &StatusBarButton::clicked, m_view, &KTextEditor::ViewPrivate::gotoLine);
116
117 // show the zoom level of the text
118 m_zoomLevel = new StatusBarButton(this);
119 topLayout->addWidget(m_zoomLevel);
120 connect(m_zoomLevel, &StatusBarButton::clicked, [this] {
121 m_view->renderer()->resetFontSizes();
122 });
123
124 // show the current mode, like INSERT, OVERWRITE, VI + modifiers like [BLOCK]
125 m_inputMode = new StatusBarButton(this);
126 topLayout->addWidget(m_inputMode);
127 m_inputMode->setWhatsThis(i18n("Insert mode and VI input mode indicator. Click to change the mode."));
128 connect(m_inputMode, &StatusBarButton::clicked, [this] {
129 m_view->currentInputMode()->toggleInsert();
130 });
131
132 // Add dictionary button which allows user to switch dictionary of the document
133 m_dictionary = new StatusBarButton(this);
134 topLayout->addWidget(m_dictionary, 0);
135 m_dictionary->setWhatsThis(i18n("Change dictionary"));
136 m_dictionaryMenu = new KateStatusBarOpenUpMenu(m_dictionary);
137 m_dictionaryMenu->addAction(m_view->action(QStringLiteral("tools_change_dictionary")));
138 m_dictionaryMenu->addAction(m_view->action(QStringLiteral("tools_clear_dictionary_ranges")));
139 m_dictionaryMenu->addAction(m_view->action(QStringLiteral("tools_toggle_automatic_spell_checking")));
140 m_dictionaryMenu->addAction(m_view->action(QStringLiteral("tools_spelling_from_cursor")));
141 m_dictionaryMenu->addAction(m_view->action(QStringLiteral("tools_spelling")));
142 m_dictionaryMenu->addSeparator();
143 m_dictionaryGroup = new QActionGroup(m_dictionaryMenu);
144 QMapIterator<QString, QString> i(Sonnet::Speller().preferredDictionaries());
145 while (i.hasNext()) {
146 i.next();
147 QAction *action = m_dictionaryGroup->addAction(i.key());
148 action->setData(i.value());
149 action->setToolTip(i.key());
150 action->setCheckable(true);
151 m_dictionaryMenu->addAction(action);
152 }
153 m_dictionary->setMenu(m_dictionaryMenu);
154 connect(m_dictionaryGroup, &QActionGroup::triggered, this, &KateStatusBar::changeDictionary);
155
156 // allow to change indentation configuration
157 m_tabsIndent = new StatusBarButton(this);
158 topLayout->addWidget(m_tabsIndent);
159
160 m_indentSettingsMenu = new KateStatusBarOpenUpMenu(m_tabsIndent);
161 m_indentSettingsMenu->addSection(i18n("Tab Width"));
162 m_tabGroup = new QActionGroup(this);
163 addNumberAction(m_tabGroup, m_indentSettingsMenu, -1);
164 addNumberAction(m_tabGroup, m_indentSettingsMenu, 8);
165 addNumberAction(m_tabGroup, m_indentSettingsMenu, 4);
166 addNumberAction(m_tabGroup, m_indentSettingsMenu, 2);
167 connect(m_tabGroup, &QActionGroup::triggered, this, &KateStatusBar::slotTabGroup);
168
169 m_indentSettingsMenu->addSection(i18n("Indentation Width"));
170 m_indentGroup = new QActionGroup(this);
171 addNumberAction(m_indentGroup, m_indentSettingsMenu, -1);
172 addNumberAction(m_indentGroup, m_indentSettingsMenu, 8);
173 addNumberAction(m_indentGroup, m_indentSettingsMenu, 4);
174 addNumberAction(m_indentGroup, m_indentSettingsMenu, 2);
175 connect(m_indentGroup, &QActionGroup::triggered, this, &KateStatusBar::slotIndentGroup);
176
177 m_indentSettingsMenu->addSection(i18n("Indentation Mode"));
178 QActionGroup *radioGroup = new QActionGroup(m_indentSettingsMenu);
179 m_mixedAction = m_indentSettingsMenu->addAction(i18n("Tabulators && Spaces"));
180 m_mixedAction->setCheckable(true);
181 m_mixedAction->setActionGroup(radioGroup);
182 m_hardAction = m_indentSettingsMenu->addAction(i18n("Tabulators"));
183 m_hardAction->setCheckable(true);
184 m_hardAction->setActionGroup(radioGroup);
185 m_softAction = m_indentSettingsMenu->addAction(i18n("Spaces"));
186 m_softAction->setCheckable(true);
187 m_softAction->setActionGroup(radioGroup);
188 connect(radioGroup, &QActionGroup::triggered, this, &KateStatusBar::slotIndentTabMode);
189
190 m_tabsIndent->setMenu(m_indentSettingsMenu);
191
192 // add encoding button which allows user to switch encoding of document
193 // this will reuse the encoding action menu of the view
194 m_encoding = new StatusBarButton(this);
195 topLayout->addWidget(m_encoding);
196 m_encoding->setMenu(m_view->encodingAction()->menu());
197 m_encoding->setWhatsThis(i18n("Encoding"));
198
199 m_eol = new StatusBarButton(this);
200 m_eol->setWhatsThis(i18n("End of line type"));
201 m_eol->setToolTip(i18n("End of line type"));
202 m_eol->setMenu(m_view->getEolMenu());
203 topLayout->addWidget(m_eol);
204
205 // load the mode menu, which contains a scrollable list + search bar.
206 // This is an alternative menu to the mode action menu of the view.
207 m_modeMenuList = new KateModeMenuList(i18n("Mode"), this);
208 m_modeMenuList->setWhatsThis(i18n(
209 "Here you can choose which mode should be used for the current document. This will influence the highlighting and folding being used, for example."));
210 m_modeMenuList->updateMenu(m_view->doc());
211 // add mode button which allows user to switch mode of document
212 m_mode = new StatusBarButton(this);
213 topLayout->addWidget(m_mode);
214 m_modeMenuList->setButton(m_mode, KateModeMenuList::AlignHInverse, KateModeMenuList::AlignTop, KateModeMenuList::AutoUpdateTextButton(false));
215 m_mode->setMenu(m_modeMenuList);
216 m_mode->setWhatsThis(i18n("Syntax highlighting"));
217
218 // signals for the statusbar
219 connect(m_view, &KTextEditor::View::cursorPositionChanged, this, &KateStatusBar::cursorPositionChanged);
220 connect(m_view, &KTextEditor::View::viewModeChanged, this, &KateStatusBar::viewModeChanged);
221 connect(m_view, &KTextEditor::View::selectionChanged, this, &KateStatusBar::selectionChanged);
222 connect(m_view->doc(), &KTextEditor::Document::configChanged, this, &KateStatusBar::documentConfigChanged);
223 connect(m_view->document(), &KTextEditor::DocumentPrivate::modeChanged, this, &KateStatusBar::modeChanged);
224 connect(m_view, &KTextEditor::View::configChanged, this, &KateStatusBar::configChanged);
225 connect(m_view->doc(), &KTextEditor::DocumentPrivate::defaultDictionaryChanged, this, &KateStatusBar::updateDictionary);
226 connect(m_view->doc(), &KTextEditor::DocumentPrivate::dictionaryRangesPresent, this, &KateStatusBar::updateDictionary);
227 connect(m_view, &KTextEditor::ViewPrivate::caretChangedRange, this, &KateStatusBar::updateDictionary);
228
229 updateStatus();
230 toggleWordCount(KateViewConfig::global()->showWordCount());
231}
232
233bool KateStatusBar::eventFilter(QObject *obj, QEvent *event)
234{
236}
237
238void KateStatusBar::contextMenuEvent(QContextMenuEvent *event)
239{
240 // TODO Add option "Show Statusbar" and options to show/hide buttons of the status bar
241 QMenu menu(this);
242
243 if (childAt(event->pos()) == m_inputMode) {
244 if (QAction *inputModesAction = m_view->actionCollection()->action(QStringLiteral("view_input_modes"))) {
245 if (QMenu *inputModesMenu = inputModesAction->menu()) {
246 const auto actions = inputModesMenu->actions();
247 for (int i = 0; i < actions.count(); ++i) {
248 menu.addAction(actions.at(i));
249 }
250 menu.addSeparator();
251 }
252 }
253 }
254
255 QAction *showLines = menu.addAction(i18n("Show line count"), this, &KateStatusBar::toggleShowLines);
256 showLines->setCheckable(true);
257 showLines->setChecked(KateViewConfig::global()->showLineCount());
258 QAction *showWords = menu.addAction(i18n("Show word count"), this, &KateStatusBar::toggleShowWords);
259 showWords->setCheckable(true);
260 showWords->setChecked(KateViewConfig::global()->showWordCount());
261 auto a = menu.addAction(i18n("Line/Column compact mode"), this, [](bool checked) {
262 KateViewConfig::global()->setValue(KateViewConfig::StatusbarLineColumnCompact, checked);
263 });
264 a->setCheckable(true);
265 a->setChecked(KateViewConfig::global()->value(KateViewConfig::StatusbarLineColumnCompact).toBool());
266 menu.exec(event->globalPos());
267}
268
269void KateStatusBar::toggleShowLines(bool checked)
270{
271 KateViewConfig::global()->setValue(KateViewConfig::ShowLineCount, checked);
272}
273
274void KateStatusBar::toggleShowWords(bool checked)
275{
276 KateViewConfig::global()->setShowWordCount(checked);
277}
278
279void KateStatusBar::updateStatus()
280{
281 selectionChanged();
282 viewModeChanged();
283 cursorPositionChanged();
284 documentConfigChanged();
285 modeChanged();
286 updateDictionary();
287 updateEOL();
288}
289
290void KateStatusBar::selectionChanged()
291{
292 const unsigned int newSelectionMode = m_view->blockSelection();
293 if (newSelectionMode == m_selectionMode) {
294 return;
295 }
296
297 // remember new mode and update info
298 m_selectionMode = newSelectionMode;
299 viewModeChanged();
300}
301
302void KateStatusBar::viewModeChanged()
303{
304 // prepend BLOCK for block selection mode
305 QString text = m_view->viewModeHuman();
306 if (m_view->blockSelection()) {
307 text = i18n("[BLOCK] %1", text);
308 }
309
310 m_inputMode->setText(text);
311}
312
313void KateStatusBar::cursorPositionChanged()
314{
315 KTextEditor::Cursor position(m_view->cursorPositionVirtual());
316 const int l = position.line() + 1;
317 const int c = position.column() + 1;
318
319 // Update line/column label
320 QString text;
321 if (KateViewConfig::global()->value(KateViewConfig::StatusbarLineColumnCompact).toBool()) {
322 if (KateViewConfig::global()->showLineCount()) {
323 text = i18n("%1/%2:%3", QLocale().toString(l), QLocale().toString(m_view->doc()->lines()), QLocale().toString(c));
324 } else {
325 text = i18n("%1:%2", QLocale().toString(l), QLocale().toString(c));
326 }
327 } else {
328 if (KateViewConfig::global()->showLineCount()) {
329 text = i18n("Line %1 of %2, Column %3", QLocale().toString(l), QLocale().toString(m_view->doc()->lines()), QLocale().toString(c));
330 } else {
331 text = i18n("Line %1, Column %2", QLocale().toString(l), QLocale().toString(c));
332 }
333 }
334 if (m_wordCounter) {
335 text.append(QLatin1String(", ") + m_wordCount);
336 }
337 m_cursorPosition->setText(text);
338}
339
340void KateStatusBar::updateDictionary()
341{
342 const auto spellchecker = Sonnet::Speller();
343 const auto availableDictionaries = spellchecker.availableDictionaries();
344 // No dictionaries available? => hide
345 if (availableDictionaries.isEmpty()) {
346 m_dictionary->hide();
347 return;
348 }
349
350 QString newDict;
351 // Check if at the current cursor position is a special dictionary in use
352 KTextEditor::Cursor position(m_view->cursorPositionVirtual());
353 const QList<QPair<KTextEditor::MovingRange *, QString>> dictRanges = m_view->doc()->dictionaryRanges();
354 for (const auto &rangeDictPair : dictRanges) {
355 const KTextEditor::MovingRange *range = rangeDictPair.first;
356 if (range->contains(position) || range->end() == position) {
357 newDict = rangeDictPair.second;
358 break;
359 }
360 }
361 // Check if the default dictionary is in use
362 if (newDict.isEmpty()) {
363 newDict = m_view->doc()->defaultDictionary();
364 if (newDict.isEmpty()) {
365 newDict = spellchecker.defaultLanguage();
366 }
367 }
368 // Update button and menu only on a changed dictionary
369 if (!m_dictionaryGroup->checkedAction() || (m_dictionaryGroup->checkedAction()->data().toString() != newDict) || m_dictionary->text().isEmpty()) {
370 bool found = false;
371 // Remove "-w_accents -variant_0" and such from dict-code to keep it small and clean
372 m_dictionary->setText(newDict.section(QLatin1Char('-'), 0, 0));
373 // For maximum user clearness, change the checked menu option
374 m_dictionaryGroup->blockSignals(true);
375 const auto acts = m_dictionaryGroup->actions();
376 for (auto a : acts) {
377 if (a->data().toString() == newDict) {
378 a->setChecked(true);
379 found = true;
380 break;
381 }
382 }
383 if (!found) {
384 // User has chose some other dictionary from combo box, we need to add that
385 QString dictName = availableDictionaries.key(newDict);
386 if (!dictName.isEmpty()) {
387 QAction *action = m_dictionaryGroup->addAction(dictName);
388 action->setData(newDict);
389 action->setCheckable(true);
390 action->setChecked(true);
391 m_dictionaryMenu->addAction(action);
392 }
393 }
394 m_dictionaryGroup->blockSignals(false);
395 }
396}
397
398void KateStatusBar::documentConfigChanged()
399{
400 m_encoding->setText(m_view->document()->encoding());
401 KateDocumentConfig *config = ((KTextEditor::DocumentPrivate *)m_view->document())->config();
402 int tabWidth = config->tabWidth();
403 int indentationWidth = config->indentationWidth();
404 bool replaceTabsDyn = config->replaceTabsDyn();
405
406 static const KLocalizedString spacesOnly = ki18n("Soft Tabs: %1");
407 static const KLocalizedString spacesOnlyShowTabs = ki18n("Soft Tabs: %1 (%2)");
408 static const KLocalizedString tabsOnly = ki18n("Tab Size: %1");
409 static const KLocalizedString tabSpacesMixed = ki18n("Indent/Tab: %1/%2");
410
411 if (!replaceTabsDyn) {
412 if (tabWidth == indentationWidth) {
413 m_tabsIndent->setText(tabsOnly.subs(tabWidth).toString());
414 m_tabGroup->setEnabled(false);
415 m_hardAction->setChecked(true);
416 } else {
417 m_tabsIndent->setText(tabSpacesMixed.subs(indentationWidth).subs(tabWidth).toString());
418 m_tabGroup->setEnabled(true);
419 m_mixedAction->setChecked(true);
420 }
421 } else {
422 if (tabWidth == indentationWidth) {
423 m_tabsIndent->setText(spacesOnly.subs(indentationWidth).toString());
424 m_tabGroup->setEnabled(true);
425 m_softAction->setChecked(true);
426 } else {
427 m_tabsIndent->setText(spacesOnlyShowTabs.subs(indentationWidth).subs(tabWidth).toString());
428 m_tabGroup->setEnabled(true);
429 m_softAction->setChecked(true);
430 }
431 }
432
433 updateGroup(m_tabGroup, tabWidth);
434 updateGroup(m_indentGroup, indentationWidth);
435 updateEOL();
436}
437
438void KateStatusBar::modeChanged()
439{
440 m_mode->setText(KTextEditor::EditorPrivate::self()->modeManager()->fileType(m_view->document()->mode()).nameTranslated());
441}
442
443void KateStatusBar::addNumberAction(QActionGroup *group, QMenu *menu, int data)
444{
445 QAction *a;
446 if (data != -1) {
447 a = menu->addAction(QStringLiteral("%1").arg(data));
448 } else {
449 a = menu->addAction(i18n("Other..."));
450 }
451 a->setData(data);
452 a->setCheckable(true);
453 a->setActionGroup(group);
454}
455
456void KateStatusBar::updateGroup(QActionGroup *group, int w)
457{
458 QAction *m1 = nullptr;
459 bool found = false;
460 // linear search should be fast enough here, no additional hash
461 const auto acts = group->actions();
462 for (QAction *action : acts) {
463 int val = action->data().toInt();
464 if (val == -1) {
465 m1 = action;
466 }
467 if (val == w) {
468 found = true;
469 action->setChecked(true);
470 }
471 }
472
473 if (m1) {
474 if (found) {
475 m1->setText(i18n("Other..."));
476 } else {
477 m1->setText(i18np("Other (%1)", "Other (%1)", w));
478 m1->setChecked(true);
479 }
480 }
481}
482
483void KateStatusBar::slotTabGroup(QAction *a)
484{
485 int val = a->data().toInt();
486 bool ok;
487 KateDocumentConfig *config = ((KTextEditor::DocumentPrivate *)m_view->document())->config();
488 if (val == -1) {
489 val = QInputDialog::getInt(this, i18n("Tab Width"), i18n("Please specify the wanted tab width:"), config->tabWidth(), 1, 200, 1, &ok);
490 if (!ok) {
491 val = config->tabWidth();
492 }
493 }
494 config->setTabWidth(val);
495}
496
497void KateStatusBar::slotIndentGroup(QAction *a)
498{
499 int val = a->data().toInt();
500 bool ok;
501 KateDocumentConfig *config = ((KTextEditor::DocumentPrivate *)m_view->document())->config();
502 if (val == -1) {
503 val = QInputDialog::getInt(this,
504 i18n("Indentation Width"),
505 i18n("Please specify the wanted indentation width:"),
506 config->indentationWidth(),
507 1,
508 200,
509 1,
510 &ok);
511 if (!ok) {
512 val = config->indentationWidth();
513 }
514 }
515 config->configStart();
516 config->setIndentationWidth(val);
517 if (m_hardAction->isChecked()) {
518 config->setTabWidth(val);
519 }
520 config->configEnd();
521}
522
523void KateStatusBar::slotIndentTabMode(QAction *a)
524{
525 KateDocumentConfig *config = ((KTextEditor::DocumentPrivate *)m_view->document())->config();
526 if (a == m_softAction) {
527 config->setReplaceTabsDyn(true);
528 } else if (a == m_mixedAction) {
529 if (config->replaceTabsDyn()) {
530 config->setReplaceTabsDyn(false);
531 }
532 m_tabGroup->setEnabled(true);
533 } else if (a == m_hardAction) {
534 if (config->replaceTabsDyn()) {
535 config->configStart();
536 config->setReplaceTabsDyn(false);
537 config->setTabWidth(config->indentationWidth());
538 config->configEnd();
539 } else {
540 config->setTabWidth(config->indentationWidth());
541 }
542 m_tabGroup->setEnabled(false);
543 }
544}
545
546void KateStatusBar::toggleWordCount(bool on)
547{
548 if ((m_wordCounter != nullptr) == on) {
549 return;
550 }
551
552 if (on) {
553 m_wordCounter = new WordCounter(m_view);
554 connect(m_wordCounter, &WordCounter::changed, this, &KateStatusBar::wordCountChanged);
555 } else {
556 delete m_wordCounter;
557 m_wordCounter = nullptr;
558 }
559
560 wordCountChanged(0, 0, 0, 0);
561}
562
563void KateStatusBar::wordCountChanged(int wordsInDocument, int wordsInSelection, int charsInDocument, int charsInSelection)
564{
565 if (m_wordCounter) {
566 if (charsInSelection > 0) {
567 m_wordCount = i18nc("%1 and %3 are the selected words/chars count, %2 and %4 are the total words/chars count.",
568 "Words %1/%2, Chars %3/%4",
569 wordsInSelection,
570 wordsInDocument,
571 charsInSelection,
572 charsInDocument);
573 } else {
574 m_wordCount = i18nc("%1 and %2 are the total words/chars count.", "Words %1, Chars %2", wordsInDocument, charsInDocument);
575 }
576 } else {
577 m_wordCount.clear();
578 }
579
580 cursorPositionChanged();
581}
582
583void KateStatusBar::configChanged()
584{
585 toggleWordCount(m_view->config()->showWordCount());
586 const int zoom = m_view->rendererConfig()->baseFont().pointSizeF() / KateRendererConfig::global()->baseFont().pointSizeF() * 100;
587 if (zoom != 100) {
588 m_zoomLevel->setVisible(true);
589 m_zoomLevel->setText(i18n("Zoom: %1%", zoom));
590 } else {
591 m_zoomLevel->hide();
592 }
593
594 auto cfg = KateViewConfig::global();
595 auto updateButtonVisibility = [cfg](StatusBarButton *b, KateViewConfig::ConfigEntryTypes c) {
596 bool v = cfg->value(c).toBool();
597 if (v != (!b->isHidden())) {
598 b->setVisible(v);
599 }
600 };
601 updateButtonVisibility(m_inputMode, KateViewConfig::ShowStatusbarInputMode);
602 updateButtonVisibility(m_mode, KateViewConfig::ShowStatusbarHighlightingMode);
603 updateButtonVisibility(m_cursorPosition, KateViewConfig::ShowStatusbarLineColumn);
604 updateButtonVisibility(m_tabsIndent, KateViewConfig::ShowStatusbarTabSettings);
605 updateButtonVisibility(m_encoding, KateViewConfig::ShowStatusbarFileEncoding);
606 updateButtonVisibility(m_eol, KateViewConfig::ShowStatusbarEOL);
607
608 bool v = cfg->value(KateViewConfig::ShowStatusbarDictionary).toBool();
609 if (v != (!m_dictionary->isHidden()) && !Sonnet::Speller().availableDictionaries().isEmpty()) {
610 updateButtonVisibility(m_dictionary, KateViewConfig::ShowStatusbarDictionary);
611 }
612}
613
614void KateStatusBar::changeDictionary(QAction *action)
615{
616 const QString dictionary = action->data().toString();
617 m_dictionary->setText(dictionary);
618 // Code stolen from KateDictionaryBar::dictionaryChanged
619 KTextEditor::Range selection = m_view->selectionRange();
620 if (selection.isValid() && !selection.isEmpty()) {
621 m_view->doc()->setDictionary(dictionary, selection);
622 } else {
623 m_view->doc()->setDefaultDictionary(dictionary);
624 }
625}
626
627void KateStatusBar::updateEOL()
628{
629 const int eol = m_view->getEol();
630 QString text;
631 switch (eol) {
632 case KateDocumentConfig::eolUnix:
633 text = QStringLiteral("LF");
634 break;
635 case KateDocumentConfig::eolDos:
636 text = QStringLiteral("CRLF");
637 break;
638 case KateDocumentConfig::eolMac:
639 text = QStringLiteral("CR");
640 break;
641 }
642 if (text != m_eol->text()) {
643 m_eol->setText(text);
644 }
645}
646
647KateModeMenuList *KateStatusBar::modeMenu() const
648{
649 return m_modeMenuList;
650}
651
652#include "moc_katestatusbar.cpp"
static void setNoAccel(QWidget *widget)
Q_INVOKABLE QAction * action(const QString &name) const
QString toString() const
KLocalizedString subs(const KLocalizedString &a, int fieldWidth=0, QChar fillChar=QLatin1Char(' ')) const
The Cursor represents a position in a Document.
Definition cursor.h:75
void configChanged(KTextEditor::Document *document)
This signal is emitted whenever the current document configuration is changed.
virtual QString encoding() const =0
Get the current chosen encoding.
virtual QString mode() const =0
Return the name of the currently used mode.
static KTextEditor::EditorPrivate * self()
Kate Part Internal stuff ;)
A range that is bound to a specific Document, and maintains its position.
virtual const MovingCursor & end() const =0
Retrieve end cursor of this range, read-only.
bool contains(const Range &range) const
Check whether the this range wholly encompasses range.
An object representing a section of text, from one Cursor to another.
constexpr bool isEmpty() const noexcept
Returns true if this range contains no characters, ie.
constexpr bool isValid() const noexcept
Validity check.
void configChanged(KTextEditor::View *view)
This signal is emitted whenever the current view configuration is changed.
void cursorPositionChanged(KTextEditor::View *view, KTextEditor::Cursor newPosition)
This signal is emitted whenever the view's cursor position changed.
void viewModeChanged(KTextEditor::View *view, KTextEditor::View::ViewMode mode)
This signal is emitted whenever the view mode of view changes.
void selectionChanged(KTextEditor::View *view)
This signal is emitted whenever the view's selection changes.
virtual KActionCollection * actionCollection() const
void configEnd()
End a config change transaction, update the concerned KateDocumentConfig/KateDocumentConfig/KateDocum...
void configStart()
Start some config changes.
bool setValue(const int key, const QVariant &value)
Set a config value.
Class of menu to select the syntax highlighting language (mode menu).
QMap< QString, QString > availableDictionaries() const
For convenience an own button class to ensure a unified look&feel.
KLocalizedString KI18N_EXPORT ki18n(const char *text)
QString i18np(const char *singular, const char *plural, const TYPE &arg...)
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
char * toString(const EngineQuery &query)
GeoCoordinates geo(const QVariant &location)
QAction * zoom(const QObject *recvr, const char *slot, QObject *parent)
void clicked(bool checked)
void setCheckable(bool)
void setChecked(bool)
QVariant data() const const
void setActionGroup(QActionGroup *group)
void setData(const QVariant &userData)
void setToolTip(const QString &tip)
QList< QAction * > actions() const const
QAction * addAction(QAction *action)
QAction * checkedAction() const const
void setEnabled(bool)
void triggered(QAction *action)
void addStretch(int stretch)
void addWidget(QWidget *widget, int stretch, Qt::Alignment alignment)
void setSpacing(int spacing)
qreal pointSizeF() const const
int getInt(QWidget *parent, const QString &title, const QString &label, int value, int min, int max, int step, bool *ok, Qt::WindowFlags flags)
void setContentsMargins(int left, int top, int right, int bottom)
const T & at(int i) const const
int count(const T &value) const const
bool isEmpty() const const
QAction * addAction(const QString &text)
bool blockSignals(bool block)
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
virtual bool eventFilter(QObject *watched, QEvent *event)
void initStyleOption(QStyleOptionButton *option) const const
virtual QSize sizeHint() const const override
QString & append(QChar ch)
void clear()
bool isEmpty() const const
QString section(QChar sep, int start, int end, QString::SectionFlags flags) const const
PM_FocusFrameVMargin
virtual int pixelMetric(QStyle::PixelMetric metric, const QStyleOption *option, const QWidget *widget) const const=0
int toInt(bool *ok) const const
QString toString() const const
QList< QAction * > actions() const const
QWidget * childAt(int x, int y) const const
virtual bool event(QEvent *event) override
void hide()
bool isHidden() const const
QPoint mapToGlobal(const QPoint &pos) const const
QWidget * parentWidget() const const
void setGeometry(int x, int y, int w, int h)
QStyle * style() const const
virtual void setVisible(bool visible)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Sat Feb 24 2024 20:00:58 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.