Skip to content

Commit 9a70af7

Browse files
committed
Evaluation mode in the Edit Database Cell editor
Entered expressions are evaluated using SQLite and the result is saved in the cell. The SQL Evaluation mode reuses the class used for the "Execute SQL" editor so syntax highlighting and call-tips are supported. See issue #2387
1 parent 9b387d2 commit 9a70af7

File tree

7 files changed

+60
-17
lines changed

7 files changed

+60
-17
lines changed

src/EditDialog.cpp

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
#include "EditDialog.h"
22
#include "ui_EditDialog.h"
3-
#include "sqlitedb.h"
43
#include "Settings.h"
54
#include "qhexedit.h"
65
#include "docktextedit.h"
@@ -163,6 +162,7 @@ void EditDialog::loadData(const QByteArray& bArrdata)
163162
case TextEditor:
164163
case JsonEditor:
165164
case XmlEditor:
165+
case SqlEvaluator:
166166

167167
// The JSON widget buffer is now the main data source
168168
dataSource = SciBuffer;
@@ -216,6 +216,7 @@ void EditDialog::loadData(const QByteArray& bArrdata)
216216
case TextEditor:
217217
case JsonEditor:
218218
case XmlEditor:
219+
case SqlEvaluator:
219220
setDataInBuffer(bArrdata, SciBuffer);
220221
break;
221222
case RtlTextEditor:
@@ -247,8 +248,9 @@ void EditDialog::loadData(const QByteArray& bArrdata)
247248
// Update the display if in text edit or image viewer mode
248249
switch (editMode) {
249250
case TextEditor:
250-
case XmlEditor:
251251
case JsonEditor:
252+
case XmlEditor:
253+
case SqlEvaluator:
252254
// Disable text editing, and use a warning message as the contents
253255
sciEdit->setText(tr("Image data can't be viewed in this mode.") % '\n' %
254256
tr("Try switching to Image or Binary mode."));
@@ -279,7 +281,7 @@ void EditDialog::loadData(const QByteArray& bArrdata)
279281
case TextEditor:
280282
case JsonEditor:
281283
case XmlEditor:
282-
284+
case SqlEvaluator:
283285
setDataInBuffer(bArrdata, SciBuffer);
284286
break;
285287

@@ -316,6 +318,7 @@ void EditDialog::loadData(const QByteArray& bArrdata)
316318
case TextEditor:
317319
case JsonEditor:
318320
case XmlEditor:
321+
case SqlEvaluator:
319322
// Disable text editing, and use a warning message as the contents
320323
sciEdit->setText(QString(tr("Binary data can't be viewed in this mode.") % '\n' %
321324
tr("Try switching to Binary mode.")));
@@ -367,6 +370,7 @@ void EditDialog::importData(bool asLink)
367370
switch (mode) {
368371
case TextEditor:
369372
case RtlTextEditor:
373+
case SqlEvaluator:
370374
selectedFilter = FILE_FILTER_TXT;
371375
break;
372376
case HexEditor:
@@ -620,6 +624,9 @@ void EditDialog::accept()
620624
emit recordTextUpdated(m_currentIndex, newData.toUtf8(), false);
621625
}
622626
break;
627+
case DockTextEdit::SQL:
628+
emit evaluateText(m_currentIndex, sciEdit->text().toStdString());
629+
break;
623630
}
624631
break;
625632
case HexBuffer:
@@ -632,7 +639,6 @@ void EditDialog::accept()
632639
}
633640

