/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
/*
Rosegarden
A MIDI and audio sequencer and musical notation editor .
This program is Copyright 2000 - 2008
Guillaume Laurent < glaurent @ telegraph - road . org > ,
Chris Cannam < cannam @ all - day - breakfast . com > ,
Richard Bown < richard . bown @ ferventsoftware . com >
The moral rights of Guillaume Laurent , Chris Cannam , and Richard
Bown to claim authorship of this work have been asserted .
Other copyrights also apply to some parts of this work . Please
see the AUTHORS file and individual file headers for details .
This program is free software ; you can redistribute it and / or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation ; either version 2 of the
License , or ( at your option ) any later version . See the file
COPYING included with this distribution for more information .
*/
# include "RoseXmlHandler.h"
# include "sound/Midi.h"
# include <klocale.h>
# include "misc/Debug.h"
# include "misc/Strings.h"
# include "base/AudioLevel.h"
# include "base/AudioPluginInstance.h"
# include "base/BaseProperties.h"
# include "base/Colour.h"
# include "base/ColourMap.h"
# include "base/Composition.h"
# include "base/ControlParameter.h"
# include "base/Device.h"
# include "base/Instrument.h"
# include "base/Marker.h"
# include "base/MidiDevice.h"
# include "base/MidiProgram.h"
# include "base/MidiTypes.h"
# include "base/NotationTypes.h"
# include "base/RealTime.h"
# include "base/Segment.h"
# include "base/Studio.h"
# include "base/Track.h"
# include "base/TriggerSegment.h"
# include "gui/application/RosegardenGUIApp.h"
# include "gui/application/RosegardenApplication.h"
# include "gui/dialogs/FileLocateDialog.h"
# include "gui/general/ProgressReporter.h"
# include "gui/kdeext/KStartupLogo.h"
# include "gui/studio/AudioPlugin.h"
# include "gui/studio/AudioPluginManager.h"
# include "gui/widgets/CurrentProgressDialog.h"
# include "gui/widgets/ProgressDialog.h"
# include "RosegardenGUIDoc.h"
# include "sound/AudioFileManager.h"
# include <kfiledialog.h>
# include <kmessagebox.h>
# include <tqcstring.h>
# include <tqdatastream.h>
# include <tqdialog.h>
# include <tqfileinfo.h>
# include <tqstring.h>
# include <tqstringlist.h>
# include "XmlStorableEvent.h"
# include "XmlSubHandler.h"
namespace Rosegarden
{
using namespace BaseProperties ;
class ConfigurationXmlSubHandler : public XmlSubHandler
{
public :
ConfigurationXmlSubHandler ( const TQString & elementName ,
Rosegarden : : Configuration * configuration ) ;
virtual bool startElement ( const TQString & namespaceURI ,
const TQString & localName ,
const TQString & qName ,
const TQXmlAttributes & atts ) ;
virtual bool endElement ( const TQString & namespaceURI ,
const TQString & localName ,
const TQString & qName ,
bool & finished ) ;
virtual bool characters ( const TQString & ch ) ;
//--------------- Data members ---------------------------------
Rosegarden : : Configuration * m_configuration ;
TQString m_elementName ;
TQString m_propertyName ;
TQString m_propertyType ;
} ;
ConfigurationXmlSubHandler : : ConfigurationXmlSubHandler ( const TQString & elementName ,
Rosegarden : : Configuration * configuration )
: m_configuration ( configuration ) ,
m_elementName ( elementName )
{
}
bool ConfigurationXmlSubHandler : : startElement ( const TQString & , const TQString & ,
const TQString & lcName ,
const TQXmlAttributes & atts )
{
m_propertyName = lcName ;
m_propertyType = atts . value ( " type " ) ;
if ( m_propertyName = = " property " ) {
// handle alternative encoding for properties with arbitrary names
m_propertyName = atts . value ( " name " ) ;
TQString value = atts . value ( " value " ) ;
if ( value ) {
m_propertyType = " String " ;
m_configuration - > set < String > ( qstrtostr ( m_propertyName ) ,
qstrtostr ( value ) ) ;
}
}
return true ;
}
bool ConfigurationXmlSubHandler : : characters ( const TQString & chars )
{
TQString ch = chars . stripWhiteSpace ( ) ;
// this method is also called on newlines - skip these cases
if ( ch . isEmpty ( ) ) return true ;
if ( m_propertyType = = " Int " ) {
long i = ch . toInt ( ) ;
RG_DEBUG < < " \" " < < m_propertyName < < " \" "
< < " value = " < < i < < endl ;
m_configuration - > set < Int > ( qstrtostr ( m_propertyName ) , i ) ;
return true ;
}
if ( m_propertyType = = " RealTime " ) {
Rosegarden : : RealTime rt ;
int sepIdx = ch . tqfind ( ' , ' ) ;
rt . sec = ch . left ( sepIdx ) . toInt ( ) ;
rt . nsec = ch . mid ( sepIdx + 1 ) . toInt ( ) ;
RG_DEBUG < < " \" " < < m_propertyName < < " \" "
< < " sec = " < < rt . sec < < " , nsec = " < < rt . nsec < < endl ;
m_configuration - > set < Rosegarden : : RealTimeT > ( qstrtostr ( m_propertyName ) , rt ) ;
return true ;
}
if ( m_propertyType = = " Bool " ) {
TQString chLc = ch . lower ( ) ;
bool b = ( chLc = = " true " | |
chLc = = " 1 " | |
chLc = = " on " ) ;
m_configuration - > set < Rosegarden : : Bool > ( qstrtostr ( m_propertyName ) , b ) ;
return true ;
}
if ( ! m_propertyType | |
m_propertyType = = " String " ) {
m_configuration - > set < Rosegarden : : String > ( qstrtostr ( m_propertyName ) ,
qstrtostr ( ch ) ) ;
return true ;
}
return true ;
}
bool
ConfigurationXmlSubHandler : : endElement ( const TQString & ,
const TQString & ,
const TQString & lcName ,
bool & finished )
{
m_propertyName = " " ;
m_propertyType = " " ;
finished = ( lcName = = m_elementName ) ;
return true ;
}
//----------------------------------------
RoseXmlHandler : : RoseXmlHandler ( RosegardenGUIDoc * doc ,
unsigned int elementCount ,
bool createNewDevicesWhenNeeded )
: ProgressReporter ( 0 ) ,
m_doc ( doc ) ,
m_currentSegment ( 0 ) ,
m_currentEvent ( 0 ) ,
m_currentTime ( 0 ) ,
m_chordDuration ( 0 ) ,
m_segmentEndMarkerTime ( 0 ) ,
m_inChord ( false ) ,
m_inGroup ( false ) ,
m_inComposition ( false ) ,
m_groupId ( 0 ) ,
m_foundTempo ( false ) ,
m_section ( NoSection ) ,
m_device ( 0 ) ,
m_deviceRunningId ( Device : : NO_DEVICE ) ,
m_msb ( 0 ) ,
m_lsb ( 0 ) ,
m_instrument ( 0 ) ,
m_plugin ( 0 ) ,
m_pluginInBuss ( false ) ,
m_colourMap ( 0 ) ,
m_keyMapping ( 0 ) ,
m_pluginId ( 0 ) ,
m_totalElements ( elementCount ) ,
m_elementsSoFar ( 0 ) ,
m_subHandler ( 0 ) ,
m_deprecation ( false ) ,
m_createDevices ( createNewDevicesWhenNeeded ) ,
m_haveControls ( false ) ,
m_cancelled ( false ) ,
m_skipAllAudio ( false ) ,
m_hasActiveAudio ( false )
{ }
RoseXmlHandler : : ~ RoseXmlHandler ( )
{
delete m_subHandler ;
}
Composition &
RoseXmlHandler : : getComposition ( )
{
return m_doc - > getComposition ( ) ;
}
Studio &
RoseXmlHandler : : getStudio ( )
{
return m_doc - > getStudio ( ) ;
}
AudioFileManager &
RoseXmlHandler : : getAudioFileManager ( )
{
return m_doc - > getAudioFileManager ( ) ;
}
AudioPluginManager *
RoseXmlHandler : : getAudioPluginManager ( )
{
return m_doc - > getPluginManager ( ) ;
}
bool
RoseXmlHandler : : startDocument ( )
{
// Clear tracks
//
getComposition ( ) . clearTracks ( ) ;
// And the loop
//
getComposition ( ) . setLoopStart ( 0 ) ;
getComposition ( ) . setLoopEnd ( 0 ) ;
// All plugins
//
m_doc - > clearAllPlugins ( ) ;
// reset state
return true ;
}
bool
RoseXmlHandler : : startElement ( const TQString & namespaceURI ,
const TQString & localName ,
const TQString & qName , const TQXmlAttributes & atts )
{
// First check if user pressed cancel button on the progress
// dialog
//
if ( isOperationCancelled ( ) ) {
// Ideally, we'd throw here, but at this point TQt is in the stack
// and TQt is very often compiled without exception support.
//
m_cancelled = true ;
return false ;
}
TQString lcName = qName . lower ( ) ;
if ( getSubHandler ( ) ) {
return getSubHandler ( ) - > startElement ( namespaceURI , localName , lcName , atts ) ;
}
if ( lcName = = " event " ) {
// RG_DEBUG << "RoseXmlHandler::startElement: found event, current time is " << m_currentTime << endl;
if ( m_currentEvent ) {
RG_DEBUG < < " RoseXmlHandler::startElement: Warning: new event found at time " < < m_currentTime < < " before previous event has ended; previous event will be lost " < < endl ;
delete m_currentEvent ;
}
m_currentEvent = new XmlStorableEvent ( atts , m_currentTime ) ;
if ( m_currentEvent - > has ( BEAMED_GROUP_ID ) ) {
// remap -- we want to ensure that the segment's nextId
// is always used (and incremented) in preference to the
// stored id
if ( ! m_currentSegment ) {
m_errorString = " Got grouped event outside of a segment " ;
return false ;
}
long storedId = m_currentEvent - > get
< Int > ( BEAMED_GROUP_ID ) ;
if ( m_groupIdMap . find ( storedId ) = = m_groupIdMap . end ( ) ) {
m_groupIdMap [ storedId ] = m_currentSegment - > getNextId ( ) ;
}
m_currentEvent - > set
< Int > ( BEAMED_GROUP_ID , m_groupIdMap [ storedId ] ) ;
} else if ( m_inGroup ) {
m_currentEvent - > set
< Int > ( BEAMED_GROUP_ID , m_groupId ) ;
m_currentEvent - > set
< String > ( BEAMED_GROUP_TYPE , m_groupType ) ;
if ( m_groupType = = GROUP_TYPE_TUPLED ) {
m_currentEvent - > set
< Int >
( BEAMED_GROUP_TUPLET_BASE , m_groupTupletBase ) ;
m_currentEvent - > set
< Int >
( BEAMED_GROUP_TUPLED_COUNT , m_groupTupledCount ) ;
m_currentEvent - > set
< Int >
( BEAMED_GROUP_UNTUPLED_COUNT , m_groupUntupledCount ) ;
}
}
timeT duration = m_currentEvent - > getDuration ( ) ;
if ( ! m_inChord ) {
m_currentTime = m_currentEvent - > getAbsoluteTime ( ) + duration ;
// RG_DEBUG << "RoseXmlHandler::startElement: (we're not in a chord) " << endl;
} else if ( duration ! = 0 ) {
// set chord duration to the duration of the shortest
// element with a non-null duration (if no such elements,
// leave it as 0).
if ( m_chordDuration = = 0 | | duration < m_chordDuration ) {
m_chordDuration = duration ;
}
}
} else if ( lcName = = " property " ) {
if ( ! m_currentEvent ) {
RG_DEBUG < < " RoseXmlHandler::startElement: Warning: Found property outside of event at time " < < m_currentTime < < " , ignoring " < < endl ;
} else {
m_currentEvent - > setPropertyFromAttributes ( atts , true ) ;
}
} else if ( lcName = = " nproperty " ) {
if ( ! m_currentEvent ) {
RG_DEBUG < < " RoseXmlHandler::startElement: Warning: Found nproperty outside of event at time " < < m_currentTime < < " , ignoring " < < endl ;
} else {
m_currentEvent - > setPropertyFromAttributes ( atts , false ) ;
}
} else if ( lcName = = " chord " ) {
m_inChord = true ;
} else if ( lcName = = " group " ) {
if ( ! m_currentSegment ) {
m_errorString = " Got group outside of a segment " ;
return false ;
}
if ( ! m_deprecation )
std : : cerr < < " WARNING: This Rosegarden file uses the deprecated element \" group \" . We recommend re-saving the file from this version of Rosegarden to assure your ability to re-load it in future versions " < < std : : endl ;
m_deprecation = true ;
m_inGroup = true ;
m_groupId = m_currentSegment - > getNextId ( ) ;
m_groupType = qstrtostr ( atts . value ( " type " ) ) ;
if ( m_groupType = = GROUP_TYPE_TUPLED ) {
m_groupTupletBase = atts . value ( " base " ) . toInt ( ) ;
m_groupTupledCount = atts . value ( " tupled " ) . toInt ( ) ;
m_groupUntupledCount = atts . value ( " untupled " ) . toInt ( ) ;
}
} else if ( lcName = = " rosegarden-data " ) {
// FILE FORMAT VERSIONING -- see comments in
// rosegardenguidoc.cpp. We only care about major and minor
// here, not point.
TQString version = atts . value ( " version " ) ;
TQString smajor = atts . value ( " format-version-major " ) ;
TQString sminor = atts . value ( " format-version-minor " ) ;
// std::cerr << "\n\n\nRosegarden file version = \"" << version << "\"\n\n\n" << std::endl;
if ( smajor ) {
int major = smajor . toInt ( ) ;
int minor = sminor . toInt ( ) ;
if ( major > RosegardenGUIDoc : : FILE_FORMAT_VERSION_MAJOR ) {
m_errorString = i18n ( " This file was written by Rosegarden %1, and it uses \n a different file format that cannot be read by this version. " ) . tqarg ( version ) ;
return false ;
}
if ( major = = RosegardenGUIDoc : : FILE_FORMAT_VERSION_MAJOR & &
minor > RosegardenGUIDoc : : FILE_FORMAT_VERSION_MINOR ) {
CurrentProgressDialog : : freeze ( ) ;
KStartupLogo : : hideIfStillThere ( ) ;
KMessageBox : : information ( 0 , i18n ( " This file was written by Rosegarden %1, which is more recent than this version. \n There may be some incompatibilities with the file format. " ) . tqarg ( version ) ) ;
CurrentProgressDialog : : thaw ( ) ;
}
}
} else if ( lcName = = " studio " ) {
if ( m_section ! = NoSection ) {
m_errorString = " Found Studio in another section " ;
return false ;
}
// In the Studio we clear down everything apart from Devices and
// Instruments before we reload. Instruments are derived from
// the Sequencer, the bank/program information is loaded from
// the file we're currently examining.
//
getStudio ( ) . clearMidiBanksAndPrograms ( ) ;
getStudio ( ) . clearBusses ( ) ;
getStudio ( ) . clearRecordIns ( ) ;
m_section = InStudio ; // set top level section
// Get and set MIDI filters
//
TQString thruStr = atts . value ( " thrufilter " ) ;
if ( thruStr )
getStudio ( ) . setMIDIThruFilter ( thruStr . toInt ( ) ) ;
TQString recordStr = atts . value ( " recordfilter " ) ;
if ( recordStr )
getStudio ( ) . setMIDIRecordFilter ( recordStr . toInt ( ) ) ;
TQString inputStr = atts . value ( " audioinputpairs " ) ;
if ( inputStr ) {
int inputs = inputStr . toInt ( ) ;
if ( inputs < 1 )
inputs = 1 ; // we simply don't permit no inputs
while ( int ( getStudio ( ) . getRecordIns ( ) . size ( ) ) < inputs ) {
getStudio ( ) . addRecordIn ( new RecordIn ( ) ) ;
}
}
TQString mixerStr = atts . value ( " mixerdisplayoptions " ) ;
if ( mixerStr ) {
unsigned int mixer = mixerStr . toUInt ( ) ;
getStudio ( ) . setMixerDisplayOptions ( mixer ) ;
}
TQString metronomeStr = atts . value ( " metronomedevice " ) ;
if ( metronomeStr ) {
DeviceId metronome = metronomeStr . toUInt ( ) ;
getStudio ( ) . setMetronomeDevice ( metronome ) ;
}
} else if ( lcName = = " timesignature " ) {
if ( m_inComposition = = false ) {
m_errorString = " TimeSignature object found outside Composition " ;
return false ;
}
timeT t = 0 ;
TQString timeStr = atts . value ( " time " ) ;
if ( timeStr )
t = timeStr . toInt ( ) ;
int num = 4 ;
TQString numStr = atts . value ( " numerator " ) ;
if ( numStr )
num = numStr . toInt ( ) ;
int denom = 4 ;
TQString denomStr = atts . value ( " denominator " ) ;
if ( denomStr )
denom = denomStr . toInt ( ) ;
bool common = false ;
TQString commonStr = atts . value ( " common " ) ;
if ( commonStr )
common = ( commonStr = = " true " ) ;
bool hidden = false ;
TQString hiddenStr = atts . value ( " hidden " ) ;
if ( hiddenStr )
hidden = ( hiddenStr = = " true " ) ;
bool hiddenBars = false ;
TQString hiddenBarsStr = atts . value ( " hiddenbars " ) ;
if ( hiddenBarsStr )
hiddenBars = ( hiddenBarsStr = = " true " ) ;
getComposition ( ) . addTimeSignature
( t , TimeSignature ( num , denom , common , hidden , hiddenBars ) ) ;
} else if ( lcName = = " tempo " ) {
timeT t = 0 ;
TQString timeStr = atts . value ( " time " ) ;
if ( timeStr )
t = timeStr . toInt ( ) ;
tempoT tempo = Composition : : getTempoForQpm ( 120.0 ) ;
TQString tempoStr = atts . value ( " tempo " ) ;
TQString targetStr = atts . value ( " target " ) ;
TQString bphStr = atts . value ( " bph " ) ;
if ( tempoStr ) {
tempo = tempoStr . toInt ( ) ;
} else if ( bphStr ) {
tempo = Composition : : getTempoForQpm
( double ( bphStr . toInt ( ) ) / 60.0 ) ;
}
if ( targetStr ) {
getComposition ( ) . addTempoAtTime ( t , tempo , targetStr . toInt ( ) ) ;
} else {
getComposition ( ) . addTempoAtTime ( t , tempo ) ;
}
} else if ( lcName = = " composition " ) {
if ( m_section ! = NoSection ) {
m_errorString = " Found Composition in another section " ;
return false ;
}
// set Segment
m_section = InComposition ;
// Get and set the record track
//
TQString recordStr = atts . value ( " recordtrack " ) ;
if ( recordStr ) {
getComposition ( ) . setTrackRecording ( recordStr . toInt ( ) , true ) ;
}
TQString recordPlStr = atts . value ( " recordtracks " ) ;
if ( recordPlStr ) {
RG_DEBUG < < " Record tracks: " < < recordPlStr < < endl ;
TQStringList recordList = TQStringList : : split ( ' , ' , recordPlStr ) ;
for ( TQStringList : : iterator i = recordList . begin ( ) ;
i ! = recordList . end ( ) ; + + i ) {
RG_DEBUG < < " Record track: " < < ( * i ) . toInt ( ) < < endl ;
getComposition ( ) . setTrackRecording ( ( * i ) . toInt ( ) , true ) ;
}
}
// Get and set the position pointer
//
int position = 0 ;
TQString positionStr = atts . value ( " pointer " ) ;
if ( positionStr ) {
position = positionStr . toInt ( ) ;
}
getComposition ( ) . setPosition ( position ) ;
// Get and (eventually) set the default tempo.
// We prefer the new compositionDefaultTempo over the
// older defaultTempo.
//
TQString tempoStr = atts . value ( " compositionDefaultTempo " ) ;
if ( tempoStr ) {
tempoT tempo = tempoT ( tempoStr . toInt ( ) ) ;
getComposition ( ) . setCompositionDefaultTempo ( tempo ) ;
} else {
tempoStr = atts . value ( " defaultTempo " ) ;
if ( tempoStr ) {
double tempo = qstrtodouble ( tempoStr ) ;
getComposition ( ) . setCompositionDefaultTempo
( Composition : : getTempoForQpm ( tempo ) ) ;
}
}
// set the composition flag
m_inComposition = true ;
// Set the loop
//
TQString loopStartStr = atts . value ( " loopstart " ) ;
TQString loopEndStr = atts . value ( " loopend " ) ;
if ( loopStartStr & & loopEndStr ) {
int loopStart = loopStartStr . toInt ( ) ;
int loopEnd = loopEndStr . toInt ( ) ;
getComposition ( ) . setLoopStart ( loopStart ) ;
getComposition ( ) . setLoopEnd ( loopEnd ) ;
}
TQString selectedTrackStr = atts . value ( " selected " ) ;
if ( selectedTrackStr ) {
TrackId selectedTrack =
( TrackId ) selectedTrackStr . toInt ( ) ;
getComposition ( ) . setSelectedTrack ( selectedTrack ) ;
}
TQString soloTrackStr = atts . value ( " solo " ) ;
if ( soloTrackStr ) {
if ( soloTrackStr . toInt ( ) = = 1 )
getComposition ( ) . setSolo ( true ) ;
else
getComposition ( ) . setSolo ( false ) ;
}
TQString playMetStr = atts . value ( " playmetronome " ) ;
if ( playMetStr ) {
if ( playMetStr . toInt ( ) )
getComposition ( ) . setPlayMetronome ( true ) ;
else
getComposition ( ) . setPlayMetronome ( false ) ;
}
TQString recMetStr = atts . value ( " recordmetronome " ) ;
if ( recMetStr ) {
if ( recMetStr . toInt ( ) )
getComposition ( ) . setRecordMetronome ( true ) ;
else
getComposition ( ) . setRecordMetronome ( false ) ;
}
TQString nextTriggerIdStr = atts . value ( " nexttriggerid " ) ;
if ( nextTriggerIdStr ) {
getComposition ( ) . setNextTriggerSegmentId ( nextTriggerIdStr . toInt ( ) ) ;
}
TQString copyrightStr = atts . value ( " copyright " ) ;
if ( copyrightStr ) {
getComposition ( ) . setCopyrightNote ( qstrtostr ( copyrightStr ) ) ;
}
TQString startMarkerStr = atts . value ( " startMarker " ) ;
TQString endMarkerStr = atts . value ( " endMarker " ) ;
if ( startMarkerStr ) {
getComposition ( ) . setStartMarker ( startMarkerStr . toInt ( ) ) ;
}
if ( endMarkerStr ) {
getComposition ( ) . setEndMarker ( endMarkerStr . toInt ( ) ) ;
}
} else if ( lcName = = " track " ) {
if ( m_section ! = InComposition ) {
m_errorString = " Track object found outside Composition " ;
return false ;
}
int id = - 1 ;
int position = - 1 ;
int instrument = - 1 ;
std : : string label ;
bool muted = false ;
TQString trackNbStr = atts . value ( " id " ) ;
if ( trackNbStr ) {
id = trackNbStr . toInt ( ) ;
}
TQString labelStr = atts . value ( " label " ) ;
if ( labelStr ) {
label = qstrtostr ( labelStr ) ;
}
TQString mutedStr = atts . value ( " muted " ) ;
if ( mutedStr ) {
if ( mutedStr = = " true " )
muted = true ;
else
muted = false ;
}
TQString positionStr = atts . value ( " position " ) ;
if ( positionStr ) {
position = positionStr . toInt ( ) ;
}
TQString instrumentStr = atts . value ( " instrument " ) ;
if ( instrumentStr ) {
instrument = instrumentStr . toInt ( ) ;
}
Track * track = new Track ( id ,
instrument ,
position ,
label ,
muted ) ;
// track properties affecting newly created segments are initialized
// to default values in the ctor, so they don't need to be initialized
// here
TQString presetLabelStr = atts . value ( " defaultLabel " ) ;
if ( labelStr ) {
track - > setPresetLabel ( presetLabelStr . ascii ( ) ) ;
}
TQString clefStr = atts . value ( " defaultClef " ) ;
if ( clefStr ) {
track - > setClef ( clefStr . toInt ( ) ) ;
}
TQString transposeStr = atts . value ( " defaultTranspose " ) ;
if ( transposeStr ) {
track - > setTranspose ( transposeStr . toInt ( ) ) ;
}
TQString colorStr = atts . value ( " defaultColour " ) ;
if ( colorStr ) {
track - > setColor ( colorStr . toInt ( ) ) ;
}
TQString highplayStr = atts . value ( " defaultHighestPlayable " ) ;
if ( highplayStr ) {
track - > setHighestPlayable ( highplayStr . toInt ( ) ) ;
}
TQString lowplayStr = atts . value ( " defaultLowestPlayable " ) ;
if ( lowplayStr ) {
track - > setLowestPlayable ( lowplayStr . toInt ( ) ) ;
}
TQString staffSizeStr = atts . value ( " staffSize " ) ;
if ( staffSizeStr ) {
track - > setStaffSize ( staffSizeStr . toInt ( ) ) ;
}
TQString staffBracketStr = atts . value ( " staffBracket " ) ;
if ( staffBracketStr ) {
track - > setStaffBracket ( staffBracketStr . toInt ( ) ) ;
}
getComposition ( ) . addTrack ( track ) ;
} else if ( lcName = = " segment " ) {
if ( m_section ! = NoSection ) {
m_errorString = " Found Segment in another section " ;
return false ;
}
// set Segment
m_section = InSegment ;
int track = - 1 , startTime = 0 ;
unsigned int colourindex = 0 ;
TQString trackNbStr = atts . value ( " track " ) ;
if ( trackNbStr ) {
track = trackNbStr . toInt ( ) ;
}
TQString startIdxStr = atts . value ( " start " ) ;
if ( startIdxStr ) {
startTime = startIdxStr . toInt ( ) ;
}
TQString segmentType = ( atts . value ( " type " ) ) . lower ( ) ;
if ( segmentType ) {
if ( segmentType = = " audio " ) {
int audioFileId = atts . value ( " file " ) . toInt ( ) ;
// check this file id exists on the AudioFileManager
if ( getAudioFileManager ( ) . fileExists ( audioFileId ) = = false ) {
// We don't report an error as this audio file might've
// been excluded deliberately as we could't actually
// find the audio file itself.
//
return true ;
}
// Create an Audio segment and add its reference
//
m_currentSegment = new Segment ( Segment : : Audio ) ;
m_currentSegment - > setAudioFileId ( audioFileId ) ;
m_currentSegment - > setStartTime ( startTime ) ;
} else {
// Create a (normal) internal Segment
m_currentSegment = new Segment ( Segment : : Internal ) ;
}
} else {
// for the moment we default
m_currentSegment = new Segment ( Segment : : Internal ) ;
}
TQString repeatStr = atts . value ( " repeat " ) ;
if ( repeatStr . lower ( ) = = " true " ) {
m_currentSegment - > setRepeating ( true ) ;
}
TQString delayStr = atts . value ( " delay " ) ;
if ( delayStr ) {
RG_DEBUG < < " Delay string is \" " < < delayStr < < " \" " < < endl ;
long delay = delayStr . toLong ( ) ;
RG_DEBUG < < " Delay is " < < delay < < endl ;
m_currentSegment - > setDelay ( delay ) ;
}
TQString rtDelaynSec = atts . value ( " rtdelaynsec " ) ;
TQString rtDelayuSec = atts . value ( " rtdelayusec " ) ;
TQString rtDelaySec = atts . value ( " rtdelaysec " ) ;
if ( rtDelaySec & & ( rtDelaynSec | | rtDelayuSec ) ) {
if ( rtDelaynSec ) {
m_currentSegment - > setRealTimeDelay
( RealTime ( rtDelaySec . toInt ( ) ,
rtDelaynSec . toInt ( ) ) ) ;
} else {
m_currentSegment - > setRealTimeDelay
( RealTime ( rtDelaySec . toInt ( ) ,
rtDelayuSec . toInt ( ) * 1000 ) ) ;
}
}
TQString transposeStr = atts . value ( " transpose " ) ;
if ( transposeStr )
m_currentSegment - > setTranspose ( transposeStr . toInt ( ) ) ;
// fill in the label
TQString labelStr = atts . value ( " label " ) ;
if ( labelStr )
m_currentSegment - > setLabel ( qstrtostr ( labelStr ) ) ;
m_currentSegment - > setTrack ( track ) ;
//m_currentSegment->setStartTime(startTime);
TQString colourIndStr = atts . value ( " colourindex " ) ;
if ( colourIndStr ) {
colourindex = colourIndStr . toInt ( ) ;
}
m_currentSegment - > setColourIndex ( colourindex ) ;
TQString snapGridSizeStr = atts . value ( " snapgridsize " ) ;
if ( snapGridSizeStr ) {
m_currentSegment - > setSnapGridSize ( snapGridSizeStr . toInt ( ) ) ;
}
TQString viewFeaturesStr = atts . value ( " viewfeatures " ) ;
if ( viewFeaturesStr ) {
m_currentSegment - > setViewFeatures ( viewFeaturesStr . toInt ( ) ) ;
}
m_currentTime = startTime ;
TQString triggerIdStr = atts . value ( " triggerid " ) ;
TQString triggerPitchStr = atts . value ( " triggerbasepitch " ) ;
TQString triggerVelocityStr = atts . value ( " triggerbasevelocity " ) ;
TQString triggerRetuneStr = atts . value ( " triggerretune " ) ;
TQString triggerAdjustTimeStr = atts . value ( " triggeradjusttimes " ) ;
if ( triggerIdStr ) {
int pitch = - 1 ;
if ( triggerPitchStr )
pitch = triggerPitchStr . toInt ( ) ;
int velocity = - 1 ;
if ( triggerVelocityStr )
velocity = triggerVelocityStr . toInt ( ) ;
TriggerSegmentRec * rec =
getComposition ( ) . addTriggerSegment ( m_currentSegment ,
triggerIdStr . toInt ( ) ,
pitch , velocity ) ;
if ( rec ) {
if ( triggerRetuneStr )
rec - > setDefaultRetune ( triggerRetuneStr . lower ( ) = = " true " ) ;
if ( triggerAdjustTimeStr )
rec - > setDefaultTimeAdjust ( qstrtostr ( triggerAdjustTimeStr ) ) ;
}
m_currentSegment - > setStartTimeDataMember ( startTime ) ;
} else {
getComposition ( ) . addSegment ( m_currentSegment ) ;
getComposition ( ) . setSegmentStartTime ( m_currentSegment , startTime ) ;
}
TQString endMarkerStr = atts . value ( " endmarker " ) ;
if ( endMarkerStr ) {
delete m_segmentEndMarkerTime ;
m_segmentEndMarkerTime = new timeT ( endMarkerStr . toInt ( ) ) ;
}
m_groupIdMap . clear ( ) ;
} else if ( lcName = = " gui " ) {
if ( m_section ! = InSegment ) {
m_errorString = " Found GUI element outside Segment " ;
return false ;
}
} else if ( lcName = = " controller " ) {
if ( m_section ! = InSegment ) {
m_errorString = " Found Controller element outside Segment " ;
return false ;
}
TQString type = atts . value ( " type " ) ;
//RG_DEBUG << "RoseXmlHandler::startElement - controller type = " << type << endl;
if ( type = = strtoqstr ( PitchBend : : EventType ) )
m_currentSegment - > addEventRuler ( PitchBend : : EventType ) ;
else if ( type = = strtoqstr ( Controller : : EventType ) ) {
TQString value = atts . value ( " value " ) ;
if ( value ! = " " )
m_currentSegment - > addEventRuler ( Controller : : EventType , value . toInt ( ) ) ;
}
} else if ( lcName = = " resync " ) {
if ( ! m_deprecation )
std : : cerr < < " WARNING: This Rosegarden file uses the deprecated element \" resync \" . We recommend re-saving the file from this version of Rosegarden to assure your ability to re-load it in future versions " < < std : : endl ;
m_deprecation = true ;
TQString time ( atts . value ( " time " ) ) ;
bool isNumeric ;
int numTime = time . toInt ( & isNumeric ) ;
if ( isNumeric )
m_currentTime = numTime ;
} else if ( lcName = = " audio " ) {
if ( m_section ! = InAudioFiles ) {
m_errorString = " Audio object found outside Audio section " ;
return false ;
}
if ( m_skipAllAudio ) {
std : : cout < < " SKIPPING audio file " < < std : : endl ;
return true ;
}
TQString id ( atts . value ( " id " ) ) ;
TQString file ( atts . value ( " file " ) ) ;
TQString label ( atts . value ( " label " ) ) ;
if ( id . isEmpty ( ) | | file . isEmpty ( ) | | label . isEmpty ( ) ) {
m_errorString = " Audio object has empty parameters " ;
return false ;
}
m_hasActiveAudio = true ;
// attempt to insert file into AudioFileManager
// (this checks the integrity of the file at the
// same time)
//
if ( getAudioFileManager ( ) . insertFile ( qstrtostr ( label ) ,
qstrtostr ( file ) ,
id . toInt ( ) ) = = false ) {
// Ok, now attempt to use the KFileDialog saved default
// value for the AudioPath.
//
TQString thing ;
KURL url = KFileDialog : : getStartURL ( TQString ( " :WAVS " ) , thing ) ;
getAudioFileManager ( ) . setAudioPath ( url . path ( ) . latin1 ( ) ) ;
/*
RG_DEBUG < < " ATTEMPTING TO FIND IN PATH = "
< < url . path ( ) < < endl ;
*/
if ( getAudioFileManager ( ) .
insertFile ( qstrtostr ( label ) ,
qstrtostr ( file ) , id . toInt ( ) ) = = false ) {
// Freeze the progress dialog
CurrentProgressDialog : : freeze ( ) ;
// Hide splash screen if present on startup
KStartupLogo : : hideIfStillThere ( ) ;
// Create a locate file dialog - give it the file name
// and the AudioFileManager path that we've already
// tried. If we manually locate the file then we reset
// the audiofilepath to the new value and see if this
// helps us locate the rest of the files.
//
TQString newFilename = " " ;
TQString newPath = " " ;
do {
FileLocateDialog fL ( ( RosegardenGUIApp * ) m_doc - > tqparent ( ) ,
file ,
TQString ( getAudioFileManager ( ) . getAudioPath ( ) . c_str ( ) ) ) ;
int result = fL . exec ( ) ;
if ( result = = TQDialog : : Accepted ) {
newFilename = fL . getFilename ( ) ;
newPath = fL . getDirectory ( ) ;
} else if ( result = = TQDialog : : Rejected ) {
// just skip the file
break ;
} else {
// don't process any more audio files
m_skipAllAudio = true ;
CurrentProgressDialog : : thaw ( ) ;
return true ;
}
} while ( getAudioFileManager ( ) . insertFile ( qstrtostr ( label ) ,
qstrtostr ( newFilename ) ,
id . toInt ( ) ) = = false ) ;
if ( newPath ! = " " ) {
getAudioFileManager ( ) . setAudioPath ( qstrtostr ( newPath ) ) ;
// Set a document post-modify flag
//m_doc->setModified(true);
}
getAudioFileManager ( ) . print ( ) ;
// Restore progress dialog's normal state
CurrentProgressDialog : : thaw ( ) ;
} else {
// AudioPath is modified so set a document post modify flag
//
//m_doc->setModified(true);
}
}
} else if ( lcName = = " audiopath " ) {
if ( m_section ! = InAudioFiles ) {
m_errorString = " Audiopath object found outside AudioFiles section " ;
return false ;
}
TQString search ( atts . value ( " value " ) ) ;
if ( search . isEmpty ( ) ) {
m_errorString = " Audiopath has no value " ;
return false ;
}
if ( ! search . startsWith ( " / " ) & & ! search . startsWith ( " ~ " ) ) {
TQString docPath = m_doc - > getAbsFilePath ( ) ;
TQString dirPath = TQFileInfo ( docPath ) . dirPath ( ) ;
if ( TQFileInfo ( dirPath ) . exists ( ) ) {
search = dirPath + " / " + search ;
}
}
getAudioFileManager ( ) . setAudioPath ( qstrtostr ( search ) ) ;
} else if ( lcName = = " begin " ) {
double marker = qstrtodouble ( atts . value ( " index " ) ) ;
if ( ! m_currentSegment ) {
// Don't fail - as this segment could be defunct if we
// skipped loading the audio file
//
return true ;
}
if ( m_currentSegment - > getType ( ) ! = Segment : : Audio ) {
m_errorString = " Found audio begin index in non audio segment " ;
return false ;
}
// convert to RealTime from float
int sec = ( int ) marker ;
int usec = ( int ) ( ( marker - ( ( double ) sec ) ) * 1000000.0 ) ;
m_currentSegment - > setAudioStartTime ( RealTime ( sec , usec * 1000 ) ) ;
} else if ( lcName = = " end " ) {
double marker = qstrtodouble ( atts . value ( " index " ) ) ;
if ( ! m_currentSegment ) {
// Don't fail - as this segment could be defunct if we
// skipped loading the audio file
//
return true ;
}
if ( m_currentSegment - > getType ( ) ! = Segment : : Audio ) {
m_errorString = " found audio end index in non audio segment " ;
return false ;
}
int sec = ( int ) marker ;
int usec = ( int ) ( ( marker - ( ( double ) sec ) ) * 1000000.0 ) ;
RealTime markerTime ( sec , usec * 1000 ) ;
if ( markerTime < m_currentSegment - > getAudioStartTime ( ) ) {
m_errorString = " Audio end index before audio start marker " ;
return false ;
}
m_currentSegment - > setAudioEndTime ( markerTime ) ;
// Ensure we set end time according to correct RealTime end of Segment
//
RealTime realEndTime = getComposition ( ) .
getElapsedRealTime ( m_currentSegment - > getStartTime ( ) ) +
m_currentSegment - > getAudioEndTime ( ) -
m_currentSegment - > getAudioStartTime ( ) ;
timeT absEnd = getComposition ( ) . getElapsedTimeForRealTime ( realEndTime ) ;
m_currentSegment - > setEndTime ( absEnd ) ;
} else if ( lcName = = " fadein " ) {
if ( ! m_currentSegment ) {
// Don't fail - as this segment could be defunct if we
// skipped loading the audio file
//
return true ;
}
if ( m_currentSegment - > getType ( ) ! = Segment : : Audio ) {
m_errorString = " found fade in time in non audio segment " ;
return false ;
}
double marker = qstrtodouble ( atts . value ( " time " ) ) ;
int sec = ( int ) marker ;
int usec = ( int ) ( ( marker - ( ( double ) sec ) ) * 1000000.0 ) ;
RealTime markerTime ( sec , usec * 1000 ) ;
m_currentSegment - > setFadeInTime ( markerTime ) ;
m_currentSegment - > setAutoFade ( true ) ;
} else if ( lcName = = " fadeout " ) {
if ( ! m_currentSegment ) {
// Don't fail - as this segment could be defunct if we
// skipped loading the audio file
//
return true ;
}
if ( m_currentSegment - > getType ( ) ! = Segment : : Audio ) {
m_errorString = " found fade out time in non audio segment " ;
return false ;
}
double marker = qstrtodouble ( atts . value ( " time " ) ) ;
int sec = ( int ) marker ;
int usec = ( int ) ( ( marker - ( ( double ) sec ) ) * 1000000.0 ) ;
RealTime markerTime ( sec , usec * 1000 ) ;
m_currentSegment - > setFadeOutTime ( markerTime ) ;
m_currentSegment - > setAutoFade ( true ) ;
} else if ( lcName = = " device " ) {
if ( m_section ! = InStudio ) {
m_errorString = " Found Device outside Studio " ;
return false ;
}
m_haveControls = false ;
TQString type = ( atts . value ( " type " ) ) . lower ( ) ;
TQString idString = atts . value ( " id " ) ;
TQString nameStr = atts . value ( " name " ) ;
if ( idString . isNull ( ) ) {
m_errorString = " No ID on Device tag " ;
return false ;
}
int id = idString . toInt ( ) ;
if ( type = = " midi " ) {
TQString direction = atts . value ( " direction " ) . lower ( ) ;
if ( direction . isNull ( ) | |
direction = = " " | |
direction = = " play " ) { // ignore inputs
// This will leave m_device set only if there is a
// valid play midi device to modify:
skipToNextPlayDevice ( ) ;
if ( m_device ) {
if ( nameStr & & nameStr ! = " " ) {
m_device - > setName ( qstrtostr ( nameStr ) ) ;
}
} else if ( nameStr & & nameStr ! = " " ) {
addMIDIDevice ( nameStr , m_createDevices ) ; // also sets m_device
}
}
TQString connection = atts . value ( " connection " ) ;
if ( m_createDevices & & m_device & &
! connection . isNull ( ) & & connection ! = " " ) {
setMIDIDeviceConnection ( connection ) ;
}
setMIDIDeviceName ( nameStr ) ;
TQString vstr = atts . value ( " variation " ) . lower ( ) ;
MidiDevice : : VariationType variation =
MidiDevice : : NoVariations ;
if ( ! vstr . isNull ( ) ) {
if ( vstr = = " lsb " ) {
variation = MidiDevice : : VariationFromLSB ;
} else if ( vstr = = " msb " ) {
variation = MidiDevice : : VariationFromMSB ;
} else if ( vstr = = " " ) {
variation = MidiDevice : : NoVariations ;
}
}
MidiDevice * md = dynamic_cast < MidiDevice * >
( m_device ) ;
if ( md ) {
md - > setVariationType ( variation ) ;
}
} else if ( type = = " softsynth " ) {
m_device = getStudio ( ) . getDevice ( id ) ;
if ( m_device & & m_device - > getType ( ) = = Device : : SoftSynth )
m_device - > setName ( qstrtostr ( nameStr ) ) ;
} else if ( type = = " audio " ) {
m_device = getStudio ( ) . getDevice ( id ) ;
if ( m_device & & m_device - > getType ( ) = = Device : : Audio )
m_device - > setName ( qstrtostr ( nameStr ) ) ;
} else {
m_errorString = " Found unknown Device type " ;
return false ;
}
} else if ( lcName = = " librarian " ) {
// The contact details for the maintainer of the banks/programs
// information.
//
if ( m_device & & m_device - > getType ( ) = = Device : : Midi ) {
TQString name = atts . value ( " name " ) ;
TQString email = atts . value ( " email " ) ;
dynamic_cast < MidiDevice * > ( m_device ) - >
setLibrarian ( qstrtostr ( name ) , qstrtostr ( email ) ) ;
}
} else if ( lcName = = " bank " ) {
if ( m_device ) // only if we have a device
{
if ( m_section ! = InStudio & & m_section ! = InInstrument )
{
m_errorString = " Found Bank outside Studio or Instrument " ;
return false ;
}
TQString nameStr = atts . value ( " name " ) ;
m_percussion = ( atts . value ( " percussion " ) . lower ( ) = = " true " ) ;
m_msb = ( atts . value ( " msb " ) ) . toInt ( ) ;
m_lsb = ( atts . value ( " lsb " ) ) . toInt ( ) ;
// To actually create a bank
//
if ( m_section = = InStudio )
{
// Create a new bank
MidiBank bank ( m_percussion ,
m_msb ,
m_lsb ,
qstrtostr ( nameStr ) ) ;
if ( m_device - > getType ( ) = = Device : : Midi ) {
// Insert the bank
//
dynamic_cast < MidiDevice * > ( m_device ) - > addBank ( bank ) ;
}
} else // otherwise we're referencing it in an instrument
if ( m_section = = InInstrument )
{
if ( m_instrument ) {
m_instrument - > setPercussion ( m_percussion ) ;
m_instrument - > setMSB ( m_msb ) ;
m_instrument - > setLSB ( m_lsb ) ;
m_instrument - > setSendBankSelect ( true ) ;
}
}
}
} else if ( lcName = = " program " ) {
if ( m_device ) // only if we have a device
{
if ( m_section = = InStudio )
{
TQString nameStr = ( atts . value ( " name " ) ) ;
MidiByte pc = atts . value ( " id " ) . toInt ( ) ;
TQString keyMappingStr = ( atts . value ( " keymapping " ) ) ;
// Create a new program
MidiProgram program
( MidiBank ( m_percussion ,
m_msb ,
m_lsb ) ,
pc ,
qstrtostr ( nameStr ) ,
keyMappingStr ? qstrtostr ( keyMappingStr ) : " " ) ;
if ( m_device - > getType ( ) = = Device : : Midi ) {
// Insert the program
//
dynamic_cast < MidiDevice * > ( m_device ) - >
addProgram ( program ) ;
}
} else if ( m_section = = InInstrument )
{
if ( m_instrument ) {
MidiByte id = atts . value ( " id " ) . toInt ( ) ;
m_instrument - > setProgramChange ( id ) ;
m_instrument - > setSendProgramChange ( true ) ;
}
} else
{
m_errorString = " Found Program outside Studio and Instrument " ;
return false ;
}
}
} else if ( lcName = = " keymapping " ) {
if ( m_section = = InInstrument ) {
RG_DEBUG < < " Old-style keymapping in instrument found, ignoring " < < endl ;
} else {
if ( m_section ! = InStudio ) {
m_errorString = " Found Keymapping outside Studio " ;
return false ;
}
if ( m_device & & ( m_device - > getType ( ) = = Device : : Midi ) ) {
TQString name = atts . value ( " name " ) ;
m_keyMapping = new MidiKeyMapping ( qstrtostr ( name ) ) ;
m_keyNameMap . clear ( ) ;
}
}
} else if ( lcName = = " key " ) {
if ( m_keyMapping ) {
TQString numStr = atts . value ( " number " ) ;
TQString namStr = atts . value ( " name " ) ;
if ( numStr & & namStr ) {
m_keyNameMap [ numStr . toInt ( ) ] = qstrtostr ( namStr ) ;
}
}
} else if ( lcName = = " controls " ) {
// Only clear down the controllers list if we have found some controllers in the RG file
//
if ( m_device ) {
dynamic_cast < MidiDevice * > ( m_device ) - > clearControlList ( ) ;
}
m_haveControls = true ;
} else if ( lcName = = " control " ) {
if ( m_section ! = InStudio ) {
m_errorString = " Found ControlParameter outside Studio " ;
return false ;
}
if ( ! m_device ) {
//!!! ach no, we can't give this warning -- we might be in a <device> elt
// but have no sequencer support, for example. we need a separate m_inDevice
// flag
// m_deprecation = true;
// std::cerr << "WARNING: This Rosegarden file uses a deprecated control parameter structure. We recommend re-saving the file from this version of Rosegarden to assure your ability to re-load it in future versions" << std::endl;
} else if ( m_device - > getType ( ) = = Device : : Midi ) {
if ( ! m_haveControls ) {
m_errorString = " Found ControlParameter outside Controls block " ;
return false ;
}
TQString name = atts . value ( " name " ) ;
TQString type = atts . value ( " type " ) ;
TQString descr = atts . value ( " description " ) ;
TQString min = atts . value ( " min " ) ;
TQString max = atts . value ( " max " ) ;
TQString def = atts . value ( " default " ) ;
TQString conVal = atts . value ( " controllervalue " ) ;
TQString colour = atts . value ( " colourindex " ) ;
TQString ipbPosition = atts . value ( " ipbposition " ) ;
ControlParameter con ( qstrtostr ( name ) ,
qstrtostr ( type ) ,
qstrtostr ( descr ) ,
min . toInt ( ) ,
max . toInt ( ) ,
def . toInt ( ) ,
MidiByte ( conVal . toInt ( ) ) ,
colour . toInt ( ) ,
ipbPosition . toInt ( ) ) ;
dynamic_cast < MidiDevice * > ( m_device ) - >
addControlParameter ( con ) ;
}
} else if ( lcName = = " reverb " ) { // deprecated but we still read 'em
if ( ! m_deprecation )
std : : cerr < < " WARNING: This Rosegarden file uses the deprecated element \" reverb \" (now replaced by a control parameter). We recommend re-saving the file from this version of Rosegarden to assure your ability to re-load it in future versions " < < std : : endl ;
m_deprecation = true ;
if ( m_section ! = InInstrument ) {
m_errorString = " Found Reverb outside Instrument " ;
return false ;
}
MidiByte value = atts . value ( " value " ) . toInt ( ) ;
if ( m_instrument )
m_instrument - > setControllerValue ( MIDI_CONTROLLER_REVERB , value ) ;
} else if ( lcName = = " chorus " ) { // deprecated but we still read 'em
if ( ! m_deprecation )
std : : cerr < < " WARNING: This Rosegarden file uses the deprecated element \" chorus \" (now replaced by a control parameter). We recommend re-saving the file from this version of Rosegarden to assure your ability to re-load it in future versions " < < std : : endl ;
m_deprecation = true ;
if ( m_section ! = InInstrument ) {
m_errorString = " Found Chorus outside Instrument " ;
return false ;
}
MidiByte value = atts . value ( " value " ) . toInt ( ) ;
if ( m_instrument )
m_instrument - > setControllerValue ( MIDI_CONTROLLER_CHORUS , value ) ;
} else if ( lcName = = " filter " ) { // deprecated but we still read 'em
if ( ! m_deprecation )
std : : cerr < < " WARNING: This Rosegarden file uses the deprecated element \" filter \" (now replaced by a control parameter). We recommend re-saving the file from this version of Rosegarden to assure your ability to re-load it in future versions " < < std : : endl ;
m_deprecation = true ;
if ( m_section ! = InInstrument ) {
m_errorString = " Found Filter outside Instrument " ;
return false ;
}
MidiByte value = atts . value ( " value " ) . toInt ( ) ;
if ( m_instrument )
m_instrument - > setControllerValue ( MIDI_CONTROLLER_FILTER , value ) ;
} else if ( lcName = = " resonance " ) { // deprecated but we still read 'em
if ( ! m_deprecation )
std : : cerr < < " WARNING: This Rosegarden file uses the deprecated element \" resonance \" (now replaced by a control parameter). We recommend re-saving the file from this version of Rosegarden to assure your ability to re-load it in future versions " < < std : : endl ;
m_deprecation = true ;
if ( m_section ! = InInstrument ) {
m_errorString = " Found Resonance outside Instrument " ;
return false ;
}
MidiByte value = atts . value ( " value " ) . toInt ( ) ;
if ( m_instrument )
m_instrument - > setControllerValue ( MIDI_CONTROLLER_RESONANCE , value ) ;
} else if ( lcName = = " attack " ) { // deprecated but we still read 'em
if ( ! m_deprecation )
std : : cerr < < " WARNING: This Rosegarden file uses the deprecated element \" attack \" (now replaced by a control parameter). We recommend re-saving the file from this version of Rosegarden to assure your ability to re-load it in future versions " < < std : : endl ;
m_deprecation = true ;
if ( m_section ! = InInstrument ) {
m_errorString = " Found Attack outside Instrument " ;
return false ;
}
MidiByte value = atts . value ( " value " ) . toInt ( ) ;
if ( m_instrument )
m_instrument - > setControllerValue ( MIDI_CONTROLLER_ATTACK , value ) ;
} else if ( lcName = = " release " ) { // deprecated but we still read 'em
if ( ! m_deprecation )
std : : cerr < < " WARNING: This Rosegarden file uses the deprecated element \" release \" (now replaced by a control parameter). We recommend re-saving the file from this version of Rosegarden to assure your ability to re-load it in future versions " < < std : : endl ;
m_deprecation = true ;
if ( m_section ! = InInstrument ) {
m_errorString = " Found Release outside Instrument " ;
return false ;
}
MidiByte value = atts . value ( " value " ) . toInt ( ) ;
if ( m_instrument )
m_instrument - > setControllerValue ( MIDI_CONTROLLER_RELEASE , value ) ;
} else if ( lcName = = " pan " ) {
if ( m_section ! = InInstrument & & m_section ! = InBuss ) {
m_errorString = " Found Pan outside Instrument or Buss " ;
return false ;
}
MidiByte value = atts . value ( " value " ) . toInt ( ) ;
if ( m_section = = InInstrument ) {
if ( m_instrument ) {
m_instrument - > setPan ( value ) ;
m_instrument - > setSendPan ( true ) ;
}
} else if ( m_section = = InBuss ) {
if ( m_buss ) {
m_buss - > setPan ( value ) ;
}
}
// keep "velocity" so we're backwards compatible
} else if ( lcName = = " velocity " | | lcName = = " volume " ) {
if ( lcName = = " velocity " ) {
if ( ! m_deprecation )
std : : cerr < < " WARNING: This Rosegarden file uses the deprecated element \" velocity \" for an overall MIDI instrument level (now replaced by \" volume \" ). We recommend re-saving the file from this version of Rosegarden to assure your ability to re-load it in future versions " < < std : : endl ;
m_deprecation = true ;
}
if ( m_section ! = InInstrument ) {
m_errorString = " Found Volume outside Instrument " ;
return false ;
}
MidiByte value = atts . value ( " value " ) . toInt ( ) ;
if ( m_instrument ) {
if ( m_instrument - > getType ( ) = = Instrument : : Audio | |
m_instrument - > getType ( ) = = Instrument : : SoftSynth ) {
// Backward compatibility: "volume" was in a 0-127
// range and we now store "level" (float dB) instead.
// Note that we have no such compatibility for
// "recordLevel", whose range has changed silently.
if ( ! m_deprecation )
std : : cerr < < " WARNING: This Rosegarden file uses the deprecated element \" volume \" for an audio instrument (now replaced by \" level \" ). We recommend re-saving the file from this version of Rosegarden to assure your ability to re-load it in future versions " < < std : : endl ;
m_deprecation = true ;
m_instrument - > setLevel
( AudioLevel : : multiplier_to_dB ( float ( value ) / 100.0 ) ) ;
} else {
m_instrument - > setVolume ( value ) ;
m_instrument - > setSendVolume ( true ) ;
}
}
} else if ( lcName = = " level " ) {
if ( m_section ! = InBuss & &
( m_section ! = InInstrument | |
( m_instrument & &
m_instrument - > getType ( ) ! = Instrument : : Audio & &
m_instrument - > getType ( ) ! = Instrument : : SoftSynth ) ) ) {
m_errorString = " Found Level outside (audio) Instrument or Buss " ;
return false ;
}
double value = qstrtodouble ( atts . value ( " value " ) ) ;
if ( m_section = = InBuss ) {
if ( m_buss )
m_buss - > setLevel ( value ) ;
} else {
if ( m_instrument )
m_instrument - > setLevel ( value ) ;
}
} else if ( lcName = = " controlchange " ) {
if ( m_section ! = InInstrument ) {
m_errorString = " Found ControlChange outside Instrument " ;
return false ;
}
MidiByte type = atts . value ( " type " ) . toInt ( ) ;
MidiByte value = atts . value ( " value " ) . toInt ( ) ;
if ( m_instrument ) {
m_instrument - > setControllerValue ( type , value ) ;
}
} else if ( lcName = = " plugin " | | lcName = = " synth " ) {
PluginContainer * container = 0 ;
if ( m_section = = InInstrument ) {
// std::cerr << "Found plugin in instrument" << std::endl;
container = m_instrument ;
m_pluginInBuss = false ;
} else if ( m_section = = InBuss ) {
// std::cerr << "Found plugin in buss" << std::endl;
container = m_buss ;
m_pluginInBuss = true ;
} else {
m_errorString = " Found Plugin outside Instrument or Buss " ;
return false ;
}
// Despite being InInstrument or InBuss we might not actually
// have a valid one.
//
if ( container ) {
// std::cerr << "Have container" << std::endl;
emit setOperationName ( i18n ( " Loading plugins... " ) ) ;
ProgressDialog : : processEvents ( ) ;
// Get the details
int position ;
if ( lcName = = " synth " ) {
position = Instrument : : SYNTH_PLUGIN_POSITION ;
} else {
position = atts . value ( " position " ) . toInt ( ) ;
}
bool bypassed = false ;
TQString bpStr = atts . value ( " bypassed " ) ;
if ( bpStr . lower ( ) = = " true " )
bypassed = true ;
std : : string program = " " ;
TQString progStr = atts . value ( " program " ) ;
if ( progStr ) {
program = qstrtostr ( progStr ) ;
}
// Plugins are identified by a structured identifier
// string, but we will accept a LADSPA UniqueId if there's
// no identifier, for backward compatibility
TQString identifier = atts . value ( " identifier " ) ;
AudioPlugin * plugin = 0 ;
AudioPluginManager * apm = getAudioPluginManager ( ) ;
if ( ! identifier ) {
if ( atts . value ( " id " ) ) {
unsigned long id = atts . value ( " id " ) . toULong ( ) ;
if ( apm )
plugin = apm - > getPluginByUniqueId ( id ) ;
}
} else {
if ( apm )
plugin = apm - > getPluginByIdentifier ( identifier ) ;
}
// std::cerr << "Plugin identifier " << identifier << " -> plugin " << plugin << std::endl;
// If we find the plugin all is well and good but if
// we don't we just skip it.
//
if ( plugin ) {
m_plugin = container - > getPlugin ( position ) ;
if ( ! m_plugin ) {
RG_DEBUG < < " WARNING: RoseXmlHandler: instrument/buss "
< < container - > getId ( ) < < " has no plugin position "
< < position < < endl ;
} else {
m_plugin - > setAssigned ( true ) ;
m_plugin - > setBypass ( bypassed ) ;
m_plugin - > setIdentifier ( plugin - > getIdentifier ( ) . ascii ( ) ) ;
// std::cerr << "set identifier to plugin at position " << position << std::endl;
if ( program ! = " " ) {
m_plugin - > setProgram ( program ) ;
}
}
} else {
// we shouldn't be halting import of the RG file just because
// we can't match a plugin
//
if ( identifier ) {
RG_DEBUG < < " WARNING: RoseXmlHandler: plugin " < < identifier < < " not found " < < endl ;
m_pluginsNotFound . insert ( identifier ) ;
} else if ( atts . value ( " id " ) ) {
RG_DEBUG < < " WARNING: RoseXmlHandler: plugin uid " < < atts . value ( " id " ) < < " not found " < < endl ;
} else {
m_errorString = " No plugin identifier or uid specified " ;
return false ;
}
}
} else { // no instrument
if ( lcName = = " synth " ) {
TQString identifier = atts . value ( " identifier " ) ;
if ( identifier ) {
RG_DEBUG < < " WARNING: RoseXmlHandler: no instrument for plugin " < < identifier < < endl ;
m_pluginsNotFound . insert ( identifier ) ;
}
}
}
m_section = InPlugin ;
} else if ( lcName = = " port " ) {
if ( m_section ! = InPlugin ) {
m_errorString = " Found Port outside Plugin " ;
return false ;
}
unsigned long portId = atts . value ( " id " ) . toULong ( ) ;
double value = qstrtodouble ( atts . value ( " value " ) ) ;
TQString changed = atts . value ( " changed " ) ;
bool changedSinceProgram = ( changed = = " true " ) ;
if ( m_plugin ) {
m_plugin - > addPort ( portId , value ) ;
if ( changedSinceProgram ) {
PluginPortInstance * ppi = m_plugin - > getPort ( portId ) ;
if ( ppi )
ppi - > changedSinceProgramChange = true ;
}
}
} else if ( lcName = = " configure " ) {
if ( m_section ! = InPlugin ) {
m_errorString = " Found Configure outside Plugin " ;
return false ;
}
TQString key = atts . value ( " key " ) ;
TQString value = atts . value ( " value " ) ;
if ( m_plugin ) {
m_plugin - > setConfigurationValue ( qstrtostr ( key ) , qstrtostr ( value ) ) ;
}
} else if ( lcName = = " metronome " ) {
if ( m_section ! = InStudio ) {
m_errorString = " Found Metronome outside Studio " ;
return false ;
}
// Only create if we have a device
//
if ( m_device & & m_device - > getType ( ) = = Device : : Midi ) {
InstrumentId instrument =
atts . value ( " instrument " ) . toInt ( ) ;
MidiMetronome metronome ( instrument ) ;
if ( atts . value ( " barpitch " ) )
metronome . setBarPitch ( atts . value ( " barpitch " ) . toInt ( ) ) ;
if ( atts . value ( " beatpitch " ) )
metronome . setBeatPitch ( atts . value ( " beatpitch " ) . toInt ( ) ) ;
if ( atts . value ( " subbeatpitch " ) )
metronome . setSubBeatPitch ( atts . value ( " subbeatpitch " ) . toInt ( ) ) ;
if ( atts . value ( " depth " ) )
metronome . setDepth ( atts . value ( " depth " ) . toInt ( ) ) ;
if ( atts . value ( " barvelocity " ) )
metronome . setBarVelocity ( atts . value ( " barvelocity " ) . toInt ( ) ) ;
if ( atts . value ( " beatvelocity " ) )
metronome . setBeatVelocity ( atts . value ( " beatvelocity " ) . toInt ( ) ) ;
if ( atts . value ( " subbeatvelocity " ) )
metronome . setSubBeatVelocity ( atts . value ( " subbeatvelocity " ) . toInt ( ) ) ;
dynamic_cast < MidiDevice * > ( m_device ) - >
setMetronome ( metronome ) ;
}
} else if ( lcName = = " instrument " ) {
if ( m_section ! = InStudio ) {
m_errorString = " Found Instrument outside Studio " ;
return false ;
}
m_section = InInstrument ;
InstrumentId id = atts . value ( " id " ) . toInt ( ) ;
std : : string stringType = qstrtostr ( atts . value ( " type " ) ) ;
Instrument : : InstrumentType type ;
if ( stringType = = " midi " )
type = Instrument : : Midi ;
else if ( stringType = = " audio " )
type = Instrument : : Audio ;
else if ( stringType = = " softsynth " )
type = Instrument : : SoftSynth ;
else {
m_errorString = " Found unknown Instrument type " ;
return false ;
}
// Try and match an Instrument in the file with one in
// our studio
//
Instrument * instrument = getStudio ( ) . getInstrumentById ( id ) ;
// If we've got an instrument and the types match then
// we use it from now on.
//
if ( instrument & & instrument - > getType ( ) = = type ) {
m_instrument = instrument ;
// We can also get the channel from this tag
//
MidiByte channel =
( MidiByte ) atts . value ( " channel " ) . toInt ( ) ;
m_instrument - > setMidiChannel ( channel ) ;
}
} else if ( lcName = = " buss " ) {
if ( m_section ! = InStudio ) {
m_errorString = " Found Buss outside Studio " ;
return false ;
}
m_section = InBuss ;
BussId id = atts . value ( " id " ) . toInt ( ) ;
Buss * buss = getStudio ( ) . getBussById ( id ) ;
// If we've got a buss then we use it from now on.
//
if ( buss ) {
m_buss = buss ;
} else {
m_buss = new Buss ( id ) ;
getStudio ( ) . addBuss ( m_buss ) ;
}
} else if ( lcName = = " audiofiles " ) {
if ( m_section ! = NoSection ) {
m_errorString = " Found AudioFiles inside another section " ;
return false ;
}
m_section = InAudioFiles ;
int rate = atts . value ( " expectedRate " ) . toInt ( ) ;
if ( rate ) {
getAudioFileManager ( ) . setExpectedSampleRate ( rate ) ;
}
} else if ( lcName = = " configuration " ) {
setSubHandler ( new ConfigurationXmlSubHandler
( lcName , & m_doc - > getConfiguration ( ) ) ) ;
} else if ( lcName = = " metadata " ) {
if ( m_section ! = InComposition ) {
m_errorString = " Found Metadata outside Composition " ;
return false ;
}
setSubHandler ( new ConfigurationXmlSubHandler
( lcName , & getComposition ( ) . getMetadata ( ) ) ) ;
} else if ( lcName = = " recordlevel " ) {
if ( m_section ! = InInstrument ) {
m_errorString = " Found recordLevel outside Instrument " ;
return false ;
}
double value = qstrtodouble ( atts . value ( " value " ) ) ;
// if the value retrieved is greater than (say) 15 then we
// must have an old-style 0-127 value instead of a shiny new
// dB value, so convert it
if ( value > 15.0 ) {
value = AudioLevel : : multiplier_to_dB ( value / 100 ) ;
}
if ( m_instrument )
m_instrument - > setRecordLevel ( value ) ;
} else if ( lcName = = " audioinput " ) {
if ( m_section ! = InInstrument ) {
m_errorString = " Found audioInput outside Instrument " ;
return false ;
}
int value = atts . value ( " value " ) . toInt ( ) ;
int channel = atts . value ( " channel " ) . toInt ( ) ;
TQString type = atts . value ( " type " ) ;
if ( type ) {
if ( type . lower ( ) = = " buss " ) {
if ( m_instrument )
m_instrument - > setAudioInputToBuss ( value , channel ) ;
} else if ( type . lower ( ) = = " record " ) {
if ( m_instrument )
m_instrument - > setAudioInputToRecord ( value , channel ) ;
}
}
} else if ( lcName = = " audiooutput " ) {
if ( m_section ! = InInstrument ) {
m_errorString = " Found audioOutput outside Instrument " ;
return false ;
}
int value = atts . value ( " value " ) . toInt ( ) ;
if ( m_instrument )
m_instrument - > setAudioOutput ( value ) ;
} else if ( lcName = = " appearance " ) {
m_section = InAppearance ;
} else if ( lcName = = " colourmap " ) {
if ( m_section = = InAppearance ) {
TQString mapName = atts . value ( " name " ) ;
m_inColourMap = true ;
if ( mapName = = " segmentmap " ) {
m_colourMap = & m_doc - > getComposition ( ) . getSegmentColourMap ( ) ;
} else
if ( mapName = = " generalmap " ) {
m_colourMap = & m_doc - > getComposition ( ) . getGeneralColourMap ( ) ;
} else { // This will change later once we get more of the Appearance code sorted out
RG_DEBUG < < " RoseXmlHandler::startElement : Found colourmap with unknown name \n " ;
}
} else {
m_errorString = " Found colourmap outside Appearance " ;
return false ;
}
} else if ( lcName = = " colourpair " ) {
if ( m_inColourMap & & m_colourMap ) {
unsigned int id = atts . value ( " id " ) . toInt ( ) ;
TQString name = atts . value ( " name " ) ;
unsigned int red = atts . value ( " red " ) . toInt ( ) ;
unsigned int blue = atts . value ( " blue " ) . toInt ( ) ;
unsigned int green = atts . value ( " green " ) . toInt ( ) ;
Colour colour ( red , green , blue ) ;
m_colourMap - > addItem ( colour , qstrtostr ( name ) , id ) ;
} else {
m_errorString = " Found colourpair outside ColourMap " ;
return false ;
}
} else if ( lcName = = " markers " ) {
if ( ! m_inComposition ) {
m_errorString = " Found Markers outside Composition " ;
return false ;
}
// clear down any markers
getComposition ( ) . clearMarkers ( ) ;
} else if ( lcName = = " marker " ) {
if ( ! m_inComposition ) {
m_errorString = " Found Marker outside Composition " ;
return false ;
}
int time = atts . value ( " time " ) . toInt ( ) ;
TQString name = atts . value ( " name " ) ;
TQString descr = atts . value ( " description " ) ;
Marker * marker =
new Marker ( time ,
qstrtostr ( name ) ,
qstrtostr ( descr ) ) ;
getComposition ( ) . addMarker ( marker ) ;
} else {
RG_DEBUG < < " RoseXmlHandler::startElement : Don't know how to parse this : " < < qName < < endl ;
}
return true ;
}
bool
RoseXmlHandler : : endElement ( const TQString & namespaceURI ,
const TQString & localName ,
const TQString & qName )
{
if ( getSubHandler ( ) ) {
bool finished ;
bool res = getSubHandler ( ) - > endElement ( namespaceURI , localName , qName . lower ( ) , finished ) ;
if ( finished )
setSubHandler ( 0 ) ;
return res ;
}
// Set percentage done
//
if ( ( m_totalElements > m_elementsSoFar ) & &
( + + m_elementsSoFar % 300 = = 0 ) ) {
emit setProgress ( int ( double ( m_elementsSoFar ) / double ( m_totalElements ) * 100.0 ) ) ;
ProgressDialog : : processEvents ( ) ;
}
TQString lcName = qName . lower ( ) ;
if ( lcName = = " rosegarden-data " ) {
getComposition ( ) . updateTriggerSegmentReferences ( ) ;
} else if ( lcName = = " event " ) {
if ( m_currentSegment & & m_currentEvent ) {
m_currentSegment - > insert ( m_currentEvent ) ;
m_currentEvent = 0 ;
} else if ( ! m_currentSegment & & m_currentEvent ) {
m_errorString = " Got event outside of a Segment " ;
return false ;
}
} else if ( lcName = = " chord " ) {
m_currentTime + = m_chordDuration ;
m_inChord = false ;
m_chordDuration = 0 ;
} else if ( lcName = = " group " ) {
m_inGroup = false ;
} else if ( lcName = = " segment " ) {
if ( m_currentSegment & & m_segmentEndMarkerTime ) {
m_currentSegment - > setEndMarkerTime ( * m_segmentEndMarkerTime ) ;
delete m_segmentEndMarkerTime ;
m_segmentEndMarkerTime = 0 ;
}
m_currentSegment = 0 ;
m_section = NoSection ;
} else if ( lcName = = " bar-segment " | | lcName = = " tempo-segment " ) {
m_currentSegment = 0 ;
} else if ( lcName = = " composition " ) {
m_inComposition = false ;
m_section = NoSection ;
} else if ( lcName = = " studio " ) {
m_section = NoSection ;
} else if ( lcName = = " buss " ) {
m_section = InStudio ;
m_buss = 0 ;
} else if ( lcName = = " instrument " ) {
m_section = InStudio ;
m_instrument = 0 ;
} else if ( lcName = = " plugin " ) {
if ( m_pluginInBuss ) {
m_section = InBuss ;
} else {
m_section = InInstrument ;
}
m_plugin = 0 ;
m_pluginId = 0 ;
} else if ( lcName = = " device " ) {
m_device = 0 ;
} else if ( lcName = = " keymapping " ) {
if ( m_section = = InStudio ) {
if ( m_keyMapping ) {
if ( ! m_keyNameMap . empty ( ) ) {
MidiDevice * md = dynamic_cast < MidiDevice * >
( m_device ) ;
if ( md ) {
m_keyMapping - > setMap ( m_keyNameMap ) ;
md - > addKeyMapping ( * m_keyMapping ) ;
}
}
m_keyMapping = 0 ;
}
}
} else if ( lcName = = " audiofiles " ) {
m_section = NoSection ;
} else if ( lcName = = " appearance " ) {
m_section = NoSection ;
} else if ( lcName = = " colourmap " ) {
m_inColourMap = false ;
m_colourMap = 0 ;
}
return true ;
}
bool
RoseXmlHandler : : characters ( const TQString & s )
{
if ( m_subHandler )
return m_subHandler - > characters ( s ) ;
return true ;
}
TQString
RoseXmlHandler : : errorString ( )
{
return m_errorString ;
}
bool
RoseXmlHandler : : error ( const TQXmlParseException & exception )
{
m_errorString = TQString ( " %1 at line %2, column %3 " )
. tqarg ( exception . message ( ) )
. tqarg ( exception . lineNumber ( ) )
. tqarg ( exception . columnNumber ( ) ) ;
return TQXmlDefaultHandler : : error ( exception ) ;
}
bool
RoseXmlHandler : : fatalError ( const TQXmlParseException & exception )
{
m_errorString = TQString ( " %1 at line %2, column %3 " )
. tqarg ( exception . message ( ) )
. tqarg ( exception . lineNumber ( ) )
. tqarg ( exception . columnNumber ( ) ) ;
return TQXmlDefaultHandler : : fatalError ( exception ) ;
}
bool
RoseXmlHandler : : endDocument ( )
{
if ( m_foundTempo = = false ) {
getComposition ( ) . setCompositionDefaultTempo
( Composition : : getTempoForQpm ( 120.0 ) ) ;
}
return true ;
}
void
RoseXmlHandler : : setSubHandler ( XmlSubHandler * sh )
{
delete m_subHandler ;
m_subHandler = sh ;
}
void
RoseXmlHandler : : addMIDIDevice ( TQString name , bool createAtSequencer )
{
unsigned int deviceId = 0 ;
if ( createAtSequencer ) {
TQByteArray data ;
TQByteArray replyData ;
TQCString replyType ;
TQDataStream arg ( data , IO_WriteOnly ) ;
arg < < ( int ) Device : : Midi ;
arg < < ( unsigned int ) MidiDevice : : Play ;
if ( ! rgapp - > sequencerCall ( " addDevice(int, unsigned int) " , replyType , replyData , data ) ) {
SETQMAN_DEBUG < < " RoseXmlHandler::addMIDIDevice - "
< < " can't call sequencer addDevice " < < endl ;
return ;
}
if ( replyType = = " unsigned int " ) {
TQDataStream reply ( replyData , IO_ReadOnly ) ;
reply > > deviceId ;
} else {
SETQMAN_DEBUG < < " RoseXmlHandler::addMIDIDevice - "
< < " got unknown returntype from addDevice() " < < endl ;
return ;
}
if ( deviceId = = Device : : NO_DEVICE ) {
SETQMAN_DEBUG < < " RoseXmlHandler::addMIDIDevice - "
< < " sequencer addDevice failed " < < endl ;
return ;
}
SETQMAN_DEBUG < < " RoseXmlHandler::addMIDIDevice - "
< < " added device " < < deviceId < < endl ;
} else {
// Generate a new device id at the base Studio side only.
// This may not correspond to any given device id at the
// sequencer side. We should _never_ do this in a document
// that's actually intended to be retained for use, only
// in temporary documents for device import etc.
int tempId = - 1 ;
for ( DeviceListIterator i = getStudio ( ) . getDevices ( ) - > begin ( ) ;
i ! = getStudio ( ) . getDevices ( ) - > end ( ) ; + + i ) {
if ( int ( ( * i ) - > getId ( ) ) > tempId )
tempId = int ( ( * i ) - > getId ( ) ) ;
}
deviceId = tempId + 1 ;
}
// add the device, so we can name it and set our pointer to it --
// instruments will be sync'd later in the natural course of things
getStudio ( ) . addDevice ( qstrtostr ( name ) , deviceId , Device : : Midi ) ;
m_device = getStudio ( ) . getDevice ( deviceId ) ;
m_deviceRunningId = deviceId ;
}
void
RoseXmlHandler : : skipToNextPlayDevice ( )
{
SETQMAN_DEBUG < < " RoseXmlHandler::skipToNextPlayDevice; m_deviceRunningId is " < < m_deviceRunningId < < endl ;
for ( DeviceList : : iterator i = getStudio ( ) . getDevices ( ) - > begin ( ) ;
i ! = getStudio ( ) . getDevices ( ) - > end ( ) ; + + i ) {
MidiDevice * md =
dynamic_cast < MidiDevice * > ( * i ) ;
if ( md & & md - > getDirection ( ) = = MidiDevice : : Play ) {
if ( m_deviceRunningId = = Device : : NO_DEVICE | |
md - > getId ( ) > m_deviceRunningId ) {
SETQMAN_DEBUG < < " RoseXmlHandler::skipToNextPlayDevice: found next device: id " < < md - > getId ( ) < < endl ;
m_device = md ;
m_deviceRunningId = md - > getId ( ) ;
return ;
}
}
}
SETQMAN_DEBUG < < " RoseXmlHandler::skipToNextPlayDevice: fresh out of devices " < < endl ;
m_device = 0 ;
}
void
RoseXmlHandler : : setMIDIDeviceConnection ( TQString connection )
{
SETQMAN_DEBUG < < " RoseXmlHandler::setMIDIDeviceConnection( " < < connection < < " ) " < < endl ;
MidiDevice * md = dynamic_cast < MidiDevice * > ( m_device ) ;
if ( ! md )
return ;
TQByteArray data ;
TQDataStream arg ( data , IO_WriteOnly ) ;
arg < < ( unsigned int ) md - > getId ( ) ;
arg < < connection ;
rgapp - > sequencerSend ( " setPlausibleConnection(unsigned int, TQString) " ,
data ) ;
// connection should be sync'd later in the natural course of things
}
void
RoseXmlHandler : : setMIDIDeviceName ( TQString name )
{
SETQMAN_DEBUG < < " RoseXmlHandler::setMIDIDeviceName( " < < name < < " ) " < < endl ;
MidiDevice * md = dynamic_cast < MidiDevice * > ( m_device ) ;
if ( ! md )
return ;
TQByteArray data ;
TQDataStream arg ( data , IO_WriteOnly ) ;
arg < < ( unsigned int ) md - > getId ( ) ;
arg < < name ;
std : : cerr < < " Renaming device " < < md - > getId ( ) < < " to " < < name < < std : : endl ;
rgapp - > sequencerSend ( " renameDevice(unsigned int, TQString) " ,
data ) ;
}
}