$search
00001 /* 00002 Aseba - an event-based framework for distributed robot control 00003 Copyright (C) 2007--2012: 00004 Stephane Magnenat <stephane at magnenat dot net> 00005 (http://stephane.magnenat.net) 00006 and other contributors, see authors.txt for details 00007 00008 This program is free software: you can redistribute it and/or modify 00009 it under the terms of the GNU Lesser General Public License as published 00010 by the Free Software Foundation, version 3 of the License. 00011 00012 This program is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU Lesser General Public License for more details. 00016 00017 You should have received a copy of the GNU Lesser General Public License 00018 along with this program. If not, see <http://www.gnu.org/licenses/>. 00019 */ 00020 00021 #ifndef AESL_EDITOR_H 00022 #define AESL_EDITOR_H 00023 00024 #include <QSyntaxHighlighter> 00025 00026 #include <QWidget> 00027 #include <QHash> 00028 #include <QTextCharFormat> 00029 #include <QTextBlockUserData> 00030 #include <QTextEdit> 00031 #include <QCompleter> 00032 #include <QRegExp> 00033 00034 class QTextDocument; 00035 00036 namespace Aseba 00037 { 00040 00041 class AeslEditor; 00042 00043 class AeslHighlighter : public QSyntaxHighlighter 00044 { 00045 Q_OBJECT 00046 00047 public: 00048 AeslHighlighter(AeslEditor *editor, QTextDocument *parent = 0); 00049 00050 protected: 00051 void highlightBlock(const QString &text); 00052 00053 private: 00054 struct HighlightingRule 00055 { 00056 QRegExp pattern; 00057 QTextCharFormat format; 00058 }; 00059 QVector<HighlightingRule> highlightingRules; 00060 struct CommentBlockRule 00061 { 00062 QRegExp begin; 00063 QRegExp end; 00064 QTextCharFormat format; 00065 }; 00066 // For multi-lines comments 00067 CommentBlockRule commentBlockRules; 00068 enum BlockState 00069 { 00070 STATE_DEFAULT=-1, // Qt default 00071 NO_COMMENT=0, // Normal block 00072 COMMENT, // Block with multilines comments 00073 }; 00074 00075 AeslEditor *editor; 00076 }; 00077 00078 struct AeslEditorUserData : public QTextBlockUserData 00079 { 00080 QMap<QString, QVariant> properties; 00081 00082 AeslEditorUserData(const QString &property, const QVariant &value = QVariant()) { properties.insert(property, value); } 00083 virtual ~AeslEditorUserData() { } 00084 }; 00085 00086 class AeslEditorSidebar : public QWidget 00087 { 00088 Q_OBJECT 00089 00090 public: 00091 AeslEditorSidebar(AeslEditor* editor); 00092 virtual QSize sizeHint() const; 00093 00094 public slots: 00095 virtual void scroll(int verticalScroll); 00096 00097 protected: 00098 virtual void paintEvent(QPaintEvent *event); 00099 virtual void mousePressEvent(QMouseEvent *event) {QWidget::mousePressEvent(event);} 00100 00101 virtual int idealWidth() const = 0; 00102 int posToLineNumber(int y); 00103 00104 protected: 00105 AeslEditor* editor; 00106 QSize currentSizeHint; 00107 int verticalScroll; 00108 }; 00109 00110 class AeslLineNumberSidebar : public AeslEditorSidebar 00111 { 00112 Q_OBJECT 00113 00114 public: 00115 AeslLineNumberSidebar(AeslEditor* editor); 00116 00117 public slots: 00118 void showLineNumbers(bool state); 00119 00120 protected: 00121 virtual void paintEvent(QPaintEvent *event); 00122 virtual int idealWidth() const; 00123 }; 00124 00125 class AeslBreakpointSidebar : public AeslEditorSidebar 00126 { 00127 Q_OBJECT 00128 00129 public: 00130 AeslBreakpointSidebar(AeslEditor* editor); 00131 00132 protected: 00133 virtual void paintEvent(QPaintEvent *event); 00134 virtual void mousePressEvent(QMouseEvent *event); 00135 virtual int idealWidth() const; 00136 00137 protected: 00138 const int borderSize; 00139 QRect breakpoint; 00140 }; 00141 00142 class ScriptTab; 00143 00144 enum LocalContext { 00145 UnknownContext, 00146 VarDefContext, 00147 LeftValueContext, 00148 FunctionContext, 00149 EventContext, 00150 GeneralContext 00151 }; 00152 00153 class AeslEditor : public QTextEdit 00154 { 00155 Q_OBJECT 00156 00157 signals: 00158 void breakpointSet(unsigned line); 00159 void breakpointCleared(unsigned line); 00160 void breakpointClearedAll(); 00161 00162 void refreshModelRequest(LocalContext context); 00163 00164 public: 00165 AeslEditor(const ScriptTab* tab); 00166 virtual ~AeslEditor() { } 00167 virtual void contextMenuEvent ( QContextMenuEvent * e ); 00168 00169 bool isBreakpoint(); // apply to the current line 00170 bool isBreakpoint(QTextBlock block); 00171 bool isBreakpoint(int line); 00172 void toggleBreakpoint(); // apply to the current line 00173 void toggleBreakpoint(QTextBlock block); 00174 void setBreakpoint(); // apply to the current line 00175 void setBreakpoint(QTextBlock block); 00176 void clearBreakpoint(); // apply to the current line 00177 void clearBreakpoint(QTextBlock block); 00178 void clearAllBreakpoints(); 00179 00180 void setCompleterModel(QAbstractItemModel* model); 00181 00182 enum CommentOperation { 00183 CommentSelection, 00184 UncommentSelection 00185 }; 00186 void commentAndUncommentSelection(CommentOperation commentOperation); 00187 00188 public: 00189 const ScriptTab* tab; 00190 bool debugging; 00191 QWidget *dropSourceWidget; 00192 00193 protected slots: 00194 void insertCompletion(const QString &completion); 00195 00196 protected: 00197 virtual void dropEvent(QDropEvent *event); 00198 virtual void insertFromMimeData ( const QMimeData * source ); 00199 virtual void keyPressEvent(QKeyEvent * event); 00200 00201 virtual bool handleCompleter(QKeyEvent * event); 00202 virtual bool handleTab(QKeyEvent * event); 00203 virtual bool handleNewLine(QKeyEvent * event); 00204 virtual void detectLocalContextChange(QKeyEvent * event); 00205 virtual void doCompletion(QKeyEvent * event); 00206 00207 QString textUnderCursor() const; 00208 QString previousWord() const; 00209 QString currentLine() const; 00210 00211 protected: 00212 QCompleter *completer; 00213 const QRegExp vardefRegexp; 00214 const QRegExp leftValueRegexp; 00215 LocalContext previousContext; 00216 bool editingLeftValue; 00217 }; 00218 00220 }; // Aseba 00221 00222 #endif