diff options
Diffstat (limited to 'SQLiteStudio3/guiSQLiteStudio/sqleditor.cpp')
| -rw-r--r-- | SQLiteStudio3/guiSQLiteStudio/sqleditor.cpp | 100 |
1 files changed, 52 insertions, 48 deletions
diff --git a/SQLiteStudio3/guiSQLiteStudio/sqleditor.cpp b/SQLiteStudio3/guiSQLiteStudio/sqleditor.cpp index c3fd257..b3656a6 100644 --- a/SQLiteStudio3/guiSQLiteStudio/sqleditor.cpp +++ b/SQLiteStudio3/guiSQLiteStudio/sqleditor.cpp @@ -20,6 +20,7 @@ #include "dbtree/dbtreeitem.h" #include "dbtree/dbtree.h" #include "dbtree/dbtreemodel.h" +#include "common/lazytrigger.h" #include <QAction> #include <QMenu> #include <QTimer> @@ -66,8 +67,9 @@ void SqlEditor::init() connect(this, SIGNAL(blockCountChanged(int)), this, SLOT(updateLineNumberAreaWidth())); connect(this, SIGNAL(updateRequest(QRect,int)), this, SLOT(updateLineNumberArea(QRect,int))); - connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(highlightCurrentLine())); + connect(this, SIGNAL(textChanged()), this, SLOT(checkContentSize())); connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(cursorMoved())); + connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(highlightCurrentLine())); updateLineNumberAreaWidth(); highlightCurrentLine(); @@ -79,15 +81,14 @@ void SqlEditor::init() connect(completer, SIGNAL(leftPressed()), this, SLOT(completerLeftPressed())); connect(completer, SIGNAL(rightPressed()), this, SLOT(completerRightPressed())); - autoCompleteTimer = new QTimer(this); - autoCompleteTimer->setSingleShot(true); - autoCompleteTimer->setInterval(autoCompleterDelay); - connect(autoCompleteTimer, SIGNAL(timeout()), this, SLOT(checkForAutoCompletion())); + autoCompleteTrigger = new LazyTrigger(autoCompleterDelay, + [this]() -> bool {return autoCompletion && !deletionKeyPressed;}, + this); + connect(autoCompleteTrigger, SIGNAL(triggered()), this, SLOT(checkForAutoCompletion())); + + queryParserTrigger = new LazyTrigger(queryParserDelay, this); + connect(autoCompleteTrigger, SIGNAL(triggered()), this, SLOT(parseContents())); - queryParserTimer = new QTimer(this); - queryParserTimer->setSingleShot(true); - queryParserTimer->setInterval(queryParserDelay); - connect(queryParserTimer, SIGNAL(timeout()), this, SLOT(parseContents())); connect(this, SIGNAL(textChanged()), this, SLOT(scheduleQueryParser())); queryParser = new Parser(Dialect::Sqlite3); @@ -502,17 +503,9 @@ void SqlEditor::completeSelected() insertPlainText(value); } -void SqlEditor::scheduleAutoCompletion() -{ - autoCompleteTimer->stop(); - - if (autoCompletion && !deletionKeyPressed) - autoCompleteTimer->start(); -} - void SqlEditor::checkForAutoCompletion() { - if (!db || !autoCompletion || deletionKeyPressed) + if (!db || !autoCompletion || deletionKeyPressed || !richFeaturesEnabled) return; Lexer lexer(getDialect()); @@ -545,7 +538,7 @@ void SqlEditor::refreshValidObjects() QSet<QString> databases = resolver.getDatabases(); databases << "main"; QStringList objects; - foreach (const QString& dbName, databases) + for (const QString& dbName : databases) { objects = resolver.getAllObjects(dbName); objectsInNamedDb[dbName] << objects; @@ -623,6 +616,9 @@ int SqlEditor::lineNumberAreaWidth() void SqlEditor::highlightParenthesis() { + if (!richFeaturesEnabled) + return; + // Clear extra selections QList<QTextEdit::ExtraSelection> selections = extraSelections(); @@ -703,6 +699,14 @@ void SqlEditor::indentSelected(bool shiftPressed) QTextDocument* doc = document(); QTextBlock startBlock = doc->findBlock(cursor.selectionStart()); QTextBlock endBlock = doc->findBlock(cursor.selectionEnd()); + + if (cursor.selectionEnd() > endBlock.position()) + { + QTextBlock afterEndBlock = endBlock.next(); + if (afterEndBlock.isValid()) + endBlock = afterEndBlock; + } + for (QTextBlock it = startBlock; it != endBlock; it = it.next()) { if (shiftPressed) @@ -834,18 +838,8 @@ void SqlEditor::completerRightPressed() void SqlEditor::parseContents() { - if (document()->characterCount() > SqliteSyntaxHighlighter::MAX_QUERY_LENGTH) - { - if (richFeaturesEnabled) - notifyWarn(tr("Contents of the SQL editor are huge, so errors detecting and existing objects highlighting are temporarily disabled.")); - - richFeaturesEnabled = false; + if (!richFeaturesEnabled) return; - } - else if (!richFeaturesEnabled) - { - richFeaturesEnabled = true; - } // Updating dialect according to current database (if any) Dialect dialect = Dialect::Sqlite3; @@ -880,9 +874,9 @@ void SqlEditor::checkForSyntaxErrors() // Marking invalid tokens, like in "SELECT * from test] t" - the "]" token is invalid. // Such tokens don't cause parser to fail. - foreach (SqliteQueryPtr query, queryParser->getQueries()) + for (SqliteQueryPtr query : queryParser->getQueries()) { - foreach (TokenPtr token, query->tokens) + for (TokenPtr token : query->tokens) { if (token->type == Token::INVALID) markErrorAt(token->start, token->end, true); @@ -896,7 +890,7 @@ void SqlEditor::checkForSyntaxErrors() } // Setting new markers when errors were detected - foreach (ParserError* error, queryParser->getErrors()) + for (ParserError* error : queryParser->getErrors()) markErrorAt(sqlIndex(error->getFrom()), sqlIndex(error->getTo())); emit errorsChecked(true); @@ -912,10 +906,10 @@ void SqlEditor::checkForValidObjects() Dialect dialect = db->getDialect(); QList<SqliteStatement::FullObject> fullObjects; QString dbName; - foreach (SqliteQueryPtr query, queryParser->getQueries()) + for (SqliteQueryPtr query : queryParser->getQueries()) { fullObjects = query->getContextFullObjects(); - foreach (const SqliteStatement::FullObject& fullObj, fullObjects) + for (const SqliteStatement::FullObject& fullObj : fullObjects) { dbName = fullObj.database ? stripObjName(fullObj.database->value, dialect) : "main"; if (!objectsInNamedDb.contains(dbName)) @@ -945,10 +939,8 @@ void SqlEditor::scheduleQueryParser(bool force) syntaxValidated = false; document()->setModified(false); - queryParserTimer->stop(); - queryParserTimer->start(); - - scheduleAutoCompletion(); + queryParserTrigger->schedule(); + autoCompleteTrigger->schedule(); } int SqlEditor::sqlIndex(int idx) @@ -1053,6 +1045,21 @@ void SqlEditor::cursorMoved() } } +void SqlEditor::checkContentSize() +{ + if (document()->characterCount() > SqliteSyntaxHighlighter::MAX_QUERY_LENGTH) + { + if (richFeaturesEnabled) + notifyWarn(tr("Contents of the SQL editor are huge, so errors detecting and existing objects highlighting are temporarily disabled.")); + + richFeaturesEnabled = false; + } + else if (!richFeaturesEnabled) + { + richFeaturesEnabled = true; + } +} + void SqlEditor::formatSql() { QString sql = hasSelection() ? getSelectedText() : toPlainText(); @@ -1094,17 +1101,14 @@ void SqlEditor::loadFromFile() setFileDialogInitPathByFile(fName); - QFile file(fName); - if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) + QString err; + QString sql = readFileContents(fName, &err); + if (sql.isNull() && !err.isNull()) { - notifyError(tr("Could not open file '%1' for reading: %2").arg(fName).arg(file.errorString())); + notifyError(tr("Could not open file '%1' for reading: %2").arg(fName).arg(err)); return; } - QTextStream stream(&file); - stream.setCodec("UTF-8"); - QString sql = stream.readAll(); - file.close(); setPlainText(sql); loadedFile = fName; @@ -1556,7 +1560,7 @@ void SqlEditor::setShowLineNumbers(bool value) void SqlEditor::checkSyntaxNow() { - queryParserTimer->stop(); + queryParserTrigger->cancel(); parseContents(); } @@ -1617,7 +1621,7 @@ const SqlEditor::DbObject* SqlEditor::getValidObjectForPosition(const QPoint& po const SqlEditor::DbObject* SqlEditor::getValidObjectForPosition(int position, bool movedLeft) { - foreach (const DbObject& obj, validDbObjects) + for (const DbObject& obj : validDbObjects) { if ((!movedLeft && position > obj.from && position-1 <= obj.to) || (movedLeft && position >= obj.from && position <= obj.to)) |
