← 输入框|github.com|刷新
Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions src/ExtendedScintilla.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,17 @@ ExtendedScintilla::ExtendedScintilla(QWidget* parent) :
QShortcut* shortcutPrint = new QShortcut(QKeySequence(tr("Ctrl+P")), this, nullptr, nullptr, Qt::WidgetShortcut);
connect(shortcutPrint, &QShortcut::activated, this, &ExtendedScintilla::openPrintDialog);

// QScintilla only binds Ctrl++ and Ctrl+- to zoom. On keyboards where the plus sign needs the Shift key (Ctrl+Shift+= on
// a US layout, Ctrl+Shift+; on a Japanese one) the Shift modifier is sent too, so that binding never matches and there
// was no way to zoom in. Add the usual alternatives as well as a way back to the normal size. Ctrl+0 would be the
// obvious key for the latter but it is already used by the main window to reset the window layout.
QShortcut* shortcutZoomInShift = new QShortcut(QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_Plus), this, nullptr, nullptr, Qt::WidgetShortcut);
connect(shortcutZoomInShift, &QShortcut::activated, this, [this]() { zoomIn(); });
QShortcut* shortcutZoomInEqual = new QShortcut(QKeySequence(Qt::CTRL | Qt::Key_Equal), this, nullptr, nullptr, Qt::WidgetShortcut);
connect(shortcutZoomInEqual, &QShortcut::activated, this, [this]() { zoomIn(); });
QShortcut* shortcutZoomReset = new QShortcut(QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_0), this, nullptr, nullptr, Qt::WidgetShortcut);
connect(shortcutZoomReset, &QShortcut::activated, this, [this]() { zoomTo(0); });

// Prepare for adding the find/replace option to the QScintilla context menu
setContextMenuPolicy(Qt::CustomContextMenu);
connect(this, &ExtendedScintilla::customContextMenuRequested, this, &ExtendedScintilla::showContextMenu);
Expand Down
2 changes: 2 additions & 0 deletions src/PreferencesDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ void PreferencesDialog::loadSettings()
ui->checkErrorIndicators->setChecked(Settings::getValue("editor", "error_indicators").toBool());
ui->checkHorizontalTiling->setChecked(Settings::getValue("editor", "horizontal_tiling").toBool());
ui->checkCloseButtonOnTabs->setChecked(Settings::getValue("editor", "close_button_on_tabs").toBool());
ui->checkToggleCommentOnMarginClick->setChecked(Settings::getValue("editor", "toggle_comment_on_margin_click").toBool());

ui->listExtensions->addItems(Settings::getValue("extensions", "list").toStringList());
for (int i=0;i<ui->listBuiltinExtensions->count();++i)
Expand Down Expand Up @@ -244,6 +245,7 @@ void PreferencesDialog::saveSettings(bool accept)
Settings::setValue("editor", "error_indicators", ui->checkErrorIndicators->isChecked());
Settings::setValue("editor", "horizontal_tiling", ui->checkHorizontalTiling->isChecked());
Settings::setValue("editor", "close_button_on_tabs", ui->checkCloseButtonOnTabs->isChecked());
Settings::setValue("editor", "toggle_comment_on_margin_click", ui->checkToggleCommentOnMarginClick->isChecked());

