diff options
Diffstat (limited to 'src-qt5')
6 files changed, 137 insertions, 108 deletions
diff --git a/src-qt5/desktop-utils/lumina-textedit/MainUI.cpp b/src-qt5/desktop-utils/lumina-textedit/MainUI.cpp index fe1e689b..bc08e521 100644 --- a/src-qt5/desktop-utils/lumina-textedit/MainUI.cpp +++ b/src-qt5/desktop-utils/lumina-textedit/MainUI.cpp @@ -283,6 +283,7 @@ void MainUI::OpenFile(QString file){ //Default to US English Dictionary hunspellPath = dir+"/hunspell/"; hunspell = new Hunspell(QString(hunspellPath + "en_US.aff").toLocal8Bit(), QString(hunspellPath + "en_US.dic").toLocal8Bit()); + edit->setDictionary(hunspell); } } } diff --git a/src-qt5/desktop-utils/lumina-textedit/PlainTextEditor.cpp b/src-qt5/desktop-utils/lumina-textedit/PlainTextEditor.cpp index 285cd1b9..d1f29974 100644 --- a/src-qt5/desktop-utils/lumina-textedit/PlainTextEditor.cpp +++ b/src-qt5/desktop-utils/lumina-textedit/PlainTextEditor.cpp @@ -291,6 +291,7 @@ void PlainTextEditor::LNW_updateWidth(){ void PlainTextEditor::LNW_highlightLine(){ QList<QTextEdit::ExtraSelection> sels; + foreach(Word *word, wordList) { sels.append(word->sel); }; if(this->isReadOnly()){ return; } QColor highC = QColor(0,0,0,50); //just darken the line a bit @@ -388,19 +389,34 @@ void PlainTextEditor::updateLNW(){ LNW_updateWidth(); } +Word *PlainTextEditor::wordAtPosition(int blockNum, int pos) { + foreach(Word *word, wordList) { + //qDebug() << word->word << "WordBlock:" << word->blockNum << "Block:" << blockNum << "WordPos:" << word->position << "Pos:" << pos; + if(word->blockNum == blockNum and pos >= word->position and pos <= word->position+word->word.length()) + return word; + } + return NULL; +} + void PlainTextEditor::contextMenuEvent(QContextMenuEvent *ev){ QMenu *menu = createStandardContextMenu(); - qDebug() << this->textCursor().blockNumber() << this->textCursor().columnNumber() << this->textCursor().position(); - /*QMenu *menu = new QMenu(); - QString word = ""; - foreach(Word *word, wordList) { + /*qDebug() << this->textCursor().blockNumber() << this->textCursor().positionInBlock(); + Word *word = wordAtPosition(this->textCursor().blockNumber(), this->textCursor().positionInBlock()); + QList<QAction*> suggestionList; + if(word != NULL) { foreach(QString word, word->suggestions) { QAction *suggestionAction = menu->addAction(word); + connect(suggestionAction, &QAction::triggered, this, [=]() { Something }); + suggestionList.append(suggestionAction); } - } - menu->addSeparator(); - QAction *ignoreAll = menu->addAction(tr("Ignore All")); - QAction *addToDictionary = menu->addAction(tr("Add to Dictionary"));*/ + menu->addSeparator(); + QAction *ignore = menu->addAction(tr("Ignore")); + connect(ignore, &QAction::triggered, this, [word]() { word->ignore(); }); + QAction *ignoreAll = menu->addAction(tr("Ignore All")); + connect(ignoreAll, &QAction::triggered, this, [=]() { foreach(Word *wordP, wordList) { if(wordP->word == word->word) { wordP->ignore(); }} }); + QAction *addToDictionary = menu->addAction(tr("Add to Dictionary")); + connect(addToDictionary, &QAction::triggered, this, [word, this]() { hunspell->add(word->word.toStdString()); }); + }*/ menu->exec(ev->globalPos()); delete menu; } @@ -410,7 +426,7 @@ void PlainTextEditor::keyPressEvent(QKeyEvent *ev) { if(ev->matches(QKeySequence::Paste) or ev->matches(QKeySequence::Cut)) { QClipboard *clipboard = QGuiApplication::clipboard(); int epos = this->textCursor().position() + clipboard->text().size(); - qDebug() << this->textCursor().position() << epos; + //qDebug() << this->textCursor().position() << epos; QTimer::singleShot(100, this, [=]() { emit CheckSpelling(this->textCursor().position(), epos); }); } diff --git a/src-qt5/desktop-utils/lumina-textedit/PlainTextEditor.h b/src-qt5/desktop-utils/lumina-textedit/PlainTextEditor.h index 353f4d40..8ca8037d 100644 --- a/src-qt5/desktop-utils/lumina-textedit/PlainTextEditor.h +++ b/src-qt5/desktop-utils/lumina-textedit/PlainTextEditor.h @@ -13,6 +13,8 @@ #include <QPaintEvent> #include <QFileSystemWatcher> +#include <hunspell/hunspell.hxx> + #include "syntaxSupport.h" #include "Word.h" @@ -32,6 +34,7 @@ public: void LoadFile(QString filepath); bool SaveFile(bool newname = false); QString currentFile(); + Word *wordAtPosition(int, int); bool hasChange(); bool readOnlyFile(); @@ -41,6 +44,7 @@ public: void paintLNW(QPaintEvent *ev); //forwarded from the LNW paint event void updateLNW(); void setWordList(QList<Word*> _wordList) { wordList = _wordList; } + void setDictionary(Hunspell *_hunspell) { hunspell = _hunspell; } QFontMetrics *metrics; @@ -53,6 +57,7 @@ private: QList<Word*> wordList; //Syntax Highlighting class Custom_Syntax *SYNTAX; + Hunspell *hunspell; //Bracket/Perentheses matching functions int matchleft, matchright; //positions within the document diff --git a/src-qt5/desktop-utils/lumina-textedit/syntaxSupport.cpp b/src-qt5/desktop-utils/lumina-textedit/syntaxSupport.cpp index a80d4149..6a3acfed 100644 --- a/src-qt5/desktop-utils/lumina-textedit/syntaxSupport.cpp +++ b/src-qt5/desktop-utils/lumina-textedit/syntaxSupport.cpp @@ -46,6 +46,11 @@ bool SyntaxFile::highlight_excess_whitespace(){ return formatObj.value("highlight_whitespace_eol").toBool(); } +bool SyntaxFile::check_spelling(){ + if(!formatObj.contains("check_spelling")){ return false; } + return formatObj.value("check_spelling").toBool(); +} + int SyntaxFile::tab_length(){ int num = -1; if(formatObj.contains("tab_width")){ num = formatObj.value("tab_width").toInt(); } diff --git a/src-qt5/desktop-utils/lumina-textedit/syntaxSupport.h b/src-qt5/desktop-utils/lumina-textedit/syntaxSupport.h index 9949a90c..f7321869 100644 --- a/src-qt5/desktop-utils/lumina-textedit/syntaxSupport.h +++ b/src-qt5/desktop-utils/lumina-textedit/syntaxSupport.h @@ -27,147 +27,148 @@ struct SyntaxRule{ class SyntaxFile{ private: - QJsonObject metaObj; - QJsonObject formatObj; + QJsonObject metaObj; + QJsonObject formatObj; - QColor colorFromOption(QString opt, QSettings *settings); + QColor colorFromOption(QString opt, QSettings *settings); public: - QVector<SyntaxRule> rules; - QDateTime lastLoaded; - QString fileLoaded; + QVector<SyntaxRule> rules; + QDateTime lastLoaded; + QString fileLoaded; - SyntaxFile(){} + SyntaxFile(){} - QString name(); - int char_limit(); - bool highlight_excess_whitespace(); - int tab_length(); + QString name(); + int char_limit(); + bool highlight_excess_whitespace(); + bool check_spelling(); + int tab_length(); - void SetupDocument(QPlainTextEdit *editor); - bool supportsFile(QString file); //does this syntax set support the file? - bool supportsFirstLine(QString line); //is the type of file defined by the first line of the file? ("#!/bin/<something>" for instance) + void SetupDocument(QPlainTextEdit *editor); + bool supportsFile(QString file); //does this syntax set support the file? + bool supportsFirstLine(QString line); //is the type of file defined by the first line of the file? ("#!/bin/<something>" for instance) - //Main Loading routine (run this before other functions) - bool LoadFile(QString file, QSettings *settings); + //Main Loading routine (run this before other functions) + bool LoadFile(QString file, QSettings *settings); - //Main function for finding/loading all syntax files - static QList<SyntaxFile> availableFiles(QSettings *settings); + //Main function for finding/loading all syntax files + static QList<SyntaxFile> availableFiles(QSettings *settings); }; class Custom_Syntax : public QSyntaxHighlighter{ - Q_OBJECT + Q_OBJECT private: - QSettings *settings; + QSettings *settings; SyntaxFile syntax; public: - Custom_Syntax(QSettings *set, QTextDocument *parent = 0) : QSyntaxHighlighter(parent){ - settings = set; - } - ~Custom_Syntax(){} + Custom_Syntax(QSettings *set, QTextDocument *parent = 0) : QSyntaxHighlighter(parent){ + settings = set; + } + ~Custom_Syntax(){} - QString loadedRules(){ return syntax.name(); } + QString loadedRules(){ return syntax.name(); } - static QStringList availableRules(QSettings *settings); - static QStringList knownColors(); - static void SetupDefaultColors(QSettings *settings); - static QString ruleForFile(QString filename, QSettings *settings); - static QString ruleForFirstLine(QString line, QSettings *settings); - void loadRules(QString type); - void loadRules(SyntaxFile sfile); + static QStringList availableRules(QSettings *settings); + static QStringList knownColors(); + static void SetupDefaultColors(QSettings *settings); + static QString ruleForFile(QString filename, QSettings *settings); + static QString ruleForFirstLine(QString line, QSettings *settings); + void loadRules(QString type); + void loadRules(SyntaxFile sfile); - void reloadRules(){ - loadRules( syntax.name() ); - } + void reloadRules(){ + loadRules( syntax.name() ); + } - void setupDocument(QPlainTextEdit *edit){ syntax.SetupDocument(edit); } //simple redirect for the function in the currently-loaded rules + void setupDocument(QPlainTextEdit *edit){ syntax.SetupDocument(edit); } //simple redirect for the function in the currently-loaded rules protected: - void highlightBlock(const QString &text){ + void highlightBlock(const QString &text){ //qDebug() << "Highlight Block:" << text; - //Now look for any multi-line patterns (starting/continuing/ending) - int start = 0; - int splitactive = previousBlockState(); - if(splitactive>syntax.rules.length()-1){ splitactive = -1; } //just in case - - while(start>=0 && start<=text.length()-1){ - //qDebug() << "split check:" << start << splitactive; - if(splitactive>=0){ - //Find the end of the current rule - int end = syntax.rules[splitactive].endPattern.indexIn(text, start); - if(end==-1){ + //Now look for any multi-line patterns (starting/continuing/ending) + int start = 0; + int splitactive = previousBlockState(); + if(splitactive>syntax.rules.length()-1){ splitactive = -1; } //just in case + + while(start>=0 && start<=text.length()-1){ + //qDebug() << "split check:" << start << splitactive; + if(splitactive>=0){ + //Find the end of the current rule + int end = syntax.rules[splitactive].endPattern.indexIn(text, start); + if(end==-1){ //qDebug() << "Highlight to end of line:" << text << start; - //rule did not finish - apply to all + //rule did not finish - apply to all if(start>0){ setFormat(start-1, text.length()-start+1, syntax.rules[splitactive].format); } else{ setFormat(start, text.length()-start, syntax.rules[splitactive].format); } - break; //stop looking for more multi-line patterns - }else{ - //Found end point within the same line + break; //stop looking for more multi-line patterns + }else{ + //Found end point within the same line //qDebug() << "Highlight to particular point:" << text << start << end; - int len = end-start+syntax.rules[splitactive].endPattern.matchedLength(); + int len = end-start+syntax.rules[splitactive].endPattern.matchedLength(); if(start>0){ start--; len++; } //need to include the first character as well - setFormat(start, len , syntax.rules[splitactive].format); - start+=len; //move pointer to the end of handled range - splitactive = -1; //done with this rule - } - } //end check for end match - //Look for the start of any new split rules - //qDebug() << "Loop over multi-line rules"; - for(int i=0; i<syntax.rules.length() && splitactive<0; i++){ - //qDebug() << "Check Rule:" << i << syntax.rules[i].startPattern << syntax.rules[i].endPattern; + setFormat(start, len , syntax.rules[splitactive].format); + start+=len; //move pointer to the end of handled range + splitactive = -1; //done with this rule + } + } //end check for end match + //Look for the start of any new split rules + //qDebug() << "Loop over multi-line rules"; + for(int i=0; i<syntax.rules.length() && splitactive<0; i++){ + //qDebug() << "Check Rule:" << i << syntax.rules[i].startPattern << syntax.rules[i].endPattern; if(syntax.rules[i].startPattern.isEmpty()){ continue; } //qDebug() << "Look for start of split rule:" << syntax.rules[i].startPattern << splitactive; - int newstart = syntax.rules[i].startPattern.indexIn(text,start); - if(newstart>=start){ + int newstart = syntax.rules[i].startPattern.indexIn(text,start); + if(newstart>=start){ //qDebug() << "Got Start of split rule:" << start << newstart << text; - splitactive = i; - start = newstart+1; + splitactive = i; + start = newstart+1; if(start>=text.length()-1){ //qDebug() << "Special case: start now greater than line length"; //Need to apply highlighting to this section too - start matches the end of the line setFormat(start-1, text.length()-start+1, syntax.rules[splitactive].format); } - } - } - if(splitactive<0){ break; } //no other rules found - go ahead and exit the loop + } + } + if(splitactive<0){ break; } //no other rules found - go ahead and exit the loop } //end scan over line length and multi-line formats - setCurrentBlockState(splitactive); + setCurrentBlockState(splitactive); //Do all the single-line patterns - for(int i=0; i<syntax.rules.length(); i++){ + for(int i=0; i<syntax.rules.length(); i++){ if(syntax.rules[i].pattern.isEmpty()){ continue; } //not a single-line rule - QRegExp patt(syntax.rules[i].pattern); //need a copy of the rule's pattern (will be changing it below) - int index = patt.indexIn(text); + QRegExp patt(syntax.rules[i].pattern); //need a copy of the rule's pattern (will be changing it below) + int index = patt.indexIn(text); if(splitactive>=0 || index<start){ continue; } //skip this one - falls within a multi-line pattern above - while(index>=0){ - int len = patt.matchedLength(); - if(format(index)==currentBlock().charFormat()){ setFormat(index, len, syntax.rules[i].format); } //only apply highlighting if not within a section already - index = patt.indexIn(text, index+len); //go to the next match - } - }//end loop over normal (single-line) patterns - - //Now go through and apply any document-wide formatting rules + while(index>=0){ + int len = patt.matchedLength(); + if(format(index)==currentBlock().charFormat()){ setFormat(index, len, syntax.rules[i].format); } //only apply highlighting if not within a section already + index = patt.indexIn(text, index+len); //go to the next match + } + }//end loop over normal (single-line) patterns + + //Now go through and apply any document-wide formatting rules QTextCharFormat fmt; fmt.setBackground( QColor( settings->value("colors/bracket-missing").toString() ) ); int max = syntax.char_limit(); - if(max >= 0 && ( (text.length()+(text.count("\t")*(syntax.tab_length()-1)) )> max) ){ - //Line longer than it should be - highlight the offending characters - //Need to be careful about where tabs show up in the line - int len = 0; - for(int i=0; i<text.length(); i++){ - if(text[i]=='\t'){ len += syntax.tab_length(); } - else{ len++; } - if(len>max){ setFormat(i, text.length()-i, fmt); break; } - } - } - if(syntax.highlight_excess_whitespace()){ - int last = text.length()-1; - while(last>=0 && (text[last]==' ' || text[last]=='\t' ) ){ last--; } - if(last < text.length()-1){ - setFormat(last+1, text.length()-1-last, fmt); - } - } - } + if(max >= 0 && ( (text.length()+(text.count("\t")*(syntax.tab_length()-1)) )> max) ) { + //Line longer than it should be - highlight the offending characters + //Need to be careful about where tabs show up in the line + int len = 0; + for(int i=0; i<text.length() and len<=max; i++){ + len += (text[i]=='\t') ? syntax.tab_length() : 1; + if(len>max) + setFormat(i, text.length()-i, fmt); + } + } + if(syntax.highlight_excess_whitespace()){ + int last = text.length()-1; + while(last>=0 && (text[last]==' ' || text[last]=='\t' ) ){ last--; } + if(last < text.length()-1){ + setFormat(last+1, text.length()-1-last, fmt); + } + } + } }; #endif diff --git a/src-qt5/desktop-utils/lumina-textedit/syntax_rules/cpp.syntax b/src-qt5/desktop-utils/lumina-textedit/syntax_rules/cpp.syntax index ada90b24..acbc3d6f 100644 --- a/src-qt5/desktop-utils/lumina-textedit/syntax_rules/cpp.syntax +++ b/src-qt5/desktop-utils/lumina-textedit/syntax_rules/cpp.syntax @@ -13,6 +13,7 @@ "format": { "line_wrap": false, "highlight_whitespace_eol": true + "check_spelling": false }, "rules": [{ "name": "multi-line comment", |