mirror of https://github.com/vitalif/openscad
commit
784b503f0d
|
@ -4,8 +4,7 @@ export QMAKESPEC=unsupported/macx-clang
|
||||||
|
|
||||||
#export OPENCSGDIR=$PWD/../OpenCSG-1.3.0
|
#export OPENCSGDIR=$PWD/../OpenCSG-1.3.0
|
||||||
#export CGALDIR=$PWD/../install/CGAL-3.6
|
#export CGALDIR=$PWD/../install/CGAL-3.6
|
||||||
#export QCODEEDITDIR=$PWD/../qcodeedit-2.2.3/install
|
#export DYLD_LIBRARY_PATH=$OPENCSGDIR/lib
|
||||||
#export DYLD_LIBRARY_PATH=$OPENCSGDIR/lib:$QCODEEDITDIR/lib
|
|
||||||
|
|
||||||
# ccache:
|
# ccache:
|
||||||
export PATH=/opt/local/libexec/ccache:$PATH
|
export PATH=/opt/local/libexec/ccache:$PATH
|
||||||
|
|
|
@ -4,8 +4,7 @@ export QMAKESPEC=macx-g++
|
||||||
|
|
||||||
#export OPENCSGDIR=$PWD/../OpenCSG-1.3.0
|
#export OPENCSGDIR=$PWD/../OpenCSG-1.3.0
|
||||||
#export CGALDIR=$PWD/../install/CGAL-3.6
|
#export CGALDIR=$PWD/../install/CGAL-3.6
|
||||||
#export QCODEEDITDIR=$PWD/../qcodeedit-2.2.3/install
|
#export DYLD_LIBRARY_PATH=$OPENCSGDIR/lib
|
||||||
#export DYLD_LIBRARY_PATH=$OPENCSGDIR/lib:$QCODEEDITDIR/lib
|
|
||||||
|
|
||||||
# Own own Qt
|
# Own own Qt
|
||||||
export PATH=$OPENSCAD_LIBRARIES/bin:$PATH
|
export PATH=$OPENSCAD_LIBRARIES/bin:$PATH
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#include "editor.h"
|
#include "editor.h"
|
||||||
#include "Preferences.h"
|
#include "Preferences.h"
|
||||||
|
|
||||||
#ifndef _QCODE_EDIT_
|
|
||||||
void Editor::indentSelection()
|
void Editor::indentSelection()
|
||||||
{
|
{
|
||||||
QTextCursor cursor = textCursor();
|
QTextCursor cursor = textCursor();
|
||||||
|
@ -109,4 +108,3 @@ void Editor::wheelEvent ( QWheelEvent * event )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
16
src/editor.h
16
src/editor.h
|
@ -3,26 +3,11 @@
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <QWheelEvent>
|
#include <QWheelEvent>
|
||||||
|
|
||||||
#ifdef _QCODE_EDIT_
|
|
||||||
#include <qeditor.h>
|
|
||||||
class Editor : public QEditor
|
|
||||||
#else
|
|
||||||
#include <QTextEdit>
|
#include <QTextEdit>
|
||||||
class Editor : public QTextEdit
|
class Editor : public QTextEdit
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
#ifdef _QCODE_EDIT_
|
|
||||||
Editor(QWidget *parent) : QEditor(parent) {}
|
|
||||||
QString toPlainText() const { return text(); }
|
|
||||||
void setPlainText(const QString& text) { setText(text); }
|
|
||||||
public slots:
|
|
||||||
//void zoomIn() { zoom(1); }
|
|
||||||
void zoomIn(int n = 1) { zoom(n); }
|
|
||||||
//void zoomOut() { zoom(-1); }
|
|
||||||
void zoomOut(int n = 1) { zoom(-n); }
|
|
||||||
#else
|
|
||||||
Editor(QWidget *parent) : QTextEdit(parent) { setAcceptRichText(false); }
|
Editor(QWidget *parent) : QTextEdit(parent) { setAcceptRichText(false); }
|
||||||
public slots:
|
public slots:
|
||||||
void zoomIn();
|
void zoomIn();
|
||||||
|
@ -36,5 +21,4 @@ public slots:
|
||||||
void uncommentSelection();
|
void uncommentSelection();
|
||||||
private:
|
private:
|
||||||
void wheelEvent ( QWheelEvent * event );
|
void wheelEvent ( QWheelEvent * event );
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -24,34 +24,295 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "highlighter.h"
|
/*
|
||||||
#include "parsersettings.h" // extern int parser_error_pos;
|
Syntax Highlighter for OpenSCAD
|
||||||
|
based on Syntax Highlight code by Christopher Olah
|
||||||
|
|
||||||
|
Speed Note:
|
||||||
|
|
||||||
|
setFormat() is very slow. normally this doesnt matter because we
|
||||||
|
only highlight a block or two at once. But when OpenSCAD first starts,
|
||||||
|
QT automatigically calls 'highlightBlock' on every single textblock in the file
|
||||||
|
even if it's not visible in the window. On a large file (50,000 lines) this
|
||||||
|
can take several seconds.
|
||||||
|
|
||||||
|
Also, QT 4.5 and lower do not have rehighlightBlock(), so they will be slow
|
||||||
|
on large files as well, as they re-highlight everything after each compile.
|
||||||
|
|
||||||
|
The vast majority of OpenSCAD files, however, are not 50,000 lines and
|
||||||
|
most machines have Qt > 4.5
|
||||||
|
|
||||||
|
See Also:
|
||||||
|
|
||||||
|
Giles Bathgate's Rapcad lexer-based highlighter: rapcad.org
|
||||||
|
|
||||||
|
Test suite:
|
||||||
|
|
||||||
|
1. action: open example001, remove first {, hit f5
|
||||||
|
expected result: error highlight appears on last }, cursor moves there
|
||||||
|
action: replace first {, hit f5
|
||||||
|
expected result: error highlight disappears
|
||||||
|
|
||||||
|
1a. action: open example001, remove first {, hit f5
|
||||||
|
expected result: error highlight appears on last }, cursor moves there
|
||||||
|
action: replace first { with the letter 'P', hit f5
|
||||||
|
expected result: error highlight on last } disappears, appears on elsewhere
|
||||||
|
action: replace first {, hit f5
|
||||||
|
expected result: error highlight disappears
|
||||||
|
|
||||||
|
2. action: type a=b into any file
|
||||||
|
expected result: '=' is highlighted with its appropriate format
|
||||||
|
|
||||||
|
2a. action: type a=b=c=d=e=f= into any file
|
||||||
|
expected result: each '=' is highlighted with its appropriate format
|
||||||
|
|
||||||
|
3. action: open example001, put '===' after first ; hit f5
|
||||||
|
expected result: error highlight appears in ===
|
||||||
|
action: remove '==='
|
||||||
|
expected result: error highlight disappears
|
||||||
|
|
||||||
|
3a. action: open example001, put '=' after first ; hit f5
|
||||||
|
expected result: error highlight appears
|
||||||
|
action: remove '='
|
||||||
|
expected result: error highlight disappears
|
||||||
|
|
||||||
|
3b. action: open example001, put '=' after first {
|
||||||
|
expected result: error highlight appears
|
||||||
|
action: remove '='
|
||||||
|
expected result: error highlight disappears
|
||||||
|
|
||||||
|
3c. action: open example001, replace first { with '='
|
||||||
|
expected result: error highlight appears
|
||||||
|
action: remove '=', replace with {
|
||||||
|
expected result: error highlight disappears
|
||||||
|
|
||||||
|
4. action: open example001, remove last ';' but not trailing whitespace/\n
|
||||||
|
expected result: error highlight appears somewhere near end
|
||||||
|
action: replace last ';'
|
||||||
|
expected result: error highlight disappears
|
||||||
|
|
||||||
|
5. action: open file, type in a multi-line comment
|
||||||
|
expected result: multiline comment should be highlighted appropriately
|
||||||
|
|
||||||
|
6. action: open example001, remove first ')'
|
||||||
|
expected result: highlight should appear appropriately
|
||||||
|
|
||||||
|
7. action: create a large file (50,000 lines). eg at a bash prompt:
|
||||||
|
for i in {1..2000}; do cat examples/example001.scad >> test5k.scad ; done
|
||||||
|
action: open file in openscad
|
||||||
|
expected result: it should load in a reasonable amount of time
|
||||||
|
action: scroll to bottom, put '=' after last ;
|
||||||
|
expected result: there should be a highlight, and a report of syntax error
|
||||||
|
action: comment out the highlighter code from mainwin.cc, recompile,
|
||||||
|
run openscad again on the large file. put '=' after last ;
|
||||||
|
expected result: there should be only a small difference in speed.
|
||||||
|
|
||||||
|
8. action: open any file, and hold down 'f5' key to repeatedly reparse
|
||||||
|
expected result: no crashing!
|
||||||
|
|
||||||
|
9. action: for i in examples/ex* ; do ./openscad $i ; done
|
||||||
|
expected result: make sure the colors look harmonious
|
||||||
|
|
||||||
|
10. action: type random string of [][][][]()()[][90,3904,00,000]
|
||||||
|
expected result: all should be highlighted correctly
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "highlighter.h"
|
||||||
|
#include <QTextDocument>
|
||||||
|
#include <QTextCursor>
|
||||||
|
#include <QColor>
|
||||||
|
//#include <iostream>
|
||||||
|
|
||||||
#ifdef _QCODE_EDIT_
|
|
||||||
Highlighter::Highlighter(QDocument *parent)
|
|
||||||
#else
|
|
||||||
Highlighter::Highlighter(QTextDocument *parent)
|
Highlighter::Highlighter(QTextDocument *parent)
|
||||||
#endif
|
|
||||||
: QSyntaxHighlighter(parent)
|
: QSyntaxHighlighter(parent)
|
||||||
{
|
{
|
||||||
|
tokentypes["operator"] << "=" << "!" << "&&" << "||" << "+" << "-" << "*" << "/" << "%" << "!" << "#" << ";";
|
||||||
|
typeformats["operator"].setForeground(Qt::blue);
|
||||||
|
|
||||||
|
tokentypes["keyword"] << "module" << "function" << "for" << "intersection_for" << "if" << "assign";
|
||||||
|
typeformats["keyword"].setForeground(QColor("Green"));
|
||||||
|
typeformats["keyword"].setToolTip("Keyword");
|
||||||
|
|
||||||
|
tokentypes["transform"] << "scale" << "translate" << "rotate" << "multmatrix" << "color" << "projection" << "hull";
|
||||||
|
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";
|
||||||
|
typeformats["import"].setForeground(Qt::darkYellow);
|
||||||
|
|
||||||
|
tokentypes["special"] << "$children" << "child" << "$fn" << "$fa" << "$fb";
|
||||||
|
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 tokens 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 ];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
quoteFormat.setForeground(Qt::darkMagenta);
|
||||||
|
commentFormat.setForeground(Qt::darkCyan);
|
||||||
|
errorFormat.setBackground(Qt::red);
|
||||||
|
numberFormat.setForeground(QColor("DarkRed"));
|
||||||
|
|
||||||
|
errorState = false;
|
||||||
|
errorPos = -1;
|
||||||
|
lastErrorBlock = parent->begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Highlighter::highlightError(int error_pos)
|
||||||
|
{
|
||||||
|
errorState = true;
|
||||||
|
errorPos = error_pos;
|
||||||
|
|
||||||
|
QTextBlock err_block = document()->findBlock( errorPos );
|
||||||
|
//std::cout << "error pos: " << error_pos << " doc len: " << document()->characterCount() << "\n";
|
||||||
|
|
||||||
|
while (err_block.text().remove(QRegExp("\\s+")).size()==0) {
|
||||||
|
//std::cout << "special case - errors at end of file w whitespace\n";
|
||||||
|
err_block = err_block.previous();
|
||||||
|
errorPos = err_block.position()+err_block.length() - 2;
|
||||||
|
}
|
||||||
|
if ( errorPos == lastDocumentPos()-1 ) {
|
||||||
|
errorPos--;
|
||||||
|
}
|
||||||
|
|
||||||
|
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";
|
||||||
|
errorPos--;
|
||||||
|
}
|
||||||
|
err_block = document()->findBlock(errorPos);
|
||||||
|
|
||||||
|
portable_rehighlightBlock( err_block );
|
||||||
|
|
||||||
|
errorState = false;
|
||||||
|
lastErrorBlock = err_block;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Highlighter::unhighlightLastError()
|
||||||
|
{
|
||||||
|
portable_rehighlightBlock( lastErrorBlock );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Highlighter::portable_rehighlightBlock( const QTextBlock &block )
|
||||||
|
{
|
||||||
|
#if (QT_VERSION >= QT_VERSION_CHECK(4, 6, 0))
|
||||||
|
rehighlightBlock( block );
|
||||||
|
#else
|
||||||
|
rehighlight(); // slow on very large files
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int Highlighter::lastDocumentPos()
|
||||||
|
{
|
||||||
|
#if (QT_VERSION >= QT_VERSION_CHECK(4, 5, 0))
|
||||||
|
return document()->characterCount();
|
||||||
|
#else
|
||||||
|
QTextBlock lastblock = document()->lastBlock();
|
||||||
|
return lastblock.position() + lastblock.length();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Highlighter::highlightBlock(const QString &text)
|
void Highlighter::highlightBlock(const QString &text)
|
||||||
{
|
{
|
||||||
int n = previousBlockState();
|
int block_first_pos = currentBlock().position();
|
||||||
if (n < 0)
|
//int block_last_pos = block_first_pos + currentBlock().length() - 1;
|
||||||
n = 0;
|
//std::cout << "block[" << block_first_pos << ":" << block_last_pos << "]"
|
||||||
int k = n + text.size() + 1;
|
// << ", err:" << errorPos << "," << errorState
|
||||||
setCurrentBlockState(k);
|
// << ", text:'" << text.toStdString() << "'\n";
|
||||||
if (parser_error_pos >= n && parser_error_pos < k) {
|
|
||||||
QTextCharFormat style;
|
// Split the block into pieces and highlight each as appropriate
|
||||||
style.setBackground(Qt::red);
|
QString newtext = text;
|
||||||
setFormat(0, text.size(), style);
|
QStringList splitHelpers;
|
||||||
#if 0
|
QStringList::iterator sh, token;
|
||||||
style.setBackground(Qt::black);
|
// splitHelpers - so "[a+b]" is treated as "[ a + b ]" and formatted
|
||||||
style.setForeground(Qt::white);
|
splitHelpers << tokentypes["operator"] << "(" << ")" << "[" << "]" << "," << ":";
|
||||||
setFormat(parser_error_pos - n, 1, style);
|
for ( sh = splitHelpers.begin(); sh!=splitHelpers.end(); ++sh ) {
|
||||||
#endif
|
newtext = newtext.replace( *sh, " " + *sh + " ");
|
||||||
}
|
}
|
||||||
|
//std::cout << "\nnewtext: " << newtext.toStdString() << "\n";
|
||||||
|
QStringList tokens = newtext.split(QRegExp("\\s"));
|
||||||
|
int tokindex = 0; // tokindex helps w duplicate tokens in a single block
|
||||||
|
bool numtest;
|
||||||
|
for ( token = tokens.begin(); token!=tokens.end(); ++token ){
|
||||||
|
if ( tokenFormats.contains( *token ) ) {
|
||||||
|
tokindex = text.indexOf( *token, tokindex );
|
||||||
|
setFormat( tokindex, token->size(), tokenFormats[ *token ]);
|
||||||
|
//std::cout << "found tok '" << (*token).toStdString() << "' at " << tokindex << "\n";
|
||||||
|
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";
|
||||||
|
tokindex += token->size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Quoting and Comments.
|
||||||
|
state_e state = (state_e) previousBlockState();
|
||||||
|
for (int n = 0; n < text.size(); ++n){
|
||||||
|
if (state == NORMAL){
|
||||||
|
if (text[n] == '"'){
|
||||||
|
state = QUOTE;
|
||||||
|
setFormat(n,1,quoteFormat);
|
||||||
|
} else if (text[n] == '/'){
|
||||||
|
if (text[n+1] == '/'){
|
||||||
|
setFormat(n,text.size(),commentFormat);
|
||||||
|
break;
|
||||||
|
} else if (text[n+1] == '*'){
|
||||||
|
setFormat(n++,2,commentFormat);
|
||||||
|
state = COMMENT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (state == QUOTE){
|
||||||
|
setFormat(n,1,quoteFormat);
|
||||||
|
if (text[n] == '"' && text[n-1] != '\\')
|
||||||
|
state = NORMAL;
|
||||||
|
} else if (state == COMMENT){
|
||||||
|
setFormat(n,1,commentFormat);
|
||||||
|
if (text[n] == '*' && text[n+1] == '/'){
|
||||||
|
setFormat(++n,1,commentFormat);
|
||||||
|
state = NORMAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setCurrentBlockState((int) state);
|
||||||
|
|
||||||
|
// Highlight an error. Do it last to 'overwrite' other formatting.
|
||||||
|
if (errorState) {
|
||||||
|
setFormat( errorPos - block_first_pos, 1, errorFormat);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,20 +2,27 @@
|
||||||
#define HIGHLIGHTER_H_
|
#define HIGHLIGHTER_H_
|
||||||
|
|
||||||
#include <QSyntaxHighlighter>
|
#include <QSyntaxHighlighter>
|
||||||
|
#include <QTextFormat>
|
||||||
#ifdef _QCODE_EDIT_
|
#include <QHash>
|
||||||
#include "qdocument.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class Highlighter : public QSyntaxHighlighter
|
class Highlighter : public QSyntaxHighlighter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
#ifdef _QCODE_EDIT_
|
enum state_e {NORMAL=-1,QUOTE,COMMENT};
|
||||||
Highlighter(QDocument *parent);
|
QHash<QString, QTextCharFormat> tokenFormats;
|
||||||
#else
|
QTextCharFormat errorFormat, commentFormat, quoteFormat, numberFormat;
|
||||||
Highlighter(QTextDocument *parent);
|
Highlighter(QTextDocument *parent);
|
||||||
#endif
|
|
||||||
void highlightBlock(const QString &text);
|
void highlightBlock(const QString &text);
|
||||||
|
void highlightError(int error_pos);
|
||||||
|
void unhighlightLastError();
|
||||||
|
private:
|
||||||
|
QTextBlock lastErrorBlock;
|
||||||
|
int errorPos;
|
||||||
|
bool errorState;
|
||||||
|
QMap<QString,QStringList> tokentypes;
|
||||||
|
QMap<QString,QTextCharFormat> typeformats;
|
||||||
|
int lastDocumentPos();
|
||||||
|
void portable_rehighlightBlock( const QTextBlock &text );
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -70,11 +70,6 @@
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
#include <QProgressDialog>
|
#include <QProgressDialog>
|
||||||
#include <QMutexLocker>
|
#include <QMutexLocker>
|
||||||
#ifdef _QCODE_EDIT_
|
|
||||||
#include "qdocument.h"
|
|
||||||
#include "qformatscheme.h"
|
|
||||||
#include "qlanguagefactory.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
|
@ -185,16 +180,8 @@ MainWindow::MainWindow(const QString &filename)
|
||||||
fps = 0;
|
fps = 0;
|
||||||
fsteps = 1;
|
fsteps = 1;
|
||||||
|
|
||||||
highlighter = NULL;
|
highlighter = new Highlighter(editor->document());
|
||||||
#ifdef _QCODE_EDIT_
|
|
||||||
QFormatScheme *formats = new QFormatScheme("qxs/openscad.qxf");
|
|
||||||
QDocument::setDefaultFormatScheme(formats);
|
|
||||||
QLanguageFactory *languages = new QLanguageFactory(formats,this);
|
|
||||||
languages->addDefinitionPath("qxs");
|
|
||||||
languages->setLanguage(editor, "openscad");
|
|
||||||
#else
|
|
||||||
editor->setTabStopWidth(30);
|
editor->setTabStopWidth(30);
|
||||||
#endif
|
|
||||||
editor->setLineWrapping(true); // Not designable
|
editor->setLineWrapping(true); // Not designable
|
||||||
|
|
||||||
this->glview->statusLabel = new QLabel(this);
|
this->glview->statusLabel = new QLabel(this);
|
||||||
|
@ -348,13 +335,8 @@ MainWindow::MainWindow(const QString &filename)
|
||||||
updateRecentFileActions();
|
updateRecentFileActions();
|
||||||
|
|
||||||
connect(editor->document(), SIGNAL(contentsChanged()), this, SLOT(animateUpdateDocChanged()));
|
connect(editor->document(), SIGNAL(contentsChanged()), this, SLOT(animateUpdateDocChanged()));
|
||||||
#ifdef _QCODE_EDIT_
|
|
||||||
connect(editor, SIGNAL(contentModified(bool)), this, SLOT(setWindowModified(bool)));
|
|
||||||
connect(editor, SIGNAL(contentModified(bool)), fileActionSave, SLOT(setEnabled(bool)));
|
|
||||||
#else
|
|
||||||
connect(editor->document(), SIGNAL(modificationChanged(bool)), this, SLOT(setWindowModified(bool)));
|
connect(editor->document(), SIGNAL(modificationChanged(bool)), this, SLOT(setWindowModified(bool)));
|
||||||
connect(editor->document(), SIGNAL(modificationChanged(bool)), fileActionSave, SLOT(setEnabled(bool)));
|
connect(editor->document(), SIGNAL(modificationChanged(bool)), fileActionSave, SLOT(setEnabled(bool)));
|
||||||
#endif
|
|
||||||
connect(this->glview, SIGNAL(doAnimateUpdate()), this, SLOT(animateUpdate()));
|
connect(this->glview, SIGNAL(doAnimateUpdate()), this, SLOT(animateUpdate()));
|
||||||
|
|
||||||
connect(Preferences::inst(), SIGNAL(requestRedraw()), this->glview, SLOT(updateGL()));
|
connect(Preferences::inst(), SIGNAL(requestRedraw()), this->glview, SLOT(updateGL()));
|
||||||
|
@ -484,12 +466,7 @@ void
|
||||||
MainWindow::openFile(const QString &new_filename)
|
MainWindow::openFile(const QString &new_filename)
|
||||||
{
|
{
|
||||||
#ifdef ENABLE_MDI
|
#ifdef ENABLE_MDI
|
||||||
#ifdef _QCODE_EDIT_
|
|
||||||
if (this->editor->document()->lines() > 1 ||
|
|
||||||
!this->editor->document()->text(true, false).trimmed().isEmpty()) {
|
|
||||||
#else
|
|
||||||
if (!editor->toPlainText().isEmpty()) {
|
if (!editor->toPlainText().isEmpty()) {
|
||||||
#endif
|
|
||||||
new MainWindow(new_filename);
|
new MainWindow(new_filename);
|
||||||
clearCurrentOutput();
|
clearCurrentOutput();
|
||||||
return;
|
return;
|
||||||
|
@ -958,11 +935,7 @@ void MainWindow::hideEditor()
|
||||||
|
|
||||||
void MainWindow::pasteViewportTranslation()
|
void MainWindow::pasteViewportTranslation()
|
||||||
{
|
{
|
||||||
#ifdef _QCODE_EDIT_
|
|
||||||
QDocumentCursor cursor = editor->cursor();
|
|
||||||
#else
|
|
||||||
QTextCursor cursor = editor->textCursor();
|
QTextCursor cursor = editor->textCursor();
|
||||||
#endif
|
|
||||||
QString txt;
|
QString txt;
|
||||||
txt.sprintf("[ %.2f, %.2f, %.2f ]", -this->glview->object_trans_x, -this->glview->object_trans_y, -this->glview->object_trans_z);
|
txt.sprintf("[ %.2f, %.2f, %.2f ]", -this->glview->object_trans_x, -this->glview->object_trans_y, -this->glview->object_trans_z);
|
||||||
cursor.insertText(txt);
|
cursor.insertText(txt);
|
||||||
|
@ -970,11 +943,7 @@ void MainWindow::pasteViewportTranslation()
|
||||||
|
|
||||||
void MainWindow::pasteViewportRotation()
|
void MainWindow::pasteViewportRotation()
|
||||||
{
|
{
|
||||||
#ifdef _QCODE_EDIT_
|
|
||||||
QDocumentCursor cursor = editor->cursor();
|
|
||||||
#else
|
|
||||||
QTextCursor cursor = editor->textCursor();
|
QTextCursor cursor = editor->textCursor();
|
||||||
#endif
|
|
||||||
QString txt;
|
QString txt;
|
||||||
txt.sprintf("[ %.2f, %.2f, %.2f ]",
|
txt.sprintf("[ %.2f, %.2f, %.2f ]",
|
||||||
fmodf(360 - this->glview->object_rot_x + 90, 360), fmodf(360 - this->glview->object_rot_y, 360), fmodf(360 - this->glview->object_rot_z, 360));
|
fmodf(360 - this->glview->object_rot_x + 90, 360), fmodf(360 - this->glview->object_rot_y, 360), fmodf(360 - this->glview->object_rot_z, 360));
|
||||||
|
@ -1068,24 +1037,16 @@ bool MainWindow::compileTopLevelDocument(bool reload)
|
||||||
QFileInfo(this->fileName).absolutePath().toLocal8Bit(),
|
QFileInfo(this->fileName).absolutePath().toLocal8Bit(),
|
||||||
false);
|
false);
|
||||||
|
|
||||||
// Error highlighting
|
if (!animate_panel->isVisible()) {
|
||||||
delete this->highlighter;
|
highlighter->unhighlightLastError();
|
||||||
this->highlighter = NULL;
|
if (!this->root_module) {
|
||||||
|
|
||||||
if (!this->root_module) {
|
|
||||||
this->highlighter = new Highlighter(editor->document());
|
|
||||||
|
|
||||||
if (!animate_panel->isVisible()) {
|
|
||||||
#ifdef _QCODE_EDIT_
|
|
||||||
QDocumentCursor cursor = editor->cursor();
|
|
||||||
cursor.setPosition(parser_error_pos);
|
|
||||||
#else
|
|
||||||
QTextCursor cursor = editor->textCursor();
|
QTextCursor cursor = editor->textCursor();
|
||||||
cursor.setPosition(parser_error_pos);
|
cursor.setPosition(parser_error_pos);
|
||||||
editor->setTextCursor(cursor);
|
editor->setTextCursor(cursor);
|
||||||
#endif
|
highlighter->highlightError( parser_error_pos );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool changed = shouldcompiletoplevel;
|
bool changed = shouldcompiletoplevel;
|
||||||
|
|
Loading…
Reference in New Issue