$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 MAINWINDOW_H 00022 #define MAINWINDOW_H 00023 00024 #include <QMainWindow> 00025 #include <QString> 00026 #include <QMessageBox> 00027 #include <QItemSelection> 00028 #include <QTableView> 00029 #include <QSplitter> 00030 #include <QTextEdit> 00031 #include <QMultiMap> 00032 #include <QTabWidget> 00033 #include <QCloseEvent> 00034 #include <QFuture> 00035 #include <QFutureWatcher> 00036 #include <QToolButton> 00037 #include <QToolBar> 00038 #include <QCompleter> 00039 #include <QSortFilterProxyModel> 00040 #include <QSignalMapper> 00041 00042 #include "AeslEditor.h" 00043 #include "CustomDelegate.h" 00044 #include "CustomWidgets.h" 00045 #include "ModelAggregator.h" 00046 00047 #include "../compiler/compiler.h" 00048 #include <fstream> 00049 #include <sstream> 00050 #include <vector> 00051 #include <string> 00052 #include "Target.h" 00053 #include "TargetModels.h" 00054 #include "Plugin.h" 00055 #include "HelpViewer.h" 00056 #include "ConfigDialog.h" 00057 00058 class QLabel; 00059 class QSpinBox; 00060 class QGroupBox; 00061 class QPushButton; 00062 class QListWidget; 00063 class QListWidgetItem; 00064 class QTreeView; 00065 class QTranslator; 00066 //class QTextBrowser; 00067 class QToolBox; 00068 class QCheckBox; 00069 00070 namespace Aseba 00071 { 00074 00075 class TargetVariablesModel; 00076 class TargetFunctionsModel; 00077 class TargetMemoryModel; 00078 class MaskableNamedValuesVectorModel; 00079 class NamedValuesVectorModel; 00080 class AeslEditor; 00081 class AeslLineNumberSidebar; 00082 class AeslBreakpointSidebar; 00083 class AeslHighlighter; 00084 class EventViewer; 00085 class EditorsPlotsTabWidget; 00086 class DraggableListWidget; 00087 class FindDialog; 00088 class MainWindow; 00089 00090 class CompilationLogDialog: public QTextEdit 00091 { 00092 Q_OBJECT 00093 00094 public: 00095 CompilationLogDialog(QWidget *parent = 0); 00096 signals: 00097 void hidden(); 00098 protected: 00099 virtual void hideEvent ( QHideEvent * event ); 00100 }; 00101 00102 class EditorsPlotsTabWidget: public QTabWidget 00103 { 00104 Q_OBJECT 00105 00106 public: 00107 EditorsPlotsTabWidget(); 00108 virtual ~EditorsPlotsTabWidget(); 00109 void addTab(QWidget* widget, const QString& label, bool closable = false); 00110 void highlightTab(int index, QColor color = Qt::red); 00111 void setExecutionMode(int index, Target::ExecutionMode state); 00112 00113 public slots: 00114 void removeAndDeleteTab(int index = -1); 00115 00116 protected slots: 00117 void vmMemoryResized(int, int, int); // for vmMemoryView QTreeView child widget 00118 void tabChanged(int index); 00119 00120 protected: 00121 virtual void resetHighlight(int index); 00122 virtual void vmMemoryViewResize(NodeTab* tab); 00123 virtual void readSettings(); 00124 virtual void writeSettings(); 00125 00126 int vmMemorySize[2]; 00127 }; 00128 00129 class ScriptTab 00130 { 00131 public: 00132 typedef NodeToolInterface::SavedContent SavedContent; 00133 typedef QList<SavedContent> SavedPlugins; 00134 00135 ScriptTab(const unsigned id):id(id) {} 00136 virtual ~ScriptTab() {} 00137 00138 unsigned nodeId() const { return id; } 00139 virtual SavedPlugins savePlugins() const = 0; 00140 00141 protected: 00142 void createEditor(); 00143 00144 unsigned id; 00145 00146 friend class MainWindow; 00147 AeslEditor* editor; 00148 AeslLineNumberSidebar* linenumbers; 00149 AeslBreakpointSidebar* breakpoints; 00150 AeslHighlighter *highlighter; 00151 }; 00152 00153 class AbsentNodeTab : public QWidget, public ScriptTab 00154 { 00155 Q_OBJECT 00156 00157 public: 00158 AbsentNodeTab(const unsigned id, const QString& name, const QString& sourceCode, const SavedPlugins& savedPlugins); 00159 00160 virtual SavedPlugins savePlugins() const { return savedPlugins; } 00161 00162 const QString name; 00163 SavedPlugins savedPlugins; 00164 }; 00165 00166 class NodeTab : public QSplitter, public ScriptTab, public VariableListener 00167 { 00168 Q_OBJECT 00169 00170 public: 00171 struct CompilationResult 00172 { 00173 bool dump; 00174 bool success; 00175 BytecodeVector bytecode; 00176 unsigned allocatedVariablesCount; 00177 Compiler::VariablesMap variablesMap; 00178 Error error; 00179 std::wostringstream compilationMessages; 00180 00181 CompilationResult(bool dump):dump(dump) {} 00182 }; 00183 00184 00185 public: 00186 NodeTab(MainWindow* mainWindow, Target *target, const CommonDefinitions *commonDefinitions, int id, QWidget *parent = 0); 00187 ~NodeTab(); 00188 unsigned productId() const { return pid; } 00189 00190 void variablesMemoryChanged(unsigned start, const VariablesDataVector &variables); 00191 00192 signals: 00193 void uploadReadynessChanged(bool); 00194 00195 protected: 00196 virtual void timerEvent ( QTimerEvent * event ); 00197 virtual void variableValueUpdated(const QString& name, const VariablesDataVector& values); 00198 void setupWidgets(); 00199 void setupConnections(); 00200 virtual SavedPlugins savePlugins() const; 00201 void restorePlugins(const SavedPlugins& savedPlugins, bool fromFile); 00202 void updateToolList(); 00203 00204 public slots: 00205 void clearExecutionErrors(); 00206 void refreshCompleterModel(LocalContext context); 00207 //void sortCompleterModel(); 00208 00209 protected slots: 00210 void resetClicked(); 00211 void loadClicked(); 00212 void runInterruptClicked(); 00213 void nextClicked(); 00214 void refreshMemoryClicked(); 00215 void autoRefreshMemoryClicked(int state); 00216 00217 void writeBytecode(); 00218 void reboot(); 00219 void saveBytecode(); 00220 00221 void setVariableValues(unsigned, const VariablesDataVector &); 00222 void insertVariableName(const QModelIndex &); 00223 00224 void editorContentChanged(); 00225 void recompile(); 00226 void markTargetUnsynced(); 00227 00228 // keywords 00229 void keywordClicked(QString); 00230 // void varButtonClicked(); 00231 // void ifButtonClicked(); 00232 // void elseifButtonClicked(); 00233 // void elseButtonClicked(); 00234 // void oneventButtonClicked(); 00235 // void whileButtonClicked(); 00236 // void forButtonClicked(); 00237 // void subroutineButtonClicked(); 00238 // void callsubButtonClicked(); 00239 void showKeywords(bool show); 00240 00241 void showMemoryUsage(bool show); 00242 00243 void displayCode(QList<QString> code, int line); 00244 00245 void cursorMoved(); 00246 void goToError(); 00247 00248 void setBreakpoint(unsigned line); 00249 void clearBreakpoint(unsigned line); 00250 void breakpointClearedAll(); 00251 00252 void executionPosChanged(unsigned line); 00253 void executionModeChanged(Target::ExecutionMode mode); 00254 00255 void breakpointSetResult(unsigned line, bool success); 00256 00257 void closePlugins(); 00258 00259 void updateHidden(); 00260 00261 void compilationCompleted(); 00262 00263 protected: 00264 void processCompilationResult(CompilationResult* result); 00265 void rehighlight(); 00266 void reSetBreakpoints(); 00267 00268 // editor properties code 00269 bool setEditorProperty(const QString &property, const QVariant &value, unsigned line, bool removeOld = false); 00270 bool clearEditorProperty(const QString &property, unsigned line); 00271 bool clearEditorProperty(const QString &property); 00272 void switchEditorProperty(const QString &oldProperty, const QString &newProperty); 00273 00274 protected: 00275 friend class MainWindow; 00276 friend class AeslEditor; 00277 friend class EditorsPlotsTabWidget; 00278 00279 unsigned pid; 00280 friend class InvasivePlugin; 00281 Target *target; 00282 const CommonDefinitions *commonDefinitions; 00283 00284 MainWindow* mainWindow; 00285 QLabel *cursorPosText; 00286 QLabel *compilationResultImage; 00287 QLabel *compilationResultText; 00288 QLabel *memoryUsageText; 00289 00290 QLabel *executionModeLabel; 00291 QPushButton *loadButton; 00292 QPushButton *resetButton; 00293 QPushButton *runInterruptButton; 00294 QPushButton *nextButton; 00295 QPushButton *refreshMemoryButton; 00296 QCheckBox *autoRefreshMemoryCheck; 00297 00298 00299 // keywords // Jiwon 00300 QToolButton *varButton; 00301 QToolButton *ifButton; 00302 QToolButton *elseifButton; 00303 QToolButton *elseButton; 00304 QToolButton *oneventButton; 00305 QToolButton *whileButton; 00306 QToolButton *forButton; 00307 QToolButton *subroutineButton; 00308 QToolButton *callsubButton; 00309 QToolBar *keywordsToolbar; 00310 QSignalMapper *signalMapper; 00311 00312 TargetVariablesModel *vmMemoryModel; 00313 QTreeView *vmMemoryView; 00314 QLineEdit *vmMemoryFilter; 00315 00316 TargetFunctionsModel *vmFunctionsModel; 00317 QTreeView *vmFunctionsView; 00318 00319 DraggableListWidget* vmLocalEvents; 00320 00321 QCompleter *completer; 00322 QAbstractItemModel* eventAggregator; 00323 QAbstractItemModel* variableAggregator; 00324 QSortFilterProxyModel* sortingProxy; 00325 TreeChainsawFilter* functionsFlatModel; 00326 00327 QToolBox* toolBox; 00328 QVBoxLayout* toolListLayout; 00329 int toolListIndex; 00330 NodeToolInterfaces tools; 00331 00332 int refreshTimer; 00333 00334 bool rehighlighting; 00335 int errorPos; 00336 int currentPC; 00337 Target::ExecutionMode previousMode; 00338 bool firstCompilation; 00339 bool showHidden; 00340 00341 QFuture<CompilationResult*> compilationFuture; 00342 QFutureWatcher<CompilationResult*> compilationWatcher; 00343 bool compilationDirty; 00344 bool isSynchronized; 00345 00346 BytecodeVector bytecode; 00347 unsigned allocatedVariablesCount; 00348 }; 00349 00350 class NewNamedValueDialog : public QDialog 00351 { 00352 Q_OBJECT 00353 00354 public: 00355 NewNamedValueDialog(QString* name, int* value, int min, int max); 00356 static bool getNamedValue(QString* name, int* value, int min, int max, QString title, QString valueName, QString valueDescription); 00357 00358 protected slots: 00359 void okSlot(); 00360 void cancelSlot(); 00361 00362 protected: 00363 QLabel* label1; 00364 QLineEdit* line1; 00365 QLabel* label2; 00366 QSpinBox* line2; 00367 00368 QString* name; 00369 int* value; 00370 }; 00371 00372 class MainWindow : public QMainWindow 00373 { 00374 Q_OBJECT 00375 00376 public: 00377 MainWindow(QVector<QTranslator*> translators, const QString& commandLineTarget, bool autoRefresh, QWidget *parent = 0); 00378 ~MainWindow(); 00379 00380 signals: 00381 void MainWindowClosed(); 00382 00383 private slots: 00384 void about(); 00385 bool newFile(); 00386 void openFile(const QString &path = QString()); 00387 void openRecentFile(); 00388 bool save(); 00389 bool saveFile(const QString &previousFileName = QString()); 00390 void exportMemoriesContent(); 00391 void importMemoriesContent(); 00392 void copyAll(); 00393 void findTriggered(); 00394 void replaceTriggered(); 00395 void commentTriggered(); 00396 void uncommentTriggered(); 00397 void showLineNumbersChanged(bool state); 00398 void goToLine(); 00399 void showSettings(); 00400 void showHidden(bool show); 00401 void showKeywords(bool show); 00402 00403 void toggleBreakpoint(); 00404 void clearAllBreakpoints(); 00405 00406 void loadAll(); 00407 void resetAll(); 00408 void runAll(); 00409 void pauseAll(); 00410 void stopAll(); 00411 00412 void clearAllExecutionError(); 00413 00414 void uploadReadynessChanged(); 00415 void tabChanged(int); 00416 void sendEvent(); 00417 void sendEventIf(const QModelIndex &); 00418 void toggleEventVisibleButton(const QModelIndex &); 00419 void plotEvent(); 00420 void eventContextMenuRequested(const QPoint & pos); 00421 void plotEvent(const unsigned eventId); 00422 void logEntryDoubleClicked(QListWidgetItem *); 00423 void showCompilationMessages(bool doShown); 00424 void compilationMessagesWasHidden(); 00425 void showMemoryUsage(bool show); 00426 00427 void addEventNameClicked(); 00428 void removeEventNameClicked(); 00429 void eventsUpdated(bool indexChanged = false); 00430 void eventsUpdatedDirty(); 00431 void eventsDescriptionsSelectionChanged(); 00432 00433 void resetStatusText(); // Jiwon 00434 00435 void addConstantClicked(); 00436 void removeConstantClicked(); 00437 void constantsSelectionChanged(); 00438 00439 void nodeConnected(unsigned node); 00440 void nodeDisconnected(unsigned node); 00441 void networkDisconnected(); 00442 00443 void userEventsDropped(unsigned amount); 00444 void userEvent(unsigned id, const VariablesDataVector &data); 00445 void arrayAccessOutOfBounds(unsigned node, unsigned line, unsigned size, unsigned index); 00446 void divisionByZero(unsigned node, unsigned line); 00447 void eventExecutionKilled(unsigned node, unsigned line); 00448 void nodeSpecificError(unsigned node, unsigned line, const QString& message); 00449 00450 void executionPosChanged(unsigned node, unsigned line); 00451 void executionModeChanged(unsigned node, Target::ExecutionMode mode); 00452 void variablesMemoryEstimatedDirty(unsigned node); 00453 00454 void variablesMemoryChanged(unsigned node, unsigned start, const VariablesDataVector &variables); 00455 00456 void breakpointSetResult(unsigned node, unsigned line, bool success); 00457 00458 void recompileAll(); 00459 void writeAllBytecodes(); 00460 void rebootAllNodes(); 00461 00462 void sourceChanged(); 00463 void updateWindowTitle(); 00464 00465 void showUserManual(); 00466 00467 void openToUrlFromAction() const; 00468 00469 public slots: 00470 void applySettings(); 00471 00472 private: 00473 virtual void timerEvent ( QTimerEvent * event ); 00474 00475 // utility functions 00476 int getIndexFromId(unsigned node) const; 00477 NodeTab* getTabFromId(unsigned node) const; 00478 NodeTab* getTabFromName(const QString& name, unsigned preferedId = 0) const; 00479 int getAbsentIndexFromId(unsigned node) const; 00480 AbsentNodeTab* getAbsentTabFromId(unsigned node) const; 00481 void addErrorEvent(unsigned node, unsigned line, const QString& message); 00482 void clearDocumentSpecificTabs(); 00483 bool askUserBeforeDiscarding(); 00484 00485 // gui initialisation code 00486 void regenerateOpenRecentMenu(); 00487 void updateRecentFiles(const QString& fileName); 00488 void regenerateToolsMenus(); 00489 void generateHelpMenu(); 00490 void regenerateHelpMenu(); 00491 void setupWidgets(); 00492 void setupConnections(); 00493 void setupMenu(); 00494 void closeEvent ( QCloseEvent * event ); 00495 bool readSettings(); 00496 void writeSettings(); 00497 00498 // tabs and nodes 00499 friend class NodeTab; 00500 friend class AeslEditor; 00501 friend class InvasivePlugin; 00502 EditorsPlotsTabWidget* nodes; 00503 ScriptTab* currentScriptTab; 00504 int getDescriptionTimer; 00505 00506 #ifdef HAVE_QWT 00507 00508 // events viewers. only one event per viewer 00509 friend class EventViewer; 00510 typedef QMultiMap<unsigned, EventViewer*> EventViewers; 00511 EventViewers eventsViewers; 00512 00513 #endif // HAVE_QWT 00514 00515 // events 00516 QPushButton* addEventNameButton; 00517 QPushButton* removeEventNameButton; 00518 QPushButton* sendEventButton; 00519 #ifdef HAVE_QWT 00520 QPushButton* plotEventButton; 00521 #endif // HAVE_QWT 00522 QListWidget* logger; 00523 QPushButton* clearLogger; 00524 QLabel* statusText; // Jiwon 00525 FixedWidthTableView* eventsDescriptionsView; 00526 00527 // constants 00528 QPushButton* addConstantButton; 00529 QPushButton* removeConstantButton; 00530 FixedWidthTableView* constantsView; 00531 00532 // models 00533 MaskableNamedValuesVectorModel* eventsDescriptionsModel; 00534 NamedValuesVectorModel* constantsDefinitionsModel; 00535 00536 // global buttons 00537 QAction* loadAllAct; 00538 QAction* resetAllAct; 00539 QAction* runAllAct; 00540 QAction* pauseAllAct; 00541 QToolBar* globalToolBar; 00542 00543 // open recent actions 00544 QMenu *openRecentMenu; 00545 00546 // tools 00547 QMenu *writeBytecodeMenu; 00548 QAction *writeAllBytecodesAct; 00549 QMenu *rebootMenu; 00550 QMenu *saveBytecodeMenu; 00551 QMenu *helpMenu; 00552 typedef QList<QAction*> ActionList; 00553 QAction* helpMenuTargetSpecificSeparator; 00554 ActionList targetSpecificHelp; 00555 00556 // Menu action that need dynamic reconnection 00557 QAction *cutAct; 00558 QAction *copyAct; 00559 QAction *pasteAct; 00560 QAction *undoAct; 00561 QAction *redoAct; 00562 QAction *findAct; 00563 QAction *replaceAct; 00564 QAction *commentAct; 00565 QAction *uncommentAct; 00566 QAction *showLineNumbers; 00567 QAction *goToLineAct; 00568 QAction *toggleBreakpointAct; 00569 QAction *clearAllBreakpointsAct; 00570 QAction *showHiddenAct; 00571 QAction *showKeywordsAct; 00572 QAction* showCompilationMsg; 00573 QAction* showMemoryUsageAct; 00574 00575 // gui helper stuff 00576 CompilationLogDialog *compilationMessageBox; 00577 FindDialog* findDialog; 00578 QString actualFileName; 00579 bool sourceModified; 00580 bool autoMemoryRefresh; 00581 HelpViewer helpViewer; 00582 00583 // compiler and source code related stuff 00584 CommonDefinitions commonDefinitions; 00585 Target *target; 00586 }; 00587 00589 }; // Aseba 00590 00591 #endif 00592