diff --git a/ChangeLog b/ChangeLog index 7a429b93d..7695ab7d1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,8 +1,84 @@ +2006-03-19 Tobias Doerffel + + * src/core/track.cpp: + * src/core/track_container.cpp: + * src/tracks/pattern.cpp: + in loadSettings(): do not get confused by meta-data (journal etc.) + + * src/lib/journalling_object.cpp: + - lot of bugfixes + - save/load data of journal-entry (QVariant) by encoding/decoding it + with base64 + + * include/base64.h: + * src/lib/base64.cpp: + support for encoding and decoding whole QVariant, independent of its + type (the result is one string, representing data of any type (int, + QMap, QVector QString...) - this is just awesome!!) + + * src/tracks/instrument_track.cpp: + do not crash in several situations if instrument is not loaded for + some reason (e.g. invalid preset) + + * src/core/track.cpp: + full support for undo/redo adding/removing a TCO (track-type + independent) + +2006-03-18 Tobias Doerffel + + * src/core/main_window.cpp: + avoid layouting-errors when restore widget-state by showing widget + while moving it + + * include/note.h: + * src/core/note.cpp: + undo/redo-support for note-properties + + * most files: + - derive from journallingObject instead of settings and/or engineObject + - in saveSettings() do not create own node, instead directly set + attributes of passed dom-element + + * include/journalling_object.h: + * src/lib/journalling_object.cpp: + - added saveSettings() and loadSettings()-method from former + settings-class + - new wrapper-functions around saveSettings() and loadSettings(): + saveState() + restoreState() + -> objects do not have to create a new node on their own, + saveState() does it for them using nodeName() as node-name + -> journal of object is saved/restored automatically + + * include/settings.h: + removed + +2006-03-16 Tobias Doerffel + + * include/journalling_object.h: + - renamed from editable_object.h + - renamed editStep to journalEntry + - renamed editableObject to journallingObject + - renamed other method-names + + * include/project_journal.h: + * src/lib/project_journal.cpp: + renamed editHistory to projectJournal and changed file-names + accordingly + + * most files: + renamed class channelTrack to instrumentTrack and changed other + method-names to match new naming-convention + + * include/instrument_track.h: + * src/tracks/instrument_track.cpp: + renamed channel_track.* to instrument_track.* + 2006-03-16 Andreas Brandmaier - * plugins/organic/organic.cpp - * plugins/organic/organic.h - * plugins/organic/randomise.png + * plugins/organic/organic.cpp: + * plugins/organic/organic.h: + * plugins/organic/randomise.png: added "randomise preset" button to organic plugin 2006-03-14 Tobias Doerffel diff --git a/Makefile.am b/Makefile.am index b2bbaf538..fda00894e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -50,7 +50,7 @@ lmms_MOC = \ ./automatable_button.moc \ ./bb_editor.moc \ ./bb_track.moc \ - ./channel_track.moc \ + ./instrument_track.moc \ ./combobox.moc \ ./config_mgr.moc \ ./cpuload_widget.moc \ @@ -152,7 +152,8 @@ lmms_SOURCES = \ $(srcdir)/src/lib/base64.cpp \ $(srcdir)/src/lib/buffer_allocator.cpp \ $(srcdir)/src/lib/clipboard.cpp \ - $(srcdir)/src/lib/edit_history.cpp \ + $(srcdir)/src/lib/journalling_object.cpp \ + $(srcdir)/src/lib/project_journal.cpp \ $(srcdir)/src/lib/embed.cpp \ $(srcdir)/src/lib/ladspa_manager.cpp \ $(srcdir)/src/lib/mmp.cpp \ @@ -166,7 +167,7 @@ lmms_SOURCES = \ $(srcdir)/src/midi/midi_oss.cpp \ $(srcdir)/src/midi/midi_port.cpp \ $(srcdir)/src/tracks/bb_track.cpp \ - $(srcdir)/src/tracks/channel_track.cpp \ + $(srcdir)/src/tracks/instrument_track.cpp \ $(srcdir)/src/tracks/pattern.cpp \ $(srcdir)/src/tracks/sample_track.cpp \ $(srcdir)/src/widgets/automatable_button.cpp \ @@ -209,7 +210,7 @@ lmms_SOURCES = \ $(srcdir)/include/interpolation.h \ $(srcdir)/include/mixer.h \ $(srcdir)/include/pattern.h \ - $(srcdir)/include/channel_track.h \ + $(srcdir)/include/instrument_track.h \ $(srcdir)/include/note.h \ $(srcdir)/include/volume.h \ $(srcdir)/include/panning.h \ @@ -220,7 +221,6 @@ lmms_SOURCES = \ $(srcdir)/include/piano_widget.h \ $(srcdir)/include/effect_board.h \ $(srcdir)/include/pixmap_button.h \ - $(srcdir)/include/settings.h \ $(srcdir)/include/rename_dialog.h \ $(srcdir)/include/export_project_dialog.h \ $(srcdir)/include/note_play_handle.h \ @@ -300,8 +300,8 @@ lmms_SOURCES = \ $(srcdir)/include/rubberband.h \ $(srcdir)/include/base64.h \ $(srcdir)/include/automatable_object.h \ - $(srcdir)/include/editable_object.h \ - $(srcdir)/include/edit_history.h \ + $(srcdir)/include/journalling_object.h \ + $(srcdir)/include/project_journal.h \ $(srcdir)/include/import_filter.h \ $(srcdir)/include/engine.h \ $(srcdir)/include/qxembed.h diff --git a/README b/README index a86001492..0c8989466 100644 --- a/README +++ b/README @@ -108,7 +108,7 @@ or in the Wiki: http://wiki.mindrules.net Before coding a new big feature, please ALWAYS post your idea and suggestions -about your feature and about the actual implementation to the +about your feature and about the intended implementation to the LMMS-devel-mailinglist (lmms-devel@lists.sourceforge.net) and wait for replies! Maybe there're different ideas, improvements, hints or maybe your feature is not welcome/needed at the moment (but for sure this will be very seldom). diff --git a/TODO b/TODO index 854e0b4ab..7bf82ef55 100644 --- a/TODO +++ b/TODO @@ -1,7 +1,9 @@ -- implement editableSettingsObject -- unique id's for all editable objects -- add edit-history to project for making it possible to undo things even if you did them in a previous session -- make edit-history qobject and undo/redo slots -> direct connection to GUI +- font-size-scaling-coefficient in setup-dialog +- make note able of journalling +- before calling undoStep/redoStep from journallingObject, save journalling-state-context and disabled journalling, restore afterwards +- intelligent journal-entry-merging +- undo/redo-support in note/track etc. +- save tco-settings in trackContentWidget::saveSettings() etc. instead of track::... - restore stacking-order of windows when loading project - fix MIDI-import-filter - bristol-bindings diff --git a/configure.in b/configure.in index 4edf20c08..e224ccffb 100644 --- a/configure.in +++ b/configure.in @@ -2,8 +2,8 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ(2.50) -AC_INIT(lmms, 0.1.4-cvs20060314, tobydox/at/users/dot/sourceforge/dot/net) -AM_INIT_AUTOMAKE(lmms, 0.1.4-cvs20060314) +AC_INIT(lmms, 0.1.4-cvs20060320, tobydox/at/users/dot/sourceforge/dot/net) +AM_INIT_AUTOMAKE(lmms, 0.1.4-cvs20060320) AM_CONFIG_HEADER(config.h) diff --git a/include/arp_and_chords_tab_widget.h b/include/arp_and_chords_tab_widget.h index 51e3ea531..a8949c1e1 100644 --- a/include/arp_and_chords_tab_widget.h +++ b/include/arp_and_chords_tab_widget.h @@ -43,7 +43,7 @@ #include #endif -#include "settings.h" +#include "journalling_object.h" #include "types.h" #include "engine.h" @@ -51,7 +51,7 @@ class QPixmap; class automatableButtonGroup; -class channelTrack; +class instrumentTrack; class comboBox; class groupBox; class knob; @@ -62,12 +62,11 @@ class tempoSyncKnob; const int MAX_CHORD_POLYPHONY = 10; -class arpAndChordsTabWidget : public QWidget, public settings, - public engineObject +class arpAndChordsTabWidget : public QWidget, public journallingObject { Q_OBJECT public: - arpAndChordsTabWidget( channelTrack * _channel_track ); + arpAndChordsTabWidget( instrumentTrack * _channel_track ); virtual ~arpAndChordsTabWidget(); static struct chord diff --git a/include/automatable_button.h b/include/automatable_button.h index ab483bbd3..8572c3983 100755 --- a/include/automatable_button.h +++ b/include/automatable_button.h @@ -61,10 +61,15 @@ public: virtual void setValue( const bool _on ); - inline void setToggleButton( bool _on ) + inline void setCheckable( bool _on ) { - m_toggleButton = _on; - setStepRecording( m_toggleButton ); + m_checkable = _on; + setJournalling( m_checkable ); + } + + inline bool isCheckable( void ) const + { + return( m_checkable ); } @@ -83,7 +88,7 @@ protected: private: automatableButtonGroup * m_group; - bool m_toggleButton; + bool m_checkable; friend class automatableButtonGroup; diff --git a/include/automatable_object.h b/include/automatable_object.h index 9833e500d..c55782bf9 100755 --- a/include/automatable_object.h +++ b/include/automatable_object.h @@ -28,12 +28,22 @@ #include -#include "editable_object.h" +#include "journalling_object.h" #include "templates.h" +#ifndef QT3 + +#include + +#else + +#include + +#endif + template -class automatableObject : public editableObject +class automatableObject : public journallingObject { public: typedef automatableObject autoObj; @@ -41,7 +51,7 @@ public: automatableObject( engine * _engine, const T _val = 0, const T _min = 0, const T _max = 0, const T _step = defaultRelStep() ) : - editableObject( _engine ), + journallingObject( _engine ), m_oldValue( _val ), m_value( _val ), m_minValue( _min ), @@ -127,9 +137,9 @@ public: inline virtual void setInitValue( const T _value ) { - saveStepRecordingState( FALSE ); + saveJournallingState( FALSE ); setValue( _value ); - restoreStepRecordingState(); + restoreJournallingState(); } inline virtual void setValue( const T _value ) @@ -140,10 +150,9 @@ public: if( old_val != m_value ) { // add changes to history so user can undo it - addStep( editStep( 0, static_cast( - m_value ) - - static_cast( - old_val ) ) ); + addJournalEntry( journalEntry( 0, + static_cast( m_value ) - + static_cast( old_val ) ) ); // notify linked objects @@ -158,10 +167,10 @@ public: it->fittedValue( value() ) != it->value() ) { - it->saveStepRecordingState( - isRecordingSteps() ); + it->saveJournallingState( + isJournalling() ); it->setValue( value() ); - it->restoreStepRecordingState(); + it->restoreJournallingState(); } } } @@ -238,39 +247,57 @@ public: _object2->linkObject( _object1 ); } + virtual QString nodeName( void ) const + { + return( "automatableobject" ); + } + protected: - virtual void redoStep( const editStep & _edit_step ) + virtual void redoStep( journalEntry & _je ) { - saveStepRecordingState( FALSE ); + saveJournallingState( FALSE ); #ifndef QT3 setValue( static_cast( value() + - _edit_step.data().value() ) ); + _je.data().value() ) ); #else setValue( static_cast( value() + static_cast( - _edit_step.data().toDouble() ) ) ); + _je.data().toDouble() ) ) ); #endif - restoreStepRecordingState(); + restoreJournallingState(); } - virtual void undoStep( const editStep & _edit_step ) + virtual void undoStep( journalEntry & _je ) { + journalEntry je( _je.actionID(), #ifndef QT3 - redoStep( editStep( _edit_step.actionID(), - -_edit_step.data().value() ) ); + -_je.data().value(); #else - redoStep( editStep( _edit_step.actionID(), - static_cast( - -_edit_step.data().toDouble() ) ) ); + static_cast( -_je.data().toDouble() ) #endif + ); + redoStep( je ); } + virtual void FASTCALL saveSettings( QDomDocument & _doc, + QDomElement & _this ) + { + _this.setAttribute( "value", value() ); + } + + virtual void FASTCALL loadSettings( const QDomElement & _this ) + { + setValue( static_cast( + _this.attribute( "value" ).toDouble() ) ); + } + + // most objects will need this temporarily T m_oldValue; - inline void addStepFromOldToCurVal( void ) + inline void addJournalEntryFromOldToCurVal( void ) { - addStep( editStep( 0, value() - m_oldValue ) ); + addJournalEntry( journalEntry( 0, value() - m_oldValue ) ); } diff --git a/include/base64.h b/include/base64.h index e1ee51764..952bda1cd 100644 --- a/include/base64.h +++ b/include/base64.h @@ -36,6 +36,9 @@ #endif +class QVariant; + + namespace base64 { #ifndef QT3 @@ -55,6 +58,9 @@ namespace base64 void encode( const char * _data, const int _size, QString & _dst ); void decode( const QString & _b64, char * * _data, int * _size ); #endif + QString encode( const QVariant & _data ); + QVariant decode( const QString & _b64 ); + } ; #endif diff --git a/include/clipboard.h b/include/clipboard.h index a288c30ad..95bafc031 100644 --- a/include/clipboard.h +++ b/include/clipboard.h @@ -1,7 +1,7 @@ /* * clipboard.h - the clipboard for patterns, notes etc. * - * Copyright (c) 2004-2005 Tobias Doerffel + * Copyright (c) 2004-2006 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -46,14 +46,14 @@ #endif -class settings; +class journallingObject; namespace clipboard { typedef QMap map; extern map content; - void FASTCALL copy( settings * _settings_object ); + void FASTCALL copy( journallingObject * _object ); const QDomElement * FASTCALL getContent( const QString & _node_name ); } ; diff --git a/include/dummy_instrument.h b/include/dummy_instrument.h index c75ce62d1..b87cda72b 100644 --- a/include/dummy_instrument.h +++ b/include/dummy_instrument.h @@ -33,7 +33,7 @@ class dummyInstrument : public instrument { public: - inline dummyInstrument( channelTrack * _channel_track ) : + inline dummyInstrument( instrumentTrack * _channel_track ) : instrument( _channel_track, NULL ) { } diff --git a/include/engine.h b/include/engine.h index 6794fe22b..d2e97a0b3 100644 --- a/include/engine.h +++ b/include/engine.h @@ -27,7 +27,7 @@ #define _ENGINE_H class bbEditor; -class editHistory; +class projectJournal; class mainWindow; class mixer; class pianoRoll; @@ -92,9 +92,9 @@ public: return( m_projectNotes ); } - inline editHistory * getEditHistory( void ) + inline projectJournal * getProjectJournal( void ) { - return( m_editHistory ); + return( m_projectJournal ); } @@ -107,7 +107,7 @@ private: bbEditor * m_bbEditor; pianoRoll * m_pianoRoll; projectNotes * m_projectNotes; - editHistory * m_editHistory; + projectJournal * m_projectJournal; } ; diff --git a/include/envelope_and_lfo_widget.h b/include/envelope_and_lfo_widget.h index 9a2c284a7..0ba8fe00b 100644 --- a/include/envelope_and_lfo_widget.h +++ b/include/envelope_and_lfo_widget.h @@ -49,7 +49,7 @@ #endif -#include "settings.h" +#include "journalling_object.h" #include "types.h" #include "spc_bg_hndl_widget.h" #include "sample_buffer.h" @@ -67,9 +67,8 @@ class tempoSyncKnob; -class envelopeAndLFOWidget : public QWidget, public settings, - public specialBgHandlingWidget, - public engineObject +class envelopeAndLFOWidget : public QWidget, public journallingObject, + public specialBgHandlingWidget { Q_OBJECT public: diff --git a/include/envelope_tab_widget.h b/include/envelope_tab_widget.h index 5c6bccb27..6e88c48d9 100644 --- a/include/envelope_tab_widget.h +++ b/include/envelope_tab_widget.h @@ -41,14 +41,13 @@ #endif -#include "settings.h" #include "basic_filters.h" #include "envelope_and_lfo_widget.h" class QLabel; -class channelTrack; +class instrumentTrack; class comboBox; class groupBox; class knob; @@ -57,12 +56,11 @@ class pixmapButton; class tabWidget; -class envelopeTabWidget : public QWidget, public settings, - public engineObject +class envelopeTabWidget : public QWidget, public journallingObject { Q_OBJECT public: - envelopeTabWidget( channelTrack * _channel_track ); + envelopeTabWidget( instrumentTrack * _channel_track ); virtual ~envelopeTabWidget(); void FASTCALL processAudioBuffer( sampleFrame * _ab, diff --git a/include/file_browser.h b/include/file_browser.h index 617d3582b..de51e72fd 100644 --- a/include/file_browser.h +++ b/include/file_browser.h @@ -79,14 +79,14 @@ protected slots: void contextMenuRequest( QListViewItem * _i, const QPoint & _pos, int _col ); #endif - void sendToActiveChannel( void ); - void openInNewChannelSE( void ); - void openInNewChannelBBE( void ); + void sendToActiveInstrumentTrack( void ); + void openInNewInstrumentTrackSE( void ); + void openInNewInstrumentTrackBBE( void ); private: virtual void keyPressEvent( QKeyEvent * _ke ); - void openInNewChannel( trackContainer * _tc ); + void openInNewInstrumentTrack( trackContainer * _tc ); listView * m_l; fileItem * m_contextMenuItem; diff --git a/include/instrument.h b/include/instrument.h index f12ea5370..3f8c89006 100644 --- a/include/instrument.h +++ b/include/instrument.h @@ -53,14 +53,14 @@ // forward-declarations -class channelTrack; +class instrumentTrack; class notePlayHandle; class instrument : public QWidget, public plugin { public: - instrument( channelTrack * _channel_track, + instrument( instrumentTrack * _channel_track, const descriptor * _descriptor ); virtual ~instrument(); @@ -96,12 +96,12 @@ public: // instantiate instrument-plugin with given name or return NULL // on failure static instrument * FASTCALL instantiate( const QString & _plugin_name, - channelTrack * _channel_track ); + instrumentTrack * _channel_track ); protected: - inline channelTrack * getChannelTrack( void ) const + inline instrumentTrack * getInstrumentTrack( void ) const { - return( m_channelTrack ); + return( m_instrumentTrack ); } // instruments can use this for invalidating themselves, which is for @@ -115,7 +115,7 @@ protected: private: - channelTrack * m_channelTrack; + instrumentTrack * m_instrumentTrack; bool m_valid; } ; diff --git a/include/instrument_play_handle.h b/include/instrument_play_handle.h index 4e0147e9e..60f5ceb59 100644 --- a/include/instrument_play_handle.h +++ b/include/instrument_play_handle.h @@ -34,7 +34,7 @@ class instrumentPlayHandle : public playHandle { public: inline instrumentPlayHandle( instrument * _instrument ) : - playHandle( INSTRUMENT_PLAY_HANDLE, _instrument->eng() ), + playHandle( INSTRUMENT_PLAY_HANDLE ), m_instrument( _instrument ) { } diff --git a/include/instrument_track.h b/include/instrument_track.h new file mode 100755 index 000000000..fd8803214 --- /dev/null +++ b/include/instrument_track.h @@ -0,0 +1,306 @@ +/* + * instrument_track.h - declaration of class instrumentTrack, a track + window + * which holds an instrument-plugin + * + * Copyright (c) 2004-2006 Tobias Doerffel + * + * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + + +#ifndef _INSTRUMENT_TRACK_H +#define _INSTRUMENT_TRACK_H + +#include "qt3support.h" + +#ifdef QT4 + +#include +#include +#include +#include + +#else + +#include +#include +#include +#include + +#endif + +#include "track.h" +#include "mixer.h" +#include "midi_event_processor.h" +#include "gui_templates.h" +#include "tab_widget.h" +#include "engine.h" + + +class QLineEdit; +class arpAndChordsTabWidget; +class audioPort; +class instrumentTrackButton; +class envelopeTabWidget; +class fadeButton; +class instrument; +class knob; +class lcdSpinBox; +class midiPort; +class midiTabWidget; +class notePlayHandle; +class pianoWidget; +class presetPreviewPlayHandle; +class surroundArea; + + + +class instrumentTrack : public QWidget, public track, public midiEventProcessor +{ + Q_OBJECT +public: + instrumentTrack( trackContainer * _tc ); + virtual ~instrumentTrack(); + + inline virtual trackTypes type( void ) const + { + return( m_trackType ); + } + + + // used by instrument + void FASTCALL processAudioBuffer( sampleFrame * _buf, + const fpab_t _frames, + notePlayHandle * _n ); + + virtual void FASTCALL processInEvent( const midiEvent & _me, + const midiTime & _time ); + virtual void FASTCALL processOutEvent( const midiEvent & _me, + const midiTime & _time ); + + // returns the frequency of a given tone & octave. + // This function also includes base_tone & base_octave in + // its calculations + float FASTCALL frequency( notePlayHandle * _n ) const; + f_cnt_t FASTCALL beatLen( notePlayHandle * _n ) const; + + + // for capturing note-play-events -> need that for arpeggio, + // filter and so on + void FASTCALL playNote( notePlayHandle * _n ); + + QString instrumentName( void ) const; + void FASTCALL deleteNotePluginData( notePlayHandle * _n ); + + // name-stuff + inline const QString & name( void ) const + { + return( m_name ); + } + void FASTCALL setName( const QString & _new_name ); + + // volume & surround-position-stuff + void FASTCALL setVolume( volume _new_volume ); + volume getVolume( void ) const; + void FASTCALL setSurroundAreaPos( const QPoint & _p ); + const QPoint & surroundAreaPos( void ) const; + + // base-tone stuff + void FASTCALL setBaseTone( tones _new_tone ); + void FASTCALL setBaseOctave( octaves _new_octave ); + + inline tones baseTone( void ) const + { + return( m_baseTone ); + } + + inline octaves baseOctave( void ) const + { + return( m_baseOctave ); + } + + int FASTCALL masterKey( notePlayHandle * _n ) const; + + + // play everything in given frame-range - creates note-play-handles + virtual bool FASTCALL play( const midiTime & _start, + const f_cnt_t _start_frame, + const fpab_t _frames, + const f_cnt_t _frame_base, + Sint16 _tco_num = -1 ); + // create new track-content-object = pattern + virtual trackContentObject * FASTCALL createTCO( const midiTime & + _pos ); + + + // called by track + virtual void FASTCALL saveTrackSpecificSettings( QDomDocument & _doc, + QDomElement & _parent ); + virtual void FASTCALL loadTrackSpecificSettings( const QDomElement & + _this ); + + // load instrument whose name matches given one + instrument * FASTCALL loadInstrument( const QString & + _instrument_name ); + + // parent for all internal tab-widgets + QWidget * tabWidgetParent( void ) + { + return( m_tabWidget ); + } + + +public slots: + void surroundAreaPosChanged( const QPoint & _new_p ); + void textChanged( const QString & _new_name ); + void toggledInstrumentTrackButton( bool _on ); + + +protected: + // capture close-events for toggling instrument-track-button + virtual void closeEvent( QCloseEvent * _ce ); + virtual void dragEnterEvent( QDragEnterEvent * _dee ); + virtual void dropEvent( QDropEvent * _de ); + virtual void focusInEvent( QFocusEvent * _fe ); + + inline virtual QString nodeName( void ) const + { + return( "instrumenttrack" ); + } + // invalidates all note-play-handles linked to this instrument + void invalidateAllMyNPH( void ); + + +protected slots: + void saveSettingsBtnClicked( void ); + void activityIndicatorPressed( void ); + void activityIndicatorReleased( void ); + void midiInSelected( void ); + void midiOutSelected( void ); + void midiConfigChanged( bool ); + + +private: + trackTypes m_trackType; + + midiPort * m_midiPort; + + audioPort * m_audioPort; + + + notePlayHandle * m_notes[NOTES_PER_OCTAVE * OCTAVES]; + + QMutex m_notesMutex; + + + tones m_baseTone; + octaves m_baseOctave; + + QString m_name; + + + // widgets on the top of a instrument-track-window + tabWidget * m_generalSettingsWidget; + QLineEdit * m_instrumentNameLE; + knob * m_volumeKnob; + surroundArea * m_surroundArea; + lcdSpinBox * m_effectChannelNumber; + QPushButton * m_saveSettingsBtn; + + + // tab-widget with all children + tabWidget * m_tabWidget; + instrument * m_instrument; + envelopeTabWidget * m_envWidget; + arpAndChordsTabWidget * m_arpWidget; + midiTabWidget * m_midiWidget; + + + // test-piano at the bottom of every instrument-settings-window + pianoWidget * m_pianoWidget; + + + // widgets in track-settings-widget + knob * m_tswVolumeKnob; + fadeButton * m_tswActivityIndicator; + instrumentTrackButton * m_tswInstrumentTrackButton; + QMenu * m_tswMidiMenu; +#ifdef QT4 + QAction * m_midiInputAction; + QAction * m_midiOutputAction; +#else + int m_midiInputID; + int m_midiOutputID; +#endif + + friend class instrumentTrackButton; + friend class notePlayHandle; + friend class presetPreviewPlayHandle; + + +signals: + void noteDone( const note & _n ); + +} ; + + + + +class instrumentTrackButton : public QPushButton +{ +public: + instrumentTrackButton( instrumentTrack * _instrument_track ); + virtual ~instrumentTrackButton(); + +#ifdef QT3 + inline void setChecked( bool _on ) + { + setOn( _on ); + } + + inline bool isChecked( void ) const + { + return( isOn() ); + } + + inline void setCheckable( bool _on ) + { + QPushButton::setToggleButton( _on ); + } +#endif + + +protected: + // since we want to draw a special label (instrument- and instrument- + // name) on our button, we have to re-implement this for doing so + virtual void drawButtonLabel( QPainter * _p ); + + // allow drops on this button - we simply forward them to + // instrument-track + virtual void dragEnterEvent( QDragEnterEvent * _dee ); + virtual void dropEvent( QDropEvent * _de ); + + +private: + instrumentTrack * m_instrumentTrack; + +} ; + + +#endif diff --git a/include/journalling_object.h b/include/journalling_object.h new file mode 100755 index 000000000..0725cb0b0 --- /dev/null +++ b/include/journalling_object.h @@ -0,0 +1,213 @@ +/* + * journalling_object.h - declaration of class journallingObject + * + * Copyright (c) 2006 Tobias Doerffel + * + * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + + +#ifndef _JOURNALLING_OBJECT_H +#define _JOURNALLING_OBJECT_H + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "types.h" +#include "engine.h" +#include "qt3support.h" + +#ifndef QT3 + +#include +#include +#include + +#else + +#include +#include +#include + +#endif + + +class QDomDocument; +class QDomElement; + + +typedef Uint32 t_action_id; + + +class journallingObject; + + +class journalEntry +{ +public: + journalEntry( const t_action_id _action_id, const QVariant & _data ) : + m_actionID( _action_id ), + m_data( _data ) + { + } + + journalEntry( void ) : + m_actionID( 0 ), + m_data( 0 ) + { + } + + ~journalEntry() + { + } + + t_action_id actionID( void ) const + { + return( m_actionID ); + } + + t_action_id & actionID( void ) + { + return( m_actionID ); + } + + const QVariant & data( void ) const + { + return( m_data ); + } + + QVariant & data( void ) + { + return( m_data ); + } + + +private: + t_action_id m_actionID; + QVariant m_data; + +} ; + + +typedef vvector journalEntryVector; + + + +class journallingObject : public engineObject +{ +public: + journallingObject( engine * _engine ); + virtual ~journallingObject(); + + inline const jo_id_t id( void ) const + { + return( m_id ); + } + + void undo( void ); + void redo( void ); + + void clear( void ) + { + m_journalEntries.clear(); + m_currentJournalEntry = m_journalEntries.end(); + } + + void clearRedoSteps( void ) + { + m_journalEntries.erase( m_currentJournalEntry, + m_journalEntries.end() ); + m_currentJournalEntry = m_journalEntries.end(); + + } + + void saveJournallingState( const bool _new_state ) + { + m_journallingStateStack.push( m_journalling ); + m_journalling = _new_state; + } + + void restoreJournallingState( void ) + { + m_journalling = m_journallingStateStack.pop(); + } + + virtual QDomElement FASTCALL saveState( QDomDocument & _doc, + QDomElement & _parent ); + + virtual void FASTCALL restoreState( const QDomElement & _this ); + + + // to be implemented by actual object + virtual QString nodeName( void ) const = 0; + + +protected: + void addJournalEntry( const journalEntry & _je ); + + inline bool isJournalling( void ) const + { + return( m_journalling ); + } + + inline void setJournalling( const bool _sr ) + { + m_journalling = _sr; + } + + + // to be implemented by sub-objects + virtual void FASTCALL saveSettings( QDomDocument & _doc, + QDomElement & _this ) + { + } + + virtual void FASTCALL loadSettings( const QDomElement & _this ) + { + } + + virtual void undoStep( journalEntry & _je ) + { + } + virtual void redoStep( journalEntry & _je ) + { + } + + +private: + void saveJournal( QDomDocument & _doc, QDomElement & _parent ); + void loadJournal( const QDomElement & _this ); + + + jo_id_t m_id; + + journalEntryVector m_journalEntries; + journalEntryVector::iterator m_currentJournalEntry; + + bool m_journalling; + + vstack m_journallingStateStack; + +} ; + + + +#endif + diff --git a/include/midi_tab_widget.h b/include/midi_tab_widget.h index b8841c01c..d7ab7b6b4 100644 --- a/include/midi_tab_widget.h +++ b/include/midi_tab_widget.h @@ -43,7 +43,7 @@ #include #endif -#include "settings.h" +#include "journalling_object.h" #include "engine.h" @@ -51,18 +51,18 @@ class QMenu; class QPixmap; class QAction; -class channelTrack; +class instrumentTrack; class tabWidget; class ledCheckBox; class lcdSpinBox; class midiPort; -class midiTabWidget : public QWidget, public settings, public engineObject +class midiTabWidget : public QWidget, public journallingObject { Q_OBJECT public: - midiTabWidget( channelTrack * _channel_track, midiPort * _port ); + midiTabWidget( instrumentTrack * _channel_track, midiPort * _port ); virtual ~midiTabWidget(); @@ -91,7 +91,7 @@ protected slots: void activatedWriteablePort( int _id ); private: - channelTrack * m_channelTrack; + instrumentTrack * m_instrumentTrack; midiPort * m_midiPort; tabWidget * m_setupTabWidget; @@ -103,7 +103,7 @@ private: QMenu * m_readablePorts; QMenu * m_writeablePorts; - friend class channelTrack; + friend class instrumentTrack; } ; diff --git a/include/mmp.h b/include/mmp.h index 529b134b0..1feb55e17 100644 --- a/include/mmp.h +++ b/include/mmp.h @@ -50,12 +50,13 @@ public: UNKNOWN, SONG_PROJECT, SONG_PROJECT_TEMPLATE, - CHANNEL_SETTINGS, + INSTRUMENT_TRACK_SETTINGS, DRAG_N_DROP_DATA, + JOURNAL_DATA, EFFECT_SETTINGS, - VIDEO_PROJECT, // will come later... - BURN_PROJECT, // will come later... - PLAYLIST, // will come later... + VIDEO_PROJECT, // might come later... + BURN_PROJECT, // might come later... + PLAYLIST, // might come later... PROJ_TYPE_COUNT } ; diff --git a/include/note.h b/include/note.h index c710bdd36..711b39354 100644 --- a/include/note.h +++ b/include/note.h @@ -46,7 +46,7 @@ #include "volume.h" #include "panning.h" #include "midi_time.h" -#include "settings.h" +#include "journalling_object.h" enum tones { @@ -89,15 +89,18 @@ const int OCTAVES = 9; -class note : public settings +class note : public journallingObject { public: - note( const midiTime & _length = 0, const midiTime & _pos = 0, - tones _tone = A, octaves _octave = DEFAULT_OCTAVE, + note( engine * _engine = NULL, + const midiTime & _length = 0, + const midiTime & _pos = 0, + tones _tone = A, + octaves _octave = DEFAULT_OCTAVE, volume _volume = DEFAULT_VOLUME, panning _panning = DEFAULT_PANNING ) FASTCALL; - ~note(); + virtual ~note(); void FASTCALL setLength( const midiTime & _length ); void FASTCALL setPos( const midiTime & _pos ); @@ -154,18 +157,31 @@ public: return( m_panning ); } - virtual void FASTCALL saveSettings( QDomDocument & _doc, - QDomElement & _parent ); - virtual void FASTCALL loadSettings( const QDomElement & _this ); inline virtual QString nodeName( void ) const { return( "note" ); } +protected: + virtual void FASTCALL saveSettings( QDomDocument & _doc, + QDomElement & _parent ); + virtual void FASTCALL loadSettings( const QDomElement & _this ); + + virtual void undoStep( journalEntry & _je ); + virtual void redoStep( journalEntry & _je ); + + private: midiTime FASTCALL quantized( const midiTime & _m, const int _q_grid ); + enum actions + { + CHANGE_KEY, CHANGE_VOLUME, CHANGE_PANNING, + CHANGE_LENGTH, CHANGE_POSITION + } ; + + tones m_tone; octaves m_octave; volume m_volume; diff --git a/include/note_play_handle.h b/include/note_play_handle.h index 64c9e12a3..7ab6a2a37 100644 --- a/include/note_play_handle.h +++ b/include/note_play_handle.h @@ -32,7 +32,7 @@ #include "note.h" -class channelTrack; +class instrumentTrack; class notePlayHandle; typedef vvector notePlayHandleVector; @@ -45,8 +45,8 @@ public: void * m_pluginData; basicFilters<> * m_filter; - notePlayHandle( channelTrack * _chnl_trk, const f_cnt_t _frames_ahead, - const f_cnt_t _frames, note * _n, + notePlayHandle( instrumentTrack * _chnl_trk, const f_cnt_t _frames_ahead, + const f_cnt_t _frames, const note & _n, const bool _arp_note = FALSE ); virtual ~notePlayHandle(); @@ -57,7 +57,7 @@ public: { return( ( m_released && m_framesBeforeRelease == 0 && m_releaseFramesDone >= m_releaseFramesToDo ) || - m_channelTrack == NULL ); + m_instrumentTrack == NULL ); } virtual void checkValidity( void ); @@ -118,10 +118,10 @@ public: m_arpNote = _n->arpNote() && baseNote(); } - // returns channel-track this note-play-handle plays - inline channelTrack * getChannelTrack( void ) + // returns instrument-track this note-play-handle plays + inline instrumentTrack * getInstrumentTrack( void ) { - return( m_channelTrack ); + return( m_instrumentTrack ); } // returns whether note is a base-note, e.g. is not part of an arpeggio @@ -161,15 +161,15 @@ public: // note-play-handles belonging to given channel static constNotePlayHandleVector nphsOfChannelTrack( - const channelTrack * _ct ); + const instrumentTrack * _ct ); // return whether given note-play-handle is equal to *this bool operator==( const notePlayHandle & _nph ) const; private: - channelTrack * m_channelTrack; // needed for calling - // channelTrack::playNote + instrumentTrack * m_instrumentTrack; // needed for calling + // instrumentTrack::playNote f_cnt_t m_frames; // total frames to play f_cnt_t m_framesAhead; // numbers of frames ahead in buffer // to mix in diff --git a/include/pattern.h b/include/pattern.h index 375f5e621..64576f0a6 100644 --- a/include/pattern.h +++ b/include/pattern.h @@ -59,7 +59,7 @@ class QAction; class QProgressBar; class QPushButton; -class channelTrack; +class instrumentTrack; class patternFreezeThread; class sampleBuffer; @@ -78,7 +78,7 @@ public: BEAT_PATTERN, MELODY_PATTERN/*, AUTOMATION_PATTERN*/ } ; - pattern( channelTrack * _channel_track ); + pattern( instrumentTrack * _channel_track ); pattern( const pattern & _pat_to_copy ); virtual ~pattern(); @@ -154,9 +154,9 @@ public: return( "pattern" ); } - inline channelTrack * getChannelTrack( void ) + inline instrumentTrack * getInstrumentTrack( void ) { - return( m_channelTrack ); + return( m_instrumentTrack ); } @@ -208,7 +208,7 @@ private: bool m_needsUpdate; // general stuff - channelTrack * m_channelTrack; + instrumentTrack * m_instrumentTrack; patternTypes m_patternType; QString m_name; diff --git a/include/piano_roll.h b/include/piano_roll.h index ae138d1e8..57a5907aa 100644 --- a/include/piano_roll.h +++ b/include/piano_roll.h @@ -46,7 +46,7 @@ #include "types.h" #include "note.h" #include "engine.h" -#include "settings.h" +#include "journalling_object.h" class QPainter; @@ -60,7 +60,7 @@ class timeLine; class toolButton; -class pianoRoll : public QWidget, public engineObject, public settings +class pianoRoll : public QWidget, public journallingObject { Q_OBJECT public: diff --git a/include/piano_widget.h b/include/piano_widget.h index 4acdb0188..ac0029003 100644 --- a/include/piano_widget.h +++ b/include/piano_widget.h @@ -48,7 +48,7 @@ #include "templates.h" -class channelTrack; +class instrumentTrack; class notePlayHandle; @@ -63,7 +63,7 @@ class pianoWidget : public QWidget { Q_OBJECT public: - pianoWidget( channelTrack * _channel_track ); + pianoWidget( instrumentTrack * _channel_track ); virtual ~pianoWidget(); inline void setKeyState( int _key, bool _on = FALSE ) @@ -97,7 +97,7 @@ private: bool m_pressedKeys[NOTES_PER_OCTAVE * OCTAVES]; QScrollBar * m_pianoScroll; - channelTrack * m_channelTrack; + instrumentTrack * m_instrumentTrack; tones m_startTone; // first key when drawing octaves m_startOctave; diff --git a/include/play_handle.h b/include/play_handle.h index fb271844c..c403828a2 100644 --- a/include/play_handle.h +++ b/include/play_handle.h @@ -44,10 +44,7 @@ #endif -#include "engine.h" - - -class playHandle : public engineObject +class playHandle { public: enum types @@ -56,8 +53,7 @@ public: PRESET_PREVIEW_PLAY_HANDLE } ; - playHandle( const types _type, engine * _engine ) : - engineObject( _engine ), + playHandle( const types _type ) : m_type( _type ) { } diff --git a/include/plugin.h b/include/plugin.h index 915d50c50..a67efb9c3 100644 --- a/include/plugin.h +++ b/include/plugin.h @@ -47,9 +47,8 @@ #include "types.h" -#include "settings.h" +#include "journalling_object.h" #include "embed.h" -#include "engine.h" #define STRINGIFY_PLUGIN_NAME(s) STR(s) @@ -59,7 +58,7 @@ class QPixmap; -class plugin : public settings, public engineObject +class plugin : public journallingObject { public: enum pluginTypes diff --git a/include/preset_preview_play_handle.h b/include/preset_preview_play_handle.h index 1ea11eeb5..d0395738d 100644 --- a/include/preset_preview_play_handle.h +++ b/include/preset_preview_play_handle.h @@ -31,25 +31,25 @@ #ifdef QT4 -#include #include #else -#include #include #endif #include "note_play_handle.h" +#include "engine.h" +class instrumentTrack; +class notePlayHandle; class previewTrackContainer; -class channelTrack; -class presetPreviewPlayHandle : public playHandle +class presetPreviewPlayHandle : public playHandle, public engineObject { public: presetPreviewPlayHandle( const QString & _preset_file, @@ -61,7 +61,7 @@ public: static void cleanUp( engine * _engine ); static constNotePlayHandleVector nphsOfChannelTrack( - const channelTrack * _ct ); + const instrumentTrack * _ct ); private: inline previewTrackContainer * previewTC( void ) diff --git a/include/project_journal.h b/include/project_journal.h new file mode 100755 index 000000000..1ac494f23 --- /dev/null +++ b/include/project_journal.h @@ -0,0 +1,120 @@ +/* + * project_journal.h - declaration of class projectJournal + * + * Copyright (c) 2006 Tobias Doerffel + * + * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + + +#ifndef _PROJECT_JOURNAL_H +#define _PROJECT_JOURNAL_H + +#include "types.h" +#include "engine.h" +#include "qt3support.h" + +#ifndef QT3 + +#include +#include +#include + +#else + +#include +#include +#include + +#endif + + +class journallingObject; + + +class projectJournal : public engineObject +{ +public: + projectJournal( engine * _engine ); + virtual ~projectJournal(); + + void undo( void ); + void redo( void ); + + // tell history that a new journal entry was added to object with ID _id + void journalEntryAdded( const jo_id_t _id ); + + bool isJournalling( void ) const + { + return( m_journalling ); + } + + void setJournalling( const bool _on ) + { + m_journalling = _on; + } + + // alloc new ID and register object _obj to it + jo_id_t allocID( journallingObject * _obj ); + + // if there's already something known about ID _id, but it is currently + // unused (e.g. after jouralling object was deleted), register object + // _obj to this id + void reallocID( const jo_id_t _id, journallingObject * _obj ); + + // make ID _id unused, but keep all global journalling information + // (order of journalling entries etc.) referring to _id - needed for + // restoring a journalling object later + void freeID( const jo_id_t _id ) + { + reallocID( _id, NULL ); + } + + // completely remove everything linked with ID _id - all global + // journalling information about the ID get's lost + void forgetAboutID( const jo_id_t _id ); + + void clear( void ); + + journallingObject * getJournallingObject( const jo_id_t _id ) + { + if( m_joIDs.contains( _id ) ) + { + return( m_joIDs[_id] ); + } + return( NULL ); + } + + +private: + typedef QMap joIDMap; + typedef vvector journalEntryVector; + + joIDMap m_joIDs; + + journalEntryVector m_journalEntries; + journalEntryVector::iterator m_currentJournalEntry; + + bool m_journalling; + +} ; + + +#endif + diff --git a/include/project_notes.h b/include/project_notes.h index 496622aec..5aefc2b69 100644 --- a/include/project_notes.h +++ b/include/project_notes.h @@ -39,7 +39,7 @@ #endif -#include "settings.h" +#include "journalling_object.h" #include "engine.h" @@ -48,7 +48,7 @@ class QComboBox; class QTextEdit; -class projectNotes : public QMainWindow, public settings, public engineObject +class projectNotes : public QMainWindow, public journallingObject { Q_OBJECT public: diff --git a/include/qt3support.h b/include/qt3support.h index a46c36085..27a668979 100644 --- a/include/qt3support.h +++ b/include/qt3support.h @@ -130,8 +130,6 @@ inline QString baseName( const QString & _file ) // QAbstractButton/QButton -#define setCheckable setToggleButton -#define isCheckable isToggleButton #define setShortcut setAccel diff --git a/include/sample_play_handle.h b/include/sample_play_handle.h index 2a55fe711..4fae2bfca 100644 --- a/include/sample_play_handle.h +++ b/include/sample_play_handle.h @@ -28,13 +28,13 @@ #include "play_handle.h" #include "types.h" - +#include "engine.h" class sampleBuffer; class audioPort; -class samplePlayHandle : public playHandle +class samplePlayHandle : public playHandle, public engineObject { public: samplePlayHandle( const QString & _sample_file, engine * _engine ); diff --git a/include/song_editor.h b/include/song_editor.h index f512613ec..c12203381 100644 --- a/include/song_editor.h +++ b/include/song_editor.h @@ -150,9 +150,7 @@ public: { return( m_fileName ); } - virtual void FASTCALL saveSettings( QDomDocument & _doc, - QDomElement & _parent ); - virtual void FASTCALL loadSettings( const QDomElement & _this ); + inline virtual QString nodeName( void ) const { return( "songeditor" ); diff --git a/include/tab_button.h b/include/tab_button.h index c117da330..3ae682f1d 100644 --- a/include/tab_button.h +++ b/include/tab_button.h @@ -48,7 +48,11 @@ public: QPushButton( _text, _parent ), m_id( _id ) { +#ifndef QT3 setCheckable( TRUE ); +#else + setToggleButton( TRUE ); +#endif connect( this, SIGNAL( clicked() ), this, SLOT( slotClicked() ) ); } diff --git a/include/timeline.h b/include/timeline.h index 353ed144f..607ccf673 100644 --- a/include/timeline.h +++ b/include/timeline.h @@ -47,7 +47,7 @@ class nStateButton; class textFloat; -class timeLine : public QWidget, public engineObject, public settings +class timeLine : public QWidget, public journallingObject { Q_OBJECT public: diff --git a/include/track.h b/include/track.h index 254b2bf10..eb555012a 100644 --- a/include/track.h +++ b/include/track.h @@ -54,10 +54,9 @@ #include "types.h" #include "midi_time.h" -#include "settings.h" #include "rubberband.h" #include "engine.h" -#include "editable_object.h" +#include "journalling_object.h" class QMenu; @@ -79,8 +78,8 @@ const Uint16 TRACK_OP_WIDTH = 70; const Uint16 TCO_BORDER_WIDTH = 1; -class trackContentObject : public selectableObject, public settings, - public editableObject +class trackContentObject : public selectableObject, + public journallingObject { Q_OBJECT public: @@ -130,8 +129,8 @@ protected: void setAutoResizeEnabled( bool _e = FALSE ); float pixelsPerTact( void ); - virtual void undoStep( const editStep & _edit_step ); - virtual void redoStep( const editStep & _edit_step ); + virtual void undoStep( journalEntry & _edit_step ); + virtual void redoStep( journalEntry & _edit_step ); protected slots: @@ -164,7 +163,7 @@ private: -class trackContentWidget : public QWidget, public editableObject +class trackContentWidget : public QWidget, public journallingObject { Q_OBJECT public: @@ -206,8 +205,13 @@ protected: virtual void paintEvent( QPaintEvent * _pe ); virtual void resizeEvent( QResizeEvent * _re ); - virtual void undoStep( const editStep & _edit_step ); - virtual void redoStep( const editStep & _edit_step ); + virtual QString nodeName( void ) const + { + return( "trackcontentwidget" ); + } + + virtual void undoStep( journalEntry & _edit_step ); + virtual void redoStep( journalEntry & _edit_step ); private: @@ -364,7 +368,7 @@ private: // base-class for all tracks -class track : public settings, public engineObject +class track : public journallingObject { public: enum trackTypes @@ -419,7 +423,7 @@ public: virtual void FASTCALL saveSettings( QDomDocument & _doc, - QDomElement & _parent ); + QDomElement & _this ); virtual void FASTCALL loadSettings( const QDomElement & _this ); diff --git a/include/track_container.h b/include/track_container.h index 1e78beb41..ee1f10e65 100644 --- a/include/track_container.h +++ b/include/track_container.h @@ -45,7 +45,7 @@ #include "track.h" -#include "settings.h" +#include "journalling_object.h" #include "rubberband.h" #include "engine.h" @@ -56,7 +56,7 @@ const Uint16 DEFAULT_SCROLLBAR_SIZE = 16; -class trackContainer : public QMainWindow, public settings, public engineObject +class trackContainer : public QMainWindow, public journallingObject { Q_OBJECT public: diff --git a/include/types.h b/include/types.h index 5f7552a0b..ec70f4a9e 100644 --- a/include/types.h +++ b/include/types.h @@ -54,6 +54,6 @@ typedef Uint16 bpm_t; // tempo (MIN_BPM to MAX_BPM) typedef Uint16 bitrate_t; // bitrate in kbps typedef Sint8 fx_ch_t; // FX-channel (0 to MAX_EFFECT_CHANNEL) -typedef Uint32 eo_id_t; // (unique) ID of an editable object +typedef Uint32 jo_id_t; // (unique) ID of an journalling object #endif diff --git a/plugins/audio_file_processor/audio_file_processor.cpp b/plugins/audio_file_processor/audio_file_processor.cpp index 593159da0..b560e1176 100644 --- a/plugins/audio_file_processor/audio_file_processor.cpp +++ b/plugins/audio_file_processor/audio_file_processor.cpp @@ -47,7 +47,7 @@ #include "audio_file_processor.h" #include "song_editor.h" -#include "channel_track.h" +#include "instrument_track.h" #include "note_play_handle.h" #include "paths.h" #include "interpolation.h" @@ -72,7 +72,8 @@ plugin::descriptor audiofileprocessor_plugin_descriptor = "AudioFileProcessor", QT_TRANSLATE_NOOP( "pluginBrowser", "simple sampler with various settings for " - "using samples (e.g. drums) in a channel" ), + "using samples (e.g. drums) in an " + "instrument-track" ), "Tobias Doerffel ", 0x0100, plugin::INSTRUMENT, @@ -86,7 +87,7 @@ QPixmap * audioFileProcessor::s_artwork = NULL; -audioFileProcessor::audioFileProcessor( channelTrack * _channel_track ) : +audioFileProcessor::audioFileProcessor( instrumentTrack * _channel_track ) : instrument( _channel_track, &audiofileprocessor_plugin_descriptor ), specialBgHandlingWidget( PLUGIN_NAME::getIconPixmap( "artwork" ) ), m_sampleBuffer( eng(), "" ), @@ -103,7 +104,6 @@ audioFileProcessor::audioFileProcessor( channelTrack * _channel_track ) : m_openAudioFileButton = new pixmapButton( this, eng() ); - m_openAudioFileButton->setCheckable( FALSE ); m_openAudioFileButton->setCursor( QCursor( Qt::PointingHandCursor ) ); m_openAudioFileButton->move( 200, 90 ); m_openAudioFileButton->setActiveGraphic( embed::getIconPixmap( @@ -129,6 +129,7 @@ audioFileProcessor::audioFileProcessor( channelTrack * _channel_track ) : "doesn't sound like the original one..." ) ); m_reverseButton = new pixmapButton( this, eng() ); + m_reverseButton->setCheckable( TRUE ); m_reverseButton->move( 160, 124 ); m_reverseButton->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "reverse_on" ) ); @@ -148,6 +149,7 @@ audioFileProcessor::audioFileProcessor( channelTrack * _channel_track ) : "crash." ) ); m_loopButton = new pixmapButton( this, eng() ); + m_loopButton->setCheckable( TRUE ); m_loopButton->move( 180, 124 ); m_loopButton->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "loop_on" ) ); @@ -283,27 +285,25 @@ audioFileProcessor::~audioFileProcessor() void audioFileProcessor::saveSettings( QDomDocument & _doc, - QDomElement & _parent ) + QDomElement & _this ) { - QDomElement afp_de = _doc.createElement( nodeName() ); - afp_de.setAttribute( "src", m_sampleBuffer.audioFile() ); + _this.setAttribute( "src", m_sampleBuffer.audioFile() ); if( m_sampleBuffer.audioFile() == "" ) { QString s; - afp_de.setAttribute( "sampledata", m_sampleBuffer.toBase64( s ) ); + _this.setAttribute( "sampledata", m_sampleBuffer.toBase64( s ) ); } - afp_de.setAttribute( "sframe", QString::number( + _this.setAttribute( "sframe", QString::number( m_sampleBuffer.startFrame() / (float)m_sampleBuffer.frames() ) ); - afp_de.setAttribute( "eframe", QString::number( + _this.setAttribute( "eframe", QString::number( m_sampleBuffer.endFrame() / (float)m_sampleBuffer.frames() ) ); - afp_de.setAttribute( "reversed", QString::number( + _this.setAttribute( "reversed", QString::number( m_reverseButton->isChecked() ) ); - afp_de.setAttribute( "looped", QString::number( + _this.setAttribute( "looped", QString::number( m_loopButton->isChecked() ) ); - afp_de.setAttribute( "amp", QString::number( m_ampKnob->value() ) ); - _parent.appendChild( afp_de ); + _this.setAttribute( "amp", QString::number( m_ampKnob->value() ) ); } @@ -356,7 +356,7 @@ void audioFileProcessor::setParameter( const QString & _param, Uint32 audioFileProcessor::getBeatLen( notePlayHandle * _n ) const { const float freq_factor = BASE_FREQ / - ( getChannelTrack()->frequency( _n ) * + ( getInstrumentTrack()->frequency( _n ) * DEFAULT_SAMPLE_RATE / eng()->getMixer()->sampleRate() ); @@ -371,12 +371,12 @@ Uint32 audioFileProcessor::getBeatLen( notePlayHandle * _n ) const void audioFileProcessor::setAudioFile( const QString & _audio_file ) { // is current channel-name equal to previous-filename?? - if( getChannelTrack()->name() == + if( getInstrumentTrack()->name() == QFileInfo( m_sampleBuffer.audioFile() ).fileName() || m_sampleBuffer.audioFile() == "" ) { // then set it to new one - getChannelTrack()->setName( QFileInfo( _audio_file + getInstrumentTrack()->setName( QFileInfo( _audio_file ).fileName() ); } // else we don't touch the channel-name, because the user named it self @@ -395,7 +395,7 @@ void audioFileProcessor::playNote( notePlayHandle * _n ) sampleFrame * buf = bufferAllocator::alloc( frames ); // calculate frequency of note - const float note_freq = getChannelTrack()->frequency( _n ) / + const float note_freq = getInstrumentTrack()->frequency( _n ) / ( eng()->getMixer()->sampleRate() / DEFAULT_SAMPLE_RATE ); if( m_sampleBuffer.play( buf, _n->totalFramesPlayed(), @@ -403,7 +403,7 @@ void audioFileProcessor::playNote( notePlayHandle * _n ) m_loopButton->isChecked(), &_n->m_pluginData ) == TRUE ) { - getChannelTrack()->processAudioBuffer( buf, frames, _n ); + getInstrumentTrack()->processAudioBuffer( buf, frames, _n ); } bufferAllocator::free( buf ); } @@ -674,7 +674,7 @@ extern "C" plugin * lmms_plugin_main( void * _data ) { return( new audioFileProcessor( - static_cast( _data ) ) ); + static_cast( _data ) ) ); } diff --git a/plugins/audio_file_processor/audio_file_processor.h b/plugins/audio_file_processor/audio_file_processor.h index 48b61a235..cca63ab29 100644 --- a/plugins/audio_file_processor/audio_file_processor.h +++ b/plugins/audio_file_processor/audio_file_processor.h @@ -52,7 +52,7 @@ class audioFileProcessor : public instrument, public specialBgHandlingWidget { Q_OBJECT public: - audioFileProcessor( channelTrack * _channel_track ); + audioFileProcessor( instrumentTrack * _channel_track ); virtual ~audioFileProcessor(); virtual void FASTCALL playNote( notePlayHandle * _n ); diff --git a/plugins/bit_invader/bit_invader.cpp b/plugins/bit_invader/bit_invader.cpp index b5645baa7..c68b52f1d 100644 --- a/plugins/bit_invader/bit_invader.cpp +++ b/plugins/bit_invader/bit_invader.cpp @@ -57,7 +57,7 @@ using namespace std; #include "bit_invader.h" -#include "channel_track.h" +#include "instrument_track.h" #include "note_play_handle.h" #include "templates.h" #include "buffer_allocator.h" @@ -173,7 +173,7 @@ sample_t bSynth::nextStringSample( void ) ***********************************************************************/ -bitInvader::bitInvader( channelTrack * _channel_track ) : +bitInvader::bitInvader( instrumentTrack * _channel_track ) : instrument( _channel_track, &bitinvader_plugin_descriptor ), specialBgHandlingWidget( PLUGIN_NAME::getIconPixmap( "artwork" ) ) @@ -565,34 +565,28 @@ bitInvader::~bitInvader() -void bitInvader::saveSettings( QDomDocument & _doc, - QDomElement & _parent ) +void bitInvader::saveSettings( QDomDocument & _doc, QDomElement & _this ) { - QDomElement to_de = _doc.createElement( nodeName() ); - // Save plugin version - to_de.setAttribute( "version", "0.1" ); + _this.setAttribute( "version", "0.1" ); // Save sample length - to_de.setAttribute( "sampleLength", QString::number( sample_length ) ); + _this.setAttribute( "sampleLength", QString::number( sample_length ) ); // Save sample shape base64-encoded QString sampleString; base64::encode( (const char *)sample_shape, sample_length * sizeof(float), sampleString ); - to_de.setAttribute( "sampleShape", sampleString ); + _this.setAttribute( "sampleShape", sampleString ); // save LED normalize - to_de.setAttribute( "interpolation", + _this.setAttribute( "interpolation", m_interpolationToggle->isChecked() ); // save LED - to_de.setAttribute( "normalize", m_normalizeToggle->isChecked() ); - - _parent.appendChild( to_de ); - + _this.setAttribute( "normalize", m_normalizeToggle->isChecked() ); } @@ -686,7 +680,7 @@ void bitInvader::playNote( notePlayHandle * _n ) if ( _n->totalFramesPlayed() == 0 ) { - float freq = getChannelTrack()->frequency( _n ); + float freq = getInstrumentTrack()->frequency( _n ); float factor; if (!normalize) { @@ -713,7 +707,7 @@ void bitInvader::playNote( notePlayHandle * _n ) } } - getChannelTrack()->processAudioBuffer( buf, frames, _n ); + getInstrumentTrack()->processAudioBuffer( buf, frames, _n ); bufferAllocator::free( buf ); } @@ -805,7 +799,7 @@ extern "C" // neccessary for getting instance out of shared lib plugin * lmms_plugin_main( void * _data ) { - return( new bitInvader( static_cast( _data ) ) ); + return( new bitInvader( static_cast( _data ) ) ); } diff --git a/plugins/bit_invader/bit_invader.h b/plugins/bit_invader/bit_invader.h index 4d6b4658f..f0e51828b 100644 --- a/plugins/bit_invader/bit_invader.h +++ b/plugins/bit_invader/bit_invader.h @@ -75,7 +75,7 @@ class bitInvader : public instrument, public specialBgHandlingWidget { Q_OBJECT public: - bitInvader(channelTrack * _channel_track ); + bitInvader(instrumentTrack * _channel_track ); virtual ~bitInvader(); virtual void FASTCALL playNote( notePlayHandle * _n ); diff --git a/plugins/midi_import/midi_import.cpp b/plugins/midi_import/midi_import.cpp index 6fafb48d0..85eb91f15 100644 --- a/plugins/midi_import/midi_import.cpp +++ b/plugins/midi_import/midi_import.cpp @@ -26,7 +26,7 @@ #include "midi_import.h" #include "track_container.h" -#include "channel_track.h" +#include "instrument_track.h" #include "pattern.h" @@ -217,7 +217,7 @@ invalid_format: } // now create new channel-track for reading track - channelTrack * ct = dynamic_cast( + instrumentTrack * ct = dynamic_cast( track::create( track::CHANNEL_TRACK, _tc ) ); @@ -226,7 +226,7 @@ invalid_format: #endif // TODO: setup program, channel etc. ct->loadInstrument( "tripleoscillator" ); - ct->toggledChannelButton( FALSE ); + ct->toggledInstrumentTrackButton( FALSE ); // now create pattern to store notes in pattern * p = dynamic_cast( ct->createTCO( 0 ) ); @@ -269,7 +269,8 @@ invalid_format: NOTES_PER_OCTAVE * OCTAVES && keys[ev.key()][0] >= 0 ) { - note n( midiTime( ( tick - keys[ev.key()][0] ) / 10 ), + note n( eng(), + midiTime( ( tick - keys[ev.key()][0] ) / 10 ), midiTime( keys[ev.key()][0] / 10 ), (tones)( ev.key() % NOTES_PER_OCTAVE ), (octaves)( ev.key() / NOTES_PER_OCTAVE ), diff --git a/plugins/organic/organic.cpp b/plugins/organic/organic.cpp index 7cf904b7b..7e02726ae 100644 --- a/plugins/organic/organic.cpp +++ b/plugins/organic/organic.cpp @@ -1,5 +1,5 @@ /* - * bit_invader.cpp - instrument which uses a usereditable wavetable + * organic.cpp - additive synthesizer for organ-like sounds * * Copyright (c) 2006 Andreas Brandmaier * @@ -57,7 +57,7 @@ using namespace std; #include "organic.h" -#include "channel_track.h" +#include "instrument_track.h" #include "note_play_handle.h" #include "templates.h" #include "buffer_allocator.h" @@ -102,7 +102,7 @@ QPixmap * organicInstrument::s_artwork = NULL; ***********************************************************************/ -organicInstrument::organicInstrument( channelTrack * _channel_track ) : +organicInstrument::organicInstrument( instrumentTrack * _channel_track ) : instrument( _channel_track, &organic_plugin_descriptor ), specialBgHandlingWidget( PLUGIN_NAME::getIconPixmap( "artwork" ) ) @@ -190,7 +190,7 @@ organicInstrument::organicInstrument( channelTrack * _channel_track ) : //m_randBtn->setMask( QBitmap( PLUGIN_NAME::getIconPixmap( "btn_mask" ). // createHeuristicMask() ) ); - connect( m_randBtn, SIGNAL ( toggled(bool) ), + connect( m_randBtn, SIGNAL ( clicked() ), this, SLOT( randomiseSettings() ) ); // set harmonics @@ -232,36 +232,26 @@ organicInstrument::~organicInstrument() -void organicInstrument::saveSettings( QDomDocument & _doc, - QDomElement & _parent ) +void organicInstrument::saveSettings( QDomDocument & _doc, QDomElement & _this ) { - - QDomElement to_de = _doc.createElement( nodeName() ); - - to_de.setAttribute( "num_osc", QString::number( m_num_oscillators ) ); - to_de.setAttribute( "foldback", QString::number( fx1Knob->value() ) ); - to_de.setAttribute( "vol", QString::number( volKnob->value() ) ); + _this.setAttribute( "num_osc", QString::number( m_num_oscillators ) ); + _this.setAttribute( "foldback", QString::number( fx1Knob->value() ) ); + _this.setAttribute( "vol", QString::number( volKnob->value() ) ); for( int i = 0; i < m_num_oscillators; ++i ) { QString is = QString::number( i ); - to_de.setAttribute( "vol" + is, QString::number( + _this.setAttribute( "vol" + is, QString::number( m_osc[i].volKnob->value() ) ); - to_de.setAttribute( "pan" + is, QString::number( + _this.setAttribute( "pan" + is, QString::number( m_osc[i].panKnob->value() ) ); - to_de.setAttribute( "harmonic" + is, QString::number( + _this.setAttribute( "harmonic" + is, QString::number( m_osc[i].harmonic ) ); - to_de.setAttribute( "detune" + is, QString::number( + _this.setAttribute( "detune" + is, QString::number( m_osc[i].detuneKnob->value() ) ); - to_de.setAttribute( "wavetype" + is, QString::number( + _this.setAttribute( "wavetype" + is, QString::number( m_osc[i].waveShape ) ); } - - - - _parent.appendChild( to_de ); - - } @@ -306,7 +296,7 @@ void organicInstrument::playNote( notePlayHandle * _n ) { if( _n->totalFramesPlayed() == 0 ) { - float freq = getChannelTrack()->frequency( _n ); + float freq = getInstrumentTrack()->frequency( _n ); oscillator * oscs_l[m_num_oscillators]; oscillator * oscs_r[m_num_oscillators]; @@ -417,7 +407,7 @@ void organicInstrument::playNote( notePlayHandle * _n ) // -- -- - getChannelTrack()->processAudioBuffer( buf, frames, _n ); + getInstrumentTrack()->processAudioBuffer( buf, frames, _n ); bufferAllocator::free( buf ); } @@ -535,7 +525,7 @@ extern "C" // neccessary for getting instance out of shared lib plugin * lmms_plugin_main( void * _data ) { - return( new organicInstrument( static_cast( _data ) ) ); + return( new organicInstrument( static_cast( _data ) ) ); } diff --git a/plugins/organic/organic.h b/plugins/organic/organic.h index 63b44a8f2..75a78324d 100644 --- a/plugins/organic/organic.h +++ b/plugins/organic/organic.h @@ -1,6 +1,5 @@ /* - * bit_invader.h - declaration of class bitInvader and bSynth which - * are a wavetable synthesizer + * organic.h - additive synthesizer for organ-like sounds * * Copyright (c) 2006 Andreas Brandmaier * @@ -54,7 +53,7 @@ class organicInstrument : public instrument, public specialBgHandlingWidget { Q_OBJECT public: - organicInstrument(channelTrack * _channel_track ); + organicInstrument( instrumentTrack * _channel_track ); virtual ~organicInstrument(); virtual void FASTCALL playNote( notePlayHandle * _n ); diff --git a/plugins/plucked_string_synth/plucked_string_synth.cpp b/plugins/plucked_string_synth/plucked_string_synth.cpp index 68d26950d..65ace69a1 100644 --- a/plugins/plucked_string_synth/plucked_string_synth.cpp +++ b/plugins/plucked_string_synth/plucked_string_synth.cpp @@ -39,7 +39,7 @@ #include "plucked_string_synth.h" -#include "channel_track.h" +#include "instrument_track.h" #include "note_play_handle.h" #include "templates.h" #include "buffer_allocator.h" @@ -70,7 +70,7 @@ plugin::descriptor pluckedstringsynth_plugin_descriptor = // TODO: make this synth stereo for better better spacial (room) feeling and // add distortion -pluckedStringSynth::pluckedStringSynth( channelTrack * _channel_track ) : +pluckedStringSynth::pluckedStringSynth( instrumentTrack * _channel_track ) : instrument( _channel_track, &pluckedstringsynth_plugin_descriptor ) { m_pickKnob = new knob( knobDark_28, this, tr( "Pick position" ), @@ -107,13 +107,11 @@ pluckedStringSynth::~pluckedStringSynth() void pluckedStringSynth::saveSettings( QDomDocument & _doc, - QDomElement & _parent ) + QDomElement & _this ) { - QDomElement pss_de = _doc.createElement( nodeName() ); - pss_de.setAttribute( "pick", QString::number( m_pickKnob->value() ) ); - pss_de.setAttribute( "pickup", QString::number( + _this.setAttribute( "pick", QString::number( m_pickKnob->value() ) ); + _this.setAttribute( "pickup", QString::number( m_pickupKnob->value() ) ); - _parent.appendChild( pss_de ); } @@ -140,7 +138,7 @@ void pluckedStringSynth::playNote( notePlayHandle * _n ) { if ( _n->totalFramesPlayed() == 0 ) { - float freq = getChannelTrack()->frequency( _n ); + float freq = getInstrumentTrack()->frequency( _n ); _n->m_pluginData = new pluckSynth( freq, m_pickKnob->value(), m_pickupKnob->value(), eng()->getMixer()->sampleRate() ); @@ -159,7 +157,7 @@ void pluckedStringSynth::playNote( notePlayHandle * _n ) } } - getChannelTrack()->processAudioBuffer( buf, frames, _n ); + getInstrumentTrack()->processAudioBuffer( buf, frames, _n ); bufferAllocator::free( buf ); } @@ -269,7 +267,7 @@ extern "C" plugin * lmms_plugin_main( void * _data ) { return( new pluckedStringSynth( - static_cast( _data ) ) ); + static_cast( _data ) ) ); } diff --git a/plugins/plucked_string_synth/plucked_string_synth.h b/plugins/plucked_string_synth/plucked_string_synth.h index b54435684..f093a2ffb 100644 --- a/plugins/plucked_string_synth/plucked_string_synth.h +++ b/plugins/plucked_string_synth/plucked_string_synth.h @@ -194,7 +194,7 @@ private: class pluckedStringSynth : public instrument { public: - pluckedStringSynth(channelTrack * _channel_track ); + pluckedStringSynth( instrumentTrack * _channel_track ); virtual ~pluckedStringSynth(); virtual void FASTCALL playNote( notePlayHandle * _n ); diff --git a/plugins/triple_oscillator/triple_oscillator.cpp b/plugins/triple_oscillator/triple_oscillator.cpp index e4e818f31..182fc8b08 100644 --- a/plugins/triple_oscillator/triple_oscillator.cpp +++ b/plugins/triple_oscillator/triple_oscillator.cpp @@ -45,7 +45,7 @@ #include "triple_oscillator.h" #include "song_editor.h" -#include "channel_track.h" +#include "instrument_track.h" #include "note_play_handle.h" #include "knob.h" #include "buffer_allocator.h" @@ -79,7 +79,7 @@ plugin::descriptor tripleoscillator_plugin_descriptor = } -tripleOscillator::tripleOscillator( channelTrack * _channel_track ) : +tripleOscillator::tripleOscillator( instrumentTrack * _channel_track ) : instrument( _channel_track, &tripleoscillator_plugin_descriptor ), m_modulationAlgo1( oscillator::MIX ), m_modulationAlgo2( oscillator::MIX ) @@ -505,37 +505,33 @@ tripleOscillator::~tripleOscillator() -void tripleOscillator::saveSettings( QDomDocument & _doc, - QDomElement & _parent ) +void tripleOscillator::saveSettings( QDomDocument & _doc, QDomElement & _this ) { - QDomElement to_de = _doc.createElement( nodeName() ); - to_de.setAttribute( "modalgo1", QString::number( m_modulationAlgo1 ) ); - to_de.setAttribute( "modalgo2", QString::number( m_modulationAlgo2 ) ); + _this.setAttribute( "modalgo1", QString::number( m_modulationAlgo1 ) ); + _this.setAttribute( "modalgo2", QString::number( m_modulationAlgo2 ) ); for( int i = 0; i < NUM_OF_OSCILLATORS; ++i ) { QString is = QString::number( i ); - to_de.setAttribute( "vol" + is, QString::number( + _this.setAttribute( "vol" + is, QString::number( m_osc[i].volKnob->value() ) ); - to_de.setAttribute( "pan" + is, QString::number( + _this.setAttribute( "pan" + is, QString::number( m_osc[i].panKnob->value() ) ); - to_de.setAttribute( "coarse" + is, QString::number( + _this.setAttribute( "coarse" + is, QString::number( m_osc[i].coarseKnob->value() ) ); - to_de.setAttribute( "finel" + is, QString::number( + _this.setAttribute( "finel" + is, QString::number( m_osc[i].fineLKnob->value() ) ); - to_de.setAttribute( "finer" + is, QString::number( + _this.setAttribute( "finer" + is, QString::number( m_osc[i].fineRKnob->value() ) ); - to_de.setAttribute( "phoffset" + is, QString::number( + _this.setAttribute( "phoffset" + is, QString::number( m_osc[i].phaseOffsetKnob->value() ) ); - to_de.setAttribute( "stphdetun" + is, QString::number( + _this.setAttribute( "stphdetun" + is, QString::number( m_osc[i].stereoPhaseDetuningKnob->value() ) ); - to_de.setAttribute( "wavetype" + is, QString::number( + _this.setAttribute( "wavetype" + is, QString::number( m_osc[i].waveShape ) ); - to_de.setAttribute( "userwavefile" + is, + _this.setAttribute( "userwavefile" + is, m_osc[i].m_sampleBuffer->audioFile() ); } - - _parent.appendChild( to_de ); } @@ -590,7 +586,7 @@ void tripleOscillator::playNote( notePlayHandle * _n ) { if( _n->totalFramesPlayed() == 0 ) { - float freq = getChannelTrack()->frequency( _n ); + float freq = getInstrumentTrack()->frequency( _n ); oscillator * oscs_l[NUM_OF_OSCILLATORS]; oscillator * oscs_r[NUM_OF_OSCILLATORS]; @@ -695,7 +691,7 @@ void tripleOscillator::playNote( notePlayHandle * _n ) osc_l->update( buf, frames, 0 ); osc_r->update( buf, frames, 1 ); - getChannelTrack()->processAudioBuffer( buf, frames, _n ); + getInstrumentTrack()->processAudioBuffer( buf, frames, _n ); bufferAllocator::free( buf ); } @@ -821,7 +817,7 @@ extern "C" plugin * lmms_plugin_main( void * _data ) { return( new tripleOscillator( - static_cast( _data ) ) ); + static_cast( _data ) ) ); } } diff --git a/plugins/triple_oscillator/triple_oscillator.h b/plugins/triple_oscillator/triple_oscillator.h index 03dfe7bd2..1159f846e 100644 --- a/plugins/triple_oscillator/triple_oscillator.h +++ b/plugins/triple_oscillator/triple_oscillator.h @@ -45,7 +45,7 @@ class tripleOscillator : public instrument { Q_OBJECT public: - tripleOscillator( channelTrack * _channel ); + tripleOscillator( instrumentTrack * _channel ); virtual ~tripleOscillator(); virtual void FASTCALL playNote( notePlayHandle * _n ); @@ -72,7 +72,7 @@ protected slots: private: - channelTrack * m_channelTrack; + instrumentTrack * m_instrumentTrack; struct oscillatorData { diff --git a/plugins/vestige/vestige.cpp b/plugins/vestige/vestige.cpp index dc068d210..34c573091 100644 --- a/plugins/vestige/vestige.cpp +++ b/plugins/vestige/vestige.cpp @@ -49,7 +49,7 @@ #endif -#include "channel_track.h" +#include "instrument_track.h" #include "note_play_handle.h" #include "buffer_allocator.h" #include "mixer.h" @@ -87,7 +87,7 @@ plugin::descriptor vestige_plugin_descriptor = QPixmap * vestigeInstrument::s_artwork = NULL; -vestigeInstrument::vestigeInstrument( channelTrack * _channel_track ) : +vestigeInstrument::vestigeInstrument( instrumentTrack * _channel_track ) : instrument( _channel_track, &vestige_plugin_descriptor ), specialBgHandlingWidget( PLUGIN_NAME::getIconPixmap( "artwork" ) ), m_plugin( NULL ), @@ -211,33 +211,30 @@ void vestigeInstrument::loadSettings( const QDomElement & _this ) -void vestigeInstrument::saveSettings( QDomDocument & _doc, - QDomElement & _parent ) +void vestigeInstrument::saveSettings( QDomDocument & _doc, QDomElement & _this ) { - QDomElement vst_de = _doc.createElement( nodeName() ); - vst_de.setAttribute( "plugin", m_pluginDLL ); + _this.setAttribute( "plugin", m_pluginDLL ); m_pluginMutex.lock(); if( m_plugin != NULL ) { if( m_plugin->pluginWidget() != NULL ) { - vst_de.setAttribute( "guivisible", + _this.setAttribute( "guivisible", m_plugin->pluginWidget()->isVisible() ); } const QMap & dump = m_plugin->parameterDump(); - vst_de.setAttribute( "numparams", dump.size() ); + _this.setAttribute( "numparams", dump.size() ); for( QMap::const_iterator it = dump.begin(); it != dump.end(); ++it ) { #ifdef QT4 - vst_de.setAttribute( it.key(), it.value() ); + _this.setAttribute( it.key(), it.value() ); #else - vst_de.setAttribute( it.key(), it.data() ); + _this.setAttribute( it.key(), it.data() ); #endif } } m_pluginMutex.unlock(); - _parent.appendChild( vst_de ); } @@ -258,9 +255,9 @@ void vestigeInstrument::setParameter( const QString & _param, { m_pluginMutex.lock(); bool set_ch_name = ( m_plugin != NULL && - getChannelTrack()->name() == m_plugin->name() ) || - getChannelTrack()->name() == - channelTrack::tr( "Default" ); + getInstrumentTrack()->name() == m_plugin->name() ) || + getInstrumentTrack()->name() == + instrumentTrack::tr( "Default" ); m_pluginMutex.unlock(); closePlugin(); @@ -305,16 +302,16 @@ void vestigeInstrument::setParameter( const QString & _param, m_plugin->setTempo( eng()->getSongEditor()->getTempo() ); if( set_ch_name == TRUE ) { - getChannelTrack()->setName( m_plugin->name() ); + getInstrumentTrack()->setName( m_plugin->name() ); } if( m_plugin->pluginWidget() != NULL ) { #ifdef QT4 m_plugin->pluginWidget()->setWindowIcon( - getChannelTrack()->windowIcon() ); + getInstrumentTrack()->windowIcon() ); #else m_plugin->pluginWidget()->setWindowIcon( - *( getChannelTrack()->windowIcon() ) ); + *( getInstrumentTrack()->windowIcon() ) ); #endif } m_pluginMutex.unlock(); @@ -339,7 +336,7 @@ void vestigeInstrument::play( void ) m_plugin->process( NULL, buf ); - getChannelTrack()->processAudioBuffer( buf, frames, NULL ); + getInstrumentTrack()->processAudioBuffer( buf, frames, NULL ); bufferAllocator::free( buf ); } @@ -355,7 +352,7 @@ void vestigeInstrument::playNote( notePlayHandle * _n ) if( _n->totalFramesPlayed() == 0 && m_plugin != NULL ) { m_plugin->enqueueMidiEvent( midiEvent( NOTE_ON, 0, - getChannelTrack()->masterKey( _n ), + getInstrumentTrack()->masterKey( _n ), _n->getVolume() ), _n->framesAhead() ); } m_pluginMutex.unlock(); @@ -370,7 +367,7 @@ void vestigeInstrument::deleteNotePluginData( notePlayHandle * _n ) if( m_plugin != NULL ) { m_plugin->enqueueMidiEvent( midiEvent( NOTE_OFF, 0, - getChannelTrack()->masterKey( _n ), + getInstrumentTrack()->masterKey( _n ), 0 ), 0 ); } m_pluginMutex.unlock(); @@ -551,7 +548,7 @@ extern "C" // neccessary for getting instance out of shared lib plugin * lmms_plugin_main( void * _data ) { - return( new vestigeInstrument( static_cast( _data ) ) ); + return( new vestigeInstrument( static_cast( _data ) ) ); } diff --git a/plugins/vestige/vestige.h b/plugins/vestige/vestige.h index 9dadb73c1..d45d0be6d 100644 --- a/plugins/vestige/vestige.h +++ b/plugins/vestige/vestige.h @@ -53,7 +53,7 @@ class vestigeInstrument : public instrument, public specialBgHandlingWidget { Q_OBJECT public: - vestigeInstrument( channelTrack * _channel_track ); + vestigeInstrument( instrumentTrack * _channel_track ); virtual ~vestigeInstrument(); virtual void play( void ); diff --git a/src/core/arp_and_chords_tab_widget.cpp b/src/core/arp_and_chords_tab_widget.cpp index 95c7dbcf1..2a30cb007 100644 --- a/src/core/arp_and_chords_tab_widget.cpp +++ b/src/core/arp_and_chords_tab_widget.cpp @@ -2,7 +2,7 @@ /* * arp_and_chords_tab_widget.cpp - widget for use in arp/chord-tab of - * channel-window + * instrument-track-window * * Copyright (c) 2004-2006 Tobias Doerffel * @@ -57,7 +57,7 @@ #include "tooltip.h" #include "gui_templates.h" #include "tempo_sync_knob.h" -#include "channel_track.h" +#include "instrument_track.h" #include "led_checkbox.h" #include "preset_preview_play_handle.h" #include "combobox.h" @@ -194,10 +194,9 @@ const int ARP_GROUPBOX_HEIGHT = 240 - ARP_GROUPBOX_Y; -arpAndChordsTabWidget::arpAndChordsTabWidget( channelTrack * _channel_track ) : - QWidget( _channel_track->tabWidgetParent() ), - settings(), - engineObject( _channel_track->eng() ) +arpAndChordsTabWidget::arpAndChordsTabWidget( instrumentTrack * _instrument_track ) : + QWidget( _instrument_track->tabWidgetParent() ), + journallingObject( _instrument_track->eng() ) { m_chordsGroupBox = new groupBox( tr( "CHORDS" ), this, eng() ); m_chordsGroupBox->setGeometry( CHORDS_GROUPBOX_X, CHORDS_GROUPBOX_Y, @@ -449,7 +448,8 @@ void arpAndChordsTabWidget::processNote( notePlayHandle * _n ) break; } // create copy of base-note - note note_copy( 0, 0, (tones)( sub_note_key % + note note_copy( NULL, 0, 0, + (tones)( sub_note_key % NOTES_PER_OCTAVE ), (octaves)( sub_note_key / NOTES_PER_OCTAVE ), @@ -459,9 +459,9 @@ void arpAndChordsTabWidget::processNote( notePlayHandle * _n ) // different notePlayHandle * note_play_handle = new notePlayHandle( - _n->getChannelTrack(), + _n->getInstrumentTrack(), _n->framesAhead(), - _n->frames(), ¬e_copy ); + _n->frames(), note_copy ); // add sub-note to base-note, now all stuff is // done by notePlayHandle::play_note() _n->addSubNote( note_play_handle ); @@ -484,12 +484,12 @@ void arpAndChordsTabWidget::processNote( notePlayHandle * _n ) const int selected_arp = m_arpComboBox->value(); constNotePlayHandleVector cnphv = notePlayHandle::nphsOfChannelTrack( - _n->getChannelTrack() ); + _n->getInstrumentTrack() ); if( m_arpModeComboBox->value() != FREE && cnphv.size() == 0 ) { // maybe we're playing only a preset-preview-note? cnphv = presetPreviewPlayHandle::nphsOfChannelTrack( - _n->getChannelTrack() ); + _n->getInstrumentTrack() ); if( cnphv.size() == 0 ) { // still nothing found here, so lets return @@ -600,7 +600,7 @@ void arpAndChordsTabWidget::processNote( notePlayHandle * _n ) } // create new arp-note - note new_note( midiTime( 0 ), midiTime( 0 ), + note new_note( NULL, midiTime( 0 ), midiTime( 0 ), static_cast( sub_note_key % NOTES_PER_OCTAVE ), static_cast( sub_note_key / @@ -612,14 +612,14 @@ void arpAndChordsTabWidget::processNote( notePlayHandle * _n ) // duplicate note-play-handle, only ptr to note is different // and is_arp_note=TRUE notePlayHandle * note_play_handle = new notePlayHandle( - _n->getChannelTrack(), + _n->getInstrumentTrack(), ( ( m_arpModeComboBox->value() != FREE ) ? cnphv.first()->framesAhead() : _n->framesAhead() ) + frames_processed, gated_frames, - &new_note, + new_note, TRUE ); // add sub-note to base-note - now all stuff is done by @@ -643,24 +643,22 @@ void arpAndChordsTabWidget::processNote( notePlayHandle * _n ) void arpAndChordsTabWidget::saveSettings( QDomDocument & _doc, - QDomElement & _parent ) + QDomElement & _this ) { - QDomElement act_de = _doc.createElement( nodeName() ); - act_de.setAttribute( "chorddisabled", !m_chordsGroupBox->isActive() ); - act_de.setAttribute( "chord", m_chordsComboBox->value() ); - act_de.setAttribute( "chordrange", m_chordRangeKnob->value() ); + _this.setAttribute( "chorddisabled", !m_chordsGroupBox->isActive() ); + _this.setAttribute( "chord", m_chordsComboBox->value() ); + _this.setAttribute( "chordrange", m_chordRangeKnob->value() ); - act_de.setAttribute( "arpdisabled", !m_arpGroupBox->isActive() ); - act_de.setAttribute( "arp", m_arpComboBox->value() ); - act_de.setAttribute( "arprange", m_arpRangeKnob->value() ); - act_de.setAttribute( "arptime", m_arpTimeKnob->value() ); - act_de.setAttribute( "arpgate", m_arpGateKnob->value() ); - act_de.setAttribute( "arpdir", m_arpDirectionBtnGrp->value() ); - act_de.setAttribute( "arpsyncmode", + _this.setAttribute( "arpdisabled", !m_arpGroupBox->isActive() ); + _this.setAttribute( "arp", m_arpComboBox->value() ); + _this.setAttribute( "arprange", m_arpRangeKnob->value() ); + _this.setAttribute( "arptime", m_arpTimeKnob->value() ); + _this.setAttribute( "arpgate", m_arpGateKnob->value() ); + _this.setAttribute( "arpdir", m_arpDirectionBtnGrp->value() ); + _this.setAttribute( "arpsyncmode", ( int ) m_arpTimeKnob->getSyncMode() ); - act_de.setAttribute( "arpmode", m_arpModeComboBox->value() ); - _parent.appendChild( act_de ); + _this.setAttribute( "arpmode", m_arpModeComboBox->value() ); } diff --git a/src/core/engine.cpp b/src/core/engine.cpp index b0fd6155f..03307137e 100644 --- a/src/core/engine.cpp +++ b/src/core/engine.cpp @@ -26,7 +26,7 @@ #include "bb_editor.h" -#include "edit_history.h" +#include "project_journal.h" #include "engine.h" #include "main_window.h" #include "mixer.h" @@ -43,9 +43,9 @@ engine::engine( const bool _has_gui ) : m_songEditor( NULL ), m_bbEditor( NULL ), m_pianoRoll( NULL ), - m_editHistory( NULL ) + m_projectJournal( NULL ) { - m_editHistory = new editHistory( this ); + m_projectJournal = new projectJournal( this ); m_mainWindow = new mainWindow( this ); m_mixer = new mixer( this ); m_songEditor = new songEditor( this ); diff --git a/src/core/envelope_and_lfo_widget.cpp b/src/core/envelope_and_lfo_widget.cpp index 34fc7b04a..4c16bf239 100644 --- a/src/core/envelope_and_lfo_widget.cpp +++ b/src/core/envelope_and_lfo_widget.cpp @@ -110,13 +110,12 @@ envelopeAndLFOWidget::envelopeAndLFOWidget( float _value_for_zero_amount, QWidget * _parent, engine * _engine ) : QWidget( _parent ), - settings(), + journallingObject( _engine ), #ifdef QT4 specialBgHandlingWidget( palette().color( backgroundRole() ) ), #else specialBgHandlingWidget( paletteBackgroundColor() ), #endif - engineObject( _engine ), m_used( FALSE ), m_valueForZeroAmount( _value_for_zero_amount ), m_pahdEnv( NULL ), diff --git a/src/core/envelope_tab_widget.cpp b/src/core/envelope_tab_widget.cpp index 05cc2835c..02b64a216 100644 --- a/src/core/envelope_tab_widget.cpp +++ b/src/core/envelope_tab_widget.cpp @@ -2,7 +2,7 @@ /* * envelope_tab_widget.cpp - widget for use in envelope/lfo/filter-tab of - * channel-window + * instrument-track-window * * Copyright (c) 2004-2006 Tobias Doerffel * @@ -50,7 +50,7 @@ #include "tab_widget.h" #include "embed.h" #include "gui_templates.h" -#include "channel_track.h" +#include "instrument_track.h" #include "combobox.h" @@ -83,10 +83,9 @@ static const QString targetNames[envelopeTabWidget::TARGET_COUNT][2] = -envelopeTabWidget::envelopeTabWidget( channelTrack * _channel_track ) : - QWidget( _channel_track->tabWidgetParent() ), - settings(), - engineObject( _channel_track->eng() ) +envelopeTabWidget::envelopeTabWidget( instrumentTrack * _instrument_track ) : + QWidget( _instrument_track->tabWidgetParent() ), + journallingObject( _instrument_track->eng() ) { m_targetsTabWidget = new tabWidget( tr( "TARGET" ), this ); @@ -171,14 +170,14 @@ envelopeTabWidget::envelopeTabWidget( channelTrack * _channel_track ) : QWhatsThis::add( m_filterComboBox, #endif tr( "Here you can select the built-in filter you want to use " - "in this channel. Filters are very important for " - "changing the characteristics of a sound." ) ); + "for this instrument-track. Filters are very important " + "for changing the characteristics of a sound." ) ); m_filterCutKnob = new knob( knobBright_26, m_filterGroupBox, tr( "cutoff-frequency" ), eng() ); m_filterCutKnob->setLabel( tr( "CUTOFF" ) ); - m_filterCutKnob->setRange( 0.0, 10000.0, 1.0 ); + m_filterCutKnob->setRange( 0.0, 14000.0, 1.0 ); m_filterCutKnob->move( 140, 18 ); m_filterCutKnob->setInitValue( 16000.0 ); m_filterCutKnob->setHintText( tr( "cutoff-frequency:" ) + " ", " " + @@ -494,24 +493,18 @@ f_cnt_t envelopeTabWidget::releaseFrames( void ) -void envelopeTabWidget::saveSettings( QDomDocument & _doc, - QDomElement & _parent ) +void envelopeTabWidget::saveSettings( QDomDocument & _doc, QDomElement & _this ) { - QDomElement etw_de = _doc.createElement( nodeName() ); - etw_de.setAttribute( "ftype", m_filterComboBox->value() ); - etw_de.setAttribute( "fcut", m_filterCutKnob->value() ); - etw_de.setAttribute( "fres", m_filterResKnob->value() ); - etw_de.setAttribute( "fwet", m_filterGroupBox->isActive() ); - _parent.appendChild( etw_de ); + _this.setAttribute( "ftype", m_filterComboBox->value() ); + _this.setAttribute( "fcut", m_filterCutKnob->value() ); + _this.setAttribute( "fres", m_filterResKnob->value() ); + _this.setAttribute( "fwet", m_filterGroupBox->isActive() ); for( int i = 0; i < TARGET_COUNT; ++i ) { - QDomElement target_de = _doc.createElement( - m_envLFOWidgets[i]->nodeName() + - QString( - targetNames[i][1] ).toLower() ); - m_envLFOWidgets[i]->saveSettings( _doc, target_de ); - etw_de.appendChild( target_de ); + m_envLFOWidgets[i]->saveState( _doc, _this ).setTagName( + m_envLFOWidgets[i]->nodeName() + + QString( targetNames[i][1] ).toLower() ); } } @@ -537,7 +530,7 @@ void envelopeTabWidget::loadSettings( const QDomElement & _this ) m_envLFOWidgets[i]->nodeName() + QString( targetNames[i][1] ).toLower() ) { - m_envLFOWidgets[i]->loadSettings( + m_envLFOWidgets[i]->restoreState( node.toElement() ); } } diff --git a/src/core/file_browser.cpp b/src/core/file_browser.cpp index 50b284bb1..360f6f4fb 100644 --- a/src/core/file_browser.cpp +++ b/src/core/file_browser.cpp @@ -51,7 +51,7 @@ #include "song_editor.h" #include "bb_editor.h" #include "embed.h" -#include "channel_track.h" +#include "instrument_track.h" #include "mmp.h" #include "preset_preview_play_handle.h" #include "sample_play_handle.h" @@ -177,14 +177,17 @@ void fileBrowser::contextMenuRequest( QListViewItem * i, const QPoint &, int ) { m_contextMenuItem = f; QMenu * contextMenu = new QMenu( this ); - contextMenu->addAction( tr( "Send to active channel" ), this, - SLOT( sendToActiveChannel() ) ); - contextMenu->addAction( tr( "Open in new channel/Song-Editor" ), + contextMenu->addAction( tr( "Send to active instrument-track" ), this, - SLOT( openInNewChannelSE() ) ); - contextMenu->addAction( tr( "Open in new channel/B+B Editor" ), + SLOT( sendToActiveInstrumentTrack() ) ); + contextMenu->addAction( tr( "Open in new instrument-track/" + "Song-Editor" ), this, - SLOT( openInNewChannelBBE() ) ); + SLOT( openInNewInstrumentTrackSE() ) ); + contextMenu->addAction( tr( "Open in new instrument-track/" + "B+B Editor" ), + this, + SLOT( openInNewInstrumentTrackBBE() ) ); contextMenu->exec( QCursor::pos() ); m_contextMenuItem = NULL; delete contextMenu; @@ -195,7 +198,7 @@ void fileBrowser::contextMenuRequest( QListViewItem * i, const QPoint &, int ) -void fileBrowser::sendToActiveChannel( void ) +void fileBrowser::sendToActiveInstrumentTrack( void ) { if( eng()->getMainWindow()->workspace() != NULL ) { @@ -209,24 +212,24 @@ void fileBrowser::sendToActiveChannel( void ) #ifdef QT4 QListIterator w( pl ); w.toBack(); - // now we travel through the window-list until we find a - // channel-track + // now we travel through the window-list until we find an + // instrument-track while( w.hasPrevious() ) { - channelTrack * ct = dynamic_cast( + instrumentTrack * ct = dynamic_cast( w.previous() ); #else QWidget * w = pl.last(); - // now we travel through the window-list until we find a - // channel-track + // now we travel through the window-list until we find an + // instrument-track while( w != NULL ) { - channelTrack * ct = dynamic_cast( w ); + instrumentTrack * ct = dynamic_cast( w ); #endif if( ct != NULL && ct->isHidden() == FALSE ) { - // ok, it's a channel-track, so we can apply the - // sample or the preset + // ok, it's an instrument-track, so we can apply + // the sample or the preset if( m_contextMenuItem->type() == fileItem::SAMPLE_FILE ) { @@ -248,7 +251,7 @@ void fileBrowser::sendToActiveChannel( void ) firstChild(). toElement() ); } - ct->toggledChannelButton( TRUE ); + ct->toggledInstrumentTrackButton( TRUE ); break; } #ifndef QT4 @@ -261,11 +264,11 @@ void fileBrowser::sendToActiveChannel( void ) -void fileBrowser::openInNewChannel( trackContainer * _tc ) +void fileBrowser::openInNewInstrumentTrack( trackContainer * _tc ) { if( m_contextMenuItem->type() == fileItem::SAMPLE_FILE ) { - channelTrack * ct = dynamic_cast( + instrumentTrack * ct = dynamic_cast( track::create( track::CHANNEL_TRACK, _tc ) ); #ifdef LMMS_DEBUG assert( ct != NULL ); @@ -276,19 +279,19 @@ void fileBrowser::openInNewChannel( trackContainer * _tc ) afp->setParameter( "samplefile", m_contextMenuItem->fullName() ); } - ct->toggledChannelButton( TRUE ); + ct->toggledInstrumentTrackButton( TRUE ); } else if( m_contextMenuItem->type() == fileItem::PRESET_FILE ) { multimediaProject mmp( m_contextMenuItem->fullName() ); track * t = track::create( track::CHANNEL_TRACK, _tc ); - channelTrack * ct = dynamic_cast( t ); + instrumentTrack * ct = dynamic_cast( t ); if( ct != NULL ) { ct->loadTrackSpecificSettings( mmp.content(). firstChild(). toElement() ); - ct->toggledChannelButton( TRUE ); + ct->toggledInstrumentTrackButton( TRUE ); } } } @@ -296,17 +299,17 @@ void fileBrowser::openInNewChannel( trackContainer * _tc ) -void fileBrowser::openInNewChannelSE( void ) +void fileBrowser::openInNewInstrumentTrackSE( void ) { - openInNewChannel( eng()->getSongEditor() ); + openInNewInstrumentTrack( eng()->getSongEditor() ); } -void fileBrowser::openInNewChannelBBE( void ) +void fileBrowser::openInNewInstrumentTrackBBE( void ) { - openInNewChannel( eng()->getBBEditor() ); + openInNewInstrumentTrack( eng()->getBBEditor() ); } @@ -352,7 +355,7 @@ void listView::contentsMouseDoubleClickEvent( QMouseEvent * _me ) { // samples are per default opened in bb-editor because // they're likely drum-samples etc. - channelTrack * ct = dynamic_cast( + instrumentTrack * ct = dynamic_cast( track::create( track::CHANNEL_TRACK, eng()->getBBEditor() ) ); #ifdef LMMS_DEBUG @@ -365,7 +368,7 @@ void listView::contentsMouseDoubleClickEvent( QMouseEvent * _me ) afp->setParameter( "samplefile", f->fullName() ); } - ct->toggledChannelButton( TRUE ); + ct->toggledInstrumentTrackButton( TRUE ); } else if( f->type() == fileItem::PRESET_FILE ) { @@ -373,13 +376,13 @@ void listView::contentsMouseDoubleClickEvent( QMouseEvent * _me ) multimediaProject mmp( f->fullName() ); track * t = track::create( track::CHANNEL_TRACK, eng()->getBBEditor() ); - channelTrack * ct = dynamic_cast( t ); + instrumentTrack * ct = dynamic_cast( t ); if( ct != NULL ) { ct->loadTrackSpecificSettings( mmp.content(). firstChild(). toElement() ); - ct->toggledChannelButton( TRUE ); + ct->toggledInstrumentTrackButton( TRUE ); } } else if( f->type() == fileItem::PROJECT_FILE ) @@ -797,7 +800,7 @@ void fileItem::determineFileType( void ) { m_type = PROJECT_FILE; } - else if( t == multimediaProject::CHANNEL_SETTINGS ) + else if( t == multimediaProject::INSTRUMENT_TRACK_SETTINGS ) { m_type = PRESET_FILE; } diff --git a/src/core/instrument.cpp b/src/core/instrument.cpp index 5ededdf0a..3927002e7 100644 --- a/src/core/instrument.cpp +++ b/src/core/instrument.cpp @@ -26,19 +26,19 @@ #include "instrument.h" -#include "channel_track.h" +#include "instrument_track.h" #include "dummy_instrument.h" -instrument::instrument( channelTrack * _channel_track, +instrument::instrument( instrumentTrack * _instrument_track, const descriptor * _descriptor ) : - QWidget( _channel_track->tabWidgetParent() ), - plugin( _descriptor, _channel_track->eng() ), - m_channelTrack( _channel_track ), + QWidget( _instrument_track->tabWidgetParent() ), + plugin( _descriptor, _instrument_track->eng() ), + m_instrumentTrack( _instrument_track ), m_valid( TRUE ) { setFixedSize( 250, 250 ); - m_channelTrack->setWindowIcon( *getDescriptor()->logo ); + m_instrumentTrack->setWindowIcon( *getDescriptor()->logo ); } @@ -81,9 +81,9 @@ f_cnt_t instrument::beatLen( notePlayHandle * ) const instrument * instrument::instantiate( const QString & _plugin_name, - channelTrack * _channel_track ) + instrumentTrack * _instrument_track ) { - plugin * p = plugin::instantiate( _plugin_name, _channel_track ); + plugin * p = plugin::instantiate( _plugin_name, _instrument_track ); // check whether instantiated plugin is an instrument if( dynamic_cast( p ) != NULL ) { @@ -93,7 +93,7 @@ instrument * instrument::instantiate( const QString & _plugin_name, // not quite... so delete plugin and return dummy instrument delete p; - return( new dummyInstrument( _channel_track ) ); + return( new dummyInstrument( _instrument_track ) ); } diff --git a/src/core/main_window.cpp b/src/core/main_window.cpp index f8726a97a..2e3fc3139 100644 --- a/src/core/main_window.cpp +++ b/src/core/main_window.cpp @@ -76,7 +76,7 @@ #include "setup_dialog.h" #include "audio_dummy.h" #include "tool_button.h" -#include "edit_history.h" +#include "project_journal.h" #if QT_VERSION >= 0x030100 @@ -621,8 +621,9 @@ void mainWindow::restoreWidgetState( QWidget * _w, const QDomElement & _de ) _de.attribute( "height" ).toInt() ); if( !r.isNull() ) { - _w->setShown( _de.attribute( "visible" ).toInt() ); + _w->show(); _w->parentWidget()->move( r.topLeft() ); + _w->setShown( _de.attribute( "visible" ).toInt() ); _w->resize( r.size() ); } } @@ -857,7 +858,7 @@ void mainWindow::togglePianoRollWin( void ) void mainWindow::undo( void ) { - eng()->getEditHistory()->undo(); + eng()->getProjectJournal()->undo(); } @@ -865,7 +866,7 @@ void mainWindow::undo( void ) void mainWindow::redo( void ) { - eng()->getEditHistory()->redo(); + eng()->getProjectJournal()->redo(); } diff --git a/src/core/midi_tab_widget.cpp b/src/core/midi_tab_widget.cpp index 410e61b42..a9d9fd9aa 100644 --- a/src/core/midi_tab_widget.cpp +++ b/src/core/midi_tab_widget.cpp @@ -48,7 +48,7 @@ #include "midi_tab_widget.h" -#include "channel_track.h" +#include "instrument_track.h" #include "midi_port.h" #include "tab_widget.h" #include "led_checkbox.h" @@ -60,12 +60,11 @@ -midiTabWidget::midiTabWidget( channelTrack * _channel_track, +midiTabWidget::midiTabWidget( instrumentTrack * _instrument_track, midiPort * _port ) : - QWidget( _channel_track->tabWidgetParent() ), - settings(), - engineObject( _channel_track->eng() ), - m_channelTrack( _channel_track ), + QWidget( _instrument_track->tabWidgetParent() ), + journallingObject( _instrument_track->eng() ), + m_instrumentTrack( _instrument_track ), m_midiPort( _port ), m_readablePorts( NULL ), m_writeablePorts( NULL ) @@ -194,13 +193,12 @@ midiTabWidget::~midiTabWidget() -void midiTabWidget::saveSettings( QDomDocument & _doc, QDomElement & _parent ) +void midiTabWidget::saveSettings( QDomDocument & _doc, QDomElement & _this ) { - QDomElement mw_de = _doc.createElement( nodeName() ); - mw_de.setAttribute( "inputchannel", m_inputChannelSpinBox->value() ); - mw_de.setAttribute( "outputchannel", m_outputChannelSpinBox->value() ); - mw_de.setAttribute( "receive", m_receiveCheckBox->isChecked() ); - mw_de.setAttribute( "send", m_sendCheckBox->isChecked() ); + _this.setAttribute( "inputchannel", m_inputChannelSpinBox->value() ); + _this.setAttribute( "outputchannel", m_outputChannelSpinBox->value() ); + _this.setAttribute( "receive", m_receiveCheckBox->isChecked() ); + _this.setAttribute( "send", m_sendCheckBox->isChecked() ); if( m_readablePorts != NULL && m_receiveCheckBox->isChecked() == TRUE ) { @@ -230,7 +228,7 @@ void midiTabWidget::saveSettings( QDomDocument & _doc, QDomElement & _parent ) { rp.truncate( rp.length() - 1 ); } - mw_de.setAttribute( "inports", rp ); + _this.setAttribute( "inports", rp ); } if( m_writeablePorts != NULL && m_sendCheckBox->isChecked() == TRUE ) @@ -261,10 +259,8 @@ void midiTabWidget::saveSettings( QDomDocument & _doc, QDomElement & _parent ) { wp.truncate( wp.length() - 1 ); } - mw_de.setAttribute( "outports", wp ); + _this.setAttribute( "outports", wp ); } - - _parent.appendChild( mw_de ); } diff --git a/src/core/note.cpp b/src/core/note.cpp index e79c5c332..a2df53160 100644 --- a/src/core/note.cpp +++ b/src/core/note.cpp @@ -45,8 +45,10 @@ -note::note( const midiTime & _length, const midiTime & _pos, tones _tone, - octaves _octave, volume _volume, panning _panning ) : +note::note( engine * _engine, const midiTime & _length, const midiTime & _pos, + tones _tone, octaves _octave, volume _volume, + panning _panning ) : + journallingObject( _engine ), m_tone( C ), m_octave( DEFAULT_OCTAVE ), m_volume( DEFAULT_VOLUME ), @@ -54,10 +56,15 @@ note::note( const midiTime & _length, const midiTime & _pos, tones _tone, m_length( _length ), m_pos( _pos ) { + //saveJournallingState( FALSE ); + setJournalling( FALSE ); + setTone( _tone ); setOctave( _octave ); setVolume( _volume ); setPanning( _panning ); + + //restoreJournallingState(); } @@ -72,6 +79,7 @@ note::~note() void note::setLength( const midiTime & _length ) { + addJournalEntry( journalEntry( CHANGE_LENGTH, m_length - _length ) ); m_length = _length; } @@ -80,6 +88,7 @@ void note::setLength( const midiTime & _length ) void note::setPos( const midiTime & _pos ) { + addJournalEntry( journalEntry( CHANGE_POSITION, m_pos - _pos ) ); m_pos = _pos; } @@ -88,17 +97,9 @@ void note::setPos( const midiTime & _pos ) void note::setTone( const tones _tone ) { - if( _tone >= C && _tone <= H ) - { - m_tone = _tone; - } - else - { - m_tone = tLimit( _tone, C, H ); -#ifdef LMMS_DEBUG - printf ( "Tone out of range (note::setTone)\n" ); -#endif - } + const tones t = tLimit( _tone, C, H ); + addJournalEntry( journalEntry( CHANGE_KEY, (int) m_tone - t ) ); + m_tone = t; } @@ -106,17 +107,10 @@ void note::setTone( const tones _tone ) void note::setOctave( const octaves _octave ) { - if( _octave >= MIN_OCTAVE && _octave <= MAX_OCTAVE ) - { - m_octave = _octave; - } - else - { - m_octave = tLimit( _octave, MIN_OCTAVE, MAX_OCTAVE ); -#ifdef LMMS_DEBUG - printf( "Octave out of range (note::setOctave)\n" ); -#endif - } + const octaves o = tLimit( _octave, MIN_OCTAVE, MAX_OCTAVE ); + addJournalEntry( journalEntry( CHANGE_KEY, NOTES_PER_OCTAVE * + ( (int) m_octave - o ) ) ); + m_octave = o; } @@ -124,8 +118,12 @@ void note::setOctave( const octaves _octave ) void note::setKey( const int _key ) { + const int k = key(); + saveJournallingState( FALSE ); setTone( static_cast( _key % NOTES_PER_OCTAVE ) ); setOctave( static_cast( _key / NOTES_PER_OCTAVE ) ); + restoreJournallingState(); + addJournalEntry( journalEntry( CHANGE_KEY, k - key() ) ); } @@ -133,17 +131,9 @@ void note::setKey( const int _key ) void note::setVolume( const volume _volume ) { - if( _volume <= MAX_VOLUME ) - { - m_volume = _volume; - } - else - { - m_volume = tMin( _volume, MAX_VOLUME ); -#ifdef LMMS_DEBUG - printf( "Volume out of range (note::setVolume)\n" ); -#endif - } + const volume v = tMin( _volume, MAX_VOLUME ); + addJournalEntry( journalEntry( CHANGE_VOLUME, (int) m_volume - v ) ); + m_volume = v; } @@ -151,16 +141,9 @@ void note::setVolume( const volume _volume ) void note::setPanning( const panning _panning ) { - if( _panning >= PANNING_LEFT && _panning <= PANNING_RIGHT ) - { - m_panning = _panning; - } -#ifdef LMMS_DEBUG - else - { - printf( "Paning out of range (note::setPanning)\n" ); - } -#endif + const panning p = tLimit( _panning, PANNING_LEFT, PANNING_RIGHT ); + addJournalEntry( journalEntry( CHANGE_PANNING, (int) m_panning - p ) ); + m_panning = p; } @@ -199,16 +182,14 @@ void note::quantizePos( const int _q_grid ) -void note::saveSettings( QDomDocument & _doc, QDomElement & _parent ) +void note::saveSettings( QDomDocument & _doc, QDomElement & _this ) { - QDomElement note_de = _doc.createElement( "note" ); - note_de.setAttribute( "tone", m_tone ); - note_de.setAttribute( "oct", m_octave ); - note_de.setAttribute( "vol", m_volume ); - note_de.setAttribute( "pan", m_panning ); - note_de.setAttribute( "len", m_length ); - note_de.setAttribute( "pos", m_pos ); - _parent.appendChild( note_de ); + _this.setAttribute( "tone", m_tone ); + _this.setAttribute( "oct", m_octave ); + _this.setAttribute( "vol", m_volume ); + _this.setAttribute( "pan", m_panning ); + _this.setAttribute( "len", m_length ); + _this.setAttribute( "pos", m_pos ); } @@ -227,5 +208,43 @@ void note::loadSettings( const QDomElement & _this ) +void note::undoStep( journalEntry & _je ) +{ + saveJournallingState( FALSE ); + switch( static_cast( _je.actionID() ) ) + { + case CHANGE_KEY: + setKey( key() - _je.data().toInt() ); + break; + + case CHANGE_VOLUME: + setVolume( getVolume() - _je.data().toInt() ); + break; + + case CHANGE_PANNING: + setVolume( getPanning() - _je.data().toInt() ); + break; + + case CHANGE_LENGTH: + setLength( length() - _je.data().toInt() ); + break; + + case CHANGE_POSITION: + setPos( pos() - _je.data().toInt() ); + break; + } + restoreJournallingState(); +} + + + + +void note::redoStep( journalEntry & _je ) +{ + journalEntry je( _je.actionID(), -_je.data().toInt() ); + undoStep( je ); +} + + #endif diff --git a/src/core/note_play_handle.cpp b/src/core/note_play_handle.cpp index ececd7968..8a2ad2c8e 100644 --- a/src/core/note_play_handle.cpp +++ b/src/core/note_play_handle.cpp @@ -27,26 +27,27 @@ #include "note_play_handle.h" -#include "channel_track.h" +#include "instrument_track.h" #include "envelope_tab_widget.h" #include "midi.h" #include "midi_port.h" #include "song_editor.h" #include "piano_widget.h" #include "config_mgr.h" +#include "project_journal.h" - -notePlayHandle::notePlayHandle( channelTrack * _chnl_trk, +notePlayHandle::notePlayHandle( instrumentTrack * _it, const f_cnt_t _frames_ahead, const f_cnt_t _frames, - note * _n, + const note & _n, const bool _arp_note ) : - playHandle( NOTE_PLAY_HANDLE, _chnl_trk->eng() ), - note( *_n ), + playHandle( NOTE_PLAY_HANDLE ), + note( NULL, _n.length(), _n.pos(), _n.tone(), _n.octave(), + _n.getVolume(), _n.getPanning() ), m_pluginData( NULL ), m_filter( NULL ), - m_channelTrack( _chnl_trk ), + m_instrumentTrack( _it ), m_frames( 0 ), m_framesAhead( _frames_ahead ), m_totalFramesPlayed( 0 ), @@ -62,18 +63,18 @@ notePlayHandle::notePlayHandle( channelTrack * _chnl_trk, if( !configManager::inst()->value( "ui", "manualchannelpiano" ).toInt() ) { - m_channelTrack->m_pianoWidget->setKeyState( key(), TRUE ); + m_instrumentTrack->m_pianoWidget->setKeyState( key(), TRUE ); } // send MIDI-note-on-event - m_channelTrack->processOutEvent( midiEvent( NOTE_ON, - m_channelTrack->m_midiPort->outputChannel(), + m_instrumentTrack->processOutEvent( midiEvent( NOTE_ON, + m_instrumentTrack->m_midiPort->outputChannel(), key(), tLimit( (Uint16) ( ( getVolume() / 100.0f ) * - ( m_channelTrack->getVolume() / 100.0f ) * + ( m_instrumentTrack->getVolume() / 100.0f ) * 127 ), 0, 127 ) ), midiTime::fromFrames( m_framesAhead, - eng()->getSongEditor()->framesPerTact() ) ); + m_instrumentTrack->eng()->getSongEditor()->framesPerTact() ) ); } @@ -86,9 +87,9 @@ notePlayHandle::~notePlayHandle() noteOff( 0 ); } - if( m_channelTrack != NULL ) + if( m_instrumentTrack != NULL ) { - m_channelTrack->deleteNotePluginData( this ); + m_instrumentTrack->deleteNotePluginData( this ); } for( notePlayHandleVector::iterator it = m_subNotes.begin(); @@ -106,24 +107,26 @@ notePlayHandle::~notePlayHandle() void notePlayHandle::play( void ) { - if( m_muted == TRUE || m_channelTrack == NULL ) + if( m_muted == TRUE || m_instrumentTrack == NULL ) { return; } if( m_released == FALSE && m_totalFramesPlayed + - eng()->getMixer()->framesPerAudioBuffer() >= m_frames ) + m_instrumentTrack->eng()->getMixer()->framesPerAudioBuffer() >= + m_frames ) { noteOff( m_frames - m_totalFramesPlayed ); } // play note! - m_channelTrack->playNote( this ); + m_instrumentTrack->playNote( this ); if( m_released == TRUE ) { - f_cnt_t todo = eng()->getMixer()->framesPerAudioBuffer(); + f_cnt_t todo = + m_instrumentTrack->eng()->getMixer()->framesPerAudioBuffer(); // if this note is base-note for arpeggio, always set // m_releaseFramesToDo to bigger value than m_releaseFramesDone // because we do not allow notePlayHandle::done() to be true @@ -132,7 +135,7 @@ void notePlayHandle::play( void ) if( arpBaseNote() == TRUE ) { m_releaseFramesToDo = m_releaseFramesDone + 2 * - eng()->getMixer()->framesPerAudioBuffer(); + m_instrumentTrack->eng()->getMixer()->framesPerAudioBuffer(); } // look whether we have frames left to be done before release if( m_framesBeforeRelease ) @@ -140,7 +143,7 @@ void notePlayHandle::play( void ) // yes, then look whether these samples can be played // within one audio-buffer if( m_framesBeforeRelease <= - eng()->getMixer()->framesPerAudioBuffer() ) + m_instrumentTrack->eng()->getMixer()->framesPerAudioBuffer() ) { // yes, then we did less releaseFramesDone todo -= m_framesBeforeRelease; @@ -153,7 +156,7 @@ void notePlayHandle::play( void ) // release-phase yet) todo = 0; m_framesBeforeRelease -= - eng()->getMixer()->framesPerAudioBuffer(); + m_instrumentTrack->eng()->getMixer()->framesPerAudioBuffer(); } } // look whether we're in release-phase @@ -201,7 +204,8 @@ void notePlayHandle::play( void ) } // update internal data - m_totalFramesPlayed += eng()->getMixer()->framesPerAudioBuffer(); + m_totalFramesPlayed += + m_instrumentTrack->eng()->getMixer()->framesPerAudioBuffer(); } @@ -209,8 +213,8 @@ void notePlayHandle::play( void ) void notePlayHandle::checkValidity( void ) { - if( m_channelTrack != NULL && - m_channelTrack->type() == track::NULL_TRACK ) + if( m_instrumentTrack != NULL && + m_instrumentTrack->type() == track::NULL_TRACK ) { // track-type being track::NULL_TRACK indicates a track whose // removal is in progress, so we have to invalidate ourself @@ -218,8 +222,8 @@ void notePlayHandle::checkValidity( void ) { noteOff( 0 ); } - m_channelTrack->deleteNotePluginData( this ); - m_channelTrack = NULL; + m_instrumentTrack->deleteNotePluginData( this ); + m_instrumentTrack = NULL; } // sub-notes might not be registered at mixer (for example arpeggio- // notes), so they wouldn't invalidate them-selves @@ -244,23 +248,23 @@ void notePlayHandle::noteOff( const f_cnt_t _s ) // then set some variables indicating release-state m_framesBeforeRelease = _s; - if( m_channelTrack != NULL ) + if( m_instrumentTrack != NULL ) { m_releaseFramesToDo = tMax( 10, - m_channelTrack->m_envWidget->releaseFrames() ); + m_instrumentTrack->m_envWidget->releaseFrames() ); if( !configManager::inst()->value( "ui", "manualchannelpiano" ).toInt() ) { - m_channelTrack->m_pianoWidget->setKeyState( key(), + m_instrumentTrack->m_pianoWidget->setKeyState( key(), FALSE ); } // send MIDI-note-off-event - m_channelTrack->processOutEvent( midiEvent( NOTE_OFF, - m_channelTrack->m_midiPort->outputChannel(), + m_instrumentTrack->processOutEvent( midiEvent( NOTE_OFF, + m_instrumentTrack->m_midiPort->outputChannel(), key(), 0 ), midiTime::fromFrames( m_framesBeforeRelease, - eng()->getSongEditor()->framesPerTact() ) ); + m_instrumentTrack->eng()->getSongEditor()->framesPerTact() ) ); } else { @@ -275,8 +279,8 @@ void notePlayHandle::noteOff( const f_cnt_t _s ) f_cnt_t notePlayHandle::actualReleaseFramesToDo( void ) const { - return( ( m_channelTrack != NULL ) ? - m_channelTrack->m_envWidget->releaseFrames() : 0 ); + return( ( m_instrumentTrack != NULL ) ? + m_instrumentTrack->m_envWidget->releaseFrames() : 0 ); } @@ -285,9 +289,9 @@ f_cnt_t notePlayHandle::actualReleaseFramesToDo( void ) const void notePlayHandle::setFrames( const f_cnt_t _frames ) { m_frames = _frames; - if( m_frames == 0 && m_channelTrack != NULL ) + if( m_frames == 0 && m_instrumentTrack != NULL ) { - m_frames = m_channelTrack->beatLen( this ); + m_frames = m_instrumentTrack->beatLen( this ); } } @@ -296,8 +300,8 @@ void notePlayHandle::setFrames( const f_cnt_t _frames ) float notePlayHandle::volumeLevel( const f_cnt_t _frame ) { - return( ( m_channelTrack != NULL ) ? - m_channelTrack->m_envWidget->volumeLevel( this, _frame ) : 0 ); + return( ( m_instrumentTrack != NULL ) ? + m_instrumentTrack->m_envWidget->volumeLevel( this, _frame ) : 0 ); } @@ -319,14 +323,15 @@ void notePlayHandle::mute( void ) int notePlayHandle::index( void ) const { - const playHandleVector & phv = eng()->getMixer()->playHandles(); + const playHandleVector & phv = + m_instrumentTrack->eng()->getMixer()->playHandles(); int idx = 0; for( constPlayHandleVector::const_iterator it = phv.begin(); it != phv.end(); ++it ) { const notePlayHandle * nph = dynamic_cast( *it ); - if( nph == NULL || nph->m_channelTrack != m_channelTrack || + if( nph == NULL || nph->m_instrumentTrack != m_instrumentTrack || nph->released() == TRUE ) { continue; @@ -344,9 +349,9 @@ int notePlayHandle::index( void ) const constNotePlayHandleVector notePlayHandle::nphsOfChannelTrack( - const channelTrack * _ct ) + const instrumentTrack * _it ) { - const playHandleVector & phv = _ct->eng()->getMixer()->playHandles(); + const playHandleVector & phv = _it->eng()->getMixer()->playHandles(); constNotePlayHandleVector cnphv; for( constPlayHandleVector::const_iterator it = phv.begin(); @@ -354,7 +359,7 @@ constNotePlayHandleVector notePlayHandle::nphsOfChannelTrack( { const notePlayHandle * nph = dynamic_cast( *it ); - if( nph != NULL && nph->m_channelTrack == _ct && + if( nph != NULL && nph->m_instrumentTrack == _it && nph->released() == FALSE ) { cnphv.push_back( nph ); @@ -372,7 +377,7 @@ bool notePlayHandle::operator==( const notePlayHandle & _nph ) const key() == _nph.key() && getVolume() == _nph.getVolume() && getPanning() == _nph.getPanning() && - m_channelTrack == _nph.m_channelTrack && + m_instrumentTrack == _nph.m_instrumentTrack && m_frames == _nph.m_frames && m_framesAhead == _nph.m_framesAhead && m_totalFramesPlayed == _nph.m_totalFramesPlayed && diff --git a/src/core/piano_roll.cpp b/src/core/piano_roll.cpp index 4074a4143..567dc52da 100644 --- a/src/core/piano_roll.cpp +++ b/src/core/piano_roll.cpp @@ -49,6 +49,7 @@ #include #define addButton insert +#define setCheckable setToggleButton #endif @@ -69,7 +70,7 @@ #include "templates.h" #include "gui_templates.h" #include "timeline.h" -#include "channel_track.h" +#include "instrument_track.h" #include "tooltip.h" #include "midi.h" #include "tool_button.h" @@ -131,7 +132,7 @@ const int DEFAULT_PR_PPT = KEY_LINE_HEIGHT * DEFAULT_STEPS_PER_TACT; pianoRoll::pianoRoll( engine * _engine ) : QWidget( _engine->getMainWindow()->workspace() ), - engineObject( _engine ), + journallingObject( _engine ), m_paintPixmap(), m_cursorInside( FALSE ), m_pattern( NULL ), @@ -545,7 +546,7 @@ void pianoRoll::setCurrentPattern( pattern * _new_pattern ) // and now connect to noteDone()-signal of channel so that // we receive note-off-events from it's midi-port for recording it - connect( m_pattern->getChannelTrack(), + connect( m_pattern->getInstrumentTrack(), SIGNAL( noteDone( const note & ) ), this, SLOT( recordNote( const note & ) ) ); @@ -557,11 +558,9 @@ void pianoRoll::setCurrentPattern( pattern * _new_pattern ) -void pianoRoll::saveSettings( QDomDocument & _doc, QDomElement & _parent ) +void pianoRoll::saveSettings( QDomDocument & _doc, QDomElement & _this ) { - QDomElement pr_de = _doc.createElement( nodeName() ); - mainWindow::saveWidgetState( this, pr_de ); - _parent.appendChild( pr_de ); + mainWindow::saveWidgetState( this, _this ); } @@ -1243,7 +1242,8 @@ void pianoRoll::mousePressEvent( QMouseEvent * _me ) midiTime note_pos( pos_tact_64th ); midiTime note_len( newNoteLen() ); - note new_note( note_len, note_pos, + note new_note( eng(), + note_len, note_pos, (tones)( key_num % NOTES_PER_OCTAVE ), (octaves)( key_num / @@ -1370,7 +1370,7 @@ void pianoRoll::mousePressEvent( QMouseEvent * _me ) if( play_note == TRUE && m_recording == FALSE && eng()->getSongEditor()->playing() == FALSE ) { - m_pattern->getChannelTrack()->processInEvent( + m_pattern->getInstrumentTrack()->processInEvent( midiEvent( NOTE_ON, 0, key_num, vol * 127 / 100 ), midiTime() ); @@ -1387,13 +1387,13 @@ void pianoRoll::mouseReleaseEvent( QMouseEvent * _me ) { if( m_action == CHANGE_NOTE_VOLUME && m_currentNote != NULL ) { - m_pattern->getChannelTrack()->processInEvent( + m_pattern->getInstrumentTrack()->processInEvent( midiEvent( NOTE_OFF, 0, m_currentNote->key(), 0 ), midiTime() ); } else { - m_pattern->getChannelTrack()->processInEvent( + m_pattern->getInstrumentTrack()->processInEvent( midiEvent( NOTE_OFF, 0, getKey( _me->y() ), 0 ), midiTime() ); } @@ -1446,7 +1446,7 @@ void pianoRoll::mouseMoveEvent( QMouseEvent * _me ) #endif Qt::LeftButton ) { - m_pattern->getChannelTrack()->processInEvent( + m_pattern->getInstrumentTrack()->processInEvent( midiEvent( NOTE_OFF, 0, released_key, 0 ), midiTime() ); if( @@ -1462,7 +1462,7 @@ void pianoRoll::mouseMoveEvent( QMouseEvent * _me ) m_recording == FALSE && eng()->getSongEditor()->playing() == FALSE ) { - m_pattern->getChannelTrack()->processInEvent( + m_pattern->getInstrumentTrack()->processInEvent( midiEvent( NOTE_ON, 0, key_num, DEFAULT_VOLUME * 127 / 100 ), midiTime() ); @@ -1487,7 +1487,7 @@ void pianoRoll::mouseMoveEvent( QMouseEvent * _me ) MAX_VOLUME ); m_currentNote->setVolume( vol ); m_pattern->update(); - m_pattern->getChannelTrack()->processInEvent( + m_pattern->getInstrumentTrack()->processInEvent( midiEvent( KEY_PRESSURE, 0, key_num, vol * 127 / 100 ), midiTime() ); @@ -2524,6 +2524,7 @@ midiTime pianoRoll::newNoteLen( void ) const #ifdef QT3 #undef addButton +#undef setCheckable #endif diff --git a/src/core/piano_widget.cpp b/src/core/piano_widget.cpp index 5e83d206f..91a7d29f8 100644 --- a/src/core/piano_widget.cpp +++ b/src/core/piano_widget.cpp @@ -42,7 +42,7 @@ #include "piano_widget.h" -#include "channel_track.h" +#include "instrument_track.h" #include "midi.h" #include "templates.h" #include "embed.h" @@ -77,9 +77,9 @@ const int PW_BLACK_KEY_HEIGHT = 38; const int LABEL_TEXT_SIZE = 7; -pianoWidget::pianoWidget (channelTrack * _parent ) : +pianoWidget::pianoWidget( instrumentTrack * _parent ) : QWidget( _parent ), - m_channelTrack( _parent ), + m_instrumentTrack( _parent ), m_startTone( C ), m_startOctave( OCTAVE_3 ) { @@ -242,7 +242,7 @@ void pianoWidget::mousePressEvent( QMouseEvent * _me ) vol = DEFAULT_VOLUME; } // set note on - m_channelTrack->processInEvent( + m_instrumentTrack->processInEvent( midiEvent( NOTE_ON, 0, key_num, vol * 127 / 100 ), midiTime() ); @@ -250,9 +250,9 @@ void pianoWidget::mousePressEvent( QMouseEvent * _me ) } else { - m_channelTrack->setBaseTone( static_cast( + m_instrumentTrack->setBaseTone( static_cast( key_num % NOTES_PER_OCTAVE ) ); - m_channelTrack->setBaseOctave( static_cast( + m_instrumentTrack->setBaseOctave( static_cast( key_num / NOTES_PER_OCTAVE ) ); } @@ -269,7 +269,7 @@ void pianoWidget::mouseReleaseEvent( QMouseEvent * _me ) { int released_key = getKeyFromMouse( _me->pos() ); - m_channelTrack->processInEvent( + m_instrumentTrack->processInEvent( midiEvent( NOTE_OFF, 0, released_key, 0 ), midiTime() ); m_pressedKeys[released_key] = FALSE; @@ -309,7 +309,7 @@ void pianoWidget::mouseMoveEvent( QMouseEvent * _me ) // user just moved the cursor one pixel left but on the same key) if( key_num != released_key ) { - m_channelTrack->processInEvent( + m_instrumentTrack->processInEvent( midiEvent( NOTE_OFF, 0, released_key, 0 ), midiTime() ); m_pressedKeys[released_key] = FALSE; @@ -321,16 +321,16 @@ void pianoWidget::mouseMoveEvent( QMouseEvent * _me ) { if( _me->pos().y() > PIANO_BASE ) { - m_channelTrack->processInEvent( + m_instrumentTrack->processInEvent( midiEvent( NOTE_ON, 0, key_num, vol ), midiTime() ); m_pressedKeys[key_num] = TRUE; } else { - m_channelTrack->setBaseTone( (tones) + m_instrumentTrack->setBaseTone( (tones) ( key_num % NOTES_PER_OCTAVE ) ); - m_channelTrack->setBaseOctave( (octaves) + m_instrumentTrack->setBaseOctave( (octaves) ( key_num / NOTES_PER_OCTAVE ) ); } } @@ -339,7 +339,7 @@ void pianoWidget::mouseMoveEvent( QMouseEvent * _me ) } else if( m_pressedKeys[key_num] == TRUE ) { - m_channelTrack->processInEvent( + m_instrumentTrack->processInEvent( midiEvent( KEY_PRESSURE, 0, key_num, vol ), midiTime() ); } @@ -397,7 +397,7 @@ void pianoWidget::keyPressEvent( QKeyEvent * _ke ) if( _ke->isAutoRepeat() == FALSE && key_num > -1 ) { - m_channelTrack->processInEvent( + m_instrumentTrack->processInEvent( midiEvent( NOTE_ON, 0, key_num, DEFAULT_VOLUME ), midiTime() ); m_pressedKeys[key_num] = TRUE; @@ -418,7 +418,7 @@ void pianoWidget::keyReleaseEvent( QKeyEvent * _ke ) ( DEFAULT_OCTAVE - 1 ) * NOTES_PER_OCTAVE; if( _ke->isAutoRepeat() == FALSE && key_num > -1 ) { - m_channelTrack->processInEvent( + m_instrumentTrack->processInEvent( midiEvent( NOTE_OFF, 0, key_num, 0 ), midiTime() ); m_pressedKeys[key_num] = FALSE; @@ -442,7 +442,7 @@ void pianoWidget::focusOutEvent( QFocusEvent * ) { if( m_pressedKeys[i] == TRUE ) { - m_channelTrack->processInEvent( + m_instrumentTrack->processInEvent( midiEvent( NOTE_OFF, 0, i, 0 ), midiTime() ); m_pressedKeys[i] = FALSE; @@ -523,8 +523,8 @@ void pianoWidget::paintEvent( QPaintEvent * ) p.setPen( QColor ( 0xFF, 0xFF, 0xFF ) ); - int base_key = m_channelTrack->baseTone() + - m_channelTrack->baseOctave() * NOTES_PER_OCTAVE; + int base_key = m_instrumentTrack->baseTone() + + m_instrumentTrack->baseOctave() * NOTES_PER_OCTAVE; if( KEY_ORDER[base_key % NOTES_PER_OCTAVE] == WHITE_KEY ) { p.fillRect( QRect( getKeyX( base_key ), 1, PW_WHITE_KEY_WIDTH-1, diff --git a/src/core/plugin.cpp b/src/core/plugin.cpp index 69bc03b45..15a8aee92 100644 --- a/src/core/plugin.cpp +++ b/src/core/plugin.cpp @@ -64,8 +64,7 @@ static plugin::descriptor dummy_plugin_descriptor = plugin::plugin( const descriptor * _descriptor, engine * _engine ) : - settings(), - engineObject( _engine ), + journallingObject( _engine ), m_descriptor( _descriptor ) { if( dummy_plugin_descriptor.logo == NULL ) diff --git a/src/core/preset_preview_play_handle.cpp b/src/core/preset_preview_play_handle.cpp index a68acd9f1..10a9c67cc 100644 --- a/src/core/preset_preview_play_handle.cpp +++ b/src/core/preset_preview_play_handle.cpp @@ -42,7 +42,7 @@ #include "preset_preview_play_handle.h" #include "note_play_handle.h" -#include "channel_track.h" +#include "instrument_track.h" #include "track_container.h" #include "mmp.h" #include "debug.h" @@ -56,7 +56,7 @@ class previewTrackContainer : public trackContainer public: previewTrackContainer( engine * _engine ) : trackContainer( _engine ), - m_previewChannelTrack( dynamic_cast( + m_previewChannelTrack( dynamic_cast( track::create( track::CHANNEL_TRACK, this ) )), m_previewNote( NULL ), @@ -81,7 +81,7 @@ public: return( "previewtc" ); } - channelTrack * previewChannelTrack( void ) + instrumentTrack * previewChannelTrack( void ) { return( m_previewChannelTrack ); } @@ -108,7 +108,7 @@ public: private: - channelTrack * m_previewChannelTrack; + instrumentTrack * m_previewChannelTrack; notePlayHandle * m_previewNote; QMutex m_dataMutex; @@ -123,7 +123,8 @@ QMap presetPreviewPlayHandle::presetPreviewPlayHandle( const QString & _preset_file, engine * _engine ) : - playHandle( PRESET_PREVIEW_PLAY_HANDLE, _engine ), + playHandle( PRESET_PREVIEW_PLAY_HANDLE ), + engineObject( _engine ), m_previewNote( NULL ) { if( s_previewTCs.contains( _engine ) == FALSE ) @@ -149,11 +150,12 @@ presetPreviewPlayHandle::presetPreviewPlayHandle( midiPort::DUMMY ); // create temporary note - note n( 0, 0, static_cast( A ), - static_cast( DEFAULT_OCTAVE-1 ), 100 ); + note n(); // create note-play-handle for it m_previewNote = new notePlayHandle( previewTC()->previewChannelTrack(), - 0, ~0, &n ); + 0, ~0, + note( NULL, 0, 0, static_cast( A ), + static_cast( DEFAULT_OCTAVE-1 ), 100 ) ); previewTC()->setPreviewNote( m_previewNote ); @@ -209,15 +211,15 @@ void presetPreviewPlayHandle::cleanUp( engine * _engine ) constNotePlayHandleVector presetPreviewPlayHandle::nphsOfChannelTrack( - const channelTrack * _ct ) + const instrumentTrack * _it ) { constNotePlayHandleVector cnphv; - if( s_previewTCs.contains( _ct->eng() ) == TRUE ) + if( s_previewTCs.contains( _it->eng() ) == TRUE ) { - previewTrackContainer * tc = s_previewTCs[_ct->eng()]; + previewTrackContainer * tc = s_previewTCs[_it->eng()]; tc->lockData(); if( tc->previewNote() != NULL && - tc->previewNote()->getChannelTrack() == _ct ) + tc->previewNote()->getInstrumentTrack() == _it ) { cnphv.push_back( tc->previewNote() ); } diff --git a/src/core/sample_play_handle.cpp b/src/core/sample_play_handle.cpp index dfa76939e..bdbfbd67e 100644 --- a/src/core/sample_play_handle.cpp +++ b/src/core/sample_play_handle.cpp @@ -34,7 +34,8 @@ samplePlayHandle::samplePlayHandle( const QString & _sample_file, engine * _engine ) : - playHandle( SAMPLE_PLAY_HANDLE, _engine ), + playHandle( SAMPLE_PLAY_HANDLE ), + engineObject( _engine ), m_sampleBuffer( new sampleBuffer( eng(), _sample_file ) ), m_ownSampleBuffer( TRUE ), m_doneMayReturnTrue( TRUE ), @@ -47,7 +48,8 @@ samplePlayHandle::samplePlayHandle( const QString & _sample_file, samplePlayHandle::samplePlayHandle( sampleBuffer * _sample_buffer ) : - playHandle( SAMPLE_PLAY_HANDLE, _sample_buffer->eng() ), + playHandle( SAMPLE_PLAY_HANDLE ), + engineObject( _sample_buffer->eng() ), m_sampleBuffer( _sample_buffer ), m_ownSampleBuffer( FALSE ), m_doneMayReturnTrue( TRUE ), diff --git a/src/core/song_editor.cpp b/src/core/song_editor.cpp index f57ed3a8c..537a661f1 100644 --- a/src/core/song_editor.cpp +++ b/src/core/song_editor.cpp @@ -65,6 +65,7 @@ #include #define addButton insert +#define setCheckable setToggleButton #endif @@ -76,7 +77,7 @@ #include "templates.h" #include "export_project_dialog.h" #include "bb_track.h" -#include "channel_track.h" +#include "instrument_track.h" #include "mmp.h" #include "midi_client.h" #include "timeline.h" @@ -94,7 +95,7 @@ #include "combobox.h" #include "main_window.h" #include "import_filter.h" -#include "edit_history.h" +#include "project_journal.h" #include "debug.h" @@ -382,7 +383,7 @@ songEditor::songEditor( engine * _engine ) : static_cast( powf( 2.0f, i ) ) ) + "%" ); } - m_zoomingComboBox->setValue( m_zoomingComboBox->findText( + m_zoomingComboBox->setInitValue( m_zoomingComboBox->findText( "100%" ) ); connect( m_zoomingComboBox, SIGNAL( activated( const QString & ) ), this, SLOT( zoomingChanged( const QString & ) ) ); @@ -1339,7 +1340,7 @@ bool songEditor::mayChangeProject( void ) void songEditor::clearProject( void ) { - eng()->getEditHistory()->setGlobalStepRecording( FALSE ); + eng()->getProjectJournal()->setJournalling( FALSE ); if( m_playing ) { @@ -1362,11 +1363,14 @@ void songEditor::clearProject( void ) } clearAllTracks(); + eng()->getBBEditor()->clearAllTracks(); eng()->getProjectNotes()->clear(); - eng()->getEditHistory()->setGlobalStepRecording( TRUE ); + eng()->getProjectJournal()->clear(); + + eng()->getProjectJournal()->setJournalling( TRUE ); } @@ -1378,15 +1382,15 @@ void songEditor::createNewProject( void ) { clearProject(); - eng()->getEditHistory()->setGlobalStepRecording( FALSE ); + eng()->getProjectJournal()->setJournalling( FALSE ); track * t; t = track::create( track::CHANNEL_TRACK, this ); - dynamic_cast< channelTrack * >( t )->loadInstrument( + dynamic_cast< instrumentTrack * >( t )->loadInstrument( "tripleoscillator" ); track::create( track::SAMPLE_TRACK, this ); t = track::create( track::CHANNEL_TRACK, eng()->getBBEditor() ); - dynamic_cast< channelTrack * >( t )->loadInstrument( + dynamic_cast< instrumentTrack * >( t )->loadInstrument( "tripleoscillator" ); track::create( track::BB_TRACK, this ); @@ -1402,7 +1406,7 @@ void songEditor::createNewProject( void ) eng()->getMainWindow()->resetWindowTitle( "" ); - eng()->getEditHistory()->setGlobalStepRecording( TRUE ); + eng()->getProjectJournal()->setJournalling( TRUE ); } @@ -1426,7 +1430,7 @@ void FASTCALL songEditor::loadProject( const QString & _file_name ) { clearProject(); - eng()->getEditHistory()->setGlobalStepRecording( FALSE ); + eng()->getProjectJournal()->setJournalling( FALSE ); m_fileName = _file_name; m_oldFileName = _file_name; @@ -1485,24 +1489,24 @@ void FASTCALL songEditor::loadProject( const QString & _file_name ) { if( node.nodeName() == "trackcontainer" ) { - loadSettings( node.toElement() ); + restoreState( node.toElement() ); } else if( node.nodeName() == eng()->getPianoRoll()->nodeName() ) { - eng()->getPianoRoll()->loadSettings( + eng()->getPianoRoll()->restoreState( node.toElement() ); } else if( node.nodeName() == eng()->getProjectNotes()->nodeName() ) { - eng()->getProjectNotes()->loadSettings( + eng()->getProjectNotes()->restoreState( node.toElement() ); } else if( node.nodeName() == m_playPos[PLAY_SONG].m_timeLine->nodeName() ) { - m_playPos[PLAY_SONG].m_timeLine->loadSettings( + m_playPos[PLAY_SONG].m_timeLine->restoreState( node.toElement() ); } } @@ -1516,7 +1520,7 @@ void FASTCALL songEditor::loadProject( const QString & _file_name ) eng()->getMainWindow()->resetWindowTitle( "" ); - eng()->getEditHistory()->setGlobalStepRecording( TRUE ); + eng()->getProjectJournal()->setJournalling( TRUE ); } @@ -1540,11 +1544,11 @@ bool songEditor::saveProject( void ) mmp.head().appendChild( mp ); - saveSettings( mmp, mmp.content() ); + saveState( mmp, mmp.content() ); - eng()->getPianoRoll()->saveSettings( mmp, mmp.content() ); - eng()->getProjectNotes()->saveSettings( mmp, mmp.content() ); - m_playPos[PLAY_SONG].m_timeLine->saveSettings( mmp, mmp.content() ); + eng()->getPianoRoll()->saveState( mmp, mmp.content() ); + eng()->getProjectNotes()->saveState( mmp, mmp.content() ); + m_playPos[PLAY_SONG].m_timeLine->saveState( mmp, mmp.content() ); if( mmp.writeFile( m_fileName, m_oldFileName == "" || m_fileName != m_oldFileName ) == TRUE ) @@ -1687,27 +1691,12 @@ void songEditor::exportProject( void ) - -void songEditor::saveSettings( QDomDocument & _doc, QDomElement & _parent ) -{ - trackContainer::saveSettings( _doc, _parent ); -} - - - - -void songEditor::loadSettings( const QDomElement & _this ) -{ - trackContainer::loadSettings( _this ); -} - - - #include "song_editor.moc" #ifdef QT3 #undef addButton +#undef setCheckable #endif diff --git a/src/core/timeline.cpp b/src/core/timeline.cpp index f5761f7dc..948f53b30 100644 --- a/src/core/timeline.cpp +++ b/src/core/timeline.cpp @@ -66,7 +66,7 @@ timeLine::timeLine( const int _xoff, const int _yoff, const float _ppt, songEditor::playPos & _pos, const midiTime & _begin, QWidget * _parent, engine * _engine ) : QWidget( _parent ), - engineObject( _engine ), + journallingObject( _engine ), m_autoScroll( AUTOSCROLL_ENABLED ), m_loopPoints( LOOP_POINTS_DISABLED ), m_behaviourAtStop( BACK_TO_ZERO ), @@ -176,13 +176,11 @@ void timeLine::addToolButtons( QWidget * _tool_bar ) -void timeLine::saveSettings( QDomDocument & _doc, QDomElement & _parent ) +void timeLine::saveSettings( QDomDocument & _doc, QDomElement & _this ) { - QDomElement tl_de = _doc.createElement( nodeName() ); - tl_de.setAttribute( "lp0pos", (int) loopBegin() ); - tl_de.setAttribute( "lp1pos", (int) loopEnd() ); - tl_de.setAttribute( "lpstate", m_loopPoints ); - _parent.appendChild( tl_de ); + _this.setAttribute( "lp0pos", (int) loopBegin() ); + _this.setAttribute( "lp1pos", (int) loopEnd() ); + _this.setAttribute( "lpstate", m_loopPoints ); } diff --git a/src/core/track.cpp b/src/core/track.cpp index 83783b0c3..adba617d4 100644 --- a/src/core/track.cpp +++ b/src/core/track.cpp @@ -51,7 +51,7 @@ #include "track.h" #include "track_container.h" -#include "channel_track.h" +#include "instrument_track.h" #include "bb_track.h" #include "sample_track.h" #include "song_editor.h" @@ -65,7 +65,7 @@ #include "mmp.h" #include "main_window.h" #include "text_float.h" - +#include "project_journal.h" const Sint16 RESIZE_GRIP_WIDTH = 4; @@ -88,8 +88,7 @@ trackContentObject::trackContentObject( track * _track ) : , Qt::WDestructiveClose #endif ), - settings(), - editableObject( _track->eng() ), + journallingObject( _track->eng() ), m_track( _track ), m_startPosition(), m_length(), @@ -112,10 +111,10 @@ trackContentObject::trackContentObject( track * _track ) : #endif show(); - setStepRecording( FALSE ); + setJournalling( FALSE ); movePosition( 0 ); changeLength( 0 ); - setStepRecording( TRUE ); + setJournalling( TRUE ); setFixedHeight( parentWidget()->height() - 2 ); setAcceptDrops( TRUE ); @@ -146,7 +145,7 @@ void trackContentObject::movePosition( const midiTime & _pos ) if( m_startPosition != _pos ) { //getTrack()->eng()->getSongEditor()->setModified(); - addStep( editStep( MOVE, m_startPosition - _pos ) ); + addJournalEntry( journalEntry( MOVE, m_startPosition - _pos ) ); m_startPosition = _pos; } m_track->getTrackWidget()->changePosition(); @@ -163,7 +162,7 @@ void trackContentObject::changeLength( const midiTime & _length ) if( m_length != _length ) { //getTrack()->eng()->getSongEditor()->setModified(); - addStep( editStep( RESIZE, m_length - _length ) ); + addJournalEntry( journalEntry( RESIZE, m_length - _length ) ); m_length = _length; } setFixedWidth( static_cast( m_length * pixelsPerTact() / @@ -197,7 +196,7 @@ void trackContentObject::dropEvent( QDropEvent * _de ) // at least save position before getting to moved to somewhere // the user doesn't expect... midiTime pos = startPosition(); - loadSettings( mmp.content().firstChild().toElement() ); + restoreState( mmp.content().firstChild().toElement() ); movePosition( pos ); _de->accept(); } @@ -253,7 +252,7 @@ void trackContentObject::mousePressEvent( QMouseEvent * _me ) getTrack()->eng()->getMainWindow()->isCtrlPressed() == TRUE ) { multimediaProject mmp( multimediaProject::DRAG_N_DROP_DATA ); - saveSettings( mmp, mmp.content() ); + saveState( mmp, mmp.content() ); #ifdef QT4 QPixmap thumbnail = QPixmap::grabWidget( this ).scaled( 128, 128, @@ -265,8 +264,7 @@ void trackContentObject::mousePressEvent( QMouseEvent * _me ) QPixmap thumbnail = QPixmap::grabWidget( this ). convertToImage().smoothScale( s ); #endif - new stringPairDrag( "tco_" + - QString::number( m_track->type() ), + new stringPairDrag( QString( "tco_%1" ).arg( m_track->type() ), mmp.toString(), thumbnail, this, m_track->eng() ); } @@ -274,7 +272,7 @@ void trackContentObject::mousePressEvent( QMouseEvent * _me ) /* eng()->getMainWindow()->isShiftPressed() == FALSE &&*/ fixedTCOs() == FALSE ) { - setStepRecording( FALSE ); + setJournalling( FALSE ); m_initialMouseX = _me->x(); @@ -308,7 +306,6 @@ void trackContentObject::mousePressEvent( QMouseEvent * _me ) // setup text-float as if TCO was already moved/resized mouseMoveEvent( _me ); s_textFloat->show(); - } else if( ( _me->button() == Qt::MidButton/* || ( _me->button() == Qt::LeftButton && @@ -431,8 +428,8 @@ void trackContentObject::mouseReleaseEvent( QMouseEvent * _me ) { if( m_action == MOVE || m_action == RESIZE ) { - setStepRecording( TRUE ); - addStep( editStep( m_action, m_oldTime - + setJournalling( TRUE ); + addJournalEntry( journalEntry( m_action, m_oldTime - ( ( m_action == MOVE ) ? m_startPosition : m_length ) ) ); } @@ -493,29 +490,28 @@ float trackContentObject::pixelsPerTact( void ) -void trackContentObject::undoStep( const editStep & _edit_step ) +void trackContentObject::undoStep( journalEntry & _je ) { - saveStepRecordingState( FALSE ); - switch( _edit_step.actionID() ) + saveJournallingState( FALSE ); + switch( _je.actionID() ) { case MOVE: - movePosition( startPosition() + - _edit_step.data().toInt() ); + movePosition( startPosition() + _je.data().toInt() ); break; case RESIZE: - changeLength( length() + _edit_step.data().toInt() ); + changeLength( length() + _je.data().toInt() ); break; } - restoreStepRecordingState(); + restoreJournallingState(); } -void trackContentObject::redoStep( const editStep & _edit_step ) +void trackContentObject::redoStep( journalEntry & _je ) { - undoStep( editStep( _edit_step.actionID(), - -_edit_step.data().toInt() ) ); + journalEntry je( _je.actionID(), -_je.data().toInt() ); + undoStep( je ); } @@ -556,7 +552,7 @@ void trackContentObject::paste( void ) { if( clipboard::getContent( nodeName() ) != NULL ) { - loadSettings( *( clipboard::getContent( nodeName() ) ) ); + restoreState( *( clipboard::getContent( nodeName() ) ) ); } } @@ -576,7 +572,7 @@ void trackContentObject::setAutoResizeEnabled( bool _e ) // =========================================================================== trackContentWidget::trackContentWidget( trackWidget * _parent ) : QWidget( _parent ), - editableObject( _parent->getTrack()->eng() ), + journallingObject( _parent->getTrack()->eng() ), m_trackWidget( _parent ) { #ifdef QT4 @@ -625,15 +621,18 @@ csize trackContentWidget::numOfTCOs( void ) trackContentObject * FASTCALL trackContentWidget::addTCO( trackContentObject * _tco ) { - //addStep( editStep( ADD_TCO, 0 ) ); + QMap map; + map["id"] = _tco->id(); + addJournalEntry( journalEntry( ADD_TCO, map ) ); + m_trackContentObjects.push_back( _tco ); _tco->move( 0, 1 ); - _tco->saveStepRecordingState( FALSE ); + _tco->saveJournallingState( FALSE ); m_trackWidget->changePosition(); - _tco->restoreStepRecordingState(); + _tco->restoreJournallingState(); - getTrack()->eng()->getSongEditor()->setModified(); + //getTrack()->eng()->getSongEditor()->setModified(); return( _tco ); // just for convenience } @@ -656,7 +655,12 @@ void trackContentWidget::removeTCO( trackContentObject * _tco, _tco ); if( it != m_trackContentObjects.end() ) { - //addStep( editStep( REMOVE_TCO, 0 ) ); + QMap map; + multimediaProject mmp( multimediaProject::JOURNAL_DATA ); + _tco->saveState( mmp, mmp.content() ); + map["id"] = _tco->id(); + map["state"] = mmp.toString(); + addJournalEntry( journalEntry( REMOVE_TCO, map ) ); if( _also_delete ) { delete _tco; @@ -785,7 +789,7 @@ void trackContentWidget::dropEvent( QDropEvent * _de ) multimediaProject mmp( value, FALSE ); // at least save position before getting moved to somewhere // the user doesn't expect... - tco->loadSettings( mmp.content().firstChild().toElement() ); + tco->restoreState( mmp.content().firstChild().toElement() ); tco->movePosition( pos ); _de->accept(); } @@ -812,9 +816,9 @@ void trackContentWidget::mousePressEvent( QMouseEvent * _me ) const midiTime pos = getPosition( _me->x() ).getTact() * 64; trackContentObject * tco = addTCO( getTrack()->createTCO( pos ) ); - tco->saveStepRecordingState( FALSE ); + tco->saveJournallingState( FALSE ); tco->movePosition( pos ); - tco->restoreStepRecordingState(); + tco->restoreJournallingState(); } } @@ -861,26 +865,57 @@ void trackContentWidget::resizeEvent( QResizeEvent * _re ) -void trackContentWidget::undoStep( const editStep & _edit_step ) +void trackContentWidget::undoStep( journalEntry & _je ) { - saveStepRecordingState( FALSE ); - switch( _edit_step.actionID() ) + saveJournallingState( FALSE ); + switch( _je.actionID() ) { case ADD_TCO: + { + QMap map = _je.data().toMap(); + journallingObject * jo = + eng()->getProjectJournal()->getJournallingObject( map["id"].toInt() ); + assert( jo != NULL ); + multimediaProject mmp( + multimediaProject::JOURNAL_DATA ); + jo->saveState( mmp, mmp.content() ); + map["state"] = mmp.toString(); + _je.data() = map; + delete jo; break; + } + case REMOVE_TCO: + { + trackContentObject * tco = addTCO( + getTrack()->createTCO( + midiTime( 0 ) ) ); + multimediaProject mmp( + _je.data().toMap()["state"].toString(), FALSE ); + tco->restoreState( + mmp.content().firstChild().toElement() ); break; + } } - restoreStepRecordingState(); + restoreJournallingState(); } -void trackContentWidget::redoStep( const editStep & _edit_step ) +void trackContentWidget::redoStep( journalEntry & _je ) { -/* undoStep( editStep( _edit_step.actionID(), - -_edit_step.data().toInt() ) );*/ + switch( _je.actionID() ) + { + case ADD_TCO: + case REMOVE_TCO: + _je.actionID() = ( _je.actionID() == ADD_TCO ) ? + REMOVE_TCO : ADD_TCO; + undoStep( _je ); + _je.actionID() = ( _je.actionID() == ADD_TCO ) ? + REMOVE_TCO : ADD_TCO; + break; + } } @@ -945,6 +980,7 @@ trackOperationsWidget::trackOperationsWidget( trackWidget * _parent ) : m_muteBtn = new pixmapButton( this, m_trackWidget->getTrack()->eng() ); m_muteBtn->setActiveGraphic( embed::getIconPixmap( "mute_on" ) ); m_muteBtn->setInactiveGraphic( embed::getIconPixmap( "mute_off" ) ); + m_muteBtn->setCheckable( TRUE ); m_muteBtn->move( 44, 4 ); m_muteBtn->show(); connect( m_muteBtn, SIGNAL( toggled( bool ) ), this, @@ -993,9 +1029,9 @@ m_trackWidget->getTrack()->eng()->getMainWindow()->isCtrlPressed() == TRUE && m_trackWidget->getTrack()->type() != track::BB_TRACK ) { multimediaProject mmp( multimediaProject::DRAG_N_DROP_DATA ); - m_trackWidget->getTrack()->saveSettings( mmp, mmp.content() ); - new stringPairDrag( "track_" + - QString::number( m_trackWidget->getTrack()->type() ), + m_trackWidget->getTrack()->saveState( mmp, mmp.content() ); + new stringPairDrag( QString( "track_%1" ).arg( + m_trackWidget->getTrack()->type() ), mmp.toString(), QPixmap::grabWidget( &m_trackWidget->getTrackSettingsWidget() ), this, m_trackWidget->getTrack()->eng() ); @@ -1214,7 +1250,7 @@ void trackWidget::dropEvent( QDropEvent * _de ) // value contains our XML-data so simply create a // multimediaProject which does the rest for us... multimediaProject mmp( value, FALSE ); - m_track->loadSettings( mmp.content().firstChild().toElement() ); + m_track->restoreState( mmp.content().firstChild().toElement() ); _de->accept(); } } @@ -1370,8 +1406,7 @@ midiTime trackWidget::endPosition( const midiTime & _pos_start ) // =========================================================================== track::track( trackContainer * _tc ) : - settings(), - engineObject( _tc->eng() ), + journallingObject( _tc->eng() ), m_trackContainer( _tc ) { m_trackWidget = new trackWidget( this, @@ -1404,7 +1439,7 @@ track * FASTCALL track::create( trackTypes _tt, trackContainer * _tc ) switch( _tt ) { - case CHANNEL_TRACK: t = new channelTrack( _tc ); break; + case CHANNEL_TRACK: t = new instrumentTrack( _tc ); break; case BB_TRACK: t = new bbTrack( _tc ); break; case SAMPLE_TRACK: t = new sampleTrack( _tc ); break; // case EVENT_TRACK: @@ -1430,7 +1465,7 @@ track * FASTCALL track::create( const QDomElement & _this, { track * t = create( static_cast( _this.attribute( "type" ).toInt() ), _tc ); - t->loadSettings( _this ); + t->restoreState( _this ); return( t ); } @@ -1441,7 +1476,7 @@ track * FASTCALL track::clone( track * _track ) { QDomDocument doc; QDomElement parent = doc.createElement( "clone" ); - _track->saveSettings( doc, parent ); + _track->saveState( doc, parent ); QDomElement e = parent.firstChild().toElement(); return( create( e, _track->getTrackContainer() ) ); } @@ -1457,25 +1492,26 @@ tact track::length( void ) const -void FASTCALL track::saveSettings( QDomDocument & _doc, QDomElement & _parent ) +void FASTCALL track::saveSettings( QDomDocument & _doc, QDomElement & _this ) { csize num_of_tcos = getTrackContentWidget()->numOfTCOs(); - QDomElement track_de = _doc.createElement( "track" ); - track_de.setAttribute( "type", type() ); - track_de.setAttribute( "muted", muted() ); - track_de.setAttribute( "height", m_trackWidget->height() ); - _parent.appendChild( track_de ); + _this.setTagName( "track" ); + _this.setAttribute( "type", type() ); + _this.setAttribute( "muted", muted() ); + _this.setAttribute( "height", m_trackWidget->height() ); - // let actual track (channelTrack, bbTrack, sampleTrack etc.) save + QDomElement ts_de = _doc.createElement( nodeName() ); + // let actual track (instrumentTrack, bbTrack, sampleTrack etc.) save // its settings - saveTrackSpecificSettings( _doc, track_de ); + saveTrackSpecificSettings( _doc, ts_de ); + _this.appendChild( ts_de ); // now save settings of all TCO's for( csize i = 0; i < num_of_tcos; ++i ) { trackContentObject * tco = getTCO( i ); - tco->saveSettings( _doc, track_de ); + tco->saveState( _doc, _this ); } } @@ -1500,15 +1536,20 @@ void FASTCALL track::loadSettings( const QDomElement & _this ) { if( node.isElement() ) { - if( nodeName() == node.nodeName() ) + if( node.nodeName() == nodeName() || +#warning compat-code, remove in 0.3.0 + ( node.nodeName() == "channeltrack" && + nodeName() == "instrumenttrack" ) + ) { loadTrackSpecificSettings( node.toElement() ); } - else + else if( + !node.toElement().attribute( "metadata" ).toInt() ) { trackContentObject * tco = createTCO( midiTime( 0 ) ); - tco->loadSettings( node.toElement() ); + tco->restoreState( node.toElement() ); addTCO( tco ); } } diff --git a/src/core/track_container.cpp b/src/core/track_container.cpp index ca54c6e31..2e05058a9 100644 --- a/src/core/track_container.cpp +++ b/src/core/track_container.cpp @@ -55,7 +55,7 @@ #include "mixer.h" #include "song_editor.h" #include "string_pair_drag.h" -#include "channel_track.h" +#include "instrument_track.h" #include "mmp.h" #include "config_mgr.h" #include "import_filter.h" @@ -70,8 +70,7 @@ trackContainer::trackContainer( engine * _engine ) : , 0, Qt::WStyle_Title #endif ), - settings(), - engineObject( _engine ), + journallingObject( _engine ), m_currentPosition( 0, 0 ), m_scrollArea( new scrollArea( this ) ), m_ppt( DEFAULT_PIXELS_PER_TACT ), @@ -105,18 +104,17 @@ trackContainer::~trackContainer() -void trackContainer::saveSettings( QDomDocument & _doc, QDomElement & _parent ) +void trackContainer::saveSettings( QDomDocument & _doc, QDomElement & _this ) { - QDomElement tc_de = _doc.createElement( "trackcontainer" ); - tc_de.setAttribute( "type", nodeName() ); - mainWindow::saveWidgetState( this, tc_de ); - _parent.appendChild( tc_de ); + _this.setTagName( "trackcontainer" ); + _this.setAttribute( "type", nodeName() ); + mainWindow::saveWidgetState( this, _this ); // save settings of each track for( trackWidgetVector::iterator it = m_trackWidgets.begin(); it != m_trackWidgets.end(); ++it ) { - ( *it )->getTrack()->saveSettings( _doc, tc_de ); + ( *it )->getTrack()->saveState( _doc, _this ); } } @@ -170,7 +168,8 @@ void trackContainer::loadSettings( const QDomElement & _this ) break; } - if( node.isElement() ) + if( node.isElement() && + !node.toElement().attribute( "metadata" ).toInt() ) { track::create( node.toElement(), this ); } @@ -436,32 +435,32 @@ void trackContainer::dropEvent( QDropEvent * _de ) QString value = stringPairDrag::decodeValue( _de ); if( type == "instrument" ) { - channelTrack * ct = dynamic_cast( + instrumentTrack * it = dynamic_cast( track::create( track::CHANNEL_TRACK, this ) ); - ct->loadInstrument( value ); - ct->toggledChannelButton( TRUE ); + it->loadInstrument( value ); + it->toggledInstrumentTrackButton( TRUE ); _de->accept(); } else if( type == "sampledata" || type == "samplefile" ) { - channelTrack * ct = dynamic_cast( + instrumentTrack * it = dynamic_cast( track::create( track::CHANNEL_TRACK, this ) ); - instrument * i = ct->loadInstrument( "audiofileprocessor" ); + instrument * i = it->loadInstrument( "audiofileprocessor" ); i->setParameter( type, value ); - ct->toggledChannelButton( TRUE ); + it->toggledInstrumentTrackButton( TRUE ); _de->accept(); } else if( type == "presetfile" ) { multimediaProject mmp( value ); - channelTrack * ct = dynamic_cast( + instrumentTrack * it = dynamic_cast( track::create( track::CHANNEL_TRACK, this ) ); - ct->loadTrackSpecificSettings( mmp.content().firstChild(). + it->loadTrackSpecificSettings( mmp.content().firstChild(). toElement() ); - ct->toggledChannelButton( TRUE ); + it->toggledInstrumentTrackButton( TRUE ); _de->accept(); } else if( type == "midifile" ) diff --git a/src/lib/base64.cpp b/src/lib/base64.cpp index 85745f15b..1689effc9 100644 --- a/src/lib/base64.cpp +++ b/src/lib/base64.cpp @@ -30,8 +30,16 @@ #include "base64.h" #include "types.h" +#ifndef QT3 + +#include +#include + +#else + +#include +#include -#ifdef QT3 namespace base64 { @@ -168,4 +176,55 @@ void decode( const QString & _b64, char * * _data, int * _size ) #endif +namespace base64 +{ + + +QString encode( const QVariant & _data ) +{ + QBuffer buf; +#ifndef QT3 + buf.open( QBuffer::WriteOnly ); +#else + buf.open( IO_WriteOnly ); +#endif + QDataStream out( &buf ); + out << _data; + QByteArray data = buf.buffer(); + QString dst; +#ifndef QT3 + encode( data.constData(), data.size(), dst ); +#else + encode( data.data(), data.size(), dst ); +#endif + return( dst ); +} + + + + +QVariant decode( const QString & _b64 ) +{ + char * dst = NULL; + int dsize = 0; + base64::decode( _b64, &dst, &dsize ); +#ifndef QT3 + QByteArray ba( dst, dsize ); + QBuffer buf( &ba ); + buf.open( QBuffer::ReadOnly ); +#else + QByteArray ba; + ba.setRawData( dst, dsize ); + QBuffer buf( ba ); + buf.open( IO_ReadOnly ); +#endif + QDataStream in( &buf ); + QVariant ret; + in >> ret; + return( ret ); +} + + +} ; + #endif diff --git a/src/lib/clipboard.cpp b/src/lib/clipboard.cpp index c8388bd77..800d6268f 100644 --- a/src/lib/clipboard.cpp +++ b/src/lib/clipboard.cpp @@ -26,7 +26,7 @@ #include "clipboard.h" -#include "settings.h" +#include "journalling_object.h" namespace clipboard @@ -35,13 +35,12 @@ namespace clipboard map content; - void copy( settings * _settings_object ) + void copy( journallingObject * _obj ) { QDomDocument doc; QDomElement parent = doc.createElement( "clipboard" ); - _settings_object->saveSettings( doc, parent ); - content[_settings_object->nodeName()] = - parent.firstChild().toElement(); + _obj->saveState( doc, parent ); + content[_obj->nodeName()] = parent.firstChild().toElement(); } diff --git a/src/lib/journalling_object.cpp b/src/lib/journalling_object.cpp new file mode 100644 index 000000000..da0e667a1 --- /dev/null +++ b/src/lib/journalling_object.cpp @@ -0,0 +1,222 @@ +#ifndef SINGLE_SOURCE_COMPILE + +/* + * journalling_object.cpp - implementation of journalling-object related stuff + * + * Copyright (c) 2006 Tobias Doerffel + * + * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + + +#include "journalling_object.h" +#include "project_journal.h" +#include "base64.h" + +#include "qt3support.h" + +#ifndef QT3 + +#include + +#else + +#include + +#endif + + + +journallingObject::journallingObject( engine * _engine ) : + engineObject( _engine ), + m_id( ( eng() != NULL ) ? eng()->getProjectJournal()->allocID( this ) : + 0 ), + m_journalEntries(), + m_currentJournalEntry( m_journalEntries.end() ), + m_journalling( TRUE ) +{ +} + + + + +journallingObject::~journallingObject() +{ + if( eng() != NULL ) + { + eng()->getProjectJournal()->freeID( id() ); + } +} + + + + +void journallingObject::undo( void ) +{ + if( m_journalEntries.empty() == TRUE ) + { + return; + } + + if( m_currentJournalEntry - 1 >= m_journalEntries.begin() ) + { + undoStep( *--m_currentJournalEntry ); + } +} + + + + +void journallingObject::redo( void ) +{ + if( m_journalEntries.empty() == TRUE ) + { + return; + } + + if( m_currentJournalEntry < m_journalEntries.end() ) + { + redoStep( *m_currentJournalEntry++ ); + } +} + + + + +QDomElement journallingObject::saveState( QDomDocument & _doc, + QDomElement & _parent ) +{ + QDomElement _this = _doc.createElement( nodeName() ); + saveSettings( _doc, _this ); + saveJournal( _doc, _this ); + _parent.appendChild( _this ); + return( _this ); +} + + + + +void journallingObject::restoreState( const QDomElement & _this ) +{ + saveJournallingState( FALSE ); + loadSettings( _this ); + QDomNode node = _this.firstChild(); + while( !node.isNull() ) + { + if( node.isElement() && node.nodeName() == "journal" ) + { + loadJournal( node.toElement() ); + } + node = node.nextSibling(); + } + restoreJournallingState(); +} + + + + +void journallingObject::addJournalEntry( const journalEntry & _edit_step ) +{ + if( !( eng() == NULL || + eng()->getProjectJournal()->isJournalling() == FALSE || + isJournalling() == FALSE ) ) + { + m_journalEntries.erase( m_currentJournalEntry, + m_journalEntries.end() ); + m_journalEntries.push_back( _edit_step ); + m_currentJournalEntry = m_journalEntries.end(); + eng()->getProjectJournal()->journalEntryAdded( id() ); + } +} + + + + +void journallingObject::saveJournal( QDomDocument & _doc, + QDomElement & _parent ) +{ +/* // avoid creating empty journal-nodes + if( m_journalEntries.size() == 0 ) + { + return; + }*/ + QDomElement journal_de = _doc.createElement( "journal" ); + journal_de.setAttribute( "id", id() ); + journal_de.setAttribute( "entries", m_journalEntries.size() ); + journal_de.setAttribute( "curentry", m_currentJournalEntry - + m_journalEntries.begin() ); + journal_de.setAttribute( "metadata", TRUE ); + + for( journalEntryVector::const_iterator it = m_journalEntries.begin(); + it != m_journalEntries.end(); ++it ) + { + QDomElement je_de = _doc.createElement( "entry" ); + je_de.setAttribute( "pos", it - m_journalEntries.begin() ); + je_de.setAttribute( "actionid", it->actionID() ); + je_de.setAttribute( "data", base64::encode( it->data() ) ); + journal_de.appendChild( je_de ); + } + + _parent.appendChild( journal_de ); +} + + + + +void journallingObject::loadJournal( const QDomElement & _this ) +{ + clear(); + + const jo_id_t new_id = _this.attribute( "id" ).toInt(); + + if( new_id == 0 ) + { + return; + } + + if( id() != new_id ) + { + eng()->getProjectJournal()->forgetAboutID( id() ); + eng()->getProjectJournal()->reallocID( new_id, this ); + m_id = new_id; + } + + m_journalEntries.resize( _this.attribute( "entries" ).toInt() ); + + QDomNode node = _this.firstChild(); + while( !node.isNull() ) + { + if( node.isElement() ) + { + const QDomElement & je = node.toElement(); + m_journalEntries[je.attribute( "pos" ).toInt()] = + journalEntry( + je.attribute( "actionid" ).toInt(), + base64::decode( je.attribute( "data" ) ) ); + } + node = node.nextSibling(); + } + + m_currentJournalEntry = m_journalEntries.begin() + + _this.attribute( "curentry" ).toInt(); +} + + + +#endif diff --git a/src/lib/mmp.cpp b/src/lib/mmp.cpp index e78b7bca0..5f00332ad 100644 --- a/src/lib/mmp.cpp +++ b/src/lib/mmp.cpp @@ -55,11 +55,14 @@ multimediaProject::typeDescStruct { multimediaProject::UNKNOWN, "unknown" }, { multimediaProject::SONG_PROJECT, "song" }, { multimediaProject::SONG_PROJECT_TEMPLATE, "songtemplate" }, - { multimediaProject::CHANNEL_SETTINGS, "channelsettings" }, +#warning compat-code, remove in 0.3.0 + { multimediaProject::INSTRUMENT_TRACK_SETTINGS, + "instrumenttracksettings,channelsettings" }, { multimediaProject::DRAG_N_DROP_DATA, "dnddata" }, + { multimediaProject::JOURNAL_DATA, "journaldata" }, { multimediaProject::EFFECT_SETTINGS, "effectsettings" }, - { multimediaProject::VIDEO_PROJECT, "video" }, - { multimediaProject::BURN_PROJECT, "burn" }, + { multimediaProject::VIDEO_PROJECT, "videoproject" }, + { multimediaProject::BURN_PROJECT, "burnproject" }, { multimediaProject::PLAYLIST, "playlist" } } ; @@ -162,7 +165,9 @@ multimediaProject::multimediaProject( const QString & _in_file_name, { m_head = node.toElement(); } - else if( node.nodeName() == typeName( m_type ) ) + else if( node.nodeName() == typeName( m_type ) || +#warning compat-code, remove in 0.3.0 + node.nodeName() == "channelsettings" ) { m_content = node.toElement(); } @@ -189,7 +194,7 @@ bool multimediaProject::writeFile( const QString & _fn, bool _overwrite_check ) #endif ); QString fn = _fn; - if( type() == CHANNEL_SETTINGS ) + if( type() == INSTRUMENT_TRACK_SETTINGS ) { if( fn.section( '.', -2, -1 ) != "cs.xml" ) { @@ -282,7 +287,12 @@ multimediaProject::projectTypes multimediaProject::type( { for( int i = 0; i < PROJ_TYPE_COUNT; ++i ) { - if( s_types[i].m_name == _type_name ) + if( s_types[i].m_name == _type_name || ( + s_types[i].m_name.contains( "," ) && ( + s_types[i].m_name.section( ',', 0, 0 ) == _type_name || + s_types[i].m_name.section( ',', 1, 1 ) == _type_name ) ) + ) + { return( static_cast( i ) ); diff --git a/src/lib/project_journal.cpp b/src/lib/project_journal.cpp new file mode 100644 index 000000000..6bed987bf --- /dev/null +++ b/src/lib/project_journal.cpp @@ -0,0 +1,162 @@ +#ifndef SINGLE_SOURCE_COMPILE + +/* + * project_journal.cpp - implementation of project-journal + * + * Copyright (c) 2006 Tobias Doerffel + * + * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + + +#include + +#include "project_journal.h" +#include "journalling_object.h" +#include "song_editor.h" + + + +projectJournal::projectJournal( engine * _engine ) : + engineObject( _engine ), + m_joIDs(), + m_journalEntries(), + m_currentJournalEntry( m_journalEntries.end() ) +{ +} + + + + +projectJournal::~projectJournal() +{ +} + + + + +void projectJournal::undo( void ) +{ + if( m_journalEntries.empty() == TRUE ) + { + return; + } + + journallingObject * jo; + + if( m_currentJournalEntry - 1 >= m_journalEntries.begin() && + ( jo = m_joIDs[*--m_currentJournalEntry] ) != NULL ) + { + jo->undo(); + eng()->getSongEditor()->setModified(); + } +} + + + + +void projectJournal::redo( void ) +{ + if( m_journalEntries.empty() == TRUE ) + { + return; + } + + journallingObject * jo; + + if( m_currentJournalEntry < m_journalEntries.end() && + ( jo = m_joIDs[*m_currentJournalEntry++] ) != NULL ) + { + jo->redo(); + eng()->getSongEditor()->setModified(); + } +} + + + + +void projectJournal::journalEntryAdded( const jo_id_t _id ) +{ + m_journalEntries.erase( m_currentJournalEntry, m_journalEntries.end() ); + m_journalEntries.push_back( _id ); + m_currentJournalEntry = m_journalEntries.end(); + eng()->getSongEditor()->setModified(); + printf("history size:%d\n", m_journalEntries.size()); +} + + + + +jo_id_t projectJournal::allocID( journallingObject * _obj ) +{ + const jo_id_t EO_ID_MAX = 1 << 20; + + jo_id_t id; + while( m_joIDs.contains( id = static_cast( (float) rand() / + RAND_MAX * EO_ID_MAX ) ) ) + { + } + m_joIDs[id] = _obj; + //printf("new id: %d\n", id ); + return( id ); +} + + + + +void projectJournal::reallocID( const jo_id_t _id, journallingObject * _obj ) +{ + //printf("realloc %d %d\n", _id, _obj); + if( m_joIDs.contains( _id ) ) + { + m_joIDs[_id] = _obj; + } +} + + + + +void projectJournal::forgetAboutID( const jo_id_t _id ) +{ + journalEntryVector::iterator it; + while( ( it = qFind( m_journalEntries.begin(), m_journalEntries.end(), + _id ) ) != m_journalEntries.end() ) + { + if( m_currentJournalEntry >= it ) + { + --m_currentJournalEntry; + } + m_journalEntries.erase( it ); + } + m_joIDs.erase( _id ); +} + + + + +void projectJournal::clear( void ) +{ + while( m_joIDs.size() ) + { + forgetAboutID( m_joIDs.keys().front() ); + } +} + + +#endif diff --git a/src/lmms_single_source.cpp b/src/lmms_single_source.cpp index f634e3995..d6da8a54e 100644 --- a/src/lmms_single_source.cpp +++ b/src/lmms_single_source.cpp @@ -1,8 +1,11 @@ #ifdef SINGLE_SOURCE_COMPILE #undef SINGLE_SOURCE_COMPILE +#include "src/tracks/instrument_track.cpp" +#include "src/core/midi_tab_widget.cpp" #include "src/lib/string_pair_drag.cpp" #include "src/lib/buffer_allocator.cpp" -#include "src/lib/edit_history.cpp" +#include "src/lib/journalling_object.cpp" +#include "src/lib/project_journal.cpp" #include "src/lib/embed.cpp" #include "src/lib/base64.cpp" #include "src/lib/mmp.cpp" @@ -39,7 +42,6 @@ #include "src/core/track.cpp" #include "src/core/file_browser.cpp" #include "src/core/surround_area.cpp" -#include "src/core/midi_tab_widget.cpp" #include "src/midi/midi_alsa_seq.cpp" #include "src/midi/midi_oss.cpp" #include "src/midi/midi_port.cpp" @@ -59,7 +61,6 @@ #include "src/lmms_single_source.cpp" #include "src/tracks/pattern.cpp" #include "src/tracks/bb_track.cpp" -#include "src/tracks/channel_track.cpp" #include "src/tracks/sample_track.cpp" #include "src/widgets/project_notes.cpp" #include "src/widgets/led_checkbox.cpp" diff --git a/src/tracks/bb_track.cpp b/src/tracks/bb_track.cpp index a6054eff6..a20868c26 100644 --- a/src/tracks/bb_track.cpp +++ b/src/tracks/bb_track.cpp @@ -72,9 +72,9 @@ bbTCO::bbTCO( track * _track, const QColor & _c ) : bbTrack::numOfBBTrack( getTrack() ) ); if( t > 0 ) { - saveStepRecordingState( FALSE ); + saveJournallingState( FALSE ); changeLength( midiTime( t, 0 ) ); - restoreStepRecordingState(); + restoreJournallingState(); } } @@ -192,21 +192,19 @@ void bbTCO::paintEvent( QPaintEvent * ) -void bbTCO::saveSettings( QDomDocument & _doc, QDomElement & _parent ) +void bbTCO::saveSettings( QDomDocument & _doc, QDomElement & _this ) { - QDomElement bbtco_de = _doc.createElement( nodeName() ); - bbtco_de.setAttribute( "name", m_name ); - if( _parent.nodeName() == "clipboard" ) + _this.setAttribute( "name", m_name ); + if( _this.parentNode().nodeName() == "clipboard" ) { - bbtco_de.setAttribute( "pos", -1 ); + _this.setAttribute( "pos", -1 ); } else { - bbtco_de.setAttribute( "pos", startPosition() ); + _this.setAttribute( "pos", startPosition() ); } - bbtco_de.setAttribute( "len", length() ); - bbtco_de.setAttribute( "color", m_color.rgb() ); - _parent.appendChild( bbtco_de ); + _this.setAttribute( "len", length() ); + _this.setAttribute( "color", m_color.rgb() ); } @@ -419,18 +417,16 @@ trackContentObject * bbTrack::createTCO( const midiTime & _pos ) void bbTrack::saveTrackSpecificSettings( QDomDocument & _doc, - QDomElement & _parent ) + QDomElement & _this ) { - QDomElement bbt_de = _doc.createElement( nodeName() ); - bbt_de.setAttribute( "name", m_trackLabel->text() ); - bbt_de.setAttribute( "icon", m_trackLabel->pixmapFile() ); -/* bbt_de.setAttribute( "current", s_infoMap[this] == + _this.setAttribute( "name", m_trackLabel->text() ); + _this.setAttribute( "icon", m_trackLabel->pixmapFile() ); +/* _this.setAttribute( "current", s_infoMap[this] == eng()->getBBEditor()->currentBB() );*/ - _parent.appendChild( bbt_de ); if( s_infoMap[this] == 0 && - _parent.parentNode().nodeName() != "clone" ) + _this.parentNode().nodeName() != "clone" ) { - eng()->getBBEditor()->saveSettings( _doc, bbt_de ); + eng()->getBBEditor()->saveState( _doc, _this ); } } @@ -446,7 +442,7 @@ void bbTrack::loadTrackSpecificSettings( const QDomElement & _this ) } if( _this.firstChild().isElement() ) { - eng()->getBBEditor()->loadSettings( + eng()->getBBEditor()->restoreState( _this.firstChild().toElement() ); } /* doesn't work yet because bbTrack-ctor also sets current bb so if diff --git a/src/tracks/instrument_track.cpp b/src/tracks/instrument_track.cpp new file mode 100644 index 000000000..56d3d8304 --- /dev/null +++ b/src/tracks/instrument_track.cpp @@ -0,0 +1,1327 @@ +#ifndef SINGLE_SOURCE_COMPILE + +/* + * instrument_track.cpp - implementation of instrument-track-class + * (window + data-structures) + * + * Copyright (c) 2004-2006 Tobias Doerffel + * + * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + + +#include "qt3support.h" + +#ifdef QT4 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#else + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif + + +#include "instrument_track.h" +#include "pattern.h" +#include "main_window.h" +#include "song_editor.h" +#include "effect_board.h" +#include "envelope_tab_widget.h" +#include "arp_and_chords_tab_widget.h" +#include "instrument.h" +#include "audio_port.h" +#include "midi_client.h" +#include "midi_port.h" +#include "midi_tab_widget.h" +#include "note_play_handle.h" +#include "embed.h" +#include "fade_button.h" +#include "knob.h" +#include "lcd_spinbox.h" +#include "led_checkbox.h" +#include "piano_widget.h" +#include "surround_area.h" +#include "tooltip.h" +#include "tab_widget.h" +#include "buffer_allocator.h" +#include "config_mgr.h" +#include "debug.h" +#include "mmp.h" +#include "string_pair_drag.h" + + +const char * volume_help = QT_TRANSLATE_NOOP( "instrumentTrack", + "With this knob you can set " + "the volume of the opened " + "channel."); +const char * surroundarea_help = QT_TRANSLATE_NOOP( "instrumentTrack", + "Within this rectangle you can " + "set the position where the " + "channel should be audible. " + "You should have a soundcard " + "supporting at least surround " + "4.0 for enjoying this " + "feature." ); + + +const int CHANNEL_WIDTH = 250; +const int INSTRUMENT_WIDTH = CHANNEL_WIDTH; +const int INSTRUMENT_HEIGHT = INSTRUMENT_WIDTH; +const int PIANO_HEIGHT = 84; + + +instrumentTrack::instrumentTrack( trackContainer * _tc ) : + QWidget( _tc->eng()->getMainWindow()->workspace() ), + track( _tc ), + midiEventProcessor(), + m_trackType( CHANNEL_TRACK ), + m_midiPort( eng()->getMixer()->getMIDIClient()->addPort( this, + tr( "unnamed_channel" ) ) ), + m_audioPort( new audioPort( tr( "unnamed_channel" ), eng() ) ), + m_notes(), + m_notesMutex(), + m_baseTone( A ), + m_baseOctave( OCTAVE_4 ), + m_instrument( NULL ), +#ifdef QT4 + m_midiInputAction( NULL ), + m_midiOutputAction( NULL ) +#else + m_midiInputID( -1 ), + m_midiOutputID( -1 ) +#endif +{ + m_notesMutex.lock(); + for( int i = 0; i < NOTES_PER_OCTAVE * OCTAVES; ++i ) + { + m_notes[i] = NULL; + } + m_notesMutex.unlock(); + + +#ifdef QT4 + eng()->getMainWindow()->workspace()->addWindow( this ); +#endif + + setAcceptDrops( TRUE ); + + hide(); + + getTrackWidget()->setFixedHeight( 32 ); + + + // creation of widgets for track-settings-widget + m_tswVolumeKnob = new knob( knobSmall_17, getTrackSettingsWidget(), + tr( "Channel volume" ), eng() ); + m_tswVolumeKnob->setRange( MIN_VOLUME, MAX_VOLUME, 1.0f ); + m_tswVolumeKnob->setInitValue( DEFAULT_VOLUME ); + m_tswVolumeKnob->setHintText( tr( "Channel volume:" ) + " ", "%" ); + m_tswVolumeKnob->move( 4, 4 ); + m_tswVolumeKnob->setLabel( tr( "VOL" ) ); + m_tswVolumeKnob->show(); +/* connect( m_tswVolumeKnob, SIGNAL( valueChanged( float ) ), this, + SLOT( volValueChanged( float ) ) );*/ +#ifdef QT4 + m_tswVolumeKnob->setWhatsThis( +#else + QWhatsThis::add( m_tswVolumeKnob, +#endif + tr( volume_help ) ); + + QPushButton * tsw_midi = new QPushButton( + embed::getIconPixmap( "piano" ), QString::null, + getTrackSettingsWidget() ); + tsw_midi->setGeometry( 32, 2, 28, 28 ); + tsw_midi->show(); + toolTip::add( tsw_midi, tr( "MIDI input/output" ) ); + m_tswMidiMenu = new QMenu( tsw_midi ); + tsw_midi->setMenu( m_tswMidiMenu ); + + + m_tswActivityIndicator = new fadeButton( QColor( 96, 96, 96 ), + QColor( 255, 204, 0 ), + getTrackSettingsWidget() ); + m_tswActivityIndicator->setGeometry( 212, 2, 8, 28 ); + m_tswActivityIndicator->show(); + connect( m_tswActivityIndicator, SIGNAL( pressed( void ) ), + this, SLOT( activityIndicatorPressed() ) ); + connect( m_tswActivityIndicator, SIGNAL( released( void ) ), + this, SLOT( activityIndicatorReleased() ) ); + + + m_tswInstrumentTrackButton = new instrumentTrackButton( this ); + m_tswInstrumentTrackButton->setCheckable( TRUE ); + m_tswInstrumentTrackButton->setGeometry( 64, 2, 144, 28 ); + m_tswInstrumentTrackButton->show(); + connect( m_tswInstrumentTrackButton, SIGNAL( toggled( bool ) ), this, + SLOT( toggledInstrumentTrackButton( bool ) ) ); + + + + // init own layout + widgets +#ifdef QT4 + setFocusPolicy( Qt::StrongFocus ); +#else + setFocusPolicy( StrongFocus ); +#endif + QVBoxLayout * vlayout = new QVBoxLayout( this ); + vlayout->setMargin( 0 ); + vlayout->setSpacing( 0 ); + + m_generalSettingsWidget = new tabWidget( tr( "GENERAL SETTINGS" ), + this ); + m_generalSettingsWidget->setFixedHeight( 90 ); + + // setup line-edit for changing channel-name + m_instrumentNameLE = new QLineEdit( m_generalSettingsWidget ); + m_instrumentNameLE->setFont( pointSize<8>( + m_instrumentNameLE->font() ) ); + m_instrumentNameLE->setGeometry( 10, 16, 230, 18 ); + connect( m_instrumentNameLE, SIGNAL( textChanged( const QString & ) ), + this, SLOT( textChanged( const QString & ) ) ); + + + // setup volume-knob + m_volumeKnob = new knob( knobBright_26, m_generalSettingsWidget, + tr( "Channel volume" ), eng() ); + m_volumeKnob->move( 10, 44 ); + m_volumeKnob->setRange( MIN_VOLUME, MAX_VOLUME, 1.0f ); + m_volumeKnob->setInitValue( DEFAULT_VOLUME ); + m_volumeKnob->setHintText( tr( "Channel volume:" ) + " ", "%" ); + m_volumeKnob->setLabel( tr( "VOLUME" ) ); + +#ifdef QT4 + m_volumeKnob->setWhatsThis( +#else + QWhatsThis::add( m_volumeKnob, +#endif + tr( volume_help ) ); +/* connect( m_volumeKnob, SIGNAL( valueChanged( float ) ), this, + SLOT( volValueChanged( float ) ) );*/ + knob::linkObjects( m_tswVolumeKnob, m_volumeKnob ); + + + // setup surround-area + m_surroundArea = new surroundArea( m_generalSettingsWidget ); + m_surroundArea->move( 20 + m_volumeKnob->width(), 38 ); + m_surroundArea->show(); +#ifdef QT4 + m_surroundArea->setWhatsThis( +#else + QWhatsThis::add( m_surroundArea, +#endif + tr( surroundarea_help ) ); + + connect( m_surroundArea, SIGNAL( valueChanged( const QPoint & ) ), + this, + SLOT( surroundAreaPosChanged( const QPoint & ) ) ); + + + + // setup spinbox for selecting FX-channel + m_effectChannelNumber = new lcdSpinBox( MIN_EFFECT_CHANNEL, + MAX_EFFECT_CHANNEL, 2, + m_generalSettingsWidget, + eng() ); + m_effectChannelNumber->setInitValue( DEFAULT_EFFECT_CHANNEL ); + m_effectChannelNumber->setLabel( tr( "FX CHNL" ) ); + m_effectChannelNumber->move( m_surroundArea->x() + + m_surroundArea->width() + 16, 40 ); + + + m_saveSettingsBtn = new QPushButton( embed::getIconPixmap( + "project_save" ), "", + m_generalSettingsWidget ); + m_saveSettingsBtn->setGeometry( m_effectChannelNumber->x() + + m_effectChannelNumber->width() + 20, 40, + 32, 32 ); + connect( m_saveSettingsBtn, SIGNAL( clicked() ), this, + SLOT( saveSettingsBtnClicked() ) ); + toolTip::add( m_saveSettingsBtn, + tr( "Save current channel settings in a preset-file" ) ); +#ifdef QT4 + m_saveSettingsBtn->setWhatsThis( +#else + QWhatsThis::add( m_saveSettingsBtn, +#endif + tr( "Click here, if you want to save current channel settings " + "in a preset-file. Later you can load this preset by " + "double-clicking it in the preset-browser." ) ); + + + setVolume( DEFAULT_VOLUME ); + setSurroundAreaPos( QPoint() ); + setName( tr( "Default" ) ); + + + m_tabWidget = new tabWidget( "", this ); + m_tabWidget->setFixedHeight( INSTRUMENT_HEIGHT + 12 ); + + + // create other tab-widgets + m_envWidget = new envelopeTabWidget( this ); + m_arpWidget = new arpAndChordsTabWidget( this ); + m_midiWidget = new midiTabWidget( this, m_midiPort ); + m_tabWidget->addTab( m_envWidget, tr( "ENV/LFO/FILTER" ), 1 ); + m_tabWidget->addTab( m_arpWidget, tr( "ARP/CHORD" ), 2 ); + m_tabWidget->addTab( m_midiWidget, tr( "MIDI" ), 3 ); + + // setup piano-widget + m_pianoWidget = new pianoWidget( this ); + m_pianoWidget->setFixedSize( CHANNEL_WIDTH, PIANO_HEIGHT ); + + + vlayout->addWidget( m_generalSettingsWidget ); + vlayout->addWidget( m_tabWidget ); + vlayout->addWidget( m_pianoWidget ); + +#ifdef QT4 + m_midiInputAction = m_tswMidiMenu->addMenu( + m_midiWidget->m_readablePorts ); + m_midiOutputAction = m_tswMidiMenu->addMenu( + m_midiWidget->m_writeablePorts ); + m_midiInputAction->setText( tr( "MIDI input" ) ); + m_midiOutputAction->setText( tr( "MIDI output" ) ); + if( m_midiWidget->m_readablePorts == NULL ) + { + connect( m_midiInputAction, SIGNAL( changed() ), this, + SLOT( midiInSelected() ) ); + } + if( m_midiWidget->m_writeablePorts == NULL ) + { + connect( m_midiOutputAction, SIGNAL( changed() ), this, + SLOT( midiOutSelected() ) ); + } +#else + m_midiInputID = m_tswMidiMenu->insertItem( tr( "MIDI input" ), + m_midiWidget->m_readablePorts ); + if( m_midiWidget->m_readablePorts == NULL ) + { + m_tswMidiMenu->connectItem( m_midiInputID, this, + SLOT( midiInSelected() ) ); + } + m_midiOutputID = m_tswMidiMenu->insertItem( tr( "MIDI output" ), + m_midiWidget->m_writeablePorts ); + if( m_midiWidget->m_writeablePorts == NULL ) + { + m_tswMidiMenu->connectItem( m_midiOutputID, this, + SLOT( midiOutSelected() ) ); + } +#endif + if( m_midiWidget->m_readablePorts == NULL || + m_midiWidget->m_writeablePorts == NULL ) + { + connect( m_midiWidget->m_sendCheckBox, + SIGNAL( toggled( bool ) ), + this, SLOT( midiConfigChanged( bool ) ) ); + connect( m_midiWidget->m_receiveCheckBox, + SIGNAL( toggled( bool ) ), + this, SLOT( midiConfigChanged( bool ) ) ); + } + + + // set window-icon + setWindowIcon( embed::getIconPixmap( "instrument_track" ) ); + + + _tc->updateAfterTrackAdd(); +} + + + + + + +instrumentTrack::~instrumentTrack() +{ + invalidateAllMyNPH(); + delete m_audioPort; + eng()->getMixer()->getMIDIClient()->removePort( m_midiPort ); +} + + + + + + + +void instrumentTrack::saveSettingsBtnClicked( void ) +{ +#ifdef QT4 + QFileDialog sfd( this, tr( "Save channel-settings in file" ), "", + tr( "Channel-Settings-File (*.cs.xml)" ) ); +#else + QFileDialog sfd( this, "", TRUE ); + sfd.setWindowTitle( tr( "Save channel-settings in file" ) ); + sfd.setFilter( tr( "Channel-Settings-File (*.cs.xml)" ) ); +#endif + + QString preset_root = configManager::inst()->presetsDir(); + if( !QDir( preset_root ).exists() ) + { + QDir().mkdir( preset_root ); + } + if( !QDir( preset_root + instrumentName() ).exists() ) + { + QDir( preset_root ).mkdir( instrumentName() ); + } + + sfd.setDirectory( preset_root + instrumentName() ); + sfd.setFileMode( QFileDialog::AnyFile ); + if( sfd.exec () == QDialog::Accepted && +#ifdef QT4 + !sfd.selectedFiles().isEmpty() && sfd.selectedFiles()[0] != "" +#else + sfd.selectedFile() != "" +#endif + ) + { + multimediaProject mmp( + multimediaProject::INSTRUMENT_TRACK_SETTINGS ); + saveTrackSpecificSettings( mmp, mmp.content() ); +#ifdef QT4 + mmp.writeFile( sfd.selectedFiles()[0] ); +#else + mmp.writeFile( sfd.selectedFile() ); +#endif + } +} + + + + +void instrumentTrack::activityIndicatorPressed( void ) +{ + processInEvent( midiEvent( NOTE_ON, 0, + DEFAULT_OCTAVE * NOTES_PER_OCTAVE + A, + 127 ), midiTime() ); +} + + + + +void instrumentTrack::activityIndicatorReleased( void ) +{ + processInEvent( midiEvent( NOTE_OFF, 0, + DEFAULT_OCTAVE * NOTES_PER_OCTAVE + A, + 0 ), midiTime() ); +} + + + + +void instrumentTrack::midiInSelected( void ) +{ +#ifdef QT4 + m_midiInputAction->setChecked( !m_midiInputAction->isChecked() ); + m_midiWidget->m_receiveCheckBox->setChecked( + m_midiInputAction->isChecked() ); +#else + m_tswMidiMenu->setItemChecked( m_midiInputID, + !m_tswMidiMenu->isItemChecked( m_midiInputID ) ); + m_midiWidget->m_receiveCheckBox->setChecked( + m_tswMidiMenu->isItemChecked( m_midiInputID ) ); +#endif +} + + + +void instrumentTrack::midiOutSelected( void ) +{ +#ifdef QT4 + m_midiOutputAction->setChecked( !m_midiOutputAction->isChecked() ); + m_midiWidget->m_sendCheckBox->setChecked( + m_midiOutputAction->isChecked() ); +#else + m_tswMidiMenu->setItemChecked( m_midiOutputID, + !m_tswMidiMenu->isItemChecked( m_midiOutputID ) ); + m_midiWidget->m_sendCheckBox->setChecked( + m_tswMidiMenu->isItemChecked( m_midiOutputID ) ); +#endif +} + + + + +void instrumentTrack::midiConfigChanged( bool ) +{ +#ifdef QT4 + m_midiInputAction->setChecked( + m_midiWidget->m_receiveCheckBox->isChecked() ); + m_midiOutputAction->setChecked( + m_midiWidget->m_sendCheckBox->isChecked() ); +#else + m_tswMidiMenu->setItemChecked( m_midiInputID, + m_midiWidget->m_receiveCheckBox->isChecked( ) ); + m_tswMidiMenu->setItemChecked( m_midiOutputID, + m_midiWidget->m_sendCheckBox->isChecked( ) ); +#endif +} + + + + +float instrumentTrack::frequency( notePlayHandle * _n ) const +{ + return( BASE_FREQ * powf( 2.0f, (float)( _n->tone() - m_baseTone + + eng()->getSongEditor()->masterPitch() ) / 12.0f + + (float)( _n->octave() - m_baseOctave ) ) ); +} + + + + +f_cnt_t instrumentTrack::beatLen( notePlayHandle * _n ) const +{ + if( m_instrument != NULL ) + { + const f_cnt_t len = m_instrument->beatLen( _n ); + if( len > 0 ) + { + return( len ); + } + } + return( m_envWidget->envFrames() ); +} + + + + + + +void instrumentTrack::processAudioBuffer( sampleFrame * _buf, + const fpab_t _frames, + notePlayHandle * _n ) +{ + // we must not play the sound if this instrumentTrack is muted... + if( muted() ) + { + return; + } + float v_scale = (float) getVolume() / DEFAULT_VOLUME; + + // instruments using instrument-play-handles will call this method + // without any knowledge about notes, so they pass NULL for _n, which + // is no problem for us since we just bypass the envelopes+LFOs + if( _n != NULL ) + { + m_envWidget->processAudioBuffer( _buf, _frames, _n ); + v_scale *= ( (float) _n->getVolume() / DEFAULT_VOLUME ); + const fpab_t ENV_FRAMES = 32; + if( _n->totalFramesPlayed() == 0 ) + { + // very basic envelope for not having clicks at the + // beginning + for( fpab_t i = 0; i < tMin( _frames, + ENV_FRAMES ); ++i ) + { + for( ch_cnt_t ch = 0; ch < DEFAULT_CHANNELS; + ++ch ) + { + _buf[i][ch] *= (float) i / ENV_FRAMES; + } + } + } + // last time we're called for current note? + if( ( _n->actualReleaseFramesToDo() == 0 && + _n->totalFramesPlayed() + + eng()->getMixer()->framesPerAudioBuffer() >= + _n->frames() ) || + ( _n->released() && _n->releaseFramesDone() + + eng()->getMixer()->framesPerAudioBuffer() >= + _n->actualReleaseFramesToDo() ) ) + { + // then do a soft fade-out at the end to avoid clicks + for( fpab_t i = ( _frames >= ENV_FRAMES ) ? + _frames - ENV_FRAMES : 0; + i < _frames; ++i ) + { + for( ch_cnt_t ch = 0; ch < DEFAULT_CHANNELS; + ++ch ) + { + _buf[i][ch] *= (float) ( _frames - i ) / + ENV_FRAMES; + } + } + } + } + + volumeVector v = m_surroundArea->getVolumeVector( v_scale ); + + eng()->getMixer()->bufferToPort( _buf, _frames, + ( _n != NULL ) ? _n->framesAhead() : 0, v, + m_audioPort ); +} + + + + +void instrumentTrack::processInEvent( const midiEvent & _me, + const midiTime & _time ) +{ + m_notesMutex.lock(); + switch( _me.m_type ) + { + case NOTE_ON: + if( _me.velocity() > 0 ) + { + if( m_notes[_me.key()] == NULL ) + { + if( !configManager::inst()->value( "ui", + "manualchannelpiano" ).toInt() ) + { + m_pianoWidget->setKeyState( + _me.key(), TRUE ); + } + // create temporary note + note n; + n.setKey( _me.key() ); + n.setVolume( _me.velocity() * 100 / + 127 ); + // create (timed) note-play-handle + notePlayHandle * nph = new + notePlayHandle( this, + _time.frames( eng()->getSongEditor()->framesPerTact() ), + ~0, n ); + if( eng()->getMixer()->addPlayHandle( + nph ) ) + { + m_notes[_me.key()] = nph; + } + } + break; + } + + case NOTE_OFF: + if( m_notes[_me.key()] != NULL ) + { + notePlayHandle * n = m_notes[_me.key()]; + // create dummy-note which has the same length + // as the played note for sending it later + // to all slots connected to signal noteDone() + // this is for example needed by piano-roll for + // recording notes into a pattern + note done_note( NULL, + midiTime( static_cast( + n->totalFramesPlayed() * 64 / + eng()->getSongEditor()->framesPerTact() ) ), + 0, n->tone(), n->octave(), + n->getVolume(), n->getPanning() ); + n->noteOff(); + m_notes[_me.key()] = NULL; + emit noteDone( done_note ); + } + break; + + case KEY_PRESSURE: + if( m_notes[_me.key()] != NULL ) + { + m_notes[_me.key()]->setVolume( _me.velocity() * + 100 / 128 ); + } + break; + +/* case PITCH_BEND: + if( m_pitchBendKnob != NULL ) + { + float range = tAbs( + m_pitchBendKnob->maxValue() - + m_pitchBendKnob->minValue() ); + m_pitchBendKnob->setValue( + m_pitchBendKnob->minValue() + + _me.m_data.m_param[0] * + range / 16384 ); + } + break;*/ + + default: + printf( "channel-track: unhandled MIDI-event %d\n", + _me.m_type ); + break; + } + m_notesMutex.unlock(); +} + + + + +void instrumentTrack::processOutEvent( const midiEvent & _me, + const midiTime & _time ) +{ + if( _me.m_type == NOTE_ON && !configManager::inst()->value( "ui", + "disablechannelactivityindicators" ).toInt() ) + { + //QMutexLocker ml( &m_notesMutex ); + if( m_notes[_me.key()] != NULL ) + { + return; + } + m_tswActivityIndicator->activate(); + } + // if appropriate, midi-port does futher routing + m_midiPort->processOutEvent( _me, _time ); +} + + + + +void instrumentTrack::playNote( notePlayHandle * _n ) +{ + // arpeggio- and chord-widget has to do its work -> adding sub-notes + // for chords/arpeggios + m_arpWidget->processNote( _n ); + + if( _n->arpBaseNote() == FALSE && m_instrument != NULL ) + { + // all is done, so now lets play the note! + m_instrument->playNote( _n ); + } +} + + + + +QString instrumentTrack::instrumentName( void ) const +{ + if( m_instrument != NULL ) + { + return( m_instrument->publicName() ); + } + return( "" ); +} + + + + +void instrumentTrack::deleteNotePluginData( notePlayHandle * _n ) +{ + if( m_instrument != NULL ) + { + m_instrument->deleteNotePluginData( _n ); + } +} + + + + +void instrumentTrack::setName( const QString & _new_name ) +{ + // when changing name of channel, also change name of those patterns, + // which have the same name as the channel + for( csize i = 0; i < numOfTCOs(); ++i ) + { + pattern * p = dynamic_cast( getTCO( i ) ); + if( p != NULL && p->name() == m_name || p->name() == "" ) + { + p->setName( _new_name ); + } + } + + m_name = _new_name; + setWindowTitle( m_name ); + + if( m_instrumentNameLE->text() != _new_name ) + { + m_instrumentNameLE->setText( m_name ); + } +#ifdef LMMS_DEBUG + assert( m_tswInstrumentTrackButton != NULL ); +#endif + m_tswInstrumentTrackButton->setText( m_name ); + m_midiPort->setName( m_name ); + m_audioPort->setName( m_name ); +} + + + + +void instrumentTrack::setVolume( volume _new_volume ) +{ + if( _new_volume <= MAX_VOLUME ) + { + m_volumeKnob->setValue( _new_volume ); + //m_tswVolumeKnob->setValue( _new_volume ); + } +} + + + + +volume instrumentTrack::getVolume( void ) const +{ + return( static_cast( m_volumeKnob->value() ) ); +} + + + + +void instrumentTrack::setSurroundAreaPos( const QPoint & _p ) +{ + if( m_surroundArea->value() != _p ) + { + m_surroundArea->setValue( _p ); + } +/* if( m_tswSurroundArea->value() != _p ) + { + m_tswSurroundArea->setValue( _p ); + }*/ +} + + + + +const QPoint & instrumentTrack::surroundAreaPos( void ) const +{ + return( m_surroundArea->value() ); +} + + + + +void instrumentTrack::setBaseTone( tones _new_tone ) +{ + if( _new_tone >= C && _new_tone <= H ) + { + m_baseTone = _new_tone; + } + eng()->getSongEditor()->setModified(); +} + + + + +void instrumentTrack::setBaseOctave( octaves _new_octave ) +{ + if( _new_octave >= MIN_OCTAVE && _new_octave <= MAX_OCTAVE ) + { + m_baseOctave = _new_octave; + } + eng()->getSongEditor()->setModified(); +} + + + + +int instrumentTrack::masterKey( notePlayHandle * _n ) const +{ + int key = baseTone() + baseOctave() * NOTES_PER_OCTAVE + + eng()->getSongEditor()->masterPitch(); + return( _n->key() - ( key - A - DEFAULT_OCTAVE * NOTES_PER_OCTAVE ) ); +} + + + + +bool FASTCALL instrumentTrack::play( const midiTime & _start, + const f_cnt_t _start_frame, + const fpab_t _frames, + const f_cnt_t _frame_base, + Sint16 _tco_num ) +{ + // calculate samples per tact; need that later when calculating + // sample-pos of a note + float frames_per_tact = eng()->getSongEditor()->framesPerTact(); + + vlist tcos; + if( _tco_num >= 0 ) + { + tcos.push_back( getTCO( _tco_num ) ); + } + else + { + getTCOsInRange( tcos, _start, _start + + static_cast( _frames * 64 / + frames_per_tact ) ); + } + + if ( tcos.size() == 0 ) + { + return( FALSE ); + } + + bool played_a_note = FALSE; // will be return variable + + // calculate the end of the current sample-frame + const f_cnt_t end_frame = _start_frame+_frames-1; + + for( vlist::iterator it = tcos.begin(); + it != tcos.end(); ++it ) + { + pattern * p = dynamic_cast( *it ); + if( p == NULL ) + { + continue; + } + midiTime cur_start = _start.getTact() * 64 - + ( ( _tco_num < 0 ) ? + p->startPosition() : + midiTime( 0 ) ); + if( p->frozen() && + eng()->getSongEditor()->exporting() == FALSE ) + { + volumeVector v = m_surroundArea->getVolumeVector( + 1.0f ); + // volume-vector was already used when freezing + // pattern, but only in stereo-mode, so front speakers + // are already setup + v.vol[0] = 1.0f; + v.vol[1] = 1.0f; + sampleFrame * buf = bufferAllocator::alloc( + _frames ); + + p->playFrozenData( buf, _start_frame + + static_cast( + cur_start.getTact() * + frames_per_tact ), + _frames ); + eng()->getMixer()->bufferToPort( buf, _frames, + _frame_base + + static_cast( + p->startPosition().getTact64th() * + frames_per_tact / + 64.0f ), + v, m_audioPort ); + bufferAllocator::free( buf ); + continue; + } + + // get all notes from the given pattern... + noteVector & notes = p->notes(); + // ...and set our index to zero + noteVector::iterator it = notes.begin(); + + // very effective algorithm for playing notes that are + // posated within the current sample-frame + + + if( cur_start > 0 ) + { + // skip notes which are posated before start-tact + while( it != notes.end() && ( *it )->pos() < cur_start ) + { + ++it; + } + } + + // skip notes before sample-frame + while( it != notes.end() && + ( *it )->pos( cur_start ).frames( frames_per_tact ) < + _start_frame ) + { + ++it; + } + + note * cur_note; + while( it != notes.end() && + ( ( cur_note = *it )->pos( cur_start ).frames( + frames_per_tact ) ) <= end_frame ) + { + if( cur_note->length() != 0 ) + { + const f_cnt_t frames_ahead = _frame_base - + _start_frame + + cur_note->pos( cur_start ).frames( frames_per_tact ); + + const f_cnt_t note_frames = + cur_note->length().frames( + frames_per_tact ); + +/* // generate according MIDI-events + processOutEvent( midiEvent( NOTE_ON, + m_midiPort->outputChannel(), + cur_note->key(), + cur_note->getVolume() * + 128 / 100 ), + midiTime::fromFrames( + frames_ahead, + frames_per_tact ) ); + + processOutEvent( midiEvent( NOTE_OFF, + m_midiPort->outputChannel(), + cur_note->key(), 0 ), + midiTime::fromFrames( + frames_ahead + + note_frames, + frames_per_tact ) );*/ + + notePlayHandle * note_play_handle = + new notePlayHandle( this, + frames_ahead, + note_frames, + *cur_note ); + note_play_handle->play(); + // could we play all within current number of + // frames per audio-buffer? + if( note_play_handle->done() == FALSE ) + { + // no, then insert it into + // play-handle-vector of mixer + eng()->getMixer()->addPlayHandle( + note_play_handle ); + } + else + { + // otherwise just throw it away... + delete note_play_handle; + } + played_a_note = TRUE; + } + ++it; + } + } + return( played_a_note ); +} + + + + +trackContentObject * instrumentTrack::createTCO( const midiTime & ) +{ + return( new pattern( this ) ); +} + + + + +void instrumentTrack::saveTrackSpecificSettings( QDomDocument & _doc, + QDomElement & _this ) +{ + _this.setAttribute( "name", name() ); + _this.setAttribute( "vol", getVolume() ); + + // make all coordinates positive + unsigned int x = surroundAreaPos().x() + 2 * SURROUND_AREA_SIZE; + unsigned int y = surroundAreaPos().y() + 2 * SURROUND_AREA_SIZE; + _this.setAttribute( "surpos", static_cast( x & 0xFFFF ) + + ( y * 256 * 256 ) ); + + _this.setAttribute( "fxch", m_effectChannelNumber->value() ); + _this.setAttribute( "basetone", m_baseTone ); + _this.setAttribute( "baseoct", m_baseOctave ); + _this.setAttribute( "tab", m_tabWidget->activeTab() ); + + mainWindow::saveWidgetState( this, _this ); + + if( m_instrument != NULL ) + { + m_instrument->saveState( _doc, _this ); + } + m_envWidget->saveState( _doc, _this ); + m_arpWidget->saveState( _doc, _this ); + m_midiWidget->saveState( _doc, _this ); +} + + + + +void instrumentTrack::loadTrackSpecificSettings( const QDomElement & _this ) +{ + invalidateAllMyNPH(); + + setName( _this.attribute( "name" ) ); + setVolume( _this.attribute( "vol" ).toInt() ); + + int i = _this.attribute( "surpos" ).toInt(); + setSurroundAreaPos( QPoint( ( i & 0xFFFF ) - 2 * SURROUND_AREA_SIZE, + ( i / ( 256 * 256 ) ) - 2 * SURROUND_AREA_SIZE) ); + + m_effectChannelNumber->setInitValue( + _this.attribute( "fxch" ).toInt() ); + m_baseTone = static_cast( _this.attribute( + "basetone" ).toInt() ); + m_baseOctave = static_cast( _this.attribute( + "baseoct" ).toInt() ); + + int tab = _this.attribute( "tab" ).toInt(); + + QDomNode node = _this.firstChild(); + while( !node.isNull() ) + { + if( node.isElement() ) + { + if( m_envWidget->nodeName() == node.nodeName() ) + { + m_envWidget->restoreState( node.toElement() ); + } + else if( m_arpWidget->nodeName() == node.nodeName() ) + { + m_arpWidget->restoreState( node.toElement() ); + } + else if( m_midiWidget->nodeName() == node.nodeName() ) + { + m_midiWidget->restoreState( node.toElement() ); + } + else + { + // if node-name doesn't match any known one, + // we assume that it is an instrument-plugin + // which we'll try to load + delete m_instrument; + m_instrument = instrument::instantiate( + node.nodeName(), this ); + if( m_instrument->nodeName() == + node.nodeName() ) + { + m_instrument->restoreState( + node.toElement() ); + } + m_tabWidget->addTab( m_instrument, + tr( "PLUGIN" ), 0 ); + } + } + node = node.nextSibling(); + } + + m_tabWidget->setActiveTab( tab ); + + m_pianoWidget->update(); + + mainWindow::restoreWidgetState( this, _this ); + if( isVisible() == TRUE ) + { + m_tswInstrumentTrackButton->setChecked( TRUE ); + } +} + + + + +instrument * instrumentTrack::loadInstrument( const QString & _plugin_name ) +{ + invalidateAllMyNPH(); + + delete m_instrument; + m_instrument = instrument::instantiate( _plugin_name, this ); + + m_tabWidget->addTab( m_instrument, tr( "PLUGIN" ), 0 ); + m_tabWidget->setActiveTab( 0 ); + + m_tswInstrumentTrackButton->update(); + + return( m_instrument ); +} + + + + +/*void instrumentTrack::volValueChanged( float _new_value ) +{ + setVolume( (volume) _new_value ); +}*/ + + + + +void instrumentTrack::surroundAreaPosChanged( const QPoint & _p ) +{ + setSurroundAreaPos( _p ); + eng()->getSongEditor()->setModified(); +} + + + + +void instrumentTrack::textChanged( const QString & _new_name ) +{ + setName( _new_name ); + eng()->getSongEditor()->setModified(); +} + + + + +void instrumentTrack::toggledInstrumentTrackButton( bool _on ) +{ + if( m_tswInstrumentTrackButton->isChecked() != _on ) + { + m_tswInstrumentTrackButton->setChecked( _on ); + } + if( _on ) + { + show(); + raise(); + } + else + { + hide(); + } +} + + + + +void instrumentTrack::closeEvent( QCloseEvent * _ce ) +{ + _ce->ignore(); + hide(); + m_tswInstrumentTrackButton->setChecked( FALSE ); +} + + + + +void instrumentTrack::focusInEvent( QFocusEvent * ) +{ + m_pianoWidget->setFocus(); +} + + + + +void instrumentTrack::dragEnterEvent( QDragEnterEvent * _dee ) +{ + stringPairDrag::processDragEnterEvent( _dee, "instrument,presetfile" ); +} + + + + +void instrumentTrack::dropEvent( QDropEvent * _de ) +{ + QString type = stringPairDrag::decodeKey( _de ); + QString value = stringPairDrag::decodeValue( _de ); + if( type == "instrument" ) + { + loadInstrument( value ); + eng()->getSongEditor()->setModified(); + _de->accept(); + } + else if( type == "presetfile" ) + { + multimediaProject mmp( value ); + loadTrackSpecificSettings( mmp.content().firstChild(). + toElement() ); + eng()->getSongEditor()->setModified(); + _de->accept(); + } +} + + + + +void instrumentTrack::invalidateAllMyNPH( void ) +{ + // note-play-handles check track-type to determine whether their + // channel-track is being deleted (if this is the case, they + // invalidate themselves) + m_trackType = NULL_TRACK; + + m_notesMutex.lock(); + for( int i = 0; i < NOTES_PER_OCTAVE * OCTAVES; ++i ) + { + m_notes[i] = NULL; + } + m_notesMutex.unlock(); + + // invalidate all note-play-handles linked to this channel + eng()->getMixer()->checkValidityOfPlayHandles(); + + m_trackType = CHANNEL_TRACK; +} + + + + + + + + + +instrumentTrackButton::instrumentTrackButton( instrumentTrack * + _instrument_track ) : + QPushButton( _instrument_track->getTrackSettingsWidget() ), + m_instrumentTrack( _instrument_track ) +{ + setAcceptDrops( TRUE ); +} + + + + +instrumentTrackButton::~instrumentTrackButton() +{ +} + + + + +void instrumentTrackButton::drawButtonLabel( QPainter * _p ) +{ + QString in = m_instrumentTrack->instrumentName() + ":"; + int extra = isChecked() ? -1 : -3; + _p->setFont( pointSize<7>( _p->font() ) ); +#ifdef QT4 + _p->setPen( QApplication::palette().buttonText().color() ); +#else + _p->setPen( QApplication::palette().color( QPalette::Normal, + QColorGroup::ButtonText ) ); +#endif + _p->drawText( ( width() - QFontMetrics( _p->font() ).width( in ) ) / 2 + + extra, height() / 2 + extra, in ); + _p->setPen( QColor( 0, 0, 0 ) ); + _p->drawText( ( width() - QFontMetrics( _p->font() ).width( text() ) ) / + 2 + extra, height() / 2 + + QFontMetrics( _p->font() ).height() + extra, + text() ); +} + + + + +void instrumentTrackButton::dragEnterEvent( QDragEnterEvent * _dee ) +{ + m_instrumentTrack->dragEnterEvent( _dee ); +} + + + + +void instrumentTrackButton::dropEvent( QDropEvent * _de ) +{ + m_instrumentTrack->dropEvent( _de ); + setChecked( TRUE ); +} + + + +#include "instrument_track.moc" + + +#endif diff --git a/src/tracks/pattern.cpp b/src/tracks/pattern.cpp index 4a0736611..1c47c6870 100644 --- a/src/tracks/pattern.cpp +++ b/src/tracks/pattern.cpp @@ -56,7 +56,7 @@ #include "pattern.h" -#include "channel_track.h" +#include "instrument_track.h" #include "templates.h" #include "gui_templates.h" #include "embed.h" @@ -81,13 +81,13 @@ QPixmap * pattern::s_frozen = NULL; -pattern::pattern ( channelTrack * _channel_track ) : - trackContentObject( _channel_track ), +pattern::pattern ( instrumentTrack * _instrument_track ) : + trackContentObject( _instrument_track ), m_paintPixmap(), m_needsUpdate( TRUE ), - m_channelTrack( _channel_track ), + m_instrumentTrack( _instrument_track ), m_patternType( BEAT_PATTERN ), - m_name( _channel_track->name() ), + m_name( _instrument_track->name() ), m_steps( DEFAULT_STEPS_PER_TACT ), m_frozenPatternMutex(), m_frozenPattern( NULL ), @@ -101,10 +101,10 @@ pattern::pattern ( channelTrack * _channel_track ) : pattern::pattern( const pattern & _pat_to_copy ) : - trackContentObject( _pat_to_copy.m_channelTrack ), + trackContentObject( _pat_to_copy.m_instrumentTrack ), m_paintPixmap(), m_needsUpdate( TRUE ), - m_channelTrack( _pat_to_copy.m_channelTrack ), + m_instrumentTrack( _pat_to_copy.m_instrumentTrack ), m_patternType( _pat_to_copy.m_patternType ), m_name( "" ), m_steps( _pat_to_copy.m_steps ), @@ -186,12 +186,12 @@ void pattern::init( void ) s_frozen = new QPixmap( embed::getIconPixmap( "frozen" ) ); } - saveStepRecordingState( FALSE ); + saveJournallingState( FALSE ); ensureBeatNotes(); changeLength( length() ); - restoreStepRecordingState(); + restoreJournallingState(); #ifndef QT4 // set background-mode for flicker-free redraw @@ -411,27 +411,25 @@ void pattern::playFrozenData( sampleFrame * _ab, const f_cnt_t _start_frame, -void pattern::saveSettings( QDomDocument & _doc, QDomElement & _parent ) +void pattern::saveSettings( QDomDocument & _doc, QDomElement & _this ) { - QDomElement pattern_de = _doc.createElement( nodeName() ); - pattern_de.setAttribute( "type", m_patternType ); - pattern_de.setAttribute( "name", m_name ); + _this.setAttribute( "type", m_patternType ); + _this.setAttribute( "name", m_name ); // as the target of copied/dragged pattern is always an existing // pattern, we must not store actual position, instead we store -1 // which tells loadSettings() not to mess around with position - if( _parent.nodeName() == "clipboard" || - _parent.nodeName() == "dnddata" ) + if( _this.parentNode().nodeName() == "clipboard" || + _this.parentNode().nodeName() == "dnddata" ) { - pattern_de.setAttribute( "pos", -1 ); + _this.setAttribute( "pos", -1 ); } else { - pattern_de.setAttribute( "pos", startPosition() ); + _this.setAttribute( "pos", startPosition() ); } - pattern_de.setAttribute( "len", length() ); - pattern_de.setAttribute( "steps", m_steps ); - pattern_de.setAttribute( "frozen", m_frozenPattern != NULL ); - _parent.appendChild( pattern_de ); + _this.setAttribute( "len", length() ); + _this.setAttribute( "steps", m_steps ); + _this.setAttribute( "frozen", m_frozenPattern != NULL ); // now save settings of all notes for( noteVector::iterator it = m_notes.begin(); @@ -439,7 +437,7 @@ void pattern::saveSettings( QDomDocument & _doc, QDomElement & _parent ) { if( ( *it )->length() ) { - ( *it )->saveSettings( _doc, pattern_de ); + ( *it )->saveState( _doc, _this ); } } } @@ -465,10 +463,11 @@ void pattern::loadSettings( const QDomElement & _this ) QDomNode node = _this.firstChild(); while( !node.isNull() ) { - if( node.isElement() ) + if( node.isElement() && + !node.toElement().attribute( "metadata" ).toInt() ) { - note * n = new note(); - n->loadSettings( node.toElement() ); + note * n = new note( eng() ); + n->restoreState( node.toElement() ); m_notes.push_back( n ); } node = node.nextSibling(); @@ -530,7 +529,7 @@ void pattern::clear( void ) void pattern::resetName( void ) { - m_name = m_channelTrack->name(); + m_name = m_instrumentTrack->name(); } @@ -558,7 +557,7 @@ void pattern::freeze( void ) QMessageBox::Ok ); return; } - if( m_channelTrack->muted() ) + if( m_instrumentTrack->muted() ) { if( QMessageBox:: #if QT_VERSION >= 0x030200 @@ -1143,7 +1142,7 @@ void pattern::ensureBeatNotes( void ) } if( found == FALSE ) { - addNote( note( midiTime( 0 ), midiTime( i * + addNote( note( eng(), midiTime( 0 ), midiTime( i * BEATS_PER_TACT ) ) ); } } diff --git a/src/tracks/sample_track.cpp b/src/tracks/sample_track.cpp index baf155aaf..21b1402e3 100644 --- a/src/tracks/sample_track.cpp +++ b/src/tracks/sample_track.cpp @@ -64,9 +64,9 @@ sampleTCO::sampleTCO( track * _track ) : setBackgroundMode( Qt::NoBackground ); #endif - saveStepRecordingState( FALSE ); + saveJournallingState( FALSE ); setSampleFile( "" ); - restoreStepRecordingState(); + restoreJournallingState(); // we need to receive bpm-change-events, because then we have to // change length of this TCO @@ -253,26 +253,24 @@ midiTime sampleTCO::getSampleLength( void ) const void FASTCALL sampleTCO::saveSettings( QDomDocument & _doc, - QDomElement & _parent ) + QDomElement & _this ) { - QDomElement sampletco_de = _doc.createElement( nodeName() ); - if( _parent.nodeName() == "clipboard" ) + if( _this.parentNode().nodeName() == "clipboard" ) { - sampletco_de.setAttribute( "pos", -1 ); + _this.setAttribute( "pos", -1 ); } else { - sampletco_de.setAttribute( "pos", startPosition() ); + _this.setAttribute( "pos", startPosition() ); } - sampletco_de.setAttribute( "len", length() ); - sampletco_de.setAttribute( "src", sampleFile() ); + _this.setAttribute( "len", length() ); + _this.setAttribute( "src", sampleFile() ); if( sampleFile() == "" ) { QString s; - sampletco_de.setAttribute( "data", m_sampleBuffer.toBase64( s ) ); + _this.setAttribute( "data", m_sampleBuffer.toBase64( s ) ); } // TODO: start- and end-frame - _parent.appendChild( sampletco_de ); } @@ -454,12 +452,10 @@ trackContentObject * sampleTrack::createTCO( const midiTime & ) void sampleTrack::saveTrackSpecificSettings( QDomDocument & _doc, - QDomElement & _parent ) + QDomElement & _this ) { - QDomElement st_de = _doc.createElement( nodeName() ); - st_de.setAttribute( "name", m_trackLabel->text() ); - st_de.setAttribute( "icon", m_trackLabel->pixmapFile() ); - _parent.appendChild( st_de ); + _this.setAttribute( "name", m_trackLabel->text() ); + _this.setAttribute( "icon", m_trackLabel->pixmapFile() ); } diff --git a/src/widgets/automatable_button.cpp b/src/widgets/automatable_button.cpp index 9585771ae..aaa2c6b9c 100644 --- a/src/widgets/automatable_button.cpp +++ b/src/widgets/automatable_button.cpp @@ -33,7 +33,7 @@ automatableButton::automatableButton( QWidget * _parent, engine * _engine ) : QWidget( _parent ), autoObj( _engine, FALSE, TRUE, FALSE ), m_group( NULL ), - m_toggleButton( FALSE ) + m_checkable( FALSE ) { } @@ -55,7 +55,7 @@ void automatableButton::mousePressEvent( QMouseEvent * _me ) { if( _me->button() == Qt::LeftButton ) { - if( m_toggleButton == FALSE ) + if( m_checkable == FALSE ) { setChecked( TRUE ); } @@ -76,7 +76,7 @@ void automatableButton::mousePressEvent( QMouseEvent * _me ) void automatableButton::mouseReleaseEvent( QMouseEvent * _me ) { - if( m_toggleButton == FALSE ) + if( m_checkable == FALSE ) { setChecked( FALSE ); } @@ -88,7 +88,7 @@ void automatableButton::mouseReleaseEvent( QMouseEvent * _me ) void automatableButton::toggle( void ) { - if( m_toggleButton == TRUE && m_group != NULL ) + if( m_checkable == TRUE && m_group != NULL ) { if( value() == FALSE ) { @@ -147,11 +147,11 @@ automatableButtonGroup::~automatableButtonGroup() void automatableButtonGroup::addButton( automatableButton * _btn ) { _btn->m_group = this; - _btn->setToggleButton( TRUE ); + _btn->setCheckable( TRUE ); _btn->setChecked( FALSE ); // disable step-recording as we're recording changes of states of // button-group members on our own - _btn->setStepRecording( FALSE ); + _btn->setJournalling( FALSE ); m_buttons.push_back( _btn ); setRange( 0, m_buttons.size() - 1 ); diff --git a/src/widgets/group_box.cpp b/src/widgets/group_box.cpp index bd05f1162..94e92513a 100644 --- a/src/widgets/group_box.cpp +++ b/src/widgets/group_box.cpp @@ -74,7 +74,7 @@ groupBox::groupBox( const QString & _caption, QWidget * _parent, updatePixmap(); m_led = new pixmapButton( this, eng() ); - m_led->setToggleButton( TRUE ); + m_led->setCheckable( TRUE ); m_led->move( 2, 3 ); m_led->setActiveGraphic( embed::getIconPixmap( "led_green" ) ); m_led->setInactiveGraphic( embed::getIconPixmap( "led_off" ) ); diff --git a/src/widgets/kmultitabbar.cpp b/src/widgets/kmultitabbar.cpp index 1e585844a..0757a7431 100644 --- a/src/widgets/kmultitabbar.cpp +++ b/src/widgets/kmultitabbar.cpp @@ -5,7 +5,7 @@ #include "qt3support.h" -#ifdef QT4 +#ifndef QT3 #include "kmultitabbar.h" @@ -1220,7 +1220,7 @@ KMultiTabBarTab::KMultiTabBarTab(const QPixmap& pic, const QString& text, d=new KMultiTabBarTabPrivate(); setIcon(pic); m_expandedSize=24; - setCheckable(true); + setToggleButton(true); } KMultiTabBarTab::~KMultiTabBarTab() { diff --git a/src/widgets/knob.cpp b/src/widgets/knob.cpp index 433ddb0d2..68112c4d7 100644 --- a/src/widgets/knob.cpp +++ b/src/widgets/knob.cpp @@ -411,7 +411,7 @@ void knob::mousePressEvent( QMouseEvent * _me ) if( _me->button() == Qt::LeftButton && eng()->getMainWindow()->isCtrlPressed() == FALSE ) { - setStepRecording( FALSE ); + setJournalling( FALSE ); m_oldValue = value(); const QPoint & p = _me->pos(); @@ -478,8 +478,8 @@ void knob::mouseMoveEvent( QMouseEvent * _me ) //! Mouse Release Event handler void knob::mouseReleaseEvent( QMouseEvent * /* _me*/ ) { - setStepRecording( TRUE ); - addStepFromOldToCurVal(); + setJournalling( TRUE ); + addJournalEntryFromOldToCurVal(); if( m_buttonPressed ) { diff --git a/src/widgets/lcd_spinbox.cpp b/src/widgets/lcd_spinbox.cpp index 06835b4d8..ab8c3ee6e 100644 --- a/src/widgets/lcd_spinbox.cpp +++ b/src/widgets/lcd_spinbox.cpp @@ -170,10 +170,10 @@ void lcdSpinBox::mouseMoveEvent( QMouseEvent * _me ) int dy = _me->globalY() - m_origMousePos.y(); if( dy > 1 || dy < -1 ) { - setStepRecording( FALSE );// why is this neccessary?! + setJournalling( FALSE );// why is this neccessary?! setInitValue( value() - dy / 2 * step() ); emit valueChanged( value() ); - setStepRecording( TRUE ); + setJournalling( TRUE ); QCursor::setPos( m_origMousePos ); } } @@ -184,7 +184,7 @@ void lcdSpinBox::mouseMoveEvent( QMouseEvent * _me ) void lcdSpinBox::mouseReleaseEvent( QMouseEvent * _me ) { - addStepFromOldToCurVal(); + addJournalEntryFromOldToCurVal(); QCursor::setPos( m_origMousePos ); QApplication::restoreOverrideCursor(); diff --git a/src/widgets/led_checkbox.cpp b/src/widgets/led_checkbox.cpp index 4400ba4e6..11fe9d34e 100644 --- a/src/widgets/led_checkbox.cpp +++ b/src/widgets/led_checkbox.cpp @@ -59,7 +59,7 @@ ledCheckBox::ledCheckBox( const QString & _text, QWidget * _parent, automatableButton( _parent, _engine ), m_text( _text ) { - setToggleButton( TRUE ); + setCheckable( TRUE ); if( _color >= TOTAL_COLORS || _color < YELLOW ) { diff --git a/src/widgets/project_notes.cpp b/src/widgets/project_notes.cpp index c7bc24e7c..3bf8aa6d7 100644 --- a/src/widgets/project_notes.cpp +++ b/src/widgets/project_notes.cpp @@ -79,7 +79,7 @@ projectNotes::projectNotes( engine * _engine) : , 0, Qt::WStyle_Title #endif ), - engineObject( _engine ) + journallingObject( _engine ) { #ifdef QT4 eng()->getMainWindow()->workspace()->addWindow( this ); @@ -570,15 +570,12 @@ void projectNotes::alignmentChanged( int _a ) -void projectNotes::saveSettings( QDomDocument & _doc, QDomElement & _parent ) +void projectNotes::saveSettings( QDomDocument & _doc, QDomElement & _this ) { - QDomElement pn_de = _doc.createElement( nodeName() ); - mainWindow::saveWidgetState( this, pn_de ); + mainWindow::saveWidgetState( this, _this ); QDomCDATASection ds = _doc.createCDATASection( m_edit->toHtml() ); - pn_de.appendChild( ds ); - - _parent.appendChild( pn_de ); + _this.appendChild( ds ); }