summaryrefslogtreecommitdiffstats
path: root/src/document/RosegardenGUIDoc.h
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-03-01 18:37:05 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-03-01 18:37:05 +0000
commit145364a8af6a1fec06556221e66d4b724a62fc9a (patch)
tree53bd71a544008c518034f208d64c932dc2883f50 /src/document/RosegardenGUIDoc.h
downloadrosegarden-145364a8af6a1fec06556221e66d4b724a62fc9a.tar.gz
rosegarden-145364a8af6a1fec06556221e66d4b724a62fc9a.zip
Added old abandoned KDE3 version of the RoseGarden MIDI tool
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/rosegarden@1097595 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'src/document/RosegardenGUIDoc.h')
-rw-r--r--src/document/RosegardenGUIDoc.h733
1 files changed, 733 insertions, 0 deletions
diff --git a/src/document/RosegardenGUIDoc.h b/src/document/RosegardenGUIDoc.h
new file mode 100644
index 0000000..1cdc88e
--- /dev/null
+++ b/src/document/RosegardenGUIDoc.h
@@ -0,0 +1,733 @@
+
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
+
+/*
+ Rosegarden
+ A MIDI and audio sequencer and musical notation editor.
+
+ This program is Copyright 2000-2008
+ Guillaume Laurent <[email protected]>,
+ Chris Cannam <[email protected]>,
+ Richard Bown <[email protected]>
+
+ The moral rights of Guillaume Laurent, Chris Cannam, and Richard
+ Bown to claim authorship of this work have been asserted.
+
+ Other copyrights also apply to some parts of this work. Please
+ see the AUTHORS file and individual file headers for details.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version. See the file
+ COPYING included with this distribution for more information.
+*/
+
+#ifndef _RG_ROSEGARDENGUIDOC_H_
+#define _RG_ROSEGARDENGUIDOC_H_
+
+#include "base/Composition.h"
+#include "base/Configuration.h"
+#include "base/Device.h"
+#include "base/MidiProgram.h"
+#include "base/RealTime.h"
+#include "base/Segment.h"
+#include "base/Studio.h"
+#include "gui/application/RosegardenGUIApp.h"
+#include "gui/editors/segment/segmentcanvas/AudioPreviewThread.h"
+#include <map>
+#include "sound/AudioFileManager.h"
+// #include <qlist.h> (fixes problem for Adam Dingle)
+#include <qobject.h>
+#include <qstring.h>
+#include <qstringlist.h>
+#include <vector>
+#include "base/Event.h"
+
+
+class QWidget;
+class QTextStream;
+class NoteOnRecSet;
+class KProgress;
+
+
+namespace Rosegarden
+{
+
+class SequenceManager;
+class RosegardenGUIView;
+class ProgressDialog;
+class MultiViewCommandHistory;
+class MappedComposition;
+class Event;
+class EditViewBase;
+class Clipboard;
+class AudioPluginManager;
+
+
+static const int MERGE_AT_END = (1 << 0);
+static const int MERGE_IN_NEW_TRACKS = (1 << 1);
+static const int MERGE_KEEP_OLD_TIMINGS = (1 << 2);
+static const int MERGE_KEEP_NEW_TIMINGS = (1 << 3);
+
+
+/**
+ * RosegardenGUIDoc provides a document object for a document-view model.
+ *
+ * The RosegardenGUIDoc class provides a document object that can be
+ * used in conjunction with the classes RosegardenGUIApp and
+ * RosegardenGUIView to create a document-view model for standard KDE
+ * applications based on KApplication and KTMainWindow. Thereby, the
+ * document object is created by the RosegardenGUIApp instance and
+ * contains the document structure with the according methods for
+ * manipulation of the document data by RosegardenGUIView
+ * objects. Also, RosegardenGUIDoc contains the methods for
+ * serialization of the document data from and to files.
+ *
+ * RosegardenGUIDoc owns the Composition in the document.
+ */
+
+class RosegardenGUIDoc : public QObject
+{
+ Q_OBJECT
+public:
+
+ /**
+ * Constructor for the fileclass of the application
+ */
+ RosegardenGUIDoc(QWidget *parent,
+ AudioPluginManager *audioPluginManager = 0,
+ bool skipAutoload = false,
+ const char *name=0);
+
+private:
+ RosegardenGUIDoc(RosegardenGUIDoc *doc);
+ RosegardenGUIDoc& operator=(const RosegardenGUIDoc &doc);
+
+public:
+ static int FILE_FORMAT_VERSION_MAJOR;
+ static int FILE_FORMAT_VERSION_MINOR;
+ static int FILE_FORMAT_VERSION_POINT;
+
+ /**
+ * Destructor for the fileclass of the application
+ */
+ ~RosegardenGUIDoc();
+
+ /**
+ * adds a view to the document which represents the document
+ * contents. Usually this is your main view.
+ */
+ void attachView(RosegardenGUIView *view);
+
+ /**
+ * removes a view from the list of currently connected views
+ */
+ void detachView(RosegardenGUIView *view);
+
+ /**
+ * adds an Edit View (notation, matrix, event list)
+ */
+ void attachEditView(EditViewBase*);
+
+ /**
+ * removes a view from the list of currently connected edit views
+ */
+ void detachEditView(EditViewBase*);
+
+ /**
+ * delete all Edit Views
+ */
+ void deleteEditViews();
+
+protected:
+ /**
+ * sets the modified flag for the document after a modifying
+ * action on the view connected to the document.
+ *
+ * this is just an accessor, other components should call
+ * slotDocumentModified() and clearModifiedStatus() instead of
+ * this method, which perform all the related housework.
+ *
+ */
+ void setModified(bool m=true);
+
+public:
+ /**
+ * returns if the document is modified or not. Use this to
+ * determine if your document needs saving by the user on closing.
+ */
+ bool isModified() const { return m_modified; };
+
+ /**
+ * clears the 'modified' status of the document (sets it back to false).
+ *
+ */
+ void clearModifiedStatus();
+
+ /**
+ * "save modified" - asks the user for saving if the document is
+ * modified
+ */
+ bool saveIfModified();
+
+ /**
+ * get the autosave interval in seconds
+ */
+ unsigned int getAutoSavePeriod() const;
+
+ /**
+ * Load the document by filename and format and emit the
+ * updateViews() signal. The "permanent" argument should be true
+ * if this document is intended to be loaded to the GUI for real
+ * editing work: in this case, any necessary device-synchronisation
+ * with the sequencer will be carried out. If permanent is false,
+ * the sequencer's device list will be left alone.
+ */
+ bool openDocument(const QString &filename, bool permanent = true,
+ const char *format=0);
+
+ /**
+ * merge another document into this one
+ */
+ void mergeDocument(RosegardenGUIDoc *doc, int options);
+
+ /**
+ * saves the document under filename and format.
+ *
+ * errMsg will be set to a user-readable error message if save fails
+ */
+ bool saveDocument(const QString &filename, QString& errMsg,
+ bool autosave = false);
+
+ /**
+ * exports all or part of the studio to a file. If devices is
+ * empty, exports all devices.
+ */
+ bool exportStudio(const QString &filename,
+ std::vector<DeviceId> devices =
+ std::vector<DeviceId>());
+
+ /**
+ * sets the path to the file connected with the document
+ */
+ void setAbsFilePath(const QString &filename);
+
+ /**
+ * returns the pathname of the current document file
+ */
+ const QString &getAbsFilePath() const;
+
+ /**
+ * sets the filename of the document
+ */
+ void setTitle(const QString &_t);
+
+ /**
+ * returns the title of the document
+ */
+ const QString &getTitle() const;
+
+ /**
+ * Returns true if the file is a regular Rosegarden ".rg" file,
+ * false if it's an imported file or a new file (not yet saved)
+ */
+ bool isRegularDotRGFile();
+
+ void setQuickMarker();
+ void jumpToQuickMarker();
+ timeT getQuickMarkerTime() { return m_quickMarkerTime; }
+
+ /**
+ * returns the global command history
+ */
+ MultiViewCommandHistory *getCommandHistory() {
+ return m_commandHistory;
+ }
+
+ /**
+ * returns the composition (the principal constituent of the document)
+ */
+ Composition& getComposition() { return m_composition; }
+
+ /**
+ * returns the composition (the principal constituent of the document)
+ */
+ const Composition& getComposition() const { return m_composition; }
+
+ /*
+ * return the Studio
+ */
+ Studio& getStudio() { return m_studio;}
+
+ const Studio& getStudio() const { return m_studio;}
+
+ /*
+ * return the AudioPreviewThread
+ */
+ AudioPreviewThread& getAudioPreviewThread()
+ { return m_audioPreviewThread; }
+
+ const AudioPreviewThread& getAudioPreviewThread() const
+ { return m_audioPreviewThread; }
+
+ /*
+ * return the AudioFileManager
+ */
+ AudioFileManager& getAudioFileManager()
+ { return m_audioFileManager; }
+
+ const AudioFileManager& getAudioFileManager() const
+ { return m_audioFileManager; }
+
+ /*
+ * return the Configuration object
+ */
+ DocumentConfiguration& getConfiguration() { return m_config; }
+
+ const DocumentConfiguration& getConfiguration() const
+ { return m_config; }
+
+ /**
+ * returns the cut/copy/paste clipboard
+ */
+ Clipboard *getClipboard();
+
+ /**
+ * Returns whether the sequencer us running
+ */
+ bool isSequencerRunning();
+
+ /**
+ * insert some recorded MIDI events into our recording Segment
+ */
+ void insertRecordedMidi(const MappedComposition &mc);
+
+ /**
+ * Update the recording progress -- called regularly from
+ * RosegardenGUIApp::slotUpdatePlaybackPosition() while recording
+ */
+ void updateRecordingMIDISegment();
+
+ /**
+ * Update the recording progress for audio
+ */
+ void updateRecordingAudioSegments();
+
+ /**
+ * Tidy up the recording SegmentItems and other post record jobs
+ */
+ void stopRecordingMidi();
+ void stopRecordingAudio();
+
+ /**
+ * Register audio samples at the sequencer
+ */
+ void prepareAudio();
+
+ /**
+ * Cause the playPositionChanged signal to be emitted and any
+ * associated internal work in the document to happen
+ */
+ void setPlayPosition(timeT);
+
+ /**
+ * Cause the loopChanged signal to be emitted and any
+ * associated internal work in the document to happen
+ */
+ void setLoop(timeT, timeT);
+
+ /**
+ * Cause the document to use the given time as the origin
+ * when inserting any subsequent recorded data
+ */
+ void setRecordStartTime(timeT t) { m_recordStartTime = t; }
+
+ /*
+ * Sync device information with sequencer
+ */
+ void syncDevices();
+
+ /*
+ * Get a MappedDevice from the sequencer and add the
+ * results to our Studio
+ */
+ void getMappedDevice(DeviceId id);
+
+ void addRecordMIDISegment(TrackId);
+ void addRecordAudioSegment(InstrumentId, AudioFileId);
+
+ // Audio play and record latencies direct from the sequencer
+ //
+ RealTime getAudioPlayLatency();
+ RealTime getAudioRecordLatency();
+ void updateAudioRecordLatency();
+
+ // Complete the add of an audio file when a new file has finished
+ // being recorded at the sequencer. This method will ensure that
+ // the audio file is added to the AudioFileManager, that
+ // a preview is generated and that the sequencer also knows to add
+ // the new file to its own hash table. Flow of control is a bit
+ // awkward around new audio files as timing is crucial - the gui can't
+ // access the file until lead-out information has been written by the
+ // sequencer.
+ //
+ // Note that the sequencer doesn't know the audio file id (yet),
+ // only the instrument it was recorded to. (It does know the
+ // filename, but the instrument id is enough for us.)
+ //
+ void finalizeAudioFile(InstrumentId instrument);
+
+ // Tell the document that an audio file has been orphaned. An
+ // orphaned audio file is a file that was created by recording in
+ // Rosegarden during the current session, but that has been
+ // unloaded from the audio file manager. It's therefore likely
+ // that no other application will be using it, and that that user
+ // doesn't want to keep it. We can offer to delete these files
+ // permanently when the document is saved.
+ //
+ void addOrphanedRecordedAudioFile(QString fileName);
+ void addOrphanedDerivedAudioFile(QString fileName);
+
+ // Consider whether to orphan the given audio file which is about
+ // to be removed from the audio file manager.
+ //
+ void notifyAudioFileRemoval(AudioFileId id);
+
+ /*
+ void setAudioRecordLatency(const RealTime &latency)
+ { m_audioRecordLatency = latency; }
+ void setAudioPlayLatency(const RealTime &latency)
+ { m_audioPlayLatency = latency; }
+ */
+
+ // Return the AudioPluginManager
+ //
+ AudioPluginManager* getPluginManager()
+ { return m_pluginManager; }
+
+ // Clear all plugins from sequencer and from gui
+ //
+ void clearAllPlugins();
+
+ // Initialise the MIDI controllers after we've loaded a file
+ //
+ void initialiseControllers();
+
+ // Clear the studio at the sequencer
+ //
+ void clearStudio();
+
+ // Initialise the Studio with a new document's settings
+ //
+ void initialiseStudio();
+
+ // Get the sequence manager from the app
+ //
+ SequenceManager* getSequenceManager()
+ { return (dynamic_cast<RosegardenGUIApp*>(parent()))
+ ->getSequenceManager(); }
+
+ //Obsolete: multitrack MIDI recording. plcl 06/2006.
+ //Segment *getRecordMIDISegment() { return m_recordMIDISegment; }
+
+ QStringList getTimers();
+ QString getCurrentTimer();
+ void setCurrentTimer(QString);
+
+ /**
+ * return the list of the views currently connected to the document
+ */
+ QList<RosegardenGUIView>& getViewList() { return m_viewList; }
+
+ bool isBeingDestroyed() { return m_beingDestroyed; }
+
+ static const unsigned int MinNbOfTracks; // 64
+
+public slots:
+ /**
+ * calls repaint() on all views connected to the document object
+ * and is called by the view by which the document has been
+ * changed. As this view normally repaints itself, it is excluded
+ * from the paintEvent.
+ */
+ void slotUpdateAllViews(RosegardenGUIView *sender);
+
+ /**
+ * set the 'modified' flag of the document to true,
+ * clears the 'autosaved' flag, emits the 'documentModified' signal.
+ *
+ * always call this when changes have occurred on the document.
+ */
+ void slotDocumentModified();
+ void slotDocumentRestored();
+
+ /**
+ * saves the document to a suitably-named backup file
+ */
+ void slotAutoSave();
+
+ void slotSetPointerPosition(timeT);
+ void slotSetPlayPosition(timeT t) { setPlayPosition(t); }
+ void slotSetLoop(timeT s, timeT e) {setLoop(s,e);}
+
+ void slotDocColoursChanged();
+
+signals:
+ /**
+ * Emitted when document is modified or saved
+ */
+ void documentModified(bool);
+
+ /**
+ * Emitted during playback, to suggest that views should track along,
+ * as well as when pointer is moved via a click on the loop ruler.
+ */
+ void pointerPositionChanged(timeT);
+
+ /**
+ * Emitted during recording, to indicate that some new notes (it's
+ * only emitted for notes) have appeared in the recording segment
+ * and anything tracking should track. updatedFrom gives the
+ * start of the new region, which is presumed to extend up to the
+ * end of the segment.
+ */
+ void recordMIDISegmentUpdated(Segment *recordSegment,
+ timeT updatedFrom);
+
+ /**
+ * Emitted when a new MIDI recording segment is set
+ */
+ void newMIDIRecordingSegment(Segment*);
+
+ /**
+ * Emitted when a new audio recording segment is set
+ */
+ void newAudioRecordingSegment(Segment*);
+
+ void makeTrackVisible(int trackPosition);
+
+ void stoppedAudioRecording();
+ void stoppedMIDIRecording();
+ void audioFileFinalized(Segment*);
+
+ void playPositionChanged(timeT);
+ void loopChanged(timeT, timeT);
+ void docColoursChanged();
+ void devicesResyncd();
+
+protected:
+ /**
+ * initializes the document generally
+ */
+ void newDocument();
+
+ /**
+ * Autoload
+ */
+ void performAutoload();
+
+ /**
+ * Parse the Rosegarden file in \a file
+ *
+ * \a errMsg will contains the error messages
+ * if parsing failed.
+ *
+ * @return false if parsing failed
+ * @see RoseXmlHandler
+ */
+ bool xmlParse(QString fileContents, QString &errMsg,
+ ProgressDialog *progress,
+ unsigned int elementCount,
+ bool permanent,
+ bool &cancelled);
+
+ /**
+ * Set the "auto saved" status of the document
+ * Doc. modification sets it to false, autosaving
+ * sets it to true
+ */
+ void setAutoSaved(bool s) { m_autoSaved = s; }
+
+ /**
+ * Returns whether the document should be auto-saved
+ */
+ bool isAutoSaved() const { return m_autoSaved; }
+
+ /**
+ * Returns the name of the autosave file
+ */
+ QString getAutoSaveFileName();
+
+ /**
+ * Save document to the given file. This function does the actual
+ * save of the file to the given filename; saveDocument() wraps
+ * this, saving to a temporary file and then renaming to the
+ * required file, so as not to lose the original if a failure
+ * occurs during overwriting.
+ */
+ bool saveDocumentActual(const QString &filename, QString& errMsg,
+ bool autosave = false);
+
+ /**
+ * Save one segment to the given text stream
+ */
+ void saveSegment(QTextStream&, Segment*, KProgress*,
+ long totalNbOfEvents, long &count,
+ QString extraAttributes = QString::null);
+
+ bool deleteOrphanedAudioFiles(bool documentWillNotBeSaved);
+
+
+ /**
+ * A struct formed by a Segment pointer and an iterator to the same
+ * Segment, used in NoteOn calculations when recording MIDI.
+ */
+ struct NoteOnRec {
+ Segment *m_segment;
+ Segment::iterator m_segmentIterator;
+ };
+
+ /**
+ * A vector of NoteOnRec elements, necessary in multitrack MIDI
+ * recording for NoteOn calculations
+ */
+ typedef std::vector<NoteOnRec> NoteOnRecSet;
+
+ /**
+ * Store a single NoteOnRec element in the m_noteOnEvents map
+ */
+ void storeNoteOnEvent( Segment *s, Segment::iterator it,
+ int device, int channel );
+
+ /**
+ * Replace recorded Note events in one or several segments, returning the
+ * resulting NoteOnRecSet
+ */
+ NoteOnRecSet* replaceRecordedEvent(NoteOnRecSet &rec_vec, Event *fresh);
+
+ /**
+ * Insert a recorded event in one or several segments
+ */
+ void insertRecordedEvent(Event *ev, int device, int channel, bool isNoteOn);
+
+ //--------------- Data members ---------------------------------
+
+ /**
+ * the list of the views currently connected to the document
+ */
+ QList<RosegardenGUIView> m_viewList;
+
+ /**
+ * the list of the edit views currently editing a part of this document
+ */
+ QList<EditViewBase> m_editViewList;
+
+ /**
+ * the modified flag of the current document
+ */
+ bool m_modified;
+
+ /**
+ * the autosaved status of the current document
+ */
+ bool m_autoSaved;
+
+ /**
+ * the title of the current document
+ */
+ QString m_title;
+
+ /**
+ * absolute file path of the current document
+ */
+ QString m_absFilePath;
+
+ /**
+ * the composition this document is wrapping
+ */
+ Composition m_composition;
+
+ /**
+ * stores AudioFile mappings
+ */
+ AudioFileManager m_audioFileManager;
+
+ /**
+ * calculates AudioFile previews
+ */
+ AudioPreviewThread m_audioPreviewThread;
+
+ typedef std::map<InstrumentId, Segment *> RecordingSegmentMap;
+
+ /**
+ * Segments onto which we can record MIDI events
+ */
+ //Segment *m_recordMIDISegment;
+ RecordingSegmentMap m_recordMIDISegments;
+
+ /**
+ * Segments for recording audio (per instrument)
+ */
+ RecordingSegmentMap m_recordAudioSegments;
+
+ /**
+ * a map[Pitch] of NoteOnRecSet elements, for NoteOn calculations
+ */
+ typedef std::map<int, NoteOnRecSet> PitchMap;
+
+ /**
+ * a map[Channel] of PitchMap
+ */
+ typedef std::map<int, PitchMap> ChanMap;
+
+ /**
+ * a map[Port] of ChanMap
+ */
+ typedef std::map<int, ChanMap> NoteOnMap;
+
+ /**
+ * During recording, we collect note-ons that haven't yet had a note-off
+ * in here
+ */
+ NoteOnMap m_noteOnEvents;
+
+
+ MultiViewCommandHistory *m_commandHistory;
+
+ /**
+ * the Studio
+ */
+ Studio m_studio;
+
+ /*
+ * A configuration object
+ *
+ */
+ DocumentConfiguration m_config;
+
+ // AudioPluginManager - sequencer and local plugin management
+ //
+ AudioPluginManager *m_pluginManager;
+
+ RealTime m_audioRecordLatency;
+
+ timeT m_recordStartTime;
+
+ timeT m_quickMarkerTime;
+
+ std::vector<QString> m_orphanedRecordedAudioFiles;
+ std::vector<QString> m_orphanedDerivedAudioFiles;
+
+ // Autosave period for this document in seconds
+ //
+ int m_autoSavePeriod;
+
+ // Set to true when the dtor starts
+ bool m_beingDestroyed;
+};
+
+
+}
+
+#endif