mirror of
https://github.com/sqlitebrowser/sqlitebrowser.git
synced 2026-01-29 15:29:50 -06:00
Drop the QTextEdit widget in the Edit Database Cell dock
Use the QScintilla widget for all the text modes of the Edit Database Cell dock. All the features are believed to be preserved. - The plain text mode is materialised removing the lexer. - Null values are indicated now in the margin instead of using a placeholder. The same pattern is also used for the Image and BLOB data cases when the editor is switched to a text mode. In the dark mode, the line number margin matches now the style-sheet and instead of the configurable editor colours. - Read-only state in the editor is hinted by the caret not blinking, but the text is still selectable by keyboard or mouse. Features and fixes added by using this widget: - Find/Replace dialog for the plain text editor. See issue #1746 - The QScintilla widget does not strip CR characters. See issue #1793 - Line numbers and visible caret line in the text mode.
This commit is contained in:
@@ -20,12 +20,13 @@
|
||||
#include <QPrintPreviewDialog>
|
||||
#include <QPainter>
|
||||
#include <QClipboard>
|
||||
#include <QTextDocument>
|
||||
|
||||
EditDialog::EditDialog(QWidget* parent)
|
||||
: QDialog(parent),
|
||||
ui(new Ui::EditDialog),
|
||||
currentIndex(QModelIndex()),
|
||||
dataSource(TextBuffer),
|
||||
dataSource(SciBuffer),
|
||||
dataType(Null),
|
||||
isReadOnly(true)
|
||||
{
|
||||
@@ -47,9 +48,7 @@ EditDialog::EditDialog(QWidget* parent)
|
||||
QShortcut* ins = new QShortcut(QKeySequence(Qt::Key_Insert), this);
|
||||
connect(ins, SIGNAL(activated()), this, SLOT(toggleOverwriteMode()));
|
||||
|
||||
connect(ui->editorText, SIGNAL(textChanged()), this, SLOT(updateApplyButton()));
|
||||
connect(hexEdit, SIGNAL(dataChanged()), this, SLOT(updateApplyButton()));
|
||||
|
||||
connect(sciEdit, SIGNAL(textChanged()), this, SLOT(updateApplyButton()));
|
||||
connect(sciEdit, SIGNAL(textChanged()), this, SLOT(editTextChanged()));
|
||||
|
||||
@@ -124,19 +123,10 @@ void EditDialog::loadData(const QByteArray& data)
|
||||
// Data type specific handling
|
||||
switch (dataType) {
|
||||
case Null:
|
||||
// Set enabled any of the text widgets
|
||||
ui->editorText->setEnabled(true);
|
||||
// Set enabled the text widget
|
||||
sciEdit->setEnabled(true);
|
||||
switch (editMode) {
|
||||
case TextEditor:
|
||||
// The text widget buffer is now the main data source
|
||||
dataSource = TextBuffer;
|
||||
|
||||
// Empty the text editor contents, then enable text editing
|
||||
ui->editorText->clear();
|
||||
|
||||
break;
|
||||
|
||||
case JsonEditor:
|
||||
case XmlEditor:
|
||||
|
||||
@@ -178,8 +168,6 @@ void EditDialog::loadData(const QByteArray& data)
|
||||
|
||||
switch (editMode) {
|
||||
case TextEditor:
|
||||
setDataInBuffer(data, TextBuffer);
|
||||
break;
|
||||
case JsonEditor:
|
||||
case XmlEditor:
|
||||
setDataInBuffer(data, SciBuffer);
|
||||
@@ -194,7 +182,7 @@ void EditDialog::loadData(const QByteArray& data)
|
||||
ui->editorImage->setPixmap(QPixmap(0,0));
|
||||
|
||||
// Load the text into the text editor
|
||||
setDataInBuffer(data, TextBuffer);
|
||||
setDataInBuffer(data, SciBuffer);
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -210,19 +198,12 @@ void EditDialog::loadData(const QByteArray& data)
|
||||
// Update the display if in text edit or image viewer mode
|
||||
switch (editMode) {
|
||||
case TextEditor:
|
||||
// Disable text editing, and use a warning message as the contents
|
||||
ui->editorText->setText(QString("<i>" %
|
||||
tr("Image data can't be viewed in this mode.") % "<br/>" %
|
||||
tr("Try switching to Image or Binary mode.") %
|
||||
"</i>"));
|
||||
ui->editorText->setEnabled(false);
|
||||
break;
|
||||
|
||||
case XmlEditor:
|
||||
case JsonEditor:
|
||||
// Disable text editing, and use a warning message as the contents
|
||||
sciEdit->setText(tr("Image data can't be viewed in this mode.") % '\n' %
|
||||
tr("Try switching to Image or Binary mode."));
|
||||
sciEdit->setTextInMargin(tr("Image"));
|
||||
sciEdit->setEnabled(false);
|
||||
|
||||
break;
|
||||
@@ -239,9 +220,6 @@ void EditDialog::loadData(const QByteArray& data)
|
||||
// Set the XML data in any buffer or update image in image viewer mode
|
||||
switch (editMode) {
|
||||
case TextEditor:
|
||||
setDataInBuffer(data, TextBuffer);
|
||||
break;
|
||||
|
||||
case JsonEditor:
|
||||
case XmlEditor:
|
||||
|
||||
@@ -276,20 +254,13 @@ void EditDialog::loadData(const QByteArray& data)
|
||||
|
||||
switch (editMode) {
|
||||
case TextEditor:
|
||||
case JsonEditor:
|
||||
case XmlEditor:
|
||||
// Disable text editing, and use a warning message as the contents
|
||||
ui->editorText->setText(QString("<i>" %
|
||||
tr("Binary data can't be viewed in this mode.") % "<br/>" %
|
||||
tr("Try switching to Binary mode.") %
|
||||
"</i>"));
|
||||
ui->editorText->setEnabled(false);
|
||||
break;
|
||||
|
||||
case JsonEditor:
|
||||
case XmlEditor:
|
||||
// Disable text editing, and use a warning message as the contents
|
||||
sciEdit->setText(QString(tr("Binary data can't be viewed in this mode.") % '\n' %
|
||||
tr("Try switching to Binary mode.")));
|
||||
sciEdit->setEnabled(false);
|
||||
sciEdit->setText(QString(tr("Binary data can't be viewed in this mode.") % '\n' %
|
||||
tr("Try switching to Binary mode.")));
|
||||
sciEdit->setTextInMargin(Settings::getValue("databrowser", "blob_text").toString());
|
||||
sciEdit->setEnabled(false);
|
||||
break;
|
||||
|
||||
case ImageViewer:
|
||||
@@ -429,10 +400,6 @@ void EditDialog::exportData()
|
||||
else
|
||||
file.write(hexEdit->data());
|
||||
break;
|
||||
case TextBuffer:
|
||||
// Data source is the text buffer
|
||||
file.write(ui->editorText->toPlainText().toUtf8());
|
||||
break;
|
||||
case SciBuffer:
|
||||
// Data source is the Scintilla buffer
|
||||
file.write(sciEdit->text().toUtf8());
|
||||
@@ -445,7 +412,6 @@ void EditDialog::exportData()
|
||||
|
||||
void EditDialog::setNull()
|
||||
{
|
||||
ui->editorText->clear();
|
||||
ui->editorImage->clear();
|
||||
hexEdit->setData(QByteArray());
|
||||
sciEdit->clear();
|
||||
@@ -456,8 +422,7 @@ void EditDialog::setNull()
|
||||
// and a NULL, so we need to record NULL outside of that
|
||||
dataType = Null;
|
||||
|
||||
// Ensure the text (plain and Scintilla) editors are enabled
|
||||
ui->editorText->setEnabled(true);
|
||||
// Ensure the text (Scintilla) editor is enabled
|
||||
sciEdit->setEnabled(true);
|
||||
|
||||
// Update the cell data info in the bottom left of the Edit Cell
|
||||
@@ -465,7 +430,7 @@ void EditDialog::setNull()
|
||||
// the better visual clue of containing a NULL value (placeholder).
|
||||
updateCellInfoAndMode(hexEdit->data());
|
||||
|
||||
ui->editorText->setFocus();
|
||||
sciEdit->setFocus();
|
||||
}
|
||||
|
||||
void EditDialog::updateApplyButton()
|
||||
@@ -495,18 +460,18 @@ void EditDialog::accept()
|
||||
}
|
||||
|
||||
switch (dataSource) {
|
||||
case TextBuffer:
|
||||
{
|
||||
QString oldData = currentIndex.data(Qt::EditRole).toString();
|
||||
QString newData = removedBom + ui->editorText->toPlainText();
|
||||
// Check first for null case, otherwise empty strings cannot overwrite NULL values
|
||||
if ((currentIndex.data(Qt::EditRole).isNull() && dataType != Null) || oldData != newData)
|
||||
// The data is different, so commit it back to the database
|
||||
emit recordTextUpdated(currentIndex, removedBom + newData.toUtf8(), false);
|
||||
break;
|
||||
}
|
||||
case SciBuffer:
|
||||
switch (sciEdit->language()) {
|
||||
case DockTextEdit::PlainText:
|
||||
{
|
||||
QString oldData = currentIndex.data(Qt::EditRole).toString();
|
||||
QString newData = removedBom + sciEdit->text();
|
||||
// Check first for null case, otherwise empty strings cannot overwrite NULL values
|
||||
if ((currentIndex.data(Qt::EditRole).isNull() && dataType != Null) || oldData != newData)
|
||||
// The data is different, so commit it back to the database
|
||||
emit recordTextUpdated(currentIndex, removedBom + newData.toUtf8(), false);
|
||||
break;
|
||||
}
|
||||
case DockTextEdit::JSON:
|
||||
{
|
||||
QString oldData = currentIndex.data(Qt::EditRole).toString();
|
||||
@@ -588,22 +553,23 @@ void EditDialog::setDataInBuffer(const QByteArray& data, DataSources source)
|
||||
// 2) Set the text in the corresponding editor widget (the text widget for the Image case).
|
||||
// 3) Enable the widget.
|
||||
switch (dataSource) {
|
||||
case TextBuffer:
|
||||
{
|
||||
// Load the text into the text editor, remove BOM first if there is one
|
||||
QByteArray dataWithoutBom = data;
|
||||
removedBom = removeBom(dataWithoutBom);
|
||||
|
||||
textData = QString::fromUtf8(dataWithoutBom.constData(), dataWithoutBom.size());
|
||||
ui->editorText->setPlainText(textData);
|
||||
|
||||
// Select all of the text by default (this is useful for simple text data that we usually edit as a whole)
|
||||
ui->editorText->selectAll();
|
||||
ui->editorText->setEnabled(true);
|
||||
break;
|
||||
}
|
||||
case SciBuffer:
|
||||
switch (sciEdit->language()) {
|
||||
case DockTextEdit::PlainText:
|
||||
{
|
||||
// Load the text into the text editor, remove BOM first if there is one
|
||||
QByteArray dataWithoutBom = data;
|
||||
removedBom = removeBom(dataWithoutBom);
|
||||
|
||||
textData = QString::fromUtf8(dataWithoutBom.constData(), dataWithoutBom.size());
|
||||
sciEdit->setText(textData);
|
||||
|
||||
// Select all of the text by default (this is useful for simple text data that we usually edit as a whole)
|
||||
if (!isReadOnly)
|
||||
sciEdit->selectAll();
|
||||
sciEdit->setEnabled(true);
|
||||
break;
|
||||
}
|
||||
case DockTextEdit::JSON:
|
||||
{
|
||||
QJsonParseError parseError;
|
||||
@@ -670,30 +636,6 @@ void EditDialog::editModeChanged(int newMode)
|
||||
|
||||
// * If the dataSource is the text buffer, the data is always text *
|
||||
switch (dataSource) {
|
||||
case TextBuffer:
|
||||
switch (newMode) {
|
||||
case TextEditor: // Switching to the text editor
|
||||
// Nothing to do, as the text is already in the text buffer
|
||||
break;
|
||||
|
||||
case JsonEditor: // Switching to one of the Scintilla editor modes
|
||||
case XmlEditor:
|
||||
|
||||
setDataInBuffer(ui->editorText->toPlainText().toUtf8(), SciBuffer);
|
||||
break;
|
||||
|
||||
case HexEditor: // Switching to the hex editor
|
||||
// Convert the text widget buffer for the hex widget
|
||||
// The hex widget buffer is now the main data source
|
||||
setDataInBuffer(removedBom + ui->editorText->toPlainText().toUtf8(), HexBuffer);
|
||||
break;
|
||||
|
||||
case ImageViewer:
|
||||
// Clear any image from the image viewing widget
|
||||
ui->editorImage->setPixmap(QPixmap(0,0));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case HexBuffer:
|
||||
|
||||
// * If the dataSource is the hex buffer, the contents could be anything
|
||||
@@ -706,11 +648,6 @@ void EditDialog::editModeChanged(int newMode)
|
||||
break;
|
||||
case SciBuffer:
|
||||
switch (newMode) {
|
||||
case TextEditor: // Switching to the text editor
|
||||
// Convert the text widget buffer for the JSON widget
|
||||
setDataInBuffer(sciEdit->text().toUtf8(), TextBuffer);
|
||||
break;
|
||||
|
||||
case HexEditor: // Switching to the hex editor
|
||||
// Convert the text widget buffer for the hex widget
|
||||
setDataInBuffer(sciEdit->text().toUtf8(), HexBuffer);
|
||||
@@ -732,6 +669,7 @@ void EditDialog::editModeChanged(int newMode)
|
||||
}
|
||||
break;
|
||||
|
||||
case TextEditor: // Switching to the text editor
|
||||
case JsonEditor: // Switching to the JSON editor
|
||||
case XmlEditor: // Switching to the XML editor
|
||||
// The text is already in the Sci buffer but we need to perform the necessary formatting.
|
||||
@@ -745,30 +683,20 @@ void EditDialog::editModeChanged(int newMode)
|
||||
// Called for every keystroke in the text editor (only)
|
||||
void EditDialog::editTextChanged()
|
||||
{
|
||||
if (dataSource == TextBuffer || dataSource == SciBuffer) {
|
||||
if (dataSource == SciBuffer) {
|
||||
|
||||
// Update the cell info in the bottom left manually. This is because
|
||||
// updateCellInfoAndMode() only works with QByteArray's (for now)
|
||||
int dataLength;
|
||||
bool isModified;
|
||||
int dataLength = sciEdit->text().length();
|
||||
bool isModified = sciEdit->isModified();
|
||||
|
||||
if(dataSource == TextBuffer) {
|
||||
// TextBuffer
|
||||
dataLength = ui->editorText->toPlainText().length();
|
||||
isModified = ui->editorText->document()->isModified();
|
||||
} else {
|
||||
// SciBuffer
|
||||
dataLength = sciEdit->text().length();
|
||||
isModified = sciEdit->isModified();
|
||||
}
|
||||
// Data has been changed in the text editor, so it can't be a NULL
|
||||
// If data has been entered in the text editor, it can't be a NULL
|
||||
// any more. It hasn't been validated yet, so it cannot be JSON nor XML.
|
||||
if (dataType == Null && isModified)
|
||||
if (dataType == Null && isModified && dataLength != 0)
|
||||
dataType = Text;
|
||||
|
||||
if (dataType != Null) {
|
||||
ui->editorText->setStyleSheet("");
|
||||
ui->editorText->setPlaceholderText("");
|
||||
sciEdit->clearTextInMargin();
|
||||
ui->labelType->setText(tr("Type of data currently in cell: Text / Numeric"));
|
||||
}
|
||||
ui->labelSize->setText(tr("%n character(s)", "", dataLength));
|
||||
@@ -826,7 +754,6 @@ void EditDialog::toggleOverwriteMode()
|
||||
currentMode = !currentMode;
|
||||
|
||||
hexEdit->setOverwriteMode(currentMode);
|
||||
ui->editorText->setOverwriteMode(currentMode);
|
||||
sciEdit->setOverwriteMode(currentMode);
|
||||
}
|
||||
|
||||
@@ -843,15 +770,13 @@ void EditDialog::setFocus()
|
||||
|
||||
switch (editMode) {
|
||||
case TextEditor:
|
||||
ui->editorText->setFocus();
|
||||
ui->editorText->selectAll();
|
||||
sciEdit->setFocus();
|
||||
if (sciEdit->language() == DockTextEdit::PlainText && !isReadOnly)
|
||||
sciEdit->selectAll();
|
||||
break;
|
||||
case HexEditor:
|
||||
hexEdit->setFocus();
|
||||
break;
|
||||
case SciEditor:
|
||||
sciEdit->setFocus();
|
||||
break;
|
||||
case ImageViewer:
|
||||
// Nothing to do
|
||||
break;
|
||||
@@ -869,15 +794,8 @@ void EditDialog::setReadOnly(bool ro)
|
||||
ui->actionNull->setEnabled(!ro);
|
||||
ui->actionImport->setEnabled(!ro);
|
||||
|
||||
ui->editorText->setReadOnly(ro);
|
||||
sciEdit->setReadOnly(ro);
|
||||
hexEdit->setReadOnly(ro);
|
||||
|
||||
// This makes the caret being visible for selection, although the editor is read-only. The read-only state is hinted by the
|
||||
// caret not blinking. The same should happen for QScintilla, but it always lets the user select text by keyboard (ok) but
|
||||
// the caret is also blinking when in read-only mode (not ok).
|
||||
Qt::TextInteractionFlags textFlags = ro? Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard : Qt::TextEditorInteraction;
|
||||
ui->editorText->setTextInteractionFlags(textFlags);
|
||||
}
|
||||
|
||||
void EditDialog::switchEditorMode(bool autoSwitchForType)
|
||||
@@ -937,14 +855,15 @@ void EditDialog::updateCellInfoAndMode(const QByteArray& data)
|
||||
|
||||
// Use a switch statement for the other data types to keep things neat :)
|
||||
switch (dataType) {
|
||||
case Null:
|
||||
case Null: {
|
||||
// NULL data type
|
||||
ui->labelType->setText(tr("Type of data currently in cell: NULL"));
|
||||
ui->labelSize->setText(tr("%n byte(s)", "", 0));
|
||||
ui->editorText->setStyleSheet("QTextEdit{ font-style: italic; }");
|
||||
ui->editorText->setPlaceholderText(Settings::getValue("databrowser", "null_text").toString());
|
||||
break;
|
||||
|
||||
// Use margin to set the NULL text.
|
||||
sciEdit->setTextInMargin(Settings::getValue("databrowser", "null_text").toString());
|
||||
break;
|
||||
}
|
||||
case XML:
|
||||
case Text: {
|
||||
// Text only
|
||||
@@ -997,13 +916,9 @@ QString EditDialog::humanReadableSize(double byteCount) const
|
||||
|
||||
void EditDialog::reloadSettings()
|
||||
{
|
||||
// Set the databrowser font for the text editor but the (SQL) editor
|
||||
// font for hex editor, since it needs a Monospace font and the
|
||||
// databrowser font would be usually of variable width.
|
||||
QFont textFont(Settings::getValue("databrowser", "font").toString());
|
||||
textFont.setPointSize(Settings::getValue("databrowser", "fontsize").toInt());
|
||||
ui->editorText->setFont(textFont);
|
||||
|
||||
// Set the (SQL) editor font for hex editor, since it needs a
|
||||
// Monospace font and the databrowser font would be usually of
|
||||
// variable width.
|
||||
QFont hexFont(Settings::getValue("editor", "font").toString());
|
||||
hexFont.setPointSize(Settings::getValue("databrowser", "fontsize").toInt());
|
||||
hexEdit->setFont(hexFont);
|
||||
@@ -1018,6 +933,10 @@ void EditDialog::setStackCurrentIndex(int editMode)
|
||||
{
|
||||
switch (editMode) {
|
||||
case TextEditor:
|
||||
// Scintilla case: switch to the single Scintilla editor and set language
|
||||
ui->editorStack->setCurrentIndex(TextEditor);
|
||||
sciEdit->setLanguage(DockTextEdit::PlainText);
|
||||
break;
|
||||
case HexEditor:
|
||||
case ImageViewer:
|
||||
// General case: switch to the selected editor
|
||||
@@ -1025,12 +944,12 @@ void EditDialog::setStackCurrentIndex(int editMode)
|
||||
break;
|
||||
case JsonEditor:
|
||||
// Scintilla case: switch to the single Scintilla editor and set language
|
||||
ui->editorStack->setCurrentIndex(SciEditor);
|
||||
ui->editorStack->setCurrentIndex(TextEditor);
|
||||
sciEdit->setLanguage(DockTextEdit::JSON);
|
||||
break;
|
||||
case XmlEditor:
|
||||
// Scintilla case: switch to the single Scintilla editor and set language
|
||||
ui->editorStack->setCurrentIndex(SciEditor);
|
||||
ui->editorStack->setCurrentIndex(TextEditor);
|
||||
sciEdit->setLanguage(DockTextEdit::XML);
|
||||
break;
|
||||
}
|
||||
@@ -1049,9 +968,6 @@ void EditDialog::openPrintDialog()
|
||||
|
||||
QTextDocument *document = new QTextDocument();
|
||||
switch (dataSource) {
|
||||
case TextBuffer:
|
||||
document->setPlainText(ui->editorText->toPlainText());
|
||||
break;
|
||||
case SciBuffer:
|
||||
// This case isn't really expected because the Scintilla widget has it's own printing slot
|
||||
document->setPlainText(sciEdit->text());
|
||||
|
||||
@@ -62,7 +62,6 @@ private:
|
||||
QByteArray removedBom;
|
||||
|
||||
enum DataSources {
|
||||
TextBuffer,
|
||||
HexBuffer,
|
||||
SciBuffer
|
||||
};
|
||||
@@ -78,13 +77,14 @@ private:
|
||||
XML
|
||||
};
|
||||
|
||||
// Edit modes and editor stack (this must be aligned with the UI)
|
||||
// Note that JSON and XML share the Scintilla widget.
|
||||
// Edit modes and editor stack (this must be aligned with the UI).
|
||||
// Note that text modes (plain, JSON and XML) share the Scintilla widget,
|
||||
// Consequently the editor stack range is TextEditor..ImageViewer.
|
||||
enum EditModes {
|
||||
TextEditor = 0,
|
||||
HexEditor = 1,
|
||||
ImageViewer = 2,
|
||||
JsonEditor, SciEditor = 3,
|
||||
JsonEditor = 3,
|
||||
XmlEditor = 4
|
||||
};
|
||||
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
<property name="windowTitle">
|
||||
<string>Edit database cell</string>
|
||||
</property>
|
||||
<property name="whatsThis">
|
||||
<string>This area displays information about the data present in this database cell</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
@@ -126,24 +129,12 @@
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="verticalLayout_4">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QTextEdit" name="editorText">
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Monospace</family>
|
||||
</font>
|
||||
</property>
|
||||
<property name="whatsThis">
|
||||
<string>This area displays information about the data present in this database cell</string>
|
||||
</property>
|
||||
<property name="acceptRichText">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
<widget class="QWidget" name="editorSci">
|
||||
<property name="whatsThis">
|
||||
<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.
|
||||
|
||||
Errors are indicated with a red squiggle underline.</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QWidget" name="editorBinary">
|
||||
<property name="contextMenuPolicy">
|
||||
@@ -159,8 +150,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>84</width>
|
||||
<height>35</height>
|
||||
<width>598</width>
|
||||
<height>265</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
@@ -177,13 +168,6 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QWidget" name="editorSci">
|
||||
<property name="whatsThis">
|
||||
<string>This editor mode lets you edit JSON or XML data with syntax highlighting, automatic formatting and validation before saving.
|
||||
|
||||
Errors are indicated with a red squiggle underline.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
@@ -379,7 +363,6 @@ Errors are indicated with a red squiggle underline.</string>
|
||||
<tabstops>
|
||||
<tabstop>comboMode</tabstop>
|
||||
<tabstop>buttonAutoSwitchMode</tabstop>
|
||||
<tabstop>editorText</tabstop>
|
||||
<tabstop>buttonApply</tabstop>
|
||||
</tabstops>
|
||||
<resources>
|
||||
@@ -418,22 +401,6 @@ Errors are indicated with a red squiggle underline.</string>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>editorText</sender>
|
||||
<signal>textChanged()</signal>
|
||||
<receiver>EditDialog</receiver>
|
||||
<slot>editTextChanged()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>279</x>
|
||||
<y>191</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>339</x>
|
||||
<y>335</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>actionIndent</sender>
|
||||
<signal>toggled(bool)</signal>
|
||||
|
||||
@@ -124,19 +124,27 @@ void ExtendedScintilla::setupSyntaxHighlightingFormat(QsciLexer *lexer, const QS
|
||||
void ExtendedScintilla::setLexer(QsciLexer *lexer)
|
||||
{
|
||||
QsciScintilla::setLexer(lexer);
|
||||
reloadCommonSettings();
|
||||
}
|
||||
|
||||
// Set margins according to settings. setLexer seems to reset these colours.
|
||||
// Use desktop default colors for margins when following desktop style, or the custom colors otherwise.
|
||||
void ExtendedScintilla::reloadCommonSettings()
|
||||
{
|
||||
// Set margins and default text colours according to settings. setLexer seems to reset these colours.
|
||||
|
||||
// Use desktop default colors for margins when following desktop
|
||||
// style, or the colors matching the dark style-sheet, otherwise.
|
||||
switch (Settings::getValue("General", "appStyle").toInt()) {
|
||||
case Settings::FollowDesktopStyle :
|
||||
setMarginsBackgroundColor(QPalette().color(QPalette::Active, QPalette::Window));
|
||||
setMarginsForegroundColor(QPalette().color(QPalette::Active, QPalette::WindowText));
|
||||
break;
|
||||
case Settings::DarkStyle :
|
||||
setMarginsBackgroundColor(QColor(Settings::getValue("syntaxhighlighter","background_colour").toString()));
|
||||
setMarginsForegroundColor(QColor(Settings::getValue("syntaxhighlighter","foreground_colour").toString()));
|
||||
setMarginsBackgroundColor(QColor("#32414B"));
|
||||
setMarginsForegroundColor(QColor("#EFF0F1"));
|
||||
break;
|
||||
}
|
||||
setPaper(Settings::getValue("syntaxhighlighter", "background_colour").toString());
|
||||
setColor(Settings::getValue("syntaxhighlighter", "foreground_colour").toString());
|
||||
}
|
||||
|
||||
void ExtendedScintilla::reloadKeywords()
|
||||
@@ -285,3 +293,18 @@ void ExtendedScintilla::openPrintDialog()
|
||||
|
||||
delete dialog;
|
||||
}
|
||||
|
||||
void ExtendedScintilla::setReadOnly(bool ro)
|
||||
{
|
||||
QsciScintilla::setReadOnly(ro);
|
||||
// Disable or enable caret blinking so it is obvious whether the text can be modified or not. Otherwise there isn't any other hint.
|
||||
SendScintilla(QsciScintillaBase::SCI_SETCARETPERIOD, ro ? 0 : 500);
|
||||
}
|
||||
|
||||
void ExtendedScintilla::setText(const QString& text)
|
||||
{
|
||||
// Reset scroll width, so the scroll bar is readjusted to the new text.
|
||||
// Otherwise, it grows always bigger.
|
||||
setScrollWidth(80);
|
||||
QsciScintilla::setText(text);
|
||||
}
|
||||
|
||||
@@ -21,6 +21,10 @@ public:
|
||||
void clearSelection();
|
||||
// Override parent setLexer
|
||||
void setLexer(QsciLexer *lexer) override;
|
||||
// Override parent setReadOnly
|
||||
void setReadOnly(bool ro) override;
|
||||
// Override parent setText
|
||||
void setText(const QString& text) override;
|
||||
|
||||
public slots:
|
||||
void reloadKeywords();
|
||||
@@ -37,6 +41,7 @@ protected:
|
||||
|
||||
void setupSyntaxHighlightingFormat(QsciLexer *lexer, const QString& settings_name, int style);
|
||||
void reloadLexerSettings(QsciLexer *lexer);
|
||||
void reloadCommonSettings();
|
||||
|
||||
int errorIndicatorNumber;
|
||||
bool showErrorIndicators;
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#include "docktextedit.h"
|
||||
#include "Settings.h"
|
||||
|
||||
#include <Qsci/qscistyle.h>
|
||||
|
||||
QsciLexerJSON* DockTextEdit::jsonLexer = nullptr;
|
||||
QsciLexerXML* DockTextEdit::xmlLexer = nullptr;
|
||||
|
||||
@@ -13,8 +15,8 @@ DockTextEdit::DockTextEdit(QWidget* parent) :
|
||||
if(xmlLexer == nullptr)
|
||||
xmlLexer = new QsciLexerXML(this);
|
||||
|
||||
// Set the JSON lexer as default
|
||||
setLexer(jsonLexer);
|
||||
// Set plain text as default
|
||||
setLanguage(PlainText);
|
||||
|
||||
jsonLexer->setFoldCompact(false);
|
||||
jsonLexer->setHighlightComments(true);
|
||||
@@ -33,6 +35,11 @@ void DockTextEdit::reloadSettings()
|
||||
reloadLexerSettings(jsonLexer);
|
||||
reloadLexerSettings(xmlLexer);
|
||||
|
||||
// Set the databrowser font for the plain text editor.
|
||||
QFont textFont(Settings::getValue("databrowser", "font").toString());
|
||||
textFont.setPointSize(Settings::getValue("databrowser", "fontsize").toInt());
|
||||
setFont(textFont);
|
||||
|
||||
setupSyntaxHighlightingFormat(jsonLexer, "comment", QsciLexerJSON::CommentLine);
|
||||
setupSyntaxHighlightingFormat(jsonLexer, "comment", QsciLexerJSON::CommentBlock);
|
||||
setupSyntaxHighlightingFormat(jsonLexer, "keyword", QsciLexerJSON::Keyword);
|
||||
@@ -74,11 +81,35 @@ void DockTextEdit::setLanguage(Language lang)
|
||||
{
|
||||
m_language = lang;
|
||||
switch (lang) {
|
||||
case PlainText: {
|
||||
setLexer(nullptr);
|
||||
setFolding(QsciScintilla::NoFoldStyle);
|
||||
break;
|
||||
}
|
||||
case JSON:
|
||||
setLexer(jsonLexer);
|
||||
setFolding(QsciScintilla::BoxedTreeFoldStyle);
|
||||
break;
|
||||
case XML:
|
||||
setLexer(xmlLexer);
|
||||
setFolding(QsciScintilla::BoxedTreeFoldStyle);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void DockTextEdit::setTextInMargin(const QString& text)
|
||||
{
|
||||
clearMarginText();
|
||||
setMarginType(0, QsciScintilla::TextMargin);
|
||||
setMarginText(0, text, QsciStyle(QsciScintillaBase::STYLE_LINENUMBER));
|
||||
setMarginWidth(0, text);
|
||||
reloadCommonSettings();
|
||||
}
|
||||
|
||||
void DockTextEdit::clearTextInMargin()
|
||||
{
|
||||
clearMarginText();
|
||||
setMarginLineNumbers(0, true);
|
||||
reloadCommonSettings();
|
||||
linesChanged();
|
||||
}
|
||||
|
||||
@@ -20,13 +20,20 @@ public:
|
||||
// Enumeration of supported languages
|
||||
enum Language
|
||||
{
|
||||
PlainText,
|
||||
JSON,
|
||||
XML
|
||||
};
|
||||
|
||||
void setLanguage(Language lang);
|
||||
Language language() { return m_language; }
|
||||
|
||||
|
||||
// Disables the line-number margin and sets this text in the first line.
|
||||
void setTextInMargin(const QString& text);
|
||||
|
||||
// Resets margin to their original line-number mode
|
||||
void clearTextInMargin();
|
||||
|
||||
public slots:
|
||||
void reloadSettings();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user