MainWindowBase.h
Go to the documentation of this file.
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2 
3 /*
4  Sonic Visualiser
5  An audio file viewer and annotation editor.
6  Centre for Digital Music, Queen Mary, University of London.
7  This file copyright 2006-2007 Chris Cannam and QMUL.
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 as
11  published by the Free Software Foundation; either version 2 of the
12  License, or (at your option) any later version. See the file
13  COPYING included with this distribution for more information.
14 */
15 
16 #ifndef SV_MAIN_WINDOW_BASE_H
17 #define SV_MAIN_WINDOW_BASE_H
18 
19 #include <QFrame>
20 #include <QString>
21 #include <QUrl>
22 #include <QMainWindow>
23 #include <QPointer>
24 #include <QThread>
25 
26 #include "base/Command.h"
27 #include "view/ViewManager.h"
28 #include "view/PaneStack.h"
29 #include "base/PropertyContainer.h"
30 #include "base/RecentFiles.h"
31 #include "base/FrameTimer.h"
32 #include "layer/LayerFactory.h"
33 #include "transform/Transform.h"
34 #include "SVFileReader.h"
35 #include "data/fileio/FileFinder.h"
36 #include "data/fileio/FileSource.h"
37 #include "data/osc/OSCQueue.h"
38 #include "data/osc/OSCMessageCallback.h"
39 #include "data/model/Model.h"
40 
41 #include <map>
42 
43 class Document;
44 class PaneStack;
45 class Pane;
46 class View;
47 class Fader;
48 class Overview;
49 class Layer;
50 class WaveformLayer;
51 class WaveFileModel;
52 class AudioCallbackPlaySource;
53 class TimeStretchWrapper;
54 class AudioCallbackRecordTarget;
55 class CommandHistory;
56 class QMenu;
57 class AudioDial;
58 class LevelPanWidget;
59 class LevelPanToolButton;
60 class QLabel;
61 class QCheckBox;
62 class PreferencesDialog;
63 class QTreeView;
64 class QPushButton;
65 class OSCMessage;
66 class OSCScript;
67 class MIDIInput;
68 class KeyReference;
69 class Labeller;
70 class ModelDataTableDialog;
71 class QSignalMapper;
72 class QShortcut;
73 class AlignmentModel;
74 class LayerGeometryProvider;
75 
76 namespace breakfastquay {
77  class SystemPlaybackTarget;
78  class SystemAudioIO;
79 }
80 
90 class MainWindowBase : public QMainWindow,
91  public FrameTimer,
92  public OSCMessageCallback
93 {
94  Q_OBJECT
95 
96 public:
101  enum AudioMode {
102 
105 
108 
111 
113  AUDIO_PLAYBACK_AND_RECORD
114  };
115 
119  enum MIDIMode {
120 
123 
125  MIDI_LISTEN
126  };
127 
128  MainWindowBase(AudioMode audioMode, MIDIMode midiMode,
129  PaneStack::Options paneStackOptions);
130  virtual ~MainWindowBase();
131 
137  AskUser
138  };
139 
144  FileOpenWrongMode // attempted to open layer when no main model present
145  };
146 
149  RecordCreateAdditionalModel
150  };
151 
152  virtual FileOpenStatus open(FileSource source, AudioFileOpenMode = AskUser);
153  virtual FileOpenStatus openPath(QString fileOrUrl, AudioFileOpenMode = AskUser);
154  virtual FileOpenStatus openAudio(FileSource source, AudioFileOpenMode = AskUser, QString templateName = "");
155  virtual FileOpenStatus openPlaylist(FileSource source, AudioFileOpenMode = AskUser);
156  virtual FileOpenStatus openLayer(FileSource source);
157  virtual FileOpenStatus openImage(FileSource source);
158 
159  virtual FileOpenStatus openDirOfAudio(QString dirPath);
160 
161  virtual FileOpenStatus openSession(FileSource source);
162  virtual FileOpenStatus openSessionPath(QString fileOrUrl);
163  virtual FileOpenStatus openSessionTemplate(QString templateName);
164  virtual FileOpenStatus openSessionTemplate(FileSource source);
165 
166  virtual bool saveSessionFile(QString path);
167  virtual bool saveSessionTemplate(QString path);
168 
169  virtual bool exportLayerToSVL(Layer *layer,
170  QString toPath, QString &error);
171 
172  virtual bool exportLayerToMIDI(Layer *layer,
173  MultiSelection *selectionsToWrite, // or null
174  QString toPath, QString &error);
175 
176  virtual bool exportLayerToRDF(Layer *layer,
177  QString toPath, QString &error);
178 
179  virtual bool exportLayerToCSV(Layer *layer, LayerGeometryProvider *provider,
180  MultiSelection *selectionsToWrite, // or null
181  QString delimiter,
182  DataExportOptions options,
183  QString toPath, QString &error);
184 
185  // Delegate to one of the above depending on extension of path,
186  // using the default export options
187  virtual bool exportLayerTo(Layer *layer, LayerGeometryProvider *provider,
188  MultiSelection *selectionsToWrite, // or null
189  QString toPath, QString &error);
190 
191  void cueOSCScript(QString filename);
192 
194  sv_frame_t getFrame() const override;
195 
196  void setDefaultFfwdRwdStep(RealTime step) {
197  m_defaultFfwdRwdStep = step;
198  }
199 
201  m_audioRecordMode = mode;
202  }
203 
204 signals:
205  // Used to toggle the availability of menu actions
206  void canAddPane(bool);
207  void canDeleteCurrentPane(bool);
208  void canAddLayer(bool);
209  void canImportMoreAudio(bool);
210  void canReplaceMainAudio(bool);
211  void canImportLayer(bool);
212  void canChangeSessionTemplate(bool);
213  void canExportAudio(bool);
214  void canExportLayer(bool);
215  void canExportImage(bool);
216  void canRenameLayer(bool);
217  void canEditLayer(bool);
218  void canEditLayerTabular(bool);
219  void canMeasureLayer(bool);
220  void canSelect(bool);
221  void canClearSelection(bool);
222  void canEditSelection(bool);
223  void canDeleteSelection(bool);
224  void canPaste(bool);
225  void canInsertInstant(bool);
226  void canInsertInstantsAtBoundaries(bool);
227  void canInsertItemAtSelection(bool);
228  void canRenumberInstants(bool);
229  void canSubdivideInstants(bool);
230  void canWinnowInstants(bool);
231  void canDeleteCurrentLayer(bool);
232  void canZoom(bool);
233  void canScroll(bool);
234  void canPlay(bool);
235  void canRecord(bool);
236  void canFfwd(bool);
237  void canRewind(bool);
238  void canPlaySelection(bool);
239  void canSpeedUpPlayback(bool);
240  void canSlowDownPlayback(bool);
241  void canChangePlaybackSpeed(bool);
242  void canSelectPreviousPane(bool);
243  void canSelectNextPane(bool);
244  void canSelectPreviousLayer(bool);
245  void canSelectNextLayer(bool);
246  void canSave(bool);
247  void canSaveAs(bool);
248  void hideSplash();
249  void hideSplash(QWidget *);
250  void sessionLoaded();
251  void audioFileLoaded();
252  void replacedDocument();
253  void activity(QString);
254 
255 public slots:
256  virtual void preferenceChanged(PropertyContainer::PropertyName);
257  virtual void resizeConstrained(QSize);
258  virtual void recreateAudioIO();
259 
260 protected slots:
261  virtual void zoomIn();
262  virtual void zoomOut();
263  virtual void zoomToFit();
264  virtual void zoomDefault();
265  virtual void scrollLeft();
266  virtual void scrollRight();
267  virtual void jumpLeft();
268  virtual void jumpRight();
269  virtual void peekLeft();
270  virtual void peekRight();
271 
272  virtual void showNoOverlays();
273  virtual void showMinimalOverlays();
274  virtual void showAllOverlays();
275 
276  virtual void toggleTimeRulers();
277  virtual void toggleZoomWheels();
278  virtual void togglePropertyBoxes();
279  virtual void toggleStatusBar();
280  virtual void toggleCentreLine();
281 
282  virtual void play();
283  virtual void ffwd();
284  virtual void ffwdEnd();
285  virtual void rewind();
286  virtual void rewindStart();
287  virtual void record();
288  virtual void stop();
289 
290  virtual void ffwdSimilar();
291  virtual void rewindSimilar();
292 
293  virtual void deleteCurrentPane();
294  virtual void deleteCurrentLayer();
295  virtual void editCurrentLayer();
296 
297  virtual void previousPane();
298  virtual void nextPane();
299  virtual void previousLayer();
300  virtual void nextLayer();
301 
302  virtual void playLoopToggled();
303  virtual void playSelectionToggled();
304  virtual void playSoloToggled();
305 
306  virtual void audioChannelCountIncreased(int count);
307 
308  virtual void sampleRateMismatch(sv_samplerate_t, sv_samplerate_t, bool) = 0;
309  virtual void audioOverloadPluginDisabled() = 0;
310 
311  virtual void playbackFrameChanged(sv_frame_t);
312  virtual void globalCentreFrameChanged(sv_frame_t);
313  virtual void viewCentreFrameChanged(View *, sv_frame_t);
314  virtual void viewZoomLevelChanged(View *, ZoomLevel, bool);
315  virtual void monitoringLevelsChanged(float, float) = 0;
316  virtual void recordDurationChanged(sv_frame_t, sv_samplerate_t);
317 
318  virtual void currentPaneChanged(Pane *);
319  virtual void currentLayerChanged(Pane *, Layer *);
320 
321  virtual void selectAll();
322  virtual void selectToStart();
323  virtual void selectToEnd();
324  virtual void selectVisible();
325  virtual void clearSelection();
326 
327  virtual void cut();
328  virtual void copy();
329  virtual void paste();
330  virtual void pasteAtPlaybackPosition();
331  virtual void pasteRelative(sv_frame_t offset);
332  virtual void deleteSelected();
333 
334  virtual void insertInstant();
335  virtual void insertInstantAt(sv_frame_t);
336  virtual void insertInstantsAtBoundaries();
337  virtual void insertItemAtSelection();
338  virtual void insertItemAt(sv_frame_t, sv_frame_t);
339  virtual void renumberInstants();
340  virtual void subdivideInstantsBy(int);
341  virtual void winnowInstantsBy(int);
342 
343  virtual void documentModified();
344  virtual void documentRestored();
345 
346  virtual void layerAdded(Layer *);
347  virtual void layerRemoved(Layer *);
348  virtual void layerAboutToBeDeleted(Layer *);
349  virtual void layerInAView(Layer *, bool);
350 
351  virtual void mainModelChanged(ModelId);
352  virtual void modelAdded(ModelId);
353 
354  virtual void updateMenuStates();
355  virtual void updateDescriptionLabel() = 0;
356  virtual void updateWindowTitle();
357 
358  virtual void modelGenerationFailed(QString, QString) = 0;
359  virtual void modelGenerationWarning(QString, QString) = 0;
360  virtual void modelRegenerationFailed(QString, QString, QString) = 0;
361  virtual void modelRegenerationWarning(QString, QString, QString) = 0;
362 
363  virtual void alignmentComplete(ModelId);
364  virtual void alignmentFailed(ModelId, QString) = 0;
365 
366  virtual void paneRightButtonMenuRequested(Pane *, QPoint point) = 0;
367  virtual void panePropertiesRightButtonMenuRequested(Pane *, QPoint point) = 0;
368  virtual void layerPropertiesRightButtonMenuRequested(Pane *, Layer *, QPoint point) = 0;
369 
370  virtual void paneAdded(Pane *) = 0;
371  virtual void paneHidden(Pane *) = 0;
372  virtual void paneAboutToBeDeleted(Pane *) = 0;
373  virtual void paneDropAccepted(Pane *, QStringList) = 0;
374  virtual void paneDropAccepted(Pane *, QString) = 0;
375  virtual void paneDeleteButtonClicked(Pane *);
376 
377  virtual void oscReady();
378  virtual void pollOSC();
379  virtual void oscScriptFinished();
380 
381  virtual void contextHelpChanged(const QString &);
382  virtual void inProgressSelectionChanged();
383 
384  virtual FileOpenStatus openSessionFromRDF(FileSource source);
385  virtual FileOpenStatus openLayersFromRDF(FileSource source);
386 
387  virtual void closeSession() = 0;
388 
389  virtual void emitHideSplash();
390 
391  virtual void newerVersionAvailable(QString) { }
392 
393  virtual void menuActionMapperInvoked(QObject *);
394 
395 protected:
396  QString m_sessionFile;
397  QString m_audioFile;
399 
400  // This is used in the window title. It's the upstream location
401  // (maybe a URL) the user provided as source of the main model. It
402  // should be set in cases where there is no current session file
403  // and m_sessionFile is empty, or where a new main model has been
404  // imported into an existing session. It should be used only for
405  // user presentation, never parsed - treat it as an opaque label
407 
408  PaneStack *m_paneStack;
409  ViewManager *m_viewManager;
411 
414 
415  AudioCallbackPlaySource *m_playSource;
416  AudioCallbackRecordTarget *m_recordTarget;
417  breakfastquay::SystemPlaybackTarget *m_playTarget; // only one of this...
418  breakfastquay::SystemAudioIO *m_audioIO; // ... and this exists
419 
420  class OSCQueueStarter : public QThread
421  {
422  public:
423  OSCQueueStarter(MainWindowBase *mwb, bool withNetworkPort) :
424  QThread(mwb), m_mwb(mwb), m_withPort(withNetworkPort) { }
425 
426  void run() override {
427  // NB creating the queue object can take a long time
428  OSCQueue *queue = new OSCQueue(m_withPort);
429  m_mwb->m_oscQueue = queue;
430  }
431 
432  private:
435  };
436 
437  OSCQueue *m_oscQueue;
441 
442  void startOSCQueue(bool withNetworkPort);
443  void startOSCScript();
444 
445  MIDIInput *m_midiInput;
446 
447  RecentFiles m_recentFiles;
448  RecentFiles m_recentTransforms;
449 
453 
454  Labeller *m_labeller;
455 
457  mutable QString m_myStatusMessage;
458 
460 
462 
464 
465  mutable QLabel *m_statusLabel;
466  QLabel *getStatusLabel() const;
467 
468  ModelId getMainModelId() const;
469  std::shared_ptr<WaveFileModel> getMainModel() const;
470  void createDocument();
471 
472  FileOpenStatus addOpenedAudioModel(FileSource source,
473  ModelId model,
474  AudioFileOpenMode mode,
475  QString templateName,
476  bool registerSource);
477 
478  sv_frame_t getModelsStartFrame() const; // earliest across all views
479  sv_frame_t getModelsEndFrame() const; // latest across all views
480 
481  Pane *addPaneToStack();
482  Layer *getSnapLayer() const;
483 
484  typedef std::map<Layer *, QPointer<ModelDataTableDialog> > LayerDataDialogMap;
485  typedef std::set<QPointer<ModelDataTableDialog> > DataDialogSet;
486  typedef std::map<View *, DataDialogSet> ViewDataDialogMap;
487 
488  LayerDataDialogMap m_layerDataDialogMap;
489  ViewDataDialogMap m_viewDataDialogMap;
490 
491  void removeLayerEditDialog(Layer *);
492 
494  {
495  public:
496  PaneCallback(MainWindowBase *mw) : m_mw(mw) { }
497  Pane *addPane() override { return m_mw->addPaneToStack(); }
498  void setWindowSize(int width, int height) override {
499  m_mw->resizeConstrained(QSize(width, height));
500  }
501  void addSelection(sv_frame_t start, sv_frame_t end) override {
502  m_mw->m_viewManager->addSelectionQuietly(Selection(start, end));
503  }
504  protected:
506  };
507 
508  class AddPaneCommand : public Command
509  {
510  public:
512  virtual ~AddPaneCommand();
513 
514  void execute() override;
515  void unexecute() override;
516  QString getName() const override;
517 
518  Pane *getPane() { return m_pane; }
519 
520  protected:
522  Pane *m_pane; // Main window owns this, but I determine its lifespan
523  Pane *m_prevCurrentPane; // I don't own this
524  bool m_added;
525  };
526 
527  class RemovePaneCommand : public Command
528  {
529  public:
530  RemovePaneCommand(MainWindowBase *mw, Pane *pane);
531  virtual ~RemovePaneCommand();
532 
533  void execute() override;
534  void unexecute() override;
535  QString getName() const override;
536 
537  protected:
539  Pane *m_pane; // Main window owns this, but I determine its lifespan
540  Pane *m_prevCurrentPane; // I don't own this
541  bool m_added;
542  };
543 
544  virtual bool checkSaveModified() = 0;
545 
546  virtual QString getOpenFileName(FileFinder::FileType type);
547  virtual QString getSaveFileName(FileFinder::FileType type);
548  virtual void registerLastOpenedFilePath(FileFinder::FileType type, QString path);
549 
550  virtual QString getDefaultSessionTemplate() const;
551  virtual void setDefaultSessionTemplate(QString);
552 
553  virtual void findTimeRulerLayer();
554 
555  virtual void createAudioIO();
556  virtual void deleteAudioIO();
557 
558  virtual void openHelpUrl(QString url);
559  virtual void openLocalFolder(QString path);
560 
561  virtual void setupMenus() = 0;
562  virtual void updateVisibleRangeDisplay(Pane *p) const = 0;
563  virtual void updatePositionStatusDisplays() const = 0;
564 
565  // Call this after setting up the menu bar, to fix up single-key
566  // shortcuts on OS/X and do any other platform-specific tidying
567  virtual void finaliseMenus();
568  virtual void finaliseMenu(QMenu *);
569 
570  // Call before finaliseMenus if you wish to have a say in this question
571  void setIconsVisibleInMenus(bool visible) { m_iconsVisibleInMenus = visible; }
573 
574  // Only used on OS/X to work around a Qt/Cocoa bug, see finaliseMenus
575  QSignalMapper *m_menuShortcutMapper;
576  QList<QShortcut *> m_appShortcuts;
577 
578  virtual bool shouldCreateNewSessionForRDFAudio(bool *) { return true; }
579 
580  virtual void connectLayerEditDialog(ModelDataTableDialog *dialog);
581 
582  virtual void toXml(QTextStream &stream, bool asTemplate);
583 };
584 
585 
586 #endif
AudioCallbackRecordTarget * m_recordTarget
AudioMode m_audioMode
QLabel * m_statusLabel
virtual bool shouldCreateNewSessionForRDFAudio(bool *)
void setIconsVisibleInMenus(bool visible)
OSCQueueStarter * m_oscQueueStarter
MIDIMode
Determine whether to open a MIDI input device.
RecentFiles m_recentFiles
RealTime m_defaultFfwdRwdStep
OSCQueueStarter(MainWindowBase *mwb, bool withNetworkPort)
The base class for the SV main window.
virtual void newerVersionAvailable(QString)
QString m_oscScriptFile
breakfastquay::SystemPlaybackTarget * m_playTarget
QList< QShortcut * > m_appShortcuts
bool m_initialDarkBackground
std::map< Layer *, QPointer< ModelDataTableDialog > > LayerDataDialogMap
QString m_sessionFile
void setWindowSize(int width, int height) override
breakfastquay::SystemAudioIO * m_audioIO
RecentFiles m_recentTransforms
Open for playback, never for recording.
void setDefaultFfwdRwdStep(RealTime step)
Open for playback when model loaded, switch to I/O if record called.
void addSelection(sv_frame_t start, sv_frame_t end) override
AudioMode
Determine what kind of audio device to open when the first model is loaded or record() is called...
Document * m_document
Open no MIDI device.
MIDIMode m_midiMode
QSignalMapper * m_menuShortcutMapper
QString m_myStatusMessage
PaneCallback(MainWindowBase *mw)
A Sonic Visualiser document consists of a set of data models, and also the visualisation layers used ...
Definition: Document.h:71
void setAudioRecordMode(AudioRecordMode mode)
ViewDataDialogMap m_viewDataDialogMap
MIDIInput * m_midiInput
Open no audio device, ever.
std::map< View *, DataDialogSet > ViewDataDialogMap
AudioRecordMode m_audioRecordMode
std::set< QPointer< ModelDataTableDialog > > DataDialogSet
Layer * m_timeRulerLayer
OSCQueue * m_oscQueue
OSCScript * m_oscScript
bool m_iconsVisibleInMenus
LayerDataDialogMap m_layerDataDialogMap
QString m_originalLocation
PaneStack * m_paneStack
Labeller * m_labeller
AudioCallbackPlaySource * m_playSource
ViewManager * m_viewManager