1 //=========================================================
2 //  MusE
3 //  Linux Music Editor
4 //  $Id: app.h,v 1.34.2.14 2009/11/16 11:29:33 lunar_shuttle Exp $
5 //
6 //  (C) Copyright 1999-2004 Werner Schweer (ws@seh.de)
7 //  (C) Copyright 2016 Tim E. Real (terminator356 on sourceforge)
8 //
9 //  This program is free software; you can redistribute it and/or
10 //  modify it under the terms of the GNU General Public License
11 //  as published by the Free Software Foundation; version 2 of
12 //  the License, or (at your option) any later version.
13 //
14 //  This program is distributed in the hope that it will be useful,
15 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 //  GNU General Public License for more details.
18 //
19 //  You should have received a copy of the GNU General Public License
20 //  along with this program; if not, write to the Free Software
21 //  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
22 //
23 //=========================================================
24 
25 #ifndef __APP_H__
26 #define __APP_H__
27 
28 #include "config.h"
29 #include "globaldefs.h"
30 #include "cobject.h"
31 
32 #include <QFileInfo>
33 #include <QMainWindow>
34 #include <QRect>
35 #include <QString>
36 #include <QPointer>
37 
38 #include <list>
39 #include <time.h>
40 #include <sys/time.h>
41 #if defined(__FreeBSD__)
42 #include <unistd.h>
43 #endif
44 
45 
46 // Forward declarations:
47 class QCloseEvent;
48 class QMenu;
49 class QToolBar;
50 class QToolButton;
51 class QProgressDialog;
52 class QTimer;
53 class QMdiSubWindow;
54 class MuseMdiArea;
55 class QDockWidget;
56 
57 namespace MusECore {
58 class AudioOutput;
59 class MidiInstrument;
60 class MidiPort;
61 class MidiTrack;
62 class Part;
63 class PartList;
64 class SynthI;
65 class Track;
66 class Undo;
67 class WaveTrack;
68 class Xml;
69 }
70 
71 namespace MusEGui {
72 class Appearance;
73 class Arranger;
74 class ArrangerView;
75 class AudioMixerApp;
76 class BigTime;
77 class ClipListEdit;
78 class EditInstrument;
79 class EditToolBar;
80 class GlobalSettingsConfig;
81 class MRConfig;
82 class MarkerView;
83 class LMaster;
84 class MetronomeConfig;
85 class MidiFileConfig;
86 class MidiFilterConfig;
87 class MidiInputTransformDialog;
88 class MidiSyncConfig;
89 class MidiTransformerDialog;
90 class RhythmGen;
91 class ScoreEdit;
92 class ShortcutConfig;
93 class TopWin;
94 class TopLevelList;
95 class Transport;
96 class VisibleTracks;
97 class RouteDialog;
98 class CpuToolbar;
99 class CpuStatusBar;
100 class SnooperDialog;
101 class MasterEdit;
102 
103 #define MENU_ADD_SYNTH_ID_BASE 0x8000
104 
105 
106 //---------------------------------------------------------
107 //   MusE
108 //---------------------------------------------------------
109 
110 class MusE : public QMainWindow
111 {
112     Q_OBJECT
113     enum {CMD_FOLLOW_NO, CMD_FOLLOW_JUMP, CMD_FOLLOW_CONTINUOUS };
114 
115     //File menu items:
116     enum { CMD_OPEN_RECENT=0, CMD_LOAD_TEMPLATE, CMD_SAVE_AS, CMD_IMPORT_MIDI,
117            CMD_EXPORT_MIDI, CMD_IMPORT_PART, CMD_IMPORT_AUDIO, CMD_QUIT, CMD_OPEN_DRUMS, CMD_OPEN_WAVE,
118            CMD_OPEN_LIST, CMD_OPEN_LIST_MASTER, CMD_GLOBAL_CONFIG,
119            CMD_OPEN_GRAPHIC_MASTER, CMD_OPEN_MIDI_TRANSFORM, CMD_TRANSPOSE,
120            CMD_GLOBAL_CUT, CMD_GLOBAL_INSERT, CMD_GLOBAL_SPLIT, CMD_COPY_RANGE,
121            CMD_CUT_EVENTS, CMD_CONFIG_SHORTCUTS, CMD_CONFIG_METRONOME, CMD_CONFIG_MIDISYNC,
122            CMD_MIDI_FILE_CONFIG, CMD_APPEARANCE_SETTINGS, CMD_CONFIG_MIDI_PORTS, CMD_CONFIG_AUDIO_PORTS,
123            CMD_MIDI_EDIT_INSTRUMENTS, CMD_MIDI_RESET, CMD_MIDI_INIT, CMD_MIDI_LOCAL_OFF,
124            CMD_MIXER_SNAPSHOT, CMD_MIXER_AUTOMATION_CLEAR, CMD_OPEN_HELP, CMD_OPEN_HOMEPAGE,
125            CMD_OPEN_BUG, CMD_START_WHATSTHIS,
126            CMD_AUDIO_BOUNCE_TO_FILE, CMD_AUDIO_BOUNCE_TO_TRACK, CMD_AUDIO_RESTART,
127            CMD_LAST };
128 
129     // File menu actions
130     QAction *fileSaveAction, *fileOpenAction, *fileNewAction, *fileNewFromTemplateAction;
131     QAction *fileSaveRevisionAction, *fileSaveAsAction, *fileSaveAsNewProjectAction, *fileSaveAsTemplateAction;
132     QAction *fileImportMidiAction, *fileExportMidiAction;
133     QAction *fileImportPartAction, *fileImportWaveAction, *fileMoveWaveFiles, *quitAction;
134     QAction *fileCloseAction;
135     QAction *editSongInfoAction;
136 
137     MuseMdiArea* mdiArea;
138 
139     TopWin* activeTopWin;
140     TopWin* currentMenuSharingTopwin;
141     TopWin* waitingForTopwin;
142 
143     std::list<QToolBar*> requiredToolbars; //always displayed
144     std::list<QToolBar*> optionalToolbars; //only displayed when no toolbar-sharing window is active
145     std::list<QToolBar*> foreignToolbars;  //holds a temporary list of the toolbars of a toolbar-sharer
146     std::list<QMenu*> leadingMenus;
147     std::list<QMenu*> trailingMenus;
148 
149     QList<QDockWidget *> hiddenDocks;
150 
151     // View Menu actions
152     QAction *viewTransportAction, *viewBigtimeAction, *viewMixerAAction, *viewMixerBAction, *viewCliplistAction, *viewMarkerAction;
153     QAction *fullscreenAction, *toggleDocksAction;
154     QAction *masterGraphicAction, *masterListAction;
155 
156     // Midi Menu Actions
157     QAction *midiEditInstAction, *midiResetInstAction, *midiInitInstActions, *midiLocalOffAction;
158     QAction *midiTrpAction, *midiInputTrfAction, *midiInputFilterAction, *midiRemoteAction;
159 #ifdef BUILD_EXPERIMENTAL
160     QAction *midiRhythmAction;
161 #endif
162 
163     // Audio Menu Actions
164     QAction *audioBounce2TrackAction, *audioBounce2FileAction, *audioRestartAction;
165 
166     // Automation Menu Actions
167     // REMOVE Tim. automation. Removed.
168     // Deprecated. MusEGlobal::automation is now fixed TRUE
169     //  for now until we decide what to do with it.
170     //       QAction *autoMixerAction;
171     QAction *autoSnapshotAction, *autoClearAction;
172 
173     // Settings Menu Actions
174     QAction *settingsGlobalAction, *settingsShortcutsAction, *settingsMetronomeAction, *settingsMidiSyncAction;
175     QAction *settingsMidiIOAction, *settingsAppearanceAction, *settingsMidiPortAction;
176     QAction *dontFollowAction, *followPageAction, *followCtsAction;
177     QAction *rewindOnStopAction;
178     // Help Menu Actions
179     QAction *helpManualAction, *helpHomepageAction, *helpReportAction, *helpAboutAction, *helpDidYouKnow, *helpSnooperAction;
180 
181     QString appName;
182 
183     QFileInfo project;
184     QString _lastProjectFilePath;
185     bool _lastProjectWasTemplate;
186     bool _lastProjectLoadedConfig;
187     QToolBar *tools;
188     CpuToolbar* cpuLoadToolbar;
189     CpuStatusBar* cpuStatusBar;
190 
191     // when adding a toolbar to the main window, remember adding it to
192     // either the requiredToolbars or optionalToolbars list!
193 
194     Transport* transport;
195     BigTime* bigtime;
196     EditInstrument* editInstrument;
197 
198     // when adding a menu to the main window, remember adding it to
199     // either the leadingMenus or trailingMenus list!
200     QMenu *menu_file, *menuView, *menuSettings, *menuWindows, *menu_help;
201     QMenu* menu_audio, *menuUtils;
202     QMenu* menu_functions; // *menuScriptPlugins;
203 
204     QMenu* follow;
205 //    QMenu* midiInputPlugins;
206 
207     QWidget* midiPortConfig;
208     QWidget* softSynthesizerConfig;
209     MidiSyncConfig* midiSyncConfig;
210     MRConfig* midiRemoteConfig;
211 #ifdef BUILD_EXPERIMENTAL
212     RhythmGen* midiRhythmGenerator;
213 #endif
214     MetronomeConfig* metronomeConfig;
215     MidiFileConfig* midiFileConfig;
216     GlobalSettingsConfig* globalSettingsConfig;
217     MidiFilterConfig* midiFilterConfig;
218     MidiInputTransformDialog* midiInputTransform;
219     ShortcutConfig* shortcutConfig;
220     Appearance* appearance;
221     SnooperDialog* _snooperDialog;
222     AudioMixerApp* mixer1;
223     AudioMixerApp* mixer2;
224     RouteDialog* routeDialog;
225     // NOTE: For deleting parentless dialogs and widgets, please add them to deleteParentlessDialogs().
226     void deleteParentlessDialogs();
227 
228     Arranger* _arranger;
229     ToplevelList toplevels;
230     ClipListEdit* clipListEdit;
231     QDockWidget* clipListDock;
232     MarkerView* markerView;
233     QDockWidget* markerDock;
234     LMaster* masterList;
235     QDockWidget* masterListDock;
236     ArrangerView* arrangerView;
237     MidiTransformerDialog* midiTransformerDialog;
238     QMenu* openRecent;
239     QPointer<MasterEdit> masterEditor;
240 
241     bool writeTopwinState;
242     // Set to restart MusE (almost) from scratch before calling close().
243     bool _isRestartingApp;
244 
245     bool readMidi(FILE*);
246     void read(MusECore::Xml& xml, bool doReadMidiPorts, bool isTemplate);
247     void processTrack(MusECore::MidiTrack* track);
248 
249     void write(MusECore::Xml& xml, bool writeTopwins) const;
250     // If clear_all is false, it will not touch things like midi ports.
251     bool clearSong(bool clear_all = true);
252     bool save(const QString&, bool overwriteWarn, bool writeTopwins);
253     void setUntitledProject();
254     void setConfigDefaults();
255 
256     void readConfigParts(MusECore::Xml& xml);
257     void readToplevels(MusECore::Xml& xml);
258     MusECore::PartList* getMidiPartsToEdit();
259     MusECore::Part* readPart(MusECore::Xml& xml);
260     bool checkRegionNotNull();
261     void loadProjectFile1(const QString&, bool songTemplate, bool doReadMidiPorts);
262     // Write global configuration.
263     void writeGlobalConfiguration(int level, MusECore::Xml&) const;
264     // Write song specific configuration.
265     void writeConfiguration(int level, MusECore::Xml&) const;
266     void updateConfiguration();
267     QString projectTitle(QString name);
268     void toggleTrackArmSelectedTrack();
269     void centerAndResize();
270     void closeDocks();
271     void addTabbedDock(Qt::DockWidgetArea area, QDockWidget *widget);
272     void saveStateExtra();
273     void saveStateTopLevels();
274     bool findOpenEditor(const TopWin::ToplevelType type, MusECore::PartList* pl);
275     bool findOpenListEditor(MusECore::PartList* pl);
276     bool filterInvalidParts(const TopWin::ToplevelType type, MusECore::PartList* pl);
277     void updateStatusBar();
278     void setAndAdjustFonts();
279 
280     QTimer *saveTimer;
281     QTimer *blinkTimer;
282     QTimer *messagePollTimer;
283     int saveIncrement;
284 
285     timeval lastCpuTime;
286     timespec lastSysTime;
287     float fAvrCpuLoad;
288     int avrCpuLoadCounter;
289     float fCurCpuLoad;
290 
291 signals:
292     void configChanged();
293     void activeTopWinChanged(MusEGui::TopWin*);
294     void blinkTimerToggled(bool state);
295 
296 private slots:
297     void heartBeat();
298     void blinkTimerSlot();
299     void saveTimerSlot();
300     void messagePollTimerSlot();
301     void loadProject();
302     bool save();
303     void configGlobalSettings();
304     void quitDoc();
305     void about();
306     void aboutQt();
307     void startHelpBrowser();
308     void startHomepageBrowser();
309     void startBugBrowser();
310     void importMidi();
311     void importWave();
312     void importPart();
313     void exportMidi();
314     void findUnusedWaveFiles();
315 
316     void toggleTransport(bool);
317     void toggleBigTime(bool);
318     void toggleMixer1(bool);
319     void toggleMixer2(bool);
320 
321     void configMidiSync();
322     void configMidiFile();
323     void configShortCuts();
324     void configShortCutsSaveConfig();
325     void configMetronome();
326     void configAppearance();
327 
328     void startSongInfo(bool editable=true);
329 
330     void writeGlobalConfiguration() const;
331     void showClipList(bool);
332 
333     void openRecentMenu();
334     void selectProject(QAction* act);
335     void cmd(int);
336 
337     void startMidiInputPlugin(int);
338     void hideMitPluginTranspose();
339     void hideMidiInputTransform();
340     void hideMidiFilterConfig();
341     void hideMidiRemoteConfig();
342 #ifdef BUILD_EXPERIMENTAL
343     void hideMidiRhythmGenerator();
344 #endif
345     void resetMidiDevices();
346     void initMidiDevices();
347     void localOff();
348     void switchMixerAutomation();
349     void takeAutomationSnapshot();
350     void clearAutomation();
351     void bigtimeClosed();
352     void mixer1Closed();
353     void mixer2Closed();
354 
355     void activeTopWinChangedSlot(MusEGui::TopWin*);
356     void setCurrentMenuSharingTopwin(MusEGui::TopWin*);
357 
358     void bringToFront(QWidget* win);
359     void setFullscreen(bool);
360     void setDirty();
361     void toggleRewindOnStop(bool);
362     void toggleDocks(bool show);
363 
364 public slots:
365     void saveNewRevision();
366     void saveAsNewProject();
367     bool saveAs(bool overrideProjectSaveDialog = false);
368     void saveAsTemplate();
369     void bounceToFile(MusECore::AudioOutput* ao = nullptr);
370     void bounceToTrack(MusECore::AudioOutput* ao = nullptr);
371     void closeEvent(QCloseEvent*event) override;
372     void loadProjectFile(const QString&);
373     void loadProjectFile(const QString&, bool songTemplate, bool doReadMidiPorts);
374     void fileClose();
375     void toplevelDeleting(MusEGui::TopWin* tl);
376     bool seqRestart();
377     void loadTemplate();
378     void loadDefaultTemplate();
379     void showBigtime(bool);
380     void showMixer1(bool);
381     void showMixer2(bool);
382     void startRouteDialog();
383     void showMarker(bool);
384     void importMidi(const QString &file);
385     void showDidYouKnowDialogIfEnabled();
386     void showDidYouKnowDialog();
387     void startEditInstrument(const QString& find_instrument = QString(), EditInstrumentTabType show_tab = EditInstrumentPatches);
388     void configMidiPorts();
389 
390     void startEditor(MusECore::PartList*, int);
391     void startScoreQuickly();
392     void startPianoroll(bool newwin = false);
393     void startPianoroll(MusECore::PartList* pl, bool showDefaultCtrls = false, bool newwin = false);
394     void startWaveEditor(bool newwin = false);
395     void startWaveEditor(MusECore::PartList*, bool newwin = false);
396     void openInScoreEdit(ScoreEdit* destination, MusECore::PartList* pl, bool allInOne=false);
397     void openInScoreEdit(ScoreEdit* destination, bool allInOne=false);
398     void openInScoreEdit_allInOne(QWidget* destination);
399     void openInScoreEdit_oneStaffPerTrack(QWidget* destination);
400     void startMasterEditor();
401     void showMasterList(bool);
402     void startListEditor(bool newwin = false);
403     void startListEditor(MusECore::PartList*, bool newwin = false);
404     void startDrumEditor(bool newwin = false);
405     void startDrumEditor(MusECore::PartList* pl, bool showDefaultCtrls = false, bool newwin = false);
406     void startEditor(MusECore::Track*);
407     void startMidiTransformer();
408     void startSnooper();
409 
410     void focusChanged(QWidget* old, QWidget* now);
411 
412     void addMdiSubWindow(QMdiSubWindow*);
413     void shareMenuAndToolbarChanged(MusEGui::TopWin*, bool);
414     void topwinMenuInited(MusEGui::TopWin*);
415     void setActiveMdiSubWindow(QMdiSubWindow*);
416 
417 
418     void updateWindowMenu();
419 
420     void resetXrunsCounter();
421 
422     bool startPythonBridge();
423     bool stopPythonBridge();
424 
425     void addProjectToRecentList(const QString& name);
426     void saveProjectRecentList();
427 
428 public:
429     MusE();
430 
431     void populateAddTrack();
432 
433     // Loads a default song according to settings, or filename_override if not empty.
434     // If filename_override is not empty, use_template and load_config are used.
435     void loadDefaultSong(const QString& filename_override, bool use_template, bool load_config);
436     bool loadConfigurationColors(QWidget* parent = 0);
437     bool saveConfigurationColors(QWidget* parent = 0);
438     // Whether to restart MusE (almost) from scratch when calling close().
restartingApp()439     bool restartingApp() const { return _isRestartingApp;}
440     // Set to restart MusE (almost) from scratch before calling close().
setRestartingApp(bool v)441     void setRestartingApp(bool v) { _isRestartingApp = v;}
arranger()442     Arranger* arranger() const { return _arranger; }
443     int arrangerRaster() const;
444     int currentPartColorIndex() const;
445 
getArrangerView()446     ArrangerView* getArrangerView() const { return arrangerView; }
447     QRect configGeometryMain;
448     QProgressDialog *progress;
449     bool importMidi(const QString name, bool merge);
450     void kbAccel(int);
451 
452     // writeFlag: Write to configuration file.
453     void changeConfig(bool writeFlag);
454 
455     void seqStop();
456     bool seqStart();
457     // Starts the ALSA midi portion of the sequencer. audioDevice must be valid.
458     // Returns true if successful or already running.
459     //       bool seqStartMidi();
460     void setHeartBeat();
461     void stopHeartBeat();
462     void importController(int, MusECore::MidiPort*, int);
projectFileInfo()463     const QFileInfo& projectFileInfo() const { return project; }
lastProjectFilePath()464     QString lastProjectFilePath() const { return _lastProjectFilePath; };
lastProjectWasTemplate()465     bool lastProjectWasTemplate() const { return _lastProjectWasTemplate; }
lastProjectLoadedConfig()466     bool lastProjectLoadedConfig() const { return _lastProjectLoadedConfig; }
467     QString projectTitle() const;
468     QString projectPath() const;
469     QString projectExtension() const;
470     QWidget* mixer1Window();
471     QWidget* mixer2Window();
472     QWidget* transportWindow();
473     QWidget* bigtimeWindow();
474     bool importWaveToTrack(QString& name, unsigned tick=0, MusECore::Track* track=NULL);
475     void importPartToTrack(QString& filename, unsigned tick, MusECore::Track* track);
476     void showTransport(bool flag);
477     bool restoreState(const QByteArray &state, int version = 0);
478 
getToplevels()479     const ToplevelList* getToplevels() { return &toplevels; }
480 
getCurrentMenuSharingTopwin()481     TopWin* getCurrentMenuSharingTopwin() { return currentMenuSharingTopwin; }
482 
483     float getCPULoad();
484     void initStatusBar();
485     void setStatusBarText(const QString &message, int timeout = 0);
486     void clearStatusBarText();
487 
488     void launchBrowser(QString &whereTo);
489 
490     QMenu* createPopupMenu() override;
491 
492 #ifdef HAVE_LASH
493     void lash_idle_cb ();
494 #endif
495 };
496 
497 extern void addProject(const QString& name);
498 
499 } // namespace MusEGui
500 
501 #endif // __APP_H__
502