QStringList extList;
for(int i=0;i<ui->listExtensions->count();++i)
Expand Down
21 changes: 21 additions & 0 deletions src/PreferencesDialog.ui
Original file line number Diff line number Diff line change
Expand Up @@ -1880,6 +1880,26 @@ Can be set to 0 for disabling completion.</string>
</property>
</widget>
</item>
<item row="11" column="0">
<widget class="QLabel" name="labelToggleCommentOnMarginClick">
<property name="text">
<string>Toggle comment on line number click</string>
</property>
<property name="buddy">
<cstring>checkToggleCommentOnMarginClick</cstring>
</property>
</widget>
</item>
<item row="11" column="1">
<widget class="QCheckBox" name="checkToggleCommentOnMarginClick">
<property name="toolTip">
<string>If enabled, clicking a line number in the SQL editors comments or uncomments that line instead of selecting it. The Un/comment block command and its keyboard shortcut can always be used.</string>
</property>
<property name="text">
<string>enabled</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
Expand Down Expand Up @@ -2086,6 +2106,7 @@ Can be set to 0 for disabling completion.</string>
<tabstop>checkErrorIndicators</tabstop>
<tabstop>checkHorizontalTiling</tabstop>
<tabstop>checkCloseButtonOnTabs</tabstop>
<tabstop>checkToggleCommentOnMarginClick</tabstop>
<tabstop>listExtensions</tabstop>
<tabstop>buttonAddExtension</tabstop>
<tabstop>buttonRemoveExtension</tabstop>
Expand Down
4 changes: 4 additions & 0 deletions src/Settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,10 @@ QVariant Settings::getDefaultValue(const std::string& group, const std::string&
if(group == "editor" && name == "horizontal_tiling")
return false;

// editor/toggle_comment_on_margin_click?
if(group == "editor" && name == "toggle_comment_on_margin_click")
return false;

// editor/splitter1_sizes?
if(group == "editor" && name == "splitter1_sizes")
return QVariant();
Expand Down
3 changes: 3 additions & 0 deletions src/docktextedit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ DockTextEdit::DockTextEdit(QWidget* parent) :
if(xmlLexer == nullptr)
xmlLexer = new QsciLexerXML(this);

// The content of a cell is not SQL code, so don't comment lines by clicking on their number
commentOnMarginClickApplies = false;

// Set plain text as default
setLanguage(PlainText);

Expand Down
38 changes: 34 additions & 4 deletions src/sqltextedit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
SqlUiLexer* SqlTextEdit::sqlLexer = nullptr;

SqlTextEdit::SqlTextEdit(QWidget* parent) :
ExtendedScintilla(parent)
ExtendedScintilla(parent),
commentOnMarginClickApplies(true)
{
// Create lexer object if not done yet
if(sqlLexer == nullptr)
Expand Down Expand Up @@ -53,6 +54,12 @@ SqlTextEdit::SqlTextEdit(QWidget* parent) :
QShortcut* shortcutToggleComment = new QShortcut(QKeySequence(tr("Ctrl+/")), this, nullptr, nullptr, Qt::WidgetShortcut);
connect(shortcutToggleComment, &QShortcut::activated, this, &SqlTextEdit::toggleBlockComment);

// Margin 0 is the one with the line numbers. It only emits this signal when it is sensitive to clicks, see updateMarginSensitivity.
connect(this, &SqlTextEdit::marginClicked, this, [this](int margin, int line, Qt::KeyboardModifiers) {
if(margin == 0)
toggleLineComments(line, line);
});

// Do rest of initialisation
reloadSettings();
}
Expand All @@ -71,6 +78,7 @@ void SqlTextEdit::reloadSettings()
}
// Set wrap lines
setWrapMode(static_cast<QsciScintilla::WrapMode>(Settings::getValue("editor", "wrap_lines").toInt()));
updateMarginSensitivity();

ExtendedScintilla::reloadSettings();

Expand Down Expand Up @@ -100,6 +108,18 @@ void SqlTextEdit::reloadSettings()
setupSyntaxHighlightingFormat(sqlLexer, "identifier", QsciLexerSQL::QuotedIdentifier);
}

void SqlTextEdit::setReadOnly(bool ro)
{
ExtendedScintilla::setReadOnly(ro);
updateMarginSensitivity();
}

void SqlTextEdit::updateMarginSensitivity()
{
// A click on a line number selects that line. When asked for, comment or uncomment the line instead. A sensitive margin
// takes over all the clicks on it, so only do this if there is something to comment. It is off by default.
setMarginSensitivity(0, commentOnMarginClickApplies && !isReadOnly() && Settings::getValue("editor", "toggle_comment_on_margin_click").toBool());
}

void SqlTextEdit::toggleBlockComment()
{
Expand All @@ -121,13 +141,23 @@ void SqlTextEdit::toggleBlockComment()

getSelection(&lineFrom, &indexFrom, &lineTo, &indexTo);

bool uncomment = text(lineFrom).contains(QRegularExpression("^[ \t]*--"));

// If the selection ends before the first character of a line, don't
// take this line into account for un/commenting.
if (indexTo==0)
lineTo--;

toggleLineComments(lineFrom, lineTo);
}