634641
if (!newTextData.isEmpty()) {
635-
636642
QString oldData = m_currentIndex.data(Qt::EditRole).toString();
637643
// Check first for null case, otherwise empty strings cannot overwrite NULL values
638644
if ((m_currentIndex.data(Qt::EditRole).isNull() && dataType != Null) || oldData != newTextData)
@@ -675,6 +681,7 @@ void EditDialog::setDataInBuffer(const QByteArray& bArrdata, DataSources source)
675681
case SciBuffer:
676682
switch (sciEdit->language()) {
677683
case DockTextEdit::PlainText:
684+
case DockTextEdit::SQL:
678685
{
679686
// Load the text into the text editor, remove BOM first if there is one
680687
QByteArray dataWithoutBom = bArrdata;
@@ -756,6 +763,10 @@ void EditDialog::editModeChanged(int newMode)
756763
ui->actionIndent->setEnabled(newMode == JsonEditor || newMode == XmlEditor);
757764
setStackCurrentIndex(newMode);
758765

766+
// Change focus from the mode combo to the editor to start typing.
767+
if (ui->comboMode->hasFocus())
768+
setFocus();
769+
759770
// * If the dataSource is the text buffer, the data is always text *
760771
switch (dataSource) {
761772
case QtBuffer:
@@ -767,7 +778,7 @@ void EditDialog::editModeChanged(int newMode)
767778
case TextEditor: // Switching to one of the Scintilla editor modes
768779
case JsonEditor:
769780
case XmlEditor:
770-
781+
case SqlEvaluator:
771782
setDataInBuffer(ui->qtEdit->toPlainText().toUtf8(), SciBuffer);
772783
break;
773784

@@ -820,9 +831,10 @@ void EditDialog::editModeChanged(int newMode)
820831
}
821832
break;
822833

823-
case TextEditor: // Switching to the text editor
824-
case JsonEditor: // Switching to the JSON editor
825-
case XmlEditor: // Switching to the XML editor
834+
case TextEditor:
835+
case JsonEditor:
836+
case XmlEditor:
837+
case SqlEvaluator:
826838
// The text is already in the Sci buffer but we need to perform the necessary formatting.
827839
setDataInBuffer(sciEdit->text().toUtf8(), SciBuffer);
828840

@@ -1117,6 +1129,11 @@ void EditDialog::setStackCurrentIndex(int editMode)
11171129
ui->editorStack->setCurrentIndex(TextEditor);
11181130
sciEdit->setLanguage(DockTextEdit::XML);
11191131
break;
1132+
case SqlEvaluator:
1133+
// Scintilla case: switch to the single Scintilla editor and set language
1134+
ui->editorStack->setCurrentIndex(TextEditor);
1135+
sciEdit->setLanguage(DockTextEdit::SQL);
1136+
break;
11201137
}
11211138
}
11221139

src/EditDialog.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ private slots:
5151

5252
signals:
5353
void recordTextUpdated(const QPersistentModelIndex& idx, const QByteArray& bArrdata, bool isBlob);
54+
void evaluateText(const QPersistentModelIndex& idx, const std::string& text);
5455
void requestUrlOrFileOpen(const QString& urlString);
5556

5657
private:
@@ -84,7 +85,7 @@ private slots:
8485
};
8586

8687
// Edit modes and editor stack (this must be aligned with the UI).
87-
// Note that text modes (plain, JSON and XML) share the Scintilla widget,
88+
// Note that text modes (plain, JSON, XML and SQL evaluator) share the Scintilla widget,
8889
// Consequently the editor stack range is TextEditor..ImageViewer.
8990
enum EditModes {
9091
// Modes with their own widget in the stack:
@@ -94,7 +95,8 @@ private slots:
9495
ImageEditor = 3,
9596
// Modes in the Scintilla editor:
9697
JsonEditor = 4,
97-
XmlEditor = 5
98+
XmlEditor = 5,
99+
SqlEvaluator = 6
98100
};
99101

100102
int checkDataType(const QByteArray& bArrdata) const;

src/EditDialog.ui

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,11 @@
8888
<string>XML</string>
8989
</property>
9090
</item>
91+
<item>
92+
<property name="text">
93+
<string>Evaluation</string>
94+
</property>
95+
</item>
9196
</widget>
9297
</item>
9398
<item>
@@ -153,7 +158,9 @@
153158
<property name="whatsThis">
154159
<string>The text editor modes let you edit plain text, as well as JSON or XML data with syntax highlighting, automatic formatting and validation before saving.
155160

156-
Errors are indicated with a red squiggle underline.</string>
161+
Errors are indicated with a red squiggle underline.
162+
163+
In the Evaluation mode, entered SQLite expressions are evaluated and the result applied to the cell.</string>
157164
</property>
158165
</widget>
159166
<widget class="QWidget" name="rtlVerticalLayout">

src/MainWindow.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,7 @@ void MainWindow::init()
428428

