diff --git a/autotests/src/vimode/base.cpp b/autotests/src/vimode/base.cpp --- a/autotests/src/vimode/base.cpp +++ b/autotests/src/vimode/base.cpp @@ -106,7 +106,7 @@ Q_ASSERT(vi_input_mode_manager); vi_global = vi_input_mode->globalState(); Q_ASSERT(vi_global); - kate_document->config()->setShowSpaces(true); // Flush out some issues in the KateRenderer when rendering spaces. + kate_document->config()->setShowSpaces(KateDocumentConfig::Trailing); // Flush out some issues in the KateRenderer when rendering spaces. kate_view->config()->setScrollBarMiniMap(false); kate_view->config()->setScrollBarPreview(false); diff --git a/src/dialogs/katedialogs.cpp b/src/dialogs/katedialogs.cpp --- a/src/dialogs/katedialogs.cpp +++ b/src/dialogs/katedialogs.cpp @@ -673,7 +673,7 @@ connect(textareaUi->cmbDynamicWordWrapIndicator, SIGNAL(activated(int)), this, SLOT(slotChanged())); connect(textareaUi->sbDynamicWordWrapDepth, SIGNAL(valueChanged(int)), this, SLOT(slotChanged())); connect(textareaUi->chkShowTabs, SIGNAL(toggled(bool)), this, SLOT(slotChanged())); - connect(textareaUi->chkShowSpaces, SIGNAL(toggled(bool)), this, SLOT(slotChanged())); + connect(textareaUi->spacesComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, &KateViewDefaultsConfig::slotChanged); connect(textareaUi->chkShowIndentationLines, SIGNAL(toggled(bool)), this, SLOT(slotChanged())); connect(textareaUi->sliSetMarkerSize, SIGNAL(valueChanged(int)), this, SLOT(slotChanged())); connect(textareaUi->chkShowWholeBracketExpression, SIGNAL(toggled(bool)), this, SLOT(slotChanged())); @@ -720,7 +720,7 @@ KateViewConfig::global()->setDynWordWrapIndicators(textareaUi->cmbDynamicWordWrapIndicator->currentIndex()); KateViewConfig::global()->setDynWordWrapAlignIndent(textareaUi->sbDynamicWordWrapDepth->value()); KateDocumentConfig::global()->setShowTabs(textareaUi->chkShowTabs->isChecked()); - KateDocumentConfig::global()->setShowSpaces(textareaUi->chkShowSpaces->isChecked()); + KateDocumentConfig::global()->setShowSpaces(KateDocumentConfig::WhitespaceRendering(textareaUi->spacesComboBox->currentIndex())); KateDocumentConfig::global()->setMarkerSize(textareaUi->sliSetMarkerSize->value()); KateViewConfig::global()->setLineNumbers(bordersUi->chkLineNumbers->isChecked()); KateViewConfig::global()->setIconBar(bordersUi->chkIconBorder->isChecked()); @@ -753,7 +753,7 @@ textareaUi->cmbDynamicWordWrapIndicator->setCurrentIndex(KateViewConfig::global()->dynWordWrapIndicators()); textareaUi->sbDynamicWordWrapDepth->setValue(KateViewConfig::global()->dynWordWrapAlignIndent()); textareaUi->chkShowTabs->setChecked(KateDocumentConfig::global()->showTabs()); - textareaUi->chkShowSpaces->setChecked(KateDocumentConfig::global()->showSpaces()); + textareaUi->spacesComboBox->setCurrentIndex(KateDocumentConfig::global()->showSpaces()); textareaUi->sliSetMarkerSize->setValue(KateDocumentConfig::global()->markerSize()); bordersUi->chkLineNumbers->setChecked(KateViewConfig::global()->lineNumbers()); bordersUi->chkIconBorder->setChecked(KateViewConfig::global()->iconBar()); diff --git a/src/dialogs/textareaappearanceconfigwidget.ui b/src/dialogs/textareaappearanceconfigwidget.ui --- a/src/dialogs/textareaappearanceconfigwidget.ui +++ b/src/dialogs/textareaappearanceconfigwidget.ui @@ -148,25 +148,27 @@ Whitespace Highlighting - - - - - The editor will display a symbol to indicate the presence of a tab in the text. - - - &Highlight tabulators - - - - - - - Highlight trailing &spaces - + + + + + + None + + + + + Trailing + + + + + All + + - + true @@ -179,28 +181,52 @@ - - - - Size of the visible highlight marker. - - - 1 - - - 5 - - - 1 - - - Qt::Horizontal - - - + + + + Size of the visible highlight marker. + + + 1 + + + 5 + + + 1 + + + Qt::Horizontal + + + + + + + Whitepaces + + + + + + + The editor will display a symbol to indicate the presence of a tab in the text. + + + + + + + + + + Highlight tabulators + + + @@ -306,8 +332,8 @@ chkDynWrapAtStaticMarker cmbDynamicWordWrapIndicator sbDynamicWordWrapDepth + spacesComboBox chkShowTabs - chkShowSpaces sliSetMarkerSize chkShowIndentationLines chkShowWholeBracketExpression diff --git a/src/document/katedocument.cpp b/src/document/katedocument.cpp --- a/src/document/katedocument.cpp +++ b/src/document/katedocument.cpp @@ -4605,7 +4605,7 @@ } else if (var == QLatin1String("show-tabs") && checkBoolValue(val, &state)) { m_config->setShowTabs(state); } else if (var == QLatin1String("show-trailing-spaces") && checkBoolValue(val, &state)) { - m_config->setShowSpaces(state); + m_config->setShowSpaces(state ? KateDocumentConfig::Trailing : KateDocumentConfig::None); } else if (var == QLatin1String("space-indent") && checkBoolValue(val, &state)) { // this is for backward compatibility; see below spaceIndent = state; diff --git a/src/render/katerenderer.h b/src/render/katerenderer.h --- a/src/render/katerenderer.h +++ b/src/render/katerenderer.h @@ -26,6 +26,7 @@ #include #include "katetextline.h" #include "katelinelayout.h" +#include "kateconfig.h" #include #include @@ -172,17 +173,17 @@ void setShowTabs(bool showTabs); /** - * @returns whether trailing spaces should be shown. + * Set which spaces should be rendered */ - inline bool showTrailingSpaces() const - { - return m_showSpaces; - } + void setShowSpaces(KateDocumentConfig::WhitespaceRendering showSpaces); /** - * Set whether a mark should be painted for trailing spaces. + * @returns whether which spaces should be rendered */ - void setShowTrailingSpaces(bool showSpaces); + inline KateDocumentConfig::WhitespaceRendering showSpaces() const + { + return m_showSpaces; + } /** * Update marker size shown. @@ -372,7 +373,7 @@ /** * Paint a trailing space on position (x, y). */ - void paintTrailingSpace(QPainter &paint, qreal x, qreal y); + void paintSpace(QPainter &paint, qreal x, qreal y); /** * Paint a tab stop marker on position (x, y). */ @@ -410,7 +411,7 @@ bool m_drawCaret; bool m_showSelections; bool m_showTabs; - bool m_showSpaces; + KateDocumentConfig::WhitespaceRendering m_showSpaces = KateDocumentConfig::None; float m_markerSize; bool m_showNonPrintableSpaces; bool m_printerFriendly; diff --git a/src/render/katerenderer.cpp b/src/render/katerenderer.cpp --- a/src/render/katerenderer.cpp +++ b/src/render/katerenderer.cpp @@ -59,7 +59,7 @@ , m_drawCaret(true) , m_showSelections(true) , m_showTabs(true) - , m_showSpaces(true) + , m_showSpaces(KateDocumentConfig::Trailing) , m_showNonPrintableSpaces(false) , m_printerFriendly(false) , m_config(new KateRendererConfig(this)) @@ -116,7 +116,7 @@ m_showTabs = showTabs; } -void KateRenderer::setShowTrailingSpaces(bool showSpaces) +void KateRenderer::setShowSpaces(KateDocumentConfig::WhitespaceRendering showSpaces) { m_showSpaces = showSpaces; } @@ -179,7 +179,7 @@ { m_printerFriendly = printerFriendly; setShowTabs(false); - setShowTrailingSpaces(false); + setShowSpaces(KateDocumentConfig::None); setShowSelections(false); setDrawCaret(false); } @@ -271,7 +271,7 @@ paint.setPen(penBackup); } -void KateRenderer::paintTrailingSpace(QPainter &paint, qreal x, qreal y) +void KateRenderer::paintSpace(QPainter &paint, qreal x, qreal y) { QPen penBackup(paint.pen()); QPen pen(config()->tabMarkerColor()); @@ -723,22 +723,26 @@ } // draw trailing spaces - if (showTrailingSpaces()) { + if (showSpaces() != KateDocumentConfig::None) { int spaceIndex = line.endCol() - 1; - int trailingPos = range->textLine()->lastChar(); - if (trailingPos < 0) { - trailingPos = 0; - } + const int trailingPos = showSpaces() == KateDocumentConfig::All ? 0 : qMax(range->textLine()->lastChar(), 0); + if (spaceIndex >= trailingPos) { - while (spaceIndex >= line.startCol() && text.at(spaceIndex).isSpace()) { + for (; spaceIndex >= line.startCol(); --spaceIndex) { + if (!text.at(spaceIndex).isSpace()) { + if (showSpaces() == KateDocumentConfig::Trailing) + break; + else + continue; + } + if (text.at(spaceIndex) != QLatin1Char('\t') || !showTabs()) { if (range->layout()->textOption().alignment() == Qt::AlignRight) { // Draw on left for RTL lines - paintTrailingSpace(paint, line.lineLayout().cursorToX(spaceIndex) - xStart - spaceWidth() / 2.0, y); + paintSpace(paint, line.lineLayout().cursorToX(spaceIndex) - xStart - spaceWidth() / 2.0, y); } else { - paintTrailingSpace(paint, line.lineLayout().cursorToX(spaceIndex) - xStart + spaceWidth() / 2.0, y); + paintSpace(paint, line.lineLayout().cursorToX(spaceIndex) - xStart + spaceWidth() / 2.0, y); } } - --spaceIndex; } } } diff --git a/src/utils/katecmds.cpp b/src/utils/katecmds.cpp --- a/src/utils/katecmds.cpp +++ b/src/utils/katecmds.cpp @@ -403,7 +403,7 @@ } else if (cmd == QLatin1String("set-show-tabs")) { config->setShowTabs(enable); } else if (cmd == QLatin1String("set-show-trailing-spaces")) { - config->setShowSpaces(enable); + config->setShowSpaces(enable ? KateDocumentConfig::Trailing : KateDocumentConfig::None); } else if (cmd == QLatin1String("set-word-wrap")) { v->doc()->setWordWrap(enable); } diff --git a/src/utils/kateconfig.h b/src/utils/kateconfig.h --- a/src/utils/kateconfig.h +++ b/src/utils/kateconfig.h @@ -209,6 +209,12 @@ tabSmart = 2 //!< indents in leading space, otherwise inserts tab }; + enum WhitespaceRendering { + None, + Trailing, + All + }; + uint tabHandling() const; void setTabHandling(uint tabHandling); @@ -236,8 +242,8 @@ void setShowTabs(bool on); bool showTabs() const; - void setShowSpaces(bool on); - bool showSpaces() const; + void setShowSpaces(WhitespaceRendering on); + WhitespaceRendering showSpaces() const; void setMarkerSize(uint markerSize); uint markerSize() const; @@ -361,7 +367,7 @@ bool m_showTabsSet : 1; bool m_showTabs : 1; bool m_showSpacesSet : 1; - bool m_showSpaces : 1; + WhitespaceRendering m_showSpaces : 2; uint m_markerSize = 1; bool m_replaceTabsDynSet : 1; bool m_replaceTabsDyn : 1; diff --git a/src/utils/kateconfig.cpp b/src/utils/kateconfig.cpp --- a/src/utils/kateconfig.cpp +++ b/src/utils/kateconfig.cpp @@ -178,7 +178,7 @@ m_smartHomeSet(false), m_showTabsSet(false), m_showSpacesSet(false), - + m_showSpaces(None), m_replaceTabsDynSet(false), m_removeSpacesSet(false), m_newLineAtEofSet(false), @@ -223,6 +223,7 @@ m_smartHomeSet(false), m_showTabsSet(false), m_showSpacesSet(false), + m_showSpaces(None), m_markerSize(1), m_replaceTabsDynSet(false), m_removeSpacesSet(false), @@ -262,6 +263,7 @@ m_smartHomeSet(false), m_showTabsSet(false), m_showSpacesSet(false), + m_showSpaces(None), m_markerSize(1), m_replaceTabsDynSet(false), m_removeSpacesSet(false), @@ -345,7 +347,7 @@ setKeepExtraSpaces(config.readEntry(KEY_KEEP_EXTRA_SPACES, false)); setIndentPastedText(config.readEntry(KEY_INDENT_PASTED_TEXT, false)); setBackspaceIndents(config.readEntry(KEY_BACKSPACE_INDENTS, true)); - setShowSpaces(config.readEntry(KEY_SHOW_SPACES, false)); + setShowSpaces(KateDocumentConfig::WhitespaceRendering(config.readEntry(KEY_SHOW_SPACES, int(KateDocumentConfig::None)))); setMarkerSize(config.readEntry(KEY_MARKER_SIZE, 1)); setReplaceTabsDyn(config.readEntry(KEY_REPLACE_TABS_DYN, true)); setRemoveSpaces(config.readEntry(KEY_REMOVE_SPACES, 0)); @@ -396,7 +398,7 @@ config.writeEntry(KEY_KEEP_EXTRA_SPACES, keepExtraSpaces()); config.writeEntry(KEY_INDENT_PASTED_TEXT, indentPastedText()); config.writeEntry(KEY_BACKSPACE_INDENTS, backspaceIndents()); - config.writeEntry(KEY_SHOW_SPACES, showSpaces()); + config.writeEntry(KEY_SHOW_SPACES, int(showSpaces())); config.writeEntry(KEY_MARKER_SIZE, markerSize()); config.writeEntry(KEY_REPLACE_TABS_DYN, replaceTabsDyn()); config.writeEntry(KEY_REMOVE_SPACES, removeSpaces()); @@ -729,7 +731,7 @@ return s_global->showTabs(); } -void KateDocumentConfig::setShowSpaces(bool on) +void KateDocumentConfig::setShowSpaces(WhitespaceRendering on) { if (m_showSpacesSet && m_showSpaces == on) { return; @@ -743,7 +745,7 @@ configEnd(); } -bool KateDocumentConfig::showSpaces() const +KateDocumentConfig::WhitespaceRendering KateDocumentConfig::showSpaces() const { if (m_showSpacesSet || isGlobal()) { return m_showSpaces; diff --git a/src/view/kateviewinternal.cpp b/src/view/kateviewinternal.cpp --- a/src/view/kateviewinternal.cpp +++ b/src/view/kateviewinternal.cpp @@ -2986,7 +2986,7 @@ renderer()->setCaretStyle(m_currentInputMode->caretStyle()); renderer()->setShowTabs(doc()->config()->showTabs()); - renderer()->setShowTrailingSpaces(doc()->config()->showSpaces()); + renderer()->setShowSpaces(doc()->config()->showSpaces()); renderer()->updateMarkerSize(); int sy = startz * h;