diff options
author | Don Bright <hugh.m.bright@gmail.com> | 2013-12-29 21:25:35 (GMT) |
---|---|---|
committer | Don Bright <hugh.m.bright@gmail.com> | 2013-12-29 21:25:35 (GMT) |
commit | f0e077269467ea38f54d517f4daea5c014a27df9 (patch) | |
tree | e80a5b791ca876673991bd55db95abac95b313c3 | |
parent | 6938ae2dfde578e3980d077adefb86a4bdbd9df1 (diff) |
enable disabling of syntax highlighter, add highlighter for dark backgrounds
-rw-r--r-- | src/MainWindow.h | 1 | ||||
-rw-r--r-- | src/Preferences.cc | 13 | ||||
-rw-r--r-- | src/Preferences.h | 2 | ||||
-rw-r--r-- | src/Preferences.ui | 59 | ||||
-rw-r--r-- | src/highlighter.cc | 150 | ||||
-rw-r--r-- | src/highlighter.h | 3 | ||||
-rw-r--r-- | src/mainwin.cc | 8 |
7 files changed, 183 insertions, 53 deletions
diff --git a/src/MainWindow.h b/src/MainWindow.h index ac999bf..4948d46 100644 --- a/src/MainWindow.h +++ b/src/MainWindow.h @@ -70,6 +70,7 @@ private slots: void updateTVal(); void setFileName(const QString &filename); void setFont(const QString &family, uint size); + void setSyntaxHighlight(const QString &s); void showProgress(); void openCSGSettingsChanged(); diff --git a/src/Preferences.cc b/src/Preferences.cc index 0f3115e..eed877d 100644 --- a/src/Preferences.cc +++ b/src/Preferences.cc @@ -59,6 +59,7 @@ Preferences::Preferences(QWidget *parent) : QMainWindow(parent) QString found_family(QFontInfo(font).family()); this->defaultmap["editor/fontfamily"] = found_family; this->defaultmap["editor/fontsize"] = 12; + this->defaultmap["editor/syntaxhighlight"] = "For Light Background"; uint savedsize = getValue("editor/fontsize").toUInt(); QFontDatabase db; @@ -86,7 +87,6 @@ Preferences::Preferences(QWidget *parent) : QMainWindow(parent) this->defaultmap["advanced/openCSGLimit"] = RenderSettings::inst()->openCSGTermLimit; this->defaultmap["advanced/forceGoldfeather"] = false; - // Toolbar QActionGroup *group = new QActionGroup(this); group->addAction(prefsAction3DView); @@ -193,6 +193,13 @@ void Preferences::on_fontSize_editTextChanged(const QString &size) emit fontChanged(getValue("editor/fontfamily").toString(), intsize); } +void Preferences::on_syntaxHighlight_currentIndexChanged(const QString &s) +{ + QSettings settings; + settings.setValue("editor/syntaxhighlight", s); + emit syntaxHighlightChanged(s); +} + void unimplemented_msg() { QMessageBox mbox; @@ -330,6 +337,10 @@ void Preferences::updateGUI() this->fontSize->setEditText(fontsize); } + QString shighlight = getValue("editor/syntaxhighlight").toString(); + int shidx = this->syntaxHighlight->findText(shighlight); + if (shidx >= 0) this->syntaxHighlight->setCurrentIndex(shidx); + if (AutoUpdater *updater = AutoUpdater::updater()) { this->updateCheckBox->setChecked(updater->automaticallyChecksForUpdates()); this->snapshotCheckBox->setChecked(updater->enableSnapshots()); diff --git a/src/Preferences.h b/src/Preferences.h index 4656793..1230c8a 100644 --- a/src/Preferences.h +++ b/src/Preferences.h @@ -24,6 +24,7 @@ public slots: void on_colorSchemeChooser_itemSelectionChanged(); void on_fontChooser_activated(const QString &); void on_fontSize_editTextChanged(const QString &); + void on_syntaxHighlight_currentIndexChanged(const QString &); void on_openCSGWarningBox_toggled(bool); void on_enableOpenCSGBox_toggled(bool); void on_cgalCacheSizeEdit_textChanged(const QString &); @@ -38,6 +39,7 @@ signals: void requestRedraw() const; void fontChanged(const QString &family, uint size) const; void openCSGSettingsChanged() const; + void syntaxHighlightChanged(const QString &s); private: Preferences(QWidget *parent = NULL); diff --git a/src/Preferences.ui b/src/Preferences.ui index d67db6a..ea039f2 100644 --- a/src/Preferences.ui +++ b/src/Preferences.ui @@ -27,7 +27,7 @@ <item> <widget class="QStackedWidget" name="stackedWidget"> <property name="currentIndex"> - <number>2</number> + <number>1</number> </property> <widget class="QWidget" name="page3DView"> <layout class="QVBoxLayout" name="verticalLayout_4"> @@ -136,7 +136,7 @@ <widget class="QFontComboBox" name="fontChooser"> <property name="currentFont"> <font> - <family>Monaco</family> + <family>DejaVu Sans</family> <pointsize>12</pointsize> </font> </property> @@ -165,6 +165,61 @@ </layout> </item> <item> + <layout class="QHBoxLayout" name="horizontalLayout_5"> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <widget class="QLabel" name="label_9"> + <property name="font"> + <font> + <weight>75</weight> + <bold>true</bold> + </font> + </property> + <property name="text"> + <string>Color syntax highlighting</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_3"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Maximum</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>30</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QComboBox" name="syntaxHighlight"> + <item> + <property name="text"> + <string>For Light Background</string> + </property> + </item> + <item> + <property name="text"> + <string>For Dark Background</string> + </property> + </item> + <item> + <property name="text"> + <string>Off</string> + </property> + </item> + </widget> + </item> + </layout> + </item> + <item> <spacer name="verticalSpacer_4"> <property name="orientation"> <enum>Qt::Vertical</enum> diff --git a/src/highlighter.cc b/src/highlighter.cc index 1da0e88..0402b4d 100644 --- a/src/highlighter.cc +++ b/src/highlighter.cc @@ -121,72 +121,110 @@ */ #include "highlighter.h" +#include "Preferences.h" #include <QTextDocument> #include <QTextCursor> #include <QColor> -//#include <iostream> +//#include "printutils.h" + +void format_colors_for_light_background(QMap<QString,QTextCharFormat> &formats) +{ + //PRINT("format for light"); + formats["operator"].setForeground(Qt::blue); + formats["math"].setForeground(Qt::green); + formats["keyword"].setForeground(QColor("Green")); + formats["keyword"].setToolTip("Keyword"); + formats["transform"].setForeground(QColor("Indigo")); + formats["csgop"].setForeground(QColor("DarkGreen")); + formats["prim3d"].setForeground(QColor("DarkBlue")); + formats["prim2d"].setForeground(QColor("MidnightBlue")); + formats["import"].setForeground(Qt::darkYellow); + formats["special"].setForeground(Qt::darkGreen); + formats["extrude"].setForeground(Qt::darkGreen); + formats["bracket"].setForeground(QColor("Green")); + formats["curlies"].setForeground(QColor(32,32,20)); + formats["bool"].setForeground(QColor("DarkRed")); + + formats["_$quote"].setForeground(Qt::darkMagenta); + formats["_$comment"].setForeground(Qt::darkCyan); + formats["_$number"].setForeground(QColor("DarkRed")); +} + +void format_colors_for_dark_background(QMap<QString,QTextCharFormat> &formats) +{ + //PRINT("format for dark"); + formats["operator"].setForeground(Qt::blue); + formats["math"].setForeground(Qt::green); + formats["keyword"].setForeground(QColor("LightGreen")); + formats["keyword"].setToolTip("Keyword"); + formats["transform"].setForeground(QColor("Indigo")); + formats["csgop"].setForeground(QColor("LightGreen")); + formats["prim3d"].setForeground(QColor("LightBlue")); + formats["prim2d"].setForeground(QColor("LightBlue")); + formats["import"].setForeground(QColor("LightYellow")); + formats["special"].setForeground(QColor("LightGreen")); + formats["extrude"].setForeground(QColor("LightGreen")); + formats["bracket"].setForeground(QColor("Green")); + formats["curlies"].setForeground(QColor(132,132,120)); + formats["bool"].setForeground(QColor("LightRed")); + + formats["_$quote"].setForeground(Qt::magenta); + formats["_$comment"].setForeground(Qt::cyan); + formats["_$number"].setForeground(Qt::red); +} + +void Highlighter::assignFormatsToTokens(const QString &s) +{ + //PRINTB("assign fmts %s",s.toStdString()); + if (s=="For Light Background") { + format_colors_for_light_background(this->typeformats); + } else if (s=="For Dark Background") { + format_colors_for_dark_background(this->typeformats); + } else return; + + // Put each token into single QHash, and map it to it's appropriate + // qtextchar format (color, bold, etc). For example, '(' is type + // 'bracket' so it should get the 'bracket' format from + // typeformats[] which is, maybe, Green. + + QList<QString>::iterator ki; + QList<QString> toktypes = tokentypes.keys(); + for ( ki=toktypes.begin(); ki!=toktypes.end(); ++ki ) { + QString toktype = *ki; + QStringList::iterator it; + for ( it = tokentypes[toktype].begin(); it < tokentypes[toktype].end(); ++it) { + QString token = *it; + //PRINTB("set format for %s: type %s", token.toStdString()%toktype.toStdString() );; + tokenFormats[ token ] = typeformats [ toktype ]; + } + } +} Highlighter::Highlighter(QTextDocument *parent) : QSyntaxHighlighter(parent) { tokentypes["operator"] << "=" << "!" << "&&" << "||" << "+" << "-" << "*" << "/" << "%" << "!" << "#" << ";"; - typeformats["operator"].setForeground(Qt::blue); - tokentypes["math"] << "abs" << "sign" << "acos" << "asin" << "atan" << "atan2" << "sin" << "cos" << "floor" << "round" << "ceil" << "ln" << "log" << "lookup" << "min" << "max" << "pow" << "sqrt" << "exp" << "rands"; - typeformats["math"].setForeground(Qt::green); - tokentypes["keyword"] << "module" << "function" << "for" << "intersection_for" << "if" << "assign" << "echo"<< "search" << "str"; - typeformats["keyword"].setForeground(QColor("Green")); - typeformats["keyword"].setToolTip("Keyword"); - tokentypes["transform"] << "scale" << "translate" << "rotate" << "multmatrix" << "color" << "projection" << "hull" << "resize" << "mirror" << "minkowski"; - typeformats["transform"].setForeground(QColor("Indigo")); - tokentypes["csgop"] << "union" << "intersection" << "difference" << "render"; - typeformats["csgop"].setForeground(QColor("DarkGreen")); - tokentypes["prim3d"] << "cube" << "cylinder" << "sphere" << "polyhedron"; - typeformats["prim3d"].setForeground(QColor("DarkBlue")); - tokentypes["prim2d"] << "square" << "polygon" << "circle"; - typeformats["prim2d"].setForeground(QColor("MidnightBlue")); - tokentypes["import"] << "include" << "use" << "import_stl" << "import" << "import_dxf" << "dxf_dim" << "dxf_cross" << "surface"; - typeformats["import"].setForeground(Qt::darkYellow); - tokentypes["special"] << "$children" << "child" << "children" << "$fn" << "$fa" << "$fs" << "$t" << "$vpt" << "$vpr"; - typeformats["special"].setForeground(Qt::darkGreen); - tokentypes["extrude"] << "linear_extrude" << "rotate_extrude"; - typeformats["extrude"].setForeground(Qt::darkGreen); - tokentypes["bracket"] << "[" << "]" << "(" << ")"; - typeformats["bracket"].setForeground(QColor("Green")); - tokentypes["curlies"] << "{" << "}"; - typeformats["curlies"].setForeground(QColor(32,32,20)); - tokentypes["bool"] << "true" << "false"; - typeformats["bool"].setForeground(QColor("DarkRed")); - // Put each token into single QHash, mapped to it's format - QList<QString>::iterator ki; - QList<QString> toktypes = tokentypes.keys(); - for ( ki=toktypes.begin(); ki!=toktypes.end(); ++ki ) { - QString toktype = *ki; - QStringList::iterator it; - for ( it = tokentypes[toktype].begin(); it < tokentypes[toktype].end(); ++it) { - QString token = *it; - //std::cout << token.toStdString() << "\n"; - tokenFormats[ token ] = typeformats [ toktype ]; - } - } + tokentypes["_$comment"] << "_$comment"; // bit of a kludge here + tokentypes["_$quote"] << "_$quote"; + tokentypes["_$number"] << "_$number"; - quoteFormat.setForeground(Qt::darkMagenta); - commentFormat.setForeground(Qt::darkCyan); - errorFormat.setBackground(Qt::red); - numberFormat.setForeground(QColor("DarkRed")); + QString syntaxhighlight = Preferences::inst()->getValue("editor/syntaxhighlight").toString(); + this->assignFormatsToTokens(syntaxhighlight); + errorFormat.setBackground(Qt::red); errorState = false; errorPos = -1; lastErrorBlock = parent->begin(); @@ -198,10 +236,10 @@ void Highlighter::highlightError(int error_pos) errorPos = error_pos; QTextBlock err_block = document()->findBlock( errorPos ); - //std::cout << "error pos: " << error_pos << " doc len: " << document()->characterCount() << "\n"; + //PRINTB( "error pos: %i doc len: %i ", error_pos % document()->characterCount() ); while (err_block.text().remove(QRegExp("\\s+")).size()==0) { - //std::cout << "special case - errors at end of file w whitespace\n"; + //PRINT("special case - errors at end of file w whitespace"; err_block = err_block.previous(); errorPos = err_block.position()+err_block.length() - 2; } @@ -211,7 +249,7 @@ void Highlighter::highlightError(int error_pos) int block_last_pos = err_block.position() + err_block.length() - 1; if ( errorPos == block_last_pos ) { - //std::cout << "special case - errors at ends of certain blocks\n"; + //PRINT( "special case - errors at ends of certain blocks"); errorPos--; } err_block = document()->findBlock(errorPos); @@ -254,6 +292,18 @@ void Highlighter::highlightBlock(const QString &text) // << ", err:" << errorPos << "," << errorState // << ", text:'" << text.toStdString() << "'\n"; + // If desired, skip all highlighting .. except for error highlighting. + if (Preferences::inst()->getValue("editor/syntaxhighlight").toString()==QString("Off")) { + if (errorState) + setFormat( errorPos - block_first_pos, 1, errorFormat); + return; + } + + // bit of a kludge (for historical convenience) + QTextCharFormat "eFormat = tokenFormats["_$quote"]; + QTextCharFormat &commentFormat = tokenFormats["_$comment"]; + QTextCharFormat &numberFormat = tokenFormats["_$number"]; + // Split the block into chunks (tokens), based on whitespace, // and then highlight each token as appropriate QString newtext = text; @@ -265,7 +315,7 @@ void Highlighter::highlightBlock(const QString &text) for ( sh = splitHelpers.begin(); sh!=splitHelpers.end(); ++sh ) { newtext = newtext.replace( *sh, " " + *sh + " "); } - //std::cout << "\nnewtext: " << newtext.toStdString() << "\n"; + //PRINTB("\nnewtext: %s", newtext.toStdString() ); QStringList tokens = newtext.split(QRegExp("\\s")); int tokindex = 0; // tokindex helps w duplicate tokens in a single block bool numtest; @@ -273,14 +323,16 @@ void Highlighter::highlightBlock(const QString &text) if ( tokenFormats.contains( *token ) ) { tokindex = text.indexOf( *token, tokindex ); setFormat( tokindex, token->size(), tokenFormats[ *token ]); - //std::cout << "found tok '" << (*token).toStdString() << "' at " << tokindex << "\n"; + std::string tokprint = (*token).toStdString(); + //PRINTB("found tok '%s' at %i", tokprint % tokindex ); tokindex += token->size(); } else { (*token).toDouble( &numtest ); if ( numtest ) { tokindex = text.indexOf( *token, tokindex ); setFormat( tokindex, token->size(), numberFormat ); - //std::cout << "found num '" << (*token).toStdString() << "' at " << tokindex << "\n"; + std::string tokprint = (*token).toStdString(); + //PRINTB("found num '%s' at %i", tokprint % tokindex ); tokindex += token->size(); } } diff --git a/src/highlighter.h b/src/highlighter.h index b4ffae8..10f9b0a 100644 --- a/src/highlighter.h +++ b/src/highlighter.h @@ -10,11 +10,12 @@ class Highlighter : public QSyntaxHighlighter public: enum state_e {NORMAL=-1,QUOTE,COMMENT}; QHash<QString, QTextCharFormat> tokenFormats; - QTextCharFormat errorFormat, commentFormat, quoteFormat, numberFormat; + QTextCharFormat errorFormat; Highlighter(QTextDocument *parent); void highlightBlock(const QString &text); void highlightError(int error_pos); void unhighlightLastError(); + void assignFormatsToTokens(const QString &); private: QTextBlock lastErrorBlock; int errorPos; diff --git a/src/mainwin.cc b/src/mainwin.cc index 1ad8bc8..c2a7b7e 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -369,6 +369,8 @@ MainWindow::MainWindow(const QString &filename) this, SLOT(setFont(const QString&,uint))); connect(Preferences::inst(), SIGNAL(openCSGSettingsChanged()), this, SLOT(openCSGSettingsChanged())); + connect(Preferences::inst(), SIGNAL(syntaxHighlightChanged(const QString&)), + this, SLOT(setSyntaxHighlight(const QString&))); Preferences::inst()->apply(); // make sure it looks nice.. @@ -1899,6 +1901,12 @@ void MainWindow::setFont(const QString &family, uint size) editor->setFont(font); } +void MainWindow::setSyntaxHighlight(const QString &s) +{ + this->highlighter->assignFormatsToTokens( s ); + this->highlighter->rehighlight(); // slow on large files +} + void MainWindow::quit() { QCloseEvent ev; |