429429
// Connect some more signals and slots
430430
connect(editDock, &EditDialog::recordTextUpdated, this, &MainWindow::updateRecordText);
431+
connect(editDock, &EditDialog::evaluateText, this, &MainWindow::evaluateText);
431432
connect(editDock, &EditDialog::requestUrlOrFileOpen, this, &MainWindow::openUrlOrFile);
432433
connect(ui->dbTreeWidget->selectionModel(), &QItemSelectionModel::currentChanged, this, &MainWindow::changeTreeSelection);
433434
connect(ui->dockEdit, &QDockWidget::visibilityChanged, this, &MainWindow::toggleEditDock);
@@ -986,6 +987,12 @@ void MainWindow::updateRecordText(const QPersistentModelIndex& idx, const QByteA
986987
m_currentTabTableModel->setTypedData(idx, isBlob, text);
987988
}
988989

990+
void MainWindow::evaluateText(const QPersistentModelIndex& idx, const std::string& text)
991+
{
992+
QByteArray value = db.querySingleValueFromDb("SELECT " + text, /* log */ true, DBBrowserDB::Wait);
993+
m_currentTabTableModel->setTypedData(idx, !isTextOnly(value), value);
994+
}
995+
989996
void MainWindow::toggleEditDock(bool visible)
990997
{
991998
if (!visible) {

src/MainWindow.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ private slots:
175175
void helpWhatsThis();
176176
void helpAbout();
177177
void updateRecordText(const QPersistentModelIndex& idx, const QByteArray& text, bool isBlob);
178+
void evaluateText(const QPersistentModelIndex& idx, const std::string& text);
178179
void toggleEditDock(bool visible);
179180
void dataTableSelectionChanged(const QModelIndex& index);
180181
void doubleClickTable(const QModelIndex& index);

src/docktextedit.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "docktextedit.h"
22
#include "Settings.h"
3+
#include "SqlUiLexer.h"
34

45
#include <Qsci/qscistyle.h>
56
#include <Qsci/qscilexerjson.h>
@@ -9,7 +10,7 @@ QsciLexerJSON* DockTextEdit::jsonLexer = nullptr;
910
QsciLexerXML* DockTextEdit::xmlLexer = nullptr;
1011

1112
DockTextEdit::DockTextEdit(QWidget* parent) :
12-
ExtendedScintilla(parent)
13+
SqlTextEdit(parent)
1314
{
1415
// Create lexer objects if not done yet
1516
if(jsonLexer == nullptr)
@@ -29,7 +30,8 @@ DockTextEdit::DockTextEdit(QWidget* parent) :
2930

3031
void DockTextEdit::reloadSettings()
3132
{
32-
// Set the parent settings for both lexers
33+
// Set the parent settings for all lexers
34+
SqlTextEdit::reloadSettings();
3335
reloadLexerSettings(jsonLexer);
3436
reloadLexerSettings(xmlLexer);
3537

@@ -94,6 +96,10 @@ void DockTextEdit::setLanguage(Language lang)
9496
setLexer(xmlLexer);
9597
setFolding(QsciScintilla::BoxedTreeFoldStyle);
9698
break;
99+
case SQL:
100+
setLexer(sqlLexer);
101+
setFolding(QsciScintilla::BoxedTreeFoldStyle);
102+
break;
97103
}
98104
}
99105

src/docktextedit.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
#ifndef DOCKTEXTEDIT_H
22
#define DOCKTEXTEDIT_H
33

4-
#include "ExtendedScintilla.h"
4+
#include "sqltextedit.h"
55

66
class QsciLexerJSON;
77
class QsciLexerXML;
8+
class SqlUiLexer;
89

910
/**
1011
* @brief The DockTextEdit class
11-
* This class is based on our Extended QScintilla widget
12+
* This class extends our QScintilla SQL Text Edit adding XML, JSON and plain text modes.
1213
*/
13-
class DockTextEdit : public ExtendedScintilla
14+
class DockTextEdit : public SqlTextEdit
1415
{
1516
Q_OBJECT
1617

@@ -22,7 +23,8 @@ class DockTextEdit : public ExtendedScintilla
2223
{
2324
PlainText,
2425
JSON,
25-
XML
26+
XML,
27+
SQL
2628
};
2729

2830
void setLanguage(Language lang);
@@ -40,6 +42,7 @@ public slots:
4042
protected:
4143
static QsciLexerJSON* jsonLexer;
4244
static QsciLexerXML* xmlLexer;
45+
4346
private:
4447
Language m_language;
4548
QFont plainTextFont;

0 commit comments

Comments
 (0)