mirror of https://github.com/vitalif/openscad
Merge pull request #580 from openscad/colorsfix
Colorsfix - 3 options for syntax highlighterexport-menu
commit
bf19347248
|
@ -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();
|
||||
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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>
|
||||
|
@ -164,6 +164,61 @@
|
|||
</item>
|
||||
</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">
|
||||
|
|
|
@ -121,55 +121,72 @@
|
|||
*/
|
||||
|
||||
#include "highlighter.h"
|
||||
#include "Preferences.h"
|
||||
#include <QTextDocument>
|
||||
#include <QTextCursor>
|
||||
#include <QColor>
|
||||
//#include <iostream>
|
||||
//#include "printutils.h"
|
||||
|
||||
Highlighter::Highlighter(QTextDocument *parent)
|
||||
: QSyntaxHighlighter(parent)
|
||||
void format_colors_for_light_background(QMap<QString,QTextCharFormat> &formats)
|
||||
{
|
||||
tokentypes["operator"] << "=" << "!" << "&&" << "||" << "+" << "-" << "*" << "/" << "%" << "!" << "#" << ";";
|
||||
typeformats["operator"].setForeground(Qt::blue);
|
||||
//PRINT("format for light");
|
||||
formats["operator"].setForeground(Qt::blue);
|
||||
formats["math"].setForeground(QColor("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"));
|
||||
|
||||
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");
|
||||
formats["_$quote"].setForeground(Qt::darkMagenta);
|
||||
formats["_$comment"].setForeground(Qt::darkCyan);
|
||||
formats["_$number"].setForeground(QColor("DarkRed"));
|
||||
}
|
||||
|
||||
tokentypes["transform"] << "scale" << "translate" << "rotate" << "multmatrix" << "color" << "projection" << "hull" << "resize" << "mirror" << "minkowski";
|
||||
typeformats["transform"].setForeground(QColor("Indigo"));
|
||||
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"));
|
||||
|
||||
tokentypes["csgop"] << "union" << "intersection" << "difference" << "render";
|
||||
typeformats["csgop"].setForeground(QColor("DarkGreen"));
|
||||
formats["_$quote"].setForeground(Qt::magenta);
|
||||
formats["_$comment"].setForeground(Qt::cyan);
|
||||
formats["_$number"].setForeground(Qt::red);
|
||||
}
|
||||
|
||||
tokentypes["prim3d"] << "cube" << "cylinder" << "sphere" << "polyhedron";
|
||||
typeformats["prim3d"].setForeground(QColor("DarkBlue"));
|
||||
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;
|
||||
|
||||
tokentypes["prim2d"] << "square" << "polygon" << "circle";
|
||||
typeformats["prim2d"].setForeground(QColor("MidnightBlue"));
|
||||
// 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.
|
||||
|
||||
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 ) {
|
||||
|
@ -177,16 +194,37 @@ Highlighter::Highlighter(QTextDocument *parent)
|
|||
QStringList::iterator it;
|
||||
for ( it = tokentypes[toktype].begin(); it < tokentypes[toktype].end(); ++it) {
|
||||
QString token = *it;
|
||||
//std::cout << token.toStdString() << "\n";
|
||||
//PRINTB("set format for %s: type %s", token.toStdString()%toktype.toStdString() );;
|
||||
tokenFormats[ token ] = typeformats [ toktype ];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Highlighter::Highlighter(QTextDocument *parent)
|
||||
: QSyntaxHighlighter(parent)
|
||||
{
|
||||
tokentypes["operator"] << "=" << "!" << "&&" << "||" << "+" << "-" << "*" << "/" << "%" << "!" << "#" << ";";
|
||||
tokentypes["math"] << "abs" << "sign" << "acos" << "asin" << "atan" << "atan2" << "sin" << "cos" << "floor" << "round" << "ceil" << "ln" << "log" << "lookup" << "min" << "max" << "pow" << "sqrt" << "exp" << "rands";
|
||||
tokentypes["keyword"] << "module" << "function" << "for" << "intersection_for" << "if" << "assign" << "echo"<< "search" << "str";
|
||||
tokentypes["transform"] << "scale" << "translate" << "rotate" << "multmatrix" << "color" << "projection" << "hull" << "resize" << "mirror" << "minkowski";
|
||||
tokentypes["csgop"] << "union" << "intersection" << "difference" << "render";
|
||||
tokentypes["prim3d"] << "cube" << "cylinder" << "sphere" << "polyhedron";
|
||||
tokentypes["prim2d"] << "square" << "polygon" << "circle";
|
||||
tokentypes["import"] << "include" << "use" << "import_stl" << "import" << "import_dxf" << "dxf_dim" << "dxf_cross" << "surface";
|
||||
tokentypes["special"] << "$children" << "child" << "children" << "$fn" << "$fa" << "$fs" << "$t" << "$vpt" << "$vpr";
|
||||
tokentypes["extrude"] << "linear_extrude" << "rotate_extrude";
|
||||
tokentypes["bracket"] << "[" << "]" << "(" << ")";
|
||||
tokentypes["curlies"] << "{" << "}";
|
||||
tokentypes["bool"] << "true" << "false";
|
||||
|
||||
tokentypes["_$comment"] << "_$comment"; // bit of a kludge here
|
||||
tokentypes["_$quote"] << "_$quote";
|
||||
tokentypes["_$number"] << "_$number";
|
||||
|
||||
QString syntaxhighlight = Preferences::inst()->getValue("editor/syntaxhighlight").toString();
|
||||
this->assignFormatsToTokens(syntaxhighlight);
|
||||
|
||||
quoteFormat.setForeground(Qt::darkMagenta);
|
||||
commentFormat.setForeground(Qt::darkCyan);
|
||||
errorFormat.setBackground(Qt::red);
|
||||
numberFormat.setForeground(QColor("DarkRed"));
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue