1 /*
2     SPDX-FileCopyrightText: 2011-2018 Dominik Haumann <dhaumann@kde.org>
3     SPDX-FileCopyrightText: 2013 Gerald Senarclens de Grancy <oss@senarclens.eu>
4 
5     SPDX-License-Identifier: LGPL-2.0-or-later
6 */
7 
8 #include "variablelineedit.h"
9 
10 #include "kateautoindent.h"
11 #include "katedocument.h"
12 #include "kateglobal.h"
13 #include "katerenderer.h"
14 #include "katesyntaxmanager.h"
15 #include "kateview.h"
16 #include "variableitem.h"
17 #include "variablelistview.h"
18 
19 #include <QApplication>
20 #include <QComboBox>
21 #include <QFrame>
22 #include <QHBoxLayout>
23 #include <QLineEdit>
24 #include <QSizeGrip>
25 #include <QStyle>
26 #include <QToolButton>
27 #include <QVBoxLayout>
28 
29 #include <KLocalizedString>
30 
31 #include <sonnet/speller.h>
32 
VariableLineEdit(QWidget * parent)33 VariableLineEdit::VariableLineEdit(QWidget *parent)
34     : QWidget(parent)
35 {
36     QHBoxLayout *hl = new QHBoxLayout(this);
37     hl->setContentsMargins(0, 0, 0, 0);
38 
39     m_lineedit = new QLineEdit(this);
40     m_button = new QToolButton(this);
41     m_button->setIcon(QIcon::fromTheme(QStringLiteral("tools-wizard")));
42     m_button->setToolTip(i18n("Show list of valid variables."));
43 
44     hl->addWidget(m_lineedit);
45     hl->addWidget(m_button);
46 
47     m_popup.reset(new QFrame(nullptr, Qt::Popup));
48     m_popup->setFrameStyle(QFrame::StyledPanel | QFrame::Raised);
49     QVBoxLayout *l = new QVBoxLayout(m_popup.get());
50     l->setSpacing(0);
51     l->setContentsMargins(0, 0, 0, 0);
52 
53     // forward text changed signal
54     connect(m_lineedit, &QLineEdit::textChanged, this, &VariableLineEdit::textChanged);
55 
56     // open popup on button click
57     connect(m_button, &QToolButton::clicked, this, &VariableLineEdit::editVariables);
58 }
59 
editVariables()60 void VariableLineEdit::editVariables()
61 {
62     m_listview = new VariableListView(m_lineedit->text(), m_popup.get());
63     addKateItems(m_listview);
64     connect(m_listview, &VariableListView::aboutToHide, this, &VariableLineEdit::updateVariableLine);
65 
66     m_popup->layout()->addWidget(m_listview);
67 
68     if (layoutDirection() == Qt::LeftToRight) {
69         QPoint topLeft = mapToGlobal(m_lineedit->geometry().bottomLeft());
70         const int w = m_button->geometry().right() - m_lineedit->geometry().left();
71         const int h = 300; //(w * 2) / 4;
72         m_popup->setGeometry(QRect(topLeft, QSize(w, h)));
73     } else {
74         QPoint topLeft = mapToGlobal(m_button->geometry().bottomLeft());
75         const int w = m_lineedit->geometry().right() - m_button->geometry().left();
76         const int h = 300; //(w * 2) / 4;
77         m_popup->setGeometry(QRect(topLeft, QSize(w, h)));
78     }
79     m_popup->show();
80 }
81 
updateVariableLine()82 void VariableLineEdit::updateVariableLine()
83 {
84     Q_ASSERT(m_listview);
85 
86     QString variables = m_listview->variableLine();
87     m_lineedit->setText(variables);
88 
89     m_popup->layout()->removeWidget(m_listview);
90     m_listview->deleteLater();
91     m_listview = nullptr;
92 }
93 
addKateItems(VariableListView * listview)94 void VariableLineEdit::addKateItems(VariableListView *listview)
95 {
96     VariableItem *item = nullptr;
97 
98     // If a current active doc is available
99     KTextEditor::ViewPrivate *activeView = nullptr;
100     KTextEditor::DocumentPrivate *activeDoc = nullptr;
101 
102     KateDocumentConfig *docConfig = KateDocumentConfig::global();
103     KateViewConfig *viewConfig = KateViewConfig::global();
104     KateRendererConfig *rendererConfig = KateRendererConfig::global();
105 
106     if ((activeView = qobject_cast<KTextEditor::ViewPrivate *>(KTextEditor::EditorPrivate::self()->application()->activeMainWindow()->activeView()))) {
107         activeDoc = activeView->doc();
108         viewConfig = activeView->config();
109         docConfig = activeDoc->config();
110         rendererConfig = activeView->renderer()->config();
111     }
112 
113     // Add 'auto-brackets' to list
114     item = new VariableBoolItem(QStringLiteral("auto-brackets"), false);
115     item->setHelpText(i18nc("short translation please", "Enable automatic insertion of brackets."));
116     listview->addItem(item);
117 
118     // Add 'auto-center-lines' to list
119     item = new VariableIntItem(QStringLiteral("auto-center-lines"), viewConfig->autoCenterLines());
120     static_cast<VariableIntItem *>(item)->setRange(1, 100);
121     item->setHelpText(i18nc("short translation please", "Set the number of autocenter lines."));
122     listview->addItem(item);
123 
124     // Add 'background-color' to list
125     item = new VariableColorItem(QStringLiteral("background-color"), rendererConfig->backgroundColor());
126     item->setHelpText(i18nc("short translation please", "Set the document background color."));
127     listview->addItem(item);
128 
129     // Add 'backspace-indents' to list
130     item = new VariableBoolItem(QStringLiteral("backspace-indents"), docConfig->backspaceIndents());
131     item->setHelpText(i18nc("short translation please", "Pressing backspace in leading whitespace unindents."));
132     listview->addItem(item);
133 
134     // Add 'block-selection' to list
135     item = new VariableBoolItem(QStringLiteral("block-selection"), false);
136     if (activeView) {
137         static_cast<VariableBoolItem *>(item)->setValue(activeView->blockSelection());
138     }
139     item->setHelpText(i18nc("short translation please", "Enable block selection mode."));
140     listview->addItem(item);
141 
142     // Add 'byte-order-mark' (bom) to list
143     item = new VariableBoolItem(QStringLiteral("byte-order-mark"), docConfig->bom());
144     item->setHelpText(i18nc("short translation please", "Enable the byte order mark (BOM) when saving Unicode files."));
145     listview->addItem(item);
146 
147     // Add 'bracket-highlight-color' to list
148     item = new VariableColorItem(QStringLiteral("bracket-highlight-color"), rendererConfig->highlightedBracketColor());
149     item->setHelpText(i18nc("short translation please", "Set the color for the bracket highlight."));
150     listview->addItem(item);
151 
152     // Add 'current-line-color' to list
153     item = new VariableColorItem(QStringLiteral("current-line-color"), rendererConfig->highlightedLineColor());
154     item->setHelpText(i18nc("short translation please", "Set the background color for the current line."));
155     listview->addItem(item);
156 
157     // Add 'default-dictionary' to list
158     Sonnet::Speller speller;
159     item = new VariableSpellCheckItem(QStringLiteral("default-dictionary"), speller.defaultLanguage());
160     item->setHelpText(i18nc("short translation please", "Set the default dictionary used for spell checking."));
161     listview->addItem(item);
162 
163     // Add 'dynamic-word-wrap' to list
164     item = new VariableBoolItem(QStringLiteral("dynamic-word-wrap"), viewConfig->dynWordWrap());
165     item->setHelpText(i18nc("short translation please", "Enable dynamic word wrap of long lines."));
166     listview->addItem(item);
167 
168     // Add 'end-of-line' (eol) to list
169     item = new VariableStringListItem(QStringLiteral("end-of-line"),
170                                       {QStringLiteral("unix"), QStringLiteral("mac"), QStringLiteral("dos")},
171                                       docConfig->eolString());
172     item->setHelpText(i18nc("short translation please", "Sets the end of line mode."));
173     listview->addItem(item);
174 
175     // Add 'folding-markers' to list
176     item = new VariableBoolItem(QStringLiteral("folding-markers"), viewConfig->foldingBar());
177     item->setHelpText(i18nc("short translation please", "Enable folding markers in the editor border."));
178     listview->addItem(item);
179 
180     // Add 'folding-preview' to list
181     item = new VariableBoolItem(QStringLiteral("folding-preview"), viewConfig->foldingPreview());
182     item->setHelpText(i18nc("short translation please", "Enable folding preview in the editor border."));
183     listview->addItem(item);
184 
185     // Add 'font-size' to list
186     item = new VariableIntItem(QStringLiteral("font-size"), rendererConfig->baseFont().pointSize());
187     static_cast<VariableIntItem *>(item)->setRange(4, 128);
188     item->setHelpText(i18nc("short translation please", "Set the point size of the document font."));
189     listview->addItem(item);
190 
191     // Add 'font' to list
192     item = new VariableFontItem(QStringLiteral("font"), rendererConfig->baseFont());
193     item->setHelpText(i18nc("short translation please", "Set the font of the document."));
194     listview->addItem(item);
195 
196     // Add 'syntax' (hl) to list
197     /* Prepare list of highlighting modes */
198     QStringList hls;
199     hls.reserve(KateHlManager::self()->modeList().size());
200     for (const auto &hl : KateHlManager::self()->modeList()) {
201         hls << hl.name();
202     }
203 
204     item = new VariableStringListItem(QStringLiteral("syntax"), hls, hls.at(0));
205     if (activeDoc) {
206         static_cast<VariableStringListItem *>(item)->setValue(activeDoc->highlightingMode());
207     }
208     item->setHelpText(i18nc("short translation please", "Set the syntax highlighting."));
209     listview->addItem(item);
210 
211     // Add 'icon-bar-color' to list
212     item = new VariableColorItem(QStringLiteral("icon-bar-color"), rendererConfig->iconBarColor());
213     item->setHelpText(i18nc("short translation please", "Set the icon bar color."));
214     listview->addItem(item);
215 
216     // Add 'icon-border' to list
217     item = new VariableBoolItem(QStringLiteral("icon-border"), viewConfig->iconBar());
218     item->setHelpText(i18nc("short translation please", "Enable the icon border in the editor view."));
219     listview->addItem(item);
220 
221     // Add 'indent-mode' to list
222     item = new VariableStringListItem(QStringLiteral("indent-mode"), KateAutoIndent::listIdentifiers(), docConfig->indentationMode());
223     item->setHelpText(i18nc("short translation please", "Set the auto indentation style."));
224     listview->addItem(item);
225 
226     // Add 'indent-pasted-text' to list
227     item = new VariableBoolItem(QStringLiteral("indent-pasted-text"), docConfig->indentPastedText());
228     item->setHelpText(i18nc("short translation please", "Adjust indentation of text pasted from the clipboard."));
229     listview->addItem(item);
230 
231     // Add 'indent-width' to list
232     item = new VariableIntItem(QStringLiteral("indent-width"), docConfig->indentationWidth());
233     static_cast<VariableIntItem *>(item)->setRange(1, 200);
234     item->setHelpText(i18nc("short translation please", "Set the indentation depth for each indent level."));
235     listview->addItem(item);
236 
237     // Add 'keep-extra-spaces' to list
238     item = new VariableBoolItem(QStringLiteral("keep-extra-spaces"), docConfig->keepExtraSpaces());
239     item->setHelpText(i18nc("short translation please", "Allow odd indentation level (no multiple of indent width)."));
240     listview->addItem(item);
241 
242     // Add 'line-numbers' to list
243     item = new VariableBoolItem(QStringLiteral("line-numbers"), viewConfig->lineNumbers());
244     item->setHelpText(i18nc("short translation please", "Show line numbers."));
245     listview->addItem(item);
246 
247     // Add 'newline-at-eof' to list
248     item = new VariableBoolItem(QStringLiteral("newline-at-eof"), docConfig->ovr());
249     item->setHelpText(i18nc("short translation please", "Insert newline at end of file on save."));
250     listview->addItem(item);
251 
252     // Add 'overwrite-mode' to list
253     item = new VariableBoolItem(QStringLiteral("overwrite-mode"), docConfig->ovr());
254     item->setHelpText(i18nc("short translation please", "Enable overwrite mode in the document."));
255     listview->addItem(item);
256 
257     // Add 'persistent-selection' to list
258     item = new VariableBoolItem(QStringLiteral("persistent-selection"), viewConfig->persistentSelection());
259     item->setHelpText(i18nc("short translation please", "Enable persistent text selection."));
260     listview->addItem(item);
261 
262     // Add 'replace-tabs-save' to list
263     item = new VariableBoolItem(QStringLiteral("replace-tabs-save"), false);
264     item->setHelpText(i18nc("short translation please", "Replace tabs with spaces when saving the document."));
265     listview->addItem(item);
266 
267     // Add 'replace-tabs' to list
268     item = new VariableBoolItem(QStringLiteral("replace-tabs"), docConfig->replaceTabsDyn());
269     item->setHelpText(i18nc("short translation please", "Replace tabs with spaces."));
270     listview->addItem(item);
271 
272     // Add 'remove-trailing-spaces' to list
273     item = new VariableRemoveSpacesItem(QStringLiteral("remove-trailing-spaces"), docConfig->removeSpaces());
274     item->setHelpText(i18nc("short translation please", "Remove trailing spaces when saving the document."));
275     listview->addItem(item);
276 
277     // Add 'scrollbar-minimap' to list
278     item = new VariableBoolItem(QStringLiteral("scrollbar-minimap"), viewConfig->scrollBarMiniMap());
279     item->setHelpText(i18nc("short translation please", "Show scrollbar minimap."));
280     listview->addItem(item);
281 
282     // Add 'scrollbar-preview' to list
283     item = new VariableBoolItem(QStringLiteral("scrollbar-preview"), viewConfig->scrollBarPreview());
284     item->setHelpText(i18nc("short translation please", "Show scrollbar preview."));
285     listview->addItem(item);
286 
287     // Add 'scheme' to list
288     QStringList themeNames;
289     const auto sortedThemes = KateHlManager::self()->sortedThemes();
290     themeNames.reserve(sortedThemes.size());
291     for (const auto &theme : sortedThemes) {
292         themeNames.append(theme.name());
293     }
294     item = new VariableStringListItem(QStringLiteral("scheme"), themeNames, rendererConfig->schema());
295     item->setHelpText(i18nc("short translation please", "Set the color scheme."));
296     listview->addItem(item);
297 
298     // Add 'selection-color' to list
299     item = new VariableColorItem(QStringLiteral("selection-color"), rendererConfig->selectionColor());
300     item->setHelpText(i18nc("short translation please", "Set the text selection color."));
301     listview->addItem(item);
302 
303     // Add 'show-tabs' to list
304     item = new VariableBoolItem(QStringLiteral("show-tabs"), docConfig->showTabs());
305     item->setHelpText(i18nc("short translation please", "Visualize tabs and trailing spaces."));
306     listview->addItem(item);
307 
308     // Add 'smart-home' to list
309     item = new VariableBoolItem(QStringLiteral("smart-home"), docConfig->smartHome());
310     item->setHelpText(i18nc("short translation please", "Enable smart home navigation."));
311     listview->addItem(item);
312 
313     // Add 'tab-indents' to list
314     item = new VariableBoolItem(QStringLiteral("tab-indents"), docConfig->tabIndentsEnabled());
315     item->setHelpText(i18nc("short translation please", "Pressing TAB key indents."));
316     listview->addItem(item);
317 
318     // Add 'tab-width' to list
319     item = new VariableIntItem(QStringLiteral("tab-width"), docConfig->tabWidth());
320     static_cast<VariableIntItem *>(item)->setRange(1, 200);
321     item->setHelpText(i18nc("short translation please", "Set the tab display width."));
322     listview->addItem(item);
323 
324     // Add 'undo-steps' to list
325     item = new VariableIntItem(QStringLiteral("undo-steps"), 0);
326     static_cast<VariableIntItem *>(item)->setRange(0, 100);
327     item->setHelpText(i18nc("short translation please", "Set the number of undo steps to remember (0 equals infinity)."));
328     listview->addItem(item);
329 
330     // Add 'word-wrap-column' to list
331     item = new VariableIntItem(QStringLiteral("word-wrap-column"), docConfig->wordWrapAt());
332     static_cast<VariableIntItem *>(item)->setRange(20, 200);
333     item->setHelpText(i18nc("short translation please", "Set the word wrap column."));
334     listview->addItem(item);
335 
336     // Add 'word-wrap-marker-color' to list
337     item = new VariableColorItem(QStringLiteral("word-wrap-marker-color"), rendererConfig->wordWrapMarkerColor());
338     item->setHelpText(i18nc("short translation please", "Set the word wrap marker color."));
339     listview->addItem(item);
340 
341     // Add 'word-wrap' to list
342     item = new VariableBoolItem(QStringLiteral("word-wrap"), docConfig->wordWrap());
343     item->setHelpText(i18nc("short translation please", "Enable word wrap while typing text."));
344     listview->addItem(item);
345 }
346 
setText(const QString & text)347 void VariableLineEdit::setText(const QString &text)
348 {
349     m_lineedit->setText(text);
350 }
351 
clear()352 void VariableLineEdit::clear()
353 {
354     m_lineedit->clear();
355 }
356 
text()357 QString VariableLineEdit::text()
358 {
359     return m_lineedit->text();
360 }
361