void SqlTextEdit::toggleLineComments(int lineFrom, int lineTo)
{
lineFrom = qMax(lineFrom, 0);
lineTo = qMin(lineTo, lines() - 1);
if (lineFrom > lineTo)
return;

bool uncomment = text(lineFrom).contains(QRegularExpression("^[ \t]*--"));

beginUndoAction();

// Iterate over the selected lines, get line text, make
Expand All @@ -141,7 +171,7 @@ void SqlTextEdit::toggleBlockComment()
else
lineText.replace(QRegularExpression("^"), "-- ");

indexTo = text(line).length();
int indexTo = text(line).length();
if (lineText.endsWith("\r\n"))
indexTo--;

Expand Down
12 changes: 12 additions & 0 deletions src/sqltextedit.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,22 @@ class SqlTextEdit : public ExtendedScintilla

static SqlUiLexer* sqlLexer;

// Override parent setReadOnly
void setReadOnly(bool ro) override;

public slots:
void reloadSettings();
void toggleBlockComment();
// Comment or uncomment the lines from lineFrom to lineTo (both included) as a single undo action.
// The first of them decides whether all of them get commented or uncommented.
void toggleLineComments(int lineFrom, int lineTo);

protected:
// Whether the setting to comment a line by clicking its number applies to this editor. Subclasses which don't hold SQL code turn it off.
bool commentOnMarginClickApplies;

private:
void updateMarginSensitivity();
};

#endif
60 changes: 60 additions & 0 deletions src/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -123,3 +123,63 @@ set(TESTCACHE_HDR
add_executable(test-cache ${TESTCACHE_HDR} ${TESTCACHE_SRC})
target_link_libraries(test-cache ${QT_MAJOR}::Test)
add_test(NAME test-cache COMMAND $<TARGET_FILE:test-cache>)

# test sql editor

set(TESTSQLEDITOR_SRC
TestSqlEditor.cpp
SqlEditorTestSupport.cpp
../sqltextedit.cpp
../docktextedit.cpp
../ExtendedScintilla.cpp
../FindReplaceDialog.cpp
../SqlUiLexer.cpp
../Settings.cpp
../sql/sqlitetypes.cpp
../sql/ObjectIdentifier.cpp
../sql/Query.cpp
../sql/parser/ParserDriver.cpp
../sql/parser/sqlite3_lexer.cpp
../sql/parser/sqlite3_parser.cpp
)

set(TESTSQLEDITOR_HDR
TestSqlEditor.h
../sqltextedit.h
../docktextedit.h
../ExtendedScintilla.h
../FindReplaceDialog.h
../SqlUiLexer.h
../Settings.h
../sql/sqlitetypes.h
../sql/Query.h
../sql/ObjectIdentifier.h
../sql/parser/ParserDriver.h
../sql/parser/sqlite3_lexer.h
../sql/parser/sqlite3_location.h
../sql/parser/sqlite3_parser.hpp
)

add_executable(test-sql-editor ${TESTSQLEDITOR_HDR} ${TESTSQLEDITOR_SRC} ../FindReplaceDialog.ui)
if(QT_MAJOR STREQUAL "Qt6")
set_target_properties(test-sql-editor PROPERTIES AUTOUIC_OPTIONS "--connections=string")
endif()
target_link_libraries(test-sql-editor ${QT_MAJOR}::Test ${QT_MAJOR}::Widgets ${QT_MAJOR}::PrintSupport QScintilla::QScintilla ${LIBSQLITE_NAME} ${QT5_COMPAT})
add_test(NAME test-sql-editor COMMAND $<TARGET_FILE:test-sql-editor>)
if(WIN32)
set(_se_extra_paths "")
foreach(_p IN LISTS CMAKE_PREFIX_PATH)
list(APPEND _se_extra_paths "${_p}" "${_p}/bin")
# OpenSSL 3 Universal installer layout: bin/x86, bin/x64
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
list(APPEND _se_extra_paths "${_p}/bin/x64")
else()
list(APPEND _se_extra_paths "${_p}/bin/x86")
endif()
endforeach()
# SQLite and SQLCipher are built as DLLs in the CMake prefix by the Windows CI jobs.
string(REPLACE ";" "\\;" TESTSQLEDITOR_PATH "${_se_extra_paths};$ENV{PATH}")
set_tests_properties(test-sql-editor PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen;PATH=${TESTSQLEDITOR_PATH}")
else()
set_tests_properties(test-sql-editor PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen")
endif()
12 changes: 12 additions & 0 deletions src/tests/SqlEditorTestSupport.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#include "../sqlitedb.h"

namespace sqlb
{

// The same wrapper sqlitedb.cpp provides. It is repeated here so the editor tests do not have to link the whole database code.
QString escapeIdentifier(const QString& id)
{
return QString::fromStdString(escapeIdentifier(id.toStdString()));
}

}
Loading
Loading