KTextEditor

configtab.cpp
1/*
2 SPDX-FileCopyrightText: KDE Developers
3
4 SPDX-License-Identifier: LGPL-2.0-or-later
5*/
6
7#include <QFileDialog>
8#include <QTableWidgetItem>
9#include <QWhatsThis>
10
11#include <KLocalizedString>
12#include <KMessageBox>
13
14#include "ui_configwidget.h"
15#include <utils/kateconfig.h>
16#include <utils/kateglobal.h>
17#include <vimode/config/configtab.h>
18#include <vimode/keyparser.h>
19
20using namespace KateVi;
21
22ConfigTab::ConfigTab(QWidget *parent, Mappings *mappings)
23 : KateConfigPage(parent)
24 , m_mappings(mappings)
25{
26 // This will let us have more separation between this page and
27 // the QTabWidget edge (ereslibre)
28 QVBoxLayout *layout = new QVBoxLayout(this);
29 QWidget *newWidget = new QWidget(this);
30
31 ui = new Ui::ConfigWidget();
32 ui->setupUi(newWidget);
33
34 // Make the header take all the width in equal parts.
35 ui->tblNormalModeMappings->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
36 ui->tblInsertModeMappings->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
37 ui->tblVisualModeMappings->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
38
39 // What's This? help can be found in the ui file
40 reload();
41
42 //
43 // after initial reload, connect the stuff for the changed() signal
44 //
45 connect(ui->chkViCommandsOverride, &QCheckBox::toggled, this, &ConfigTab::slotChanged);
46 connect(ui->chkViRelLineNumbers, &QCheckBox::toggled, this, &ConfigTab::slotChanged);
47 connect(ui->tblNormalModeMappings, &QTableWidget::cellChanged, this, &ConfigTab::slotChanged);
48 connect(ui->btnAddNewRow, &QPushButton::clicked, this, &ConfigTab::addMappingRow);
49 connect(ui->btnAddNewRow, &QPushButton::clicked, this, &ConfigTab::slotChanged);
50 connect(ui->btnRemoveSelectedRows, &QPushButton::clicked, this, &ConfigTab::removeSelectedMappingRows);
51 connect(ui->btnRemoveSelectedRows, &QPushButton::clicked, this, &ConfigTab::slotChanged);
52 connect(ui->btnImportNormal, &QPushButton::clicked, this, &ConfigTab::importNormalMappingRow);
53 connect(ui->btnImportNormal, &QPushButton::clicked, this, &ConfigTab::slotChanged);
54
55 layout->addWidget(newWidget);
56}
57
58ConfigTab::~ConfigTab()
59{
60 delete ui;
61}
62
63void ConfigTab::applyTab(QTableWidget *mappingsTable, Mappings::MappingMode mode)
64{
65 m_mappings->clear(mode);
66
67 for (int i = 0; i < mappingsTable->rowCount(); i++) {
68 QTableWidgetItem *from = mappingsTable->item(i, 0);
69 QTableWidgetItem *to = mappingsTable->item(i, 1);
70 QTableWidgetItem *recursive = mappingsTable->item(i, 2);
71
72 if (from && to && recursive) {
73 const Mappings::MappingRecursion recursion = recursive->checkState() == Qt::Checked ? Mappings::Recursive : Mappings::NonRecursive;
74 m_mappings->add(mode, from->text(), to->text(), recursion);
75 }
76 }
77}
78
79void ConfigTab::reloadTab(QTableWidget *mappingsTable, Mappings::MappingMode mode)
80{
81 const QStringList l = m_mappings->getAll(mode);
82 mappingsTable->setRowCount(l.size());
83
84 int i = 0;
85 for (const QString &f : l) {
86 QTableWidgetItem *from = new QTableWidgetItem(KeyParser::self()->decodeKeySequence(f));
87 QString s = m_mappings->get(mode, f);
88 QTableWidgetItem *to = new QTableWidgetItem(KeyParser::self()->decodeKeySequence(s));
89 QTableWidgetItem *recursive = new QTableWidgetItem();
91 const bool isRecursive = m_mappings->isRecursive(mode, f);
92 recursive->setCheckState(isRecursive ? Qt::Checked : Qt::Unchecked);
93
94 mappingsTable->setItem(i, 0, from);
95 mappingsTable->setItem(i, 1, to);
96 mappingsTable->setItem(i, 2, recursive);
97
98 i++;
99 }
100}
101
102void ConfigTab::apply()
103{
104 // nothing changed, no need to apply stuff
105 if (!hasChanged()) {
106 return;
107 }
108 m_changed = false;
109
110 KateViewConfig::global()->configStart();
111
112 // General options.
113 KateViewConfig::global()->setValue(KateViewConfig::ViRelativeLineNumbers, ui->chkViRelLineNumbers->isChecked());
114 KateViewConfig::global()->setValue(KateViewConfig::ViInputModeStealKeys, ui->chkViCommandsOverride->isChecked());
115
116 // Mappings.
117 applyTab(ui->tblNormalModeMappings, Mappings::NormalModeMapping);
118 applyTab(ui->tblInsertModeMappings, Mappings::InsertModeMapping);
119 applyTab(ui->tblVisualModeMappings, Mappings::VisualModeMapping);
120
121 KateViewConfig::global()->configEnd();
122}
123
124void ConfigTab::reload()
125{
126 // General options.
127 ui->chkViRelLineNumbers->setChecked(KateViewConfig::global()->viRelativeLineNumbers());
128 ui->chkViCommandsOverride->setChecked(KateViewConfig::global()->viInputModeStealKeys());
129
130 // Mappings.
131 reloadTab(ui->tblNormalModeMappings, Mappings::NormalModeMapping);
132 reloadTab(ui->tblInsertModeMappings, Mappings::InsertModeMapping);
133 reloadTab(ui->tblVisualModeMappings, Mappings::VisualModeMapping);
134}
135
136void ConfigTab::reset()
137{
138 /* Do nothing. */
139}
140
141void ConfigTab::defaults()
142{
143 /* Do nothing. */
144}
145
146void ConfigTab::showWhatsThis(const QString &text)
147{
149}
150
151void ConfigTab::addMappingRow()
152{
153 // Pick the current widget.
154 QTableWidget *mappingsTable = ui->tblNormalModeMappings;
155 if (ui->tabMappingModes->currentIndex() == 1) {
156 mappingsTable = ui->tblInsertModeMappings;
157 } else if (ui->tabMappingModes->currentIndex() == 2) {
158 mappingsTable = ui->tblVisualModeMappings;
159 }
160
161 // And add a new row.
162 int rows = mappingsTable->rowCount();
163 mappingsTable->insertRow(rows);
164 QTableWidgetItem *recursive = new QTableWidgetItem();
166 recursive->setCheckState(Qt::Unchecked);
167 mappingsTable->setItem(rows, 2, recursive);
168 mappingsTable->setCurrentCell(rows, 0);
169 mappingsTable->editItem(mappingsTable->currentItem());
170}
171
172void ConfigTab::removeSelectedMappingRows()
173{
174 // Pick the current widget.
175 QTableWidget *mappingsTable = ui->tblNormalModeMappings;
176 if (ui->tabMappingModes->currentIndex() == 1) {
177 mappingsTable = ui->tblInsertModeMappings;
178 } else if (ui->tabMappingModes->currentIndex() == 2) {
179 mappingsTable = ui->tblVisualModeMappings;
180 }
181
182 // And remove the selected rows.
183 const QList<QTableWidgetSelectionRange> l = mappingsTable->selectedRanges();
184 for (const QTableWidgetSelectionRange &range : l) {
185 for (int i = 0; i < range.bottomRow() - range.topRow() + 1; i++) {
186 mappingsTable->removeRow(range.topRow());
187 }
188 }
189}
190
191void ConfigTab::importNormalMappingRow()
192{
193 const QString &fileName = QFileDialog::getOpenFileName(this);
194
195 if (fileName.isEmpty()) {
196 return;
197 }
198
199 QFile configFile(fileName);
200 if (!configFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
201 KMessageBox::error(this, i18n("Unable to open the config file for reading."), i18n("Unable to open file"));
202 return;
203 }
204
205 QTextStream stream(&configFile);
206 const QRegularExpression mapleader(QStringLiteral("(?:\\w:)?mapleader"));
207 while (!stream.atEnd()) {
208 const QStringList line = stream.readLine().split(QLatin1Char(' '));
209
210 // TODO - allow recursive mappings to be read.
211 if (line.size() > 2
212 && (line[0] == QLatin1String("noremap") || line[0] == QLatin1String("no") || line[0] == QLatin1String("nnoremap")
213 || line[0] == QLatin1String("nn"))) {
214 int rows = ui->tblNormalModeMappings->rowCount();
215 ui->tblNormalModeMappings->insertRow(rows);
216 ui->tblNormalModeMappings->setItem(rows, 0, new QTableWidgetItem(line[1]));
217 ui->tblNormalModeMappings->setItem(rows, 1, new QTableWidgetItem(line[2]));
218 QTableWidgetItem *recursive = new QTableWidgetItem();
220 recursive->setCheckState(Qt::Unchecked);
221 ui->tblNormalModeMappings->setItem(rows, 2, recursive);
222 } else if (line.size() == 4 && line[0] == QLatin1String("let") && line[2] == QLatin1String("=") && mapleader.match(line[1]).hasMatch()) {
223 const QStringView leader = QStringView(line[3]).mid(1, line[3].length() - 2);
224 if (!leader.isEmpty()) {
225 m_mappings->setLeader(leader[0]);
226 }
227 }
228 }
229}
230
231QString ConfigTab::name() const
232{
233 return i18n("Vi Input Mode");
234}
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.
QString i18n(const char *text, const TYPE &arg...)
void error(QWidget *parent, const QString &text, const QString &title, const KGuiItem &buttonOk, Options options=Notify)
const QList< QKeySequence > & reload()
void clicked(bool checked)
void toggled(bool checked)
void addWidget(QWidget *widget, int stretch, Qt::Alignment alignment)
QPoint pos()
QString getOpenFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, Options options)
qsizetype size() const const
bool isEmpty() const const
QStringView mid(qsizetype start, qsizetype length) const const
bool isEmpty() const const
ItemIsEnabled
void cellChanged(int row, int column)
QTableWidgetItem * currentItem() const const
void editItem(QTableWidgetItem *item)
void insertRow(int row)
QTableWidgetItem * item(int row, int column) const const
void removeRow(int row)
QList< QTableWidgetSelectionRange > selectedRanges() const const
void setCurrentCell(int row, int column)
void setItem(int row, int column, QTableWidgetItem *item)
void setRowCount(int rows)
Qt::CheckState checkState() const const
void setCheckState(Qt::CheckState state)
void setFlags(Qt::ItemFlags flags)
QString text() const const
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
void showText(const QPoint &pos, const QString &text, QWidget *w)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:15:44 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.