1 /* 2 Copyright (C) 2008, 2009 Andres Cabrera 3 mantaraya36@gmail.com 4 5 This file is part of CsoundQt. 6 7 CsoundQt is free software; you can redistribute it 8 and/or modify it under the terms of the GNU Lesser General Public 9 License as published by the Free Software Foundation; either 10 version 2.1 of the License, or (at your option) any later version. 11 12 CsoundQt is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU Lesser General Public License for more details. 16 17 You should have received a copy of the GNU Lesser General Public 18 License along with Csound; if not, write to the Free Software 19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 20 02111-1307 USA 21 */ 22 23 #ifndef QUTECSOUND_H 24 #define QUTECSOUND_H 25 26 #ifdef USE_QT5 27 #include <QtWidgets> 28 #ifdef USE_QT_GT_53 29 #include <QQuickWidget> 30 #include <QQuickItem> 31 #endif 32 #else 33 #include <QtGui> 34 #include <QDesktopServices> 35 #endif 36 #include <QLocalServer> 37 #include <QLocalSocket> 38 39 #include "types.h" 40 #include "configlists.h" 41 42 #ifdef MACOSX_PRE_SNOW 43 // Needed to be able to grab menus back from FLTK 44 #include <Carbon/Carbon.h> 45 #endif 46 47 #define QCS_USE_NEW_ICON 48 49 class QAction; 50 class QMenu; 51 class QTextEdit; 52 53 class DockHelp; 54 class WidgetPanel; 55 class Inspector; 56 #ifdef QCS_PYTHONQT 57 class PythonConsole; 58 #endif 59 class DockConsole; 60 class DebugPanel; 61 class OpEntryParser; 62 class Options; 63 class ConfigLists; 64 class DocumentPage; 65 class UtilitiesDialog; 66 class Curve; 67 class GraphicWindow; 68 class KeyboardShortcuts; 69 class EventDispatcher; 70 class EventSheet; 71 class CsoundEngine; 72 class MidiHandler; 73 class MidiLearnDialog; 74 class WidgetLayout; 75 76 #if defined(QCS_QTHTML) 77 class CsoundHtmlView; 78 #endif 79 80 class CsoundQt:public QMainWindow 81 { 82 Q_OBJECT 83 84 friend class WidgetPanel; //to pass ud 85 friend class FileOpenEater; //to pass curPage 86 public: 87 CsoundQt(QStringList fileNames); 88 ~CsoundQt(); 89 static void utilitiesMessageCallback(CSOUND *csound, 90 int /*attr*/, 91 const char *fmt, 92 va_list args); 93 94 // Editor 95 QString setDocument(int index); // Returns document name 96 void insertText(QString text, int index = -1, int section = -1); 97 void setCsd(QString text, int index = -1); 98 void setFullText(QString text, int index = -1); 99 void setOrc(QString text, int index = -1); 100 void setSco(QString text, int index = -1); 101 void setWidgetsText(QString text, int index = -1); 102 void setPresetsText(QString text, int index = -1); 103 void setOptionsText(QString text, int index = -1); 104 int getDocument(QString name = ""); // Returns document index. -1 if not current open 105 QString getSelectedText(int index = -1, int section = 0); 106 QString getCsd(int index); 107 QString getFullText(int index); 108 QString getOrc(int index); 109 QString getSco(int index); 110 QString getWidgetsText(int index); 111 QString getSelectedWidgetsText(int index); 112 QString getPresetsText(int index); 113 QString getOptionsText(int index); 114 QString getFileName(int index); 115 QString getFilePath(int index); 116 // Widgets 117 void setChannelValue(QString channel, double value, int index = -1); 118 double getChannelValue(QString channel, int index = -1); 119 void setChannelString(QString channel, QString value, int index = -1); 120 QString getChannelString(QString channel, int index = -1); 121 void setWidgetProperty(QString widgetid, QString property, QVariant value, int index= -1); 122 QVariant getWidgetProperty(QString widgetid, QString property, int index= -1); 123 QString createNewLabel(int x = -1, int y = -1, QString channel = QString(), int index = -1); 124 QString createNewDisplay(int x = -1, int y = -1, QString channel = QString(), int index = -1); 125 QString createNewScrollNumber(int x = -1, int y = -1, QString channel = QString(), int index = -1); 126 QString createNewLineEdit(int x = -1, int y = -1, QString channel = QString(), int index = -1); 127 QString createNewSpinBox(int x = -1, int y = -1, QString channel = QString(), int index = -1); 128 QString createNewSlider(int x = -1, int y = -1, QString channel = QString(), int index = -1); 129 QString createNewButton(int x = -1, int y = -1, QString channel = QString(), int index = -1); 130 QString createNewKnob(int x = -1, int y = -1, QString channel = QString(), int index = -1); 131 QString createNewCheckBox(int x = -1, int y = -1, QString channel = QString(), int index = -1); 132 QString createNewMenu(int x = -1, int y = -1, QString channel = QString(), int index = -1); 133 QString createNewMeter(int x = -1, int y = -1, QString channel = QString(), int index = -1); 134 QString createNewConsole(int x = -1, int y = -1, QString channel = QString(), int index = -1); 135 QString createNewGraph(int x = -1, int y = -1, QString channel = QString(), int index = -1); 136 QString createNewScope(int x = -1, int y = -1, QString channel = QString(), int index = -1); 137 // int popKeyPressEvent(); // return ASCII code of key press event for Csound or -1 if no event 138 // int popKeyReleaseEvent(); // return ASCII code of key release event for Csound -1 if no 139 QStringList getWidgetUuids(int index = -1); 140 QStringList listWidgetProperties(QString widgetid, int index = -1); // widgetid can be eihter uuid (prefered) or channel 141 bool destroyWidget(QString widgetid, int index = -1); 142 void loadPreset(int preSetIndex, int index); 143 //Live Event Sheets 144 EventSheet* getSheet(int index = -1, int sheetIndex = -1); 145 EventSheet* getSheet(int index = -1, QString sheetName = QString()); 146 // Engine 147 CsoundEngine *getEngine(int index = -1); 148 OpEntryParser *m_opcodeTree; 149 void stkCheck(); 150 // localServer 151 bool startServer(); 152 #if defined(QCS_QTHTML) 153 void updateHtmlView(); 154 #endif 155 public slots: 156 int loadFile(QString fileName, bool runNow = false); 157 int loadFileFromSystem(QString fileName); // checks for m_options->autoPlay, if the function is called from other class 158 void newFile(); 159 bool closeTab(bool forceCloseApp = false, int index = -1); 160 bool saveFile(const QString &fileName, bool saveWidgets = true); 161 void play(bool realtime = true, int index = -1); 162 void runInTerm(bool realtime = true); 163 void pause(int index = -1); 164 void stop(int index = -1); 165 void stopAll(); 166 void stopAllOthers(); 167 void markStopped(); 168 void perfEnded(); 169 void render(); 170 void record(bool); 171 void sendEvent(QString eventLine, double delay = 0); 172 void sendEvent(int index, QString line, double delay = 0); 173 void changePage(int index); 174 void pageLeft(); 175 void pageRight(); 176 void setWidgetTooltipsVisible(bool visible); 177 void closeExtraPanels(); // to close help and console panels when esc is pressed in the editor 178 179 // void updateWidgets(); 180 void openExample(); 181 void openTemplate(); 182 void logMessage(QString msg); 183 void statusBarMessage(QString message); 184 // void registerLiveEvent(QWidget *e); 185 void evaluateCsound(QString code = QString()); 186 void breakpointReached(); 187 void setParsedUDOs(); 188 189 190 protected: 191 virtual void closeEvent(QCloseEvent *event); 192 // virtual void keyPressEvent(QKeyEvent *event); 193 private slots: 194 void open(); 195 void reload(); 196 void openFromAction(); 197 void openFromAction(QString fileName); 198 void runScriptFromAction(); 199 void runScript(QString fileName); 200 void createCodeGraph(); 201 void closeGraph(); 202 bool save(); 203 bool saveAs(); 204 void createApp(); 205 bool saveNoWidgets(); 206 void info(); 207 // Edition 208 void copy(); 209 void cut(); 210 void paste(); 211 void undo(); 212 void redo(); 213 void evaluateSection(); 214 void evaluate(QString code = QString()); 215 void evaluatePython(QString code = QString()); 216 void evaluateString(QString evalCode); 217 void setScratchPadMode(bool csdMode); 218 void setWidgetEditMode(bool); // This is not necessary as the action is passed and connected in the widget layout 219 void duplicate(); 220 void print(); 221 void findReplace(); // Direct to current Page 222 void findString(); // Direct to current Page 223 bool join(bool ask = true); 224 void showUtilities(bool); 225 void getToIn(); 226 void inToGet(); 227 void updateCsladspaText(); 228 void updateCabbageText(); 229 void saveWidgetsToQml(); 230 void setCurrentAudioFile(const QString fileName); 231 void openExternalEditor(); 232 void openExternalPlayer(); 233 void setEditorFocus(); 234 void setHelpEntry(); 235 void setFullScreen(bool full); 236 void checkFullScreen(); 237 void setEditorFullScreen(bool full); 238 void setHtmlFullScreen(bool full); 239 void setHelpFullScreen(bool full); 240 void setWidgetsFullScreen(bool full); 241 void showDebugger(bool show); 242 void showVirtualKeyboard(bool show); 243 void showTableEditor(bool show); 244 void virtualKeyboardActOff(QObject *parent=0); 245 void tableEditorActOff(QObject *parent=0); 246 void showHtml5Gui(bool show); 247 void splitView(bool split); 248 void showMidiLearn(); 249 void virtualMidiIn(QVariant on, QVariant note, QVariant channel, QVariant velocity); 250 void virtualCCIn(int channel, int cc, int value); 251 void handleTableSyntax(QString syntax); 252 void openManualExample(QString fileName); 253 void openExternalBrowser(QUrl url = QUrl()); 254 void openPdfFile(QString name); 255 void openFLOSSManual(); 256 void openQuickRef(); 257 void openOnlineDocumentation(); 258 void resetPreferences(); 259 void reportBug(); 260 void requestFeature(); 261 void chat(); 262 void openShortcutDialog(); 263 void downloadManual(); 264 void about(); 265 void donate(); 266 void documentWasModified(); 267 void configure(); 268 void applySettings(); 269 void setCurrentOptionsForPage(DocumentPage *p); 270 void runUtility(QString flags); 271 // void widgetDockLocationChanged(Qt::DockWidgetArea area); 272 void updateInspector(); 273 void updateCurrentPageTask(); 274 void markInspectorUpdate(); // Notification that inspector needs update 275 void setDefaultKeyboardShortcuts(); 276 void showNoPythonQtWarning(); 277 void showOrc(bool); 278 void showScore(bool); 279 void showOptions(bool); 280 void showFileB(bool); 281 void showOther(bool); 282 void showOtherCsd(bool); 283 void showWidgetEdit(bool); 284 void toggleLineArea(); 285 void toggleParameterMode(); 286 // void showParametersInEditor(); 287 void onNewConnection(); // when new client is connecting to localServer 288 void onReadyRead(); // when message comes in 289 void disableInternalRtMidi(); 290 void focusToTab(int tab); 291 void ambiguosShortcut(); 292 void testAudioSetup(); 293 void checkSyntaxMenuAction(); 294 getCurrentDocumentPage()295 DocumentPage *getCurrentDocumentPage() { 296 if(curPage >= documentPages.size()) 297 return nullptr; 298 return documentPages[curPage]; 299 } 300 void gotoLineDialog(); 301 302 #ifdef QCS_DEBUGGER 303 void runDebugger(); 304 void stopDebugger(); 305 void pauseDebugger(); 306 void continueDebugger(); 307 void addBreakpoint(int line, int instr, int skip); 308 void addInstrumentBreakpoint(double instr, int skip); 309 void removeBreakpoint(int line, int instr); 310 void removeInstrumentBreakpoint(double instr); 311 #endif 312 private: 313 void createActions(); 314 void setKeyboardShortcutsList(); 315 void connectActions(); 316 QString getExamplePath(QString dir); 317 void createMenus(); 318 void fillFileMenu(); 319 void fillFavoriteMenu(); 320 void fillFavoriteSubMenu(QDir dir, QMenu *m, int depth); 321 void fillScriptsMenu(); 322 void fillScriptsSubMenu(QDir dir, QMenu *m, int depth); 323 void fillEditScriptsSubMenu(QDir dir, QMenu *m, int depth); 324 void createToolBars(); 325 void createStatusBar(); 326 void readSettings(); 327 void storeSettings(); 328 void writeSettings(QStringList openFiles=QStringList(), int lastIndex = 0); 329 void clearSettings(); 330 void setToolbarIconSize(int size); 331 int execute(QString executable, QString options); 332 // bool saveCurrent(); 333 bool makeNewPage(QString fileName, QString text); 334 bool loadCompanionFile(const QString &fileName); 335 void setCurrentFile(const QString &fileName); 336 QString strippedName(const QString &fullFileName); 337 QString generateScript(bool realtime = true, QString tempFileName = "", QString executable = ""); 338 void getCompanionFileName(); 339 void setWidgetPanelGeometry(); 340 int isOpen(QString fileName); // Returns index of document if open -1 if not open 341 // void markErrorLine(); 342 QString getSaveFileName(); 343 void createQuickRefPdf(); 344 void deleteTab(int index = -1); 345 void openLogFile(); 346 void showNewFormatWarning(); 347 void setupEnvironment(); 348 ConfigLists m_configlists; 349 QTabWidget *documentTabs; 350 GraphicWindow *m_graphic; // To display the code graph images 351 QVector<DocumentPage *> documentPages; 352 Options *m_options; 353 DockConsole *m_console; 354 DockHelp *helpPanel; 355 WidgetPanel *widgetPanel; // Dock widget, for containing the widget layout 356 QDockWidget *m_scratchPad; 357 #ifdef USE_QT_GT_53 358 QQuickWidget *m_virtualKeyboard, *m_tableEditor; 359 QPointer <QQuickWidget> m_virtualKeyboardPointer, m_tableEditorPointer; // to control, if the object is deleted 360 #endif 361 #if defined(QCS_QTHTML) 362 public: CsoundHtmlView *csoundHtmlView; 363 #endif 364 private: 365 // QString m_widgetClipboard; 366 Inspector *m_inspector; 367 #ifdef QCS_DEBUGGER 368 DebugPanel *m_debugPanel; 369 CsoundEngine *m_debugEngine; 370 #endif 371 #ifdef QCS_PYTHONQT 372 PythonConsole *m_pythonConsole; 373 #endif 374 MidiHandler *midiHandler; 375 MidiLearnDialog *m_midiLearn; 376 QFile logFile; 377 QVector<QAction *> m_keyActions; //Actions which have keyboard shortcuts 378 QMenu *fileMenu; 379 QMenu *recentMenu; 380 QMenu *templateMenu; 381 QMenu *editMenu; 382 QMenu *controlMenu; 383 QMenu *viewMenu; 384 QMenu *favoriteMenu; 385 QMenu *scriptsMenu; 386 QMenu *helpMenu; 387 // QToolBar *fileToolBar; 388 // QToolBar *editToolBar; 389 QToolBar *controlToolBar; 390 QToolBar *configureToolBar; 391 QAction *newAct; 392 QAction *openAct; 393 QAction *reloadAct; 394 QAction *saveAct; 395 QAction *saveAsAct; 396 QAction *createAppAct; 397 QAction *saveNoWidgetsAct; 398 QAction *closeTabAct; 399 QAction *printAct; 400 QAction *createCodeGraphAct; 401 QAction *infoAct; 402 QAction *exitAct; 403 QList<QAction *> openRecentAct; 404 QAction *undoAct; 405 QAction *redoAct; 406 QAction *cutAct; 407 QAction *copyAct; 408 QAction *pasteAct; 409 QAction *duplicateAct; 410 QAction *joinAct; 411 QAction *evaluateAct; 412 QAction *evaluateSectionAct; 413 QAction *scratchPadCsdModeAct; 414 QAction *getToInAct; 415 QAction *inToGetAct; 416 QAction *csladspaAct; 417 QAction *cabbageAct; 418 QAction *qmlAct; 419 QAction *findAct; 420 QAction *findAgainAct; 421 QAction *configureAct; 422 QAction *setShortcutsAct; 423 QAction *editAct; 424 QAction *runAct; 425 QAction *testAudioSetupAct; 426 QAction *checkSyntaxAct; 427 QAction *runTermAct; 428 QAction *pauseAct; 429 QAction *stopAct; 430 QAction *stopAllAct; 431 QAction *recAct; 432 QAction *renderAct; 433 QAction *externalEditorAct; 434 QAction *externalPlayerAct; 435 QAction *focusEditorAct; 436 QAction *showHelpAct; 437 QAction *raiseHelpAct; 438 QAction *showManualAct; 439 QAction *downloadManualAct; 440 QAction *showGenAct; 441 QAction *showOverviewAct; 442 QAction *showOpcodeQuickRefAct; 443 QAction *showConsoleAct; 444 QAction *raiseConsoleAct; 445 QAction *viewFullScreenAct; 446 QAction *viewEditorFullScreenAct; 447 QAction *viewHtmlFullScreenAct; 448 QAction *viewHelpFullScreenAct; 449 QAction *viewWidgetsFullScreenAct; 450 #ifdef QCS_DEBUGGER 451 QAction *showDebugAct; 452 #endif 453 QAction *showVirtualKeyboardAct; 454 QAction *showTableEditorAct; 455 #if defined(QCS_QTHTML) 456 QAction *showHtml5Act; 457 QAction *raiseHtml5Act; 458 #endif 459 QAction *midiLearnAct; 460 QAction *splitViewAct; 461 QAction *showOrcAct; 462 QAction *showScoreAct; 463 QAction *showOptionsAct; 464 QAction *showFileBAct; 465 QAction *showOtherAct; 466 QAction *showOtherCsdAct; 467 QAction *showWidgetEditAct; 468 QAction *setHelpEntryAct; 469 QAction *browseBackAct; 470 QAction *browseForwardAct; 471 QAction *externalBrowserAct; 472 QAction *openQuickRefAct; 473 QAction *openDocumentationAct; 474 QAction *showUtilitiesAct; 475 QAction *showWidgetsAct; 476 QAction *raiseWidgetsAct; 477 478 QAction *showInspectorAct; 479 QAction *raiseInspectorAct; 480 QAction *showLiveEventsAct; 481 QAction *showPythonConsoleAct; 482 QAction *raisePythonConsoleAct; 483 QAction *showScratchPadAct; 484 QAction *raiseScratchPadAct; 485 QAction *commentAct; 486 // QAction *uncommentAct; 487 QAction *indentAct; 488 QAction *unindentAct; 489 QAction *killLineAct; 490 QAction *killToEndAct; 491 QAction *gotoLineAct; 492 QAction *goBackAct; 493 QAction *aboutAct; 494 QAction *donateAct; 495 // QAction *aboutQtAct; 496 QAction *resetPreferencesAct; 497 QAction *reportBugAct; 498 QAction *requestFeatureAct; 499 QAction *chatAct; 500 QAction *lineNumbersAct; 501 QAction *parameterModeAct; 502 // QAction *showParametersAct; 503 QSignalMapper *focusMapper; 504 int curPage; 505 int curCsdPage; // To recall last csd visited 506 int configureTab; // Tab in last configure dialog accepted 507 QString lastUsedDir; 508 QString lastFileDir; 509 QString quickRefFileName; 510 QStringList recentFiles; 511 QStringList lastFiles; 512 QStringList tempScriptFiles; //Remember temp files to delete them later 513 int lastTabIndex; 514 bool m_resetPrefs; // Flag to reset preferences to default when closing 515 bool m_inspectorNeedsUpdate; 516 bool m_closing; // CsoundQt is closing (to inform timer threads) 517 UtilitiesDialog *utilitiesDialog; 518 QIcon modIcon; 519 QString currentAudioFile; 520 QString initialDir; 521 QMutex closemutex; 522 QLocalServer * m_server; // for receiving 'open file' messages from other instances 523 #ifdef MACOSX_PRE_SNOW 524 MenuBarHandle menuBarHandle; 525 #endif 526 QByteArray m_preFullScreenState; 527 QString m_fullScreenComponent; 528 }; 529 530 class FileOpenEater : public QObject 531 { 532 Q_OBJECT 533 public: FileOpenEater()534 FileOpenEater() {m_mw = 0;} setMainWindow(CsoundQt * mainWindow)535 void setMainWindow(CsoundQt *mainWindow) { 536 m_mw = mainWindow; 537 while (!fileEventQueue.isEmpty()) { 538 QString fileName = fileEventQueue.takeFirst(); 539 qDebug() << "FileOpenEater::setMainWindow opening file " << fileName << endl; 540 m_mw->loadFileFromSystem(fileName); 541 } 542 } 543 QStringList fileEventQueue; 544 protected: eventFilter(QObject * obj,QEvent * event)545 bool eventFilter(QObject *obj, QEvent *event) 546 { 547 if (event->type() == QEvent::FileOpen) { 548 QFileOpenEvent *fileEvent = static_cast<QFileOpenEvent*>(event); 549 if (m_mw == 0) { 550 fileEventQueue << fileEvent->file(); 551 } 552 else { 553 m_mw->loadFileFromSystem(fileEvent->file()); 554 } 555 qDebug() << "FileOpenEater::eventFilter " << fileEvent->file(); 556 return true; 557 } else { 558 // standard event processing 559 return QObject::eventFilter(obj, event); 560 } 561 } 562 563 CsoundQt *m_mw; 564 }; 565 566 #endif 567